Version 0.5.5.0 .

svn merge -r 22342:22413 https://dart.googlecode.com/svn/branches/bleeding_edge trunk

git-svn-id: http://dart.googlecode.com/svn/trunk@22416 260f80e4-7a28-3924-810f-c04153c831b5
diff --git a/pkg/analyzer_experimental/bin/analyzer.dart b/pkg/analyzer_experimental/bin/analyzer.dart
index f4806ac..2beb6aa 100644
--- a/pkg/analyzer_experimental/bin/analyzer.dart
+++ b/pkg/analyzer_experimental/bin/analyzer.dart
@@ -10,37 +10,117 @@
 import 'dart:async';
 import 'dart:io';
 
+import 'package:analyzer_experimental/src/generated/java_io.dart';
+import 'package:analyzer_experimental/src/generated/engine.dart';
+import 'package:analyzer_experimental/src/generated/error.dart';
+import 'package:analyzer_experimental/src/generated/source_io.dart';
+import 'package:analyzer_experimental/src/generated/sdk.dart';
+import 'package:analyzer_experimental/src/generated/sdk_io.dart';
+import 'package:analyzer_experimental/src/generated/ast.dart';
+import 'package:analyzer_experimental/src/generated/element.dart';
 import 'package:analyzer_experimental/options.dart';
 
-// Exit status codes.
-const OK_EXIT = 0;
-const ERROR_EXIT = 1;
+part 'package:analyzer_experimental/analyzer.dart';
+part 'package:analyzer_experimental/error_formatter.dart';
 
 void main() {
-  run(new Options().arguments).then((result) {
-    exit(result.error ? ERROR_EXIT : OK_EXIT);
-  });
-}
-
-/** The result of an analysis. */
-class AnalysisResult {
-  final bool error;
-  AnalysisResult.forFailure() : error = true;
-  AnalysisResult.forSuccess() : error = false;
-}
-
-
-/**
- * Runs the dart analyzer with the command-line options in [args].
- * See [CommandLineOptions] for a list of valid arguments.
- */
-Future<AnalysisResult> run(List<String> args) {
-
-  var options = new CommandLineOptions.parse(args);
-  if (options == null) {
-    return new Future.value(new AnalysisResult.forFailure());
+  var args = new Options().arguments;
+  var options = CommandLineOptions.parse(args);
+  if (options.shouldBatch) {
+    BatchRunner.runAsBatch(args, (List<String> args) {
+      var options = CommandLineOptions.parse(args);
+      return _runAnalyzer(options);
+    });
+  } else {
+    ErrorSeverity result = _runAnalyzer(options);
+    exit(result.ordinal);
   }
+}
 
-  //TODO(pquitslund): call out to analyzer...
+ErrorSeverity _runAnalyzer(CommandLineOptions options) {
+  for (String sourcePath in options.sourceFiles) {
+    sourcePath = sourcePath.trim();
+    // check that file exists
+    if (!new File(sourcePath).existsSync()) {
+      print('File not found: $sourcePath');
+      return ErrorSeverity.ERROR;
+    }
+    // check that file is Dart file
+    if (!AnalysisEngine.isDartFileName(sourcePath)) {
+      print('$sourcePath is not a Dart file');
+      return ErrorSeverity.ERROR;
+    }
+    // start analysis
+    _ErrorFormatter formatter = new _ErrorFormatter(options.machineFormat ? stderr : stdout, options);
+    formatter.startAnalysis();
+    // do analyze
+    _AnalyzerImpl analyzer = new _AnalyzerImpl(options);
+    analyzer.analyze(sourcePath);
+    // pring errors
+    formatter.formatErrors(analyzer.errorInfos);
+    // prepare status
+    ErrorSeverity status = analyzer.maxErrorSeverity;
+    if (status == ErrorSeverity.WARNING && options.warningsAreFatal) {
+      status = ErrorSeverity.ERROR;
+    }
+    return status;
+  }
+}
 
-}
\ No newline at end of file
+typedef ErrorSeverity BatchRunnerHandler(List<String> args);
+
+/// Provides a framework to read command line options from stdin and feed them to a callback.
+class BatchRunner {
+  /**
+   * Run the tool in 'batch' mode, receiving command lines through stdin and returning pass/fail
+   * status through stdout. This feature is intended for use in unit testing.
+   */
+  static ErrorSeverity runAsBatch(List<String> sharedArgs, BatchRunnerHandler handler) {
+    stdout.writeln('>>> BATCH START');
+    Stopwatch stopwatch = new Stopwatch();
+    stopwatch.start();
+    int testsFailed = 0;
+    int totalTests = 0;
+    ErrorSeverity batchResult = ErrorSeverity.NONE;
+    // read line from stdin
+    Stream cmdLine = stdin
+        .transform(new StringDecoder())
+        .transform(new LineTransformer());
+    var subscription = cmdLine.listen((String line) {
+      // may be finish
+      if (line.isEmpty) {
+        stdout.writeln('>>> BATCH END (${totalTests - testsFailed}/$totalTests) ${stopwatch.elapsedMilliseconds}ms');
+        exit(batchResult.ordinal);
+      }
+      // prepare aruments
+      var args;
+      {
+        var lineArgs = line.split(new RegExp('\\s+'));
+        args = new List<String>();
+        args.addAll(sharedArgs);
+        args.addAll(lineArgs);
+        args.remove('-b');
+        args.remove('--batch');
+      }
+      // analyze single set of arguments
+      try {
+        totalTests++;
+        ErrorSeverity result = handler(args);
+        bool resultPass = result != ErrorSeverity.ERROR;
+        if (!resultPass) {
+          testsFailed++;
+        }
+        batchResult = batchResult.max(result);
+        // Write stderr end token and flush.
+        stderr.writeln('>>> EOF STDERR');
+        String resultPassString = resultPass ? 'PASS' : 'FAIL';
+        stdout.writeln('>>> TEST $resultPassString ${stopwatch.elapsedMilliseconds}ms');
+      } catch (e, stackTrace) {
+        stderr.writeln(e);
+        stderr.writeln(stackTrace);
+        stderr.writeln('>>> EOF STDERR');
+        stdout.writeln('>>> TEST CRASH');
+      }
+    });
+  }
+}
diff --git a/pkg/analyzer_experimental/lib/analyzer.dart b/pkg/analyzer_experimental/lib/analyzer.dart
index 8df6d94..47f0129 100644
--- a/pkg/analyzer_experimental/lib/analyzer.dart
+++ b/pkg/analyzer_experimental/lib/analyzer.dart
@@ -1,4 +1,134 @@
 // Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
 // for 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 analyzer;
 
+/// Analyzes single library [File].
+class _AnalyzerImpl {
+  final CommandLineOptions options;
+  DartSdk sdk;
+
+  ContentCache contentCache = new ContentCache();
+  SourceFactory sourceFactory;
+  AnalysisContext context;
+
+  /// All [Source]s references by the analyzed library.
+  final Set<Source> sources = new Set<Source>();
+
+  /// All [AnalysisErrorInfo]s in the analyzed library.
+  final List<AnalysisErrorInfo> errorInfos = new List<AnalysisErrorInfo>();
+
+  _AnalyzerImpl(CommandLineOptions this.options) {
+    sdk = new DirectoryBasedDartSdk(new JavaFile(options.dartSdkPath));
+  }
+
+  /**
+   * Treats the [sourcePath] as the top level library and analyzes it.
+   */
+  void analyze(String sourcePath) {
+    sources.clear();
+    errorInfos.clear();
+    if (sourcePath == null) {
+      throw new ArgumentError("sourcePath cannot be null");
+    }
+    var sourceFile = new JavaFile(sourcePath);
+    var librarySource = new FileBasedSource.con1(contentCache, sourceFile);
+    // resolve library
+    prepareAnalysisContext(sourceFile);
+    var libraryElement = context.computeLibraryElement(librarySource);
+    // prepare source and errors
+    prepareSources(libraryElement);
+    prepareErrors();
+  }
+
+  /// Returns the maximal [ErrorSeverity] of the recorded errors.
+  ErrorSeverity get maxErrorSeverity {
+    var status = ErrorSeverity.NONE;
+    for (AnalysisErrorInfo errorInfo in errorInfos) {
+      for (AnalysisError error in errorInfo.errors) {
+        var severity = error.errorCode.errorSeverity;
+        status = status.max(severity);
+      }
+    }
+    return status;
+  }
+
+  void prepareAnalysisContext(JavaFile sourceFile) {
+    List<UriResolver> resolvers = [new DartUriResolver(sdk), new FileUriResolver()];
+    // may be add package resolver
+    {
+      var packageDirectory = getPackageDirectoryFor(sourceFile);
+      if (packageDirectory != null) {
+        resolvers.add(new PackageUriResolver([packageDirectory]));
+      }
+    }
+    sourceFactory = new SourceFactory.con1(contentCache, resolvers);
+    context = AnalysisEngine.instance.createAnalysisContext();
+    context.sourceFactory = sourceFactory;
+  }
+
+  /// Fills [sources].
+  void prepareSources(LibraryElement library) {
+    var units = new Set<CompilationUnitElement>();
+    var libraries = new Set<LibraryElement>();
+    addLibrarySources(library, libraries, units);
+  }
+
+  void addCompilationUnitSource(CompilationUnitElement unit, Set<LibraryElement> libraries,
+      Set<CompilationUnitElement> units) {
+    if (unit == null || units.contains(unit)) {
+      return;
+    }
+    units.add(unit);
+    sources.add(unit.source);
+  }
+
+  void addLibrarySources(LibraryElement library, Set<LibraryElement> libraries,
+      Set<CompilationUnitElement> units) {
+    if (library == null || libraries.contains(library)) {
+      return;
+    }
+    libraries.add(library);
+    // may be skip library
+    {
+      UriKind uriKind = library.source.uriKind;
+      // Optionally skip package: libraries.
+      if (!options.showPackageWarnings && uriKind == UriKind.PACKAGE_URI) {
+        return;
+      }
+      // Optionally skip SDK libraries.
+      if (!options.showSdkWarnings && uriKind == UriKind.DART_URI) {
+        return;
+      }
+    }
+    // add compilation units
+    addCompilationUnitSource(library.definingCompilationUnit, libraries, units);
+    for (CompilationUnitElement child in library.parts) {
+      addCompilationUnitSource(child, libraries, units);
+    }
+    // add referenced libraries
+    for (LibraryElement child in library.importedLibraries) {
+      addLibrarySources(child, libraries, units);
+    }
+    for (LibraryElement child in library.exportedLibraries) {
+      addLibrarySources(child, libraries, units);
+    }
+  }
+
+  /// Fills [errorInfos].
+  void prepareErrors() {
+    for (Source source in sources) {
+      var sourceErrors = context.getErrors(source);
+      errorInfos.add(sourceErrors);
+    }
+  }
+
+  static JavaFile getPackageDirectoryFor(JavaFile sourceFile) {
+    JavaFile sourceFolder = sourceFile.getParentFile();
+    JavaFile packagesFolder = new JavaFile.relative(sourceFolder, "packages");
+    if (packagesFolder.exists()) {
+      return packagesFolder;
+    }
+    return null;
+  }
+}
diff --git a/pkg/analyzer_experimental/lib/error_formatter.dart b/pkg/analyzer_experimental/lib/error_formatter.dart
new file mode 100644
index 0000000..9aafb9f
--- /dev/null
+++ b/pkg/analyzer_experimental/lib/error_formatter.dart
@@ -0,0 +1,143 @@
+part of analyzer;
+
+/**
+ * Helper for formatting [AnalysisError]s.
+ * The two format options are a user consumable format and a machine consumable format.
+ */
+class _ErrorFormatter {
+  StringSink out;
+  CommandLineOptions options;
+
+  _ErrorFormatter(this.out, this.options);
+
+  void startAnalysis() {
+    if (!options.machineFormat) {
+      out.writeln("Analyzing ${options.sourceFiles}...");
+    }
+  }
+
+  void formatErrors(List<AnalysisErrorInfo> errorInfos) {
+    var errors = new List<AnalysisError>();
+    var errorToLine = new Map<AnalysisError, LineInfo>();
+    for (AnalysisErrorInfo errorInfo in errorInfos) {
+      for (AnalysisError error in errorInfo.errors) {
+        errors.add(error);
+        errorToLine[error] = errorInfo.lineInfo;
+      }
+    }
+    // sort errors
+    errors.sort((AnalysisError error1, AnalysisError error2) {
+      // severity
+      int compare = error2.errorCode.errorSeverity.compareTo(error1.errorCode.errorSeverity);
+      if (compare != 0) {
+        return compare;
+      }
+      // path
+      compare = Comparable.compare(error1.source.fullName.toLowerCase(), error2.source.fullName.toLowerCase());
+      if (compare != 0) {
+        return compare;
+      }
+      // offset
+      return error1.offset - error2.offset;
+    });
+    // format errors
+    int errorCount = 0;
+    int warnCount = 0;
+    for (AnalysisError error in errors) {
+      if (error.errorCode.errorSeverity == ErrorSeverity.ERROR) {
+        errorCount++;
+      } else if (error.errorCode.errorSeverity == ErrorSeverity.WARNING) {
+        if (options.warningsAreFatal) {
+          errorCount++;
+        } else {
+          warnCount++;
+        }
+      }
+      formatError(errorToLine, error);
+    }
+    // print statistics
+    if (!options.machineFormat) {
+      if (errorCount != 0 && warnCount != 0) {
+        out.write(errorCount);
+        out.write(' ');
+        out.write(pluralize("error", errorCount));
+        out.write(' and ');
+        out.write(warnCount);
+        out.write(' ');
+        out.write(pluralize("warning", warnCount));
+        out.writeln(' found.');
+      } else if (errorCount != 0) {
+        out.write(errorCount);
+        out.write(' ');
+        out.write(pluralize("error", errorCount));
+        out.writeln(' found.');
+      } else if (warnCount != 0) {
+        out.write(warnCount);
+        out.write(' ');
+        out.write(pluralize("warning", warnCount));
+        out.writeln(' found.');
+      } else {
+        out.writeln("No issues found.");
+      }
+    }
+  }
+
+  void formatError(Map<AnalysisError, LineInfo> errorToLine, AnalysisError error) {
+    Source source = error.source;
+    LineInfo_Location location = errorToLine[error].getLocation(error.offset);
+    int length = error.length;
+    var severity = error.errorCode.errorSeverity;
+    if (options.machineFormat) {
+      if (severity == ErrorSeverity.WARNING && options.warningsAreFatal) {
+        severity = ErrorSeverity.ERROR;
+      }
+      out.write(severity);
+      out.write('|');
+      out.write(error.errorCode.type);
+      out.write('|');
+      out.write(error.errorCode);
+      out.write('|');
+      out.write(escapePipe(source.fullName));
+      out.write('|');
+      out.write(location.lineNumber);
+      out.write('|');
+      out.write(location.columnNumber);
+      out.write('|');
+      out.write(length);
+      out.write('|');
+      out.writeln(escapePipe(error.message));
+    } else {
+      // [warning] 'foo' is not a method or function (/Users/devoncarew/temp/foo.dart:-1:-1)
+      out.write('[');
+      out.write(severity.displayName);
+      out.write('] ');
+      out.write(error.message);
+      out.write(' (');
+      out.write(source.fullName);
+      out.write(':');
+      out.write(location.lineNumber);
+      out.write(':');
+      out.write(location.columnNumber);
+      out.writeln(')');
+    }
+  }
+
+  static String escapePipe(String input) {
+    var result = new StringBuffer();
+    for (var c in input.codeUnits) {
+      if (c == '\\' || c == '|') {
+        result.write('\\');
+      }
+      result.writeCharCode(c);
+    }
+    return result.toString();
+  }
+
+  static String pluralize(String word, int count) {
+    if (count == 1) {
+      return word;
+    } else {
+      return word + "s";
+    }
+  }
+}
diff --git a/pkg/analyzer_experimental/lib/options.dart b/pkg/analyzer_experimental/lib/options.dart
index b426129..d26060b 100644
--- a/pkg/analyzer_experimental/lib/options.dart
+++ b/pkg/analyzer_experimental/lib/options.dart
@@ -10,8 +10,6 @@
 
 
 const _BINARY_NAME = 'analyzer';
-const _SDK_ENV = 'com.google.dart.sdk';
-final _DEFAULT_SDK_LOCATION = Platform.environment[_SDK_ENV];
 
 /**
  * Analyzer commandline configuration options.
@@ -27,8 +25,11 @@
   /** Whether to ignore unrecognized flags */
   final bool ignoreUnrecognizedFlags;
 
-  /** Whether to print metrics */
-  final bool showMetrics;
+  /** Whether to show package: warnings */
+  final bool showPackageWarnings;
+
+  /** Whether to show SDK warnings */
+  final bool showSdkWarnings;
 
   /** Whether to treat warnings as fatal */
   final bool warningsAreFatal;
@@ -46,22 +47,41 @@
     : shouldBatch = args['batch'],
       machineFormat = args['machine_format'],
       ignoreUnrecognizedFlags = args['ignore_unrecognized_flags'],
-      showMetrics = args['metrics'],
+      showPackageWarnings = args['show_package_warnings'],
+      showSdkWarnings = args['show_sdk_warnings'],
       warningsAreFatal = args['fatal_warnings'],
       dartSdkPath = args['dart_sdk'],
       sourceFiles = args.rest;
 
   /**
    * Parse [args] into [CommandLineOptions] describing the specified
-   * analyzer options.  In case of a format error, [null] is returned.
+   * analyzer options. In case of a format error, prints error and exists.
    */
-  factory CommandLineOptions.parse(List<String> args) {
+  static CommandLineOptions parse(List<String> args) {
+    CommandLineOptions options = _parse(args);
+    // check SDK
+    {
+      var sdkPath = options.dartSdkPath;
+      // check that SDK is specified
+      if (sdkPath == null) {
+        print('Usage: $_BINARY_NAME: no Dart SDK found.');
+        exit(15);
+      }
+      // check that SDK is existing directory
+      if (!(new Directory(sdkPath)).existsSync()) {
+        print('Usage: $_BINARY_NAME: invalid Dart SDK path: $sdkPath');
+        exit(15);
+      }
+    }
+    // OK
+    return options;
+  }
 
+  static CommandLineOptions _parse(List<String> args) {
     var parser = new _CommandLineParser()
       ..addFlag('batch', abbr: 'b', help: 'Run in batch mode',
           defaultsTo: false, negatable: false)
-      ..addOption('dart_sdk', help: 'Specify path to the Dart sdk',
-          defaultsTo: _DEFAULT_SDK_LOCATION)
+      ..addOption('dart_sdk', help: 'Specify path to the Dart sdk')
       ..addFlag('machine_format', help: 'Specify whether errors '
         'should be in machine format',
           defaultsTo: false, negatable: false)
@@ -70,29 +90,44 @@
           defaultsTo: false, negatable: false)
       ..addFlag('fatal_warnings', help: 'Treat non-type warnings as fatal',
           defaultsTo: false, negatable: false)
-       ..addFlag('metrics', help: 'Print metrics',
-          defaultsTo: false, negatable: false)
+      ..addFlag('show_package_warnings', help: 'Show warnings from package: imports',
+         defaultsTo: false, negatable: false)
+      ..addFlag('show_sdk_warnings', help: 'Show warnings from SDK imports',
+         defaultsTo: false, negatable: false)
       ..addFlag('help', abbr: 'h', help: 'Display this help message',
-          defaultsTo: false, negatable: false);
+         defaultsTo: false, negatable: false);
 
     try {
       var results = parser.parse(args);
-      if (results['help'] || results.rest.length == 0) {
+      // help requests
+      if (results['help']) {
         _showUsage(parser);
-        return null;
+        exit(0);
+      }
+      // batch mode and input files
+      if (results['batch']) {
+        if (results.rest.length != 0) {
+          print('No source files expected in the batch mode.');
+          _showUsage(parser);
+          exit(15);
+        }
+      } else {
+        if (results.rest.length == 0) {
+          _showUsage(parser);
+          exit(15);
+        }
       }
       return new CommandLineOptions._fromArgs(results);
     } on FormatException catch (e) {
       print(e.message);
       _showUsage(parser);
-      return null;
+      exit(15);
     }
 
   }
 
   static _showUsage(parser) {
-    print('Usage: ${_BINARY_NAME} [options...] '
-      '<libraries to analyze...>');
+    print('Usage: $_BINARY_NAME [options...] <libraries to analyze...>');
     print(parser.getUsage());
   }
 
@@ -194,6 +229,4 @@
     }
     return i;
   }
-
 }
-
diff --git a/pkg/analyzer_experimental/test/options_test.dart b/pkg/analyzer_experimental/test/options_test.dart
index 02b194c..e885cda 100644
--- a/pkg/analyzer_experimental/test/options_test.dart
+++ b/pkg/analyzer_experimental/test/options_test.dart
@@ -12,30 +12,30 @@
   group('AnalyzerOptions.parse()', () {
 
     test('defaults', () {
-      CommandLineOptions options = new CommandLineOptions.parse(['foo.dart']);
-      expect(options, isNotNull);
-      expect(options.shouldBatch, isFalse);
-      expect(options.machineFormat, isFalse);
-      expect(options.ignoreUnrecognizedFlags, isFalse);
-      expect(options.showMetrics, isFalse);
-      expect(options.warningsAreFatal, isFalse);
-      expect(options.dartSdkPath, isNull);
-      expect(options.sourceFiles, equals(['foo.dart']));
-
+//      CommandLineOptions options = CommandLineOptions.parse(['foo.dart']);
+//      expect(options, isNotNull);
+//      expect(options.shouldBatch, isFalse);
+//      expect(options.machineFormat, isFalse);
+//      expect(options.ignoreUnrecognizedFlags, isFalse);
+//      expect(options.showPackageWarnings, isFalse);
+//      expect(options.showSdkWarnings, isFalse);
+//      expect(options.warningsAreFatal, isFalse);
+//      expect(options.dartSdkPath, isNull);
+//      expect(options.sourceFiles, equals(['foo.dart']));
     });
 
-    test('notice unrecognized flags', () {
-      CommandLineOptions options = new CommandLineOptions.parse(['--bar', '--baz',
-        'foo.dart']);
-      expect(options, isNull);
-    });
-
-    test('ignore unrecognized flags', () {
-      CommandLineOptions options = new CommandLineOptions.parse([
-        '--ignore_unrecognized_flags', '--bar', '--baz', 'foo.dart']);
-      expect(options, isNotNull);
-      expect(options.sourceFiles, equals(['foo.dart']));
-    });
+//    test('notice unrecognized flags', () {
+//      CommandLineOptions options = new CommandLineOptions.parse(['--bar', '--baz',
+//        'foo.dart']);
+//      expect(options, isNull);
+//    });
+//
+//    test('ignore unrecognized flags', () {
+//      CommandLineOptions options = new CommandLineOptions.parse([
+//        '--ignore_unrecognized_flags', '--bar', '--baz', 'foo.dart']);
+//      expect(options, isNotNull);
+//      expect(options.sourceFiles, equals(['foo.dart']));
+//    });
 
   });
 
diff --git a/pkg/browser/lib/dart.js b/pkg/browser/lib/dart.js
index ee339de7..b507378 100644
--- a/pkg/browser/lib/dart.js
+++ b/pkg/browser/lib/dart.js
@@ -27,6 +27,9 @@
           var script = document.createElement('script');
           script.src = scripts[i].src.replace(/\.dart(?=\?|$)/, '.dart.js');
           var parent = scripts[i].parentNode;
+	  // TODO(vsm): Find a solution for issue 8455 that works with more
+	  // than one script.
+	  document.currentScript = script;
           parent.replaceChild(script, scripts[i]);
         }
       }
diff --git a/pkg/http/lib/src/request.dart b/pkg/http/lib/src/request.dart
index 20da3c1..2520b2a 100644
--- a/pkg/http/lib/src/request.dart
+++ b/pkg/http/lib/src/request.dart
@@ -154,7 +154,7 @@
   ContentType get _contentType {
     var contentType = headers[HttpHeaders.CONTENT_TYPE];
     if (contentType == null) return null;
-    return new ContentType.fromString(contentType);
+    return ContentType.parse(contentType);
   }
 
   set _contentType(ContentType value) {
diff --git a/pkg/http/lib/src/response.dart b/pkg/http/lib/src/response.dart
index c036fe9..b7e0a48 100644
--- a/pkg/http/lib/src/response.dart
+++ b/pkg/http/lib/src/response.dart
@@ -89,6 +89,6 @@
 /// `application/octet-stream`.
 ContentType _contentTypeForHeaders(Map<String, String> headers) {
   var contentType = headers[HttpHeaders.CONTENT_TYPE];
-  if (contentType != null) return new ContentType.fromString(contentType);
+  if (contentType != null) return ContentType.parse(contentType);
   return new ContentType("application", "octet-stream");
 }
diff --git a/pkg/http/test/multipart_test.dart b/pkg/http/test/multipart_test.dart
index 288a445..1be547d 100644
--- a/pkg/http/test/multipart_test.dart
+++ b/pkg/http/test/multipart_test.dart
@@ -31,8 +31,7 @@
 
     var future = item.finalize().toBytes().then((bodyBytes) {
       var body = decodeUtf8(bodyBytes);
-      var contentType = new ContentType.fromString(
-          item.headers['content-type']);
+      var contentType = ContentType.parse(item.headers['content-type']);
       var boundary = contentType.parameters['boundary'];
       var expected = cleanUpLiteral(_pattern)
           .replaceAll("\n", "\r\n")
diff --git a/pkg/oauth2/lib/src/handle_access_token_response.dart b/pkg/oauth2/lib/src/handle_access_token_response.dart
index 65e706e..c82c818 100644
--- a/pkg/oauth2/lib/src/handle_access_token_response.dart
+++ b/pkg/oauth2/lib/src/handle_access_token_response.dart
@@ -33,7 +33,7 @@
 
   var contentType = response.headers['content-type'];
   if (contentType != null) {
-    contentType = new ContentType.fromString(contentType);
+    contentType = ContentType.parse(contentType);
   }
   validate(contentType != null && contentType.value == "application/json",
       'content-type was "$contentType", expected "application/json"');
@@ -103,7 +103,7 @@
 
   var contentType = response.headers['content-type'];
   if (contentType != null) {
-    contentType = new ContentType.fromString(contentType);
+    contentType = ContentType.parse(contentType);
   }
   validate(contentType != null && contentType.value == "application/json",
       'content-type was "$contentType", expected "application/json"');
diff --git a/pkg/unittest/lib/mock.dart b/pkg/unittest/lib/mock.dart
index b6e48a4..1721dcf 100644
--- a/pkg/unittest/lib/mock.dart
+++ b/pkg/unittest/lib/mock.dart
@@ -102,12 +102,25 @@
  *       }
  *     }
  *
+ * However, there is an even easier way, by calling [Mock.spy], e.g.:
+ *
+ *      var foo = new Foo();
+ *      var spy = new Mock.spy(foo);
+ *      print(spy.bar(1, 2, 3));
+ *
+ * Spys created with Mock.spy do not have user-defined behavior;
+ * they are simply proxies,  and thus will throw an exception if
+ * you call [when]. They capture all calls in the log, so you can
+ * do assertions on their history, such as:
+ *
+ *       spy.getLogs(callsTo('bar')).verify(happenedOnce);
+ *
  * [pub]: http://pub.dartlang.org
  */
 
 library mock;
 
-import 'dart:mirrors' show MirrorSystem;
+import 'dart:mirrors';
 import 'dart:collection' show LinkedHashMap;
 
 import 'matcher.dart';
@@ -1246,6 +1259,9 @@
   /** How to handle unknown method calls - swallow or throw. */
   final bool _throwIfNoBehavior;
 
+  /** For spys, the real object that we are spying on. */
+  Object _realObject;
+
   /** Whether to create an audit log or not. */
   bool _logging;
 
@@ -1286,6 +1302,19 @@
   }
 
   /**
+   * This constructor creates a spy with no user-defined behavior.
+   * This is simply a proxy for a real object that passes calls
+   * through to that real object but captures an audit trail of
+   * calls made to the object that can be queried and validated
+   * later.
+   */
+  Mock.spy(this._realObject, {this.name, this.log})
+    : _behaviors = null,
+     _throwIfNoBehavior = true {
+    logging = true;
+  }
+
+  /**
    * [when] is used to create a new or extend an existing [Behavior].
    * A [CallMatcher] [filter] must be supplied, and the [Behavior]s for
    * that signature are returned (being created first if needed).
@@ -1324,6 +1353,17 @@
         method = method.substring(0, method.length - 1);
       }
     }
+    if (_behaviors == null) { // Spy.
+      var mirror = reflect(_realObject);
+      try {
+        var result = mirror.delegate(invocation);
+        log.add(new LogEntry(name, method, args, Action.PROXY, result));
+        return result;
+      } catch (e) {
+        log.add(new LogEntry(name, method, args, Action.THROW, e));
+        throw e;
+      }
+    }
     bool matchedMethodName = false;
     MatchState matchState = new MatchState();
     for (String k in _behaviors.keys) {
@@ -1360,7 +1400,8 @@
           throw value;
         } else if (action == Action.PROXY) {
           // TODO(gram): Replace all this with:
-          //     var rtn = invocation.invokeOn(value);
+          //     var rtn = reflect(value).apply(invocation.positionalArguments,
+          //         invocation.namedArguments);
           // once that is supported.
           var rtn;
           switch (args.length) {
diff --git a/pkg/unittest/test/mock_test.dart b/pkg/unittest/test/mock_test.dart
index 5669f3f..1204c39 100644
--- a/pkg/unittest/test/mock_test.dart
+++ b/pkg/unittest/test/mock_test.dart
@@ -718,5 +718,15 @@
     expect(m.foo("bar", "mock"), "C");
     m.resetBehavior();
   });
+
+  solo_test('Spys', () {
+    var real = new Foo();
+    var spy = new Mock.spy(real);
+    var sum = spy.sum(1, 2, 3);
+    expect(sum, 6);
+    expect(() => spy.total(1, 2, 3), throwsNoSuchMethodError);
+    spy.getLogs(callsTo('sum')).verify(happenedExactly(1));
+    spy.getLogs(callsTo('total')).verify(happenedExactly(1));
+  });
 }
 
diff --git a/runtime/bin/dartutils.cc b/runtime/bin/dartutils.cc
index a803fca..370eed0 100644
--- a/runtime/bin/dartutils.cc
+++ b/runtime/bin/dartutils.cc
@@ -191,11 +191,52 @@
 }
 
 
-static const uint8_t* ReadFile(const char* filename,
-                               intptr_t* file_len,
-                               const char** error_msg) {
-  File* file = File::Open(filename, File::kRead);
-  if (file == NULL) {
+void* DartUtils::OpenFile(const char* name, bool write) {
+  File* file = File::Open(name, write ? File::kWriteTruncate : File::kRead);
+  return reinterpret_cast<void*>(file);
+}
+
+
+void DartUtils::ReadFile(const uint8_t** data,
+                         intptr_t* file_len,
+                         void* stream) {
+  ASSERT(data != NULL);
+  ASSERT(file_len != NULL);
+  ASSERT(stream != NULL);
+  File* file_stream = reinterpret_cast<File*>(stream);
+  *file_len = file_stream->Length();
+  ASSERT(*file_len > 0);
+  uint8_t* text_buffer = reinterpret_cast<uint8_t*>(malloc(*file_len));
+  ASSERT(text_buffer != NULL);
+  if (!file_stream->ReadFully(text_buffer, *file_len)) {
+    *data = NULL;
+    *file_len = -1;  // Indicates read was not successful.
+    return;
+  }
+  *data = text_buffer;
+}
+
+
+void DartUtils::WriteFile(const void* buffer,
+                          intptr_t num_bytes,
+                          void* stream) {
+  ASSERT(stream != NULL);
+  File* file_stream = reinterpret_cast<File*>(stream);
+  bool bytes_written = file_stream->WriteFully(buffer, num_bytes);
+  ASSERT(bytes_written);
+}
+
+
+void DartUtils::CloseFile(void* stream) {
+  delete reinterpret_cast<File*>(stream);
+}
+
+
+static const uint8_t* ReadFileFully(const char* filename,
+                                    intptr_t* file_len,
+                                    const char** error_msg) {
+  void* stream = DartUtils::OpenFile(filename, false);
+  if (stream == NULL) {
     const char* format = "Unable to open file: %s";
     intptr_t len = snprintf(NULL, 0, format, filename);
     // TODO(iposva): Allocate from the zone instead of leaking error string
@@ -205,20 +246,14 @@
     *error_msg = msg;
     return NULL;
   }
-  *file_len = file->Length();
-  uint8_t* text_buffer = reinterpret_cast<uint8_t*>(malloc(*file_len));
-  if (text_buffer == NULL) {
-    delete file;
-    *error_msg = "Unable to allocate buffer";
-    return NULL;
+  *file_len = -1;
+  const uint8_t* text_buffer = NULL;
+  DartUtils::ReadFile(&text_buffer, file_len, stream);
+  if (text_buffer == NULL || *file_len == -1) {
+    *error_msg = "Unable to read file contents";
+    text_buffer = NULL;
   }
-  if (!file->ReadFully(text_buffer, *file_len)) {
-    delete file;
-    free(text_buffer);
-    *error_msg = "Unable to fully read contents";
-    return NULL;
-  }
-  delete file;
+  DartUtils::CloseFile(stream);
   return text_buffer;
 }
 
@@ -226,7 +261,7 @@
 Dart_Handle DartUtils::ReadStringFromFile(const char* filename) {
   const char* error_msg = NULL;
   intptr_t len;
-  const uint8_t* text_buffer = ReadFile(filename, &len, &error_msg);
+  const uint8_t* text_buffer = ReadFileFully(filename, &len, &error_msg);
   if (text_buffer == NULL) {
     return Dart_Error(error_msg);
   }
@@ -384,7 +419,9 @@
   Dart_StringToCString(script_path, &script_path_cstr);
   const char* error_msg = NULL;
   intptr_t len;
-  const uint8_t* text_buffer = ReadFile(script_path_cstr, &len, &error_msg);
+  const uint8_t* text_buffer = ReadFileFully(script_path_cstr,
+                                             &len,
+                                             &error_msg);
   if (text_buffer == NULL) {
     return Dart_Error(error_msg);
   }
diff --git a/runtime/bin/dartutils.h b/runtime/bin/dartutils.h
index 074cc12..a9d1393 100644
--- a/runtime/bin/dartutils.h
+++ b/runtime/bin/dartutils.h
@@ -108,6 +108,10 @@
   static Dart_Handle CanonicalizeURL(CommandLineOptions* url_mapping,
                                      Dart_Handle library,
                                      const char* url_str);
+  static void* OpenFile(const char* name, bool write);
+  static void ReadFile(const uint8_t** data, intptr_t* file_len, void* stream);
+  static void WriteFile(const void* buffer, intptr_t num_bytes, void* stream);
+  static void CloseFile(void* stream);
   static Dart_Handle ReadStringFromFile(const char* filename);
   static Dart_Handle LibraryTagHandler(Dart_LibraryTag tag,
                                        Dart_Handle library,
diff --git a/runtime/bin/eventhandler_win.cc b/runtime/bin/eventhandler_win.cc
index 6a43dd5..6819fce 100644
--- a/runtime/bin/eventhandler_win.cc
+++ b/runtime/bin/eventhandler_win.cc
@@ -23,7 +23,8 @@
 namespace dart {
 namespace bin {
 
-static const int kBufferSize = 32 * 1024;
+static const int kBufferSize = 64 * 1024;
+static const int kStdioBufferSize = 16 * 1024;
 
 static const int kInfinityTimeout = -1;
 static const int kTimeoutId = -1;
@@ -212,10 +213,16 @@
 
 void Handle::ReadSyncCompleteAsync() {
   ASSERT(pending_read_ != NULL);
+  ASSERT(pending_read_->GetBufferSize() >= kStdioBufferSize);
+
+  DWORD buffer_size = pending_read_->GetBufferSize();
+  if (GetFileType(handle_) == FILE_TYPE_CHAR) {
+    buffer_size = kStdioBufferSize;
+  }
   DWORD bytes_read = 0;
   BOOL ok = ReadFile(handle_,
                      pending_read_->GetBufferStart(),
-                     pending_read_->GetBufferSize(),
+                     buffer_size,
                      &bytes_read,
                      NULL);
   if (!ok) {
diff --git a/runtime/bin/file.cc b/runtime/bin/file.cc
index de9d1e9..bc8ca4c 100644
--- a/runtime/bin/file.cc
+++ b/runtime/bin/file.cc
@@ -1061,8 +1061,8 @@
 
 static CObject* FileDeleteLinkRequest(const CObjectArray& request) {
   if (request.Length() == 2 && request[1]->IsString()) {
-    CObjectString filename(request[1]);
-    bool result = File::DeleteLink(filename.CString());
+    CObjectString link_path(request[1]);
+    bool result = File::DeleteLink(link_path.CString());
     if (result) {
       return CObject::True();
     } else {
@@ -1073,6 +1073,55 @@
 }
 
 
+static CObject* FileLinkTargetRequest(const CObjectArray& request) {
+  if (request.Length() == 2 && request[1]->IsString()) {
+    CObjectString link_path(request[1]);
+    char* target = File::LinkTarget(link_path.CString());
+    if (target != NULL) {
+      CObject* result = new CObjectString(CObject::NewString(target));
+      free(target);
+      return result;
+    } else {
+      return CObject::NewOSError();
+    }
+  }
+  return CObject::IllegalArgumentError();
+}
+
+
+static CObject* FileTypeRequest(const CObjectArray& request) {
+  if (request.Length() == 3 &&
+      request[1]->IsString() &&
+      request[2]->IsBool()) {
+    CObjectString path(request[1]);
+    CObjectBool follow_links(request[2]);
+    File::Type type = File::GetType(path.CString(), follow_links.Value());
+    return new CObjectInt32(CObject::NewInt32(type));
+  }
+  return CObject::IllegalArgumentError();
+}
+
+
+static CObject* FileIdenticalRequest(const CObjectArray& request) {
+  if (request.Length() == 3 &&
+      request[1]->IsString() &&
+      request[2]->IsString()) {
+    CObjectString path1(request[1]);
+    CObjectString path2(request[2]);
+    File::Identical result = File::AreIdentical(path1.CString(),
+                                                path2.CString());
+    if (result == File::kError) {
+      return CObject::NewOSError();
+    } else if (result == File::kIdentical) {
+      return CObject::True();
+    } else {
+      return CObject::False();
+    }
+  }
+  return CObject::IllegalArgumentError();
+}
+
+
 static void FileService(Dart_Port dest_port_id,
                  Dart_Port reply_port_id,
                  Dart_CObject* message) {
@@ -1145,6 +1194,15 @@
         case File::kCreateLinkRequest:
           response = FileCreateLinkRequest(request);
           break;
+        case File::kLinkTargetRequest:
+          response = FileLinkTargetRequest(request);
+          break;
+        case File::kTypeRequest:
+          response = FileTypeRequest(request);
+          break;
+        case File::kIdenticalRequest:
+          response = FileIdenticalRequest(request);
+          break;
         default:
           UNREACHABLE();
       }
diff --git a/runtime/bin/file.h b/runtime/bin/file.h
index 9e12463..cf9f689 100644
--- a/runtime/bin/file.h
+++ b/runtime/bin/file.h
@@ -82,7 +82,10 @@
     kReadIntoRequest = 17,
     kWriteFromRequest = 18,
     kCreateLinkRequest = 19,
-    kDeleteLinkRequest = 20
+    kDeleteLinkRequest = 20,
+    kLinkTargetRequest = 21,
+    kTypeRequest = 22,
+    kIdenticalRequest = 23
   };
 
   ~File();
diff --git a/runtime/bin/file_system_entity_patch.dart b/runtime/bin/file_system_entity_patch.dart
index 2815ba6..13a7dc8 100644
--- a/runtime/bin/file_system_entity_patch.dart
+++ b/runtime/bin/file_system_entity_patch.dart
@@ -3,8 +3,8 @@
 // BSD-style license that can be found in the LICENSE file.
 
 patch class FileSystemEntity {
-  /* patch */ static int _getType(String path, bool followLinks)
+  /* patch */ static _getType(String path, bool followLinks)
       native "File_GetType";
-  /* patch */ static bool _identical(String path1, String path2)
+  /* patch */ static _identical(String path1, String path2)
       native "File_AreIdentical";
 }
diff --git a/runtime/bin/gen_snapshot.cc b/runtime/bin/gen_snapshot.cc
index d5e0a5e..41d71f1 100644
--- a/runtime/bin/gen_snapshot.cc
+++ b/runtime/bin/gen_snapshot.cc
@@ -466,7 +466,10 @@
   // Note: We don't expect isolates to be created from dart code during
   // snapshot generation.
   if (!Dart_Initialize(NULL, NULL, NULL, NULL,
-                       NULL, NULL, NULL)) {
+                       DartUtils::OpenFile,
+                       DartUtils::ReadFile,
+                       DartUtils::WriteFile,
+                       DartUtils::CloseFile)) {
     Log::PrintErr("VM initialization failed\n");
     return 255;
   }
diff --git a/runtime/bin/main.cc b/runtime/bin/main.cc
index 96ec295..f485f66 100644
--- a/runtime/bin/main.cc
+++ b/runtime/bin/main.cc
@@ -262,26 +262,6 @@
 }
 
 
-static void* OpenFile(const char* name) {
-  File* file = File::Open(name, File::kWriteTruncate);
-  ASSERT(file != NULL);
-  return reinterpret_cast<void*>(file);
-}
-
-
-static void WriteFile(const void* buffer, intptr_t num_bytes, void* stream) {
-  ASSERT(stream != NULL);
-  File* file_stream = reinterpret_cast<File*>(stream);
-  bool bytes_written = file_stream->WriteFully(buffer, num_bytes);
-  ASSERT(bytes_written);
-}
-
-
-static void CloseFile(void* stream) {
-  delete reinterpret_cast<File*>(stream);
-}
-
-
 // Convert all the arguments to UTF8. On Windows, the arguments are
 // encoded in the current code page and not UTF8.
 //
@@ -732,7 +712,10 @@
 
   // Initialize the Dart VM.
   if (!Dart_Initialize(CreateIsolateAndSetup, NULL, NULL, ShutdownIsolate,
-                       OpenFile, WriteFile, CloseFile)) {
+                       DartUtils::OpenFile,
+                       DartUtils::ReadFile,
+                       DartUtils::WriteFile,
+                       DartUtils::CloseFile)) {
     fprintf(stderr, "%s", "VM initialization failed\n");
     fflush(stderr);
     return kErrorExitCode;
diff --git a/runtime/bin/run_vm_tests.cc b/runtime/bin/run_vm_tests.cc
index c4d191e..9daac7d 100644
--- a/runtime/bin/run_vm_tests.cc
+++ b/runtime/bin/run_vm_tests.cc
@@ -8,8 +8,10 @@
 
 #include "vm/benchmark_test.h"
 #include "vm/dart.h"
+#include "bin/dartutils.h"
 #include "vm/unit_test.h"
 
+
 // TODO(iposva, asiva): This is a placeholder for the real unittest framework.
 namespace dart {
 
@@ -104,7 +106,10 @@
                                                              dart_argv);
   ASSERT(set_vm_flags_success);
   const char* err_msg = Dart::InitOnce(NULL, NULL, NULL, NULL,
-                                       NULL, NULL, NULL);
+                                       dart::bin::DartUtils::OpenFile,
+                                       dart::bin::DartUtils::ReadFile,
+                                       dart::bin::DartUtils::WriteFile,
+                                       dart::bin::DartUtils::CloseFile);
   ASSERT(err_msg == NULL);
   // Apply the filter to all registered tests.
   TestCaseBase::RunAll();
diff --git a/runtime/include/dart_api.h b/runtime/include/dart_api.h
index fcb839d..d72c662 100755
--- a/runtime/include/dart_api.h
+++ b/runtime/include/dart_api.h
@@ -646,7 +646,38 @@
  */
 typedef void (*Dart_IsolateShutdownCallback)(void* callback_data);
 
-typedef void* (*Dart_FileOpenCallback)(const char* name);
+/**
+ * Callbacks provided by the embedder for file operations. If the
+ * embedder does not allow file operations these callbacks can be
+ * NULL.
+ *
+ * Dart_FileOpenCallback - opens a file for reading or writing.
+ * \param name The name of the file to open.
+ * \param write A boolean variable which indicates if the file is to
+ *   opened for writing. If there is an existing file it needs to truncated.
+ *
+ * Dart_FileReadCallback - Read contents of file.
+ * \param data Buffer allocated in the callback into which the contents
+ *   of the file are read into. It is the responsibility of the caller to
+ *   free this buffer.
+ * \param file_length A variable into which the length of the file is returned.
+ *   In the case of an error this value would be -1.
+ * \param stream Handle to the opened file.
+ *
+ * Dart_FileWriteCallback - Write data into file.
+ * \param data Buffer which needs to be written into the file.
+ * \param length Length of the buffer.
+ * \param stream Handle to the opened file.
+ *
+ * Dart_FileCloseCallback - Closes the opened file.
+ * \param stream Handle to the opened file.
+ *
+ */
+typedef void* (*Dart_FileOpenCallback)(const char* name, bool write);
+
+typedef void (*Dart_FileReadCallback)(const uint8_t** data,
+                                      intptr_t* file_length,
+                                      void* stream);
 
 typedef void (*Dart_FileWriteCallback)(const void* data,
                                        intptr_t length,
@@ -675,6 +706,7 @@
     Dart_IsolateUnhandledExceptionCallback unhandled_exception,
     Dart_IsolateShutdownCallback shutdown,
     Dart_FileOpenCallback file_open,
+    Dart_FileReadCallback file_read,
     Dart_FileWriteCallback file_write,
     Dart_FileCloseCallback file_close);
 
diff --git a/runtime/lib/lib_sources.gypi b/runtime/lib/corelib_sources.gypi
similarity index 100%
rename from runtime/lib/lib_sources.gypi
rename to runtime/lib/corelib_sources.gypi
diff --git a/runtime/lib/libgen_in.cc b/runtime/lib/libgen_in.cc
new file mode 100644
index 0000000..03dedf8
--- /dev/null
+++ b/runtime/lib/libgen_in.cc
@@ -0,0 +1,13 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+#include "{{INCLUDE}}" // NOLINT
+
+// This file is used to generate the mapping of libraries which have
+// dart:<name> handles to the corresponding files that implement them.
+const char* {{VAR_NAME}}[] = {
+{{LIBRARY_SOURCE_MAP}}
+{{PART_SOURCE_MAP}}
+  NULL, NULL
+};
diff --git a/runtime/lib/string.cc b/runtime/lib/string.cc
index 761541a..4cc4c1e 100644
--- a/runtime/lib/string.cc
+++ b/runtime/lib/string.cc
@@ -121,6 +121,23 @@
 }
 
 
+DEFINE_NATIVE_ENTRY(OneByteString_allocate, 1) {
+  GET_NON_NULL_NATIVE_ARGUMENT(Smi, length_obj, arguments->NativeArgAt(0));
+  return OneByteString::New(length_obj.Value(), Heap::kNew);
+}
+
+
+DEFINE_NATIVE_ENTRY(OneByteString_setAt, 3) {
+  GET_NON_NULL_NATIVE_ARGUMENT(String, receiver, arguments->NativeArgAt(0));
+  ASSERT(receiver.IsOneByteString());
+  GET_NON_NULL_NATIVE_ARGUMENT(Smi, index_obj, arguments->NativeArgAt(1));
+  GET_NON_NULL_NATIVE_ARGUMENT(Smi, code_point_obj, arguments->NativeArgAt(2));
+  ASSERT((0 <= code_point_obj.Value()) && (code_point_obj.Value() <= 0xFF));
+  OneByteString::SetCharAt(receiver, index_obj.Value(), code_point_obj.Value());
+  return Object::null();
+}
+
+
 DEFINE_NATIVE_ENTRY(String_getHashCode, 1) {
   const String& receiver = String::CheckedHandle(arguments->NativeArgAt(0));
   intptr_t hash_val = receiver.Hash();
diff --git a/runtime/lib/string_patch.dart b/runtime/lib/string_patch.dart
index f20f8b0..5d2f38e 100644
--- a/runtime/lib/string_patch.dart
+++ b/runtime/lib/string_patch.dart
@@ -27,13 +27,32 @@
    *  [codePoints].
    */
   static String createFromCharCodes(Iterable<int> charCodes) {
-    // TODO(srdjan): Also skip copying of typed arrays.
-    if (charCodes is! _ObjectArray &&
-        charCodes is! _GrowableObjectArray &&
-        charCodes is! _ImmutableArray) {
-      charCodes = new List<int>.from(charCodes, growable: false);
-    }
+    if (charCodes != null) {
+      // TODO(srdjan): Also skip copying of typed arrays.
+      if (charCodes is! _ObjectArray &&
+          charCodes is! _GrowableObjectArray &&
+          charCodes is! _ImmutableArray) {
+        charCodes = new List<int>.from(charCodes, growable: false);
+      }
 
+      bool isOneByteString = true;
+      for (int i = 0; i < charCodes.length; i++) {
+        int e = charCodes[i];
+        if (e is! int) throw new ArgumentError(e);
+        // Is e Latin1?
+        if ((e < 0) || (e > 0xFF)) {
+          isOneByteString = false;
+          break;
+        }
+      }
+      if (isOneByteString) {
+        var s = _OneByteString._allocate(charCodes.length);
+        for (int i = 0; i < charCodes.length; i++) {
+          s._setAt(i, charCodes[i]);
+        }
+        return s;
+      }
+    }
     return _createFromCodePoints(charCodes);
   }
 
@@ -466,6 +485,13 @@
     }
     return super.split(pattern);
   }
+
+  // Allocates a string of given length, expecting its content to be
+  // set using _setAt.
+  static _OneByteString _allocate(int length) native "OneByteString_allocate";
+
+  // Code point value must be a valid Latin1 (0..0xFF). Index must be valid.
+  void _setAt(int index, int codePoint) native "OneByteString_setAt";
 }
 
 
diff --git a/runtime/tests/vm/vm.status b/runtime/tests/vm/vm.status
index 529a615..5787071 100644
--- a/runtime/tests/vm/vm.status
+++ b/runtime/tests/vm/vm.status
@@ -12,12 +12,12 @@
 cc/Debug_StackTraceDump1: Skip
 cc/Debug_StackTraceDump2: Skip
 
+# Flaky on buildbot. Issue 5133 and 10409.
+cc/Sleep: Pass, Fail
+
 [ $arch == x64 ]
 cc/IsolateInterrupt: Skip
 
-[ $system == windows && $mode == debug ]
-cc/Sleep: Pass, Fail  # Flaky on buildbot. Issue 5133.
-
 # The following section refers to the dart vm tests which live under
 # runtime/tests/vm/dart.
 [ $system == windows ]
@@ -72,8 +72,9 @@
 # Tests missing code generation support.
 cc/CorelibCompileAll: Skip
 cc/Dart2JSCompileAll: Skip
-# Tests needing Dart execution.
-dart/*: Skip
+dart/byte_array_test: Skip
+dart/byte_array_optimized_test: Skip
+dart/inline_stack_frame_test: Skip
 
 # TODO(ajohnsen): Fix this as part of library changes.
 [ $compiler == none ]
diff --git a/runtime/tools/gen_library_src_paths.py b/runtime/tools/gen_library_src_paths.py
new file mode 100644
index 0000000..2cb082b
--- /dev/null
+++ b/runtime/tools/gen_library_src_paths.py
@@ -0,0 +1,107 @@
+#!/usr/bin/env python
+# Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+# for 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 python script creates a source path mapping in a C++ source file from
+# a C++ source template and list of dart library files.
+
+import os
+import sys
+
+from os.path import join
+from optparse import OptionParser
+
+
+def makeFile(output_file, input_cc_file, include, var_name, lib_name, in_files):
+  part_index = [ ]
+  bootstrap_cc_text = open(input_cc_file).read()
+  bootstrap_cc_text = bootstrap_cc_text.replace("{{INCLUDE}}", include)
+  bootstrap_cc_text = bootstrap_cc_text.replace("{{VAR_NAME}}", var_name)
+  main_file_found = False
+  for string_file in in_files:
+    if string_file.endswith('.dart'):
+      if (not main_file_found):
+        inpt = open(string_file, 'r')
+        for line in inpt:
+          # File with library tag is the main file.
+          if line.startswith('library '):
+            main_file_found = True
+            bootstrap_cc_text = bootstrap_cc_text.replace(
+                 "{{LIBRARY_SOURCE_MAP}}",
+                 ' "' + lib_name + '", "' +
+                 os.path.abspath(string_file).replace('\\', '\\\\') + '", \n')
+        inpt.close()
+        if (main_file_found):
+          continue
+      part_index.append(' "' +
+          os.path.basename(string_file).replace('\\', '\\\\') + '", ')
+      part_index.append('"' +
+          os.path.abspath(string_file).replace('\\', '\\\\') + '", \n')
+  bootstrap_cc_text = bootstrap_cc_text.replace("{{PART_SOURCE_MAP}}",
+                                                ''.join(part_index))
+  open(output_file, 'w').write(bootstrap_cc_text)
+  return True
+
+
+def main(args):
+  try:
+    # Parse input.
+    parser = OptionParser()
+    parser.add_option("--output",
+                      action="store", type="string",
+                      help="output file name")
+    parser.add_option("--input_cc",
+                      action="store", type="string",
+                      help="input template file")
+    parser.add_option("--include",
+                      action="store", type="string",
+                      help="variable name")
+    parser.add_option("--library_name",
+                      action="store", type="string",
+                      help="library name")
+    parser.add_option("--var_name",
+                      action="store", type="string",
+                      help="variable name")
+
+    (options, args) = parser.parse_args()
+    if not options.output:
+      sys.stderr.write('--output not specified\n')
+      return -1
+    if not len(options.input_cc):
+      sys.stderr.write('--input_cc not specified\n')
+      return -1
+    if not len(options.include):
+      sys.stderr.write('--include not specified\n')
+      return -1
+    if not len(options.var_name):
+      sys.stderr.write('--var_name not specified\n')
+      return -1
+    if not len(options.library_name):
+      sys.stderr.write('--library_name not specified\n')
+      return -1
+    if len(args) == 0:
+      sys.stderr.write('No input files specified\n')
+      return -1
+
+    files = [ ]
+    for arg in args:
+      files.append(arg)
+
+    if not makeFile(options.output,
+                    options.input_cc,
+                    options.include,
+                    options.var_name,
+                    options.library_name,
+                    files):
+      return -1
+
+    return 0
+  except Exception, inst:
+    sys.stderr.write('gen_library_src_paths.py exception\n')
+    sys.stderr.write(str(inst))
+    sys.stderr.write('\n')
+    return -1
+
+if __name__ == '__main__':
+  sys.exit(main(sys.argv))
diff --git a/runtime/vm/assembler_arm.cc b/runtime/vm/assembler_arm.cc
index d55fab9..5f74eeb 100644
--- a/runtime/vm/assembler_arm.cc
+++ b/runtime/vm/assembler_arm.cc
@@ -563,12 +563,14 @@
 
 void Assembler::ldm(BlockAddressMode am, Register base, RegList regs,
                     Condition cond) {
+  ASSERT(regs != 0);
   EmitMultiMemOp(cond, am, true, base, regs);
 }
 
 
 void Assembler::stm(BlockAddressMode am, Register base, RegList regs,
                     Condition cond) {
+  ASSERT(regs != 0);
   EmitMultiMemOp(cond, am, false, base, regs);
 }
 
@@ -1155,9 +1157,9 @@
 }
 
 
-void Assembler::bkpt(uint16_t imm16, Condition cond) {
-  ASSERT(cond != kNoCondition);
-  int32_t encoding = (cond << kConditionShift) | B24 | B21 |
+void Assembler::bkpt(uint16_t imm16) {
+  // bkpt requires that the cond field is AL.
+  int32_t encoding = (AL << kConditionShift) | B24 | B21 |
                      ((imm16 >> 4) << 8) | B6 | B5 | B4 | (imm16 & 0xf);
   Emit(encoding);
 }
diff --git a/runtime/vm/assembler_arm.h b/runtime/vm/assembler_arm.h
index 849b644..fa2744d 100644
--- a/runtime/vm/assembler_arm.h
+++ b/runtime/vm/assembler_arm.h
@@ -436,7 +436,7 @@
   void nop(Condition cond = AL);
 
   // Note that gdb sets breakpoints using the undefined instruction 0xe7f001f0.
-  void bkpt(uint16_t imm16, Condition cond = AL);
+  void bkpt(uint16_t imm16);
   void svc(uint32_t imm24, Condition cond = AL);
 
   // Floating point instructions (VFPv3-D16 and VFPv3-D32 profiles).
diff --git a/runtime/vm/assembler_test.cc b/runtime/vm/assembler_test.cc
index 693498f..2bd9563 100644
--- a/runtime/vm/assembler_test.cc
+++ b/runtime/vm/assembler_test.cc
@@ -39,44 +39,37 @@
   const Context& ctx = Context::Handle(Context::New(0));
 
   EXPECT(old_array.raw() == grow_old_array.data());
-  EXPECT(!Isolate::Current()->store_buffer_block()->Contains(
-      reinterpret_cast<uword>(grow_old_array.raw())));
+  EXPECT(!Isolate::Current()->store_buffer()->Contains(grow_old_array.raw()));
   EXPECT(old_array.raw() == grow_new_array.data());
-  EXPECT(!Isolate::Current()->store_buffer_block()->Contains(
-      reinterpret_cast<uword>(grow_new_array.raw())));
+  EXPECT(!Isolate::Current()->store_buffer()->Contains(grow_new_array.raw()));
 
   // Store Smis into the old object.
   for (int i = -128; i < 128; i++) {
     smi = Smi::New(i);
     test_code(ctx.raw(), smi.raw(), grow_old_array.raw());
     EXPECT(reinterpret_cast<RawArray*>(smi.raw()) == grow_old_array.data());
-    EXPECT(!Isolate::Current()->store_buffer_block()->Contains(
-       reinterpret_cast<uword>(grow_old_array.raw())));
+    EXPECT(!Isolate::Current()->store_buffer()->Contains(grow_old_array.raw()));
   }
 
   // Store an old object into the old object.
   test_code(ctx.raw(), old_array.raw(), grow_old_array.raw());
   EXPECT(old_array.raw() == grow_old_array.data());
-  EXPECT(!Isolate::Current()->store_buffer_block()->Contains(
-      reinterpret_cast<uword>(grow_old_array.raw())));
+  EXPECT(!Isolate::Current()->store_buffer()->Contains(grow_old_array.raw()));
 
   // Store a new object into the old object.
   test_code(ctx.raw(), new_array.raw(), grow_old_array.raw());
   EXPECT(new_array.raw() == grow_old_array.data());
-  EXPECT(Isolate::Current()->store_buffer_block()->Contains(
-      reinterpret_cast<uword>(grow_old_array.raw())));
+  EXPECT(Isolate::Current()->store_buffer()->Contains(grow_old_array.raw()));
 
   // Store a new object into the new object.
   test_code(ctx.raw(), new_array.raw(), grow_new_array.raw());
   EXPECT(new_array.raw() == grow_new_array.data());
-  EXPECT(!Isolate::Current()->store_buffer_block()->Contains(
-      reinterpret_cast<uword>(grow_new_array.raw())));
+  EXPECT(!Isolate::Current()->store_buffer()->Contains(grow_new_array.raw()));
 
   // Store an old object into the new object.
   test_code(ctx.raw(), old_array.raw(), grow_new_array.raw());
   EXPECT(old_array.raw() == grow_new_array.data());
-  EXPECT(!Isolate::Current()->store_buffer_block()->Contains(
-      reinterpret_cast<uword>(grow_new_array.raw())));
+  EXPECT(!Isolate::Current()->store_buffer()->Contains(grow_new_array.raw()));
 }
 
 }  // namespace dart
diff --git a/runtime/vm/bootstrap.cc b/runtime/vm/bootstrap.cc
index 03e69dc..01008aa 100644
--- a/runtime/vm/bootstrap.cc
+++ b/runtime/vm/bootstrap.cc
@@ -25,7 +25,7 @@
 typedef struct {
   intptr_t index_;
   const char* uri_;
-  const char* source_;
+  const char** source_paths_;
   const char* patch_uri_;
   const char* patch_source_;
 } bootstrap_lib_props;
@@ -34,73 +34,171 @@
 static bootstrap_lib_props bootstrap_libraries[] = {
   INIT_LIBRARY(ObjectStore::kCore,
                core,
-               Bootstrap::corelib_source_,
+               Bootstrap::corelib_source_paths_,
                Bootstrap::corelib_patch_),
   INIT_LIBRARY(ObjectStore::kAsync,
                async,
-               Bootstrap::async_source_,
+               Bootstrap::async_source_paths_,
                Bootstrap::async_patch_),
   INIT_LIBRARY(ObjectStore::kCollection,
                collection,
-               Bootstrap::collection_source_,
+               Bootstrap::collection_source_paths_,
                Bootstrap::collection_patch_),
   INIT_LIBRARY(ObjectStore::kCollectionDev,
                _collection-dev,
-               Bootstrap::collection_dev_source_,
+               Bootstrap::collection_dev_source_paths_,
                Bootstrap::collection_dev_patch_),
   INIT_LIBRARY(ObjectStore::kCrypto,
                crypto,
-               Bootstrap::crypto_source_,
+               Bootstrap::crypto_source_paths_,
                NULL),
   INIT_LIBRARY(ObjectStore::kIsolate,
                isolate,
-               Bootstrap::isolate_source_,
+               Bootstrap::isolate_source_paths_,
                Bootstrap::isolate_patch_),
   INIT_LIBRARY(ObjectStore::kJson,
                json,
-               Bootstrap::json_source_,
+               Bootstrap::json_source_paths_,
                Bootstrap::json_patch_),
   INIT_LIBRARY(ObjectStore::kMath,
                math,
-               Bootstrap::math_source_,
+               Bootstrap::math_source_paths_,
                Bootstrap::math_patch_),
   INIT_LIBRARY(ObjectStore::kMirrors,
                mirrors,
-               Bootstrap::mirrors_source_,
+               Bootstrap::mirrors_source_paths_,
                Bootstrap::mirrors_patch_),
   INIT_LIBRARY(ObjectStore::kTypedData,
                typed_data,
-               Bootstrap::typed_data_source_,
+               Bootstrap::typed_data_source_paths_,
                Bootstrap::typed_data_patch_),
   INIT_LIBRARY(ObjectStore::kUtf,
                utf,
-               Bootstrap::utf_source_,
+               Bootstrap::utf_source_paths_,
                NULL),
   INIT_LIBRARY(ObjectStore::kUri,
                uri,
-               Bootstrap::uri_source_,
+               Bootstrap::uri_source_paths_,
                NULL),
 
   { ObjectStore::kNone, NULL, NULL, NULL, NULL }
 };
 
 
-static RawString* GetLibrarySource(intptr_t index, bool patch) {
-  // TODO(asiva): Replace with actual read of the source file.
-  const char* source = patch ? bootstrap_libraries[index].patch_source_ :
-                               bootstrap_libraries[index].source_;
-  ASSERT(source != NULL);
-  return String::New(source, Heap::kOld);
+static RawString* GetLibrarySource(const Library& lib,
+                                   const String& uri,
+                                   bool patch) {
+  // First check if this is a valid boot strap library and find it's index
+  // in the 'bootstrap_libraries' table above.
+  intptr_t index = 0;
+  const String& lib_uri = String::Handle(lib.url());
+  while (bootstrap_libraries[index].index_ != ObjectStore::kNone) {
+    if (lib_uri.Equals(bootstrap_libraries[index].uri_)) {
+      break;
+    }
+    index += 1;
+  }
+  if (bootstrap_libraries[index].index_ == ObjectStore::kNone) {
+    return String::null();  // Library is not a boot strap library.
+  }
+
+  if (patch) {
+    // TODO(asiva): Replace with actual read of the source file.
+    const char* source = bootstrap_libraries[index].patch_source_;
+    ASSERT(source != NULL);
+    return String::New(source, Heap::kOld);
+  }
+
+  // Try to read the source using the path specified for the uri.
+  const char** source_paths = bootstrap_libraries[index].source_paths_;
+  if (source_paths == NULL) {
+    return String::null();  // No path mapping information exists for library.
+  }
+  intptr_t i = 0;
+  const char* source_path = NULL;
+  while (source_paths[i] != NULL) {
+    if (uri.Equals(source_paths[i])) {
+      source_path = source_paths[i + 1];
+      break;
+    }
+    i += 2;
+  }
+  if (source_path == NULL) {
+    return String::null();  // Uri does not exist in path mapping information.
+  }
+
+  Dart_FileOpenCallback file_open = Isolate::file_open_callback();
+  Dart_FileReadCallback file_read = Isolate::file_read_callback();
+  Dart_FileCloseCallback file_close = Isolate::file_close_callback();
+  if (file_open == NULL || file_read == NULL || file_close == NULL) {
+    return String::null();  // File operations are not supported.
+  }
+
+  void* stream = (*file_open)(source_path, false);
+  if (stream == NULL) {
+    return String::null();
+  }
+
+  const uint8_t* utf8_array = NULL;
+  intptr_t file_length = -1;
+  (*file_read)(&utf8_array, &file_length, stream);
+  if (file_length == -1) {
+    return String::null();
+  }
+  ASSERT(utf8_array != NULL);
+
+  (*file_close)(stream);
+
+  return String::FromUTF8(utf8_array, file_length);
+}
+
+
+static RawError* Compile(const Library& library, const Script& script) {
+  if (FLAG_print_bootstrap) {
+    OS::Print("Bootstrap source '%s':\n%s\n",
+              String::Handle(script.url()).ToCString(),
+              String::Handle(script.Source()).ToCString());
+  }
+  bool update_lib_status = (script.kind() == RawScript::kScriptTag ||
+                            script.kind() == RawScript::kLibraryTag);
+  if (update_lib_status) {
+    library.SetLoadInProgress();
+  }
+  const Error& error = Error::Handle(Compiler::Compile(library, script));
+  if (update_lib_status) {
+    if (error.IsNull()) {
+      library.SetLoaded();
+    } else {
+      library.SetLoadError();
+    }
+  }
+  return error.raw();
 }
 
 
 static Dart_Handle LoadPartSource(Isolate* isolate,
                                   const Library& lib,
                                   const String& uri) {
-  // TODO(asiva): For now we return an error here, once we start
-  // loading libraries from the real source this would have to call the
-  // file read callback here and invoke Compiler::Compile on it.
-  return Dart_NewApiError("Unable to load source '%s' ", uri.ToCString());
+  const String& part_source = String::Handle(
+      isolate, GetLibrarySource(lib, uri, false));
+  const String& lib_uri = String::Handle(isolate, lib.url());
+  if (part_source.IsNull()) {
+    return Dart_NewApiError("Unable to read part file '%s' of library '%s'",
+                            uri.ToCString(), lib_uri.ToCString());
+  }
+
+  // Prepend the library URI to form a unique script URI for the part.
+  const Array& strings = Array::Handle(isolate, Array::New(3));
+  strings.SetAt(0, lib_uri);
+  strings.SetAt(1, Symbols::Slash());
+  strings.SetAt(2, uri);
+  const String& part_uri = String::Handle(isolate, String::ConcatAll(strings));
+
+  // Create a script object and compile the part.
+  const Script& part_script = Script::Handle(
+      isolate, Script::New(part_uri, part_source, RawScript::kSourceTag));
+  const Error& error = Error::Handle(isolate, Compile(lib, part_script));
+  return Api::NewHandle(isolate, error.raw());
 }
 
 
@@ -114,18 +212,12 @@
   if (!Dart_IsString(uri)) {
     return Dart_NewApiError("uri is not a string");
   }
-  const String& uri_str = Api::UnwrapStringHandle(isolate, uri);
-  ASSERT(!uri_str.IsNull());
-  bool is_dart_scheme_uri = uri_str.StartsWith(Symbols::DartScheme());
-  if (!is_dart_scheme_uri) {
-    // The bootstrap tag handler can only handle dart scheme uris.
-    return Dart_NewApiError("Do not know how to load '%s' ",
-                            uri_str.ToCString());
-  }
   if (tag == kCanonicalizeUrl) {
-    // Dart Scheme URIs do not need any canonicalization.
+    // In the boot strap loader we do not try and do any canonicalization.
     return uri;
   }
+  const String& uri_str = Api::UnwrapStringHandle(isolate, uri);
+  ASSERT(!uri_str.IsNull());
   if (tag == kImportTag) {
     // We expect the core bootstrap libraries to only import other
     // core bootstrap libraries.
@@ -142,23 +234,6 @@
 }
 
 
-static RawError* Compile(const Library& library, const Script& script) {
-  if (FLAG_print_bootstrap) {
-    OS::Print("Bootstrap source '%s':\n%s\n",
-              String::Handle(script.url()).ToCString(),
-              String::Handle(script.Source()).ToCString());
-  }
-  library.SetLoadInProgress();
-  const Error& error = Error::Handle(Compiler::Compile(library, script));
-  if (error.IsNull()) {
-    library.SetLoaded();
-  } else {
-    library.SetLoadError();
-  }
-  return error.raw();
-}
-
-
 RawError* Bootstrap::LoadandCompileScripts() {
   Isolate* isolate = Isolate::Current();
   String& uri = String::Handle();
@@ -197,7 +272,13 @@
     uri = Symbols::New(bootstrap_libraries[i].uri_);
     lib = Library::LookupLibrary(uri);
     ASSERT(!lib.IsNull());
-    source = GetLibrarySource(i, false);
+    source = GetLibrarySource(lib, uri, false);
+    if (source.IsNull()) {
+      error ^= Api::UnwrapErrorHandle(
+          isolate, Api::NewError("Unable to find dart source for %s",
+                                 uri.ToCString())).raw();
+      break;
+    }
     script = Script::New(uri, source, RawScript::kLibraryTag);
     error = Compile(lib, script);
     if (!error.IsNull()) {
@@ -207,7 +288,13 @@
     if (bootstrap_libraries[i].patch_source_ != NULL) {
       patch_uri = String::New(bootstrap_libraries[i].patch_uri_,
                               Heap::kOld);
-      source = GetLibrarySource(i, true);
+      source = GetLibrarySource(lib, uri, true);
+      if (source.IsNull()) {
+        error ^= Api::UnwrapErrorHandle(
+            isolate, Api::NewError("Unable to find dart patch source for %s",
+                                   uri.ToCString())).raw();
+        break;
+      }
       script = Script::New(patch_uri, source, RawScript::kPatchTag);
       error = lib.Patch(script);
       if (!error.IsNull()) {
diff --git a/runtime/vm/bootstrap.h b/runtime/vm/bootstrap.h
index 025b90b..8c3ae55 100644
--- a/runtime/vm/bootstrap.h
+++ b/runtime/vm/bootstrap.h
@@ -17,27 +17,30 @@
   static RawError* LoadandCompileScripts();
   static void SetupNativeResolver();
 
-  static const char async_source_[];
+  // Source path mapping for library URI and 'parts'.
+  static const char* async_source_paths_[];
+  static const char* corelib_source_paths_[];
+  static const char* collection_source_paths_[];
+  static const char* collection_dev_source_paths_[];
+  static const char* crypto_source_paths_[];
+  static const char* isolate_source_paths_[];
+  static const char* json_source_paths_[];
+  static const char* math_source_paths_[];
+  static const char* mirrors_source_paths_[];
+  static const char* typed_data_source_paths_[];
+  static const char* uri_source_paths_[];
+  static const char* utf_source_paths_[];
+
+  // Patch sources for libaries (concatenated source).
   static const char async_patch_[];
-  static const char corelib_source_[];
   static const char corelib_patch_[];
-  static const char collection_source_[];
   static const char collection_patch_[];
-  static const char collection_dev_source_[];
   static const char collection_dev_patch_[];
-  static const char crypto_source_[];
-  static const char isolate_source_[];
   static const char isolate_patch_[];
-  static const char json_source_[];
   static const char json_patch_[];
-  static const char math_source_[];
   static const char math_patch_[];
-  static const char mirrors_source_[];
   static const char mirrors_patch_[];
-  static const char typed_data_source_[];
   static const char typed_data_patch_[];
-  static const char uri_source_[];
-  static const char utf_source_[];
 };
 
 }  // namespace dart
diff --git a/runtime/vm/bootstrap_natives.h b/runtime/vm/bootstrap_natives.h
index 0a460dd..651ce74 100644
--- a/runtime/vm/bootstrap_natives.h
+++ b/runtime/vm/bootstrap_natives.h
@@ -82,6 +82,8 @@
   V(StringBuffer_createStringFromUint16Array, 3)                               \
   V(OneByteString_substringUnchecked, 3)                                       \
   V(OneByteString_splitWithCharCode, 2)                                        \
+  V(OneByteString_allocate, 1)                                                 \
+  V(OneByteString_setAt, 3)                                                    \
   V(String_getHashCode, 1)                                                     \
   V(String_getLength, 1)                                                       \
   V(String_charAt, 2)                                                          \
diff --git a/runtime/vm/code_generator.cc b/runtime/vm/code_generator.cc
index 25ffdf1..fb9e846 100644
--- a/runtime/vm/code_generator.cc
+++ b/runtime/vm/code_generator.cc
@@ -1481,15 +1481,16 @@
       function.HasOptionalParameters() ? 0 : function.num_fixed_parameters();
   // FP, PC-marker and return-address will be copied as well.
   const intptr_t frame_copy_size =
-      1  // Deoptimized function's return address: caller_frame->pc().
+      // Deoptimized function's return address: caller_frame->pc().
+      - kPcSlotIndexFromSp
       + ((frame.fp() - frame.sp()) / kWordSize)
-      + 1  // PC marker.
-      + 1  // Caller return address.
+      + kLastParamSlotIndex
       + num_args;
   intptr_t* frame_copy = new intptr_t[frame_copy_size];
   ASSERT(frame_copy != NULL);
   // Include the return address of optimized code.
-  intptr_t* start = reinterpret_cast<intptr_t*>(frame.sp() - kWordSize);
+  intptr_t* start = reinterpret_cast<intptr_t*>(
+      frame.sp() + (kPcSlotIndexFromSp * kWordSize));
   for (intptr_t i = 0; i < frame_copy_size; i++) {
     frame_copy[i] = *(start + i);
   }
@@ -1506,6 +1507,8 @@
   HANDLESCOPE(isolate);
 
   // All registers have been saved below last-fp.
+  // Note that the deopt stub is not allowed to save any other values (pc
+  // marker, pool pointer, alignment, etc...) below last-fp.
   const uword last_fp = saved_registers_address +
                         kNumberOfCpuRegisters * kWordSize +
                         kNumberOfFpuRegisters * kFpuRegisterSize;
@@ -1518,7 +1521,6 @@
   const Code& optimized_code = Code::Handle(caller_frame->LookupDartCode());
   ASSERT(optimized_code.is_optimized());
 
-
   intptr_t deopt_reason = kDeoptUnknown;
   const DeoptInfo& deopt_info = DeoptInfo::Handle(
       optimized_code.GetDeoptInfoAtPc(caller_frame->pc(), &deopt_reason));
@@ -1544,13 +1546,12 @@
       function.HasOptionalParameters() ? 0 : function.num_fixed_parameters();
   intptr_t unoptimized_stack_size =
       + deopt_info.TranslationLength() - num_args
-      - 2;  // Subtract caller FP and PC.
+      - kLastParamSlotIndex;  // Subtract caller FP and PC (possibly pc marker).
   return unoptimized_stack_size * kWordSize;
 }
 END_LEAF_RUNTIME_ENTRY
 
 
-
 static intptr_t DeoptimizeWithDeoptInfo(const Code& code,
                                         const DeoptInfo& deopt_info,
                                         const StackFrame& caller_frame,
@@ -1561,14 +1562,15 @@
   ASSERT(!deopt_table.IsNull());
   deopt_info.ToInstructions(deopt_table, &deopt_instructions);
 
-  intptr_t* start = reinterpret_cast<intptr_t*>(caller_frame.sp() - kWordSize);
+  intptr_t* start = reinterpret_cast<intptr_t*>(
+      caller_frame.sp() + (kPcSlotIndexFromSp * kWordSize));
   const Function& function = Function::Handle(code.function());
   const intptr_t num_args =
       function.HasOptionalParameters() ? 0 : function.num_fixed_parameters();
-  intptr_t to_frame_size =
-      1  // Deoptimized function's return address.
+  const intptr_t to_frame_size =
+      - kPcSlotIndexFromSp  // Deoptimized function's return address.
       + (caller_frame.fp() - caller_frame.sp()) / kWordSize
-      + 3  // caller-fp, pc, pc-marker.
+      + kLastParamSlotIndex
       + num_args;
   DeoptimizationContext deopt_context(start,
                                       to_frame_size,
diff --git a/runtime/vm/code_patcher_arm.cc b/runtime/vm/code_patcher_arm.cc
index 8239239..7109795 100644
--- a/runtime/vm/code_patcher_arm.cc
+++ b/runtime/vm/code_patcher_arm.cc
@@ -39,7 +39,9 @@
 
 
 void CodePatcher::InsertCallAt(uword start, uword target) {
-  UNIMPLEMENTED();
+  // The inserted call should not overlap the lazy deopt jump code.
+  ASSERT(start + CallPattern::kFixedLengthInBytes <= target);
+  CallPattern::InsertAt(start, target);
 }
 
 
diff --git a/runtime/vm/code_patcher_ia32.cc b/runtime/vm/code_patcher_ia32.cc
index 2bd3f1b..c9ab14c 100644
--- a/runtime/vm/code_patcher_ia32.cc
+++ b/runtime/vm/code_patcher_ia32.cc
@@ -169,6 +169,8 @@
 
 
 void CodePatcher::InsertCallAt(uword start, uword target) {
+  // The inserted call should not overlap the lazy deopt jump code.
+  ASSERT(start + CallPattern::InstructionLength() <= target);
   *reinterpret_cast<uint8_t*>(start) = 0xE8;
   CallPattern call(start);
   call.SetTargetAddress(target);
diff --git a/runtime/vm/code_patcher_x64.cc b/runtime/vm/code_patcher_x64.cc
index 1f2cebe..337892d 100644
--- a/runtime/vm/code_patcher_x64.cc
+++ b/runtime/vm/code_patcher_x64.cc
@@ -173,6 +173,8 @@
 
 
 void CodePatcher::InsertCallAt(uword start, uword target) {
+  // The inserted call should not overlap the lazy deopt jump code.
+  ASSERT(start + ShortCallPattern::InstructionLength() <= target);
   *reinterpret_cast<uint8_t*>(start) = 0xE8;
   ShortCallPattern call(start);
   call.SetTargetAddress(target);
diff --git a/runtime/vm/constants_arm.h b/runtime/vm/constants_arm.h
index 2ad1903..6dc3034 100644
--- a/runtime/vm/constants_arm.h
+++ b/runtime/vm/constants_arm.h
@@ -182,11 +182,6 @@
 const int kDartVolatileFpuRegCount = 8;
 
 
-// Dart stack frame layout.
-static const int kLastParamSlotIndex = 3;
-static const int kFirstLocalSlotIndex = -2;
-
-
 // Values for the condition field as defined in section A3.2.
 enum Condition {
   kNoCondition = -1,
diff --git a/runtime/vm/constants_ia32.h b/runtime/vm/constants_ia32.h
index b6b1367..c679e12 100644
--- a/runtime/vm/constants_ia32.h
+++ b/runtime/vm/constants_ia32.h
@@ -75,11 +75,6 @@
 const Register kStackTraceObjectReg = EDX;
 
 
-// Dart stack frame layout.
-static const int kLastParamSlotIndex = 2;
-static const int kFirstLocalSlotIndex = -2;
-
-
 enum ScaleFactor {
   TIMES_1 = 0,
   TIMES_2 = 1,
diff --git a/runtime/vm/constants_mips.h b/runtime/vm/constants_mips.h
index 5859800..1748d0e 100644
--- a/runtime/vm/constants_mips.h
+++ b/runtime/vm/constants_mips.h
@@ -201,10 +201,6 @@
 const FRegister kDartLastVolatileFpuReg = F19;
 const int kDartVolatileFpuRegCount = 20;
 
-// Dart stack frame layout.
-static const int kLastParamSlotIndex = 3;
-static const int kFirstLocalSlotIndex = -2;
-
 
 // Values for the condition field.
 // There is no condition field on MIPS, but Conditions are used and passed
diff --git a/runtime/vm/constants_x64.h b/runtime/vm/constants_x64.h
index d3f5f9f..8cc827c 100644
--- a/runtime/vm/constants_x64.h
+++ b/runtime/vm/constants_x64.h
@@ -99,11 +99,6 @@
 const Register kStackTraceObjectReg = RDX;
 
 
-// Dart stack frame layout.
-static const int kLastParamSlotIndex = 2;
-static const int kFirstLocalSlotIndex = -2;
-
-
 enum ScaleFactor {
   TIMES_1 = 0,
   TIMES_2 = 1,
diff --git a/runtime/vm/dart.cc b/runtime/vm/dart.cc
index 1351152..6acff6c 100644
--- a/runtime/vm/dart.cc
+++ b/runtime/vm/dart.cc
@@ -80,13 +80,14 @@
                            Dart_IsolateUnhandledExceptionCallback unhandled,
                            Dart_IsolateShutdownCallback shutdown,
                            Dart_FileOpenCallback file_open,
+                           Dart_FileReadCallback file_read,
                            Dart_FileWriteCallback file_write,
                            Dart_FileCloseCallback file_close) {
   // TODO(iposva): Fix race condition here.
   if (vm_isolate_ != NULL || !Flags::Initialized()) {
     return "VM already initialized.";
   }
-  Isolate::SetFileCallbacks(file_open, file_write, file_close);
+  Isolate::SetFileCallbacks(file_open, file_read, file_write, file_close);
   OS::InitOnce();
   VirtualMemory::InitOnce();
   Isolate::InitOnce();
diff --git a/runtime/vm/dart.h b/runtime/vm/dart.h
index 090c4a1..61a7a7b 100644
--- a/runtime/vm/dart.h
+++ b/runtime/vm/dart.h
@@ -25,6 +25,7 @@
       Dart_IsolateUnhandledExceptionCallback unhandled,
       Dart_IsolateShutdownCallback shutdown,
       Dart_FileOpenCallback file_open,
+      Dart_FileReadCallback file_read,
       Dart_FileWriteCallback file_write,
       Dart_FileCloseCallback file_close);
 
diff --git a/runtime/vm/dart_api_impl.cc b/runtime/vm/dart_api_impl.cc
index be450c9..2757b83 100644
--- a/runtime/vm/dart_api_impl.cc
+++ b/runtime/vm/dart_api_impl.cc
@@ -745,10 +745,12 @@
     Dart_IsolateUnhandledExceptionCallback unhandled,
     Dart_IsolateShutdownCallback shutdown,
     Dart_FileOpenCallback file_open,
+    Dart_FileReadCallback file_read,
     Dart_FileWriteCallback file_write,
     Dart_FileCloseCallback file_close) {
   const char* err_msg = Dart::InitOnce(create, interrupt, unhandled, shutdown,
-                                       file_open, file_write, file_close);
+                                       file_open, file_read, file_write,
+                                       file_close);
   if (err_msg != NULL) {
     OS::PrintErr("Dart_Initialize: %s\n", err_msg);
     return false;
diff --git a/runtime/vm/deopt_instructions.cc b/runtime/vm/deopt_instructions.cc
index bbb7adc..fce3e71 100644
--- a/runtime/vm/deopt_instructions.cc
+++ b/runtime/vm/deopt_instructions.cc
@@ -9,6 +9,7 @@
 #include "vm/intermediate_language.h"
 #include "vm/locations.h"
 #include "vm/parser.h"
+#include "vm/stack_frame.h"
 
 namespace dart {
 
@@ -40,12 +41,12 @@
 
 
 intptr_t DeoptimizationContext::GetFromFp() const {
-  return from_frame_[from_frame_size_ - 1 - num_args_ - 1];
+  return from_frame_[from_frame_size_ - num_args_ - kLastParamSlotIndex];
 }
 
 
 intptr_t DeoptimizationContext::GetFromPc() const {
-  return from_frame_[from_frame_size_ - 1 - num_args_];
+  return from_frame_[from_frame_size_ - num_args_ + kPcSlotIndexFromSp];
 }
 
 intptr_t DeoptimizationContext::GetCallerFp() const {
diff --git a/runtime/vm/deopt_instructions.h b/runtime/vm/deopt_instructions.h
index 2f90ad8..0d41ffd 100644
--- a/runtime/vm/deopt_instructions.h
+++ b/runtime/vm/deopt_instructions.h
@@ -20,8 +20,8 @@
 class DeoptimizationContext : public ValueObject {
  public:
   // 'to_frame_start' points to the return address just below the frame's
-  // stack pointer. 'num_args' is 0 if there are no arguments or if there
-  // are optional arguments.
+  // stack pointer (kPcAddressOffsetFromSp). 'num_args' is 0 if there are no
+  // arguments or if there are optional arguments.
   DeoptimizationContext(intptr_t* to_frame_start,
                         intptr_t to_frame_size,
                         const Array& object_table,
diff --git a/runtime/vm/flow_graph_builder.cc b/runtime/vm/flow_graph_builder.cc
index a1d6e6b..e341f28 100644
--- a/runtime/vm/flow_graph_builder.cc
+++ b/runtime/vm/flow_graph_builder.cc
@@ -17,6 +17,7 @@
 #include "vm/os.h"
 #include "vm/parser.h"
 #include "vm/resolver.h"
+#include "vm/stack_frame.h"
 #include "vm/stub_code.h"
 #include "vm/symbols.h"
 
diff --git a/runtime/vm/flow_graph_compiler_arm.cc b/runtime/vm/flow_graph_compiler_arm.cc
index 3f0078a..e88a8f7 100644
--- a/runtime/vm/flow_graph_compiler_arm.cc
+++ b/runtime/vm/flow_graph_compiler_arm.cc
@@ -14,6 +14,7 @@
 #include "vm/locations.h"
 #include "vm/object_store.h"
 #include "vm/parser.h"
+#include "vm/stack_frame.h"
 #include "vm/stub_code.h"
 #include "vm/symbols.h"
 
@@ -1193,7 +1194,9 @@
   // lowest address.
   const intptr_t cpu_registers = locs->live_registers()->cpu_registers();
   ASSERT((cpu_registers & ~kAllCpuRegistersList) == 0);
-  __ PushList(cpu_registers);
+  if (cpu_registers != 0) {
+    __ PushList(cpu_registers);
+  }
 }
 
 
@@ -1202,7 +1205,9 @@
   // lowest address.
   const intptr_t cpu_registers = locs->live_registers()->cpu_registers();
   ASSERT((cpu_registers & ~kAllCpuRegistersList) == 0);
-  __ PopList(cpu_registers);
+  if (cpu_registers != 0) {
+    __ PopList(cpu_registers);
+  }
 
   const intptr_t fpu_registers = locs->live_registers()->fpu_registers();
   if (fpu_registers > 0) {
diff --git a/runtime/vm/flow_graph_compiler_ia32.cc b/runtime/vm/flow_graph_compiler_ia32.cc
index ac8423e..e609740 100644
--- a/runtime/vm/flow_graph_compiler_ia32.cc
+++ b/runtime/vm/flow_graph_compiler_ia32.cc
@@ -14,6 +14,7 @@
 #include "vm/locations.h"
 #include "vm/object_store.h"
 #include "vm/parser.h"
+#include "vm/stack_frame.h"
 #include "vm/stub_code.h"
 #include "vm/symbols.h"
 
diff --git a/runtime/vm/flow_graph_compiler_mips.cc b/runtime/vm/flow_graph_compiler_mips.cc
index 6451979..466846f 100644
--- a/runtime/vm/flow_graph_compiler_mips.cc
+++ b/runtime/vm/flow_graph_compiler_mips.cc
@@ -14,6 +14,7 @@
 #include "vm/locations.h"
 #include "vm/object_store.h"
 #include "vm/parser.h"
+#include "vm/stack_frame.h"
 #include "vm/stub_code.h"
 #include "vm/symbols.h"
 
diff --git a/runtime/vm/flow_graph_compiler_x64.cc b/runtime/vm/flow_graph_compiler_x64.cc
index ca8a7e0..400ab4e 100644
--- a/runtime/vm/flow_graph_compiler_x64.cc
+++ b/runtime/vm/flow_graph_compiler_x64.cc
@@ -14,6 +14,7 @@
 #include "vm/locations.h"
 #include "vm/object_store.h"
 #include "vm/parser.h"
+#include "vm/stack_frame.h"
 #include "vm/stub_code.h"
 #include "vm/symbols.h"
 
diff --git a/runtime/vm/gc_marker.cc b/runtime/vm/gc_marker.cc
index e15c532..509f422 100644
--- a/runtime/vm/gc_marker.cc
+++ b/runtime/vm/gc_marker.cc
@@ -175,6 +175,7 @@
     ASSERT(!raw_obj->IsMarked());
     RawClass* raw_class = isolate()->class_table()->At(raw_obj->GetClassId());
     raw_obj->SetMarkBit();
+    raw_obj->ClearRememberedBit();
     if (raw_obj->IsWatched()) {
       std::pair<DelaySet::iterator, DelaySet::iterator> ret;
       // Visit all elements with a key equal to raw_obj.
@@ -201,10 +202,11 @@
     // Skip over new objects, but verify consistency of heap while at it.
     if (raw_obj->IsNewObject()) {
       // TODO(iposva): Add consistency check.
-      if (visiting_old_object_ != NULL) {
+      if ((visiting_old_object_ != NULL) &&
+          !visiting_old_object_->IsRemembered()) {
         ASSERT(p != NULL);
-        isolate()->store_buffer()->AddPointer(
-            reinterpret_cast<uword>(visiting_old_object_));
+        visiting_old_object_->SetRememberedBit();
+        isolate()->store_buffer()->AddObjectGC(visiting_old_object_);
       }
       return;
     }
@@ -263,7 +265,6 @@
   }
   // The store buffers will be rebuilt as part of marking, reset them now.
   isolate->store_buffer()->Reset();
-  isolate->store_buffer_block()->Reset();
 }
 
 
diff --git a/runtime/vm/hash_set.h b/runtime/vm/hash_set.h
deleted file mode 100644
index 4c32c84..0000000
--- a/runtime/vm/hash_set.h
+++ /dev/null
@@ -1,103 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-#ifndef VM_HASH_SET_H_
-#define VM_HASH_SET_H_
-
-#include "vm/allocation.h"
-#include "platform/utils.h"
-
-namespace dart {
-
-class HashSet {
- public:
-  HashSet(intptr_t size, intptr_t fill_ratio)
-      : keys_(new uword[size]),
-        size_mask_(size - 1),
-        growth_limit_((size * fill_ratio) / 100),
-        count_(0),
-        fill_ratio_(fill_ratio) {
-    ASSERT(Utils::IsPowerOfTwo(size));
-    ASSERT(fill_ratio < 100);
-    memset(keys_, 0, size * sizeof(*keys_));
-  }
-
-  ~HashSet() {
-    delete[] keys_;
-  }
-
-  intptr_t Size() const {
-    return size_mask_ + 1;
-  }
-
-  intptr_t Count() const {
-    return count_;
-  }
-
-  uword At(intptr_t i) const {
-    ASSERT(i >= 0);
-    ASSERT(i < Size());
-    return keys_[i];
-  }
-
-  // Returns false if the caller should stop adding entries to this HashSet.
-  bool Add(uword value) {
-    ASSERT(value != 0);
-    ASSERT(count_ < growth_limit_);
-    intptr_t hash = Hash(value);
-    while (true) {
-      if (keys_[hash] == value) {
-        return true;
-      } else if (SlotIsEmpty(hash)) {
-        keys_[hash] = value;
-        count_++;
-        return (count_ < growth_limit_);
-      }
-      hash = (hash + 1) & size_mask_;
-      // Ensure that we do not end up looping forever.
-      ASSERT(hash != Hash(value));
-    }
-    UNREACHABLE();
-  }
-
-  bool Contains(uword value) const {
-    if (value == 0) {
-      return false;
-    }
-    intptr_t hash = Hash(value);
-    while (true) {
-      if (keys_[hash] == value) {
-        return true;
-      } else if (SlotIsEmpty(hash)) {
-        return false;
-      }
-      hash = (hash + 1) & size_mask_;
-      // Ensure that we do not end up looping forever.
-      ASSERT(hash != Hash(value));
-    }
-    UNREACHABLE();
-  }
-
- private:
-  intptr_t Hash(uword value) const {
-    return value & size_mask_;
-  }
-
-  // Returns true if the given slot does not contain a value.
-  bool SlotIsEmpty(intptr_t index) const {
-    return keys_[index] == 0;
-  }
-
-  uword* keys_;
-  intptr_t size_mask_;
-  intptr_t growth_limit_;
-  intptr_t count_;
-  intptr_t fill_ratio_;
-
-  DISALLOW_IMPLICIT_CONSTRUCTORS(HashSet);
-};
-
-}  // namespace dart
-
-#endif  // VM_HASH_SET_H_
diff --git a/runtime/vm/heap.cc b/runtime/vm/heap.cc
index d36c847..72e8c7b 100644
--- a/runtime/vm/heap.cc
+++ b/runtime/vm/heap.cc
@@ -321,7 +321,7 @@
   intptr_t len = OS::SNPrint(NULL, 0, format, isolate->name(), reason);
   char* filename = isolate->current_zone()->Alloc<char>(len + 1);
   OS::SNPrint(filename, len + 1, format, isolate->name(), reason);
-  void* file = (*file_open)(filename);
+  void* file = (*file_open)(filename, true);
   if (file != NULL) {
     Profile(file_write, file);
     (*file_close)(file);
diff --git a/runtime/vm/heap_profiler.cc b/runtime/vm/heap_profiler.cc
index 781ef5b..174a61a 100644
--- a/runtime/vm/heap_profiler.cc
+++ b/runtime/vm/heap_profiler.cc
@@ -30,6 +30,7 @@
     uint8_t* new_data = new uint8_t[new_capacity];
     memmove(new_data, data_, size_);
     capacity_ = new_capacity;
+    delete[] data_;
     data_ = new_data;
   }
 }
@@ -257,52 +258,40 @@
     case kTypedDataUint8ClampedArrayCid: {
       const RawTypedData* raw_int8_array =
           reinterpret_cast<const RawTypedData*>(raw_obj);
-      WritePrimitiveArrayDump(raw_int8_array,
-                              kByte,
-                              &raw_int8_array->data_[0]);
+      WritePrimitiveArrayDump(raw_int8_array, kByte);
       break;
     }
     case kTypedDataInt16ArrayCid:
     case kTypedDataUint16ArrayCid: {
       const RawTypedData* raw_int16_array =
           reinterpret_cast<const RawTypedData*>(raw_obj);
-      WritePrimitiveArrayDump(raw_int16_array,
-                              kShort,
-                              &raw_int16_array->data_[0]);
+      WritePrimitiveArrayDump(raw_int16_array, kShort);
       break;
     }
     case kTypedDataInt32ArrayCid:
     case kTypedDataUint32ArrayCid: {
       const RawTypedData* raw_int32_array =
           reinterpret_cast<const RawTypedData*>(raw_obj);
-      WritePrimitiveArrayDump(raw_int32_array,
-                              kInt,
-                              &raw_int32_array->data_[0]);
+      WritePrimitiveArrayDump(raw_int32_array, kInt);
       break;
     }
     case kTypedDataInt64ArrayCid:
     case kTypedDataUint64ArrayCid: {
       const RawTypedData* raw_int64_array =
           reinterpret_cast<const RawTypedData*>(raw_obj);
-      WritePrimitiveArrayDump(raw_int64_array,
-                              kLong,
-                              &raw_int64_array->data_[0]);
+      WritePrimitiveArrayDump(raw_int64_array, kLong);
       break;
     }
     case kTypedDataFloat32ArrayCid: {
       const RawTypedData* raw_float32_array =
           reinterpret_cast<const RawTypedData*>(raw_obj);
-      WritePrimitiveArrayDump(raw_float32_array,
-                              kFloat,
-                              &raw_float32_array->data_[0]);
+      WritePrimitiveArrayDump(raw_float32_array, kFloat);
       break;
     }
     case kTypedDataFloat64ArrayCid: {
       const RawTypedData* raw_float64_array =
           reinterpret_cast<const RawTypedData*>(raw_obj);
-      WritePrimitiveArrayDump(raw_float64_array,
-                              kDouble,
-                              &raw_float64_array->data_[0]);
+      WritePrimitiveArrayDump(raw_float64_array, kDouble);
       break;
     }
     case kOneByteStringCid:
@@ -752,8 +741,7 @@
 //  u1 - element type
 //  [u1]* - elements
 void HeapProfiler::WritePrimitiveArrayDump(const RawTypedData* raw_byte_array,
-                                           uint8_t tag,
-                                           const void* data) {
+                                           uint8_t tag) {
   SubRecord sub(kPrimitiveArrayDump, this);
   // array object ID
   sub.WriteObjectId(raw_byte_array);
@@ -761,6 +749,7 @@
   sub.Write32(0);
   // number of elements
   intptr_t length = Smi::Value(raw_byte_array->ptr()->length_);
+  const void* data = &(raw_byte_array->ptr()->data_[0]);
   sub.Write32(length);
   // element type
   sub.Write8(tag);
diff --git a/runtime/vm/heap_profiler.h b/runtime/vm/heap_profiler.h
index fa6369e..117b46f 100644
--- a/runtime/vm/heap_profiler.h
+++ b/runtime/vm/heap_profiler.h
@@ -266,9 +266,7 @@
   void WriteInstanceDump(const RawObject* raw_obj);
   void WriteSmiInstanceDump(const RawSmi* raw_smi);
   void WriteObjectArrayDump(const RawArray* raw_array);
-  void WritePrimitiveArrayDump(const RawTypedData* raw_byte_array,
-                               uint8_t tag,
-                               const void* data);
+  void WritePrimitiveArrayDump(const RawTypedData* raw_byte_array, uint8_t tag);
 
   static const RawClass* GetClass(const RawObject* raw_obj);
   static const RawClass* GetSuperClass(const RawClass* raw_class);
diff --git a/runtime/vm/instructions_arm.cc b/runtime/vm/instructions_arm.cc
index 96cab68..43f978b 100644
--- a/runtime/vm/instructions_arm.cc
+++ b/runtime/vm/instructions_arm.cc
@@ -149,24 +149,38 @@
 }
 
 
+void CallPattern::InsertAt(uword pc, uword target_address) {
+  uint16_t target_lo = target_address & 0xffff;
+  uint16_t target_hi = target_address >> 16;
+  uword movw_ip = 0xe300c000 | ((target_lo >> 12) << 16) | (target_lo & 0xfff);
+  uword movt_ip = 0xe340c000 | ((target_hi >> 12) << 16) | (target_hi & 0xfff);
+  uword blx_ip = 0xe12fff3c;
+  *reinterpret_cast<uword*>(pc + (0 * Instr::kInstrSize)) = movw_ip;
+  *reinterpret_cast<uword*>(pc + (1 * Instr::kInstrSize)) = movt_ip;
+  *reinterpret_cast<uword*>(pc + (2 * Instr::kInstrSize)) = blx_ip;
+  ASSERT(kFixedLengthInBytes == 3 * Instr::kInstrSize);
+  CPU::FlushICache(pc, kFixedLengthInBytes);
+}
+
+
 JumpPattern::JumpPattern(uword pc) : pc_(pc) { }
 
 
 bool JumpPattern::IsValid() const {
-  Instr* movw = Instr::At(pc_ + (0 * Instr::kInstrSize));  // movw ip, target_lo
-  Instr* movt = Instr::At(pc_ + (1 * Instr::kInstrSize));  // movw ip, target_lo
-  Instr* bxip = Instr::At(pc_ + (2 * Instr::kInstrSize));  // bx ip
-  return (movw->InstructionBits() & 0xfff0f000) == 0xe300c000 &&
-         (movt->InstructionBits() & 0xfff0f000) == 0xe340c000 &&
-         (bxip->InstructionBits() & 0xffffffff) == 0xe12fff1c;
+  Instr* movw_ip = Instr::At(pc_ + (0 * Instr::kInstrSize));  // target_lo
+  Instr* movt_ip = Instr::At(pc_ + (1 * Instr::kInstrSize));  // target_hi
+  Instr* bx_ip = Instr::At(pc_ + (2 * Instr::kInstrSize));
+  return (movw_ip->InstructionBits() & 0xfff0f000) == 0xe300c000 &&
+         (movt_ip->InstructionBits() & 0xfff0f000) == 0xe340c000 &&
+         (bx_ip->InstructionBits() & 0xffffffff) == 0xe12fff1c;
 }
 
 
 uword JumpPattern::TargetAddress() const {
-  Instr* movw = Instr::At(pc_ + (0 * Instr::kInstrSize));  // movw ip, target_lo
-  Instr* movt = Instr::At(pc_ + (1 * Instr::kInstrSize));  // movw ip, target_lo
-  uint16_t target_lo = movw->MovwField();
-  uint16_t target_hi = movt->MovwField();
+  Instr* movw_ip = Instr::At(pc_ + (0 * Instr::kInstrSize));  // target_lo
+  Instr* movt_ip = Instr::At(pc_ + (1 * Instr::kInstrSize));  // target_hi
+  uint16_t target_lo = movw_ip->MovwField();
+  uint16_t target_hi = movt_ip->MovwField();
   return (target_hi << 16) | target_lo;
 }
 
@@ -174,10 +188,10 @@
 void JumpPattern::SetTargetAddress(uword target_address) const {
   uint16_t target_lo = target_address & 0xffff;
   uint16_t target_hi = target_address >> 16;
-  uword movw = 0xe300c000 | ((target_lo >> 12) << 16) | (target_lo & 0xfff);
-  uword movt = 0xe340c000 | ((target_hi >> 12) << 16) | (target_hi & 0xfff);
-  *reinterpret_cast<uword*>(pc_ + (0 * Instr::kInstrSize)) = movw;
-  *reinterpret_cast<uword*>(pc_ + (1 * Instr::kInstrSize)) = movt;
+  uword movw_ip = 0xe300c000 | ((target_lo >> 12) << 16) | (target_lo & 0xfff);
+  uword movt_ip = 0xe340c000 | ((target_hi >> 12) << 16) | (target_hi & 0xfff);
+  *reinterpret_cast<uword*>(pc_ + (0 * Instr::kInstrSize)) = movw_ip;
+  *reinterpret_cast<uword*>(pc_ + (1 * Instr::kInstrSize)) = movt_ip;
   CPU::FlushICache(pc_, 2 * Instr::kInstrSize);
 }
 
diff --git a/runtime/vm/instructions_arm.h b/runtime/vm/instructions_arm.h
index 0fb176d..f54328a 100644
--- a/runtime/vm/instructions_arm.h
+++ b/runtime/vm/instructions_arm.h
@@ -25,6 +25,12 @@
   uword TargetAddress() const;
   void SetTargetAddress(uword target_address) const;
 
+  // This constant length is only valid for inserted call patterns used for
+  // lazy deoptimization. Regular call pattern may vary in length.
+  static const int kFixedLengthInBytes = 3 * Instr::kInstrSize;
+
+  static void InsertAt(uword pc, uword target_address);
+
  private:
   uword Back(int n) const;
   int DecodeLoadObject(int end, Register* reg, Object* obj);
diff --git a/runtime/vm/intermediate_language_arm.cc b/runtime/vm/intermediate_language_arm.cc
index 9361168..710c2be 100644
--- a/runtime/vm/intermediate_language_arm.cc
+++ b/runtime/vm/intermediate_language_arm.cc
@@ -14,6 +14,7 @@
 #include "vm/object_store.h"
 #include "vm/parser.h"
 #include "vm/simulator.h"
+#include "vm/stack_frame.h"
 #include "vm/stub_code.h"
 #include "vm/symbols.h"
 
@@ -83,13 +84,16 @@
   // has its own return instruction. Method that have finally are currently
   // not optimized.
   if (!compiler->HasFinally()) {
+    Label stack_ok;
     __ Comment("Stack Check");
     const intptr_t fp_sp_dist =
         (kFirstLocalSlotIndex + 1 - compiler->StackSize()) * kWordSize;
     ASSERT(fp_sp_dist <= 0);
     __ sub(R2, SP, ShifterOperand(FP));
     __ CompareImmediate(R2, fp_sp_dist);
-    __ bkpt(0, NE);
+    __ b(&stack_ok, EQ);
+    __ bkpt(0);
+    __ Bind(&stack_ok);
   }
 #endif
   __ LeaveDartFrame();
@@ -1032,8 +1036,32 @@
 
 Representation StoreIndexedInstr::RequiredInputRepresentation(
     intptr_t idx) const {
-  UNIMPLEMENTED();
-  return kTagged;
+  // Array can be a Dart object or a pointer to external data.
+  if (idx == 0)  return kNoRepresentation;  // Flexible input representation.
+  if (idx == 1) return kTagged;  // Index is a smi.
+  ASSERT(idx == 2);
+  switch (class_id_) {
+    case kArrayCid:
+    case kTypedDataInt8ArrayCid:
+    case kTypedDataUint8ArrayCid:
+    case kExternalTypedDataUint8ArrayCid:
+    case kTypedDataUint8ClampedArrayCid:
+    case kExternalTypedDataUint8ClampedArrayCid:
+    case kTypedDataInt16ArrayCid:
+    case kTypedDataUint16ArrayCid:
+      return kTagged;
+    case kTypedDataInt32ArrayCid:
+    case kTypedDataUint32ArrayCid:
+      return value()->IsSmiValue() ? kTagged : kUnboxedMint;
+    case kTypedDataFloat32ArrayCid:
+    case kTypedDataFloat64ArrayCid:
+      return kUnboxedDouble;
+    case kTypedDataFloat32x4ArrayCid:
+      return kUnboxedFloat32x4;
+    default:
+      UNIMPLEMENTED();
+      return kTagged;
+  }
 }
 
 
@@ -1058,14 +1086,22 @@
     case kTypedDataInt8ArrayCid:
     case kTypedDataUint8ArrayCid:
     case kTypedDataUint8ClampedArrayCid:
+      locs->set_in(2, Location::RegisterOrSmiConstant(value()));
+      break;
     case kTypedDataInt16ArrayCid:
     case kTypedDataUint16ArrayCid:
     case kTypedDataInt32ArrayCid:
     case kTypedDataUint32ArrayCid:
+      locs->set_in(2, Location::RequiresRegister());
+      break;
     case kTypedDataFloat32ArrayCid:
-    case kTypedDataFloat64ArrayCid:
+      // TODO(regis): Verify.
+      // Need temp register for float-to-double conversion.
+      locs->AddTemp(Location::RequiresFpuRegister());
+      // Fall through.
+    case kTypedDataFloat64ArrayCid:  // TODO(srdjan): Support Float64 constants.
     case kTypedDataFloat32x4ArrayCid:
-      UNIMPLEMENTED();
+      locs->set_in(2, Location::RequiresFpuRegister());
       break;
     default:
       UNREACHABLE();
@@ -1132,13 +1168,64 @@
       break;
     case kTypedDataInt8ArrayCid:
     case kTypedDataUint8ArrayCid:
-    case kExternalTypedDataUint8ArrayCid:
+    case kExternalTypedDataUint8ArrayCid: {
+      if (locs()->in(2).IsConstant()) {
+        const Smi& constant = Smi::Cast(locs()->in(2).constant());
+        __ LoadImmediate(IP, static_cast<int8_t>(constant.Value()));
+        __ strb(IP, element_address);
+      } else {
+        Register value = locs()->in(2).reg();
+        __ SmiUntag(value);
+        __ strb(value, element_address);
+      }
+      break;
+    }
     case kTypedDataUint8ClampedArrayCid:
-    case kExternalTypedDataUint8ClampedArrayCid:
+    case kExternalTypedDataUint8ClampedArrayCid: {
+      if (locs()->in(2).IsConstant()) {
+        const Smi& constant = Smi::Cast(locs()->in(2).constant());
+        intptr_t value = constant.Value();
+        // Clamp to 0x0 or 0xFF respectively.
+        if (value > 0xFF) {
+          value = 0xFF;
+        } else if (value < 0) {
+          value = 0;
+        }
+        __ LoadImmediate(IP, static_cast<int8_t>(value));
+        __ strb(IP, element_address);
+      } else {
+        Register value = locs()->in(2).reg();
+        Label store_value;
+        __ SmiUntag(value);
+        __ cmp(value, ShifterOperand(0xFF));
+        // Clamp to 0x00 or 0xFF respectively.
+        __ b(&store_value, LS);
+        __ mov(value, ShifterOperand(0x00), LE);
+        __ mov(value, ShifterOperand(0xFF), GT);
+        __ Bind(&store_value);
+        __ strb(value, element_address);
+      }
+      break;
+    }
     case kTypedDataInt16ArrayCid:
-    case kTypedDataUint16ArrayCid:
+    case kTypedDataUint16ArrayCid: {
+      Register value = locs()->in(2).reg();
+      __ SmiUntag(value);
+      __ strh(value, element_address);
+      break;
+    }
     case kTypedDataInt32ArrayCid:
-    case kTypedDataUint32ArrayCid:
+    case kTypedDataUint32ArrayCid: {
+      if (value()->IsSmiValue()) {
+        ASSERT(RequiredInputRepresentation(2) == kTagged);
+        Register value = locs()->in(2).reg();
+        __ SmiUntag(value);
+        __ str(value, element_address);
+      } else {
+        UNIMPLEMENTED();
+      }
+      break;
+    }
     case kTypedDataFloat32ArrayCid:
     case kTypedDataFloat64ArrayCid:
     case kTypedDataFloat32x4ArrayCid:
diff --git a/runtime/vm/intermediate_language_mips.cc b/runtime/vm/intermediate_language_mips.cc
index c3ffa5b..cee62a3 100644
--- a/runtime/vm/intermediate_language_mips.cc
+++ b/runtime/vm/intermediate_language_mips.cc
@@ -14,6 +14,7 @@
 #include "vm/object_store.h"
 #include "vm/parser.h"
 #include "vm/simulator.h"
+#include "vm/stack_frame.h"
 #include "vm/stub_code.h"
 #include "vm/symbols.h"
 
diff --git a/runtime/vm/intrinsifier.h b/runtime/vm/intrinsifier.h
index 04b60f4..4828657 100644
--- a/runtime/vm/intrinsifier.h
+++ b/runtime/vm/intrinsifier.h
@@ -83,6 +83,8 @@
   V(_OneByteString, get:hashCode, OneByteString_getHashCode, 682660413)        \
   V(_OneByteString, _substringUncheckedNative,                                 \
       OneByteString_substringUnchecked, 713121438)                             \
+  V(_OneByteString, _setAt, OneByteString_setAt, 342452817)                    \
+  V(_OneByteString, _allocate, OneByteString_allocate, 510754908)              \
 
 
 #define MATH_LIB_INTRINSIC_LIST(V)                                             \
diff --git a/runtime/vm/intrinsifier_arm.cc b/runtime/vm/intrinsifier_arm.cc
index ad286f7..d263973 100644
--- a/runtime/vm/intrinsifier_arm.cc
+++ b/runtime/vm/intrinsifier_arm.cc
@@ -345,6 +345,16 @@
   return false;
 }
 
+
+bool Intrinsifier::OneByteString_setAt(Assembler* assembler) {
+  return false;
+}
+
+
+bool Intrinsifier::OneByteString_allocate(Assembler* assembler) {
+  return false;
+}
+
 }  // namespace dart
 
 #endif  // defined TARGET_ARCH_ARM
diff --git a/runtime/vm/intrinsifier_ia32.cc b/runtime/vm/intrinsifier_ia32.cc
index 25632ee..097da1b 100644
--- a/runtime/vm/intrinsifier_ia32.cc
+++ b/runtime/vm/intrinsifier_ia32.cc
@@ -1572,15 +1572,19 @@
 
 
 // Allocates one-byte string of length 'end - start'. The content is not
-// initialized.
+// initialized. 'length-reg' contains tagged length.
+// Returns new string as tagged pointer in EAX.
 static void TryAllocateOnebyteString(Assembler* assembler,
+                                     Label* ok,
                                      Label* failure,
-                                     intptr_t start_index_offset,
-                                     intptr_t end_index_offset) {
-  __ movl(EDI, Address(ESP, + end_index_offset));
-  __ subl(EDI, Address(ESP, + start_index_offset));
-  const intptr_t fixed_size = sizeof(RawString) + kObjectAlignment - 1;
+                                     Register length_reg) {
+  if (length_reg != EDI) {
+    __ movl(EDI, length_reg);
+  }
+  Label pop_and_fail;
+  __ pushl(EDI);  // Preserve length.
   __ SmiUntag(EDI);
+  const intptr_t fixed_size = sizeof(RawString) + kObjectAlignment - 1;
   __ leal(EDI, Address(EDI, TIMES_1, fixed_size));  // EDI is a Smi.
   __ andl(EDI, Immediate(-kObjectAlignment));
 
@@ -1592,14 +1596,14 @@
 
   // EDI: allocation size.
   __ addl(EBX, EDI);
-  __ j(CARRY, failure);
+  __ j(CARRY, &pop_and_fail, Assembler::kNearJump);
 
   // Check if the allocation fits into the remaining space.
   // EAX: potential new object start.
   // EBX: potential next object start.
   // EDI: allocation size.
   __ cmpl(EBX, Address::Absolute(heap->EndAddress()));
-  __ j(ABOVE_EQUAL, failure);
+  __ j(ABOVE_EQUAL, &pop_and_fail, Assembler::kNearJump);
 
   // Successfully allocated the object(s), now update top to point to
   // next object start and initialize the object.
@@ -1629,13 +1633,17 @@
   }
 
   // Set the length field.
-  __ movl(EDI, Address(ESP, + end_index_offset));
-  __ subl(EDI, Address(ESP, + start_index_offset));  // Length.
+  __ popl(EDI);
   __ StoreIntoObjectNoBarrier(EAX,
                               FieldAddress(EAX, String::length_offset()),
                               EDI);
   // Clear hash.
   __ movl(FieldAddress(EAX, String::hash_offset()), Immediate(0));
+  __ jmp(ok, Assembler::kNearJump);
+
+  __ Bind(&pop_and_fail);
+  __ popl(EDI);
+  __ jmp(failure);
 }
 
 
@@ -1647,9 +1655,11 @@
   const intptr_t kStringOffset = 3 * kWordSize;
   const intptr_t kStartIndexOffset = 2 * kWordSize;
   const intptr_t kEndIndexOffset = 1 * kWordSize;
-  Label fall_through;
-  TryAllocateOnebyteString(
-      assembler, &fall_through, kStartIndexOffset, kEndIndexOffset);
+  Label fall_through, ok;
+  __ movl(EDI, Address(ESP, + kEndIndexOffset));
+  __ subl(EDI, Address(ESP, + kStartIndexOffset));
+  TryAllocateOnebyteString(assembler, &ok, &fall_through, EDI);
+  __ Bind(&ok);
   // EAX: new string as tagged pointer.
   // Copy string.
   __ movl(EDI, Address(ESP, + kStringOffset));
@@ -1681,6 +1691,32 @@
   return false;
 }
 
+
+bool Intrinsifier::OneByteString_setAt(Assembler* assembler) {
+  __ movl(ECX, Address(ESP, + 1 * kWordSize));  // Value.
+  __ movl(EBX, Address(ESP, + 2 * kWordSize));  // Index.
+  __ movl(EAX, Address(ESP, + 3 * kWordSize));  // OneByteString.
+  __ SmiUntag(EBX);
+  __ SmiUntag(ECX);
+  __ movb(FieldAddress(EAX, EBX, TIMES_1, OneByteString::data_offset()), CL);
+  __ ret();
+  return true;
+}
+
+
+bool Intrinsifier::OneByteString_allocate(Assembler* assembler) {
+  __ movl(EDI, Address(ESP, + 1 * kWordSize));  // Length.
+  Label fall_through, ok;
+  TryAllocateOnebyteString(assembler, &ok, &fall_through, EDI);
+  // EDI: Start address to copy from (untagged).
+
+  __ Bind(&ok);
+  __ ret();
+
+  __ Bind(&fall_through);
+  return false;
+}
+
 #undef __
 }  // namespace dart
 
diff --git a/runtime/vm/intrinsifier_mips.cc b/runtime/vm/intrinsifier_mips.cc
index f09c712..eaa50ef 100644
--- a/runtime/vm/intrinsifier_mips.cc
+++ b/runtime/vm/intrinsifier_mips.cc
@@ -345,6 +345,16 @@
   return false;
 }
 
+
+bool Intrinsifier::OneByteString_setAt(Assembler* assembler) {
+  return false;
+}
+
+
+bool Intrinsifier::OneByteString_allocate(Assembler* assembler) {
+  return false;
+}
+
 }  // namespace dart
 
 #endif  // defined TARGET_ARCH_MIPS
diff --git a/runtime/vm/intrinsifier_x64.cc b/runtime/vm/intrinsifier_x64.cc
index cbb5e49..c9befeb 100644
--- a/runtime/vm/intrinsifier_x64.cc
+++ b/runtime/vm/intrinsifier_x64.cc
@@ -1488,15 +1488,19 @@
 
 
 // Allocates one-byte string of length 'end - start'. The content is not
-// initialized.
+// initialized. 'length-reg' contains tagged length.
+// Returns new string as tagged pointer in EAX.
 static void TryAllocateOnebyteString(Assembler* assembler,
+                                     Label* ok,
                                      Label* failure,
-                                     intptr_t start_index_offset,
-                                     intptr_t end_index_offset) {
-  __ movq(RDI, Address(RSP, + end_index_offset));
-  __ subq(RDI, Address(RSP, + start_index_offset));
-  const intptr_t fixed_size = sizeof(RawString) + kObjectAlignment - 1;
+                                     Register length_reg) {
+  if (length_reg != RDI) {
+    __ movq(RDI, length_reg);
+  }
+  Label pop_and_fail;
+  __ pushq(RDI);  // Preserve length.
   __ SmiUntag(RDI);
+  const intptr_t fixed_size = sizeof(RawString) + kObjectAlignment - 1;
   __ leaq(RDI, Address(RDI, TIMES_1, fixed_size));  // RDI is a Smi.
   __ andq(RDI, Immediate(-kObjectAlignment));
 
@@ -1509,7 +1513,7 @@
   // RDI: allocation size.
   __ movq(RCX, RAX);
   __ addq(RCX, RDI);
-  __ j(CARRY, failure);
+  __ j(CARRY,  &pop_and_fail);
 
   // Check if the allocation fits into the remaining space.
   // RAX: potential new object start.
@@ -1517,7 +1521,7 @@
   // RDI: allocation size.
   __ movq(R13, Immediate(heap->EndAddress()));
   __ cmpq(RCX, Address(R13, 0));
-  __ j(ABOVE_EQUAL, failure);
+  __ j(ABOVE_EQUAL, &pop_and_fail);
 
   // Successfully allocated the object(s), now update top to point to
   // next object start and initialize the object.
@@ -1547,13 +1551,17 @@
   }
 
   // Set the length field.
-  __ movq(RDI, Address(RSP, + end_index_offset));
-  __ subq(RDI, Address(RSP, + start_index_offset));  // Length.
+  __ popq(RDI);
   __ StoreIntoObjectNoBarrier(RAX,
                               FieldAddress(RAX, String::length_offset()),
                               RDI);
   // Clear hash.
   __ movq(FieldAddress(RAX, String::hash_offset()), Immediate(0));
+  __ jmp(ok, Assembler::kNearJump);
+
+  __ Bind(&pop_and_fail);
+  __ popq(RDI);
+  __ jmp(failure);
 }
 
 
@@ -1565,9 +1573,11 @@
   const intptr_t kStringOffset = 3 * kWordSize;
   const intptr_t kStartIndexOffset = 2 * kWordSize;
   const intptr_t kEndIndexOffset = 1 * kWordSize;
-  Label fall_through;
-  TryAllocateOnebyteString(
-      assembler, &fall_through, kStartIndexOffset, kEndIndexOffset);
+  Label fall_through, ok;
+  __ movq(RDI, Address(RSP, + kEndIndexOffset));
+  __ subq(RDI, Address(RSP, + kStartIndexOffset));
+  TryAllocateOnebyteString(assembler, &ok, &fall_through, RDI);
+  __ Bind(&ok);
   // RAX: new string as tagged pointer.
   // Copy string.
   __ movq(RSI, Address(RSP, + kStringOffset));
@@ -1600,6 +1610,32 @@
 }
 
 
+bool Intrinsifier::OneByteString_setAt(Assembler* assembler) {
+  __ movq(RCX, Address(RSP, + 1 * kWordSize));  // Value.
+  __ movq(RBX, Address(RSP, + 2 * kWordSize));  // Index.
+  __ movq(RAX, Address(RSP, + 3 * kWordSize));  // OneByteString.
+  __ SmiUntag(RBX);
+  __ SmiUntag(RCX);
+  __ movb(FieldAddress(RAX, RBX, TIMES_1, OneByteString::data_offset()), RCX);
+  __ ret();
+  return true;
+}
+
+
+bool Intrinsifier::OneByteString_allocate(Assembler* assembler) {
+  __ movq(RDI, Address(RSP, + 1 * kWordSize));  // Length.v=
+  Label fall_through, ok;
+  TryAllocateOnebyteString(assembler, &ok, &fall_through, RDI);
+  // EDI: Start address to copy from (untagged).
+
+  __ Bind(&ok);
+  __ ret();
+
+  __ Bind(&fall_through);
+  return false;
+}
+
+
 #undef __
 
 }  // namespace dart
diff --git a/runtime/vm/isolate.cc b/runtime/vm/isolate.cc
index 72f386e..473f001 100644
--- a/runtime/vm/isolate.cc
+++ b/runtime/vm/isolate.cc
@@ -312,8 +312,7 @@
 
 
 Isolate::Isolate()
-    : store_buffer_block_(),
-      store_buffer_(),
+    : store_buffer_(),
       message_notify_callback_(NULL),
       name_(NULL),
       start_time_(OS::GetCurrentTimeMicros()),
@@ -741,6 +740,7 @@
     Isolate::unhandled_exception_callback_ = NULL;
 Dart_IsolateShutdownCallback Isolate::shutdown_callback_ = NULL;
 Dart_FileOpenCallback Isolate::file_open_callback_ = NULL;
+Dart_FileReadCallback Isolate::file_read_callback_ = NULL;
 Dart_FileWriteCallback Isolate::file_write_callback_ = NULL;
 Dart_FileCloseCallback Isolate::file_close_callback_ = NULL;
 Dart_IsolateInterruptCallback Isolate::vmstats_callback_ = NULL;
diff --git a/runtime/vm/isolate.h b/runtime/vm/isolate.h
index 99f3f3b..c87b56d 100644
--- a/runtime/vm/isolate.h
+++ b/runtime/vm/isolate.h
@@ -158,12 +158,10 @@
   void VisitWeakPersistentHandles(HandleVisitor* visit,
                                   bool visit_prologue_weak_persistent_handles);
 
-  StoreBufferBlock* store_buffer_block() { return &store_buffer_block_; }
-  static intptr_t store_buffer_block_offset() {
-    return OFFSET_OF(Isolate, store_buffer_block_);
-  }
-
   StoreBuffer* store_buffer() { return &store_buffer_; }
+  static intptr_t store_buffer_offset() {
+    return OFFSET_OF(Isolate, store_buffer_);
+  }
 
   ClassTable* class_table() { return &class_table_; }
   static intptr_t class_table_offset() {
@@ -381,9 +379,11 @@
   }
 
   static void SetFileCallbacks(Dart_FileOpenCallback file_open,
+                               Dart_FileReadCallback file_read,
                                Dart_FileWriteCallback file_write,
                                Dart_FileCloseCallback file_close) {
     file_open_callback_ = file_open;
+    file_read_callback_ = file_read;
     file_write_callback_ = file_write;
     file_close_callback_ = file_close;
   }
@@ -391,6 +391,9 @@
   static Dart_FileOpenCallback file_open_callback() {
     return file_open_callback_;
   }
+  static Dart_FileReadCallback file_read_callback() {
+    return file_read_callback_;
+  }
   static Dart_FileWriteCallback file_write_callback() {
     return file_write_callback_;
   }
@@ -472,7 +475,6 @@
   char* DoStacktraceInterrupt(Dart_IsolateInterruptCallback cb);
 
   static ThreadLocalKey isolate_key;
-  StoreBufferBlock store_buffer_block_;
   StoreBuffer store_buffer_;
   ClassTable class_table_;
   MegamorphicCacheTable megamorphic_cache_table_;
@@ -520,6 +522,7 @@
   static Dart_IsolateUnhandledExceptionCallback unhandled_exception_callback_;
   static Dart_IsolateShutdownCallback shutdown_callback_;
   static Dart_FileOpenCallback file_open_callback_;
+  static Dart_FileReadCallback file_read_callback_;
   static Dart_FileWriteCallback file_write_callback_;
   static Dart_FileCloseCallback file_close_callback_;
   static Dart_IsolateInterruptCallback vmstats_callback_;
diff --git a/runtime/vm/locations.cc b/runtime/vm/locations.cc
index 1f8e01b..e1a86bc 100644
--- a/runtime/vm/locations.cc
+++ b/runtime/vm/locations.cc
@@ -8,6 +8,7 @@
 #include "vm/il_printer.h"
 #include "vm/intermediate_language.h"
 #include "vm/flow_graph_compiler.h"
+#include "vm/stack_frame.h"
 
 namespace dart {
 
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index a222421..aa85a51 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -1224,8 +1224,8 @@
     for (RawObject** curr = first; curr <= last; ++curr) {
       RawObject* raw_obj = *curr;
       if (raw_obj->IsHeapObject() && raw_obj->IsNewObject()) {
-        uword ptr = reinterpret_cast<uword>(old_obj_);
-        isolate()->store_buffer()->AddPointer(ptr);
+        old_obj_->SetRememberedBit();
+        isolate()->store_buffer()->AddObject(old_obj_);
         // Remembered this object. There is no need to continue searching.
         return;
       }
@@ -1256,7 +1256,7 @@
   RawObject* raw_obj = Object::Allocate(cls.id(), size, space);
   NoGCScope no_gc;
   memmove(raw_obj->ptr(), src.raw()->ptr(), size);
-  if (space == Heap::kOld) {
+  if ((space == Heap::kOld) && !raw_obj->IsRemembered()) {
     StoreBufferUpdateVisitor visitor(Isolate::Current(), raw_obj);
     raw_obj->VisitPointers(&visitor);
   }
diff --git a/runtime/vm/object.h b/runtime/vm/object.h
index fb7f5d1..19802e7 100644
--- a/runtime/vm/object.h
+++ b/runtime/vm/object.h
@@ -440,9 +440,10 @@
     *addr = value;
     // Filter stores based on source and target.
     if (!value->IsHeapObject()) return;
-    if (value->IsNewObject() && raw()->IsOldObject()) {
-      uword ptr = reinterpret_cast<uword>(raw());
-      Isolate::Current()->store_buffer()->AddPointer(ptr);
+    if (value->IsNewObject() && raw()->IsOldObject() &&
+        !raw()->IsRemembered()) {
+      raw()->SetRememberedBit();
+      Isolate::Current()->store_buffer()->AddObject(raw());
     }
   }
 
@@ -4421,6 +4422,9 @@
     return *CharAddr(str, index);
   }
 
+  static void SetCharAt(const String& str, intptr_t index, uint8_t code_point) {
+    *CharAddr(str, index) = code_point;
+  }
   static RawOneByteString* EscapeSpecialCharacters(const String& str);
 
   // We use the same maximum elements for all strings.
@@ -4973,9 +4977,10 @@
     *addr = value;
     // Filter stores based on source and target.
     if (!value->IsHeapObject()) return;
-    if (value->IsNewObject() && data()->IsOldObject()) {
-      uword ptr = reinterpret_cast<uword>(data());
-      Isolate::Current()->store_buffer()->AddPointer(ptr);
+    if (value->IsNewObject() && data()->IsOldObject() &&
+        !data()->IsRemembered()) {
+      data()->SetRememberedBit();
+      Isolate::Current()->store_buffer()->AddObject(data());
     }
   }
 
diff --git a/runtime/vm/os_android.cc b/runtime/vm/os_android.cc
index 2fbc169..ec6413d 100644
--- a/runtime/vm/os_android.cc
+++ b/runtime/vm/os_android.cc
@@ -50,7 +50,7 @@
     intptr_t len = OS::SNPrint(NULL, 0, format, pid);
     char* filename = new char[len + 1];
     OS::SNPrint(filename, len + 1, format, pid);
-    out_file_ = (*file_open)(filename);
+    out_file_ = (*file_open)(filename, true);
   }
 
   ~PerfCodeObserver() {
@@ -111,7 +111,7 @@
       return;
     }
     const char* filename = FLAG_generate_pprof_symbols;
-    void* out_file = (*file_open)(filename);
+    void* out_file = (*file_open)(filename, true);
     ASSERT(out_file != NULL);
     DebugInfo::ByteBuffer* debug_region = new DebugInfo::ByteBuffer();
     ASSERT(debug_region != NULL);
diff --git a/runtime/vm/os_linux.cc b/runtime/vm/os_linux.cc
index 5e7356f..d6ddd80 100644
--- a/runtime/vm/os_linux.cc
+++ b/runtime/vm/os_linux.cc
@@ -46,7 +46,7 @@
       return;
     }
     const char* filename = "v8.log.ll";
-    log_file_ = (*file_open)(filename);
+    log_file_ = (*file_open)(filename, true);
 #if defined(TARGET_ARCH_IA32)
     const char arch[] = "ia32";
 #elif defined(TARGET_ARCH_X64)
@@ -134,7 +134,7 @@
     intptr_t len = OS::SNPrint(NULL, 0, format, pid);
     char* filename = new char[len + 1];
     OS::SNPrint(filename, len + 1, format, pid);
-    out_file_ = (*file_open)(filename);
+    out_file_ = (*file_open)(filename, true);
   }
 
   ~PerfCodeObserver() {
@@ -195,7 +195,7 @@
       return;
     }
     const char* filename = FLAG_generate_pprof_symbols;
-    void* out_file = (*file_open)(filename);
+    void* out_file = (*file_open)(filename, true);
     ASSERT(out_file != NULL);
     DebugInfo::ByteBuffer* debug_region = new DebugInfo::ByteBuffer();
     ASSERT(debug_region != NULL);
diff --git a/runtime/vm/parser.cc b/runtime/vm/parser.cc
index 10adced..59f6faa 100644
--- a/runtime/vm/parser.cc
+++ b/runtime/vm/parser.cc
@@ -19,6 +19,7 @@
 #include "vm/object_store.h"
 #include "vm/resolver.h"
 #include "vm/scopes.h"
+#include "vm/stack_frame.h"
 #include "vm/symbols.h"
 
 namespace dart {
diff --git a/runtime/vm/raw_object.h b/runtime/vm/raw_object.h
index e4bf736..6f8db77 100644
--- a/runtime/vm/raw_object.h
+++ b/runtime/vm/raw_object.h
@@ -223,8 +223,9 @@
     kMarkBit = 1,
     kCanonicalBit = 2,
     kFromSnapshotBit = 3,
-    kReservedTagBit = 4,  // kReservedBit{1K, 10K,100K,1M,10M}
-    kReservedTagSize = 4,
+    kRememberedBit = 4,
+    kReservedTagBit = 5,  // kReservedBit{10K,100K,1M,10M}
+    kReservedTagSize = 3,
     kSizeTagBit = 8,
     kSizeTagSize = 8,
     kClassIdTagBit = kSizeTagBit + kSizeTagSize,
@@ -329,6 +330,20 @@
     ptr()->tags_ = CreatedFromSnapshotTag::update(true, tags);
   }
 
+  // Support for GC remembered bit.
+  bool IsRemembered() const {
+    return RememberedBit::decode(ptr()->tags_);
+  }
+  void SetRememberedBit() {
+    ASSERT(!IsRemembered());
+    uword tags = ptr()->tags_;
+    ptr()->tags_ = RememberedBit::update(true, tags);
+  }
+  void ClearRememberedBit() {
+    uword tags = ptr()->tags_;
+    ptr()->tags_ = RememberedBit::update(false, tags);
+  }
+
   bool IsDartInstance() {
     return (!IsHeapObject() || (GetClassId() >= kInstanceCid));
   }
@@ -389,6 +404,8 @@
 
   class MarkBit : public BitField<bool, kMarkBit, 1> {};
 
+  class RememberedBit : public BitField<bool, kRememberedBit, 1> {};
+
   class CanonicalObjectTag : public BitField<bool, kCanonicalBit, 1> {};
 
   class CreatedFromSnapshotTag : public BitField<bool, kFromSnapshotBit, 1> {};
diff --git a/runtime/vm/scavenger.cc b/runtime/vm/scavenger.cc
index d58a091..81aae4d 100644
--- a/runtime/vm/scavenger.cc
+++ b/runtime/vm/scavenger.cc
@@ -121,9 +121,11 @@
     ASSERT(!heap_->CodeContains(ptr));
     ASSERT(heap_->Contains(ptr));
     // If the newly written object is not a new object, drop it immediately.
-    if (!obj->IsNewObject()) return;
-    isolate()->store_buffer()->AddPointer(
-        reinterpret_cast<uword>(visiting_old_object_));
+    if (!obj->IsNewObject() || visiting_old_object_->IsRemembered()) {
+      return;
+    }
+    visiting_old_object_->SetRememberedBit();
+    isolate()->store_buffer()->AddObjectGC(visiting_old_object_);
   }
 
   void ScavengePointer(RawObject** p) {
@@ -374,36 +376,23 @@
 
 void Scavenger::IterateStoreBuffers(Isolate* isolate,
                                     ScavengerVisitor* visitor) {
-  // Drain store buffer block into store buffer to deduplicate it. It might be
-  // full of large objects repeated multiple times.
-  // Use DrainBlock directly instead of ProcessBlock because we are in the
-  // middle of a scavenge cycle and thus do not care if we are temporary
-  // running over the max number of deduplication sets.
-  StoreBufferBlock* block = isolate->store_buffer_block();
-  heap_->RecordData(kStoreBufferBlockEntries, block->Count());
-  isolate->store_buffer()->DrainBlock(block);
+  StoreBuffer* buffer = isolate->store_buffer();
+  heap_->RecordData(kStoreBufferBlockEntries, buffer->Count());
 
   // Iterating through the store buffers.
   // Grab the deduplication sets out of the store buffer.
-  StoreBuffer::DedupSet* pending = isolate->store_buffer()->DedupSets();
+  StoreBufferBlock* pending = isolate->store_buffer()->Blocks();
   intptr_t entries = 0;
   while (pending != NULL) {
-    StoreBuffer::DedupSet* next = pending->next();
-    HashSet* set = pending->set();
-    intptr_t count = set->Count();
-    intptr_t size = set->Size();
-    intptr_t handled = 0;
+    StoreBufferBlock* next = pending->next();
+    intptr_t count = pending->Count();
     entries += count;
-    for (intptr_t i = 0; i < size; i++) {
-      RawObject* raw_object = reinterpret_cast<RawObject*>(set->At(i));
-      if (raw_object != NULL) {
-        visitor->VisitingOldObject(raw_object);
-        raw_object->VisitPointers(visitor);
-        handled++;
-        if (handled == count) {
-          break;
-        }
-      }
+    for (intptr_t i = 0; i < count; i++) {
+      RawObject* raw_object = pending->At(i);
+      ASSERT(raw_object->IsRemembered());
+      raw_object->ClearRememberedBit();
+      visitor->VisitingOldObject(raw_object);
+      raw_object->VisitPointers(visitor);
     }
     delete pending;
     pending = next;
@@ -534,6 +523,7 @@
         // Resolve or copy all objects referred to by the current object. This
         // can potentially push more objects on this stack as well as add more
         // objects to be resolved in the to space.
+        ASSERT(!raw_object->IsRemembered());
         visitor->VisitingOldObject(raw_object);
         raw_object->VisitPointers(visitor);
       }
diff --git a/runtime/vm/scopes.cc b/runtime/vm/scopes.cc
index ebd35f6..c71fa16 100644
--- a/runtime/vm/scopes.cc
+++ b/runtime/vm/scopes.cc
@@ -8,6 +8,7 @@
 #include "vm/bit_vector.h"
 #include "vm/object.h"
 #include "vm/parser.h"
+#include "vm/stack_frame.h"
 #include "vm/symbols.h"
 
 namespace dart {
diff --git a/runtime/vm/stack_frame.h b/runtime/vm/stack_frame.h
index 5e5290d..b7a53f1 100644
--- a/runtime/vm/stack_frame.h
+++ b/runtime/vm/stack_frame.h
@@ -9,6 +9,18 @@
 #include "vm/object.h"
 #include "vm/stub_code.h"
 
+#if defined(TARGET_ARCH_IA32)
+#include "vm/stack_frame_ia32.h"
+#elif defined(TARGET_ARCH_X64)
+#include "vm/stack_frame_x64.h"
+#elif defined(TARGET_ARCH_ARM)
+#include "vm/stack_frame_arm.h"
+#elif defined(TARGET_ARCH_MIPS)
+#include "vm/stack_frame_mips.h"
+#else
+#error Unknown architecture.
+#endif
+
 namespace dart {
 
 // Forward declarations.
@@ -272,3 +284,4 @@
 }  // namespace dart
 
 #endif  // VM_STACK_FRAME_H_
+
diff --git a/runtime/vm/stack_frame_arm.h b/runtime/vm/stack_frame_arm.h
new file mode 100644
index 0000000..433830f
--- /dev/null
+++ b/runtime/vm/stack_frame_arm.h
@@ -0,0 +1,35 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+#ifndef VM_STACK_FRAME_ARM_H_
+#define VM_STACK_FRAME_ARM_H_
+
+namespace dart {
+
+/* ARM Dart Frame Layout
+
+               |                   | <- TOS
+Callee frame   | ...               |
+               | current LR        |    (PC of current frame)
+               | PC Marker         |    (callee's frame code entry)
+               +-------------------+
+Current frame  | ...               | <- SP of current frame
+               | first local       |
+               | caller's PP       |
+               | caller's FP       | <- FP of current frame
+               | caller's LR       |    (PC of caller frame)
+               | PC Marker         |    (current frame's code entry)
+               +-------------------+
+Caller frame   | last parameter    |
+               |  ...              |
+*/
+
+static const int kLastParamSlotIndex = 3;  // From fp.
+static const int kFirstLocalSlotIndex = -2;  // From fp.
+static const int kPcSlotIndexFromSp = -2;
+
+}  // namespace dart
+
+#endif  // VM_STACK_FRAME_ARM_H_
+
diff --git a/runtime/vm/stack_frame_ia32.h b/runtime/vm/stack_frame_ia32.h
new file mode 100644
index 0000000..46bdfd5
--- /dev/null
+++ b/runtime/vm/stack_frame_ia32.h
@@ -0,0 +1,33 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+#ifndef VM_STACK_FRAME_IA32_H_
+#define VM_STACK_FRAME_IA32_H_
+
+namespace dart {
+
+/* IA32 Dart Frame Layout
+
+               |                   | <- TOS
+Callee frame   | ...               |
+               | current ret addr  |    (PC of current frame)
+               +-------------------+
+Current frame  | ...               | <- ESP of current frame
+               | first local       |
+               | PC Marker         |    (current frame's code entry)
+               | caller's EBP      | <- EBP of current frame
+               | caller's ret addr |    (PC of caller frame)
+               +-------------------+
+Caller frame   | last parameter    |
+               |  ...              |
+*/
+
+static const int kLastParamSlotIndex = 2;  // From fp.
+static const int kFirstLocalSlotIndex = -2;  // From fp.
+static const int kPcSlotIndexFromSp = -1;
+
+}  // namespace dart
+
+#endif  // VM_STACK_FRAME_IA32_H_
+
diff --git a/runtime/vm/stack_frame_mips.h b/runtime/vm/stack_frame_mips.h
new file mode 100644
index 0000000..8a32a38
--- /dev/null
+++ b/runtime/vm/stack_frame_mips.h
@@ -0,0 +1,35 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+#ifndef VM_STACK_FRAME_MIPS_H_
+#define VM_STACK_FRAME_MIPS_H_
+
+namespace dart {
+
+/* MIPS Dart Frame Layout
+
+               |                   | <- TOS
+Callee frame   | ...               |
+               | current RA        |    (PC of current frame)
+               | PC Marker         |    (callee's frame code entry)
+               +-------------------+
+Current frame  | ...               | <- SP of current frame
+               | first local       |
+               | caller's PP       |
+               | caller's FP       | <- FP of current frame
+               | caller's RA       |    (PC of caller frame)
+               | PC Marker         |    (current frame's code entry)
+               +-------------------+
+Caller frame   | last parameter    |
+               |  ...              |
+*/
+
+static const int kLastParamSlotIndex = 3;  // From fp.
+static const int kFirstLocalSlotIndex = -2;  // From fp.
+static const int kPcSlotIndexFromSp = -2;
+
+}  // namespace dart
+
+#endif  // VM_STACK_FRAME_MIPS_H_
+
diff --git a/runtime/vm/stack_frame_x64.h b/runtime/vm/stack_frame_x64.h
new file mode 100644
index 0000000..084cd9e
--- /dev/null
+++ b/runtime/vm/stack_frame_x64.h
@@ -0,0 +1,33 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+#ifndef VM_STACK_FRAME_X64_H_
+#define VM_STACK_FRAME_X64_H_
+
+namespace dart {
+
+/* X64 Dart Frame Layout
+
+               |                   | <- TOS
+Callee frame   | ...               |
+               | current ret addr  |    (PC of current frame)
+               +-------------------+
+Current frame  | ...               | <- RSP of current frame
+               | first local       |
+               | PC Marker         |    (current frame's code entry)
+               | caller's RBP      | <- RBP of current frame
+               | caller's ret addr |    (PC of caller frame)
+               +-------------------+
+Caller frame   | last parameter    |
+               |  ...              |
+*/
+
+static const int kLastParamSlotIndex = 2;  // From fp.
+static const int kFirstLocalSlotIndex = -2;  // From fp.
+static const int kPcSlotIndexFromSp = -1;
+
+}  // namespace dart
+
+#endif  // VM_STACK_FRAME_X64_H_
+
diff --git a/runtime/vm/store_buffer.cc b/runtime/vm/store_buffer.cc
index d07728a..b5f39ec 100644
--- a/runtime/vm/store_buffer.cc
+++ b/runtime/vm/store_buffer.cc
@@ -10,98 +10,68 @@
 namespace dart {
 
 DEFINE_LEAF_RUNTIME_ENTRY(void, StoreBufferBlockProcess, Isolate* isolate) {
-  isolate->store_buffer_block()->ProcessBuffer(isolate);
+  StoreBuffer* buffer = isolate->store_buffer();
+  buffer->Expand(true);
 }
 END_LEAF_RUNTIME_ENTRY
 
 
-void StoreBufferBlock::ProcessBuffer() {
-  ProcessBuffer(Isolate::Current());
-}
-
-
-void StoreBufferBlock::ProcessBuffer(Isolate* isolate) {
-  isolate->store_buffer()->ProcessBlock(this);
-}
-
-
-bool StoreBufferBlock::Contains(uword pointer) {
-  for (int32_t i = 0; i < top_; i++) {
-    if (pointers_[i] == pointer) {
-      return true;
-    }
-  }
-  return false;
-}
-
-
 StoreBuffer::~StoreBuffer() {
-  DedupSet* current = dedup_sets_;
-  dedup_sets_ = NULL;
-  while (current != NULL) {
-    DedupSet* next = current->next();
-    delete current;
-    current = next;
+  StoreBufferBlock* block = blocks_;
+  blocks_ = NULL;
+  while (block != NULL) {
+    StoreBufferBlock* next = block->next();
+    delete block;
+    block = next;
   }
 }
 
 
 void StoreBuffer::Reset() {
-  DedupSet* current = DedupSets();
-  while (current != NULL) {
-    DedupSet* next = current->next();
-    delete current;
-    current = next;
+  StoreBufferBlock* block = blocks_->next_;
+  while (block != NULL) {
+    StoreBufferBlock* next = block->next_;
+    delete block;
+    block = next;
   }
+  blocks_->next_ = NULL;
+  blocks_->top_ = 0;
+  full_count_ = 0;
 }
 
 
-bool StoreBuffer::AddPointerInternal(uword address) {
-  ASSERT(dedup_sets_ != NULL);
-  ASSERT(Isolate::Current()->heap()->OldContains(address));
-  ASSERT((address & kSmiTagMask) != kSmiTag);
-  if (!dedup_sets_->set()->Add(address)) {
-    // Add a new DedupSet.
-    dedup_sets_ = new DedupSet(dedup_sets_);
-    count_++;
-    return true;
+bool StoreBuffer::Contains(RawObject* raw) {
+  StoreBufferBlock* block = blocks_;
+  while (block != NULL) {
+    intptr_t count = block->Count();
+    for (intptr_t i = 0; i < count; i++) {
+      if (block->At(i) == raw) {
+        return true;
+      }
+    }
+    block = block->next_;
   }
   return false;
 }
 
 
-void StoreBuffer::AddPointer(uword address) {
-  if (AddPointerInternal(address)) {
-    // Had to create a new DedupSet.
+void StoreBuffer::Expand(bool check) {
+  ASSERT(blocks_->Count() == StoreBufferBlock::kSize);
+  blocks_ = new StoreBufferBlock(blocks_);
+  full_count_++;
+  if (check) {
     CheckThreshold();
   }
 }
 
 
-bool StoreBuffer::DrainBlock(StoreBufferBlock* block) {
-  const intptr_t old_count = count_;
-  intptr_t entries = block->Count();
-  for (intptr_t i = 0; i < entries; i++) {
-    AddPointerInternal(block->At(i));
-  }
-  block->Reset();
-  return (count_ > old_count);
-}
-
-
 void StoreBuffer::CheckThreshold() {
-  // Schedule an interrupt if we have run over the max number of DedupSets.
+  // Schedule an interrupt if we have run over the max number of
+  // StoreBufferBlocks.
   // TODO(iposva): Fix magic number.
-  if (count_ > 100) {
+  if (full_count_ > 100) {
     Isolate::Current()->ScheduleInterrupts(Isolate::kStoreBufferInterrupt);
   }
 }
 
-
-void StoreBuffer::ProcessBlock(StoreBufferBlock* block) {
-  if (DrainBlock(block)) {
-    CheckThreshold();
-  }
-}
-
 }  // namespace dart
diff --git a/runtime/vm/store_buffer.h b/runtime/vm/store_buffer.h
index 5657f79..69cb803 100644
--- a/runtime/vm/store_buffer.h
+++ b/runtime/vm/store_buffer.h
@@ -7,54 +7,41 @@
 
 #include "platform/assert.h"
 #include "vm/globals.h"
-#include "vm/hash_set.h"
 
 namespace dart {
 
 // Forward declarations.
 class Isolate;
+class RawObject;
 
 class StoreBufferBlock {
  public:
   // Each block contains kSize pointers.
   static const int32_t kSize = 1024;
 
-  StoreBufferBlock() : top_(0) {}
+  explicit StoreBufferBlock(StoreBufferBlock* next) : next_(next), top_(0) {}
+
+  void Reset() { top_ = 0; }
+
+  StoreBufferBlock* next() const { return next_; }
+
+  intptr_t Count() const { return top_; }
+
+  RawObject* At(intptr_t i) const {
+    ASSERT(i >= 0);
+    ASSERT(i < top_);
+    return pointers_[i];
+  }
 
   static int top_offset() { return OFFSET_OF(StoreBufferBlock, top_); }
   static int pointers_offset() {
     return OFFSET_OF(StoreBufferBlock, pointers_);
   }
 
-  void Reset() { top_ = 0; }
-
-  intptr_t Count() const { return top_; }
-
-  uword At(intptr_t i) const {
-    ASSERT(i >= 0);
-    ASSERT(i < top_);
-    return pointers_[i];
-  }
-
-  // Add a pointer to the block of pointers. The buffer will be processed if it
-  // has been filled by this operation.
-  void AddPointer(uword pointer) {
-    ASSERT(top_ < kSize);
-    pointers_[top_++] = pointer;
-    if (top_ == kSize) {
-      ProcessBuffer();
-    }
-  }
-
-  // Process this store buffer and remember its contents in the heap.
-  void ProcessBuffer();
-  void ProcessBuffer(Isolate* isolate);
-
-  bool Contains(uword pointer);
-
  private:
+  StoreBufferBlock* next_;
   int32_t top_;
-  uword pointers_[kSize];
+  RawObject* pointers_[kSize];
 
   friend class StoreBuffer;
 
@@ -64,63 +51,54 @@
 
 class StoreBuffer {
  public:
-  // Simple linked list element containing a HashSet of old->new pointers.
-  class DedupSet {
-   public:
-    enum {
-      kSetSize = 1024,
-      kFillRatio = 75
-    };
-
-    explicit DedupSet(DedupSet* next)
-        : next_(next), set_(new HashSet(kSetSize, kFillRatio)) {}
-    ~DedupSet() {
-      delete set_;
-    }
-
-    DedupSet* next() const { return next_; }
-    HashSet* set() const { return set_; }
-
-   private:
-    DedupSet* next_;
-    HashSet* set_;
-
-    DISALLOW_COPY_AND_ASSIGN(DedupSet);
-  };
-
-  StoreBuffer() : dedup_sets_(new DedupSet(NULL)), count_(1) {}
+  StoreBuffer() : blocks_(new StoreBufferBlock(NULL)), full_count_(0) {}
   ~StoreBuffer();
 
+  intptr_t Count() const {
+    return blocks_->Count() + (full_count_ * StoreBufferBlock::kSize);
+  }
+
   void Reset();
 
-  void AddPointer(uword address);
+  void AddObject(RawObject* obj) {
+    StoreBufferBlock* block = blocks_;
+    ASSERT(block->top_ < StoreBufferBlock::kSize);
+    block->pointers_[block->top_++] = obj;
+    if (block->top_ == StoreBufferBlock::kSize) {
+      Expand(true);
+    }
+  }
 
-  // Drain StoreBufferBlock into deduplication sets.
-  // Returns true if new sets were created.
-  bool DrainBlock(StoreBufferBlock* block);
+  void AddObjectGC(RawObject* obj) {
+    StoreBufferBlock* block = blocks_;
+    ASSERT(block->top_ < StoreBufferBlock::kSize);
+    block->pointers_[block->top_++] = obj;
+    if (block->top_ == StoreBufferBlock::kSize) {
+      Expand(false);
+    }
+  }
 
-  // Drain StoreBufferBlock into deduplication sets.
-  // Schedule an interrupt if we run over the max number of deduplication sets.
-  void ProcessBlock(StoreBufferBlock* block);
-
-  DedupSet* DedupSets() {
-    DedupSet* result = dedup_sets_;
-    dedup_sets_ = new DedupSet(NULL);
-    count_ = 1;
+  StoreBufferBlock* Blocks() {
+    StoreBufferBlock* result = blocks_;
+    blocks_ = new StoreBufferBlock(NULL);
+    full_count_ = 0;
     return result;
   }
 
- private:
-  // Add pointer to deduplication sets. Returns true if the current set is full
-  // and a new set was created.
-  bool AddPointerInternal(uword address);
+  // Expand the storage and optionally check whethe to schedule an interrupt.
+  void Expand(bool check);
 
+  bool Contains(RawObject* raw);
+
+  static int blocks_offset() { return OFFSET_OF(StoreBuffer, blocks_); }
+
+ private:
   // Check if we run over the max number of deduplication sets.
   // If we did schedule an interrupt.
   void CheckThreshold();
 
-  DedupSet* dedup_sets_;
-  intptr_t count_;
+  StoreBufferBlock* blocks_;
+  intptr_t full_count_;
 
   DISALLOW_COPY_AND_ASSIGN(StoreBuffer);
 };
diff --git a/runtime/vm/stub_code_arm.cc b/runtime/vm/stub_code_arm.cc
index 852768a..39f6497 100644
--- a/runtime/vm/stub_code_arm.cc
+++ b/runtime/vm/stub_code_arm.cc
@@ -333,20 +333,25 @@
 //   +------------------+
 //   | Saved FP         | <- TOS
 //   +------------------+
-//   | return-address   |  (deoptimization point)
+//   | Saved LR         |  (deoptimization point)
 //   +------------------+
-//   | optimized frame  |
+//   | stub pc marker   |  (necessary to keep constant offset SP - Saved LR.
+//   +------------------+
+//   | optimized frame  | <- SP of optimized code
 //   |  ...             |
 //
 // Parts of the code cannot GC, part of the code can GC.
 static void GenerateDeoptimizationSequence(Assembler* assembler,
                                            bool preserve_result) {
-  __ EnterFrame((1 << FP) | (1 << LR), 0);
+  __ EnterStubFrame();  // Do not save pp (implicit saved regs to fp offset).
   // The code in this frame may not cause GC. kDeoptimizeCopyFrameRuntimeEntry
   // and kDeoptimizeFillFrameRuntimeEntry are leaf runtime calls.
   const intptr_t saved_r0_offset_from_fp = -(kNumberOfCpuRegisters - R0);
   // Result in R0 is preserved as part of pushing all registers below.
 
+  // TODO(regis): Should we align the stack before pushing the fpu registers?
+  // If we do, saved_r0_offset_from_fp is not constant anymore.
+
   // Push registers in their enumeration order: lowest register number at
   // lowest address.
   __ PushList(kAllCpuRegistersList);
@@ -363,10 +368,10 @@
     __ ldr(R1, Address(FP, saved_r0_offset_from_fp * kWordSize));
   }
 
-  __ LeaveFrame((1 << FP) | (1 << LR));
+  __ LeaveStubFrame();  // Restores FP and LR from stack.
   __ sub(SP, FP, ShifterOperand(R0));
 
-  __ EnterFrame((1 << FP) | (1 << LR), 0);
+  __ EnterStubFrame();
   __ mov(R0, ShifterOperand(SP));  // Get last FP address.
   if (preserve_result) {
     __ Push(R1);  // Preserve result.
@@ -379,7 +384,7 @@
     __ ldr(R1, Address(FP, -1 * kWordSize));
   }
   // Code above cannot cause GC.
-  __ LeaveFrame((1 << FP) | (1 << LR));
+  __ LeaveStubFrame();
   __ mov(FP, ShifterOperand(R0));
 
   // Frame is fully rewritten at this point and it is safe to perform a GC.
@@ -399,7 +404,10 @@
 
 
 void StubCode::GenerateDeoptimizeLazyStub(Assembler* assembler) {
-  __ Unimplemented("DeoptimizeLazy stub");
+  // Correct return address to point just after the call that is being
+  // deoptimized.
+  __ AddImmediate(LR, -CallPattern::kFixedLengthInBytes);
+  GenerateDeoptimizationSequence(assembler, true);  // Preserve R0.
 }
 
 
@@ -876,27 +884,40 @@
   // Save values being destroyed.
   __ PushList((1 << R1) | (1 << R2) | (1 << R3));
 
+  Label add_to_buffer;
+  // Check whether this object has already been remembered. Skip adding to the
+  // store buffer if the object is in the store buffer already.
+  // Spilled: R1, R2, R3
+  // R0: Address being stored
+  __ ldr(R2, FieldAddress(R0, Object::tags_offset()));
+  __ tst(R2, ShifterOperand(1 << RawObject::kRememberedBit));
+  __ b(&add_to_buffer, EQ);
+  __ PopList((1 << R1) | (1 << R2) | (1 << R3));
+  __ Ret();
+
+  __ Bind(&add_to_buffer);
+  __ orr(R2, R2, ShifterOperand(1 << RawObject::kRememberedBit));
+  __ str(R2, FieldAddress(R0, Object::tags_offset()));
+
   // Load the isolate out of the context.
   // Spilled: R1, R2, R3.
   // R0: address being stored.
   __ ldr(R1, FieldAddress(CTX, Context::isolate_offset()));
 
-  // Load top_ out of the StoreBufferBlock and add the address to the pointers_.
+  // Load the StoreBuffer block out of the isolate. Then load top_ out of the
+  // StoreBufferBlock and add the address to the pointers_.
   // R1: isolate.
-  intptr_t store_buffer_offset = Isolate::store_buffer_block_offset();
-  __ LoadFromOffset(kLoadWord, R2, R1,
-                    store_buffer_offset + StoreBufferBlock::top_offset());
+  __ ldr(R1, Address(R1, Isolate::store_buffer_offset()));
+  __ ldr(R2, Address(R1, StoreBufferBlock::top_offset()));
   __ add(R3, R1, ShifterOperand(R2, LSL, 2));
-  __ StoreToOffset(kStoreWord, R0, R3,
-                   store_buffer_offset + StoreBufferBlock::pointers_offset());
+  __ str(R0, Address(R3, StoreBufferBlock::pointers_offset()));
 
   // Increment top_ and check for overflow.
   // R2: top_.
-  // R1: isolate.
+  // R1: StoreBufferBlock.
   Label L;
   __ add(R2, R2, ShifterOperand(1));
-  __ StoreToOffset(kStoreWord, R2, R1,
-                   store_buffer_offset + StoreBufferBlock::top_offset());
+  __ str(R2, Address(R1, StoreBufferBlock::top_offset()));
   __ CompareImmediate(R2, StoreBufferBlock::kSize);
   // Restore values.
   __ PopList((1 << R1) | (1 << R2) | (1 << R3));
@@ -1686,10 +1707,10 @@
 }
 
 
-// Return the current stack pointer address, used to stack alignment
-// checks.
+// Return the current stack pointer address, used to do stack alignment checks.
 void StubCode::GenerateGetStackPointerStub(Assembler* assembler) {
-  __ Unimplemented("GetStackPointer Stub");
+  __ mov(R0, ShifterOperand(SP));
+  __ Ret();
 }
 
 
diff --git a/runtime/vm/stub_code_ia32.cc b/runtime/vm/stub_code_ia32.cc
index dd4a3d7..0af074b 100644
--- a/runtime/vm/stub_code_ia32.cc
+++ b/runtime/vm/stub_code_ia32.cc
@@ -959,31 +959,43 @@
   __ pushl(EDX);
   __ pushl(ECX);
 
+  Label add_to_buffer;
+  // Check whether this object has already been remembered. Skip adding to the
+  // store buffer if the object is in the store buffer already.
+  // Spilled: EDX, ECX
+  // EAX: Address being stored
+  __ movl(ECX, FieldAddress(EAX, Object::tags_offset()));
+  __ testl(ECX, Immediate(1 << RawObject::kRememberedBit));
+  __ j(EQUAL, &add_to_buffer, Assembler::kNearJump);
+  __ popl(ECX);
+  __ popl(EDX);
+  __ ret();
+
+  __ Bind(&add_to_buffer);
+  __ orl(ECX, Immediate(1 << RawObject::kRememberedBit));
+  __ movl(FieldAddress(EAX, Object::tags_offset()), ECX);
+
   // Load the isolate out of the context.
   // Spilled: EDX, ECX
   // EAX: Address being stored
   __ movl(EDX, FieldAddress(CTX, Context::isolate_offset()));
 
-  // Load top_ out of the StoreBufferBlock and add the address to the pointers_.
+  // Load the StoreBuffer block out of the isolate. Then load top_ out of the
+  // StoreBufferBlock and add the address to the pointers_.
   // Spilled: EDX, ECX
   // EAX: Address being stored
   // EDX: Isolate
-  intptr_t store_buffer_offset = Isolate::store_buffer_block_offset();
-  __ movl(ECX,
-          Address(EDX, store_buffer_offset + StoreBufferBlock::top_offset()));
-  __ movl(Address(EDX,
-                  ECX, TIMES_4,
-                  store_buffer_offset + StoreBufferBlock::pointers_offset()),
-          EAX);
+  __ movl(EDX, Address(EDX, Isolate::store_buffer_offset()));
+  __ movl(ECX, Address(EDX, StoreBufferBlock::top_offset()));
+  __ movl(Address(EDX, ECX, TIMES_4, StoreBufferBlock::pointers_offset()), EAX);
 
   // Increment top_ and check for overflow.
   // Spilled: EDX, ECX
   // ECX: top_
-  // EDX: Isolate
+  // EDX: StoreBufferBlock
   Label L;
   __ incl(ECX);
-  __ movl(Address(EDX, store_buffer_offset + StoreBufferBlock::top_offset()),
-          ECX);
+  __ movl(Address(EDX, StoreBufferBlock::top_offset()), ECX);
   __ cmpl(ECX, Immediate(StoreBufferBlock::kSize));
   // Restore values.
   // Spilled: EDX, ECX
@@ -1868,8 +1880,7 @@
 }
 
 
-// Return the current stack pointer address, used to stack alignment
-// checks.
+// Return the current stack pointer address, used to do stack alignment checks.
 // TOS + 0: return address
 // Result in EAX.
 void StubCode::GenerateGetStackPointerStub(Assembler* assembler) {
diff --git a/runtime/vm/stub_code_mips.cc b/runtime/vm/stub_code_mips.cc
index b475ae7..10f55d7 100644
--- a/runtime/vm/stub_code_mips.cc
+++ b/runtime/vm/stub_code_mips.cc
@@ -984,26 +984,44 @@
   __ sw(T2, Address(SP, 1 * kWordSize));
   __ sw(T1, Address(SP, 0 * kWordSize));
 
+  Label add_to_buffer;
+  // Check whether this object has already been remembered. Skip adding to the
+  // store buffer if the object is in the store buffer already.
+  // Spilled: T1, T2, T3.
+  // T0: Address being stored.
+  __ lw(T2, FieldAddress(T0, Object::tags_offset()));
+  __ andi(T1, T2, Immediate(1 << RawObject::kRememberedBit));
+  __ beq(T1, ZR, &add_to_buffer);
+  __ lw(T1, Address(SP, 0 * kWordSize));
+  __ lw(T2, Address(SP, 1 * kWordSize));
+  __ lw(T3, Address(SP, 2 * kWordSize));
+  __ addiu(SP, SP, Immediate(3 * kWordSize));
+  __ Ret();
+
+  __ Bind(&add_to_buffer);
+  __ ori(T2, T2, Immediate(1 << RawObject::kRememberedBit));
+  __ sw(T2, FieldAddress(T0, Object::tags_offset()));
+
   // Load the isolate out of the context.
   // Spilled: T1, T2, T3.
   // T0: Address being stored.
   __ lw(T1, FieldAddress(CTX, Context::isolate_offset()));
 
-  // Load top_ out of the StoreBufferBlock and add the address to the pointers_.
+  // Load the StoreBuffer block out of the isolate. Then load top_ out of the
+  // StoreBufferBlock and add the address to the pointers_.
   // T1: Isolate.
-  intptr_t store_buffer_offset = Isolate::store_buffer_block_offset();
-  __ lw(T2, Address(T1, store_buffer_offset + StoreBufferBlock::top_offset()));
+  __ lw(T1, Address(T1, Isolate::store_buffer_offset()));
+  __ lw(T2, Address(T1, StoreBufferBlock::top_offset()));
   __ sll(T3, T2, 2);
   __ addu(T3, T1, T3);
-  __ sw(T0,
-        Address(T3, store_buffer_offset + StoreBufferBlock::pointers_offset()));
+  __ sw(T0, Address(T3, StoreBufferBlock::pointers_offset()));
 
   // Increment top_ and check for overflow.
   // T2: top_
-  // T1: Isolate
+  // T1: StoreBufferBlock
   Label L;
   __ AddImmediate(T2, 1);
-  __ sw(T2, Address(T1, store_buffer_offset + StoreBufferBlock::top_offset()));
+  __ sw(T2, Address(T1, StoreBufferBlock::top_offset()));
   __ addiu(CMPRES, T2, Immediate(-StoreBufferBlock::kSize));
   // Restore values.
   __ lw(T1, Address(SP, 0 * kWordSize));
diff --git a/runtime/vm/stub_code_x64.cc b/runtime/vm/stub_code_x64.cc
index 6125c83..1654efb 100644
--- a/runtime/vm/stub_code_x64.cc
+++ b/runtime/vm/stub_code_x64.cc
@@ -948,28 +948,40 @@
   __ pushq(RDX);
   __ pushq(RCX);
 
+  Label add_to_buffer;
+  // Check whether this object has already been remembered. Skip adding to the
+  // store buffer if the object is in the store buffer already.
+  // Spilled: RDX, RCX
+  // RAX: Address being stored
+  __ movq(RCX, FieldAddress(RAX, Object::tags_offset()));
+  __ testq(RCX, Immediate(1 << RawObject::kRememberedBit));
+  __ j(EQUAL, &add_to_buffer, Assembler::kNearJump);
+  __ popq(RCX);
+  __ popq(RDX);
+  __ ret();
+
+  __ Bind(&add_to_buffer);
+  __ orq(RCX, Immediate(1 << RawObject::kRememberedBit));
+  __ movq(FieldAddress(RAX, Object::tags_offset()), RCX);
+
   // Load the isolate out of the context.
   // RAX: Address being stored
   __ movq(RDX, FieldAddress(CTX, Context::isolate_offset()));
 
-  // Load top_ out of the StoreBufferBlock and add the address to the pointers_.
+  // Load the StoreBuffer block out of the isolate. Then load top_ out of the
+  // StoreBufferBlock and add the address to the pointers_.
   // RAX: Address being stored
   // RDX: Isolate
-  intptr_t store_buffer_offset = Isolate::store_buffer_block_offset();
-  __ movl(RCX,
-          Address(RDX, store_buffer_offset + StoreBufferBlock::top_offset()));
-  __ movq(Address(RDX,
-                  RCX, TIMES_8,
-                  store_buffer_offset + StoreBufferBlock::pointers_offset()),
-          RAX);
+  __ movq(RDX, Address(RDX, Isolate::store_buffer_offset()));
+  __ movl(RCX, Address(RDX, StoreBufferBlock::top_offset()));
+  __ movq(Address(RDX, RCX, TIMES_8, StoreBufferBlock::pointers_offset()), RAX);
 
   // Increment top_ and check for overflow.
   // RCX: top_
-  // RDX: Isolate
+  // RDX: StoreBufferBlock
   Label L;
   __ incq(RCX);
-  __ movl(Address(RDX, store_buffer_offset + StoreBufferBlock::top_offset()),
-          RCX);
+  __ movl(Address(RDX, StoreBufferBlock::top_offset()), RCX);
   __ cmpl(RCX, Immediate(StoreBufferBlock::kSize));
   // Restore values.
   __ popq(RCX);
diff --git a/runtime/vm/symbols.h b/runtime/vm/symbols.h
index a32a7cd..2c85c1c 100644
--- a/runtime/vm/symbols.h
+++ b/runtime/vm/symbols.h
@@ -341,6 +341,9 @@
   static const String& Backtick() {
     return *(symbol_handles_[kNullCharId + '`']);
   }
+  static const String& Slash() {
+    return *(symbol_handles_[kNullCharId + '/']);
+  }
 
   // Access methods for symbol handles stored in the vm isolate.
 #define DEFINE_SYMBOL_HANDLE_ACCESSOR(symbol, literal)                         \
diff --git a/runtime/vm/vm.gypi b/runtime/vm/vm.gypi
index d55ace1..a9fd7c2 100644
--- a/runtime/vm/vm.gypi
+++ b/runtime/vm/vm.gypi
@@ -5,6 +5,7 @@
 {
   'variables': {
     'gen_source_dir': '<(LIB_DIR)',
+    'libgen_in_cc_file': '../lib/libgen_in.cc',
     'builtin_in_cc_file': '../bin/builtin_in.cc',
     'async_cc_file': '<(gen_source_dir)/async_gen.cc',
     'async_patch_cc_file': '<(gen_source_dir)/async_patch_gen.cc',
@@ -120,7 +121,7 @@
       'includes': [
         '../lib/async_sources.gypi',
         '../lib/collection_sources.gypi',
-        '../lib/lib_sources.gypi',
+        '../lib/corelib_sources.gypi',
         '../lib/isolate_sources.gypi',
         '../lib/math_sources.gypi',
         '../lib/mirrors_sources.gypi',
@@ -162,7 +163,7 @@
       'includes': [
         '../lib/async_sources.gypi',
         '../lib/collection_sources.gypi',
-        '../lib/lib_sources.gypi',
+        '../lib/corelib_sources.gypi',
         '../lib/isolate_sources.gypi',
         '../lib/math_sources.gypi',
         '../lib/mirrors_sources.gypi',
@@ -179,9 +180,6 @@
       'target_name': 'generate_async_cc_file',
       'type': 'none',
       'toolsets':['host', 'target'],
-      'variables': {
-        'async_dart': '<(gen_source_dir)/async_gen.dart',
-      },
       'includes': [
         '../../sdk/lib/async/async_sources.gypi',
       ],
@@ -194,39 +192,24 @@
       ],
       'actions': [
         {
-          'action_name': 'generate_async_dart',
-          'inputs': [
-            '../tools/concat_library.py',
-            '<@(_sources)',
-          ],
-          'outputs': [
-            '<(async_dart)',
-          ],
-          'action': [
-            'python',
-            '<@(_inputs)',
-            '--output', '<(async_dart)',
-          ],
-          'message': 'Generating ''<(async_dart)'' file.',
-        },
-        {
           'action_name': 'generate_async_cc',
           'inputs': [
-            '../tools/create_string_literal.py',
-            '<(builtin_in_cc_file)',
-            '<@(async_dart)',
+            '../tools/gen_library_src_paths.py',
+            '<(libgen_in_cc_file)',
+            '<@(_sources)',
           ],
           'outputs': [
             '<(async_cc_file)',
           ],
           'action': [
             'python',
-            'tools/create_string_literal.py',
+            'tools/gen_library_src_paths.py',
             '--output', '<(async_cc_file)',
-            '--input_cc', '<(builtin_in_cc_file)',
+            '--input_cc', '<(libgen_in_cc_file)',
             '--include', 'vm/bootstrap.h',
-            '--var_name', 'dart::Bootstrap::async_source_',
-            '<@(async_dart)',
+            '--var_name', 'dart::Bootstrap::async_source_paths_',
+            '--library_name', 'dart:async',
+            '<@(_sources)',
           ],
           'message': 'Generating ''<(async_cc_file)'' file.'
         },
@@ -236,9 +219,7 @@
       'target_name': 'generate_corelib_cc_file',
       'type': 'none',
       'toolsets':['host', 'target'],
-      'variables': {
-        'core_dart': '<(gen_source_dir)/core_gen.dart',
-      },'includes': [
+      'includes': [
         # Load the shared core library sources.
         '../../sdk/lib/core/corelib_sources.gypi',
       ],
@@ -251,39 +232,24 @@
       ],
       'actions': [
         {
-          'action_name': 'generate_core_dart',
-          'inputs': [
-            '../tools/concat_library.py',
-            '<@(_sources)',
-          ],
-          'outputs': [
-            '<(core_dart)',
-          ],
-          'action': [
-            'python',
-            '<@(_inputs)',
-            '--output', '<(core_dart)',
-          ],
-          'message': 'Generating ''<(core_dart)'' file.',
-        },
-        {
           'action_name': 'generate_corelib_cc',
           'inputs': [
-            '../tools/create_string_literal.py',
-            '<(builtin_in_cc_file)',
-            '<(core_dart)',
+            '../tools/gen_library_src_paths.py',
+            '<(libgen_in_cc_file)',
+            '<@(_sources)',
           ],
           'outputs': [
             '<(corelib_cc_file)',
           ],
           'action': [
             'python',
-            'tools/create_string_literal.py',
+            'tools/gen_library_src_paths.py',
             '--output', '<(corelib_cc_file)',
-            '--input_cc', '<(builtin_in_cc_file)',
+            '--input_cc', '<(libgen_in_cc_file)',
             '--include', 'vm/bootstrap.h',
-            '--var_name', 'dart::Bootstrap::corelib_source_',
-            '<(core_dart)',
+            '--var_name', 'dart::Bootstrap::corelib_source_paths_',
+            '--library_name', 'dart:core',
+            '<@(_sources)',
           ],
           'message': 'Generating ''<(corelib_cc_file)'' file.'
         },
@@ -295,7 +261,7 @@
       'toolsets':['host', 'target'],
       'includes': [
         # Load the runtime implementation sources.
-        '../lib/lib_sources.gypi',
+        '../lib/corelib_sources.gypi',
       ],
       'sources/': [
         # Exclude all .[cc|h] files.
@@ -332,9 +298,6 @@
       'target_name': 'generate_collection_cc_file',
       'type': 'none',
       'toolsets':['host', 'target'],
-      'variables': {
-        'collection_dart': '<(gen_source_dir)/collection_gen.dart',
-      },
       'includes': [
         # Load the shared collection library sources.
         '../../sdk/lib/collection/collection_sources.gypi',
@@ -348,39 +311,24 @@
       ],
       'actions': [
         {
-          'action_name': 'generate_collection_dart',
-          'inputs': [
-            '../tools/concat_library.py',
-            '<@(_sources)',
-          ],
-          'outputs': [
-            '<(collection_dart)',
-          ],
-          'action': [
-            'python',
-            '<@(_inputs)',
-            '--output', '<(collection_dart)',
-          ],
-          'message': 'Generating ''<(collection_dart)'' file.',
-        },
-        {
           'action_name': 'generate_collection_cc',
           'inputs': [
-            '../tools/create_string_literal.py',
-            '<(builtin_in_cc_file)',
-            '<(collection_dart)',
+            '../tools/gen_library_src_paths.py',
+            '<(libgen_in_cc_file)',
+            '<@(_sources)',
           ],
           'outputs': [
             '<(collection_cc_file)',
           ],
           'action': [
             'python',
-            'tools/create_string_literal.py',
+            'tools/gen_library_src_paths.py',
             '--output', '<(collection_cc_file)',
-            '--input_cc', '<(builtin_in_cc_file)',
+            '--input_cc', '<(libgen_in_cc_file)',
             '--include', 'vm/bootstrap.h',
-            '--var_name', 'dart::Bootstrap::collection_source_',
-            '<(collection_dart)',
+            '--var_name', 'dart::Bootstrap::collection_source_paths_',
+            '--library_name', 'dart:collection',
+            '<@(_sources)',
           ],
           'message': 'Generating ''<(collection_cc_file)'' file.'
         },
@@ -429,9 +377,6 @@
       'target_name': 'generate_collection_dev_cc_file',
       'type': 'none',
       'toolsets':['host', 'target'],
-      'variables': {
-        'collection_dev_dart': '<(gen_source_dir)/collection_dev_gen.dart',
-      },
       'includes': [
         # Load the shared collection_dev library sources.
         '../../sdk/lib/_collection_dev/collection_dev_sources.gypi',
@@ -445,39 +390,24 @@
       ],
       'actions': [
         {
-          'action_name': 'generate_collection_dev_dart',
-          'inputs': [
-            '../tools/concat_library.py',
-            '<@(_sources)',
-          ],
-          'outputs': [
-            '<(collection_dev_dart)',
-          ],
-          'action': [
-            'python',
-            '<@(_inputs)',
-            '--output', '<(collection_dev_dart)',
-          ],
-          'message': 'Generating ''<(collection_dev_dart)'' file.',
-        },
-        {
           'action_name': 'generate_collection_dev_cc',
           'inputs': [
-            '../tools/create_string_literal.py',
-            '<(builtin_in_cc_file)',
-            '<(collection_dev_dart)',
+            '../tools/gen_library_src_paths.py',
+            '<(libgen_in_cc_file)',
+            '<@(_sources)',
           ],
           'outputs': [
             '<(collection_dev_cc_file)',
           ],
           'action': [
             'python',
-            'tools/create_string_literal.py',
+            'tools/gen_library_src_paths.py',
             '--output', '<(collection_dev_cc_file)',
-            '--input_cc', '<(builtin_in_cc_file)',
+            '--input_cc', '<(libgen_in_cc_file)',
             '--include', 'vm/bootstrap.h',
-            '--var_name', 'dart::Bootstrap::collection_dev_source_',
-            '<(collection_dev_dart)',
+            '--var_name', 'dart::Bootstrap::collection_dev_source_paths_',
+            '--library_name', 'dart:_collection-dev',
+            '<@(_sources)',
           ],
           'message': 'Generating ''<(collection_dev_cc_file)'' file.'
         },
@@ -487,48 +417,30 @@
       'target_name': 'generate_crypto_cc_file',
       'type': 'none',
       'toolsets':['host', 'target'],
-      'variables': {
-        'crypto_dart': '<(gen_source_dir)/crypto_gen.dart',
-      },
       'includes': [
         # Load the shared crypto sources.
         '../../sdk/lib/crypto/crypto_sources.gypi',
       ],
       'actions': [
         {
-          'action_name': 'generate_crypto_dart',
-          'inputs': [
-            '../tools/concat_library.py',
-            '<@(_sources)',
-          ],
-          'outputs': [
-            '<(crypto_dart)',
-          ],
-          'action': [
-            'python',
-            '<@(_inputs)',
-            '--output', '<(crypto_dart)',
-          ],
-          'message': 'Generating ''<(crypto_dart)'' file.',
-        },
-        {
           'action_name': 'generate_crypto_cc',
           'inputs': [
-            '../tools/create_string_literal.py',
-            '<(builtin_in_cc_file)',
-            '<(crypto_dart)',
+            '../tools/gen_library_src_paths.py',
+            '<(libgen_in_cc_file)',
+            '<@(_sources)',
           ],
           'outputs': [
             '<(crypto_cc_file)',
           ],
           'action': [
             'python',
-            'tools/create_string_literal.py',
+            'tools/gen_library_src_paths.py',
             '--output', '<(crypto_cc_file)',
-            '--input_cc', '<(builtin_in_cc_file)',
+            '--input_cc', '<(libgen_in_cc_file)',
             '--include', 'vm/bootstrap.h',
-            '--var_name', 'dart::Bootstrap::crypto_source_',
-            '<(crypto_dart)',
+            '--var_name', 'dart::Bootstrap::crypto_source_paths_',
+            '--library_name', 'dart:crypto',
+            '<@(_sources)',
           ],
           'message': 'Generating ''<(crypto_cc_file)'' file.'
         },
@@ -538,9 +450,6 @@
       'target_name': 'generate_math_cc_file',
       'type': 'none',
       'toolsets':['host', 'target'],
-      'variables': {
-        'math_dart': '<(gen_source_dir)/math_gen.dart',
-      },
       'includes': [
         # Load the shared math library sources.
         '../../sdk/lib/math/math_sources.gypi',
@@ -554,39 +463,24 @@
       ],
       'actions': [
         {
-          'action_name': 'generate_math_dart',
-          'inputs': [
-            '../tools/concat_library.py',
-            '<@(_sources)',
-          ],
-          'outputs': [
-            '<(math_dart)',
-          ],
-          'action': [
-            'python',
-            '<@(_inputs)',
-            '--output', '<(math_dart)',
-          ],
-          'message': 'Generating ''<(math_dart)'' file.',
-        },
-        {
           'action_name': 'generate_math_cc',
           'inputs': [
-            '../tools/create_string_literal.py',
-            '<(builtin_in_cc_file)',
-            '<(math_dart)',
+            '../tools/gen_library_src_paths.py',
+            '<(libgen_in_cc_file)',
+            '<@(_sources)',
           ],
           'outputs': [
             '<(math_cc_file)',
           ],
           'action': [
             'python',
-            'tools/create_string_literal.py',
+            'tools/gen_library_src_paths.py',
             '--output', '<(math_cc_file)',
-            '--input_cc', '<(builtin_in_cc_file)',
+            '--input_cc', '<(libgen_in_cc_file)',
             '--include', 'vm/bootstrap.h',
-            '--var_name', 'dart::Bootstrap::math_source_',
-            '<(math_dart)',
+            '--var_name', 'dart::Bootstrap::math_source_paths_',
+            '--library_name', 'dart:math',
+            '<@(_sources)',
           ],
           'message': 'Generating ''<(math_cc_file)'' file.'
         },
@@ -635,9 +529,6 @@
       'target_name': 'generate_mirrors_cc_file',
       'type': 'none',
       'toolsets':['host', 'target'],
-      'variables': {
-        'mirrors_dart': '<(gen_source_dir)/mirrors_gen.dart',
-      },
       'includes': [
         # Load the shared core library sources.
         '../../sdk/lib/mirrors/mirrors_sources.gypi',
@@ -651,39 +542,24 @@
       ],
       'actions': [
         {
-          'action_name': 'generate_mirrors_dart',
-          'inputs': [
-            '../tools/concat_library.py',
-            '<@(_sources)',
-          ],
-          'outputs': [
-            '<(mirrors_dart)',
-          ],
-          'action': [
-            'python',
-            '<@(_inputs)',
-            '--output', '<(mirrors_dart)',
-          ],
-          'message': 'Generating ''<(mirrors_dart)'' file.',
-        },
-        {
           'action_name': 'generate_mirrors_cc',
           'inputs': [
-            '../tools/create_string_literal.py',
-            '<(builtin_in_cc_file)',
-            '<(mirrors_dart)',
+            '../tools/gen_library_src_paths.py',
+            '<(libgen_in_cc_file)',
+            '<@(_sources)',
           ],
           'outputs': [
             '<(mirrors_cc_file)',
           ],
           'action': [
             'python',
-            'tools/create_string_literal.py',
+            'tools/gen_library_src_paths.py',
             '--output', '<(mirrors_cc_file)',
-            '--input_cc', '<(builtin_in_cc_file)',
+            '--input_cc', '<(libgen_in_cc_file)',
             '--include', 'vm/bootstrap.h',
-            '--var_name', 'dart::Bootstrap::mirrors_source_',
-            '<(mirrors_dart)',
+            '--var_name', 'dart::Bootstrap::mirrors_source_paths_',
+            '--library_name', 'dart:mirrors',
+            '<@(_sources)',
           ],
           'message': 'Generating ''<(mirrors_cc_file)'' file.'
         },
@@ -732,9 +608,6 @@
       'target_name': 'generate_isolate_cc_file',
       'type': 'none',
       'toolsets':['host', 'target'],
-      'variables': {
-        'isolate_dart': '<(gen_source_dir)/isolate_gen.dart',
-      },
       'includes': [
         # Load the runtime implementation sources.
         '../../sdk/lib/isolate/isolate_sources.gypi',
@@ -748,39 +621,24 @@
       ],
       'actions': [
         {
-          'action_name': 'generate_isolate_dart',
-          'inputs': [
-            '../tools/concat_library.py',
-            '<@(_sources)',
-          ],
-          'outputs': [
-            '<(isolate_dart)',
-          ],
-          'action': [
-            'python',
-            '<@(_inputs)',
-            '--output', '<(isolate_dart)',
-          ],
-          'message': 'Generating ''<(isolate_dart)'' file.',
-        },
-        {
           'action_name': 'generate_isolate_cc',
           'inputs': [
-            '../tools/create_string_literal.py',
-            '<(builtin_in_cc_file)',
-            '<(isolate_dart)',
+            '../tools/gen_library_src_paths.py',
+            '<(libgen_in_cc_file)',
+            '<@(_sources)',
           ],
           'outputs': [
             '<(isolate_cc_file)',
           ],
           'action': [
             'python',
-            'tools/create_string_literal.py',
+            'tools/gen_library_src_paths.py',
             '--output', '<(isolate_cc_file)',
-            '--input_cc', '<(builtin_in_cc_file)',
+            '--input_cc', '<(libgen_in_cc_file)',
             '--include', 'vm/bootstrap.h',
-            '--var_name', 'dart::Bootstrap::isolate_source_',
-            '<(isolate_dart)',
+            '--var_name', 'dart::Bootstrap::isolate_source_paths_',
+            '--library_name', 'dart:isolate',
+            '<@(_sources)',
           ],
           'message': 'Generating ''<(isolate_cc_file)'' file.'
         },
@@ -907,48 +765,30 @@
       'target_name': 'generate_json_cc_file',
       'type': 'none',
       'toolsets':['host', 'target'],
-      'variables': {
-        'json_dart': '<(gen_source_dir)/json_gen.dart',
-      },
       'includes': [
         # Load the shared json sources.
         '../../sdk/lib/json/json_sources.gypi',
       ],
       'actions': [
         {
-          'action_name': 'generate_json_dart',
-          'inputs': [
-            '../tools/concat_library.py',
-            '<@(_sources)',
-          ],
-          'outputs': [
-            '<(json_dart)',
-          ],
-          'action': [
-            'python',
-            '<@(_inputs)',
-            '--output', '<(json_dart)',
-          ],
-          'message': 'Generating ''<(json_dart)'' file.',
-        },
-        {
           'action_name': 'generate_json_cc',
           'inputs': [
-            '../tools/create_string_literal.py',
-            '<(builtin_in_cc_file)',
-            '<(json_dart)',
+            '../tools/gen_library_src_paths.py',
+            '<(libgen_in_cc_file)',
+            '<@(_sources)',
           ],
           'outputs': [
             '<(json_cc_file)',
           ],
           'action': [
             'python',
-            'tools/create_string_literal.py',
+            'tools/gen_library_src_paths.py',
             '--output', '<(json_cc_file)',
-            '--input_cc', '<(builtin_in_cc_file)',
+            '--input_cc', '<(libgen_in_cc_file)',
             '--include', 'vm/bootstrap.h',
-            '--var_name', 'dart::Bootstrap::json_source_',
-            '<(json_dart)',
+            '--var_name', 'dart::Bootstrap::json_source_paths_',
+            '--library_name', 'dart:json',
+            '<@(_sources)',
           ],
           'message': 'Generating ''<(json_cc_file)'' file.'
         },
@@ -997,9 +837,6 @@
       'target_name': 'generate_typed_data_cc_file',
       'type': 'none',
       'toolsets':['host', 'target'],
-      'variables': {
-        'typed_data_dart': '<(gen_source_dir)/typed_data_gen.dart',
-      },
       'includes': [
         # Load the shared library sources.
         '../../sdk/lib/typed_data/typed_data_sources.gypi',
@@ -1013,39 +850,24 @@
       ],
       'actions': [
         {
-          'action_name': 'generate_typed_data_dart',
-          'inputs': [
-            '../tools/concat_library.py',
-            '<@(_sources)',
-          ],
-          'outputs': [
-            '<(typed_data_dart)',
-          ],
-          'action': [
-            'python',
-            '<@(_inputs)',
-            '--output', '<(typed_data_dart)',
-          ],
-          'message': 'Generating ''<(typed_data_dart)'' file.',
-        },
-        {
           'action_name': 'generate_typed_data_cc',
           'inputs': [
-            '../tools/create_string_literal.py',
-            '<(builtin_in_cc_file)',
-            '<(typed_data_dart)',
+            '../tools/gen_library_src_paths.py',
+            '<(libgen_in_cc_file)',
+            '<@(_sources)',
           ],
           'outputs': [
             '<(typed_data_cc_file)',
           ],
           'action': [
             'python',
-            'tools/create_string_literal.py',
+            'tools/gen_library_src_paths.py',
             '--output', '<(typed_data_cc_file)',
-            '--input_cc', '<(builtin_in_cc_file)',
+            '--input_cc', '<(libgen_in_cc_file)',
             '--include', 'vm/bootstrap.h',
-            '--var_name', 'dart::Bootstrap::typed_data_source_',
-            '<(typed_data_dart)',
+            '--var_name', 'dart::Bootstrap::typed_data_source_paths_',
+            '--library_name', 'dart:typed_data',
+            '<@(_sources)',
           ],
           'message': 'Generating ''<(typed_data_cc_file)'' file.'
         },
@@ -1094,48 +916,30 @@
       'target_name': 'generate_uri_cc_file',
       'type': 'none',
       'toolsets':['host', 'target'],
-      'variables': {
-        'uri_dart': '<(gen_source_dir)/uri_gen.dart',
-      },
       'includes': [
         # Load the shared uri sources.
         '../../sdk/lib/uri/uri_sources.gypi',
       ],
       'actions': [
         {
-          'action_name': 'generate_uri_dart',
-          'inputs': [
-            '../tools/concat_library.py',
-            '<@(_sources)',
-          ],
-          'outputs': [
-            '<(uri_dart)',
-          ],
-          'action': [
-            'python',
-            '<@(_inputs)',
-            '--output', '<(uri_dart)',
-          ],
-          'message': 'Generating ''<(uri_dart)'' file.'
-        },
-        {
           'action_name': 'generate_uri_cc',
           'inputs': [
-            '../tools/create_string_literal.py',
-            '<(builtin_in_cc_file)',
-            '<(uri_dart)',
+            '../tools/gen_library_src_paths.py',
+            '<(libgen_in_cc_file)',
+            '<@(_sources)',
           ],
           'outputs': [
             '<(uri_cc_file)',
           ],
           'action': [
             'python',
-            'tools/create_string_literal.py',
+            'tools/gen_library_src_paths.py',
             '--output', '<(uri_cc_file)',
-            '--input_cc', '<(builtin_in_cc_file)',
+            '--input_cc', '<(libgen_in_cc_file)',
             '--include', 'vm/bootstrap.h',
-            '--var_name', 'dart::Bootstrap::uri_source_',
-            '<(uri_dart)',
+            '--var_name', 'dart::Bootstrap::uri_source_paths_',
+            '--library_name', 'dart:uri',
+            '<@(_sources)',
           ],
           'message': 'Generating ''<(uri_cc_file)'' file.'
         },
@@ -1145,48 +949,30 @@
       'target_name': 'generate_utf_cc_file',
       'type': 'none',
       'toolsets':['host', 'target'],
-      'variables': {
-        'utf_dart': '<(gen_source_dir)/utf_gen.dart',
-      },
       'includes': [
         # Load the shared utf sources.
         '../../sdk/lib/utf/utf_sources.gypi',
       ],
       'actions': [
         {
-          'action_name': 'generate_utf_dart',
-          'inputs': [
-            '../tools/concat_library.py',
-            '<@(_sources)',
-          ],
-          'outputs': [
-            '<(utf_dart)',
-          ],
-          'action': [
-            'python',
-            '<@(_inputs)',
-            '--output', '<(utf_dart)',
-          ],
-          'message': 'Generating ''<(utf_dart)'' file.',
-        },
-        {
           'action_name': 'generate_utf_cc',
           'inputs': [
-            '../tools/create_string_literal.py',
-            '<(builtin_in_cc_file)',
-            '<(utf_dart)',
+            '../tools/gen_library_src_paths.py',
+            '<(libgen_in_cc_file)',
+            '<@(_sources)',
           ],
           'outputs': [
             '<(utf_cc_file)',
           ],
           'action': [
             'python',
-            'tools/create_string_literal.py',
+            'tools/gen_library_src_paths.py',
             '--output', '<(utf_cc_file)',
-            '--input_cc', '<(builtin_in_cc_file)',
+            '--input_cc', '<(libgen_in_cc_file)',
             '--include', 'vm/bootstrap.h',
-            '--var_name', 'dart::Bootstrap::utf_source_',
-            '<(utf_dart)',
+            '--var_name', 'dart::Bootstrap::utf_source_paths_',
+            '--library_name', 'dart:utf',
+            '<@(_sources)',
           ],
           'message': 'Generating ''<(utf_cc_file)'' file.'
         },
diff --git a/runtime/vm/vm_sources.gypi b/runtime/vm/vm_sources.gypi
index 9009b9e..48f3892 100644
--- a/runtime/vm/vm_sources.gypi
+++ b/runtime/vm/vm_sources.gypi
@@ -11,7 +11,6 @@
     'allocation_test.cc',
     'assembler.cc',
     'assembler.h',
-    'assembler_test.cc',
     'assembler_arm.cc',
     'assembler_arm.h',
     'assembler_arm_test.cc',
@@ -21,16 +20,17 @@
     'assembler_mips.cc',
     'assembler_mips.h',
     'assembler_mips_test.cc',
+    'assembler_test.cc',
     'assembler_x64.cc',
     'assembler_x64.h',
     'assembler_x64_test.cc',
     'assert_test.cc',
     'ast.cc',
     'ast.h',
-    'ast_test.cc',
-    'ast_printer.h',
     'ast_printer.cc',
+    'ast_printer.h',
     'ast_printer_test.cc',
+    'ast_test.cc',
     'base_isolate.h',
     'benchmark_test.cc',
     'benchmark_test.h',
@@ -53,8 +53,8 @@
     'cha.cc',
     'cha.h',
     'cha_test.cc',
-    'class_finalizer.h',
     'class_finalizer.cc',
+    'class_finalizer.h',
     'class_finalizer_test.cc',
     'class_table.cc',
     'class_table.h',
@@ -66,8 +66,8 @@
     'code_generator_test.cc',
     'code_observers.cc',
     'code_observers.h',
-    'code_patcher.h',
     'code_patcher.cc',
+    'code_patcher.h',
     'code_patcher_arm.cc',
     'code_patcher_arm_test.cc',
     'code_patcher_ia32.cc',
@@ -76,10 +76,10 @@
     'code_patcher_mips_test.cc',
     'code_patcher_x64.cc',
     'code_patcher_x64_test.cc',
-    'compiler.h',
     'compiler.cc',
-    'compiler_stats.h',
+    'compiler.h',
     'compiler_stats.cc',
+    'compiler_stats.h',
     'compiler_test.cc',
     'constants_arm.h',
     'constants_ia32.h',
@@ -89,26 +89,29 @@
     'cpu_arm.cc',
     'cpu_ia32.cc',
     'cpu_mips.cc',
-    'cpu_x64.cc',
     'cpu_test.cc',
+    'cpu_x64.cc',
     'custom_isolate_test.cc',
     'dart.cc',
     'dart.h',
     'dart_api_impl.h',
-    'dart_api_state.h',
     'dart_api_impl_test.cc',
     'dart_api_message.cc',
     'dart_api_message.h',
+    'dart_api_state.h',
     'dart_entry.cc',
     'dart_entry.h',
     'dart_entry_test.cc',
     'debugger.cc',
     'debugger.h',
+    'debugger_api_impl_test.cc',
     'debugger_arm.cc',
     'debugger_ia32.cc',
     'debugger_mips.cc',
     'debugger_x64.cc',
-    'debugger_api_impl_test.cc',
+    'debuginfo.h',
+    'debuginfo_android.cc',
+    'debuginfo_linux.cc',
     'deopt_instructions.cc',
     'deopt_instructions.h',
     'disassembler.cc',
@@ -116,11 +119,8 @@
     'disassembler_arm.cc',
     'disassembler_ia32.cc',
     'disassembler_mips.cc',
-    'disassembler_x64.cc',
     'disassembler_test.cc',
-    'debuginfo.h',
-    'debuginfo_android.cc',
-    'debuginfo_linux.cc',
+    'disassembler_x64.cc',
     'double_conversion.cc',
     'double_conversion.h',
     'exceptions.cc',
@@ -168,7 +168,6 @@
     'handles_test.cc',
     'hash_map.h',
     'hash_map_test.cc',
-    'hash_set.h',
     'heap.cc',
     'heap.h',
     'heap_profiler.cc',
@@ -195,10 +194,10 @@
     'intermediate_language_arm.cc',
     'intermediate_language_ia32.cc',
     'intermediate_language_mips.cc',
-    'intermediate_language_x64.cc',
     'intermediate_language_test.cc',
-    'intrinsifier.h',
+    'intermediate_language_x64.cc',
     'intrinsifier.cc',
+    'intrinsifier.h',
     'intrinsifier_arm.cc',
     'intrinsifier_ia32.cc',
     'intrinsifier_mips.cc',
@@ -219,10 +218,10 @@
     'memory_region_test.cc',
     'message.cc',
     'message.h',
-    'message_test.cc',
     'message_handler.cc',
     'message_handler.h',
     'message_handler_test.cc',
+    'message_test.cc',
     'native_arguments.cc',
     'native_arguments.h',
     'native_entry.cc',
@@ -233,26 +232,26 @@
     'native_message_handler.h',
     'object.cc',
     'object.h',
-    'object_test.cc',
     'object_arm_test.cc',
     'object_ia32_test.cc',
     'object_mips_test.cc',
-    'object_x64_test.cc',
     'object_store.cc',
     'object_store.h',
     'object_store_test.cc',
+    'object_test.cc',
+    'object_x64_test.cc',
+    'os.h',
     'os_android.cc',
     'os_linux.cc',
     'os_macos.cc',
-    'os_win.cc',
-    'os.h',
     'os_test.cc',
-    'parser.cc',
-    'parser.h',
-    'parser_test.cc',
+    'os_win.cc',
     'pages.cc',
     'pages.h',
     'pages_test.cc',
+    'parser.cc',
+    'parser.h',
+    'parser_test.cc',
     'port.cc',
     'port.h',
     'port_test.cc',
@@ -266,8 +265,8 @@
     'runtime_entry_arm.cc',
     'runtime_entry_ia32.cc',
     'runtime_entry_mips.cc',
-    'runtime_entry_x64.cc',
     'runtime_entry_test.cc',
+    'runtime_entry_x64.cc',
     'scanner.cc',
     'scanner.h',
     'scanner_test.cc',
@@ -286,12 +285,16 @@
     'snapshot_ids.h',
     'snapshot_test.cc',
     'stack_frame.cc',
-    'stack_frame_arm.cc',
-    'stack_frame_ia32.cc',
-    'stack_frame_mips.cc',
-    'stack_frame_x64.cc',
     'stack_frame.h',
+    'stack_frame_arm.cc',
+    'stack_frame_arm.h',
+    'stack_frame_ia32.cc',
+    'stack_frame_ia32.h',
+    'stack_frame_mips.cc',
+    'stack_frame_mips.h',
     'stack_frame_test.cc',
+    'stack_frame_x64.cc',
+    'stack_frame_x64.h',
     'store_buffer.cc',
     'store_buffer.h',
     'stub_code.cc',
@@ -307,10 +310,10 @@
     'symbols.cc',
     'symbols.h',
     'thread.h',
-    'thread_test.cc',
     'thread_pool.cc',
     'thread_pool.h',
     'thread_pool_test.cc',
+    'thread_test.cc',
     'timer.cc',
     'timer.h',
     'token.cc',
@@ -322,6 +325,8 @@
     'unit_test.cc',
     'unit_test.h',
     'utils_test.cc',
+    'verifier.cc',
+    'verifier.h',
     'virtual_memory.cc',
     'virtual_memory.h',
     'virtual_memory_android.cc',
@@ -329,8 +334,6 @@
     'virtual_memory_macos.cc',
     'virtual_memory_test.cc',
     'virtual_memory_win.cc',
-    'verifier.cc',
-    'verifier.h',
     'visitor.h',
     'vtune.cc',
     'vtune.h',
diff --git a/sdk/lib/_internal/compiler/implementation/apiimpl.dart b/sdk/lib/_internal/compiler/implementation/apiimpl.dart
index 6a81d46..2c94493 100644
--- a/sdk/lib/_internal/compiler/implementation/apiimpl.dart
+++ b/sdk/lib/_internal/compiler/implementation/apiimpl.dart
@@ -52,12 +52,15 @@
             checkDeprecationInSdk:
                 hasOption(options,
                           '--report-sdk-use-of-deprecated-language-features'),
-            strips: getStrips(options),
+            strips: extractCsvOption(options, '--force-strip='),
             enableConcreteTypeInference:
                 hasOption(options, '--enable-concrete-type-inference'),
             preserveComments: hasOption(options, '--preserve-comments'),
             verbose: hasOption(options, '--verbose'),
-            buildId: getBuildId(options)) {
+            sourceMapUri: extractSourceMapUri(options),
+            buildId: extractStringOption(
+                options, '--build-id=',
+                "build number could not be determined")) {
     if (!libraryRoot.path.endsWith("/")) {
       throw new ArgumentError("libraryRoot must end with a /");
     }
@@ -66,34 +69,40 @@
     }
   }
 
-  static String getBuildId(List<String> options) {
+  static String extractStringOption(List<String> options,
+                                    String prefix,
+                                    String defaultValue) {
     for (String option in options) {
-      if (option.startsWith('--build-id=')) {
-        return option.substring('--build-id='.length);
+      if (option.startsWith(prefix)) {
+        return option.substring(prefix.length);
       }
     }
-    return "build number could not be determined";
+    return defaultValue;
   }
 
-  static List<String> getStrips(List<String> options) {
+  static Uri extractSourceMapUri(List<String> options) {
+    var option = extractStringOption(options, '--source-map=', null);
+    return (option == null) ? null : Uri.parse(option);
+  }
+
+  // CSV: Comma separated values.
+  static List<String> extractCsvOption(List<String> options, String prefix) {
     for (String option in options) {
-      if (option.startsWith('--force-strip=')) {
-        return option.substring('--force-strip='.length).split(',');
+      if (option.startsWith(prefix)) {
+        return option.substring(prefix.length).split(',');
       }
     }
     return const <String>[];
   }
 
   static Set<String> getAllowedLibraryCategories(List<String> options) {
-    for (String option in options) {
-      if (option.startsWith('--categories=')) {
-        var result = option.substring('--categories='.length).split(',');
-        result.add('Shared');
-        result.add('Internal');
-        return new Set<String>.from(result);
-      }
+    var result = extractCsvOption(options, '--categories=');
+    if (result.isEmpty) {
+      result = ['Client'];
     }
-    return new Set<String>.from(['Client', 'Shared', 'Internal']);
+    result.add('Shared');
+    result.add('Internal');
+    return new Set<String>.from(result);
   }
 
   static bool hasOption(List<String> options, String option) {
diff --git a/sdk/lib/_internal/compiler/implementation/compile_time_constants.dart b/sdk/lib/_internal/compiler/implementation/compile_time_constants.dart
index cb39371..dc99d27 100644
--- a/sdk/lib/_internal/compiler/implementation/compile_time_constants.dart
+++ b/sdk/lib/_internal/compiler/implementation/compile_time_constants.dart
@@ -647,11 +647,6 @@
     FunctionElement constructor = elements[send];
     constructor = constructor.redirectionTarget;
     ClassElement classElement = constructor.getEnclosingClass();
-    if (classElement.isInterface()) {
-      compiler.resolver.resolveMethodElement(constructor);
-      constructor = constructor.defaultImplementation;
-      classElement = constructor.getEnclosingClass();
-    }
     // The constructor must be an implementation to ensure that field
     // initializers are handled correctly.
     constructor = constructor.implementation;
diff --git a/sdk/lib/_internal/compiler/implementation/compiler.dart b/sdk/lib/_internal/compiler/implementation/compiler.dart
index 35c4dc6..a4d4758 100644
--- a/sdk/lib/_internal/compiler/implementation/compiler.dart
+++ b/sdk/lib/_internal/compiler/implementation/compiler.dart
@@ -226,7 +226,8 @@
 }
 
 abstract class Compiler implements DiagnosticListener {
-  final Map<String, LibraryElement> libraries;
+  final Map<String, LibraryElement> libraries =
+    new Map<String, LibraryElement>();
   final Stopwatch totalCompileTime = new Stopwatch();
   int nextFreeClassId = 0;
   World world;
@@ -277,6 +278,12 @@
    */
   final bool verbose;
 
+  /**
+   * URI of the main source map if the compiler is generating source
+   * maps.
+   */
+  final Uri sourceMapUri;
+
   final api.CompilerOutputProvider outputProvider;
 
   bool disableInlining = false;
@@ -418,7 +425,7 @@
   bool enabledFunctionApply = false;
   bool enabledInvokeOn = false;
 
-  Stopwatch progress;
+  Stopwatch progress = new Stopwatch()..start();
 
   static const int PHASE_SCANNING = 0;
   static const int PHASE_RESOLVING = 1;
@@ -430,47 +437,33 @@
 
   bool hasCrashed = false;
 
-  Compiler({Tracer tracer: const Tracer(),
-            bool enableTypeAssertions: false,
-            bool enableUserAssertions: false,
-            bool enableConcreteTypeInference: false,
-            int maxConcreteTypeSize: 5,
-            bool enableMinification: false,
-            bool enableNativeLiveTypeAnalysis: false,
+  Compiler({this.tracer: const Tracer(),
+            this.enableTypeAssertions: false,
+            this.enableUserAssertions: false,
+            this.enableConcreteTypeInference: false,
+            this.maxConcreteTypeSize: 5,
+            this.enableMinification: false,
+            this.enableNativeLiveTypeAnalysis: false,
             bool emitJavaScript: true,
             bool generateSourceMap: true,
             bool disallowUnsafeEval: false,
-            bool analyzeAll: false,
+            this.analyzeAll: false,
             bool analyzeOnly: false,
             bool analyzeSignaturesOnly: false,
-            bool rejectDeprecatedFeatures: false,
-            bool checkDeprecationInSdk: false,
-            bool preserveComments: false,
-            bool verbose: false,
-            String this.buildId: "build number could not be determined",
+            this.rejectDeprecatedFeatures: false,
+            this.checkDeprecationInSdk: false,
+            this.preserveComments: false,
+            this.verbose: false,
+            this.sourceMapUri: null,
+            this.buildId: "build number could not be determined",
             outputProvider,
             List<String> strips: const []})
-      : tracer = tracer,
-        enableTypeAssertions = enableTypeAssertions,
-        enableUserAssertions = enableUserAssertions,
-        enableConcreteTypeInference = enableConcreteTypeInference,
-        maxConcreteTypeSize = maxConcreteTypeSize,
-        enableMinification = enableMinification,
-        enableNativeLiveTypeAnalysis = enableNativeLiveTypeAnalysis,
-        analyzeAll = analyzeAll,
-        rejectDeprecatedFeatures = rejectDeprecatedFeatures,
-        checkDeprecationInSdk = checkDeprecationInSdk,
-        preserveComments = preserveComments,
-        verbose = verbose,
-        libraries = new Map<String, LibraryElement>(),
-        progress = new Stopwatch(),
-        this.analyzeOnly = analyzeOnly || analyzeSignaturesOnly,
+      : this.analyzeOnly = analyzeOnly || analyzeSignaturesOnly,
         this.analyzeSignaturesOnly = analyzeSignaturesOnly,
         this.outputProvider =
             (outputProvider == null) ? NullSink.outputProvider : outputProvider
 
   {
-    progress.start();
     world = new World(this);
 
     closureMapping.ClosureNamer closureNamer;
@@ -931,9 +924,6 @@
       }
       if (identical(e.kind, ElementKind.GENERATIVE_CONSTRUCTOR)) {
         ClassElement enclosingClass = e.getEnclosingClass();
-        if (enclosingClass.isInterface()) {
-          resolved.remove(e);
-        }
         resolved.remove(e);
 
       }
@@ -954,6 +944,7 @@
 
   TreeElements analyzeElement(Element element) {
     assert(invariant(element, element.isDeclaration));
+    assert(!element.isForwardingConstructor);
     TreeElements elements = enqueuer.resolution.getCachedElements(element);
     if (elements != null) return elements;
     assert(parser != null);
@@ -1298,8 +1289,9 @@
 }
 
 /**
- * Throws an [InvariantException] if [condition] is [:false:]. [condition] must
- * be either a [:bool:] or a no-arg function returning a [:bool:].
+ * Throws a [SpannableAssertionFailure] if [condition] is
+ * [:false:]. [condition] must be either a [:bool:] or a no-arg
+ * function returning a [:bool:].
  *
  * Use this method to provide better information for assertion by calling
  * [invariant] as the argument to an [:assert:] statement:
diff --git a/sdk/lib/_internal/compiler/implementation/dart2js.dart b/sdk/lib/_internal/compiler/implementation/dart2js.dart
index 61660e5..1afb82b 100644
--- a/sdk/lib/_internal/compiler/implementation/dart2js.dart
+++ b/sdk/lib/_internal/compiler/implementation/dart2js.dart
@@ -262,6 +262,8 @@
 
   int charactersWritten = 0;
 
+  options.add('--source-map=$sourceMapOut');
+
   compilationDone(String code) {
     if (analyzeOnly) return;
     if (code == null) {
diff --git a/sdk/lib/_internal/compiler/implementation/dart_backend/backend.dart b/sdk/lib/_internal/compiler/implementation/dart_backend/backend.dart
index 830fddf..26b930d 100644
--- a/sdk/lib/_internal/compiler/implementation/dart_backend/backend.dart
+++ b/sdk/lib/_internal/compiler/implementation/dart_backend/backend.dart
@@ -280,7 +280,9 @@
     // field names used as named optionals into [fixedMemberNames].
     for (final element in resolvedElements.keys) {
       if (!element.isConstructor()) continue;
-      for (final optional in element.functionSignature.optionalParameters) {
+      Link<Element> optionalParameters =
+          element.functionSignature.optionalParameters;
+      for (final optional in optionalParameters) {
         if (optional.kind != ElementKind.FIELD_PARAMETER) continue;
         fixedMemberNames.add(optional.name.slowToString());
       }
@@ -555,18 +557,6 @@
       : this.rootElement = (rootElement is VariableElement)
           ? (rootElement as VariableElement).variables : rootElement;
 
-  visitClassNode(ClassNode node) {
-    super.visitClassNode(node);
-    // Temporary hack which should go away once interfaces
-    // and default clauses are out.
-    if (node.defaultClause != null) {
-      // Resolver cannot resolve parameterized default clauses.
-      TypeAnnotation evilCousine = new TypeAnnotation(
-          node.defaultClause.typeName, null);
-      evilCousine.accept(this);
-    }
-  }
-
   visitNode(Node node) { node.visitChildren(this); }
 
   visitTypeAnnotation(TypeAnnotation typeAnnotation) {
diff --git a/sdk/lib/_internal/compiler/implementation/dart_backend/placeholder_collector.dart b/sdk/lib/_internal/compiler/implementation/dart_backend/placeholder_collector.dart
index 601d136..e5ecbf3 100644
--- a/sdk/lib/_internal/compiler/implementation/dart_backend/placeholder_collector.dart
+++ b/sdk/lib/_internal/compiler/implementation/dart_backend/placeholder_collector.dart
@@ -572,14 +572,6 @@
     ClassElement classElement = currentElement;
     makeElementPlaceholder(node.name, classElement);
     node.visitChildren(this);
-    if (node.defaultClause != null) {
-      // Can't just visit class node's default clause because of the bug in the
-      // resolver, it just crashes when it meets type variable.
-      DartType defaultType = classElement.defaultClass;
-      assert(defaultType != null);
-      makeTypePlaceholder(node.defaultClause.typeName, defaultType);
-      visit(node.defaultClause.typeArguments);
-    }
   }
 
   visitNamedMixinApplication(NamedMixinApplication node) {
@@ -590,15 +582,6 @@
 
   bool tryResolveAndCollectTypeVariable(
       TypeDeclarationElement typeDeclaration, Identifier name) {
-    // Hack for case when interface and default class are in different
-    // libraries, try to resolve type variable to default class type arg.
-    // Example:
-    // lib1: interface I<K> default C<K> {...}
-    // lib2: class C<K> {...}
-    if (typeDeclaration is ClassElement
-        && (typeDeclaration as ClassElement).defaultClass != null) {
-      typeDeclaration = (typeDeclaration as ClassElement).defaultClass.element;
-    }
     // Another poor man type resolution.
     // Find this variable in enclosing type declaration parameters.
     for (DartType type in typeDeclaration.typeVariables) {
diff --git a/sdk/lib/_internal/compiler/implementation/dart_backend/utils.dart b/sdk/lib/_internal/compiler/implementation/dart_backend/utils.dart
index 3dbc248..4979d19 100644
--- a/sdk/lib/_internal/compiler/implementation/dart_backend/utils.dart
+++ b/sdk/lib/_internal/compiler/implementation/dart_backend/utils.dart
@@ -44,7 +44,7 @@
 
   visitClassNode(ClassNode node) => new ClassNode(
       visit(node.modifiers), visit(node.name), visit(node.typeParameters),
-      visit(node.superclass), visit(node.interfaces), visit(node.defaultClause),
+      visit(node.superclass), visit(node.interfaces),
       node.beginToken, node.extendsKeyword, visit(node.body), node.endToken);
 
   visitConditional(Conditional node) => new Conditional(
diff --git a/sdk/lib/_internal/compiler/implementation/elements/elements.dart b/sdk/lib/_internal/compiler/implementation/elements/elements.dart
index c036596..14fc59e 100644
--- a/sdk/lib/_internal/compiler/implementation/elements/elements.dart
+++ b/sdk/lib/_internal/compiler/implementation/elements/elements.dart
@@ -229,6 +229,7 @@
   bool get isImplementation;
   bool get isDeclaration;
   bool get isSynthesized;
+  bool get isForwardingConstructor;
 
   Element get implementation;
   Element get declaration;
@@ -246,6 +247,11 @@
   void setFixedBackendName(String name);
 
   Scope buildScope();
+
+  /// If the element is a forwarding constructor, [targetConstructor] holds
+  /// the generative constructor that the forwarding constructor points to
+  /// (possibly via other forwarding constructors).
+  FunctionElement get targetConstructor;
 }
 
 class Elements {
@@ -763,11 +769,6 @@
   void set resolutionState(int value);
   void set nativeTagInfo(SourceString value);
 
-  // TODO(kasperl): These seem outdated.
-  bool isInterface();
-  DartType get defaultClass;
-  void set defaultClass(DartType value);
-
   bool isObject(Compiler compiler);
   bool isSubclassOf(ClassElement cls);
   bool implementsInterface(ClassElement intrface);
@@ -823,6 +824,7 @@
 abstract class MixinApplicationElement extends ClassElement {
   ClassElement get mixin;
   void set mixin(ClassElement value);
+  void addConstructor(FunctionElement constructor);
 }
 
 abstract class LabelElement extends Element {
diff --git a/sdk/lib/_internal/compiler/implementation/elements/modelx.dart b/sdk/lib/_internal/compiler/implementation/elements/modelx.dart
index 909c4c6..4253cb1 100644
--- a/sdk/lib/_internal/compiler/implementation/elements/modelx.dart
+++ b/sdk/lib/_internal/compiler/implementation/elements/modelx.dart
@@ -132,6 +132,8 @@
 
   bool get isSynthesized => false;
 
+  bool get isForwardingConstructor => false;
+
   /**
    * Returns the element which defines the implementation for the entity of this
    * element.
@@ -270,6 +272,8 @@
 
   bool isAbstract(Compiler compiler) => modifiers.isAbstract();
   bool isForeign(Compiler compiler) => getLibrary() == compiler.foreignLibrary;
+
+  FunctionElement get targetConstructor => null;
 }
 
 /**
@@ -1088,19 +1092,15 @@
    * The patch should be parsed as if it was in the current scope. Its
    * signature must match this function's signature.
    */
-  // TODO(lrn): Consider using [defaultImplementation] to store the patch.
   FunctionElement patch = null;
   FunctionElement origin = null;
 
   /**
    * If this is a redirecting factory, [defaultImplementation] will be
-   * changed by the resolver to point to the redirection target.  If
-   * this is an interface constructor, [defaultImplementation] will be
-   * changed by the resolver to point to the default implementation.
+   * changed by the resolver to point to the redirection target.
    * Otherwise, [:identical(defaultImplementation, this):].
    */
-  // TODO(ahe): Rename this field to redirectionTarget and remove
-  // mention of interface constructors above.
+  // TODO(ahe): Rename this field to redirectionTarget.
   FunctionElement defaultImplementation;
 
   FunctionElementX(SourceString name,
@@ -1264,15 +1264,29 @@
   Token position() => constructor.position();
 }
 
+/**
+ * A constructor that is not defined in the source code but rather implied by
+ * the language semantics.
+ *
+ * This class is used to represent default constructors and forwarding
+ * constructors for mixin applications.
+ */
 class SynthesizedConstructorElementX extends FunctionElementX {
+  /// The target constructor if this synthetic constructor is a forwarding
+  /// constructor in a mixin application.
+  final FunctionElement target;
+
   SynthesizedConstructorElementX(Element enclosing)
-    : super(enclosing.name, ElementKind.GENERATIVE_CONSTRUCTOR,
-            Modifiers.EMPTY, enclosing);
+      : super(enclosing.name, ElementKind.GENERATIVE_CONSTRUCTOR,
+              Modifiers.EMPTY, enclosing),
+        target = null;
 
   SynthesizedConstructorElementX.forDefault(Element enclosing,
                                             Compiler compiler)
-    : super(enclosing.name, ElementKind.GENERATIVE_CONSTRUCTOR,
-            Modifiers.EMPTY, enclosing) {
+      : super(enclosing.name, ElementKind.GENERATIVE_CONSTRUCTOR,
+              Modifiers.EMPTY, enclosing),
+        target = null {
+    // TODO(karlklose): get rid of the fake AST.
     type = new FunctionType(this,
         compiler.types.voidType,
         const Link<DartType>(),
@@ -1286,9 +1300,40 @@
         null, Modifiers.EMPTY, null, null);
   }
 
-  bool get isSynthesized => true;
+  /**
+   * Create synthetic constructor that directly forwards to a constructor in the
+   * super class of a mixin application.
+   *
+   * In a mixin application `Base with M`, any constructor defined in `Base` is
+   * available as if they were a constructor defined in the mixin application
+   * with the same formal parameters that calls the constructor in the super
+   * class via a `super` initializer (see Ch. 9.1 in the specification).
+   */
+  SynthesizedConstructorElementX.forwarding(SourceString name, this.target,
+                                            Element enclosing)
+    : super(name, ElementKind.GENERATIVE_CONSTRUCTOR, Modifiers.EMPTY,
+            enclosing);
 
   Token position() => enclosingElement.position();
+
+  bool get isSynthesized => true;
+
+  bool get isForwardingConstructor => target != null;
+
+  FunctionElement get targetConstructor => target;
+
+  FunctionSignature computeSignature(compiler) {
+    if (target != null) {
+      return target.computeSignature(compiler);
+    } else {
+      assert(cachedNode != null);
+      return super.computeSignature(compiler);
+    }
+  }
+
+  get declaration => this;
+  get implementation => this;
+  get defaultImplementation => this;
 }
 
 class VoidElementX extends ElementX {
@@ -1360,7 +1405,6 @@
    */
   InterfaceType rawTypeCache;
   DartType supertype;
-  DartType defaultClass;
   Link<DartType> interfaces;
   SourceString nativeTagInfo;
   int supertypeLoadState;
@@ -1491,9 +1535,6 @@
       if (e.modifiers.isStatic()) continue;
       return e;
     }
-    if (isInterface()) {
-      return lookupSuperInterfaceMember(memberName, getLibrary());
-    }
     return null;
   }
 
@@ -1758,7 +1799,6 @@
     return false;
   }
 
-  bool isInterface() => false;
   bool isNative() => nativeTagInfo != null;
   void setNative(String name) {
     nativeTagInfo = new SourceString(name);
@@ -1840,7 +1880,8 @@
   final Node node;
   final Modifiers modifiers;
 
-  FunctionElement constructor;
+  Link<FunctionElement> constructors = new Link<FunctionElement>();
+
   ClassElement mixin;
 
   // TODO(kasperl): The analyzer complains when I don't have these two
@@ -1853,15 +1894,25 @@
       : super(name, enclosing, id, STATE_NOT_STARTED);
 
   bool get isMixinApplication => true;
-  bool get hasConstructor => constructor != null;
-  bool get hasLocalScopeMembers => false;
+  bool get hasConstructor => !constructors.isEmpty;
+  bool get hasLocalScopeMembers => !constructors.isEmpty;
 
   Token position() => node.getBeginToken();
 
   Node parseNode(DiagnosticListener listener) => node;
 
+  FunctionElement lookupLocalConstructor(SourceString name) {
+    for (Link<Element> link = constructors;
+         !link.isEmpty;
+         link = link.tail) {
+      if (link.head.name == name) return link.head;
+    }
+    return null;
+  }
+
   Element localLookup(SourceString name) {
-    if (this.name == name) return constructor;
+    Element constructor = lookupLocalConstructor(name);
+    if (constructor != null) return constructor;
     if (mixin == null) return null;
     Element mixedInElement = mixin.localLookup(name);
     if (mixedInElement == null) return null;
@@ -1869,6 +1920,7 @@
   }
 
   void forEachLocalMember(void f(Element member)) {
+    constructors.forEach(f);
     if (mixin != null) mixin.forEachLocalMember((Element mixedInElement) {
       if (mixedInElement.isInstanceMember()) f(mixedInElement);
     });
@@ -1879,12 +1931,16 @@
   }
 
   void addToScope(Element element, DiagnosticListener listener) {
-    throw new UnsupportedError("cannot add to scope of $this");
+    listener.internalError('cannot add to scope of $this', element: this);
+  }
+
+  void addConstructor(FunctionElement constructor) {
+    constructors = constructors.prepend(constructor);
   }
 
   void setDefaultConstructor(FunctionElement constructor, Compiler compiler) {
     assert(!hasConstructor);
-    this.constructor = constructor;
+    addConstructor(constructor);
   }
 
   Link<DartType> computeTypeParameters(Compiler compiler) {
diff --git a/sdk/lib/_internal/compiler/implementation/enqueue.dart b/sdk/lib/_internal/compiler/implementation/enqueue.dart
index 768ec2f..1278cd0 100644
--- a/sdk/lib/_internal/compiler/implementation/enqueue.dart
+++ b/sdk/lib/_internal/compiler/implementation/enqueue.dart
@@ -59,6 +59,11 @@
     assert(invariant(element, element.isDeclaration));
     if (element.isForeign(compiler)) return;
 
+    if (element.isForwardingConstructor) {
+      addToWorkList(element.targetConstructor, elements);
+      return;
+    }
+
     if (!addElementToWorkList(element, elements)) return;
 
     // Enable runtime type support if we discover a getter called runtimeType.
diff --git a/sdk/lib/_internal/compiler/implementation/js/nodes.dart b/sdk/lib/_internal/compiler/implementation/js/nodes.dart
index 9f57b32..1f1134c 100644
--- a/sdk/lib/_internal/compiler/implementation/js/nodes.dart
+++ b/sdk/lib/_internal/compiler/implementation/js/nodes.dart
@@ -934,7 +934,7 @@
   accept(NodeVisitor visitor) => visitor.visitInterpolatedExpression(this);
 
   void visitChildren(NodeVisitor visitor) {
-    value.accept(visitor);
+    if (value != null) value.accept(visitor);
   }
 
   int get precedenceLevel => value.precedenceLevel;
diff --git a/sdk/lib/_internal/compiler/implementation/js_backend/backend.dart b/sdk/lib/_internal/compiler/implementation/js_backend/backend.dart
index c1fd0aa..3cc71e4 100644
--- a/sdk/lib/_internal/compiler/implementation/js_backend/backend.dart
+++ b/sdk/lib/_internal/compiler/implementation/js_backend/backend.dart
@@ -680,6 +680,8 @@
   Element defineNativeMethodsFinishMethod;
   Element getDispatchPropertyMethod;
   Element setDispatchPropertyMethod;
+  Element initializeDispatchPropertyMethod;
+  bool needToInitializeDispatchProperty = false;
 
   bool seenAnyClass = false;
 
@@ -895,6 +897,9 @@
         compiler.findInterceptor(const SourceString('setDispatchProperty'));
     getNativeInterceptorMethod =
         compiler.findInterceptor(const SourceString('getNativeInterceptor'));
+    initializeDispatchPropertyMethod =
+        compiler.findInterceptor(
+            new SourceString(emitter.nameOfDispatchPropertyInitializer));
     defineNativeMethodsFinishMethod =
         compiler.findHelper(const SourceString('defineNativeMethodsFinish'));
 
@@ -1000,19 +1005,20 @@
     if (enqueuer.isResolutionQueue) {
       cls.ensureResolved(compiler);
       cls.forEachMember((ClassElement classElement, Element member) {
-          // All methods on [Object] are shadowed by [Interceptor].
-          if (classElement == compiler.objectClass) return;
-          Set<Element> set = interceptedElements.putIfAbsent(
-              member.name, () => new Set<Element>());
-          set.add(member);
-          if (classElement == jsInterceptorClass) return;
-          if (!classElement.isNative()) {
-            MixinApplicationElement mixinApplication = classElement;
-            assert(member.getEnclosingClass() == mixinApplication.mixin);
-            classesMixedIntoNativeClasses.add(mixinApplication.mixin);
-          }
-        },
-        includeSuperMembers: true);
+        if (member.isSynthesized) return;
+        // All methods on [Object] are shadowed by [Interceptor].
+        if (classElement == compiler.objectClass) return;
+        Set<Element> set = interceptedElements.putIfAbsent(
+            member.name, () => new Set<Element>());
+        set.add(member);
+        if (classElement == jsInterceptorClass) return;
+        if (!classElement.isNative()) {
+          MixinApplicationElement mixinApplication = classElement;
+          assert(member.getEnclosingClass() == mixinApplication.mixin);
+          classesMixedIntoNativeClasses.add(mixinApplication.mixin);
+        }
+      },
+      includeSuperMembers: true);
     }
   }
 
@@ -1067,6 +1073,9 @@
         // native classes.
         enqueuer.registerStaticUse(getNativeInterceptorMethod);
         enqueuer.registerStaticUse(defineNativeMethodsFinishMethod);
+        enqueuer.registerStaticUse(initializeDispatchPropertyMethod);
+        enqueuer.registerInstantiatedClass(jsInterceptorClass,
+                                           compiler.globalDependencies);
       }
     }
 
@@ -1143,6 +1152,10 @@
     // classes.
     enqueuer.registerStaticUse(getNativeInterceptorMethod);
     enqueuer.registerStaticUse(defineNativeMethodsFinishMethod);
+    enqueuer.registerStaticUse(initializeDispatchPropertyMethod);
+    TreeElements elements = compiler.globalDependencies;
+    enqueuer.registerInstantiatedClass(jsInterceptorClass, elements);
+    needToInitializeDispatchProperty = true;
   }
 
   JavaScriptItemCompilationContext createItemCompilationContext() {
diff --git a/sdk/lib/_internal/compiler/implementation/js_backend/emitter.dart b/sdk/lib/_internal/compiler/implementation/js_backend/emitter.dart
index 1966691..e9bb0f8 100644
--- a/sdk/lib/_internal/compiler/implementation/js_backend/emitter.dart
+++ b/sdk/lib/_internal/compiler/implementation/js_backend/emitter.dart
@@ -2365,6 +2365,25 @@
     return "${namer.isolateAccess(isolateMain)}($mainAccess)";
   }
 
+  String get nameOfDispatchPropertyInitializer => 'initializeDispatchProperty';
+
+  jsAst.Expression generateDispatchPropertyInitialization() {
+    String ref(Element element) {
+      return '${namer.CURRENT_ISOLATE}.${namer.getName(element)}';
+    }
+
+    return js(ref(backend.initializeDispatchPropertyMethod))([
+        js.fun(['a'], [ js('${ref(backend.getDispatchPropertyMethod)} = a')]),
+        js.string(generateDispatchPropertyName(0)),
+        js('${ref(backend.jsInterceptorClass)}.prototype')
+      ]);
+  }
+
+  String generateDispatchPropertyName(int seed) {
+    // TODO(sra): MD5 of contributing source code or URIs?
+    return '___dart_dispatch_record_ZxYxX_${seed}_';
+  }
+
   emitMain(CodeBuffer buffer) {
     if (compiler.isMockCompilation) return;
     Element main = compiler.mainApp.find(Compiler.MAIN);
@@ -2376,6 +2395,12 @@
     } else {
       mainCall = '${namer.isolateAccess(main)}()';
     }
+    if (backend.needToInitializeDispatchProperty) {
+      buffer.write(
+          jsAst.prettyPrint(generateDispatchPropertyInitialization(),
+                            compiler));
+    }
+    buffer.write(N);
     addComment('BEGIN invoke [main].', buffer);
     buffer.write("""
 if (typeof document !== "undefined" && document.readyState !== "complete") {
@@ -2873,6 +2898,7 @@
     jsAst.FunctionDeclaration decl = new jsAst.FunctionDeclaration(
         new jsAst.VariableDeclaration('init'), fun);
     buffer.write(jsAst.prettyPrint(decl, compiler).getText());
+    if (compiler.enableMinification) buffer.write('\n');
   }
 
   String assembleProgram() {
@@ -3031,7 +3057,8 @@
   }
 
   String buildSourceMap(CodeBuffer buffer, SourceFile compiledFile) {
-    SourceMapBuilder sourceMapBuilder = new SourceMapBuilder();
+    SourceMapBuilder sourceMapBuilder =
+        new SourceMapBuilder(compiler.sourceMapUri);
     buffer.forEachSourceLocation(sourceMapBuilder.addMapping);
     return sourceMapBuilder.build(compiledFile);
   }
diff --git a/sdk/lib/_internal/compiler/implementation/js_backend/emitter_no_eval.dart b/sdk/lib/_internal/compiler/implementation/js_backend/emitter_no_eval.dart
index f7abb04..e739b58 100644
--- a/sdk/lib/_internal/compiler/implementation/js_backend/emitter_no_eval.dart
+++ b/sdk/lib/_internal/compiler/implementation/js_backend/emitter_no_eval.dart
@@ -149,4 +149,30 @@
       js('Isolate.${namer.isolatePropertiesName} = isolateProperties'),
       js.return_('Isolate')]);
   }
+
+  String get nameOfDispatchPropertyInitializer =>
+      'initializeDispatchPropertyCSP';
+
+  jsAst.Expression generateDispatchPropertyInitialization() {
+    String ref(Element topLevelElement) {
+      return '${namer.CURRENT_ISOLATE}.${namer.getName(topLevelElement)}';
+    }
+
+    jsAst.Expression makeGetter(int seed) {
+      return js.fun('a',
+          js.return_(js('a.${generateDispatchPropertyName(seed)}')));
+    }
+
+    List<jsAst.Expression> getters = <jsAst.Expression>[
+        makeGetter(3),
+        makeGetter(2),
+        makeGetter(1),
+        makeGetter(0)];
+
+    return js(ref(backend.initializeDispatchPropertyMethod))([
+        js.fun(['a'], [ js('${ref(backend.getDispatchPropertyMethod)} = a')]),
+        new jsAst.ArrayInitializer.from(getters),
+        js('${ref(backend.jsInterceptorClass)}.prototype')
+      ]);
+  }
 }
diff --git a/sdk/lib/_internal/compiler/implementation/lib/interceptors.dart b/sdk/lib/_internal/compiler/implementation/lib/interceptors.dart
index d56fb0b..5d87979 100644
--- a/sdk/lib/_internal/compiler/implementation/lib/interceptors.dart
+++ b/sdk/lib/_internal/compiler/implementation/lib/interceptors.dart
@@ -42,11 +42,10 @@
 
 /**
  * The name of the property used on native classes and `Object.prototype` to get
- * the interceptor for a native class instance.
- * TODO(sra): The value should be initialized on isolate startup to a
- * cryptographic hash to prevent collisions.
+ * the interceptor for a native class instance.  The value is initialized on
+ * isolate startup.
  */
-var dispatchPropertyName = '_zzyzx';
+var dispatchPropertyName = null;
 
 getDispatchProperty(object) {
   // TODO(sra): Implement the magic.
@@ -139,6 +138,87 @@
 }
 
 /**
+ * Initializes the [getDispatchProperty] function and [dispatchPropertyName]
+ * variable.  Each isolate running in a web page needs a different
+ * [dispatchPropertyName], so if a given dispatch property name is in use by
+ * some other program loaded into the web page, another name is chosen.
+ *
+ * The non-CSP version is called like this:
+ *
+ *     initializeDispatchProperty(
+ *         function(x){$.getDispatchProperty=x},
+ *         '_f4$Dxv7S',
+ *         $.Interceptor);
+ *
+ * The [getDispatchProperty] function is generated from the chosen name of the
+ * property.
+ *
+ * The CSP version can't create functions via `new Function(...)`, so it is
+ * given a fixed set of functions to choose from.  If all the property names in
+ * the fixed set of functions are in use, it falls back on the definition of
+ * [getDispatchProperty] above.
+ *
+ *     initializeDispatchPropertyCSP(
+ *         function(x){$.getDispatchProperty=x},
+ *         [function(a){return a._f4$Dxv7S},
+ *          function(a){return a._Q2zpL9iY}],
+ *         $.Interceptor);
+ */
+void initializeDispatchProperty(
+    setGetDispatchPropertyFn, rootProperty, jsObjectInterceptor) {
+  // We must be extremely careful to avoid any language feature that needs an
+  // interceptor.  Avoid type annotations since they might generate type checks.
+  var objectProto = JS('=Object', 'Object.prototype');
+  for (var i = 0; ; i = JS('int', '# + 1', i)) {
+    var property = rootProperty;
+    if (JS('bool', '# > 0', i)) {
+      property = JS('String', '# + "_" + #', rootProperty, i);
+    }
+    if (JS('bool', 'typeof #[#] === "undefined"', objectProto, property)) {
+      dispatchPropertyName = property;
+      var getter = JS('', 'new Function("a", "return a." + #)', property);
+      JS('void', '#(#)', setGetDispatchPropertyFn, getter);
+      setDispatchProperty(
+          objectProto,
+          makeDispatchRecord(jsObjectInterceptor, objectProto, null));
+      return;
+    }
+  }
+}
+
+void initializeDispatchPropertyCSP(
+    setGetDispatchPropertyFn, getterFunctions, jsObjectInterceptor) {
+  // We must be extremely careful to avoid any language feature that needs an
+  // interceptor.  Avoid type annotations since they might generate type checks.
+  var objectProto = JS('=Object', 'Object.prototype');
+  var property = null;
+  var getter = null;
+  var rootProperty = null;
+  for (var i = 0; ; i = JS('int', '# + 1', i)) {
+    if (JS('bool', '# < #.length', i, getterFunctions)) {
+      getter = JS('', '#[#]', getterFunctions, i);
+      var fnText = JS('String', '"" + #', getter);
+      property =
+          JS('String', '#.match(#)[1]', fnText, JS('', r'/\.([^;}]*)/'));
+      rootProperty = property;
+    } else {
+      getter = null;
+      property = JS('String', '# + "_" + #', rootProperty, i);
+    }
+    if (JS('bool', 'typeof #[#] === "undefined"', objectProto, property)) {
+      dispatchPropertyName = property;
+      if (!identical(getter, null)) {
+        JS('void', '#(#)', setGetDispatchPropertyFn, getter);
+      }
+      setDispatchProperty(
+          objectProto,
+          makeDispatchRecord(jsObjectInterceptor, objectProto, null));
+      return;
+    }
+  }
+}
+
+/**
  * If [JSInvocationMirror._invokeOn] is being used, this variable
  * contains a JavaScript array with the names of methods that are
  * intercepted.
diff --git a/sdk/lib/_internal/compiler/implementation/lib/io_patch.dart b/sdk/lib/_internal/compiler/implementation/lib/io_patch.dart
index fab0cf5..a31da57 100644
--- a/sdk/lib/_internal/compiler/implementation/lib/io_patch.dart
+++ b/sdk/lib/_internal/compiler/implementation/lib/io_patch.dart
@@ -57,10 +57,10 @@
 }
 
 patch class FileSystemEntity {
-  patch static int _getType(String path, bool followLinks) {
+  patch static _getType(String path, bool followLinks) {
     throw new UnsupportedError("FileSystemEntity._getType");
   }
-  patch static bool _identical(String path1, String path2) {
+  patch static _identical(String path1, String path2) {
     throw new UnsupportedError("FileSystemEntity._identical");
   }
 }
diff --git a/sdk/lib/_internal/compiler/implementation/library_loader.dart b/sdk/lib/_internal/compiler/implementation/library_loader.dart
index 216bba8..b0784da 100644
--- a/sdk/lib/_internal/compiler/implementation/library_loader.dart
+++ b/sdk/lib/_internal/compiler/implementation/library_loader.dart
@@ -728,7 +728,7 @@
  * Helper class used for computing the possibly cyclic import/export scopes of
  * a set of libraries.
  *
- * This class is used by [ScannerTask.loadLibrary] to collect all newly loaded
+ * This class is used by [ScannerTask.scanLibrary] to collect all newly loaded
  * libraries and to compute their import/export scopes through a fixed-point
  * algorithm.
  */
diff --git a/sdk/lib/_internal/compiler/implementation/mirrors/dart2js_mirror.dart b/sdk/lib/_internal/compiler/implementation/mirrors/dart2js_mirror.dart
index 8dcfdab..8dec81c 100644
--- a/sdk/lib/_internal/compiler/implementation/mirrors/dart2js_mirror.dart
+++ b/sdk/lib/_internal/compiler/implementation/mirrors/dart2js_mirror.dart
@@ -291,8 +291,6 @@
 
   String get simpleName => _element.name.slowToString();
 
-  String get displayName => simpleName;
-
   /**
    * Computes the first token for this declaration using the begin token of the
    * element node or element position as indicator.
@@ -827,9 +825,7 @@
     return list;
   }
 
-  bool get isClass => !_class.isInterface();
-
-  bool get isInterface => _class.isInterface();
+  bool get isClass => true;
 
   bool get isAbstract => _class.modifiers.isAbstract();
 
@@ -852,16 +848,6 @@
     return _typeVariables;
   }
 
-  /**
-   * Returns the default type for this interface.
-   */
-  ClassMirror get defaultFactory {
-    if (_class.defaultClass != null) {
-      return new Dart2JsInterfaceTypeMirror(mirrors, _class.defaultClass);
-    }
-    return null;
-  }
-
   bool operator ==(Object other) {
     if (identical(this, other)) {
       return true;
@@ -940,8 +926,6 @@
 
   bool get isClass => false;
 
-  bool get isInterface => false;
-
   bool get isOriginalDeclaration => true;
 
   bool get isAbstract => false;
@@ -1047,8 +1031,6 @@
   Map<String, MethodMirror> get setters => const <String, MethodMirror>{};
 
   Map<String, VariableMirror> get variables => const <String, VariableMirror>{};
-
-  ClassMirror get defaultFactory => null;
 }
 
 class Dart2JsInterfaceTypeMirror extends Dart2JsTypeElementMirror
@@ -1081,8 +1063,6 @@
 
   bool get isClass => originalDeclaration.isClass;
 
-  bool get isInterface => originalDeclaration.isInterface;
-
   bool get isAbstract => originalDeclaration.isAbstract;
 
   bool get isPrivate => originalDeclaration.isPrivate;
@@ -1123,9 +1103,6 @@
   // TODO(johnniwinther): Substitute type arguments for type variables.
   Map<String, VariableMirror> get variables => originalDeclaration.variables;
 
-  // TODO(johnniwinther): Substitute type arguments for type variables?
-  ClassMirror get defaultFactory => originalDeclaration.defaultFactory;
-
   bool operator ==(Object other) {
     if (identical(this, other)) {
       return true;
@@ -1199,8 +1176,6 @@
 
   bool get isClass => originalDeclaration.isClass;
 
-  bool get isInterface => originalDeclaration.isInterface;
-
   bool get isPrivate => originalDeclaration.isPrivate;
 
   bool get isOriginalDeclaration => false;
@@ -1298,17 +1273,13 @@
     implements MethodMirror {
   final Dart2JsContainerMirror _objectMirror;
   final String simpleName;
-  final String displayName;
   final String constructorName;
-  final String operatorName;
   final Dart2JsMethodKind _kind;
 
   Dart2JsMethodMirror._internal(Dart2JsContainerMirror objectMirror,
       FunctionElement function,
       String this.simpleName,
-      String this.displayName,
       String this.constructorName,
-      String this.operatorName,
       Dart2JsMethodKind this._kind)
       : this._objectMirror = objectMirror,
         super(objectMirror.mirrors, function);
@@ -1320,16 +1291,12 @@
     // Elements.operatorNameToIdentifier.
     String simpleName =
         Elements.operatorNameToIdentifier(function.name).slowToString();
-    String displayName;
     String constructorName = null;
-    String operatorName = null;
     Dart2JsMethodKind kind;
     if (function.kind == ElementKind.GETTER) {
       kind = Dart2JsMethodKind.GETTER;
-      displayName = simpleName;
     } else if (function.kind == ElementKind.SETTER) {
       kind = Dart2JsMethodKind.SETTER;
-      displayName = simpleName;
       simpleName = '$simpleName=';
     } else if (function.kind == ElementKind.GENERATIVE_CONSTRUCTOR) {
       // TODO(johnniwinther): Support detection of redirecting constructors.
@@ -1348,7 +1315,6 @@
       } else {
         kind = Dart2JsMethodKind.GENERATIVE;
       }
-      displayName = simpleName;
     } else if (function.modifiers.isFactory()) {
       kind = Dart2JsMethodKind.FACTORY;
       constructorName = '';
@@ -1358,30 +1324,20 @@
         simpleName = simpleName.substring(0, dollarPos);
         simpleName = '$simpleName.$constructorName';
       }
-      // Simple name is TypeName.constructorName.
-      displayName = simpleName;
     } else if (realName == 'unary-') {
       kind = Dart2JsMethodKind.OPERATOR;
-      operatorName = '-';
       // Simple name is 'unary-'.
       simpleName = Mirror.UNARY_MINUS;
-      // Display name is 'operator operatorName'.
-      displayName = 'operator -';
     } else if (simpleName.startsWith('operator\$')) {
       String str = simpleName.substring(9);
       simpleName = 'operator';
       kind = Dart2JsMethodKind.OPERATOR;
-      operatorName = _getOperatorFromOperatorName(str);
-      // Simple name is 'operator operatorName'.
-      simpleName = operatorName;
-      // Display name is 'operator operatorName'.
-      displayName = 'operator $operatorName';
+      simpleName = _getOperatorFromOperatorName(str);
     } else {
       kind = Dart2JsMethodKind.REGULAR;
-      displayName = simpleName;
     }
     return new Dart2JsMethodMirror._internal(objectMirror, function,
-        simpleName, displayName, constructorName, operatorName, kind);
+        simpleName, constructorName, kind);
   }
 
   FunctionElement get _function => _element;
diff --git a/sdk/lib/_internal/compiler/implementation/mirrors/mirrors.dart b/sdk/lib/_internal/compiler/implementation/mirrors/mirrors.dart
index 1af5f14..4b2ad1b 100644
--- a/sdk/lib/_internal/compiler/implementation/mirrors/mirrors.dart
+++ b/sdk/lib/_internal/compiler/implementation/mirrors/mirrors.dart
@@ -68,14 +68,6 @@
   String get simpleName;
 
   /**
-   * The display name is the normal representation of the entity name. In most
-   * cases the display name is the simple name, but for a setter 'foo=' the
-   * display name is simply 'foo' and for the unary minus operator the display
-   * name is 'operator -'. The display name is not unique.
-   */
-  String get displayName;
-
-  /**
    * Returns the name of this entity qualified by is enclosing context. For
    * instance, the qualified name of a method 'method' in class 'Class' in
    * library 'library' is 'library.Class.method'.
@@ -366,11 +358,6 @@
   bool get isClass;
 
   /**
-   * Is [:true:] iff this type is an interface.
-   */
-  bool get isInterface;
-
-  /**
    * Is this the original declaration of this type?
    *
    * For most classes, they are their own original declaration.  For
@@ -438,11 +425,6 @@
    * declarations for this type.
    */
   Map<String, MethodMirror> get constructors;
-
-  /**
-   * Returns the default type for this interface.
-   */
-  ClassMirror get defaultFactory;
 }
 
 /**
@@ -611,12 +593,6 @@
    * Is [:true:] if this method is an operator method.
    */
   bool get isOperator;
-
-  /**
-   * Returns the operator name for operator methods, e.g. [:'<':] for
-   * [:operator <:]
-   */
-  String get operatorName;
 }
 
 /**
diff --git a/sdk/lib/_internal/compiler/implementation/mirrors/mirrors_util.dart b/sdk/lib/_internal/compiler/implementation/mirrors/mirrors_util.dart
index 41a085e..ae01ea0 100644
--- a/sdk/lib/_internal/compiler/implementation/mirrors/mirrors_util.dart
+++ b/sdk/lib/_internal/compiler/implementation/mirrors/mirrors_util.dart
@@ -13,6 +13,64 @@
 // Utility functions for using the Mirror API
 //------------------------------------------------------------------------------
 
+
+/**
+ * Return the display name for [mirror].
+ *
+ * The display name is the normal representation of the entity name. In most
+ * cases the display name is the simple name, but for a setter 'foo=' the
+ * display name is simply 'foo' and for the unary minus operator the display
+ * name is 'operator -'. For 'dart:' libraries the display name is the URI and
+ * not the library name, for instance 'dart:core' instead of 'dart.core'.
+ *
+ * The display name is not unique.
+ */
+String displayName(DeclarationMirror mirror) {
+  if (mirror is LibraryMirror) {
+    LibraryMirror library = mirror;
+    if (library.uri.scheme == 'dart') {
+      return library.uri.toString();
+    }
+  } else if (mirror is MethodMirror) {
+    MethodMirror methodMirror = mirror;
+    String simpleName = methodMirror.simpleName;
+    if (methodMirror.isSetter) {
+      // Remove trailing '='.
+      return simpleName.substring(0, simpleName.length-1);
+    } else if (methodMirror.isOperator) {
+      return 'operator ${operatorName(methodMirror)}';
+    } else if (methodMirror.isConstructor) {
+      // TODO(johnniwinther): Remove this when [simpleName] is
+      // [constructorName].
+      simpleName = methodMirror.constructorName;
+      String className = displayName(methodMirror.owner);
+      if (simpleName == '') {
+        return className;
+      } else {
+        return '$className.$simpleName';
+      }
+    }
+  }
+  return mirror.simpleName;
+}
+
+/**
+ * Returns the operator name if [methodMirror] is an operator method,
+ * for instance [:'<':] for [:operator <:] and [:'-':] for the unary minus
+ * operator. Return [:null:] if [methodMirror] is not an operator method.
+ */
+String operatorName(MethodMirror methodMirror) {
+  String simpleName = methodMirror.simpleName;
+  if (methodMirror.isOperator) {
+    if (simpleName == Mirror.UNARY_MINUS) {
+      return '-';
+    } else {
+      return simpleName;
+    }
+  }
+  return null;
+}
+
 /**
  * Returns an iterable over the type declarations directly inheriting from
  * the declaration of this type.
diff --git a/sdk/lib/_internal/compiler/implementation/native_handler.dart b/sdk/lib/_internal/compiler/implementation/native_handler.dart
index 27d990d..2b70c53 100644
--- a/sdk/lib/_internal/compiler/implementation/native_handler.dart
+++ b/sdk/lib/_internal/compiler/implementation/native_handler.dart
@@ -14,6 +14,7 @@
 import 'scanner/scannerlib.dart';
 import 'ssa/ssa.dart';
 import 'tree/tree.dart';
+import 'universe/universe.dart' show SideEffects;
 import 'util/util.dart';
 import 'js/js.dart' as js;
 
@@ -52,7 +53,7 @@
   /// Computes types instantiated due to setting a native field.
   void registerFieldStore(Element field) {}
 
-  NativeBehavior getNativeBehaviorOf(Send node) => null;
+  NativeBehavior getNativeBehaviorOf(Send node) => NativeBehavior.NONE;
 
   /**
    * Handles JS-calls, which can be an instantiation point for types.
@@ -498,6 +499,84 @@
   }
 }
 
+class SideEffectsVisitor extends js.BaseVisitor {
+  final SideEffects sideEffects;
+  SideEffectsVisitor(this.sideEffects);
+
+  void visit(js.Node node) {
+    node.accept(this);
+  }
+
+  void visitLiteralExpression(js.LiteralExpression node) {
+    sideEffects.setAllSideEffects();
+    sideEffects.setDependsOnSomething();
+    node.visitChildren(this);
+  }
+
+  void visitLiteralStatement(js.LiteralStatement node) {
+    sideEffects.setAllSideEffects();
+    sideEffects.setDependsOnSomething();
+    node.visitChildren(this);
+  }
+
+  void visitAssignment(js.Assignment node) {
+    sideEffects.setChangesStaticProperty();
+    sideEffects.setChangesInstanceProperty();
+    sideEffects.setChangesIndex();
+    node.visitChildren(this);
+  }
+
+  void visitVariableInitialization(js.VariableInitialization node) {
+    node.visitChildren(this);
+  }
+
+  void visitCall(js.Call node) {
+    sideEffects.setAllSideEffects();
+    sideEffects.setDependsOnSomething();
+    node.visitChildren(this);
+  }
+
+  void visitBinary(js.Binary node) {
+    node.visitChildren(this);
+  }
+
+  void visitThrow(js.Throw node) {
+    // TODO(ngeoffray): Incorporate a mayThrow flag in the
+    // [SideEffects] class.
+    sideEffects.setAllSideEffects();
+  }
+
+  void visitNew(js.New node) {
+    sideEffects.setAllSideEffects();
+    sideEffects.setDependsOnSomething();
+    node.visitChildren(this);
+  }
+
+  void visitPrefix(js.Prefix node) {
+    if (node.op == 'delete') {
+      sideEffects.setChangesStaticProperty();
+      sideEffects.setChangesInstanceProperty();
+      sideEffects.setChangesIndex();
+    }
+    node.visitChildren(this);
+  }
+
+  void visitVariableUse(js.VariableUse node) {
+    sideEffects.setDependsOnStaticPropertyStore();
+  }
+
+  void visitPostfix(js.Postfix node) {
+    node.visitChildren(this);
+  }
+
+  void visitAccess(js.PropertyAccess node) {
+    sideEffects.setDependsOnIndexStore();
+    sideEffects.setDependsOnInstancePropertyStore();
+    sideEffects.setDependsOnStaticPropertyStore();
+    node.visitChildren(this);
+  }
+}
+
 /**
  * A summary of the behavior of a native element.
  *
@@ -540,6 +619,10 @@
   // parsed tree.
   js.Expression codeAst;
 
+  final SideEffects sideEffects = new SideEffects.empty();
+
+  static NativeBehavior NONE = new NativeBehavior();
+
   static NativeBehavior ofJsCall(Send jsCall, Compiler compiler, resolver) {
     // The first argument of a JS-call is a string encoding various attributes
     // of the code.
@@ -567,6 +650,7 @@
 
     var behavior = new NativeBehavior();
     behavior.codeAst = js.js.parseForeignJS(code.dartString.slowToString());
+    new SideEffectsVisitor(behavior.sideEffects).visit(behavior.codeAst);
 
     String specString = specLiteral.dartString.slowToString();
     // Various things that are not in fact types.
@@ -917,7 +1001,8 @@
                                      element: element);
     }
 
-    builder.push(new HForeign(js.js(nativeMethodCall), HType.UNKNOWN, inputs));
+    builder.push(new HForeign(js.js(nativeMethodCall), HType.UNKNOWN,
+                              inputs, effects: new SideEffects()));
     builder.close(new HReturn(builder.pop())).addSuccessor(builder.graph.exit);
   } else {
     if (parameters.parameterCount != 0) {
@@ -928,6 +1013,7 @@
     LiteralString jsCode = nativeBody.asLiteralString();
     builder.push(new HForeign.statement(
         new js.LiteralStatement(jsCode.dartString.slowToString()),
-        <HInstruction>[]));
+        <HInstruction>[],
+        new SideEffects()));
   }
 }
diff --git a/sdk/lib/_internal/compiler/implementation/patch_parser.dart b/sdk/lib/_internal/compiler/implementation/patch_parser.dart
index 5a0da01..128ba88 100644
--- a/sdk/lib/_internal/compiler/implementation/patch_parser.dart
+++ b/sdk/lib/_internal/compiler/implementation/patch_parser.dart
@@ -8,7 +8,7 @@
  * Three types of elements can be patched: [LibraryElement], [ClassElement],
  * [FunctionElement]. Patches are introduced in patch libraries which are loaded
  * together with the corresponding origin library. Which libraries that are
- * patched is determined by the [dart2jsPatchPath] field of [LibraryInfo] found
+ * patched is determined by the dart2jsPatchPath field of LibraryInfo found
  * in [:lib/_internal/libraries.dart:].
  *
  * Patch libraries are parsed like regular library and thus provided with their
@@ -103,9 +103,9 @@
  * - Worklist only contain declaration elements.
  * - Most maps and sets use declarations exclusively, and their individual
  *   invariants are stated in the field comments.
- * - [TreeElements] only map to patch elements from inside a patch library.
+ * - [tree.TreeElements] only map to patch elements from inside a patch library.
  *   TODO(johnniwinther): Simplify this invariant to use only declarations in
- *   [TreeElements].
+ *   [tree.TreeElements].
  * - Builders shift between declaration and implementation depending on usages.
  * - Compile-time constants use constructor implementation exclusively.
  * - Work on function parameters is performed on the declaration of the function
diff --git a/sdk/lib/_internal/compiler/implementation/resolution/members.dart b/sdk/lib/_internal/compiler/implementation/resolution/members.dart
index 4b42981..49cd0f9 100644
--- a/sdk/lib/_internal/compiler/implementation/resolution/members.dart
+++ b/sdk/lib/_internal/compiler/implementation/resolution/members.dart
@@ -302,13 +302,12 @@
           if (tree.returnType != null) {
             error(tree, MessageKind.CONSTRUCTOR_WITH_RETURN_TYPE);
           }
-          resolveConstructorImplementation(element, tree);
         }
         ResolverVisitor visitor = visitorFor(element);
         visitor.useElement(tree, element);
         visitor.setupFunction(tree, element);
 
-        if (isConstructor) {
+        if (isConstructor && !element.isForwardingConstructor) {
           // Even if there is no initializer list we still have to do the
           // resolution in case there is an implicit super constructor call.
           InitializerResolver resolver = new InitializerResolver(visitor);
@@ -317,6 +316,8 @@
           if (redirection != null) {
             resolveRedirectingConstructor(resolver, tree, element, redirection);
           }
+        } else if (element.isForwardingConstructor) {
+          // Initializers will be checked on the original constructor.
         } else if (tree.initializers != null) {
           error(tree, MessageKind.FUNCTION_WITH_INITIALIZER);
         }
@@ -357,67 +358,6 @@
     }
   }
 
-  void resolveConstructorImplementation(FunctionElement constructor,
-                                        FunctionExpression node) {
-    if (!identical(constructor.defaultImplementation, constructor)) return;
-    ClassElement intrface = constructor.getEnclosingClass();
-    if (!intrface.isInterface()) return;
-    DartType defaultType = intrface.defaultClass;
-    if (defaultType == null) {
-      error(node, MessageKind.NO_DEFAULT_CLASS,
-            {'interfaceName': intrface.name});
-    }
-    ClassElement defaultClass = defaultType.element;
-    defaultClass.ensureResolved(compiler);
-    assert(defaultClass.resolutionState == STATE_DONE);
-    assert(defaultClass.supertypeLoadState == STATE_DONE);
-    if (defaultClass.isInterface()) {
-      error(node, MessageKind.CANNOT_INSTANTIATE_INTERFACE,
-            {'interfaceName': defaultClass.name});
-    }
-    // We have now established the following:
-    // [intrface] is an interface, let's say "MyInterface".
-    // [defaultClass] is a class, let's say "MyClass".
-
-    Selector selector;
-    // If the default class implements the interface then we must use the
-    // default class' name. Otherwise we look for a factory with the name
-    // of the interface.
-    if (defaultClass.implementsInterface(intrface)) {
-      var constructorNameString = constructor.name.slowToString();
-      // Create selector based on constructor.name but where interface
-      // is replaced with default class name.
-      // TODO(ahe): Don't use string manipulations here.
-      int classNameSeparatorIndex = constructorNameString.indexOf('\$');
-      if (classNameSeparatorIndex < 0) {
-        selector = new Selector.callDefaultConstructor(
-            defaultClass.getLibrary());
-      } else {
-        selector = new Selector.callConstructor(
-            new SourceString(
-                constructorNameString.substring(classNameSeparatorIndex + 1)),
-            defaultClass.getLibrary());
-      }
-      constructor.defaultImplementation =
-          defaultClass.lookupConstructor(selector);
-    } else {
-      selector =
-          new Selector.callConstructor(constructor.name,
-                                       defaultClass.getLibrary());
-      constructor.defaultImplementation =
-          defaultClass.lookupFactoryConstructor(selector);
-    }
-    if (constructor.defaultImplementation == null) {
-      // We failed to find a constructor named either
-      // "MyInterface.name" or "MyClass.name".
-      // TODO(aprelev@gmail.com): Use constructorNameForDiagnostics in
-      // the error message below.
-      error(node,
-            MessageKind.CANNOT_FIND_CONSTRUCTOR2,
-            {'constructorName': selector.name, 'className': defaultClass.name});
-    }
-  }
-
   TreeElements resolveField(VariableElement element) {
     Node tree = element.parseNode(compiler);
     if(element.modifiers.isStatic() && element.variables.isTopLevel()) {
@@ -566,7 +506,6 @@
       element.computeType(compiler);
       // Copy class hiearchy from origin.
       element.supertype = element.origin.supertype;
-      element.defaultClass = element.origin.defaultClass;
       element.interfaces = element.origin.interfaces;
       element.allSupertypes = element.origin.allSupertypes;
       // Stepwise assignment to ensure invariant.
@@ -2574,20 +2513,8 @@
       warnArgumentMismatch(node.send, constructor);
       compiler.backend.registerThrowNoSuchMethod(mapping);
     }
-    compiler.withCurrentElement(constructor, () {
-      FunctionExpression tree = constructor.parseNode(compiler);
-      compiler.resolver.resolveConstructorImplementation(constructor, tree);
-    });
 
-    if (constructor.defaultImplementation != constructor) {
-      // Support for deprecated interface support.
-      // TODO(ngeoffray): Remove once we remove such support.
-      world.registerStaticUse(constructor.declaration);
-      world.registerInstantiatedClass(
-          constructor.getEnclosingClass().declaration, mapping);
-      constructor = constructor.defaultImplementation;
-    }
-    // [constructor.defaultImplementation] might be the implementation element
+    // [constructor] might be the implementation element
     // and only declaration elements may be registered.
     world.registerStaticUse(constructor.declaration);
     ClassElement cls = constructor.getEnclosingClass();
@@ -3237,9 +3164,6 @@
     element.interfaces = resolveInterfaces(node.interfaces, node.superclass);
     calculateAllSupertypes(element);
 
-    if (node.defaultClause != null) {
-      element.defaultClass = visit(node.defaultClause);
-    }
     element.addDefaultConstructorIfNeeded(compiler);
     return element.computeType(compiler);
   }
@@ -3279,15 +3203,38 @@
     return mixinApplication.computeType(compiler);
   }
 
+  bool isDefaultConstructor(FunctionElement constructor) {
+    return constructor.name == constructor.getEnclosingClass().name &&
+        constructor.computeSignature(compiler).parameterCount == 0;
+  }
+
+  FunctionElement createForwardingConstructor(FunctionElement constructor,
+                                              ClassElement target) {
+    ClassElement cls = constructor.getEnclosingClass();
+    SourceString constructorName;
+    if (constructor.name == cls.name) {
+      constructorName = target.name;
+    } else {
+      SourceString selector =
+          Elements.deconstructConstructorName(constructor.name, cls);
+      constructorName =
+          Elements.constructConstructorName(target.name, selector);
+    }
+    return new SynthesizedConstructorElementX.forwarding(constructorName,
+                                                         constructor,
+                                                         target);
+  }
+
   void doApplyMixinTo(MixinApplicationElement mixinApplication,
                       DartType supertype,
                       DartType mixinType) {
     assert(mixinApplication.supertype == null);
     mixinApplication.supertype = supertype;
 
+    Node node = mixinApplication.parseNode(compiler);
     // Named mixin application may have an 'implements' clause.
     NamedMixinApplication namedMixinApplication =
-        mixinApplication.parseNode(compiler).asNamedMixinApplication();
+        node.asNamedMixinApplication();
     Link<DartType> interfaces = (namedMixinApplication != null)
         ? resolveInterfaces(namedMixinApplication.interfaces,
                             namedMixinApplication.superclass)
@@ -3302,6 +3249,24 @@
 
     assert(mixinApplication.mixin == null);
     mixinApplication.mixin = resolveMixinFor(mixinApplication, mixinType);
+
+    // Create forwarding constructors for constructor defined in the superclass
+    // because they are now hidden by the mixin application.
+    ClassElement superclass = supertype.element;
+    superclass.forEachLocalMember((Element member) {
+      if (!member.isConstructor()) return;
+      if (member.isSynthesized && !member.isForwardingConstructor) return;
+      if (isDefaultConstructor(member)) return;
+      assert(invariant(node, !member.isFactoryConstructor(),
+             message: 'mixins cannot have factory constructors'));
+      // Skip forwarding constructors and use their target.
+      FunctionElement constructor =
+          member.isForwardingConstructor ? member.targetConstructor : member;
+      assert(invariant(node, !constructor.isForwardingConstructor));
+      FunctionElement forwarder =
+          createForwardingConstructor(constructor, mixinApplication);
+      mixinApplication.addConstructor(forwarder);
+    });
     mixinApplication.addDefaultConstructorIfNeeded(compiler);
     calculateAllSupertypes(mixinApplication);
   }
@@ -3332,62 +3297,11 @@
     return mixin;
   }
 
-  // TODO(johnniwinther): Remove when default class is no longer supported.
-  DartType visitTypeAnnotation(TypeAnnotation node) {
-    return visit(node.typeName);
-  }
-
   DartType resolveType(TypeAnnotation node) {
     // TODO(johnniwinther): Report errors/warnings on resolution failures.
     return typeResolver.resolveTypeAnnotation(this, node);
   }
 
-  // TODO(johnniwinther): Remove when default class is no longer supported.
-  DartType visitIdentifier(Identifier node) {
-    Element element = scope.lookup(node.source);
-    if (element == null) {
-      error(node, MessageKind.CANNOT_RESOLVE_TYPE,  {'typeName': node});
-      return null;
-    } else if (!element.impliesType() && !element.isTypeVariable()) {
-      error(node, MessageKind.NOT_A_TYPE, {'node': node});
-      return null;
-    } else {
-      if (element.isTypeVariable()) {
-        TypeVariableElement variableElement = element;
-        return variableElement.type;
-      } else if (element.isTypedef()) {
-        compiler.unimplemented('visitIdentifier for typedefs', node: node);
-      } else {
-        // TODO(ngeoffray): Use type variables.
-        return element.computeType(compiler);
-      }
-    }
-    return null;
-  }
-
-  // TODO(johnniwinther): Remove when default class is no longer supported.
-  DartType visitSend(Send node) {
-    Identifier prefix = node.receiver.asIdentifier();
-    if (prefix == null) {
-      error(node.receiver, MessageKind.NOT_A_PREFIX, {'node': node.receiver});
-      return null;
-    }
-    Element element = scope.lookup(prefix.source);
-    if (element == null || !identical(element.kind, ElementKind.PREFIX)) {
-      error(node.receiver, MessageKind.NOT_A_PREFIX, {'node': node.receiver});
-      return null;
-    }
-    PrefixElement prefixElement = element;
-    Identifier selector = node.selector.asIdentifier();
-    var e = prefixElement.lookupLocalMember(selector.source);
-    if (e == null || !e.impliesType()) {
-      error(node.selector, MessageKind.CANNOT_RESOLVE_TYPE,
-            {'typeName': node.selector});
-      return null;
-    }
-    return e.computeType(compiler);
-  }
-
   DartType resolveSupertype(ClassElement cls, TypeAnnotation superclass) {
     DartType supertype = typeResolver.resolveTypeAnnotation(
         this, superclass, onFailure: error);
@@ -3919,13 +3833,6 @@
     if (!Elements.isUnresolved(e) && e.isClass()) {
       ClassElement cls = e;
       cls.ensureResolved(compiler);
-      if (cls.isInterface() && (cls.defaultClass == null)) {
-        // TODO(ahe): Remove this check and error message when we
-        // don't have interfaces anymore.
-        error(diagnosticNode,
-              MessageKind.CANNOT_INSTANTIATE_INTERFACE,
-              {'interfaceName': cls.name});
-      }
       // The unnamed constructor may not exist, so [e] may become unresolved.
       e = lookupConstructor(cls, diagnosticNode, const SourceString(''));
     }
@@ -3955,11 +3862,6 @@
     if (identical(e.kind, ElementKind.CLASS)) {
       ClassElement cls = e;
       cls.ensureResolved(compiler);
-      if (cls.isInterface() && (cls.defaultClass == null)) {
-        error(node.receiver,
-              MessageKind.CANNOT_INSTANTIATE_INTERFACE,
-              {'interfaceName': cls.name});
-      }
       return lookupConstructor(cls, name, name.source);
     } else if (identical(e.kind, ElementKind.PREFIX)) {
       PrefixElement prefix = e;
diff --git a/sdk/lib/_internal/compiler/implementation/resolution/resolution.dart b/sdk/lib/_internal/compiler/implementation/resolution/resolution.dart
index 1b3b927..1ae56b2 100644
--- a/sdk/lib/_internal/compiler/implementation/resolution/resolution.dart
+++ b/sdk/lib/_internal/compiler/implementation/resolution/resolution.dart
@@ -21,7 +21,8 @@
          LabelElementX,
          TargetElementX,
          MixinApplicationElementX,
-         TypedefElementX;
+         TypedefElementX,
+         SynthesizedConstructorElementX;
 import '../util/util.dart';
 import '../scanner/scannerlib.dart' show PartialMetadataAnnotation;
 
diff --git a/sdk/lib/_internal/compiler/implementation/resolution/scope.dart b/sdk/lib/_internal/compiler/implementation/resolution/scope.dart
index 92e7840..0af9fd7 100644
--- a/sdk/lib/_internal/compiler/implementation/resolution/scope.dart
+++ b/sdk/lib/_internal/compiler/implementation/resolution/scope.dart
@@ -45,7 +45,7 @@
  * [TypeDeclarationScope] defines the outer scope of a type declaration in
  * which the declared type variables and the entities in the enclosing scope are
  * available but where declared and inherited members are not available. This
- * scope is only used for class/interface declarations during resolution of the
+ * scope is only used for class declarations during resolution of the
  * class hierarchy. In all other cases [ClassScope] is used.
  */
 class TypeDeclarationScope extends NestedScope {
diff --git a/sdk/lib/_internal/compiler/implementation/resolution/secret_tree_element.dart b/sdk/lib/_internal/compiler/implementation/resolution/secret_tree_element.dart
index e8ee0f1..c9a67a6 100644
--- a/sdk/lib/_internal/compiler/implementation/resolution/secret_tree_element.dart
+++ b/sdk/lib/_internal/compiler/implementation/resolution/secret_tree_element.dart
@@ -11,7 +11,7 @@
  *
  * We have taken great care to ensure AST nodes can be cached between
  * compiler instances.  Part of this is requires that we always access
- * resolution results through [TreeElements].
+ * resolution results through TreeElements.
  *
  * So please, do not add additional elements to this library, and do
  * not import it.
@@ -29,7 +29,7 @@
 
 /**
  * Do not call this method directly.  Instead, use an instance of
- * [TreeElements].
+ * TreeElements.
  *
  * Using [Object] as return type to thwart code completion.
  */
@@ -39,7 +39,7 @@
 
 /**
  * Do not call this method directly.  Instead, use an instance of
- * [TreeElements].
+ * TreeElements.
  */
 void setTreeElement(TreeElementMixin node, Object value) {
   node._element = value;
diff --git a/sdk/lib/_internal/compiler/implementation/scanner/class_element_parser.dart b/sdk/lib/_internal/compiler/implementation/scanner/class_element_parser.dart
index 1e359aa..793c850 100644
--- a/sdk/lib/_internal/compiler/implementation/scanner/class_element_parser.dart
+++ b/sdk/lib/_internal/compiler/implementation/scanner/class_element_parser.dart
@@ -61,8 +61,6 @@
   // TODO(johnniwinther): Ensure that modifiers are always available.
   Modifiers get modifiers =>
       cachedNode != null ? cachedNode.modifiers : Modifiers.EMPTY;
-
-  bool isInterface() => identical(beginToken.stringValue, "interface");
 }
 
 class MemberListener extends NodeListener {
@@ -88,6 +86,7 @@
     return enclosingElement.name == name;
   }
 
+  // TODO(johnniwinther): Remove this method.
   SourceString getMethodNameHack(Node methodName) {
     Send send = methodName.asSend();
     if (send == null) return methodName.asIdentifier().source;
@@ -106,7 +105,9 @@
                         'implemented', node: send.receiver);
       }
       if (receiver.source != enclosingElement.name) {
-        listener.onDeprecatedFeature(receiver, 'interface factories');
+        listener.reportErrorCode(receiver,
+                                 MessageKind.INVALID_CONSTRUCTOR_NAME,
+                                 {'name': enclosingElement.name});
       }
       return Elements.constructConstructorName(receiver.source,
                                                selector.source);
@@ -143,7 +144,9 @@
     Identifier singleIdentifierName = method.name.asIdentifier();
     if (singleIdentifierName != null && singleIdentifierName.source == name) {
       if (name != enclosingElement.name) {
-        listener.onDeprecatedFeature(method.name, 'interface factories');
+        listener.reportErrorCode(singleIdentifierName,
+                                 MessageKind.INVALID_UNNAMED_CONSTRUCTOR_NAME,
+                                 {'name': enclosingElement.name});
       }
     }
     ElementKind kind = ElementKind.FUNCTION;
diff --git a/sdk/lib/_internal/compiler/implementation/scanner/keyword.dart b/sdk/lib/_internal/compiler/implementation/scanner/keyword.dart
index 9138e0f..d17bc8c 100644
--- a/sdk/lib/_internal/compiler/implementation/scanner/keyword.dart
+++ b/sdk/lib/_internal/compiler/implementation/scanner/keyword.dart
@@ -54,7 +54,6 @@
       const Keyword("get", isBuiltIn: true),
       const Keyword("implements", isBuiltIn: true),
       const Keyword("import", isBuiltIn: true),
-      const Keyword("interface", isBuiltIn: true),
       const Keyword("library", isBuiltIn: true),
       const Keyword("operator", isBuiltIn: true),
       const Keyword("part", isBuiltIn: true),
diff --git a/sdk/lib/_internal/compiler/implementation/scanner/listener.dart b/sdk/lib/_internal/compiler/implementation/scanner/listener.dart
index 6e83386..5c3243a 100644
--- a/sdk/lib/_internal/compiler/implementation/scanner/listener.dart
+++ b/sdk/lib/_internal/compiler/implementation/scanner/listener.dart
@@ -87,15 +87,6 @@
   void endExpressionStatement(Token token) {
   }
 
-  void beginDefaultClause(Token token) {
-  }
-
-  void handleNoDefaultClause(Token token) {
-  }
-
-  void endDefaultClause(Token defaultKeyword) {
-  }
-
   void beginFactoryMethod(Token token) {
   }
 
@@ -228,13 +219,6 @@
   void handleNoInitializers() {
   }
 
-  void beginInterface(Token token) {
-  }
-
-  void endInterface(int supertypeCount, Token interfaceKeyword,
-                    Token extendsKeyword, Token endToken) {
-  }
-
   void handleLabel(Token token) {
   }
 
@@ -813,31 +797,6 @@
     }
   }
 
-  void endDefaultClause(Token defaultKeyword) {
-    NodeList typeParameters = popNode();
-    Node name = popNode();
-    pushNode(new TypeAnnotation(name, typeParameters));
-  }
-
-  void handleNoDefaultClause(Token token) {
-    pushNode(null);
-  }
-
-  void endInterface(int supertypeCount, Token interfaceKeyword,
-                    Token extendsKeyword, Token endToken) {
-    // TODO(ahe): Record the defaultClause.
-    Node defaultClause = popNode();
-    NodeList supertypes =
-        makeNodeList(supertypeCount, extendsKeyword, null, ",");
-    NodeList typeParameters = popNode();
-    Identifier name = popNode();
-    int id = idGenerator();
-    pushElement(new PartialClassElement(
-        name.source, interfaceKeyword, endToken, compilationUnitElement, id));
-    rejectBuiltInIdentifier(name);
-    listener.onDeprecatedFeature(interfaceKeyword, 'interface declarations');
-  }
-
   void endFunctionTypeAlias(Token typedefKeyword, Token endToken) {
     NodeList typeVariables = popNode(); // TOOD(karlklose): do not throw away.
     Identifier name = popNode();
@@ -1228,7 +1187,7 @@
     Identifier name = popNode();
     Modifiers modifiers = popNode();
     pushNode(new ClassNode(modifiers, name, typeParameters, supertype,
-                           interfaces, null, beginToken, extendsKeyword, body,
+                           interfaces, beginToken, extendsKeyword, body,
                            endToken));
   }
 
@@ -1259,19 +1218,6 @@
                                        typedefKeyword, endToken));
   }
 
-  void endInterface(int supertypeCount, Token interfaceKeyword,
-                    Token extendsKeyword, Token endToken) {
-    NodeList body = popNode();
-    TypeAnnotation defaultClause = popNode();
-    NodeList supertypes = makeNodeList(supertypeCount, extendsKeyword,
-                                       null, ',');
-    NodeList typeParameters = popNode();
-    Identifier name = popNode();
-    pushNode(new ClassNode(Modifiers.EMPTY, name, typeParameters, null,
-                           supertypes, defaultClause, interfaceKeyword, null,
-                           body, endToken));
-  }
-
   void endClassBody(int memberCount, Token beginToken, Token endToken) {
     pushNode(makeNodeList(memberCount, beginToken, endToken, null));
   }
diff --git a/sdk/lib/_internal/compiler/implementation/scanner/parser.dart b/sdk/lib/_internal/compiler/implementation/scanner/parser.dart
index fc740d6..2a6edb6 100644
--- a/sdk/lib/_internal/compiler/implementation/scanner/parser.dart
+++ b/sdk/lib/_internal/compiler/implementation/scanner/parser.dart
@@ -48,9 +48,7 @@
   Token parseTopLevelDeclaration(Token token) {
     token = parseMetadataStar(token);
     final String value = token.stringValue;
-    if (identical(value, 'interface')) {
-      return parseInterface(token);
-    } else if ((identical(value, 'abstract')) || (identical(value, 'class'))) {
+    if ((identical(value, 'abstract')) || (identical(value, 'class'))) {
       return parseClass(token);
     } else if (identical(value, 'typedef')) {
       return parseTypedef(token);
@@ -235,31 +233,6 @@
     return token;
   }
 
-  Token parseInterface(Token token) {
-    Token interfaceKeyword = token;
-    listener.beginInterface(token);
-    token = parseIdentifier(token.next);
-    token = parseTypeVariablesOpt(token);
-    int supertypeCount = 0;
-    Token extendsKeyword = null;
-    if (optional('extends', token)) {
-      extendsKeyword = token;
-      do {
-        token = parseType(token.next);
-        ++supertypeCount;
-      } while (optional(',', token));
-    }
-    token = parseDefaultClauseOpt(token);
-    token = parseInterfaceBody(token);
-    listener.endInterface(supertypeCount, interfaceKeyword,
-                          extendsKeyword, token);
-    return token.next;
-  }
-
-  Token parseInterfaceBody(Token token) {
-    return parseClassBody(token);
-  }
-
   Token parseTypedef(Token token) {
     Token typedefKeyword = token;
     if (optional('=', peekAfterType(token.next))) {
@@ -411,21 +384,6 @@
     return false;
   }
 
-  Token parseDefaultClauseOpt(Token token) {
-    if (isDefaultKeyword(token)) {
-      // TODO(ahe): Remove support for 'factory' in this position.
-      Token defaultKeyword = token;
-      listener.beginDefaultClause(defaultKeyword);
-      token = parseIdentifier(token.next);
-      token = parseQualifiedRestOpt(token);
-      token = parseTypeVariablesOpt(token);
-      listener.endDefaultClause(defaultKeyword);
-    } else {
-      listener.handleNoDefaultClause(token);
-    }
-    return token;
-  }
-
   Token parseQualified(Token token) {
     token = parseIdentifier(token);
     while (optional('.', token)) {
@@ -885,7 +843,7 @@
 
   /**
    * Returns the token after the type which is expected to begin at [token].
-   * If [token] is not the start of a type, [Listener.unexpectedType] is called.
+   * If [token] is not the start of a type, [Listener.expectedType] is called.
    */
   Token peekAfterExpectedType(Token token) {
     if (!identical('void', token.stringValue) && !token.isIdentifier()) {
diff --git a/sdk/lib/_internal/compiler/implementation/source_map_builder.dart b/sdk/lib/_internal/compiler/implementation/source_map_builder.dart
index 6f379b2..2f732d3 100644
--- a/sdk/lib/_internal/compiler/implementation/source_map_builder.dart
+++ b/sdk/lib/_internal/compiler/implementation/source_map_builder.dart
@@ -4,9 +4,12 @@
 
 library source_map_builder;
 
+import 'dart:uri';
+
 import 'util/util.dart';
 import 'scanner/scannerlib.dart' show Token;
 import 'source_file.dart';
+import 'util/uri_extras.dart' show relativize;
 
 class SourceMapBuilder {
   static const int VLQ_BASE_SHIFT = 5;
@@ -16,6 +19,8 @@
   static const String BASE64_DIGITS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmn'
                                       'opqrstuvwxyz0123456789+/';
 
+  final Uri uri;
+
   List<SourceMapEntry> entries;
 
   Map<String, int> sourceUrlMap;
@@ -31,7 +36,7 @@
   int previousSourceNameIndex;
   bool firstEntryInLine;
 
-  SourceMapBuilder() {
+  SourceMapBuilder(this.uri) {
     entries = new List<SourceMapEntry>();
 
     sourceUrlMap = new Map<String, int>();
@@ -74,6 +79,11 @@
     buffer.write('  "version": 3,\n');
     buffer.write('  "sourceRoot": "",\n');
     buffer.write('  "sources": ');
+    if (uri != null) {
+      sourceUrlList =
+          sourceUrlList.map((url) => relativize(uri, Uri.parse(url), false))
+              .toList();
+    }
     printStringListOn(sourceUrlList, buffer);
     buffer.write(',\n');
     buffer.write('  "names": ');
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/builder.dart b/sdk/lib/_internal/compiler/implementation/ssa/builder.dart
index b769c27..ba26fe2 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/builder.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/builder.dart
@@ -1305,9 +1305,11 @@
 
       // Build the initializers in the context of the new constructor.
       TreeElements oldElements = elements;
+      if (constructor.isForwardingConstructor) {
+        constructor = constructor.targetConstructor;
+      }
       elements =
           compiler.enqueuer.resolution.getCachedElements(constructor);
-
       ClosureClassMap oldClosureData = localsHandler.closureData;
       Node node = constructor.parseNode(compiler);
       ClosureClassMap newClosureData =
@@ -2679,12 +2681,8 @@
 
   HForeign createForeign(String code,
                          HType type,
-                         List<HInstruction> inputs,
-                         {bool isSideEffectFree: false}) {
-    return new HForeign(js.js.parseForeignJS(code),
-                        type,
-                        inputs,
-                        isSideEffectFree: isSideEffectFree);
+                         List<HInstruction> inputs) {
+    return new HForeign(js.js.parseForeignJS(code), type, inputs);
   }
 
   HInstruction getRuntimeTypeInfo(HInstruction target) {
@@ -2883,6 +2881,10 @@
       return pop();
     }
 
+    if (element.isForwardingConstructor) {
+      element = element.targetConstructor;
+    }
+
     return selector.addArgumentsToList(arguments,
                                        list,
                                        element,
@@ -2991,7 +2993,8 @@
     addGenericSendArgumentsToList(link.tail.tail, inputs);
 
     HType ssaType = new HType.fromNativeBehavior(nativeBehavior, compiler);
-    push(new HForeign(nativeBehavior.codeAst, ssaType, inputs));
+    push(new HForeign(nativeBehavior.codeAst, ssaType, inputs,
+                      effects: nativeBehavior.sideEffects));
     return;
   }
 
@@ -3090,9 +3093,12 @@
     }
     visit(node.arguments.head);
     String isolateName = backend.namer.CURRENT_ISOLATE;
+    SideEffects sideEffects = new SideEffects.empty();
+    sideEffects.setAllSideEffects();
     push(new HForeign(js.js("$isolateName = #"),
                       HType.UNKNOWN,
-                      <HInstruction>[pop()]));
+                      <HInstruction>[pop()],
+                      effects: sideEffects));
   }
 
   void handleForeignCreateIsolate(Send node) {
@@ -3308,8 +3314,7 @@
       inputs.add(addTypeVariableReference(variable));
     });
 
-    HInstruction result = createForeign(
-        template, HType.STRING, inputs, isSideEffectFree: true);
+    HInstruction result = createForeign(template, HType.STRING, inputs);
     add(result);
     return result;
   }
@@ -3375,6 +3380,10 @@
 
     Element constructor = elements[node];
     Selector selector = elements.getSelector(node);
+    if (constructor.isForwardingConstructor) {
+      compiler.unimplemented('forwarded constructor in named mixin application',
+                             element: constructor.getEnclosingClass());
+    }
     if (compiler.enqueuer.resolution.getCachedElements(constructor) == null) {
       compiler.internalError("Unresolved element: $constructor", node: node);
     }
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/nodes.dart b/sdk/lib/_internal/compiler/implementation/ssa/nodes.dart
index aa28dfd..727bcc9 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/nodes.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/nodes.dart
@@ -1471,28 +1471,27 @@
 class HForeign extends HInstruction {
   final js.Node codeAst;
   final bool isStatement;
-  final bool isSideEffectFree;
 
   HForeign(this.codeAst,
            HType type,
            List<HInstruction> inputs,
            {this.isStatement: false,
-            this.isSideEffectFree: false})
+            SideEffects effects})
       : super(inputs) {
-    if (!isSideEffectFree) {
-      sideEffects.setAllSideEffects();
-      sideEffects.setDependsOnSomething();
-    }
+    if (effects != null) sideEffects.add(effects);
     instructionType = type;
   }
 
-  HForeign.statement(codeAst, List<HInstruction> inputs)
-      : this(codeAst, HType.UNKNOWN, inputs, isStatement: true);
+  HForeign.statement(codeAst, List<HInstruction> inputs, SideEffects effects)
+      : this(codeAst, HType.UNKNOWN, inputs, isStatement: true,
+             effects: effects);
 
   accept(HVisitor visitor) => visitor.visitForeign(this);
 
   bool isJsStatement() => isStatement;
-  bool canThrow() => !isSideEffectFree;
+  bool canThrow() {
+    return sideEffects.hasSideEffects() || sideEffects.dependsOnSomething();
+  }
 }
 
 class HForeignNew extends HForeign {
diff --git a/sdk/lib/_internal/compiler/implementation/tools/mini_parser.dart b/sdk/lib/_internal/compiler/implementation/tools/mini_parser.dart
index 17578d5..ba3f01d 100644
--- a/sdk/lib/_internal/compiler/implementation/tools/mini_parser.dart
+++ b/sdk/lib/_internal/compiler/implementation/tools/mini_parser.dart
@@ -229,13 +229,6 @@
     ClassNode node = popNode(); // Discard ClassNode and assert the type.
   }
 
-  void endInterface(int supertypeCount, Token interfaceKeyword,
-                    Token extendsKeyword, Token endToken) {
-    super.endInterface(supertypeCount, interfaceKeyword, extendsKeyword,
-                       endToken);
-    ClassNode node = popNode(); // Discard ClassNode and assert the type.
-  }
-
   void endTopLevelFields(int count, Token beginToken, Token endToken) {
     super.endTopLevelFields(count, beginToken, endToken);
     VariableDefinitions node = popNode(); // Discard node and assert the type.
diff --git a/sdk/lib/_internal/compiler/implementation/tree/nodes.dart b/sdk/lib/_internal/compiler/implementation/tree/nodes.dart
index 604ef46..659e7b0 100644
--- a/sdk/lib/_internal/compiler/implementation/tree/nodes.dart
+++ b/sdk/lib/_internal/compiler/implementation/tree/nodes.dart
@@ -213,15 +213,12 @@
   final NodeList typeParameters;
   final NodeList body;
 
-  // TODO(ahe, karlklose): the default keyword is not recorded.
-  final TypeAnnotation defaultClause;
-
   final Token beginToken;
   final Token extendsKeyword;
   final Token endToken;
 
   ClassNode(this.modifiers, this.name, this.typeParameters, this.superclass,
-            this.interfaces, this.defaultClause, this.beginToken,
+            this.interfaces, this.beginToken,
             this.extendsKeyword, this.body, this.endToken);
 
   ClassNode asClassNode() => this;
@@ -236,10 +233,6 @@
     if (body != null) body.accept(visitor);
   }
 
-  bool get isInterface => identical(beginToken.stringValue, 'interface');
-
-  bool get isClass => !isInterface;
-
   Token getBeginToken() => beginToken;
 
   Token getEndToken() => endToken;
diff --git a/sdk/lib/_internal/compiler/implementation/tree/prettyprint.dart b/sdk/lib/_internal/compiler/implementation/tree/prettyprint.dart
index 9f2cfbf..6d85e08 100644
--- a/sdk/lib/_internal/compiler/implementation/tree/prettyprint.dart
+++ b/sdk/lib/_internal/compiler/implementation/tree/prettyprint.dart
@@ -152,7 +152,6 @@
     visitChildNode(node.superclass, "superclass");
     visitChildNode(node.interfaces, "interfaces");
     visitChildNode(node.typeParameters, "typeParameters");
-    visitChildNode(node.defaultClause, "defaultClause");
     closeNode();
   }
 
diff --git a/sdk/lib/_internal/compiler/implementation/tree/unparser.dart b/sdk/lib/_internal/compiler/implementation/tree/unparser.dart
index f0f0de3..274117b 100644
--- a/sdk/lib/_internal/compiler/implementation/tree/unparser.dart
+++ b/sdk/lib/_internal/compiler/implementation/tree/unparser.dart
@@ -66,10 +66,6 @@
       sb.write(' ');
       visit(node.interfaces);
     }
-    if (node.defaultClause != null) {
-      sb.write(' default ');
-      visit(node.defaultClause);
-    }
     sb.write('{');
     for (final member in members) {
       visit(member);
diff --git a/sdk/lib/_internal/compiler/implementation/types/flat_type_mask.dart b/sdk/lib/_internal/compiler/implementation/types/flat_type_mask.dart
new file mode 100644
index 0000000..4e2bf37
--- /dev/null
+++ b/sdk/lib/_internal/compiler/implementation/types/flat_type_mask.dart
@@ -0,0 +1,594 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for 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 types;
+
+/**
+ * A flat type mask is a type mask that has been flatten to contain a
+ * base type.
+ */
+class FlatTypeMask implements TypeMask {
+
+  static const int EMPTY    = 0;
+  static const int EXACT    = 1;
+  static const int SUBCLASS = 2;
+  static const int SUBTYPE  = 3;
+
+  final DartType base;
+  final int flags;
+
+  FlatTypeMask(DartType base, int kind, bool isNullable)
+      : this.internal(base, (kind << 1) | (isNullable ? 1 : 0));
+
+  FlatTypeMask.empty()
+      : this.internal(null, (EMPTY << 1) | 1);
+  FlatTypeMask.exact(DartType base)
+      : this.internal(base, (EXACT << 1) | 1);
+  FlatTypeMask.subclass(DartType base)
+      : this.internal(base, (SUBCLASS << 1) | 1);
+  FlatTypeMask.subtype(DartType base)
+      : this.internal(base, (SUBTYPE << 1) | 1);
+
+  FlatTypeMask.nonNullEmpty()
+      : this.internal(null, EMPTY << 1);
+  FlatTypeMask.nonNullExact(DartType base)
+      : this.internal(base, EXACT << 1);
+  FlatTypeMask.nonNullSubclass(DartType base)
+      : this.internal(base, SUBCLASS << 1);
+  FlatTypeMask.nonNullSubtype(DartType base)
+      : this.internal(base, SUBTYPE << 1);
+
+  FlatTypeMask.internal(DartType base, this.flags)
+      : this.base = transformBase(base) {
+    assert(base == null || !(isExact && base.isDynamic));
+  }
+
+  // TODO(kasperl): We temporarily transform the base to be the raw
+  // variant of the type. Long term, we're going to keep the class
+  // element corresponding to the type in the mask instead.
+  static DartType transformBase(DartType base) {
+    if (base == null) {
+      return null;
+    } else if (base.kind != TypeKind.INTERFACE) {
+      assert(base.kind == TypeKind.INTERFACE);
+      return null;
+    } else {
+      assert(!base.isMalformed);
+      return base.asRaw();
+    }
+  }
+
+  bool get isEmpty => (flags >> 1) == EMPTY;
+  bool get isExact => (flags >> 1) == EXACT;
+  bool get isNullable => (flags & 1) != 0;
+
+  // TODO(kasperl): Get rid of these. They should not be a visible
+  // part of the implementation because they make it hard to add
+  // proper union types if we ever want to.
+  bool get isSubclass => (flags >> 1) == SUBCLASS;
+  bool get isSubtype => (flags >> 1) == SUBTYPE;
+
+  TypeMask nullable() {
+    return isNullable ? this : new FlatTypeMask.internal(base, flags | 1);
+  }
+
+  TypeMask nonNullable() {
+    return isNullable ? new FlatTypeMask.internal(base, flags & ~1) : this;
+  }
+
+  bool contains(DartType type, Compiler compiler) {
+    if (isEmpty) {
+      return false;
+    } else if (identical(base.element, type.element)) {
+      return true;
+    } else if (isExact) {
+      return false;
+    } else if (isSubclass) {
+      return isSubclassOf(type, base, compiler);
+    } else {
+      assert(isSubtype);
+      return isSubtypeOf(type, base, compiler);
+    }
+  }
+
+  bool containsOnlyInt(Compiler compiler) {
+    return base.element == compiler.intClass
+        || base.element == compiler.backend.intImplementation;
+  }
+
+  bool containsOnlyDouble(Compiler compiler) {
+    return base.element == compiler.doubleClass
+        || base.element == compiler.backend.doubleImplementation;
+  }
+
+  bool containsOnlyNum(Compiler compiler) {
+    return base.element == compiler.numClass
+        || base.element == compiler.backend.numImplementation;
+  }
+
+  bool containsOnlyNull(Compiler compiler) {
+    return base.element == compiler.nullClass
+        || base.element == compiler.backend.nullImplementation;
+  }
+
+  bool containsOnlyBool(Compiler compiler) {
+    return base.element == compiler.boolClass
+        || base.element == compiler.backend.boolImplementation;
+  }
+
+  bool containsOnlyString(Compiler compiler) {
+    return base.element == compiler.stringClass
+        || base.element == compiler.backend.stringImplementation;
+  }
+
+  bool containsOnly(ClassElement cls) {
+    return base.element == cls;
+  }
+
+  /**
+   * Returns the [ClassElement] if this type represents a single class,
+   * otherwise returns `null`.  This method is conservative.
+   */
+  ClassElement singleClass(Compiler compiler) {
+    if (isEmpty) return null;
+    if (isNullable) return null;  // It is Null and some other class.
+    ClassElement element = base.element;
+    if (isExact) {
+      return element;
+    } else if (isSubclass) {
+      return compiler.world.hasAnySubclass(element) ? null : element;
+    } else {
+      assert(isSubtype);
+      return null;
+    }
+  }
+
+  /**
+   * Returns whether or not this type mask contains all types.
+   */
+  bool containsAll(Compiler compiler) {
+    if (isEmpty || isExact) return false;
+    return identical(base.element, compiler.objectClass)
+        || identical(base.element, compiler.dynamicClass);
+  }
+
+  TypeMask union(FlatTypeMask other, Compiler compiler) {
+    if (isEmpty) {
+      return isNullable ? other.nullable() : other;
+    } else if (other.isEmpty) {
+      return other.isNullable ? nullable() : this;
+    } else if (base == other.base) {
+      return unionSame(other, compiler);
+    } else if (isSubclassOf(other.base, base, compiler)) {
+      return unionSubclass(other, compiler);
+    } else if (isSubclassOf(base, other.base, compiler)) {
+      return other.unionSubclass(this, compiler);
+    } else if (isSubtypeOf(other.base, base, compiler)) {
+      return unionSubtype(other, compiler);
+    } else if (isSubtypeOf(base, other.base, compiler)) {
+      return other.unionSubtype(this, compiler);
+    } else {
+      return unionDisjoint(other, compiler);
+    }
+  }
+
+  TypeMask unionSame(FlatTypeMask other, Compiler compiler) {
+    assert(base == other.base);
+    // The two masks share the base type, so we must chose the least
+    // constraining kind (the highest) of the two. If either one of
+    // the masks are nullable the result should be nullable too.
+    int combined = (flags > other.flags)
+        ? flags | (other.flags & 1)
+        : other.flags | (flags & 1);
+    if (flags == combined) {
+      return this;
+    } else if (other.flags == combined) {
+      return other;
+    } else {
+      return new FlatTypeMask.internal(base, combined);
+    }
+  }
+
+  TypeMask unionSubclass(FlatTypeMask other, Compiler compiler) {
+    assert(isSubclassOf(other.base, base, compiler));
+    int combined;
+    if (isExact && other.isExact) {
+      // Since the other mask is a subclass of this mask, we need the
+      // resulting union to be a subclass too. If either one of the
+      // masks are nullable the result should be nullable too.
+      combined = (SUBCLASS << 1) | ((flags | other.flags) & 1);
+    } else {
+      // Both masks are at least subclass masks, so we pick the least
+      // constraining kind (the highest) of the two. If either one of
+      // the masks are nullable the result should be nullable too.
+      combined = (flags > other.flags)
+          ? flags | (other.flags & 1)
+          : other.flags | (flags & 1);
+    }
+    return (flags != combined)
+        ? new FlatTypeMask.internal(base, combined)
+        : this;
+  }
+
+  TypeMask unionSubtype(FlatTypeMask other, Compiler compiler) {
+    assert(isSubtypeOf(other.base, base, compiler));
+    // Since the other mask is a subtype of this mask, we need the
+    // resulting union to be a subtype too. If either one of the masks
+    // are nullable the result should be nullable too.
+    int combined = (SUBTYPE << 1) | ((flags | other.flags) & 1);
+    return (flags != combined)
+        ? new FlatTypeMask.internal(base, combined)
+        : this;
+  }
+
+  TypeMask unionDisjoint(FlatTypeMask other, Compiler compiler) {
+    assert(base != other.base);
+    assert(!isSubtypeOf(base, other.base, compiler));
+    assert(!isSubtypeOf(other.base, base, compiler));
+    // If either type mask is a subtype type mask, we cannot use a
+    // subclass type mask to represent their union.
+    bool useSubclass = !isSubtype && !other.isSubtype;
+    // Compute the common supertypes of the two types.
+    ClassElement thisElement = base.element;
+    ClassElement otherElement = other.base.element;
+    Iterable<ClassElement> candidates =
+        compiler.world.commonSupertypesOf(thisElement, otherElement);
+    if (candidates.isEmpty) {
+      // TODO(kasperl): Get rid of this check. It can only happen when
+      // at least one of the two base types is 'unseen'.
+      return new TypeMask(compiler.objectClass.rawType,
+                          SUBCLASS,
+                          isNullable || other.isNullable);
+    }
+    // Compute the best candidate and its kind.
+    ClassElement bestElement;
+    int bestKind;
+    int bestSize;
+    for (ClassElement candidate in candidates) {
+      Set<ClassElement> subclasses = useSubclass
+          ? compiler.world.subclasses[candidate]
+          : null;
+      int size;
+      int kind;
+      if (subclasses != null &&
+          subclasses.contains(thisElement) &&
+          subclasses.contains(otherElement)) {
+        // If both [this] and [other] are subclasses of the supertype,
+        // then we prefer to construct a subclass type mask because it
+        // will always be at least as small as the corresponding
+        // subtype type mask.
+        kind = SUBCLASS;
+        size = subclasses.length;
+        assert(size <= compiler.world.subtypes[candidate].length);
+      } else {
+        kind = SUBTYPE;
+        size = compiler.world.subtypes[candidate].length;
+      }
+      // Update the best candidate if the new one is better.
+      if (bestElement == null || size < bestSize) {
+        bestElement = candidate;
+        bestSize = size;
+        bestKind = kind;
+      }
+    }
+    return new TypeMask(bestElement.computeType(compiler),
+                        bestKind,
+                        isNullable || other.isNullable);
+  }
+
+  TypeMask intersection(FlatTypeMask other, Compiler compiler) {
+    if (isEmpty) {
+      return other.isNullable ? this : nonNullable();
+    } else if (other.isEmpty) {
+      return isNullable ? other : other.nonNullable();
+    } else if (base == other.base) {
+      return intersectionSame(other, compiler);
+    } else if (isSubclassOf(other.base, base, compiler)) {
+      return intersectionSubclass(other, compiler);
+    } else if (isSubclassOf(base, other.base, compiler)) {
+      return other.intersectionSubclass(this, compiler);
+    } else if (isSubtypeOf(other.base, base, compiler)) {
+      return intersectionSubtype(other, compiler);
+    } else if (isSubtypeOf(base, other.base, compiler)) {
+      return other.intersectionSubtype(this, compiler);
+    } else {
+      return intersectionDisjoint(other, compiler);
+    }
+  }
+
+  TypeMask intersectionSame(FlatTypeMask other, Compiler compiler) {
+    assert(base == other.base);
+    // The two masks share the base type, so we must chose the most
+    // constraining kind (the lowest) of the two. Only if both masks
+    // are nullable, will the result be nullable too.
+    int combined = (flags < other.flags)
+        ? flags & ((other.flags & 1) | ~1)
+        : other.flags & ((flags & 1) | ~1);
+    if (flags == combined) {
+      return this;
+    } else if (other.flags == combined) {
+      return other;
+    } else {
+      return new FlatTypeMask.internal(base, combined);
+    }
+  }
+
+  TypeMask intersectionSubclass(FlatTypeMask other, Compiler compiler) {
+    assert(isSubclassOf(other.base, base, compiler));
+    // If this mask isn't at least a subclass mask, then the
+    // intersection with the other mask is empty.
+    if (isExact) return intersectionEmpty(other);
+    // Only the other mask puts constraints on the intersection mask,
+    // so base the combined flags on the other mask. Only if both
+    // masks are nullable, will the result be nullable too.
+    int combined = other.flags & ((flags & 1) | ~1);
+    if (other.flags == combined) {
+      return other;
+    } else {
+      return new FlatTypeMask.internal(other.base, combined);
+    }
+  }
+
+  TypeMask intersectionSubtype(FlatTypeMask other, Compiler compiler) {
+    assert(isSubtypeOf(other.base, base, compiler));
+    if (!isSubtype) return intersectionHelper(other, compiler);
+    // Only the other mask puts constraints on the intersection mask,
+    // so base the combined flags on the other mask. Only if both
+    // masks are nullable, will the result be nullable too.
+    int combined = other.flags & ((flags & 1) | ~1);
+    if (other.flags == combined) {
+      return other;
+    } else {
+      return new FlatTypeMask.internal(other.base, combined);
+    }
+  }
+
+  TypeMask intersectionDisjoint(FlatTypeMask other, Compiler compiler) {
+    assert(base != other.base);
+    assert(!isSubtypeOf(base, other.base, compiler));
+    assert(!isSubtypeOf(other.base, base, compiler));
+    return intersectionHelper(other, compiler);
+  }
+
+  TypeMask intersectionHelper(FlatTypeMask other, Compiler compiler) {
+    assert(base != other.base);
+    assert(!isSubclassOf(base, other.base, compiler));
+    assert(!isSubclassOf(other.base, base, compiler));
+    // If one of the masks are exact or if both of them are subclass
+    // masks, then the intersection is empty.
+    if (isExact || other.isExact) return intersectionEmpty(other);
+    if (isSubclass && other.isSubclass) return intersectionEmpty(other);
+    assert(isSubtype || other.isSubtype);
+    int kind = (isSubclass || other.isSubclass) ? SUBCLASS : SUBTYPE;
+    // Compute the set of classes that are contained in both type masks.
+    Set<ClassElement> common = commonContainedClasses(this, other, compiler);
+    if (common == null || common.isEmpty) return intersectionEmpty(other);
+    // Narrow down the candidates by only looking at common classes
+    // that do not have a superclass or supertype that will be a
+    // better candidate.
+    Iterable<ClassElement> candidates = common.where((ClassElement each) {
+      bool containsSuperclass = common.contains(each.supertype.element);
+      // If the superclass is also a candidate, then we don't want to
+      // deal with this class. If we're only looking for a subclass we
+      // know we don't have to look at the list of interfaces because
+      // they can never be in the common set.
+      if (containsSuperclass || kind == SUBCLASS) return !containsSuperclass;
+      // Run through the direct supertypes of the class. If the common
+      // set contains the direct supertype of the class, we ignore the
+      // the class because the supertype is a better candidate.
+      for (Link link = each.interfaces; !link.isEmpty; link = link.tail) {
+        if (common.contains(link.head.element)) return false;
+      }
+      return true;
+    });
+    // Run through the list of candidates and compute the union. The
+    // result will only be nullable if both masks are nullable.
+    int combined = (kind << 1) | (flags & other.flags & 1);
+    TypeMask result;
+    for (ClassElement each in candidates) {
+      TypeMask mask = new FlatTypeMask.internal(each.rawType, combined);
+      result = (result == null) ? mask : result.union(mask, compiler);
+    }
+    return result;
+  }
+
+  TypeMask intersectionEmpty(FlatTypeMask other) {
+    return new TypeMask(null, EMPTY, isNullable && other.isNullable);
+  }
+
+  Set<ClassElement> containedClasses(Compiler compiler) {
+    ClassElement element = base.element;
+    if (isExact) {
+      return new Set<ClassElement>()..add(element);
+    } else if (isSubclass) {
+      return compiler.world.subclasses[element];
+    } else {
+      assert(isSubtype);
+      return compiler.world.subtypes[element];
+    }
+  }
+
+  /**
+   * Returns whether [element] will be the one used at runtime when being
+   * invoked on an instance of [cls]. [selector] is used to ensure library
+   * privacy is taken into account.
+   */
+  static bool hasElementIn(ClassElement cls,
+                           Selector selector,
+                           Element element) {
+    // Use [:implementation:] of [element]
+    // because our function set only stores declarations.
+    Element result = findMatchIn(cls, selector);
+    return result == null
+        ? false
+        : result.implementation == element.implementation;
+  }
+
+  static Element findMatchIn(ClassElement cls, Selector selector) {
+    // Use the [:implementation] of [cls] in case the found [element]
+    // is in the patch class.
+    return cls.implementation.lookupSelector(selector);
+  }
+
+  /**
+   * Returns whether [element] is a potential target when being
+   * invoked on this type mask. [selector] is used to ensure library
+   * privacy is taken into account.
+   */
+  bool canHit(Element element, Selector selector, Compiler compiler) {
+    assert(element.name == selector.name);
+    if (isEmpty) {
+      if (!isNullable) return false;
+      return hasElementIn(
+          compiler.backend.nullImplementation, selector, element);
+    }
+
+    // TODO(kasperl): Can't we just avoid creating typed selectors
+    // based of function types?
+    Element self = base.element;
+    if (self.isTypedef()) {
+      // A typedef is a function type that doesn't have any
+      // user-defined members.
+      return false;
+    }
+
+    ClassElement other = element.getEnclosingClass();
+    if (compiler.backend.isNullImplementation(other)) {
+      return isNullable;
+    } else if (isExact) {
+      return hasElementIn(self, selector, element);
+    } else if (isSubclass) {
+      return hasElementIn(self, selector, element)
+          || other.isSubclassOf(self)
+          || compiler.world.hasAnySubclassThatMixes(self, other);
+    } else {
+      assert(isSubtype);
+      return hasElementIn(self, selector, element)
+          || other.implementsInterface(self)
+          || other.isSubclassOf(self)
+          || compiler.world.hasAnySubclassThatMixes(self, other)
+          || compiler.world.hasAnySubclassThatImplements(other, base);
+    }
+  }
+
+  /**
+   * Returns whether a [selector] call on an instance of [cls]
+   * will hit a method at runtime, and not go through [noSuchMethod].
+   */
+  static bool hasConcreteMatch(ClassElement cls,
+                               Selector selector,
+                               Compiler compiler) {
+    Element element = findMatchIn(cls, selector);
+    if (element == null) return false;
+
+    if (element.isAbstract(compiler)) {
+      ClassElement enclosingClass = element.getEnclosingClass();
+      return hasConcreteMatch(enclosingClass.superclass, selector, compiler);
+    }
+    return selector.appliesUntyped(element, compiler);
+  }
+
+  /**
+   * Returns whether a [selector] call will hit a method at runtime,
+   * and not go through [noSuchMethod].
+   */
+  bool willHit(Selector selector, Compiler compiler) {
+    Element cls;
+    if (isEmpty) {
+      if (!isNullable) return false;
+      cls = compiler.backend.nullImplementation;
+    } else {
+      cls = base.element;
+    }
+
+    if (!cls.isAbstract(compiler)) {
+      return hasConcreteMatch(cls, selector, compiler);
+    }
+
+    Set<ClassElement> subtypesToCheck;
+    if (isExact) {
+      return false;
+    } else if (isSubtype) {
+      subtypesToCheck = compiler.world.subtypes[cls];
+    } else {
+      assert(isSubclass);
+      subtypesToCheck = compiler.world.subclasses[cls];
+    }
+
+    return subtypesToCheck != null
+        && subtypesToCheck.every((ClassElement cls) {
+              return cls.isAbstract(compiler)
+                ? true
+                : hasConcreteMatch(cls, selector, compiler);
+           });
+  }
+
+  Element locateSingleElement(Selector selector, Compiler compiler) {
+    if (isEmpty) return null;
+    Iterable<Element> targets = compiler.world.allFunctions.filter(selector);
+    if (targets.length != 1) return null;
+    Element result = targets.first;
+    ClassElement enclosing = result.getEnclosingClass();
+    // We only return the found element if it is guaranteed to be
+    // implemented on the exact receiver type. It could be found in a
+    // subclass or in an inheritance-wise unrelated class in case of
+    // subtype selectors.
+    ClassElement cls = base.element;
+    return (cls.isSubclassOf(enclosing)) ? result : null;
+  }
+
+  bool operator ==(var other) {
+    if (other is !FlatTypeMask) return false;
+    FlatTypeMask otherMask = other;
+    return (flags == otherMask.flags) && (base == otherMask.base);
+  }
+
+  int get hashCode {
+    return (base == null ? 0 : base.hashCode) + 31 * flags.hashCode;
+  }
+
+  String toString() {
+    if (isEmpty) return isNullable ? '[null]' : '[empty]';
+    StringBuffer buffer = new StringBuffer();
+    if (isNullable) buffer.write('null|');
+    if (isExact) buffer.write('exact=');
+    if (isSubclass) buffer.write('subclass=');
+    if (isSubtype) buffer.write('subtype=');
+    buffer.write(base.element.name.slowToString());
+    return "[$buffer]";
+  }
+
+  static bool isSubclassOf(DartType x, DartType y, Compiler compiler) {
+    ClassElement xElement = x.element;
+    ClassElement yElement = y.element;
+    Set<ClassElement> subclasses = compiler.world.subclasses[yElement];
+    return (subclasses != null) ? subclasses.contains(xElement) : false;
+  }
+
+  static bool isSubtypeOf(DartType x, DartType y, Compiler compiler) {
+    ClassElement xElement = x.element;
+    ClassElement yElement = y.element;
+    Set<ClassElement> subtypes = compiler.world.subtypes[yElement];
+    return (subtypes != null) ? subtypes.contains(xElement) : false;
+  }
+
+  static Set<ClassElement> commonContainedClasses(FlatTypeMask x,
+                                                  FlatTypeMask y,
+                                                  Compiler compiler) {
+    Set<ClassElement> xSubset = x.containedClasses(compiler);
+    if (xSubset == null) return null;
+    Set<ClassElement> ySubset = y.containedClasses(compiler);
+    if (ySubset == null) return null;
+    Set<ClassElement> smallSet, largeSet;
+    if (xSubset.length <= ySubset.length) {
+      smallSet = xSubset;
+      largeSet = ySubset;
+    } else {
+      smallSet = ySubset;
+      largeSet = xSubset;
+    }
+    var result = smallSet.where((ClassElement each) => largeSet.contains(each));
+    return result.toSet();
+  }
+}
diff --git a/sdk/lib/_internal/compiler/implementation/types/simple_types_inferrer.dart b/sdk/lib/_internal/compiler/implementation/types/simple_types_inferrer.dart
index 39fecf2..24ed91d 100644
--- a/sdk/lib/_internal/compiler/implementation/types/simple_types_inferrer.dart
+++ b/sdk/lib/_internal/compiler/implementation/types/simple_types_inferrer.dart
@@ -576,6 +576,9 @@
   }
 
   bool analyze(Element element) {
+    if (element.isForwardingConstructor) {
+      element = element.targetConstructor;
+    }
     SimpleTypeInferrerVisitor visitor =
         new SimpleTypeInferrerVisitor(element, compiler, this);
     TypeMask returnType = visitor.run();
@@ -1968,19 +1971,19 @@
   }
 
   TypeMask handleForeignSend(Send node) {
-    // TODO(ngeoffray): Analyze JS expressions.
-    sideEffects.setAllSideEffects();    
     node.visitChildren(this);
     Selector selector = elements.getSelector(node);
     SourceString name = selector.name;
     if (name == const SourceString('JS')) {
       native.NativeBehavior nativeBehavior =
           compiler.enqueuer.resolution.nativeEnqueuer.getNativeBehaviorOf(node);
+      sideEffects.add(nativeBehavior.sideEffects);
       return inferrer.typeOfNativeBehavior(nativeBehavior);
     } else if (name == const SourceString('JS_OPERATOR_IS_PREFIX')
                || name == const SourceString('JS_OPERATOR_AS_PREFIX')) {
       return inferrer.stringType;
     } else {
+      sideEffects.setAllSideEffects();
       return inferrer.dynamicType;
     }
   }
diff --git a/sdk/lib/_internal/compiler/implementation/types/type_mask.dart b/sdk/lib/_internal/compiler/implementation/types/type_mask.dart
index df459be..47740ea 100644
--- a/sdk/lib/_internal/compiler/implementation/types/type_mask.dart
+++ b/sdk/lib/_internal/compiler/implementation/types/type_mask.dart
@@ -4,6 +4,11 @@
 
 part of types;
 
+/**
+ * A type mask represents a set of contained classes, but the
+ * operations on it are not guaranteed to be precise and they may
+ * yield conservative answers that contain too many classes.
+ */
 abstract class TypeMask {
   factory TypeMask(DartType base, int kind, bool isNullable)
       => new FlatTypeMask(base, kind, isNullable);
@@ -95,588 +100,3 @@
    */
   Element locateSingleElement(Selector selector, Compiler compiler);
 }
-
-/**
- * A type mask represents a set of contained classes, but the
- * operations on it are not guaranteed to be precise and they may
- * yield conservative answers that contain too many classes.
- */
-class FlatTypeMask implements TypeMask {
-
-  static const int EMPTY    = 0;
-  static const int EXACT    = 1;
-  static const int SUBCLASS = 2;
-  static const int SUBTYPE  = 3;
-
-  final DartType base;
-  final int flags;
-
-  FlatTypeMask(DartType base, int kind, bool isNullable)
-      : this.internal(base, (kind << 1) | (isNullable ? 1 : 0));
-
-  FlatTypeMask.empty()
-      : this.internal(null, (EMPTY << 1) | 1);
-  FlatTypeMask.exact(DartType base)
-      : this.internal(base, (EXACT << 1) | 1);
-  FlatTypeMask.subclass(DartType base)
-      : this.internal(base, (SUBCLASS << 1) | 1);
-  FlatTypeMask.subtype(DartType base)
-      : this.internal(base, (SUBTYPE << 1) | 1);
-
-  FlatTypeMask.nonNullEmpty()
-      : this.internal(null, EMPTY << 1);
-  FlatTypeMask.nonNullExact(DartType base)
-      : this.internal(base, EXACT << 1);
-  FlatTypeMask.nonNullSubclass(DartType base)
-      : this.internal(base, SUBCLASS << 1);
-  FlatTypeMask.nonNullSubtype(DartType base)
-      : this.internal(base, SUBTYPE << 1);
-
-  FlatTypeMask.internal(DartType base, this.flags)
-      : this.base = transformBase(base) {
-    assert(base == null || !(isExact && base.isDynamic));
-  }
-
-  // TODO(kasperl): We temporarily transform the base to be the raw
-  // variant of the type. Long term, we're going to keep the class
-  // element corresponding to the type in the mask instead.
-  static DartType transformBase(DartType base) {
-    if (base == null) {
-      return null;
-    } else if (base.kind != TypeKind.INTERFACE) {
-      assert(base.kind == TypeKind.INTERFACE);
-      return null;
-    } else {
-      assert(!base.isMalformed);
-      return base.asRaw();
-    }
-  }
-
-  bool get isEmpty => (flags >> 1) == EMPTY;
-  bool get isExact => (flags >> 1) == EXACT;
-  bool get isNullable => (flags & 1) != 0;
-
-  // TODO(kasperl): Get rid of these. They should not be a visible
-  // part of the implementation because they make it hard to add
-  // proper union types if we ever want to.
-  bool get isSubclass => (flags >> 1) == SUBCLASS;
-  bool get isSubtype => (flags >> 1) == SUBTYPE;
-
-  TypeMask nullable() {
-    return isNullable ? this : new FlatTypeMask.internal(base, flags | 1);
-  }
-
-  TypeMask nonNullable() {
-    return isNullable ? new FlatTypeMask.internal(base, flags & ~1) : this;
-  }
-
-  bool contains(DartType type, Compiler compiler) {
-    if (isEmpty) {
-      return false;
-    } else if (identical(base.element, type.element)) {
-      return true;
-    } else if (isExact) {
-      return false;
-    } else if (isSubclass) {
-      return isSubclassOf(type, base, compiler);
-    } else {
-      assert(isSubtype);
-      return isSubtypeOf(type, base, compiler);
-    }
-  }
-
-  bool containsOnlyInt(Compiler compiler) {
-    return base.element == compiler.intClass
-        || base.element == compiler.backend.intImplementation;
-  }
-
-  bool containsOnlyDouble(Compiler compiler) {
-    return base.element == compiler.doubleClass
-        || base.element == compiler.backend.doubleImplementation;
-  }
-
-  bool containsOnlyNum(Compiler compiler) {
-    return base.element == compiler.numClass
-        || base.element == compiler.backend.numImplementation;
-  }
-
-  bool containsOnlyNull(Compiler compiler) {
-    return base.element == compiler.nullClass
-        || base.element == compiler.backend.nullImplementation;
-  }
-
-  bool containsOnlyBool(Compiler compiler) {
-    return base.element == compiler.boolClass
-        || base.element == compiler.backend.boolImplementation;
-  }
-
-  bool containsOnlyString(Compiler compiler) {
-    return base.element == compiler.stringClass
-        || base.element == compiler.backend.stringImplementation;
-  }
-
-  bool containsOnly(ClassElement cls) {
-    return base.element == cls;
-  }
-
-  /**
-   * Returns the [ClassElement] if this type represents a single class,
-   * otherwise returns `null`.  This method is conservative.
-   */
-  ClassElement singleClass(Compiler compiler) {
-    if (isEmpty) return null;
-    if (isNullable) return null;  // It is Null and some other class.
-    ClassElement element = base.element;
-    if (isExact) {
-      return element;
-    } else if (isSubclass) {
-      return compiler.world.hasAnySubclass(element) ? null : element;
-    } else {
-      assert(isSubtype);
-      return null;
-    }
-  }
-
-  /**
-   * Returns whether or not this type mask contains all types.
-   */
-  bool containsAll(Compiler compiler) {
-    if (isEmpty || isExact) return false;
-    return identical(base.element, compiler.objectClass)
-        || identical(base.element, compiler.dynamicClass);
-  }
-
-  TypeMask union(FlatTypeMask other, Compiler compiler) {
-    if (isEmpty) {
-      return isNullable ? other.nullable() : other;
-    } else if (other.isEmpty) {
-      return other.isNullable ? nullable() : this;
-    } else if (base == other.base) {
-      return unionSame(other, compiler);
-    } else if (isSubclassOf(other.base, base, compiler)) {
-      return unionSubclass(other, compiler);
-    } else if (isSubclassOf(base, other.base, compiler)) {
-      return other.unionSubclass(this, compiler);
-    } else if (isSubtypeOf(other.base, base, compiler)) {
-      return unionSubtype(other, compiler);
-    } else if (isSubtypeOf(base, other.base, compiler)) {
-      return other.unionSubtype(this, compiler);
-    } else {
-      return unionDisjoint(other, compiler);
-    }
-  }
-
-  TypeMask unionSame(FlatTypeMask other, Compiler compiler) {
-    assert(base == other.base);
-    // The two masks share the base type, so we must chose the least
-    // constraining kind (the highest) of the two. If either one of
-    // the masks are nullable the result should be nullable too.
-    int combined = (flags > other.flags)
-        ? flags | (other.flags & 1)
-        : other.flags | (flags & 1);
-    if (flags == combined) {
-      return this;
-    } else if (other.flags == combined) {
-      return other;
-    } else {
-      return new FlatTypeMask.internal(base, combined);
-    }
-  }
-
-  TypeMask unionSubclass(FlatTypeMask other, Compiler compiler) {
-    assert(isSubclassOf(other.base, base, compiler));
-    int combined;
-    if (isExact && other.isExact) {
-      // Since the other mask is a subclass of this mask, we need the
-      // resulting union to be a subclass too. If either one of the
-      // masks are nullable the result should be nullable too.
-      combined = (SUBCLASS << 1) | ((flags | other.flags) & 1);
-    } else {
-      // Both masks are at least subclass masks, so we pick the least
-      // constraining kind (the highest) of the two. If either one of
-      // the masks are nullable the result should be nullable too.
-      combined = (flags > other.flags)
-          ? flags | (other.flags & 1)
-          : other.flags | (flags & 1);
-    }
-    return (flags != combined)
-        ? new FlatTypeMask.internal(base, combined)
-        : this;
-  }
-
-  TypeMask unionSubtype(FlatTypeMask other, Compiler compiler) {
-    assert(isSubtypeOf(other.base, base, compiler));
-    // Since the other mask is a subtype of this mask, we need the
-    // resulting union to be a subtype too. If either one of the masks
-    // are nullable the result should be nullable too.
-    int combined = (SUBTYPE << 1) | ((flags | other.flags) & 1);
-    return (flags != combined)
-        ? new FlatTypeMask.internal(base, combined)
-        : this;
-  }
-
-  TypeMask unionDisjoint(FlatTypeMask other, Compiler compiler) {
-    assert(base != other.base);
-    assert(!isSubtypeOf(base, other.base, compiler));
-    assert(!isSubtypeOf(other.base, base, compiler));
-    // If either type mask is a subtype type mask, we cannot use a
-    // subclass type mask to represent their union.
-    bool useSubclass = !isSubtype && !other.isSubtype;
-    // Compute the common supertypes of the two types.
-    ClassElement thisElement = base.element;
-    ClassElement otherElement = other.base.element;
-    Iterable<ClassElement> candidates =
-        compiler.world.commonSupertypesOf(thisElement, otherElement);
-    if (candidates.isEmpty) {
-      // TODO(kasperl): Get rid of this check. It can only happen when
-      // at least one of the two base types is 'unseen'.
-      return new TypeMask(compiler.objectClass.rawType,
-                          SUBCLASS,
-                          isNullable || other.isNullable);
-    }
-    // Compute the best candidate and its kind.
-    ClassElement bestElement;
-    int bestKind;
-    int bestSize;
-    for (ClassElement candidate in candidates) {
-      Set<ClassElement> subclasses = useSubclass
-          ? compiler.world.subclasses[candidate]
-          : null;
-      int size;
-      int kind;
-      if (subclasses != null &&
-          subclasses.contains(thisElement) &&
-          subclasses.contains(otherElement)) {
-        // If both [this] and [other] are subclasses of the supertype,
-        // then we prefer to construct a subclass type mask because it
-        // will always be at least as small as the corresponding
-        // subtype type mask.
-        kind = SUBCLASS;
-        size = subclasses.length;
-        assert(size <= compiler.world.subtypes[candidate].length);
-      } else {
-        kind = SUBTYPE;
-        size = compiler.world.subtypes[candidate].length;
-      }
-      // Update the best candidate if the new one is better.
-      if (bestElement == null || size < bestSize) {
-        bestElement = candidate;
-        bestSize = size;
-        bestKind = kind;
-      }
-    }
-    return new TypeMask(bestElement.computeType(compiler),
-                        bestKind,
-                        isNullable || other.isNullable);
-  }
-
-  TypeMask intersection(FlatTypeMask other, Compiler compiler) {
-    if (isEmpty) {
-      return other.isNullable ? this : nonNullable();
-    } else if (other.isEmpty) {
-      return isNullable ? other : other.nonNullable();
-    } else if (base == other.base) {
-      return intersectionSame(other, compiler);
-    } else if (isSubclassOf(other.base, base, compiler)) {
-      return intersectionSubclass(other, compiler);
-    } else if (isSubclassOf(base, other.base, compiler)) {
-      return other.intersectionSubclass(this, compiler);
-    } else if (isSubtypeOf(other.base, base, compiler)) {
-      return intersectionSubtype(other, compiler);
-    } else if (isSubtypeOf(base, other.base, compiler)) {
-      return other.intersectionSubtype(this, compiler);
-    } else {
-      return intersectionDisjoint(other, compiler);
-    }
-  }
-
-  TypeMask intersectionSame(FlatTypeMask other, Compiler compiler) {
-    assert(base == other.base);
-    // The two masks share the base type, so we must chose the most
-    // constraining kind (the lowest) of the two. Only if both masks
-    // are nullable, will the result be nullable too.
-    int combined = (flags < other.flags)
-        ? flags & ((other.flags & 1) | ~1)
-        : other.flags & ((flags & 1) | ~1);
-    if (flags == combined) {
-      return this;
-    } else if (other.flags == combined) {
-      return other;
-    } else {
-      return new FlatTypeMask.internal(base, combined);
-    }
-  }
-
-  TypeMask intersectionSubclass(FlatTypeMask other, Compiler compiler) {
-    assert(isSubclassOf(other.base, base, compiler));
-    // If this mask isn't at least a subclass mask, then the
-    // intersection with the other mask is empty.
-    if (isExact) return intersectionEmpty(other);
-    // Only the other mask puts constraints on the intersection mask,
-    // so base the combined flags on the other mask. Only if both
-    // masks are nullable, will the result be nullable too.
-    int combined = other.flags & ((flags & 1) | ~1);
-    if (other.flags == combined) {
-      return other;
-    } else {
-      return new FlatTypeMask.internal(other.base, combined);
-    }
-  }
-
-  TypeMask intersectionSubtype(FlatTypeMask other, Compiler compiler) {
-    assert(isSubtypeOf(other.base, base, compiler));
-    // If this mask isn't a subtype mask, then the intersection with
-    // the other mask is empty.
-    if (!isSubtype) return intersectionEmpty(other);
-    // Only the other mask puts constraints on the intersection mask,
-    // so base the combined flags on the other mask. Only if both
-    // masks are nullable, will the result be nullable too.
-    int combined = other.flags & ((flags & 1) | ~1);
-    if (other.flags == combined) {
-      return other;
-    } else {
-      return new FlatTypeMask.internal(other.base, combined);
-    }
-  }
-
-  TypeMask intersectionDisjoint(FlatTypeMask other, Compiler compiler) {
-    assert(base != other.base);
-    assert(!isSubtypeOf(base, other.base, compiler));
-    assert(!isSubtypeOf(other.base, base, compiler));
-    // If one of the masks are exact or if both of them are subclass
-    // masks, then the intersection is empty.
-    if (isExact || other.isExact) return intersectionEmpty(other);
-    if (isSubclass && other.isSubclass) return intersectionEmpty(other);
-    assert(isSubtype || other.isSubtype);
-    int kind = (isSubclass || other.isSubclass) ? SUBCLASS : SUBTYPE;
-    // Compute the set of classes that are contained in both type masks.
-    Set<ClassElement> common = commonContainedClasses(this, other, compiler);
-    if (common == null || common.isEmpty) return intersectionEmpty(other);
-    // Narrow down the candidates by only looking at common classes
-    // that do not have a superclass or supertype that will be a
-    // better candidate.
-    Iterable<ClassElement> candidates = common.where((ClassElement each) {
-      bool containsSuperclass = common.contains(each.supertype.element);
-      // If the superclass is also a candidate, then we don't want to
-      // deal with this class. If we're only looking for a subclass we
-      // know we don't have to look at the list of interfaces because
-      // they can never be in the common set.
-      if (containsSuperclass || kind == SUBCLASS) return !containsSuperclass;
-      // Run through the direct supertypes of the class. If the common
-      // set contains the direct supertype of the class, we ignore the
-      // the class because the supertype is a better candidate.
-      for (Link link = each.interfaces; !link.isEmpty; link = link.tail) {
-        if (common.contains(link.head.element)) return false;
-      }
-      return true;
-    });
-    // Run through the list of candidates and compute the union. The
-    // result will only be nullable if both masks are nullable.
-    int combined = (kind << 1) | (flags & other.flags & 1);
-    TypeMask result;
-    for (ClassElement each in candidates) {
-      TypeMask mask = new FlatTypeMask.internal(each.rawType, combined);
-      result = (result == null) ? mask : result.union(mask, compiler);
-    }
-    return result;
-  }
-
-  TypeMask intersectionEmpty(FlatTypeMask other) {
-    return new TypeMask(null, EMPTY, isNullable && other.isNullable);
-  }
-
-  Set<ClassElement> containedClasses(Compiler compiler) {
-    ClassElement element = base.element;
-    if (isExact) {
-      return new Set<ClassElement>()..add(element);
-    } else if (isSubclass) {
-      return compiler.world.subclasses[element];
-    } else {
-      assert(isSubtype);
-      return compiler.world.subtypes[element];
-    }
-  }
-
-  /**
-   * Returns whether [element] will be the one used at runtime when being
-   * invoked on an instance of [cls]. [selector] is used to ensure library
-   * privacy is taken into account.
-   */
-  static bool hasElementIn(ClassElement cls,
-                           Selector selector,
-                           Element element) {
-    // Use [:implementation:] of [element]
-    // because our function set only stores declarations.
-    Element result = findMatchIn(cls, selector);
-    return result == null
-        ? false
-        : result.implementation == element.implementation;
-  }
-
-  static Element findMatchIn(ClassElement cls, Selector selector) {
-    // Use the [:implementation] of [cls] in case the found [element]
-    // is in the patch class.
-    return cls.implementation.lookupSelector(selector);
-  }
-
-  /**
-   * Returns whether [element] is a potential target when being
-   * invoked on this type mask. [selector] is used to ensure library
-   * privacy is taken into account.
-   */
-  bool canHit(Element element, Selector selector, Compiler compiler) {
-    assert(element.name == selector.name);
-    if (isEmpty) {
-      if (!isNullable) return false;
-      return hasElementIn(
-          compiler.backend.nullImplementation, selector, element);
-    }
-
-    // TODO(kasperl): Can't we just avoid creating typed selectors
-    // based of function types?
-    Element self = base.element;
-    if (self.isTypedef()) {
-      // A typedef is a function type that doesn't have any
-      // user-defined members.
-      return false;
-    }
-
-    ClassElement other = element.getEnclosingClass();
-    if (compiler.backend.isNullImplementation(other)) {
-      return isNullable;
-    } else if (isExact) {
-      return hasElementIn(self, selector, element);
-    } else if (isSubclass) {
-      return hasElementIn(self, selector, element)
-          || other.isSubclassOf(self)
-          || compiler.world.hasAnySubclassThatMixes(self, other);
-    } else {
-      assert(isSubtype);
-      return hasElementIn(self, selector, element)
-          || other.implementsInterface(self)
-          || other.isSubclassOf(self)
-          || compiler.world.hasAnySubclassThatMixes(self, other)
-          || compiler.world.hasAnySubclassThatImplements(other, base);
-    }
-  }
-
-  /**
-   * Returns whether a [selector] call on an instance of [cls]
-   * will hit a method at runtime, and not go through [noSuchMethod].
-   */
-  static bool hasConcreteMatch(ClassElement cls,
-                               Selector selector,
-                               Compiler compiler) {
-    Element element = findMatchIn(cls, selector);
-    if (element == null) return false;
-
-    if (element.isAbstract(compiler)) {
-      ClassElement enclosingClass = element.getEnclosingClass();
-      return hasConcreteMatch(enclosingClass.superclass, selector, compiler);
-    }
-    return selector.appliesUntyped(element, compiler);
-  }
-
-  /**
-   * Returns whether a [selector] call will hit a method at runtime,
-   * and not go through [noSuchMethod].
-   */
-  bool willHit(Selector selector, Compiler compiler) {
-    Element cls;
-    if (isEmpty) {
-      if (!isNullable) return false;
-      cls = compiler.backend.nullImplementation;
-    } else {
-      cls = base.element;
-    }
-
-    if (!cls.isAbstract(compiler)) {
-      return hasConcreteMatch(cls, selector, compiler);
-    }
-
-    Set<ClassElement> subtypesToCheck;
-    if (isExact) {
-      return false;
-    } else if (isSubtype) {
-      subtypesToCheck = compiler.world.subtypes[cls];
-    } else {
-      assert(isSubclass);
-      subtypesToCheck = compiler.world.subclasses[cls];
-    }
-
-    return subtypesToCheck != null
-        && subtypesToCheck.every((ClassElement cls) {
-              return cls.isAbstract(compiler)
-                ? true
-                : hasConcreteMatch(cls, selector, compiler);
-           });
-  }
-
-  Element locateSingleElement(Selector selector, Compiler compiler) {
-    if (isEmpty) return null;
-    Iterable<Element> targets = compiler.world.allFunctions.filter(selector);
-    if (targets.length != 1) return null;
-    Element result = targets.first;
-    ClassElement enclosing = result.getEnclosingClass();
-    // We only return the found element if it is guaranteed to be
-    // implemented on the exact receiver type. It could be found in a
-    // subclass or in an inheritance-wise unrelated class in case of
-    // subtype selectors.
-    ClassElement cls = base.element;
-    return (cls.isSubclassOf(enclosing)) ? result : null;
-  }
-
-  bool operator ==(var other) {
-    if (other is !FlatTypeMask) return false;
-    FlatTypeMask otherMask = other;
-    return (flags == otherMask.flags) && (base == otherMask.base);
-  }
-
-  int get hashCode {
-    return (base == null ? 0 : base.hashCode) + 31 * flags.hashCode;
-  }
-
-  String toString() {
-    if (isEmpty) return isNullable ? '[null]' : '[empty]';
-    StringBuffer buffer = new StringBuffer();
-    if (isNullable) buffer.write('null|');
-    if (isExact) buffer.write('exact=');
-    if (isSubclass) buffer.write('subclass=');
-    if (isSubtype) buffer.write('subtype=');
-    buffer.write(base.element.name.slowToString());
-    return "[$buffer]";
-  }
-
-  static bool isSubclassOf(DartType x, DartType y, Compiler compiler) {
-    ClassElement xElement = x.element;
-    ClassElement yElement = y.element;
-    Set<ClassElement> subclasses = compiler.world.subclasses[yElement];
-    return (subclasses != null) ? subclasses.contains(xElement) : false;
-  }
-
-  static bool isSubtypeOf(DartType x, DartType y, Compiler compiler) {
-    ClassElement xElement = x.element;
-    ClassElement yElement = y.element;
-    Set<ClassElement> subtypes = compiler.world.subtypes[yElement];
-    return (subtypes != null) ? subtypes.contains(xElement) : false;
-  }
-
-  static Set<ClassElement> commonContainedClasses(FlatTypeMask x,
-                                                  FlatTypeMask y,
-                                                  Compiler compiler) {
-    Set<ClassElement> xSubset = x.containedClasses(compiler);
-    if (xSubset == null) return null;
-    Set<ClassElement> ySubset = y.containedClasses(compiler);
-    if (ySubset == null) return null;
-    Set<ClassElement> smallSet, largeSet;
-    if (xSubset.length <= ySubset.length) {
-      smallSet = xSubset;
-      largeSet = ySubset;
-    } else {
-      smallSet = ySubset;
-      largeSet = xSubset;
-    }
-    var result = smallSet.where((ClassElement each) => largeSet.contains(each));
-    return result.toSet();
-  }
-}
diff --git a/sdk/lib/_internal/compiler/implementation/types/types.dart b/sdk/lib/_internal/compiler/implementation/types/types.dart
index dee04af..34444fd 100644
--- a/sdk/lib/_internal/compiler/implementation/types/types.dart
+++ b/sdk/lib/_internal/compiler/implementation/types/types.dart
@@ -17,6 +17,7 @@
 import '../dart_types.dart';
 
 part 'concrete_types_inferrer.dart';
+part 'flat_type_mask.dart';
 part 'type_mask.dart';
 
 /**
diff --git a/sdk/lib/_internal/compiler/implementation/warnings.dart b/sdk/lib/_internal/compiler/implementation/warnings.dart
index 014415d..00cdcce 100644
--- a/sdk/lib/_internal/compiler/implementation/warnings.dart
+++ b/sdk/lib/_internal/compiler/implementation/warnings.dart
@@ -48,6 +48,10 @@
       'cannot resolve constructor #{constructorName}');
   static const CANNOT_RESOLVE_CONSTRUCTOR_FOR_IMPLICIT = const MessageKind(
       'cannot resolve constructor #{constructorName} for implicit super call');
+  static const INVALID_UNNAMED_CONSTRUCTOR_NAME = const MessageKind(
+      'Error: Unnamed constructor name must be #{name}.');
+  static const INVALID_CONSTRUCTOR_NAME = const MessageKind(
+      'Error: Constructor name must start with #{name}.');
   static const CANNOT_RESOLVE_TYPE = const MessageKind(
       'cannot resolve type #{typeName}');
   static const DUPLICATE_DEFINITION = const MessageKind(
@@ -64,8 +68,6 @@
       "'Object' does not have a superclass");
   static const CANNOT_FIND_CONSTRUCTOR = const MessageKind(
       'cannot find constructor #{constructorName}');
-  static const CANNOT_FIND_CONSTRUCTOR2 = const MessageKind(
-      'cannot find constructor #{constructorName} in #{className}');
   static const CYCLIC_CLASS_HIERARCHY = const MessageKind(
       '#{className} creates a cycle in the class hierarchy');
   static const INVALID_RECEIVER_IN_INITIALIZER = const MessageKind(
@@ -178,9 +180,6 @@
   static const NO_SUCH_LIBRARY_MEMBER = const MessageKind(
       '#{libraryName} has no member named #{memberName}');
 
-  static const CANNOT_INSTANTIATE_INTERFACE = const MessageKind(
-      "cannot instantiate interface '#{interfaceName}'");
-
   static const CANNOT_INSTANTIATE_TYPEDEF = const MessageKind(
       "cannot instantiate typedef '#{typedefName}'");
 
diff --git a/sdk/lib/_internal/dartdoc/lib/dartdoc.dart b/sdk/lib/_internal/dartdoc/lib/dartdoc.dart
index cf35cd9..152f32c 100644
--- a/sdk/lib/_internal/dartdoc/lib/dartdoc.dart
+++ b/sdk/lib/_internal/dartdoc/lib/dartdoc.dart
@@ -94,15 +94,6 @@
 }
 
 /**
- * Returns the display name of the library. This is necessary to account for
- * dart: libraries.
- */
-String displayName(LibraryMirror library) {
-  var uri = library.uri.toString();
-  return uri.startsWith('dart:') ?  uri.toString() : library.simpleName;
-}
-
-/**
  * Copies all of the files in the directory [from] to [to]. Does *not*
  * recursively copy subdirectories.
  *
@@ -405,8 +396,9 @@
         return true;
       }
     }
-    if (libraryName.startsWith('dart:')) {
-      String suffix = libraryName.substring('dart:'.length);
+    Uri uri = library.uri;
+    if (uri.scheme == 'dart') {
+      String suffix = uri.path;
       LibraryInfo info = LIBRARIES[suffix];
       if (info != null) {
         return info.documented && includeApi;
@@ -421,9 +413,9 @@
    */
   bool shouldLinkToPublicApi(LibraryMirror library) {
     if (linkToApi) {
-      String libraryName = displayName(library);
-      if (libraryName.startsWith('dart:')) {
-        String suffix = libraryName.substring('dart:'.length);
+      Uri uri = library.uri;
+      if (uri.scheme == 'dart') {
+        String suffix = uri.path;
         LibraryInfo info = LIBRARIES[suffix];
         if (info != null) {
           return info.documented;
@@ -602,7 +594,7 @@
 
         var library1 = _librariesByPath[export1.exporter];
         var library2 = _librariesByPath[export2.exporter];
-        return Comparable.compare(library1.displayName, library2.displayName);
+        return Comparable.compare(displayName(library1), displayName(library2));
       });
       hiddenLibraryExports[exporteePath] = exports;
     });
@@ -842,11 +834,9 @@
       if (!showPrivate && type.isPrivate) continue;
 
       var typeInfo = {};
-      typeInfo[NAME] = type.displayName;
+      typeInfo[NAME] = displayName(type);
       if (type.isClass) {
         typeInfo[KIND] = CLASS;
-      } else if (type.isInterface) {
-        typeInfo[KIND] = INTERFACE;
       } else {
         assert(type.isTypedef);
         typeInfo[KIND] = TYPEDEF;
@@ -859,7 +849,7 @@
       if (!type.originalDeclaration.typeVariables.isEmpty) {
         final typeVariables = [];
         for (final typeVariable in type.originalDeclaration.typeVariables) {
-          typeVariables.add(typeVariable.displayName);
+          typeVariables.add(displayName(typeVariable));
         }
         typeInfo[ARGS] = typeVariables.join(', ');
       }
@@ -895,7 +885,7 @@
           memberInfo[NO_PARAMS] = true;
         }
       }
-      memberInfo[NAME] = member.displayName;
+      memberInfo[NAME] = displayName(member);
       var anchor = memberAnchor(member);
       if (anchor != memberInfo[NAME]) {
         memberInfo[LINK_NAME] = anchor;
@@ -1000,7 +990,6 @@
     docMembers(library);
 
     // Document the types.
-    final interfaces = <ClassMirror>[];
     final abstractClasses = <ClassMirror>[];
     final classes = <ClassMirror>[];
     final typedefs = <TypedefMirror>[];
@@ -1018,8 +1007,6 @@
         } else {
           classes.add(type);
         }
-      } else if (type.isInterface){
-        interfaces.add(type);
       } else if (type is TypedefMirror) {
         typedefs.add(type);
       } else {
@@ -1027,7 +1014,6 @@
       }
     }
 
-    docTypes(interfaces, 'Interfaces');
     docTypes(abstractClasses, 'Abstract Classes');
     docTypes(classes, 'Classes');
     docTypes(typedefs, 'Typedefs');
@@ -1071,10 +1057,11 @@
 
     startFile(typeUrl(type));
 
-    var kind = 'interface';
+    var kind;
     if (type.isTypedef) {
       kind = 'typedef';
-    } else if (type.isClass) {
+    } else {
+      assert(type.isClass);
       if (type.isAbstract) {
         kind = 'abstract class';
       } else {
@@ -1148,6 +1135,7 @@
     // Don't show the inheritance details for Object. It doesn't have any base
     // class (obviously) and it has too many subclasses to be useful.
     if (type.isObject) return;
+    if (type.isTypedef) return;
 
     // Writes an unordered list of references to types with an optional header.
     listTypes(types, header) {
@@ -1181,56 +1169,30 @@
       subtypes.add(subtype);
     }
     subtypes.sort((x, y) => x.simpleName.compareTo(y.simpleName));
-    if (type.isClass) {
-      // Show the chain of superclasses.
-      if (!type.superclass.isObject) {
-        final supertypes = [];
-        var thisType = type.superclass;
-        // As a sanity check, only show up to five levels of nesting, otherwise
-        // the box starts to get hideous.
-        do {
-          supertypes.add(thisType);
-          thisType = thisType.superclass;
-        } while (!thisType.isObject);
 
-        writeln('<h3>Extends</h3>');
-        writeln('<p>');
-        for (var i = supertypes.length - 1; i >= 0; i--) {
-          typeSpan(supertypes[i]);
-          write('&nbsp;&gt;&nbsp;');
-        }
+    // Show the chain of superclasses.
+    if (!type.superclass.isObject) {
+      final supertypes = [];
+      var thisType = type.superclass;
+      do {
+        supertypes.add(thisType);
+        thisType = thisType.superclass;
+      } while (!thisType.isObject);
 
-        // Write this class.
-        typeSpan(type);
-        writeln('</p>');
+      writeln('<h3>Extends</h3>');
+      writeln('<p>');
+      for (var i = supertypes.length - 1; i >= 0; i--) {
+        typeSpan(supertypes[i]);
+        write('&nbsp;&gt;&nbsp;');
       }
 
-      listTypes(subtypes, 'Subclasses');
-      listTypes(type.superinterfaces, 'Implements');
-    } else {
-      // Show the default class.
-      if (type.defaultFactory != null) {
-        listTypes([type.defaultFactory], 'Default class');
-      }
-
-      // List extended interfaces.
-      listTypes(type.superinterfaces, 'Extends');
-
-      // List subinterfaces and implementing classes.
-      final subinterfaces = [];
-      final implementing = [];
-
-      for (final subtype in subtypes) {
-        if (subtype.isClass) {
-          implementing.add(subtype);
-        } else {
-          subinterfaces.add(subtype);
-        }
-      }
-
-      listTypes(subinterfaces, 'Subinterfaces');
-      listTypes(implementing, 'Implemented by');
+      // Write this class.
+      typeSpan(type);
+      writeln('</p>');
     }
+
+    listTypes(subtypes, 'Subclasses');
+    listTypes(type.superinterfaces, 'Implements');
   }
 
   /**
@@ -1331,14 +1293,14 @@
       if (host is LibraryMirror || member.isStatic) {
         if (member is MethodMirror) {
           if (member.isGetter) {
-            staticGetters[member.displayName] = member;
+            staticGetters[displayName(member)] = member;
           } else if (member.isSetter) {
-            staticSetters[member.displayName] = member;
+            staticSetters[displayName(member)] = member;
           } else {
             staticMethods.add(member);
           }
         } else if (member is VariableMirror) {
-          staticGetters[member.displayName] = member;
+          staticGetters[displayName(member)] = member;
         }
       }
     }
@@ -1384,12 +1346,12 @@
     memberMap.forEach((_, MemberMirror member) {
       if (member is MethodMirror) {
         if (member.isGetter) {
-          instanceGetters[member.displayName] = member;
+          instanceGetters[displayName(member)] = member;
           if (_ownerFor(member) == host) {
             allPropertiesInherited = false;
           }
         } else if (member.isSetter) {
-          instanceSetters[member.displayName] = member;
+          instanceSetters[displayName(member)] = member;
           if (_ownerFor(member) == host) {
             allPropertiesInherited = false;
           }
@@ -1405,7 +1367,7 @@
           }
         }
       } else if (member is VariableMirror) {
-        instanceGetters[member.displayName] = member;
+        instanceGetters[displayName(member)] = member;
         if (_ownerFor(member) == host) {
           allPropertiesInherited = false;
         }
@@ -1520,7 +1482,7 @@
     _currentMember = member;
 
     bool isAbstract = false;
-    String name = member.displayName;
+    String name = displayName(member);
     if (member is VariableMirror) {
       if (asGetter) {
         // Getter.
@@ -2187,7 +2149,7 @@
       if (exportedLibrary == null) return [];
       if (shouldIncludeLibrary(exportedLibrary)) return [];
       return fn(exportedLibrary).where((declaration) =>
-          export.isMemberVisible(declaration.displayName));
+          export.isMemberVisible(displayName(declaration)));
     }));
     return contents;
   }
@@ -2198,7 +2160,7 @@
    * exporter.
    */
   LibraryMirror _libraryFor(TypeMirror type) =>
-    _visibleLibrary(type.library, type.displayName);
+    _visibleLibrary(type.library, displayName(type));
 
   /**
    * Returns the owner of [declaration]. If [declaration]'s owner is a hidden
@@ -2207,7 +2169,7 @@
   DeclarationMirror _ownerFor(DeclarationMirror declaration) {
     var owner = declaration.owner;
     if (owner is! LibraryMirror) return owner;
-    return _visibleLibrary(owner, declaration.displayName);
+    return _visibleLibrary(owner, displayName(declaration));
   }
 
   /**
diff --git a/sdk/lib/_internal/dartdoc/lib/src/client/search.dart b/sdk/lib/_internal/dartdoc/lib/src/client/search.dart
index 9c439e9..ee5f922 100644
--- a/sdk/lib/_internal/dartdoc/lib/src/client/search.dart
+++ b/sdk/lib/_internal/dartdoc/lib/src/client/search.dart
@@ -120,7 +120,7 @@
       sb.write('set ');
     }
     sb.write(match.toHtml());
-    if (kind == CLASS || kind == INTERFACE || kind == TYPEDEF) {
+    if (kind == CLASS || kind == TYPEDEF) {
       sb.write(args);
     } else if (kind == CONSTRUCTOR || kind == METHOD) {
       if (noargs) {
diff --git a/sdk/lib/_internal/dartdoc/lib/src/dartdoc/nav.dart b/sdk/lib/_internal/dartdoc/lib/src/dartdoc/nav.dart
index 62fd0dc..3948f8e 100644
--- a/sdk/lib/_internal/dartdoc/lib/src/dartdoc/nav.dart
+++ b/sdk/lib/_internal/dartdoc/lib/src/dartdoc/nav.dart
@@ -17,7 +17,7 @@
  *     TypeInfo = {
  *         String NAME, // Type name.
  *         String ARGS, // Type variables, e.g. "<K,V>". Optional.
- *         String KIND, // One of CLASS, INTERFACE, or TYPEDEF.
+ *         String KIND, // One of CLASS or TYPEDEF.
  *         List<MemberInfo> MEMBERS, // Type fields and methods.
  *     };
  *     MemberInfo = {
@@ -34,7 +34,6 @@
 
 const String LIBRARY = 'library';
 const String CLASS = 'class';
-const String INTERFACE = 'interface';
 const String TYPEDEF = 'typedef';
 const String MEMBERS = 'members';
 const String TYPES = 'types';
@@ -58,8 +57,6 @@
     return 'library';
   } else if (kind == CLASS) {
     return 'class';
-  } else if (kind == INTERFACE) {
-    return 'interface';
   } else if (kind == TYPEDEF) {
     return 'typedef';
   } else if (kind == FIELD) {
diff --git a/sdk/lib/_internal/dartdoc/lib/universe_serializer.dart b/sdk/lib/_internal/dartdoc/lib/universe_serializer.dart
index edeca41..0e2e164 100755
--- a/sdk/lib/_internal/dartdoc/lib/universe_serializer.dart
+++ b/sdk/lib/_internal/dartdoc/lib/universe_serializer.dart
@@ -151,7 +151,7 @@
    */
   LibraryElement(LibraryMirror mirror,
       {MdnComment lookupMdnComment(Mirror), Set<String> includedChildren})
-      : super(mirror, 'library', _libraryName(mirror), mirror.displayName,
+      : super(mirror, 'library', _libraryName(mirror), mirror.simpleName,
           computeComment(mirror), lookupMdnComment) {
     var requiredDependencies;
     // We don't need to track our required dependencies when generating a
@@ -506,7 +506,7 @@
   List<Reference> arguments;
 
   Reference(Mirror mirror)
-      : name = mirror.displayName,
+      : name = displayName(mirror),
         refId = getId(mirror) {
     if (mirror is ClassMirror) {
       if (mirror is !TypedefMirror && !mirror.typeArguments.isEmpty) {
diff --git a/sdk/lib/_internal/pub/lib/src/http.dart b/sdk/lib/_internal/pub/lib/src/http.dart
index 123c2060..eecfda3 100644
--- a/sdk/lib/_internal/pub/lib/src/http.dart
+++ b/sdk/lib/_internal/pub/lib/src/http.dart
@@ -97,7 +97,7 @@
     if (request.method == 'POST') {
       var contentTypeString = request.headers[HttpHeaders.CONTENT_TYPE];
       if (contentTypeString == null) contentTypeString = '';
-      var contentType = new ContentType.fromString(contentTypeString);
+      var contentType = ContentType.parse(contentTypeString);
       if (request is http.MultipartRequest) {
         requestLog.writeln();
         requestLog.writeln("Body fields:");
diff --git a/sdk/lib/core/date_time.dart b/sdk/lib/core/date_time.dart
index 31daa8f..e0509d6 100644
--- a/sdk/lib/core/date_time.dart
+++ b/sdk/lib/core/date_time.dart
@@ -13,7 +13,7 @@
  *
  * Also see [Stopwatch] for means to measure time-spans.
  */
-class DateTime {
+class DateTime implements Comparable {
   // Weekday constants that are returned by [weekday] method:
   static const int MONDAY = 1;
   static const int TUESDAY = 2;
diff --git a/sdk/lib/io/common.dart b/sdk/lib/io/common.dart
index 9350ad6..022e84b 100644
--- a/sdk/lib/io/common.dart
+++ b/sdk/lib/io/common.dart
@@ -14,6 +14,30 @@
 const int _OSERROR_RESPONSE_ERROR_CODE = 1;
 const int _OSERROR_RESPONSE_MESSAGE = 2;
 
+// Functions used to receive exceptions from native ports.
+bool _isErrorResponse(response) {
+  return response is List && response[0] != _SUCCESS_RESPONSE;
+}
+
+/**
+ * Returns an Exception or an Error
+ */
+_exceptionFromResponse(response, String message) {
+  assert(_isErrorResponse(response));
+  switch (response[_ERROR_RESPONSE_ERROR_TYPE]) {
+    case _ILLEGAL_ARGUMENT_RESPONSE:
+      return new ArgumentError();
+    case _OSERROR_RESPONSE:
+      var err = new OSError(response[_OSERROR_RESPONSE_MESSAGE],
+                            response[_OSERROR_RESPONSE_ERROR_CODE]);
+      return new FileIOException(message, err);
+    case _FILE_CLOSED_RESPONSE:
+      return new FileIOException("File closed");
+    default:
+      return new Exception("Unknown error");
+  }
+}
+
 /**
   * An [OSError] object holds information about an error from the
   * operating system.
diff --git a/sdk/lib/io/directory_impl.dart b/sdk/lib/io/directory_impl.dart
index 99c0b66..0157a19 100644
--- a/sdk/lib/io/directory_impl.dart
+++ b/sdk/lib/io/directory_impl.dart
@@ -12,10 +12,6 @@
   static const LIST_REQUEST = 4;
   static const RENAME_REQUEST = 5;
 
-  static const SUCCESS_RESPONSE = 0;
-  static const ILLEGAL_ARGUMENT_RESPONSE = 1;
-  static const OSERROR_RESPONSE = 2;
-
   _Directory(String this._path);
   _Directory.fromPath(Path path) : this(path.toNativePath());
 
diff --git a/sdk/lib/io/file_impl.dart b/sdk/lib/io/file_impl.dart
index 57cfda6..89af6c3 100644
--- a/sdk/lib/io/file_impl.dart
+++ b/sdk/lib/io/file_impl.dart
@@ -197,29 +197,9 @@
 const int _WRITE_LIST_REQUEST = 18;
 const int _CREATE_LINK_REQUEST = 19;
 const int _DELETE_LINK_REQUEST = 20;
-
-// Base class for _File and _RandomAccessFile with shared functions.
-class _FileBase {
-  bool _isErrorResponse(response) {
-    return response is List && response[0] != _SUCCESS_RESPONSE;
-  }
-
-  _exceptionFromResponse(response, String message) {
-    assert(_isErrorResponse(response));
-    switch (response[_ERROR_RESPONSE_ERROR_TYPE]) {
-      case _ILLEGAL_ARGUMENT_RESPONSE:
-        return new ArgumentError();
-      case _OSERROR_RESPONSE:
-        var err = new OSError(response[_OSERROR_RESPONSE_MESSAGE],
-                              response[_OSERROR_RESPONSE_ERROR_CODE]);
-        return new FileIOException(message, err);
-      case _FILE_CLOSED_RESPONSE:
-        return new FileIOException("File closed");
-      default:
-        return new Exception("Unknown error");
-    }
-  }
-}
+const int _LINK_TARGET_REQUEST = 21;
+const int _TYPE_REQUEST = 22;
+const int _IDENTICAL_REQUEST = 23;
 
 // TODO(ager): The only reason for this class is that the patching
 // mechanism doesn't seem to like patching a private top level
@@ -229,7 +209,7 @@
 }
 
 // Class for encapsulating the native implementation of files.
-class _File extends _FileBase implements File {
+class _File implements File {
   // Constructor for file.
   _File(String this._path) {
     if (_path is! String) {
@@ -586,7 +566,7 @@
 }
 
 
-class _RandomAccessFile extends _FileBase implements RandomAccessFile {
+class _RandomAccessFile implements RandomAccessFile {
   _RandomAccessFile(int this._id, String this._path);
 
   Future<RandomAccessFile> close() {
diff --git a/sdk/lib/io/file_system_entity.dart b/sdk/lib/io/file_system_entity.dart
index ac00741..847b7d1 100644
--- a/sdk/lib/io/file_system_entity.dart
+++ b/sdk/lib/io/file_system_entity.dart
@@ -34,8 +34,8 @@
 abstract class FileSystemEntity {
   String get path;
 
-  external static int _getType(String path, bool followLinks);
-  external static bool _identical(String path1, String path2);
+  external static _getType(String path, bool followLinks);
+  external static _identical(String path1, String path2);
 
   static int _getTypeSync(String path, bool followLinks) {
     var result = _getType(path, followLinks);
@@ -43,6 +43,49 @@
     return result;
   }
 
+  static Future<int> _getTypeAsync(String path, bool followLinks) {
+    // Get a new file service port for each request.  We could also cache one.
+    var service = _FileUtils._newServicePort();
+    List request = new List(3);
+    request[0] = _TYPE_REQUEST;
+    request[1] = path;
+    request[2] = followLinks;
+    return service.call(request).then((response) {
+      if (_isErrorResponse(response)) {
+        throw _exceptionFromResponse(response,
+                                     "Error getting type of '$path'");
+      }
+      return response;
+    });
+  }
+
+  /**
+   * Do two paths refer to the same object in the file system?
+   * Links are not identical to their targets, and two links
+   * are not identical just because they point to identical targets.
+   * Links in intermediate directories in the paths are followed, though.
+   *
+   * Throws an error if one of the paths points to an object that does not
+   * exist.
+   * The target of a link can be compared by first getting it with Link.target.
+   */
+  static Future<bool> identical(String path1, String path2) {
+    // Get a new file service port for each request.  We could also cache one.
+    var service = _FileUtils._newServicePort();
+    List request = new List(3);
+    request[0] = _IDENTICAL_REQUEST;
+    request[1] = path1;
+    request[2] = path2;
+    return service.call(request).then((response) {
+      if (_isErrorResponse(response)) {
+        throw _exceptionFromResponse(response,
+            "Error in FileSystemEntity.identical($path1, $path2)");
+      }
+      return response;
+    });
+  }
+
+
   /**
    * Do two paths refer to the same object in the file system?
    * Links are not identical to their targets, and two links
@@ -55,13 +98,26 @@
    */
   static bool identicalSync(String path1, String path2) {
     var result = _identical(path1, path2);
-    _throwIfError(result, 'Error in FileSystemEntity.identical');
+    _throwIfError(result, 'Error in FileSystemEntity.identicalSync');
     return result;
   }
 
+  static Future<FileSystemEntityType> type(String path,
+                                           {bool followLinks: true})
+      => _getTypeAsync(path, followLinks).then(FileSystemEntityType._lookup);
+
   static FileSystemEntityType typeSync(String path, {bool followLinks: true})
       => FileSystemEntityType._lookup(_getTypeSync(path, followLinks));
 
+  static Future<bool> isLink(String path) => _getTypeAsync(path, false)
+      .then((type) => (type == FileSystemEntityType.LINK._type));
+
+  static Future<bool> isFile(String path) => _getTypeAsync(path, true)
+      .then((type) => (type == FileSystemEntityType.FILE._type));
+
+  static Future<bool> isDirectory(String path) => _getTypeAsync(path, true)
+      .then((type) => (type == FileSystemEntityType.DIRECTORY._type));
+
   static bool isLinkSync(String path) =>
       (_getTypeSync(path, false) == FileSystemEntityType.LINK._type);
 
diff --git a/sdk/lib/io/http.dart b/sdk/lib/io/http.dart
index 5f6a75a..47be232 100644
--- a/sdk/lib/io/http.dart
+++ b/sdk/lib/io/http.dart
@@ -451,12 +451,12 @@
  *     request.headers.add(HttpHeaders.ACCEPT, v);
  *     request.headers.add(HttpHeaders.ACCEPT, "text/html");
  *
- * To parse the header values use the [:fromString:] constructor.
+ * To parse the header values use the [:parse:] static method.
  *
  *     HttpRequest request = ...;
  *     List<String> values = request.headers[HttpHeaders.ACCEPT];
  *     values.forEach((value) {
- *       HeaderValue v = new HeaderValue.fromString(value);
+ *       HeaderValue v = HeaderValue.parse(value);
  *       // Use v.value and v.parameters
  *     });
  *
@@ -474,10 +474,9 @@
    * Creates a new header value object from parsing a header value
    * string with both value and optional parameters.
    */
-  factory HeaderValue.fromString(String value,
-                                 {String parameterSeparator: ";"}) {
-    return new _HeaderValue.fromString(
-        value, parameterSeparator: parameterSeparator);
+  static HeaderValue parse(String value,
+                           {String parameterSeparator: ";"}) {
+    return _HeaderValue.parse(value, parameterSeparator: parameterSeparator);
   }
 
   /**
@@ -552,8 +551,8 @@
    * will create a content type object with primary type [:text:], sub
    * type [:html:] and parameter [:charset:] with value [:utf-8:].
    */
-  factory ContentType.fromString(String value) {
-    return new _ContentType.fromString(value);
+  static ContentType parse(String value) {
+    return _ContentType.parse(value);
   }
 
   /**
@@ -1102,6 +1101,16 @@
  */
 abstract class HttpClientRequest implements IOSink {
   /**
+   * 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.
@@ -1282,7 +1291,10 @@
 
 
 /**
- * Represents credentials for digest authentication.
+ * 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) =>
diff --git a/sdk/lib/io/http_headers.dart b/sdk/lib/io/http_headers.dart
index 919761a..f6f756b 100644
--- a/sdk/lib/io/http_headers.dart
+++ b/sdk/lib/io/http_headers.dart
@@ -196,7 +196,7 @@
   ContentType get contentType {
     var values = _headers["content-type"];
     if (values != null) {
-      return new ContentType.fromString(values[0]);
+      return ContentType.parse(values[0]);
     } else {
       return null;
     }
@@ -477,9 +477,11 @@
 
   _HeaderValue([String this._value = "", this._parameters]);
 
-  _HeaderValue.fromString(String value, {parameterSeparator: ";"}) {
+  static _HeaderValue parse(String value, {parameterSeparator: ";"}) {
     // Parse the string.
-    _parse(value, parameterSeparator);
+    var result = new _HeaderValue();
+    result._parse(value, parameterSeparator);
+    return result;
   }
 
   String get value => _value;
@@ -621,15 +623,20 @@
     }
   }
 
-  _ContentType.fromString(String value) : super.fromString(value) {
-    int index = _value.indexOf("/");
-    if (index == -1 || index == (_value.length - 1)) {
-      _primaryType = _value.trim().toLowerCase();
-      _subType = "";
+  _ContentType._();
+
+  static _ContentType parse(String value) {
+    var result = new _ContentType._();
+    result._parse(value, ";");
+    int index = result._value.indexOf("/");
+    if (index == -1 || index == (result._value.length - 1)) {
+      result._primaryType = result._value.trim().toLowerCase();
+      result._subType = "";
     } else {
-      _primaryType = _value.substring(0, index).trim().toLowerCase();
-      _subType = _value.substring(index + 1).trim().toLowerCase();
+      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';
diff --git a/sdk/lib/io/http_impl.dart b/sdk/lib/io/http_impl.dart
index ee855ec..8ea7174 100644
--- a/sdk/lib/io/http_impl.dart
+++ b/sdk/lib/io/http_impl.dart
@@ -273,17 +273,14 @@
 
   Future<HttpClientResponse> _authenticate() {
     Future<HttpClientResponse> retryWithCredentials(_Credentials cr) {
-      if (cr != null) {
-        // TODO(sgjesse): Support digest.
-        if (cr.scheme == _AuthenticationScheme.BASIC) {
-          // Drain body and retry.
-          return fold(null, (x, y) {}).then((_) {
-              return _httpClient._openUrlFromRequest(_httpRequest.method,
-                                                     _httpRequest.uri,
-                                                     _httpRequest)
-                  .then((request) => request.close());
-            });
-        }
+      if (cr != null && cr.scheme != _AuthenticationScheme.UNKNOWN) {
+        // Drain body and retry.
+        return fold(null, (x, y) {}).then((_) {
+            return _httpClient._openUrlFromRequest(_httpRequest.method,
+                                                   _httpRequest.uri,
+                                                   _httpRequest)
+                .then((request) => request.close());
+          });
       }
 
       // Fall through to here to perform normal response handling if
@@ -294,17 +291,45 @@
     List<String> challenge = headers[HttpHeaders.WWW_AUTHENTICATE];
     assert(challenge != null || challenge.length == 1);
     _HeaderValue header =
-        new _HeaderValue.fromString(challenge[0], parameterSeparator: ",");
+        _HeaderValue.parse(challenge[0], parameterSeparator: ",");
     _AuthenticationScheme scheme =
         new _AuthenticationScheme.fromString(header.value);
     String realm = header.parameters["realm"];
 
-    // See if any credentials are available.
+    // See if any matching credentials are available.
     _Credentials cr = _httpClient._findCredentials(_httpRequest.uri, 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 retryWithCredentials(cr);
+      }
 
-    if (cr != null && !cr.used) {
-      // If credentials found prepare for retrying the request.
-      return retryWithCredentials(cr);
+      // 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"];
+            cr.algorithm = "MD5";
+            cr.qop = header.parameters["qop"];
+            cr.nonceCount = 0;
+          }
+          // Credentials where found, prepare for retrying the request.
+          return retryWithCredentials(cr);
+        } 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 retryWithCredentials(cr);
+        }
+      }
     }
 
     // Ask for more credentials if none found or the one found has
@@ -346,7 +371,7 @@
     List<String> challenge = headers[HttpHeaders.PROXY_AUTHENTICATE];
     assert(challenge != null || challenge.length == 1);
     _HeaderValue header =
-        new _HeaderValue.fromString(challenge[0], parameterSeparator: ",");
+        _HeaderValue.parse(challenge[0], parameterSeparator: ",");
     _AuthenticationScheme scheme =
         new _AuthenticationScheme.fromString(header.value);
     String realm = header.parameters["realm"];
@@ -1095,6 +1120,7 @@
   _HttpClientRequest send(Uri uri, int port, String method, _Proxy proxy) {
     // Start with pausing the parser.
     _subscription.pause();
+    _Credentials cr;  // Credentials used to authorize this request.
     var outgoing = new _HttpOutgoing(_socket);
     // Create new request object, wrapping the outgoing connection.
     var request = new _HttpClientRequest(outgoing,
@@ -1126,7 +1152,7 @@
       request.headers.set(HttpHeaders.AUTHORIZATION, "Basic $auth");
     } else {
       // Look for credentials.
-      _Credentials cr = _httpClient._findCredentials(uri);
+      cr = _httpClient._findCredentials(uri);
       if (cr != null) {
         cr.authorize(request);
       }
@@ -1153,6 +1179,18 @@
                     destroy();
                   }
                 });
+                // For digest authentication check if the server
+                // requests the client to start using a new nonce.
+                if (cr != null && cr.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) cr.nonce = nextnonce;
+                  }
+                }
                 request._onIncoming(incoming);
               })
               // If we see a state error, we failed to get the 'first'
@@ -1374,6 +1412,29 @@
   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.
+    // See http://tools.ietf.org/html/rfc3986#section-4.2
+    replaceComponents({scheme, domain, port, path}) {
+      uri = new Uri.fromComponents(
+          scheme: scheme != null ? scheme : uri.scheme,
+          domain: domain != null ? domain : uri.domain,
+          port: port != null ? port : uri.port,
+          path: path != null ? path : uri.path,
+          query: uri.query,
+          fragment: uri.fragment);
+    }
+    if (uri.domain == '') {
+      replaceComponents(domain: previous.uri.domain, port: previous.uri.port);
+    }
+    if (uri.scheme == '') {
+      replaceComponents(scheme: previous.uri.scheme);
+    }
+    if (!uri.path.startsWith('/') && previous.uri.path.startsWith('/')) {
+      var absolute = new Path.raw(previous.uri.path).directoryPath;
+      absolute = absolute.join(new Path.raw(uri.path));
+      replaceComponents(path: absolute.canonicalize().toString());
+    }
     return openUrl(method, uri).then((_HttpClientRequest request) {
           // Only follow redirects if initial request did.
           request.followRedirects = previous.followRedirects;
@@ -1948,7 +2009,24 @@
 
 
 class _Credentials {
-  _Credentials(this.uri, this.realm, this.credentials);
+  _Credentials(this.uri, this.realm, this.credentials) {
+    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();
+      hasher.add(_encodeString(creds.username));
+      hasher.add([_CharCode.COLON]);
+      hasher.add(realm.codeUnits);
+      hasher.add([_CharCode.COLON]);
+      hasher.add(_encodeString(creds.password));
+      ha1 = CryptoUtils.bytesToHex(hasher.close());
+    }
+  }
 
   _AuthenticationScheme get scheme => credentials.scheme;
 
@@ -1963,6 +2041,12 @@
   }
 
   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;
   }
@@ -1973,9 +2057,11 @@
   _HttpClientCredentials credentials;
 
   // Digest specific fields.
+  String ha1;
   String nonce;
   String algorithm;
   String qop;
+  int nonceCount;
 }
 
 
@@ -2047,9 +2133,60 @@
 
   _AuthenticationScheme get scheme => _AuthenticationScheme.DIGEST;
 
+  String authorization(_Credentials credentials, HttpClientRequest request) {
+    MD5 hasher = new MD5();
+    hasher.add(request.method.codeUnits);
+    hasher.add([_CharCode.COLON]);
+    hasher.add(request.uri.path.codeUnits);
+    var ha2 = CryptoUtils.bytesToHex(hasher.close());
+
+    String qop;
+    String cnonce;
+    String nc;
+    var x;
+    hasher = new MD5();
+    hasher.add(credentials.ha1.codeUnits);
+    hasher.add([_CharCode.COLON]);
+    if (credentials.qop == "auth") {
+      qop = credentials.qop;
+      cnonce = CryptoUtils.bytesToHex(_IOCrypto.getRandomBytes(4));
+      ++credentials.nonceCount;
+      nc = credentials.nonceCount.toRadixString(16);
+      nc = "00000000".substring(0, 8 - nc.length + 1) + nc;
+      hasher.add(credentials.nonce.codeUnits);
+      hasher.add([_CharCode.COLON]);
+      hasher.add(nc.codeUnits);
+      hasher.add([_CharCode.COLON]);
+      hasher.add(cnonce.codeUnits);
+      hasher.add([_CharCode.COLON]);
+      hasher.add(credentials.qop.codeUnits);
+      hasher.add([_CharCode.COLON]);
+      hasher.add(ha2.codeUnits);
+    } else {
+      hasher.add(credentials.nonce.codeUnits);
+      hasher.add([_CharCode.COLON]);
+      hasher.add(ha2.codeUnits);
+    }
+    var response = CryptoUtils.bytesToHex(hasher.close());
+
+    StringBuffer buffer = new StringBuffer();
+    buffer.write('Digest ');
+    buffer.write('username="$username"');
+    buffer.write(', realm="${credentials.realm}"');
+    buffer.write(', nonce="${credentials.nonce}"');
+    buffer.write(', uri="${request.uri.path}"');
+    buffer.write(', algorithm="${credentials.algorithm}"');
+    if (qop == "auth") {
+      buffer.write(', qop="$qop"');
+      buffer.write(', cnonce="$cnonce"');
+      buffer.write(', nc="$nc"');
+    }
+    buffer.write(', response="$response"');
+    return buffer.toString();
+  }
+
   void authorize(_Credentials credentials, HttpClientRequest request) {
-    // TODO(sgjesse): Implement!!!
-    throw new UnsupportedError("Digest authentication not yet supported");
+    request.headers.set(HttpHeaders.AUTHORIZATION, authorization(credentials, request));
   }
 
   void authorizeProxy(_ProxyCredentials credentials,
diff --git a/sdk/lib/io/link.dart b/sdk/lib/io/link.dart
index d36d779..bb64fe9 100644
--- a/sdk/lib/io/link.dart
+++ b/sdk/lib/io/link.dart
@@ -128,10 +128,7 @@
 
   String toString() => "Link: '$path'";
 
-  Future<bool> exists() {
-    // TODO(whesse): Replace with asynchronous version.
-    return new Future.value(existsSync());
-  }
+  Future<bool> exists() => FileSystemEntity.isLink(path);
 
   bool existsSync() => FileSystemEntity.isLinkSync(path);
 
@@ -204,8 +201,17 @@
   }
 
   Future<String> target() {
-    // TODO(whesse): Replace with asynchronous version.
-    return new Future.sync(targetSync);
+    _ensureFileService();
+    List request = new List(2);
+    request[0] = _LINK_TARGET_REQUEST;
+    request[1] = path;
+    return _fileService.call(request).then((response) {
+      if (_isErrorResponse(response)) {
+        throw _exceptionFromResponse(response,
+            "Cannot get target of link '$path'");
+      }
+      return response;
+    });
   }
 
   String targetSync() {
diff --git a/sdk/lib/io/mime_multipart_parser.dart b/sdk/lib/io/mime_multipart_parser.dart
index e757c75..55451e9 100644
--- a/sdk/lib/io/mime_multipart_parser.dart
+++ b/sdk/lib/io/mime_multipart_parser.dart
@@ -4,45 +4,84 @@
 
 part of dart.io;
 
+
+/**
+ * A Mime Multipart class representing each part parsed by
+ * [MimeMultipartTransformer]. The data is streamed in as it become available.
+ */
+abstract class MimeMultipart extends Stream<List<int>> {
+  Map<String, String> get headers;
+}
+
+class _MimeMultipartImpl extends MimeMultipart {
+  final Map<String, String> headers;
+  final Stream<List<int>> _stream;
+
+  _MimeMultipartImpl(this.headers, this._stream);
+
+  StreamSubscription<List<int>> listen(void onData(List<int> data),
+                                       {void onDone(),
+                                        void onError(error),
+                                        bool cancelOnError}) {
+    return _stream.listen(onData,
+                          onDone: onDone,
+                          onError: onError,
+                          cancelOnError: cancelOnError);
+  }
+}
+
 /**
  * Parser for MIME multipart types of data as described in RFC 2046
- * section 5.1.1. The data to parse is supplied through the [:update:]
- * method. As the data is parsed the following callbacks are called:
- *
- *   [:partStart;
- *   [:headerReceived;
- *   [:headersComplete;
- *   [:partDataReceived;
- *   [:partEnd;
- *   [:error:]
+ * section 5.1.1. The data is transformed into [MimeMultipart] objects, each
+ * of them streaming the multipart data.
  */
+class MimeMultipartTransformer
+    implements StreamTransformer<List<int>, MimeMultipart> {
+  static const int _START = 0;
+  static const int _FIRST_BOUNDARY_ENDING = 111;
+  static const int _FIRST_BOUNDARY_END = 112;
+  static const int _BOUNDARY_ENDING = 1;
+  static const int _BOUNDARY_END = 2;
+  static const int _HEADER_START = 3;
+  static const int _HEADER_FIELD = 4;
+  static const int _HEADER_VALUE_START = 5;
+  static const int _HEADER_VALUE = 6;
+  static const int _HEADER_VALUE_FOLDING_OR_ENDING = 7;
+  static const int _HEADER_VALUE_FOLD_OR_END = 8;
+  static const int _HEADER_ENDING = 9;
+  static const int _CONTENT = 10;
+  static const int _LAST_BOUNDARY_DASH2 = 11;
+  static const int _LAST_BOUNDARY_ENDING = 12;
+  static const int _LAST_BOUNDARY_END = 13;
+  static const int _DONE = 14;
+  static const int _FAILURE = 15;
 
-class _MimeMultipartParser {
-  const int _START = 0;
-  const int _FIRST_BOUNDARY_ENDING = 111;
-  const int _FIRST_BOUNDARY_END = 112;
-  const int _BOUNDARY_ENDING = 1;
-  const int _BOUNDARY_END = 2;
-  const int _HEADER_START = 3;
-  const int _HEADER_FIELD = 4;
-  const int _HEADER_VALUE_START = 5;
-  const int _HEADER_VALUE = 6;
-  const int _HEADER_VALUE_FOLDING_OR_ENDING = 7;
-  const int _HEADER_VALUE_FOLD_OR_END = 8;
-  const int _HEADER_ENDING = 9;
-  const int _CONTENT = 10;
-  const int _LAST_BOUNDARY_DASH2 = 11;
-  const int _LAST_BOUNDARY_ENDING = 12;
-  const int _LAST_BOUNDARY_END = 13;
-  const int _DONE = 14;
-  const int _FAILURE = 15;
+  StreamController _controller;
+  StreamSubscription _subscription;
 
-  // Construct a new MIME multipart parser with the boundary
-  // [boundary]. The boundary should be as specified in the content
-  // type parameter, that is without the -- prefix.
-  _MimeMultipartParser(String boundary) {
+  StreamController _multipartController;
+  Map<String, String> _headers;
+
+  List<int> _boundary;
+  int _state = _START;
+  int _boundaryIndex = 0;
+
+  // Current index in the data buffer. If index is negative then it
+  // is the index into the artificial prefix of the boundary string.
+  int _index;
+  List<int> _buffer;
+
+  StringBuffer _headerField = new StringBuffer();
+  StringBuffer _headerValue = new StringBuffer();
+
+  /**
+   * Construct a new MIME multipart parser with the boundary
+   * [boundary]. The boundary should be as specified in the content
+   * type parameter, that is without the -- prefix.
+   */
+  MimeMultipartTransformer(String boundary) {
     List<int> charCodes = boundary.codeUnits;
-    _boundary = new List<int>(4 + charCodes.length);
+    _boundary = new Uint8List(4 + charCodes.length);
     // Set-up the matching boundary preceding it with CRLF and two
     // dashes.
     _boundary[0] = _CharCode.CR;
@@ -50,15 +89,51 @@
     _boundary[2] = _CharCode.DASH;
     _boundary[3] = _CharCode.DASH;
     _boundary.setRange(4, 4 + charCodes.length, charCodes);
-    _state = _START;
-    _headerField = new StringBuffer();
-    _headerValue = new StringBuffer();
   }
 
-  int update(List<int> buffer, int offset, int count) {
-    // Current index in the data buffer. If index is negative then it
-    // is the index into the artificial prefix of the boundary string.
-    int index;
+  void _resumeStream() {
+    _subscription.resume();
+  }
+
+  void _pauseStream() {
+    _subscription.pause();
+  }
+
+  Stream<MimeMultipart> bind(Stream<List<int>> stream) {
+    _controller = new StreamController(
+        onPause: () {
+          _pauseStream();
+        },
+        onResume: () {
+          _resumeStream();
+        },
+        onListen: () {
+          _subscription = stream.listen(
+              (data) {
+                assert(_buffer == null);
+                _pauseStream();
+                _buffer = data;
+                _index = 0;
+                _parse();
+              },
+              onDone: () {
+                if (_state != _DONE) {
+                  _controller.addError(
+                      new MimeParserException("Bad multipart ending"));
+                }
+                _controller.close();
+              },
+              onError: (error) {
+                _controller.addError(error);
+              });
+        },
+        onCancel: () {
+          _subscription.cancel();
+        });
+    return _controller.stream;
+  }
+
+  void _parse() {
     // Number of boundary bytes to artificially place before the supplied data.
     int boundaryPrefix = 0;
     // Position where content starts. Will be null if no known content
@@ -73,29 +148,24 @@
     // prefix of the boundary both the content start index and index
     // can be negative.
     void reportData() {
-      if (partDataReceived == null) return;
-
       if (contentStartIndex < 0) {
-        var contentLength = boundaryPrefix + index - _boundaryIndex;
+        var contentLength = boundaryPrefix + _index - _boundaryIndex;
         if (contentLength <= boundaryPrefix) {
-          partDataReceived(
+          _multipartController.add(
               _boundary.sublist(0, contentLength));
         } else {
-          partDataReceived(
+          _multipartController.add(
               _boundary.sublist(0, boundaryPrefix));
-          partDataReceived(
-              buffer.sublist(0, contentLength - boundaryPrefix));
+          _multipartController.add(
+              _buffer.sublist(0, contentLength - boundaryPrefix));
         }
       } else {
-        var contentEndIndex = index - _boundaryIndex;
-        partDataReceived(
-            buffer.sublist(contentStartIndex, contentEndIndex));
+        var contentEndIndex = _index - _boundaryIndex;
+        _multipartController.add(
+            _buffer.sublist(contentStartIndex, contentEndIndex));
       }
     }
 
-    // Prepare for processing the buffer.
-    index = offset;
-    int lastIndex = offset + count;
     if (_state == _CONTENT && _boundaryIndex == 0) {
       contentStartIndex = 0;
     } else {
@@ -105,12 +175,15 @@
     // partial match of the boundary.
     boundaryPrefix = _boundaryIndex;
 
-    while ((index < lastIndex) && _state != _FAILURE && _state != _DONE) {
+    while ((_index < _buffer.length) && _state != _FAILURE && _state != _DONE) {
+      if (_multipartController != null && _multipartController.isPaused) {
+        return;
+      }
       int byte;
-      if (index < 0) {
-        byte = _boundary[boundaryPrefix + index];
+      if (_index < 0) {
+        byte = _boundary[boundaryPrefix + _index];
       } else {
-        byte = buffer[index];
+        byte = _buffer[_index];
       }
       switch (_state) {
         case _START:
@@ -122,7 +195,7 @@
             }
           } else {
             // Restart matching of the boundary.
-            index = index - _boundaryIndex;
+            _index = _index - _boundaryIndex;
             _boundaryIndex = 0;
           }
           break;
@@ -152,103 +225,112 @@
 
         case _BOUNDARY_END:
           _expect(byte, _CharCode.LF);
-          if (partEnd != null) {
-            partEnd(false);
-          }
+          _multipartController.close();
+          _multipartController = null;
           _state = _HEADER_START;
           break;
 
         case _HEADER_START:
+          _headers = new Map<String, String>();
           if (byte == _CharCode.CR) {
             _state = _HEADER_ENDING;
+          } else {
+            // Start of new header field.
+            _headerField.writeCharCode(_toLowerCase(byte));
+            _state = _HEADER_FIELD;
+          }
+          break;
+
+        case _HEADER_FIELD:
+          if (byte == _CharCode.COLON) {
+            _state = _HEADER_VALUE_START;
+          } else {
+            if (!_isTokenChar(byte)) {
+              throw new MimeParserException("Invalid header field name");
+            }
+            _headerField.writeCharCode(_toLowerCase(byte));
+          }
+          break;
+
+        case _HEADER_VALUE_START:
+          if (byte == _CharCode.CR) {
+            _state = _HEADER_VALUE_FOLDING_OR_ENDING;
+          } else if (byte != _CharCode.SP && byte != _CharCode.HT) {
+            // Start of new header value.
+            _headerValue.writeCharCode(byte);
+            _state = _HEADER_VALUE;
+          }
+          break;
+
+        case _HEADER_VALUE:
+          if (byte == _CharCode.CR) {
+            _state = _HEADER_VALUE_FOLDING_OR_ENDING;
+          } else {
+            _headerValue.writeCharCode(byte);
+          }
+          break;
+
+        case _HEADER_VALUE_FOLDING_OR_ENDING:
+          _expect(byte, _CharCode.LF);
+          _state = _HEADER_VALUE_FOLD_OR_END;
+          break;
+
+        case _HEADER_VALUE_FOLD_OR_END:
+          if (byte == _CharCode.SP || byte == _CharCode.HT) {
+            _state = _HEADER_VALUE_START;
+          } else {
+            String headerField = _headerField.toString();
+            String headerValue =_headerValue.toString();
+            _headers[headerField] = headerValue;
+            _headerField = new StringBuffer();
+            _headerValue = new StringBuffer();
+            if (byte == _CharCode.CR) {
+              _state = _HEADER_ENDING;
             } else {
               // Start of new header field.
               _headerField.writeCharCode(_toLowerCase(byte));
               _state = _HEADER_FIELD;
             }
-            break;
+          }
+          break;
 
-          case _HEADER_FIELD:
-            if (byte == _CharCode.COLON) {
-              _state = _HEADER_VALUE_START;
-            } else {
-              if (!_isTokenChar(byte)) {
-                throw new MimeParserException("Invalid header field name");
+        case _HEADER_ENDING:
+          _expect(byte, _CharCode.LF);
+          _multipartController = new StreamController(
+              onPause: () {
+                _pauseStream();
+              },
+              onResume: () {
+                _resumeStream();
+                _parse();
+              });
+          _controller.add(
+              new _MimeMultipartImpl(_headers, _multipartController.stream));
+          _headers = null;
+          _state = _CONTENT;
+          contentStartIndex = _index + 1;
+          break;
+
+        case _CONTENT:
+          if (byte == _boundary[_boundaryIndex]) {
+            _boundaryIndex++;
+            if (_boundaryIndex == _boundary.length) {
+              if (contentStartIndex != null) {
+                _index++;
+                reportData();
+                _index--;
               }
-              _headerField.writeCharCode(_toLowerCase(byte));
-            }
-            break;
-
-          case _HEADER_VALUE_START:
-            if (byte == _CharCode.CR) {
-              _state = _HEADER_VALUE_FOLDING_OR_ENDING;
-            } else if (byte != _CharCode.SP && byte != _CharCode.HT) {
-              // Start of new header value.
-              _headerValue.writeCharCode(byte);
-              _state = _HEADER_VALUE;
-            }
-            break;
-
-          case _HEADER_VALUE:
-            if (byte == _CharCode.CR) {
-              _state = _HEADER_VALUE_FOLDING_OR_ENDING;
-            } else {
-              _headerValue.writeCharCode(byte);
-            }
-            break;
-
-          case _HEADER_VALUE_FOLDING_OR_ENDING:
-            _expect(byte, _CharCode.LF);
-            _state = _HEADER_VALUE_FOLD_OR_END;
-            break;
-
-          case _HEADER_VALUE_FOLD_OR_END:
-            if (byte == _CharCode.SP || byte == _CharCode.HT) {
-              _state = _HEADER_VALUE_START;
-            } else {
-              String headerField = _headerField.toString();
-              String headerValue =_headerValue.toString();
-              if (headerReceived != null) {
-                headerReceived(headerField, headerValue);
-              }
-              _headerField = new StringBuffer();
-              _headerValue = new StringBuffer();
-              if (byte == _CharCode.CR) {
-                _state = _HEADER_ENDING;
-              } else {
-                // Start of new header field.
-                _headerField.writeCharCode(_toLowerCase(byte));
-                _state = _HEADER_FIELD;
-              }
-            }
-            break;
-
-          case _HEADER_ENDING:
-            _expect(byte, _CharCode.LF);
-            if (headersComplete != null) headersComplete();
-            _state = _CONTENT;
-            contentStartIndex = index + 1;
-            break;
-
-          case _CONTENT:
-            if (_toLowerCase(byte) == _toLowerCase(_boundary[_boundaryIndex])) {
-              _boundaryIndex++;
-              if (_boundaryIndex == _boundary.length) {
-                if (contentStartIndex != null) {
-                  index++;
-                  reportData();
-                  index--;
-                }
-                _boundaryIndex = 0;
-                _state = _BOUNDARY_ENDING;
-              }
-            } else {
-              // Restart matching of the boundary.
-              index = index - _boundaryIndex;
-              if (contentStartIndex == null) contentStartIndex = index;
+              _multipartController.close();
               _boundaryIndex = 0;
+              _state = _BOUNDARY_ENDING;
             }
-            break;
+          } else {
+            // Restart matching of the boundary.
+            _index = _index - _boundaryIndex;
+            if (contentStartIndex == null) contentStartIndex = _index;
+            _boundaryIndex = 0;
+          }
+          break;
 
         case _LAST_BOUNDARY_DASH2:
           _expect(byte, _CharCode.DASH);
@@ -265,9 +347,8 @@
 
         case _LAST_BOUNDARY_END:
           _expect(byte, _CharCode.LF);
-          if (partEnd != null) {
-            partEnd(true);
-          }
+          _multipartController.close();
+          _multipartController = null;
           _state = _DONE;
           break;
 
@@ -278,14 +359,20 @@
       }
 
       // Move to the next byte.
-      index++;
+      _index++;
     }
 
     // Report any known content.
     if (_state == _CONTENT && contentStartIndex != null) {
       reportData();
     }
-    return index - offset;
+
+    // Resume if at end.
+    if (_index == _buffer.length) {
+      _buffer = null;
+      _index = null;
+      _resumeStream();
+    }
   }
 
   bool _isTokenChar(int byte) {
@@ -310,19 +397,6 @@
       throw new MimeParserException("Failed to parse multipart mime 2");
     }
   }
-
-  List<int> _boundary;
-  int _state;
-  int _boundaryIndex = 0;
-
-  StringBuffer _headerField;
-  StringBuffer _headerValue;
-
-  Function partStart;
-  Function headerReceived;
-  Function headersComplete;
-  Function partDataReceived;
-  Function partEnd;
 }
 
 
diff --git a/sdk/lib/typed_data/dart2js/typed_data_dart2js.dart b/sdk/lib/typed_data/dart2js/typed_data_dart2js.dart
index 593870d..abf484b 100644
--- a/sdk/lib/typed_data/dart2js/typed_data_dart2js.dart
+++ b/sdk/lib/typed_data/dart2js/typed_data_dart2js.dart
@@ -258,7 +258,7 @@
 
   @DomName('Float32Array.fromBuffer')
   @DocsEditable
-  factory Float32List.view(ByteBuffer buffer, [int byteOffset, int length]) => 
+  factory Float32List.view(ByteBuffer buffer, [int byteOffset, int length]) =>
     _TypedArrayFactoryProvider.createFloat32List_fromBuffer(buffer, byteOffset, length);
 
   static const int BYTES_PER_ELEMENT = 4;
@@ -488,7 +488,7 @@
 
   @DomName('Float64Array.fromBuffer')
   @DocsEditable
-  factory Float64List.view(ByteBuffer buffer, [int byteOffset, int length]) => 
+  factory Float64List.view(ByteBuffer buffer, [int byteOffset, int length]) =>
     _TypedArrayFactoryProvider.createFloat64List_fromBuffer(buffer, byteOffset, length);
 
   static const int BYTES_PER_ELEMENT = 8;
@@ -718,7 +718,7 @@
 
   @DomName('Int16Array.fromBuffer')
   @DocsEditable
-  factory Int16List.view(ByteBuffer buffer, [int byteOffset, int length]) => 
+  factory Int16List.view(ByteBuffer buffer, [int byteOffset, int length]) =>
     _TypedArrayFactoryProvider.createInt16List_fromBuffer(buffer, byteOffset, length);
 
   static const int BYTES_PER_ELEMENT = 2;
@@ -948,7 +948,7 @@
 
   @DomName('Int32Array.fromBuffer')
   @DocsEditable
-  factory Int32List.view(ByteBuffer buffer, [int byteOffset, int length]) => 
+  factory Int32List.view(ByteBuffer buffer, [int byteOffset, int length]) =>
     _TypedArrayFactoryProvider.createInt32List_fromBuffer(buffer, byteOffset, length);
 
   static const int BYTES_PER_ELEMENT = 4;
@@ -1178,7 +1178,7 @@
 
   @DomName('Int8Array.fromBuffer')
   @DocsEditable
-  factory Int8List.view(ByteBuffer buffer, [int byteOffset, int length]) => 
+  factory Int8List.view(ByteBuffer buffer, [int byteOffset, int length]) =>
     _TypedArrayFactoryProvider.createInt8List_fromBuffer(buffer, byteOffset, length);
 
   static const int BYTES_PER_ELEMENT = 1;
@@ -1408,7 +1408,7 @@
 
   @DomName('Uint16Array.fromBuffer')
   @DocsEditable
-  factory Uint16List.view(ByteBuffer buffer, [int byteOffset, int length]) => 
+  factory Uint16List.view(ByteBuffer buffer, [int byteOffset, int length]) =>
     _TypedArrayFactoryProvider.createUint16List_fromBuffer(buffer, byteOffset, length);
 
   static const int BYTES_PER_ELEMENT = 2;
@@ -1638,7 +1638,7 @@
 
   @DomName('Uint32Array.fromBuffer')
   @DocsEditable
-  factory Uint32List.view(ByteBuffer buffer, [int byteOffset, int length]) => 
+  factory Uint32List.view(ByteBuffer buffer, [int byteOffset, int length]) =>
     _TypedArrayFactoryProvider.createUint32List_fromBuffer(buffer, byteOffset, length);
 
   static const int BYTES_PER_ELEMENT = 4;
@@ -1868,7 +1868,7 @@
 
   @DomName('Uint8ClampedArray.fromBuffer')
   @DocsEditable
-  factory Uint8ClampedList.view(ByteBuffer buffer, [int byteOffset, int length]) => 
+  factory Uint8ClampedList.view(ByteBuffer buffer, [int byteOffset, int length]) =>
     _TypedArrayFactoryProvider.createUint8ClampedList_fromBuffer(buffer, byteOffset, length);
 
   // Use implementation from Uint8Array.
@@ -2095,7 +2095,7 @@
 
   @DomName('Uint8Array.fromBuffer')
   @DocsEditable
-  factory Uint8List.view(ByteBuffer buffer, [int byteOffset, int length]) => 
+  factory Uint8List.view(ByteBuffer buffer, [int byteOffset, int length]) =>
     _TypedArrayFactoryProvider.createUint8List_fromBuffer(buffer, byteOffset, length);
 
   static const int BYTES_PER_ELEMENT = 1;
@@ -2328,16 +2328,16 @@
 
 
 class Uint64List extends TypedData implements JavaScriptIndexingBehavior, List<int> {
-  factory Int64List(int length) {
-    throw new UnsupportedError("Int64List not supported by dart2js.");
+  factory Uint64List(int length) {
+    throw new UnsupportedError("Uint64List not supported by dart2js.");
   }
 
-  factory Int64List.fromList(List<int> list) {
-    throw new UnsupportedError("Int64List not supported by dart2js.");
+  factory Uint64List.fromList(List<int> list) {
+    throw new UnsupportedError("Uint64List not supported by dart2js.");
   }
 
-  factory Int64List.view(ByteBuffer buffer, [int byteOffset, int length]) {
-    throw new UnsupportedError("Int64List not supported by dart2js.");
+  factory Uint64List.view(ByteBuffer buffer, [int byteOffset, int length]) {
+    throw new UnsupportedError("Uint64List not supported by dart2js.");
   }
 
   static const int BYTES_PER_ELEMENT = 8;
diff --git a/tests/co19/co19-dart2dart.status b/tests/co19/co19-dart2dart.status
index f6e4a79..78dc0f9 100644
--- a/tests/co19/co19-dart2dart.status
+++ b/tests/co19/co19-dart2dart.status
@@ -4,11 +4,6 @@
 
 [ $compiler == dart2dart ]
 Language/07_Classes/6_Constructors/1_Generative_Constructors_A04_t15: Fail # TODO(dart2dart-team): Please triage this failure.
-Language/07_Classes/6_Constructors/2_Factories_A02_t01: Fail # TODO(dart2dart-team): Please triage this failure.
-Language/07_Classes/6_Constructors/2_Factories_A02_t02: Fail # TODO(dart2dart-team): Please triage this failure.
-Language/07_Classes/6_Constructors/2_Factories_A02_t03: Fail # TODO(dart2dart-team): Please triage this failure.
-Language/07_Classes/6_Constructors/2_Factories_A02_t04: Fail # TODO(dart2dart-team): Please triage this failure.
-Language/07_Classes/6_Constructors/2_Factories_A02_t05: Fail # TODO(dart2dart-team): Please triage this failure.
 Language/07_Classes/9_Superclasses/1_Inheritance_and_Overriding_A01_t03: Fail # TODO(dart2dart-team): Please triage this failure.
 Language/11_Expressions/01_Constants_A18_t06: Fail # TODO(dart2dart-team): Please triage this failure.
 Language/11_Expressions/11_Instance_Creation/2_Const_A03_t01: Fail # TODO(dart2dart-team): Please triage this failure.
diff --git a/tests/co19/co19-dart2js.status b/tests/co19/co19-dart2js.status
index b745700..3e46304 100644
--- a/tests/co19/co19-dart2js.status
+++ b/tests/co19/co19-dart2js.status
@@ -28,11 +28,6 @@
 Language/07_Classes/1_Instance_Methods_A06_t01: Fail # TODO(ahe): Please triage this failure.
 Language/07_Classes/1_Instance_Methods_A06_t02: Fail # TODO(ahe): Please triage this failure.
 Language/07_Classes/6_Constructors/1_Generative_Constructors_A04_t15: Fail # TODO(ahe): Please triage this failure.
-Language/07_Classes/6_Constructors/2_Factories_A02_t01: Fail # TODO(ahe): Please triage this failure.
-Language/07_Classes/6_Constructors/2_Factories_A02_t02: Fail # TODO(ahe): Please triage this failure.
-Language/07_Classes/6_Constructors/2_Factories_A02_t03: Fail # TODO(ahe): Please triage this failure.
-Language/07_Classes/6_Constructors/2_Factories_A02_t04: Fail # TODO(ahe): Please triage this failure.
-Language/07_Classes/6_Constructors/2_Factories_A02_t05: Fail # TODO(ahe): Please triage this failure.
 Language/07_Classes/6_Constructors/2_Factories_A07_t01: Fail # TODO(ahe): Please triage this failure.
 Language/07_Classes/6_Constructors/3_Constant_Constructors_A05_t01: Fail # TODO(ahe): Please triage this failure.
 Language/07_Classes/6_Constructors/3_Constant_Constructors_A05_t03: Fail # TODO(ahe): Please triage this failure.
diff --git a/tests/compiler/dart2js/dart_backend_test.dart b/tests/compiler/dart2js/dart_backend_test.dart
index c024dc6..0b5f109 100644
--- a/tests/compiler/dart2js/dart_backend_test.dart
+++ b/tests/compiler/dart2js/dart_backend_test.dart
@@ -16,18 +16,18 @@
 const coreLib = r'''
 library corelib;
 class Object {}
-interface bool {}
-interface num {}
-interface int extends num {}
-interface double extends num {}
+class bool {}
+class num {}
+class int extends num {}
+class double extends num {}
 abstract class String {}
-interface Function {}
-interface List<T> {}
-interface Map<K,V> {}
-interface Closure {}
-interface Dynamic_ {}
-interface Null {}
-interface TypeError {}
+class Function {}
+class List<T> {}
+class Map<K,V> {}
+class Closure {}
+class Dynamic_ {}
+class Null {}
+class TypeError {}
 class Type {}
 class LinkedHashMap {}
 class Math {
@@ -386,12 +386,6 @@
       continuation: (String result) { Expect.equals(expectedResult, result); });
 }
 
-testDefaultClassWithArgs() {
-  testDart2Dart('main(){var result=new IA<String>();}'
-      'interface IA<T> default A<T extends Object>{IA();}'
-      'class A<T extends Object> implements IA<T>{factory A(){}}');
-}
-
 testClassExtendsWithArgs() {
   testDart2Dart('main(){new B<Object>();}'
     'class A<T extends Object>{}'
@@ -469,33 +463,6 @@
   Expect.isTrue(fooPlaceholder.nodes.contains(fooNode.name));
 }
 
-testDefaultClassNamePlaceholder() {
-  var src = '''
-interface I default C{
-  I();
-}
-
-class C {
-  I() {}
-}
-
-main() {
-  new I();
-}
-''';
-  MockCompiler compiler = new MockCompiler();
-  compiler.parseScript(src);
-  ClassElement interfaceElement = compiler.mainApp.find(buildSourceString('I'));
-  interfaceElement.ensureResolved(compiler);
-  PlaceholderCollector collector =
-      collectPlaceholders(compiler, interfaceElement);
-  ClassNode interfaceNode = interfaceElement.parseNode(compiler);
-  Node defaultTypeNode = interfaceNode.defaultClause.typeName;
-  ClassElement classElement = compiler.mainApp.find(buildSourceString('C'));
-  // Check that 'C' in default clause of I gets into placeholders.
-  Expect.isTrue(collector.elementNodes[classElement].contains(defaultTypeNode));
-}
-
 testTypeVariablesAreRenamed() {
   // Somewhat a hack: we require all the references of the identifier
   // to be renamed in the same way for the whole library. Hence
@@ -544,14 +511,14 @@
   var librarySrc = '''
 library mylib;
 
-interface I {}
+class I {}
 class A<T extends I> {}
 
 ''';
   var mainSrc = '''
 import 'mylib.dart' as mylib;
 
-interface I {}
+class I {}
 class A<T extends I> {}
 
 main() {
@@ -560,9 +527,9 @@
 }
 ''';
   var expectedResult =
-    'interface I{}'
+    'class I{}'
     'class A<T extends I>{}'
-    'interface p_I{}'
+    'class p_I{}'
     'class p_A<p_T extends p_I>{}'
     'main(){new p_A();new A();}';
   testDart2DartWithLibrary(mainSrc, librarySrc,
@@ -745,12 +712,10 @@
   testConflictSendsRename();
   testNoConflictSendsRename();
   testConflictLibraryClassRename();
-  testDefaultClassWithArgs();
   testClassExtendsWithArgs();
   testStaticInvocation();
   testLibraryGetSet();
   testFieldTypeOutput();
-  testDefaultClassNamePlaceholder();
   testTypeVariablesAreRenamed();
   testClassTypeArgumentBound();
   testDoubleMains();
diff --git a/tests/compiler/dart2js/deprecated_features_test.dart b/tests/compiler/dart2js/deprecated_features_test.dart
index bb884bf..588e77f 100644
--- a/tests/compiler/dart2js/deprecated_features_test.dart
+++ b/tests/compiler/dart2js/deprecated_features_test.dart
@@ -43,7 +43,7 @@
     throw 'Compilation failed: ${messages}';
   }
   Expect.stringEquals(
-      // This string is comprised of lines of the following format:
+      // This string is composed of lines of the following format:
       //
       // offset<source>:path:kind: message
       //
@@ -56,20 +56,15 @@
       // short-term solution and should eventually changed to include
       // a symbolic reference to a MessageKind.
       "0<#library('test');>::${deprecatedMessage('# tags')}\n"
-      "38<interface>::${deprecatedMessage('interface declarations')}\n"
       "19<part 'part.dart';>::${deprecatedMessage('missing part-of tag')}\n"
       "0<>:/part.dart:info: Note: This file has no part-of tag, but it is being"
       " used as a part.\n"
-      "163<Fisk>::${deprecatedMessage('interface factories')}\n"
-
-      // TODO(ahe): Should be <Fisk.hest>.
-      "183<Fisk>::${deprecatedMessage('interface factories')}\n"
 
       // TODO(ahe): Should be <bar>.
-      "109<Foo>::${deprecatedMessage('conflicting constructor')}\n"
+      "52<Foo>::${deprecatedMessage('conflicting constructor')}\n"
 
-      "129<bar>::info: This member conflicts with a constructor.\n"
-      "205<()>::${deprecatedMessage('getter parameters')}\n",
+      "72<bar>::info: This member conflicts with a constructor.\n"
+      "103<()>::${deprecatedMessage('getter parameters')}\n",
       messages.toString());
 }
 
@@ -85,24 +80,15 @@
 
 part 'part.dart';
 
-interface Fisk default Foo {
-  Fisk();
-  Fisk.hest();
-}
-
 class Foo {
   Foo.bar();
   static bar() => new Foo.bar();
-  factory Fisk() {}
-  factory Fisk.hest() {}
   get x() => null;
 }
 
 main() {
   var a = Foo.bar();
   var b = new Foo.bar();
-  new Fisk();
-  new Fisk.hest();
 }
 """,
     // TODO(ahe): Why isn't this 'part.dart'? Why the leading slash?
diff --git a/tests/compiler/dart2js/mirrors_test.dart b/tests/compiler/dart2js/mirrors_test.dart
index 6f81d31..38ceef2 100644
--- a/tests/compiler/dart2js/mirrors_test.dart
+++ b/tests/compiler/dart2js/mirrors_test.dart
@@ -134,7 +134,6 @@
 
   Expect.isTrue(fooClass.isClass, "Class is not class");
   Expect.isFalse(fooClass.isAbstract);
-  Expect.isFalse(fooClass.isInterface, "Class is interface");
   Expect.isFalse(fooClass.isPrivate, "Class is private");
 
   var objectType = fooClass.superclass;
@@ -163,8 +162,6 @@
   Expect.isTrue(fooClassTypeVariables.isEmpty,
                 "Type variable list is not empty");
 
-  Expect.isNull(fooClass.defaultFactory);
-
   var fooClassMembers = fooClass.members;
   Expect.isNotNull(fooClassMembers, "Declared members map is null");
   Expect.isTrue(fooClassMembers.isEmpty, "Declared members map is unempty");
@@ -450,7 +447,6 @@
 
   Expect.isTrue(barClass.isClass);
   Expect.isTrue(barClass.isAbstract);
-  Expect.isFalse(barClass.isInterface);
   Expect.isFalse(barClass.isPrivate, "Interface is private");
 
   var objectType = barClass.superclass;
@@ -487,8 +483,6 @@
   Expect.isNotNull(barE, "Type variable is null");
   Expect.isTrue(barE.isTypeVariable, "Type variable is not type variable");
 
-  Expect.isNull(barClass.defaultFactory);
-
   var barInterfaceMembers = barClass.members;
   Expect.isNotNull(barInterfaceMembers, "Declared members map is null");
   Expect.isTrue(barInterfaceMembers.isEmpty,
@@ -544,7 +538,6 @@
 
   Expect.isTrue(bazClass.isClass, "Class is not class");
   Expect.isFalse(bazClass.isAbstract);
-  Expect.isFalse(bazClass.isInterface, "Class is interface");
   Expect.isFalse(bazClass.isPrivate, "Class is private");
 
   var objectType = bazClass.superclass;
@@ -607,8 +600,6 @@
   Expect.stringEquals("mirrors_helper.Foo", bazFbound.qualifiedName,
                       "Bound is not Foo");
 
-  Expect.isNull(bazClass.defaultFactory);
-
   var bazClassMembers = bazClass.members;
   Expect.isNotNull(bazClassMembers, "Declared members map is null");
   Expect.equals(8, bazClassMembers.length,
@@ -640,7 +631,6 @@
   Expect.isFalse(method1.isGetter);
   Expect.isFalse(method1.isSetter);
   Expect.isFalse(method1.isOperator);
-  Expect.isNull(method1.operatorName);
 
   var dynamicType = method1.returnType;
   Expect.isNotNull(dynamicType, "Return type was null");
@@ -694,7 +684,6 @@
   Expect.isFalse(method2.isGetter);
   Expect.isFalse(method2.isSetter);
   Expect.isFalse(method2.isOperator);
-  Expect.isNull(method2.operatorName);
 
   var voidType = method2.returnType;
   Expect.isNotNull(voidType, "Return type was null");
@@ -761,7 +750,6 @@
   Expect.isFalse(method3.isGetter);
   Expect.isFalse(method3.isSetter);
   Expect.isFalse(method3.isOperator);
-  Expect.isNull(method3.operatorName);
 
   var method3ReturnType = method3.returnType;
   Expect.isNotNull(method3ReturnType, "Return type is null");
@@ -831,9 +819,7 @@
   // declaration:
   Expect.isTrue(funcTypedef.isOriginalDeclaration);
   Expect.isFalse(funcTypedef.isClass, "Typedef is class");
-  Expect.isFalse(funcTypedef.isInterface, "Typedef is interface");
   Expect.isFalse(funcTypedef.isPrivate, "Typedef is private");
-  Expect.isNull(funcTypedef.defaultFactory);
   // TODO(johnniwinther): Should not throw an exception since the type should
   // not be the original declaration.
   Expect.throws(() => funcTypedef.typeArguments,
@@ -866,7 +852,7 @@
   Expect.isNotNull(operator_eq, "operator == not found");
   Expect.stringEquals('==', operator_eq.simpleName,
                       "Unexpected method simpleName");
-  Expect.stringEquals('operator ==', operator_eq.displayName);
+  Expect.stringEquals('operator ==', displayName(operator_eq));
   Expect.stringEquals('mirrors_helper.Baz.==',
                       operator_eq.qualifiedName,
                       "Unexpected method qualifiedName");
@@ -887,7 +873,7 @@
   Expect.isFalse(operator_eq.isGetter);
   Expect.isFalse(operator_eq.isSetter);
   Expect.isTrue(operator_eq.isOperator);
-  Expect.stringEquals('==', operator_eq.operatorName);
+  Expect.stringEquals('==', operatorName(operator_eq));
 
   ////////////////////////////////////////////////////////////////////////////
   // int operator -() => 0;
@@ -896,7 +882,7 @@
   Expect.isNotNull(operator_negate, "operator < not found");
   Expect.stringEquals(Mirror.UNARY_MINUS, operator_negate.simpleName,
                       "Unexpected method simpleName");
-  Expect.stringEquals('operator -', operator_negate.displayName);
+  Expect.stringEquals('operator -', displayName(operator_negate));
   Expect.stringEquals('mirrors_helper.Baz.${Mirror.UNARY_MINUS}',
                       operator_negate.qualifiedName,
                       "Unexpected method qualifiedName");
@@ -917,7 +903,7 @@
   Expect.isFalse(operator_negate.isGetter);
   Expect.isFalse(operator_negate.isSetter);
   Expect.isTrue(operator_negate.isOperator);
-  Expect.stringEquals('-', operator_negate.operatorName);
+  Expect.stringEquals('-', operatorName(operator_negate));
 
 
   var bazClassConstructors = bazClass.constructors;
@@ -938,7 +924,7 @@
   Expect.isFalse(bazClassNonameConstructor.isRedirectingConstructor);
   Expect.isFalse(bazClassNonameConstructor.isFactoryConstructor);
   Expect.stringEquals('Baz', bazClassNonameConstructor.simpleName);
-  Expect.stringEquals('Baz', bazClassNonameConstructor.displayName);
+  Expect.stringEquals('Baz', displayName(bazClassNonameConstructor));
   Expect.stringEquals('mirrors_helper.Baz.Baz',
       bazClassNonameConstructor.qualifiedName);
   Expect.stringEquals('', bazClassNonameConstructor.constructorName);
@@ -956,7 +942,7 @@
   Expect.isFalse(bazClassNamedConstructor.isRedirectingConstructor);
   Expect.isFalse(bazClassNamedConstructor.isFactoryConstructor);
   Expect.stringEquals('Baz.named', bazClassNamedConstructor.simpleName);
-  Expect.stringEquals('Baz.named', bazClassNamedConstructor.displayName);
+  Expect.stringEquals('Baz.named', displayName(bazClassNamedConstructor));
   Expect.stringEquals('mirrors_helper.Baz.Baz.named',
       bazClassNamedConstructor.qualifiedName);
   Expect.stringEquals('named', bazClassNamedConstructor.constructorName);
@@ -974,7 +960,7 @@
   Expect.isFalse(bazClassFactoryConstructor.isRedirectingConstructor);
   Expect.isTrue(bazClassFactoryConstructor.isFactoryConstructor);
   Expect.stringEquals('Baz.factory', bazClassFactoryConstructor.simpleName);
-  Expect.stringEquals('Baz.factory', bazClassFactoryConstructor.displayName);
+  Expect.stringEquals('Baz.factory', displayName(bazClassFactoryConstructor));
   Expect.stringEquals('mirrors_helper.Baz.Baz.factory',
       bazClassFactoryConstructor.qualifiedName);
   Expect.stringEquals('factory', bazClassFactoryConstructor.constructorName);
diff --git a/tests/compiler/dart2js/mock_compiler.dart b/tests/compiler/dart2js/mock_compiler.dart
index 453bbf2..1aa2277 100644
--- a/tests/compiler/dart2js/mock_compiler.dart
+++ b/tests/compiler/dart2js/mock_compiler.dart
@@ -134,7 +134,11 @@
   class ObjectInterceptor {
   }
   getInterceptor(x) {}
-  getNativeInterceptor(x) {}''';
+  getNativeInterceptor(x) {}
+  getDispatchProperty(o) {}
+  initializeDispatchProperty(f,p,i) {}
+  initializeDispatchPropertyCSP(f,p,i) {}
+''';
 
 const String DEFAULT_CORELIB = r'''
   print(var obj) {}
diff --git a/tests/compiler/dart2js/resolver_test.dart b/tests/compiler/dart2js/resolver_test.dart
index 01e0205..a1d6ad3 100644
--- a/tests/compiler/dart2js/resolver_test.dart
+++ b/tests/compiler/dart2js/resolver_test.dart
@@ -463,8 +463,9 @@
       compiler.errors[0].message);
   compiler.clearErrors();
 
-  // Add the interface to the world and make sure everything is setup correctly.
-  compiler.parseScript("interface Bar {}");
+  // Add the abstract class to the world and make sure everything is setup
+  // correctly.
+  compiler.parseScript("abstract class Bar {}");
 
   ResolverVisitor visitor =
       new ResolverVisitor(compiler, null, new CollectingTreeElements(null));
@@ -484,7 +485,7 @@
 testTwoInterfaces() {
   MockCompiler compiler = new MockCompiler();
   compiler.parseScript(
-      "interface I1 {} interface I2 {} class C implements I1, I2 {}");
+      "abstract class I1 {} abstract class I2 {} class C implements I1, I2 {}");
   compiler.resolveStatement("Foo bar;");
 
   ClassElement c = compiler.mainApp.find(buildSourceString('C'));
diff --git a/tests/compiler/dart2js/type_checker_test.dart b/tests/compiler/dart2js/type_checker_test.dart
index 855a865..1381be8 100644
--- a/tests/compiler/dart2js/type_checker_test.dart
+++ b/tests/compiler/dart2js/type_checker_test.dart
@@ -266,10 +266,10 @@
 void testMethodInvocations() {
   compiler.parseScript(CLASS_WITH_METHODS);
   final String header = """{
-      ClassWithMethods c; 
-      SubClass d; 
-      var e; 
-      int i; 
+      ClassWithMethods c;
+      SubClass d;
+      var e;
+      int i;
       int j;
       int localMethod(String str) { return 0; }
       """;
@@ -431,8 +431,8 @@
 //    "  Foo.foo() {}\n" +
 //    "  Foo.bar([int i = null]) {}\n" +
 //    "}\n" +
-//    "interface Bar<T> factory Baz {\n" +
-//    "  Bar.make();\n" +
+//    "abstract class Bar<T> {\n" +
+//    "  factory Bar.make() => new Baz<T>.make();\n" +
 //    "}\n" +
 //    "class Baz {\n" +
 //    "  factory Bar<S>.make(S x) { return null; }\n" +
@@ -516,7 +516,7 @@
 
   static int staticMethod(String str) {}
 }
-interface I {
+class I {
   int intMethod();
 }
 class SubClass extends ClassWithMethods implements I {}''';
diff --git a/tests/compiler/dart2js/value_range_test.dart b/tests/compiler/dart2js/value_range_test.dart
index 32aee9f..f623ced 100644
--- a/tests/compiler/dart2js/value_range_test.dart
+++ b/tests/compiler/dart2js/value_range_test.dart
@@ -222,6 +222,11 @@
   bool identical(Object a, Object b) {}''';
 
 const String INTERCEPTORSLIB_WITH_MEMBERS = r'''
+  class Interceptor {
+    toString() {}
+    bool operator==(other) => identical(this, other);
+    noSuchMethod(im) { throw im; }
+  }
   abstract class JSIndexable {
     get length;
   }
diff --git a/tests/compiler/dart2js_foreign/native_class_is_check1_test.dart b/tests/compiler/dart2js_foreign/native_class_is_check1_test.dart
index 5c4ca64..11879ec 100644
--- a/tests/compiler/dart2js_foreign/native_class_is_check1_test.dart
+++ b/tests/compiler/dart2js_foreign/native_class_is_check1_test.dart
@@ -7,7 +7,7 @@
 import "package:expect/expect.dart";
 import 'native_metadata.dart';
 
-interface I {
+abstract class I {
   I read();
   write(I x);
 }
diff --git a/tests/compiler/dart2js_foreign/native_class_is_check3_test.dart b/tests/compiler/dart2js_foreign/native_class_is_check3_test.dart
index b6e63bb..a311203 100644
--- a/tests/compiler/dart2js_foreign/native_class_is_check3_test.dart
+++ b/tests/compiler/dart2js_foreign/native_class_is_check3_test.dart
@@ -7,10 +7,10 @@
 import "package:expect/expect.dart";
 import 'native_metadata.dart';
 
-interface J {
+abstract class J {
 }
 
-interface I extends J {
+abstract class I extends J {
   I read();
   write(I x);
 }
diff --git a/tests/compiler/dart2js_foreign/native_field_rename_2_test.dart b/tests/compiler/dart2js_foreign/native_field_rename_2_test.dart
index 55efc6c..a920236 100644
--- a/tests/compiler/dart2js_foreign/native_field_rename_2_test.dart
+++ b/tests/compiler/dart2js_foreign/native_field_rename_2_test.dart
@@ -9,7 +9,7 @@
 import "package:expect/expect.dart";
 import 'native_metadata.dart';
 
-interface I {
+abstract class I {
   int key;
 }
 
diff --git a/tests/compiler/dart2js_foreign/native_library_same_name_used_lib1.dart b/tests/compiler/dart2js_foreign/native_library_same_name_used_lib1.dart
index fbe7446..35ecf2f 100644
--- a/tests/compiler/dart2js_foreign/native_library_same_name_used_lib1.dart
+++ b/tests/compiler/dart2js_foreign/native_library_same_name_used_lib1.dart
@@ -2,13 +2,13 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// 'I' is the name of an interface and the name of the native class.
+// 'I' is the name of an abstract class and the name of the native class.
 
 library native_library_same_name_used_lib1;
 
 import 'native_library_same_name_used_lib2.dart';
 
-interface I {
+abstract class I {
   I read();
   write(I x);
 }
diff --git a/tests/compiler/dart2js_foreign/native_library_same_name_used_lib2.dart b/tests/compiler/dart2js_foreign/native_library_same_name_used_lib2.dart
index 60b9761..431cffc 100644
--- a/tests/compiler/dart2js_foreign/native_library_same_name_used_lib2.dart
+++ b/tests/compiler/dart2js_foreign/native_library_same_name_used_lib2.dart
@@ -5,10 +5,10 @@
 // Native implementation.
 
 library lib2;
-import 'native_library_same_name_used_lib1.dart';  // To get interface I.
+import 'native_library_same_name_used_lib1.dart';  // To get abstract class I.
 import 'native_metadata.dart';
 
-// Native impl has same name as interface.
+// Native impl has same name as abstract class.
 @Native("*I")
 class Impl implements I  {
   @native Impl read();
diff --git a/tests/compiler/dart2js_foreign/native_library_same_name_used_test.dart b/tests/compiler/dart2js_foreign/native_library_same_name_used_test.dart
index 90ad5d2..a8af518 100644
--- a/tests/compiler/dart2js_foreign/native_library_same_name_used_test.dart
+++ b/tests/compiler/dart2js_foreign/native_library_same_name_used_test.dart
@@ -2,7 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// Test for correct hidden native class when interface has same name.
+// Test for correct hidden native class when abstract class has same name.
 
 library main;
 import "package:expect/expect.dart";
diff --git a/tests/compiler/dart2js_foreign/native_window1_test.dart b/tests/compiler/dart2js_foreign/native_window1_test.dart
index 1f1ee85..8694830 100644
--- a/tests/compiler/dart2js_foreign/native_window1_test.dart
+++ b/tests/compiler/dart2js_foreign/native_window1_test.dart
@@ -5,7 +5,7 @@
 import "package:expect/expect.dart";
 import 'native_metadata.dart';
 
-interface Window {
+abstract class Window {
   final int document;
 }
 
diff --git a/tests/compiler/dart2js_foreign/native_window2_test.dart b/tests/compiler/dart2js_foreign/native_window2_test.dart
index 328601b..0cb3a08 100644
--- a/tests/compiler/dart2js_foreign/native_window2_test.dart
+++ b/tests/compiler/dart2js_foreign/native_window2_test.dart
@@ -5,7 +5,7 @@
 import "package:expect/expect.dart";
 import 'native_metadata.dart';
 
-interface Window {
+abstract class Window {
   final int document;
 }
 
diff --git a/tests/compiler/dart2js_native/downcast_test.dart b/tests/compiler/dart2js_native/downcast_test.dart
index 079b5f7..27ec4b2 100644
--- a/tests/compiler/dart2js_native/downcast_test.dart
+++ b/tests/compiler/dart2js_native/downcast_test.dart
@@ -6,10 +6,10 @@
 
 import "package:expect/expect.dart";
 
-interface J {
+abstract class J {
 }
 
-interface I extends J {
+abstract class I extends J {
   I read();
   write(I x);
 }
diff --git a/tests/compiler/dart2js_native/native_class_is_check1_frog_test.dart b/tests/compiler/dart2js_native/native_class_is_check1_frog_test.dart
index ece197b..e01fa1a 100644
--- a/tests/compiler/dart2js_native/native_class_is_check1_frog_test.dart
+++ b/tests/compiler/dart2js_native/native_class_is_check1_frog_test.dart
@@ -6,7 +6,7 @@
 
 // Test for correct simple is-checks on hidden native classes.
 
-interface I {
+abstract class I {
   I read();
   write(I x);
 }
diff --git a/tests/compiler/dart2js_native/native_class_is_check3_frog_test.dart b/tests/compiler/dart2js_native/native_class_is_check3_frog_test.dart
index 0a36764..490e820 100644
--- a/tests/compiler/dart2js_native/native_class_is_check3_frog_test.dart
+++ b/tests/compiler/dart2js_native/native_class_is_check3_frog_test.dart
@@ -6,10 +6,10 @@
 
 // Test for correct simple is-checks on hidden native classes.
 
-interface J {
+abstract class J {
 }
 
-interface I extends J {
+abstract class I extends J {
   I read();
   write(I x);
 }
diff --git a/tests/compiler/dart2js_native/native_field_rename_2_frog_test.dart b/tests/compiler/dart2js_native/native_field_rename_2_frog_test.dart
index 75efb3c..2bd4481 100644
--- a/tests/compiler/dart2js_native/native_field_rename_2_frog_test.dart
+++ b/tests/compiler/dart2js_native/native_field_rename_2_frog_test.dart
@@ -9,7 +9,7 @@
 import "package:expect/expect.dart";
 import 'dart:_js_helper' show JSName;
 
-interface I {
+abstract class I {
   int key;
 }
 
diff --git a/tests/compiler/dart2js_native/native_library_same_name_used_frog_test.dart b/tests/compiler/dart2js_native/native_library_same_name_used_frog_test.dart
index 4909259..1279da2 100644
--- a/tests/compiler/dart2js_native/native_library_same_name_used_frog_test.dart
+++ b/tests/compiler/dart2js_native/native_library_same_name_used_frog_test.dart
@@ -2,7 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// Test for correct hidden native class when interface has same name.
+// Test for correct hidden native class when abstract class has same name.
 
 library main;
 import "package:expect/expect.dart";
diff --git a/tests/compiler/dart2js_native/native_library_same_name_used_lib1.dart b/tests/compiler/dart2js_native/native_library_same_name_used_lib1.dart
index 3080d4c..d74671c 100644
--- a/tests/compiler/dart2js_native/native_library_same_name_used_lib1.dart
+++ b/tests/compiler/dart2js_native/native_library_same_name_used_lib1.dart
@@ -2,13 +2,13 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// 'I' is the name of an interface and the name of the native class.
+// 'I' is the name of an abstract class and the name of the native class.
 
 library native_library_same_name_used_lib1;
 
 import 'native_library_same_name_used_lib2.dart';
 
-interface I {
+abstract class I {
   I read();
   write(I x);
 }
diff --git a/tests/compiler/dart2js_native/native_library_same_name_used_lib2.dart b/tests/compiler/dart2js_native/native_library_same_name_used_lib2.dart
index 4a2e514..558e619 100644
--- a/tests/compiler/dart2js_native/native_library_same_name_used_lib2.dart
+++ b/tests/compiler/dart2js_native/native_library_same_name_used_lib2.dart
@@ -5,9 +5,9 @@
 // Native implementation.
 
 library lib2;
-import 'native_library_same_name_used_lib1.dart';  // To get interface I.
+import 'native_library_same_name_used_lib1.dart';  // To get abstract class I.
 
-// Native impl has same name as interface.
+// Native impl has same name as abstract class.
 class Impl implements I native "I" {
   Impl read() native;
   write(Impl x) native;
diff --git a/tests/compiler/dart2js_native/native_window1_frog_test.dart b/tests/compiler/dart2js_native/native_window1_frog_test.dart
index 553f924..f6b727a 100644
--- a/tests/compiler/dart2js_native/native_window1_frog_test.dart
+++ b/tests/compiler/dart2js_native/native_window1_frog_test.dart
@@ -4,7 +4,7 @@
 
 import "package:expect/expect.dart";
 
-interface Window {
+abstract class Window {
   final int document;
 }
 
diff --git a/tests/compiler/dart2js_native/native_window2_frog_test.dart b/tests/compiler/dart2js_native/native_window2_frog_test.dart
index a58450c..c1cecef 100644
--- a/tests/compiler/dart2js_native/native_window2_frog_test.dart
+++ b/tests/compiler/dart2js_native/native_window2_frog_test.dart
@@ -4,7 +4,7 @@
 
 import "package:expect/expect.dart";
 
-interface Window {
+abstract class Window {
   final int document;
 }
 
diff --git a/tests/corelib/date_time9_test.dart b/tests/corelib/date_time9_test.dart
new file mode 100644
index 0000000..40df972
--- /dev/null
+++ b/tests/corelib/date_time9_test.dart
@@ -0,0 +1,42 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+main() {
+  var dt = new DateTime.now();
+  Expect.isTrue(dt is Comparable);
+
+  var dt2 = new DateTime.fromMillisecondsSinceEpoch(100);
+  var dt3 = new DateTime.fromMillisecondsSinceEpoch(200, isUtc: true);
+  var dt3b = new DateTime.fromMillisecondsSinceEpoch(200);
+  var dt4 = new DateTime.fromMillisecondsSinceEpoch(300);
+  var dt5 = new DateTime.fromMillisecondsSinceEpoch(400, isUtc: true);
+  var dt5b = new DateTime.fromMillisecondsSinceEpoch(400);
+
+  Expect.isTrue(dt2.compareTo(dt2) == 0);
+  Expect.isTrue(dt3.compareTo(dt3) == 0);
+  Expect.isTrue(dt3b.compareTo(dt3b) == 0);
+  Expect.isTrue(dt4.compareTo(dt4) == 0);
+  Expect.isTrue(dt5.compareTo(dt5) == 0);
+  Expect.isTrue(dt5b.compareTo(dt5b) == 0);
+
+  // Time zones don't have any effect.
+  Expect.isTrue(dt3.compareTo(dt3b) == 0);
+  Expect.isTrue(dt5.compareTo(dt5b) == 0);
+
+  Expect.isTrue(dt2.compareTo(dt3) < 0);
+  Expect.isTrue(dt3.compareTo(dt4) < 0);
+  Expect.isTrue(dt4.compareTo(dt5) < 0);
+
+  Expect.isTrue(dt2.compareTo(dt3b) < 0);
+  Expect.isTrue(dt4.compareTo(dt5b) < 0);
+
+   Expect.isTrue(dt3.compareTo(dt2) > 0);
+  Expect.isTrue(dt4.compareTo(dt3) > 0);
+  Expect.isTrue(dt5.compareTo(dt4) > 0);
+
+  Expect.isTrue(dt3b.compareTo(dt2) > 0);
+  Expect.isTrue(dt5b.compareTo(dt4) > 0);
+}
diff --git a/tests/corelib/list_for_each_test.dart b/tests/corelib/list_for_each_test.dart
new file mode 100644
index 0000000..effe6da
--- /dev/null
+++ b/tests/corelib/list_for_each_test.dart
@@ -0,0 +1,61 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+import "dart:collection";
+
+class MyList extends ListBase {
+  List list;
+  MyList(this.list);
+  get length => list.length;
+  set length(value) { list.length = value; }
+  operator [](index) => list[index];
+  operator []=(index, val) { list[index] = val; }
+  toString() => list.toString();
+}
+
+void testWithoutModification(List list) {
+  var seen = [];
+  list.forEach(seen.add);
+
+  Expect.listEquals(list, seen);
+}
+
+void testWithModification(List list) {
+  if (list.isEmpty) return;
+  Expect.throws(() => list.forEach((_) => list.add(0)),
+                (e) => e is ConcurrentModificationError);
+}
+
+main() {
+  List fixedLengthList = new List(10);
+  for (int i = 0; i < 10; i++) fixedLengthList[i] = i + 1;
+
+  List growableList = new List();
+  growableList.length = 10;
+  for (int i = 0; i < 10; i++) growableList[i] = i + 1;
+
+  var growableLists = [
+    [],
+    [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
+    new MyList([1, 2, 3, 4, 5]),
+    growableList,
+  ];
+  var fixedLengthLists = [
+    const [],
+    fixedLengthList,
+    const [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
+    new MyList(const [1, 2]),
+  ];
+
+  for (var list in growableLists) {
+    print(list);
+    testWithoutModification(list);
+    testWithModification(list);
+  }
+
+  for (var list in fixedLengthLists) {
+    testWithoutModification(list);
+  }
+}
diff --git a/tests/language/constructor_name_test.dart b/tests/language/constructor_name_test.dart
new file mode 100644
index 0000000..93742a6
--- /dev/null
+++ b/tests/language/constructor_name_test.dart
@@ -0,0 +1,16 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for 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 Foo {
+  Bar.Foo(); /// 01: compile-time error
+  factory Bar(); /// 02: compile-time error
+  factory Bar.Baz(); /// 03: compile-time error
+}
+
+
+void main() {
+  new Foo();
+  new Foo.Foo(); /// 01: continued
+  new Foo.Baz(); /// 03: continued
+}
\ No newline at end of file
diff --git a/tests/language/language.status b/tests/language/language.status
index 740c10f..879ef11 100644
--- a/tests/language/language.status
+++ b/tests/language/language.status
@@ -16,9 +16,21 @@
 # 3) Update the language/src directory with the updated test.
 
 [ $compiler == dart2dart ]
+mixin_super_constructor_test: Fail
+mixin_super_constructor2_test: Fail
+mixin_super_constructor_default_test: Fail
+mixin_super_constructor_named_test: Fail
+mixin_super_constructor_positionals_test: Fail
+mixin_super_constructor_multiple_test: Fail
 closure_type_variable_test: Fail # Type variable used as expression (dartbug.com/6282)
 
 [ $compiler == none ]
+mixin_super_constructor_test: Fail
+mixin_super_constructor2_test: Fail
+mixin_super_constructor_default_test: Fail
+mixin_super_constructor_named_test: Fail
+mixin_super_constructor_positionals_test: Fail
+mixin_super_constructor_multiple_test: Fail
 closure_type_variable_test: Fail # Type variable used as expression (dartbug.com/6282)
 built_in_identifier_prefix_test: Fail # http://dartbug.com/6970
 library_juxtaposition_test: Fail # Issue 6877
diff --git a/tests/language/mixin_super_constructor2_test.dart b/tests/language/mixin_super_constructor2_test.dart
new file mode 100644
index 0000000..b54c791
--- /dev/null
+++ b/tests/language/mixin_super_constructor2_test.dart
@@ -0,0 +1,39 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+class Base {
+  int i, j;
+  Base.ctor1(int i, this.j) : this.i = i + 7;
+  Base.ctor2(int i, this.j) : this.i = i + 8;
+}
+
+abstract class M {
+  get i;
+  get j;
+  int k = 42;
+  foo() => i + j;
+}
+
+class C extends Base with M {
+  int l = 131;
+  C.ctor1() : super.ctor1(1, 13);
+  C.ctor2() : super.ctor2(1, 13);
+}
+
+main() {
+  C c1 = new C.ctor1();
+  Expect.equals(8, c1.i);
+  Expect.equals(13, c1.j);
+  Expect.equals(42, c1.k);
+  Expect.equals(131, c1.l);
+  Expect.equals(21, c1.foo());
+  C c2 = new C.ctor2();
+  Expect.equals(9, c2.i);
+  Expect.equals(13, c2.j);
+  Expect.equals(42, c2.k);
+  Expect.equals(131, c2.l);
+  Expect.equals(22, c2.foo());
+}
diff --git a/tests/language/mixin_super_constructor_default_test.dart b/tests/language/mixin_super_constructor_default_test.dart
new file mode 100644
index 0000000..08a11ad
--- /dev/null
+++ b/tests/language/mixin_super_constructor_default_test.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.
+
+import "package:expect/expect.dart";
+
+class Base {
+  int i, j;
+  Base(int i, this.j) : this.i = i + 7;
+}
+
+abstract class M {
+  get i;
+  get j;
+  int k = 42;
+  foo() => i + j;
+}
+
+class C extends Base with M {
+  int l = 131;
+  C() : super(1, 13);
+}
+
+main() {
+  C c = new C();
+  Expect.equals(8, c.i);
+  Expect.equals(13, c.j);
+  Expect.equals(21, c.foo());
+  Expect.equals(42, c.k);
+  Expect.equals(131, c.l);
+}
diff --git a/tests/language/mixin_super_constructor_multiple_test.dart b/tests/language/mixin_super_constructor_multiple_test.dart
new file mode 100644
index 0000000..9e40a24
--- /dev/null
+++ b/tests/language/mixin_super_constructor_multiple_test.dart
@@ -0,0 +1,22 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+class S {
+  int i;
+  S.foo() : i = 1742;
+}
+
+class M1 { }
+
+class M2 { }
+
+class C extends S with M1, M2 {
+  C.foo() : super.foo();
+}
+
+main() {
+  Expect.equals(1742, new C.foo().i);
+}
diff --git a/tests/language/mixin_super_constructor_named_test.dart b/tests/language/mixin_super_constructor_named_test.dart
new file mode 100644
index 0000000..71afb2a
--- /dev/null
+++ b/tests/language/mixin_super_constructor_named_test.dart
@@ -0,0 +1,38 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+class Base {
+  int i, j;
+  Base.ctor(int this.i, {int this.j: 10});
+}
+
+abstract class M {
+  get i;
+  get j;
+  int k = 42;
+  foo() => i + j;
+}
+
+class C extends Base with M {
+  int l = 131;
+  C.foo() : super.ctor(1, j: 13);
+  C.bar() : super.ctor(1);
+}
+
+main() {
+  C c1 = new C.foo();
+  Expect.equals(1, c1.i);
+  Expect.equals(13, c1.j);
+  Expect.equals(14, c1.foo());
+  Expect.equals(42, c1.k);
+  Expect.equals(131, c1.l);
+  C c2 = new C.bar();
+  Expect.equals(1, c2.i);
+  Expect.equals(10, c2.j);
+  Expect.equals(11, c2.foo());
+  Expect.equals(42, c2.k);
+  Expect.equals(131, c2.l);
+}
diff --git a/tests/language/mixin_super_constructor_positionals_test.dart b/tests/language/mixin_super_constructor_positionals_test.dart
new file mode 100644
index 0000000..215ae20
--- /dev/null
+++ b/tests/language/mixin_super_constructor_positionals_test.dart
@@ -0,0 +1,38 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+class Base {
+  int i, j;
+  Base.ctor(int this.i, [int this.j = 10]);
+}
+
+abstract class M {
+  get i;
+  get j;
+  int k = 42;
+  foo() => i + j;
+}
+
+class C extends Base with M {
+  int l = 131;
+  C.foo() : super.ctor(1, 13);
+  C.bar() : super.ctor(1);
+}
+
+main() {
+  C c1 = new C.foo();
+  Expect.equals(1, c1.i);
+  Expect.equals(13, c1.j);
+  Expect.equals(14, c1.foo());
+  Expect.equals(42, c1.k);
+  Expect.equals(131, c1.l);
+  C c2 = new C.bar();
+  Expect.equals(1, c2.i);
+  Expect.equals(10, c2.j);
+  Expect.equals(11, c2.foo());
+  Expect.equals(42, c2.k);
+  Expect.equals(131, c2.l);
+}
diff --git a/tests/language/mixin_super_constructor_test.dart b/tests/language/mixin_super_constructor_test.dart
new file mode 100644
index 0000000..f60ff5b
--- /dev/null
+++ b/tests/language/mixin_super_constructor_test.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.
+
+import "package:expect/expect.dart";
+
+class Base {
+  int i, j;
+  Base.ctor(int i, this.j) : this.i = i + 7;
+}
+
+abstract class M {
+  get i;
+  get j;
+  int k = 42;
+  foo() => i + j;
+}
+
+class C extends Base with M {
+  int l = 131;
+  C() : super.ctor(1, 13);
+}
+
+main() {
+  C c = new C();
+  Expect.equals(8, c.i);
+  Expect.equals(13, c.j);
+  Expect.equals(42, c.k);
+  Expect.equals(131, c.l);
+  Expect.equals(21, c.foo());
+}
diff --git a/tests/lib/analyzer/analyze_tests.status b/tests/lib/analyzer/analyze_tests.status
index e963348..d949e2b 100644
--- a/tests/lib/analyzer/analyze_tests.status
+++ b/tests/lib/analyzer/analyze_tests.status
@@ -33,6 +33,5 @@
 standalone/io/http_date_test: Fail
 standalone/io/http_headers_test: Fail
 standalone/io/http_parser_test: Fail
-standalone/io/mime_multipart_parser_test: Fail
 standalone/io/web_socket_protocol_processor_test: Fail
 standalone/io/url_encoding_test: Fail
diff --git a/tests/standalone/io/file_invalid_arguments_test.dart b/tests/standalone/io/file_invalid_arguments_test.dart
index 5f7f73f..273a8c7 100644
--- a/tests/standalone/io/file_invalid_arguments_test.dart
+++ b/tests/standalone/io/file_invalid_arguments_test.dart
@@ -2,6 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+import "dart:async";
 import "package:expect/expect.dart";
 import "dart:io";
 import "dart:isolate";
@@ -130,6 +131,41 @@
   });
 }
 
+Future futureThrows(Future result) {
+  return result.then((value) {
+    throw new ExpectException(
+        "futureThrows received $value instead of an exception");
+    },
+    onError: (_) => null
+  );
+}
+
+void testFileSystemEntity() {
+  Expect.throws(() => ((x) => FileSystemEntity.typeSync(x))([1,2,3]));
+  Expect.throws(() => ((x, y) =>
+      FileSystemEntity.typeSync(x, followLinks: y))(".", "why not?"));
+  Expect.throws(() => ((x, y) =>
+      FileSystemEntity.identicalSync(x, y))([1,2,3], "."));
+  Expect.throws(() => ((x, y) =>
+                       FileSystemEntity.identicalSync(x, y))(".", 52));
+  Expect.throws(() => ((x) => FileSystemEntity.isLinkSync(x))(52));
+  Expect.throws(() => ((x) => FileSystemEntity.isFileSync(x))(52));
+  Expect.throws(() => ((x) => FileSystemEntity.isDirectorySync(x))(52));
+
+  ReceivePort keepAlive = new ReceivePort();
+  futureThrows(((x) => FileSystemEntity.type(x))([1,2,3]))
+  .then((_) => futureThrows(((x, y) =>
+       FileSystemEntity.type(x, followLinks: y))(".", "why not?")))
+  .then((_) => futureThrows(((x, y) =>
+       FileSystemEntity.identical(x, y))([1,2,3], ".")))
+  .then((_) => futureThrows(((x, y) =>
+       FileSystemEntity.identical(x, y))(".", 52)))
+  .then((_) => futureThrows(((x) => FileSystemEntity.isLink(x))(52)))
+  .then((_) => futureThrows(((x) => FileSystemEntity.isFile(x))(52)))
+  .then((_) => futureThrows(((x) => FileSystemEntity.isDirectory(x))(52)))
+  .then((_) => keepAlive.close());
+}
+
 String getFilename(String path) {
   return new File(path).existsSync() ? path : 'runtime/$path';
 }
@@ -144,4 +180,5 @@
   testWriteFromInvalidArgs(new List(10), '0', 1);
   testWriteFromInvalidArgs(new List(10), 0, '1');
   testWriteStringInvalidArgs("Hello, world", 42);
+  testFileSystemEntity();
 }
diff --git a/tests/standalone/io/file_read_special_device_test.dart b/tests/standalone/io/file_read_special_device_test.dart
index 1ea10e9..c32db08 100644
--- a/tests/standalone/io/file_read_special_device_test.dart
+++ b/tests/standalone/io/file_read_special_device_test.dart
@@ -24,5 +24,8 @@
 }
 
 void main() {
-  testReadStdio();
+  // Special unix devices do not exist on Windows.
+  if (Platform.operatingSystem != 'windows') {
+    testReadStdio();
+  }
 }
diff --git a/tests/standalone/io/file_system_async_links_test.dart b/tests/standalone/io/file_system_async_links_test.dart
new file mode 100644
index 0000000..25f07a9
--- /dev/null
+++ b/tests/standalone/io/file_system_async_links_test.dart
@@ -0,0 +1,237 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "dart:async";
+import "package:expect/expect.dart";
+import "dart:io";
+import "dart:isolate";
+
+
+class FutureExpect {
+  static Future isTrue(Future<bool> result) =>
+      result.then((value) => Expect.isTrue(value));
+  static Future isFalse(Future<bool> result) =>
+      result.then((value) => Expect.isFalse(value));
+  static Future equals(expected, Future result) =>
+      result.then((value) => Expect.equals(expected, value));
+  static Future listEquals(expected, Future result) =>
+      result.then((value) => Expect.listEquals(expected, value));
+  static Future throws(Future result) =>
+      result.then((value) {
+        throw new ExpectException(
+            "FutureExpect.throws received $value instead of an exception");
+        }, onError: (_) => null);
+}
+
+
+Future testFileExistsCreate() {
+  return new Directory('').createTemp().then((temp) {
+    var x = '${temp.path}${Platform.pathSeparator}x';
+    var y = '${temp.path}${Platform.pathSeparator}y';
+    return new Link(y).create(x)
+    .then((link) => Expect.equals(y, link.path))
+    .then((_) => FutureExpect.isFalse(new File(y).exists()))
+    .then((_) => FutureExpect.isFalse(new File(x).exists()))
+    .then((_) => FutureExpect.isTrue(FileSystemEntity.isLink(y)))
+    .then((_) => FutureExpect.isFalse(FileSystemEntity.isLink(x)))
+    .then((_) => FutureExpect.equals(FileSystemEntityType.NOT_FOUND,
+                                     FileSystemEntity.type(y)))
+    .then((_) => FutureExpect.equals(FileSystemEntityType.NOT_FOUND,
+                                     FileSystemEntity.type(x)))
+    .then((_) => FutureExpect.equals(FileSystemEntityType.LINK,
+                                     FileSystemEntity.type(y,
+                                                           followLinks: false)))
+    .then((_) => FutureExpect.equals(FileSystemEntityType.NOT_FOUND,
+                                     FileSystemEntity.type(x,
+                                                           followLinks: false)))
+    .then((_) => FutureExpect.equals(x, new Link(y).target()))
+    .then((_) => new File(y).create())
+    .then((yFile) => Expect.equals(y, yFile.path))
+    .then((_) => FutureExpect.isTrue(new File(y).exists()))
+    .then((_) => FutureExpect.isTrue(new File(x).exists()))
+    .then((_) => FutureExpect.isTrue(FileSystemEntity.isLink(y)))
+    .then((_) => FutureExpect.isFalse(FileSystemEntity.isLink(x)))
+    .then((_) => FutureExpect.isTrue(FileSystemEntity.isFile(y)))
+    .then((_) => FutureExpect.isTrue(FileSystemEntity.isFile(x)))
+    .then((_) => FutureExpect.equals(FileSystemEntityType.FILE,
+                                     FileSystemEntity.type(y)))
+    .then((_) => FutureExpect.equals(FileSystemEntityType.FILE,
+                                     FileSystemEntity.type(x)))
+    .then((_) => FutureExpect.equals(FileSystemEntityType.LINK,
+                                     FileSystemEntity.type(y,
+                                                           followLinks: false)))
+    .then((_) => FutureExpect.equals(FileSystemEntityType.FILE,
+                                     FileSystemEntity.type(x,
+                                                           followLinks: false)))
+    .then((_) => FutureExpect.equals(x, new Link(y).target()))
+    .then((_) => new File(x).delete())
+    .then((xDeletedFile) => Expect.equals(x, xDeletedFile.path))
+    .then((_) => new Directory(x).create())
+    .then((xCreatedDirectory) => Expect.equals(x, xCreatedDirectory.path))
+    .then((_) => FutureExpect.isTrue(FileSystemEntity.isLink(y)))
+    .then((_) => FutureExpect.isFalse(FileSystemEntity.isLink(x)))
+    .then((_) => FutureExpect.isTrue(FileSystemEntity.isDirectory(y)))
+    .then((_) => FutureExpect.isTrue(FileSystemEntity.isDirectory(x)))
+    .then((_) => FutureExpect.equals(FileSystemEntityType.DIRECTORY,
+                                     FileSystemEntity.type(y)))
+    .then((_) => FutureExpect.equals(FileSystemEntityType.DIRECTORY,
+                                     FileSystemEntity.type(x)))
+    .then((_) => FutureExpect.equals(FileSystemEntityType.LINK,
+                                     FileSystemEntity.type(y,
+                                                           followLinks: false)))
+    .then((_) => FutureExpect.equals(FileSystemEntityType.DIRECTORY,
+                                     FileSystemEntity.type(x,
+                                                           followLinks: false)))
+    .then((_) => FutureExpect.equals(x, new Link(y).target()))
+    .then((_) => new Link(y).delete())
+    .then((_) => FutureExpect.isFalse(FileSystemEntity.isLink(y)))
+    .then((_) => FutureExpect.isFalse(FileSystemEntity.isLink(x)))
+    .then((_) => FutureExpect.equals(FileSystemEntityType.NOT_FOUND,
+                                     FileSystemEntity.type(y)))
+    .then((_) => FutureExpect.equals(FileSystemEntityType.DIRECTORY,
+                                     FileSystemEntity.type(x)))
+    .then((_) => FutureExpect.throws(new Link(y).target()))
+    .then((_) => temp.delete(recursive: true));
+  });
+}
+
+
+Future testFileDelete() {
+  return new Directory('').createTemp().then((temp) {
+    var x = '${temp.path}${Platform.pathSeparator}x';
+    var y = '${temp.path}${Platform.pathSeparator}y';
+    return new File(x).create()
+    .then((_) => new Link(y).create(x))
+    .then((_) => FutureExpect.isTrue(new File(x).exists()))
+    .then((_) => FutureExpect.isTrue(new File(y).exists()))
+    .then((_) => new File(y).delete())
+    .then((_) => FutureExpect.isTrue(new File(x).exists()))
+    .then((_) => FutureExpect.isFalse(new File(y).exists()))
+    .then((_) => new Link(y).create(x))
+    .then((_) => FutureExpect.isTrue(new File(x).exists()))
+    .then((_) => FutureExpect.isTrue(new File(y).exists()))
+    .then((_) => new File(y).delete())
+    .then((_) => FutureExpect.isTrue(new File(x).exists()))
+    .then((_) => FutureExpect.isFalse(new File(y).exists()))
+    .then((_) => temp.delete(recursive: true));
+  });
+}
+
+
+Future testFileWriteRead() {
+  return new Directory('').createTemp().then((temp) {
+    var x = '${temp.path}${Platform.pathSeparator}x';
+    var y = '${temp.path}${Platform.pathSeparator}y';
+    var data = "asdf".codeUnits;
+    return new File(x).create()
+    .then((_) => new Link(y).create(x))
+    .then((_) =>
+          (new File(y).openWrite(mode: FileMode.WRITE)..add(data)).close())
+    .then((_) => FutureExpect.listEquals(data, new File(y).readAsBytes()))
+    .then((_) => FutureExpect.listEquals(data, new File(x).readAsBytes()))
+    .then((_) => temp.delete(recursive: true));
+  });
+}
+
+
+Future testDirectoryExistsCreate() {
+  return new Directory('').createTemp().then((temp) {
+    var x = '${temp.path}${Platform.pathSeparator}x';
+    var y = '${temp.path}${Platform.pathSeparator}y';
+    return new Link(y).create(x)
+    .then((_) => FutureExpect.isFalse(new Directory(x).exists()))
+    .then((_) => FutureExpect.isFalse(new Directory(y).exists()))
+    .then((_) => FutureExpect.throws(new Directory(y).create()))
+    .then((_) => temp.delete(recursive: true));
+  });
+}
+
+
+Future testDirectoryDelete() {
+  return new Directory('').createTemp().then((temp) =>
+  new Directory('').createTemp().then((temp2) {
+    var y = '${temp.path}${Platform.pathSeparator}y';
+    var x = '${temp2.path}${Platform.pathSeparator}x';
+    var link = new Directory(y);
+    return new File(x).create()
+    .then((_) => new Link(y).create(temp2.path))
+    .then((_) => FutureExpect.isTrue(link.exists()))
+    .then((_) => FutureExpect.isTrue(temp2.exists()))
+    .then((_) => link.delete())
+    .then((_) => FutureExpect.isFalse(link.exists()))
+    .then((_) => FutureExpect.isTrue(temp2.exists()))
+    .then((_) => new Link(y).create(temp2.path))
+    .then((_) => FutureExpect.isTrue(link.exists()))
+    .then((_) => temp.delete(recursive: true))
+    .then((_) => FutureExpect.isFalse(link.exists()))
+    .then((_) => FutureExpect.isFalse(temp.exists()))
+    .then((_) => FutureExpect.isTrue(temp2.exists()))
+    .then((_) => FutureExpect.isTrue(new File(x).exists()))
+    .then((_) => temp2.delete(recursive: true));
+  }));
+}
+
+
+Future testDirectoryListing() {
+  return new Directory('').createTemp().then((temp) =>
+  new Directory('').createTemp().then((temp2) {
+    var sep = Platform.pathSeparator;
+    var y = '${temp.path}${sep}y';
+    var x = '${temp2.path}${sep}x';
+    return new File(x).create()
+    .then((_) => new Link(y).create(temp2.path))
+    .then((_) => temp.list(recursive: true).singleWhere(
+        (entry) => entry is File))
+    .then((file) => Expect.isTrue(file.path.endsWith('$y${sep}x')))
+    .then((_) => temp.list(recursive: true).singleWhere(
+        (entry) => entry is Directory))
+    .then((dir) => Expect.isTrue(dir.path.endsWith('y')))
+    .then((_) => temp.delete(recursive: true))
+    .then((_) => temp2.delete(recursive: true));
+  }));
+}
+
+
+Future testDirectoryListingBrokenLink() {
+  return new Directory('').createTemp().then((temp) {
+    var x = '${temp.path}${Platform.pathSeparator}x';
+    var link = '${temp.path}${Platform.pathSeparator}link';
+    var doesNotExist = 'this_thing_does_not_exist';
+    bool sawFile = false;
+    bool sawLink = false;
+    return new File(x).create()
+    .then((_) => new Link(link).create(doesNotExist))
+    .then((_) => temp.list(recursive: true).forEach(
+      (entity) {
+        if (entity is File) {
+          Expect.isFalse(sawFile);
+          sawFile = true;
+          Expect.isTrue(entity.path.endsWith(x));
+        } else {
+          Expect.isTrue(entity is Link);
+          Expect.isFalse(sawLink);
+          sawLink = true;
+          Expect.isTrue(entity.path.endsWith(link));
+        }
+        return true;
+      }))
+    .then((_) => temp.delete(recursive: true));
+  });
+}
+
+
+main() {
+  // Links on Windows are tested by windows_file_system_[async_]links_test.
+  if (Platform.operatingSystem != 'windows') {
+    ReceivePort keepAlive = new ReceivePort();
+    testFileExistsCreate()
+    .then((_) => testFileDelete())
+    .then((_) => testFileWriteRead())
+    .then((_) => testDirectoryExistsCreate())
+    .then((_) => testDirectoryDelete())
+    .then((_) => testDirectoryListing())
+    .then((_) => testDirectoryListingBrokenLink())
+    .then((_) => keepAlive.close());
+  }
+}
diff --git a/tests/standalone/io/file_system_links_test.dart b/tests/standalone/io/file_system_links_test.dart
index 2230c07..afe8996 100644
--- a/tests/standalone/io/file_system_links_test.dart
+++ b/tests/standalone/io/file_system_links_test.dart
@@ -239,11 +239,14 @@
 
 
 main() {
-  testFileExistsCreate();
-  testFileDelete();
-  testFileWriteRead();
-  testDirectoryExistsCreate();
-  testDirectoryDelete();
-  testDirectoryListing();
-  testDirectoryListingBrokenLink();
+  // Links on Windows are tested by windows_file_system_[async_]links_test.
+  if (Platform.operatingSystem != 'windows') {
+    testFileExistsCreate();
+    testFileDelete();
+    testFileWriteRead();
+    testDirectoryExistsCreate();
+    testDirectoryDelete();
+    testDirectoryListing();
+    testDirectoryListingBrokenLink();
+  }
 }
diff --git a/tests/standalone/io/http_auth_digest_test.dart b/tests/standalone/io/http_auth_digest_test.dart
new file mode 100644
index 0000000..70e1451
--- /dev/null
+++ b/tests/standalone/io/http_auth_digest_test.dart
@@ -0,0 +1,393 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+import 'dart:async';
+import 'dart:crypto';
+import 'dart:io';
+import 'dart:isolate';
+import 'dart:uri';
+import 'dart:utf';
+
+class Server {
+  HttpServer server;
+  int unauthCount = 0;  // Counter of the 401 responses.
+  int successCount = 0;  // Counter of the successful responses.
+  int nonceCount = 0;  // Counter of use of current nonce.
+  var ha1;
+
+  static Future<Server> start(String algorithm,
+                              String qop,
+                              {int nonceStaleAfter,
+                               bool useNextNonce: false}) {
+    return new Server()._start(algorithm, qop, nonceStaleAfter, useNextNonce);
+  }
+
+  Future<Server> _start(String serverAlgorithm,
+                        String serverQop,
+                        int nonceStaleAfter,
+                        bool useNextNonce) {
+    Set ncs = new Set();
+    // Calculate ha1.
+    String realm = "test";
+    String username = "dart";
+    String password = "password";
+    var hasher = new MD5();
+    hasher.add("${username}:${realm}:${password}".codeUnits);
+    ha1 = CryptoUtils.bytesToHex(hasher.close());
+
+    var nonce = "12345678";  // No need for random nonce in test.
+
+    var completer = new Completer();
+    HttpServer.bind("127.0.0.1", 0).then((s) {
+      server = s;
+      server.listen((HttpRequest request) {
+        sendUnauthorizedResponse(HttpResponse response, {stale: false}) {
+          response.statusCode = HttpStatus.UNAUTHORIZED;
+          StringBuffer authHeader = new StringBuffer();
+          authHeader.write('Digest');
+          authHeader.write(', realm="$realm"');
+          authHeader.write(', nonce="$nonce"');
+          if (stale) authHeader.write(', stale="true"');
+          if (serverAlgorithm != null) {
+            authHeader.write(', algorithm=$serverAlgorithm');
+          }
+          authHeader.write(', domain="/digest/"');
+          if (serverQop != null) authHeader.write(', qop="$serverQop"');
+          response.headers.set(HttpHeaders.WWW_AUTHENTICATE, authHeader);
+          unauthCount++;
+        }
+
+        var response = request.response;
+        if (request.headers[HttpHeaders.AUTHORIZATION] != null) {
+          Expect.equals(1, request.headers[HttpHeaders.AUTHORIZATION].length);
+          String authorization =
+            request.headers[HttpHeaders.AUTHORIZATION][0];
+          HeaderValue header =
+              HeaderValue.parse(
+                  authorization, parameterSeparator: ",");
+          if (header.value == "basic") {
+            sendUnauthorizedResponse(response);
+          } else if (!useNextNonce && nonceCount == nonceStaleAfter) {
+            nonce = "87654321";
+            nonceCount = 0;
+            sendUnauthorizedResponse(response, stale: true);
+          } else {
+            var uri = header.parameters["uri"];
+            var qop = header.parameters["qop"];
+            var cnonce = header.parameters["cnonce"];
+            var nc = header.parameters["nc"];
+            Expect.equals("digest", header.value);
+            Expect.equals("dart", header.parameters["username"]);
+            Expect.equals(realm, header.parameters["realm"]);
+            Expect.equals("MD5", header.parameters["algorithm"]);
+            Expect.equals(nonce, header.parameters["nonce"]);
+            Expect.equals(request.uri.path, uri);
+            if (qop != null) {
+              // A server qop of auth-int is downgraded to none by the client.
+              Expect.equals("auth", serverQop);
+              Expect.equals("auth", header.parameters["qop"]);
+              Expect.isNotNull(cnonce);
+              Expect.isNotNull(nc);
+              Expect.isFalse(ncs.contains(nc));
+              ncs.add(nc);
+            } else {
+              Expect.isNull(cnonce);
+              Expect.isNull(nc);
+            }
+            Expect.isNotNull(header.parameters["response"]);
+
+            var hasher = new MD5();
+            hasher.add("${request.method}:${uri}".codeUnits);
+            var ha2 = CryptoUtils.bytesToHex(hasher.close());
+
+            var x;
+            hasher = new MD5();
+            if (qop == null || qop == "" || qop == "none") {
+              hasher.add("$ha1:${nonce}:$ha2".codeUnits);
+            } else {
+              hasher.add("$ha1:${nonce}:${nc}:${cnonce}:${qop}:$ha2".codeUnits);
+            }
+            Expect.equals(CryptoUtils.bytesToHex(hasher.close()),
+                          header.parameters["response"]);
+
+            successCount++;
+            nonceCount++;
+
+            // Add a bogus Authentication-Info for testing.
+            var info = 'rspauth="77180d1ab3d6c9de084766977790f482", '
+                       'cnonce="8f971178", '
+                       'nc=000002c74, '
+                       'qop=auth';
+            if (useNextNonce && nonceCount == nonceStaleAfter) {
+              nonce = "abcdef01";
+              info += ', nextnonce="$nonce"';
+            }
+            response.headers.set("Authentication-Info", info);
+          }
+        } else {
+          sendUnauthorizedResponse(response);
+        }
+        response.close();
+      });
+      completer.complete(this);
+    });
+    return completer.future;
+  }
+
+  void shutdown() {
+    server.close();
+  }
+
+  int get port => server.port;
+}
+
+void testNoCredentials(String algorithm, String qop) {
+  Server.start(algorithm, qop).then((server) {
+    HttpClient client = new HttpClient();
+
+    // Add digest credentials which does not match the path requested.
+    client.addCredentials(
+        Uri.parse("http://127.0.0.1:${server.port}/xxx"),
+        "test",
+        new HttpClientDigestCredentials("dart", "password"));
+
+    // Add basic credentials for the path requested.
+    client.addCredentials(
+        Uri.parse("http://127.0.0.1:${server.port}/digest"),
+        "test",
+        new HttpClientBasicCredentials("dart", "password"));
+
+    Future makeRequest(Uri url) {
+      return client.getUrl(url)
+        .then((HttpClientRequest request) => request.close())
+        .then((HttpClientResponse response) {
+          Expect.equals(HttpStatus.UNAUTHORIZED, response.statusCode);
+          return response.fold(null, (x, y) {});
+        });
+    }
+
+    var futures = [];
+    for (int i = 0; i < 5; i++) {
+      futures.add(
+          makeRequest(
+              Uri.parse("http://127.0.0.1:${server.port}/digest")));
+    }
+    Future.wait(futures).then((_) {
+      server.shutdown();
+      client.close();
+    });
+  });
+}
+
+void testCredentials(String algorithm, String qop) {
+  Server.start(algorithm, qop).then((server) {
+    HttpClient client = new HttpClient();
+
+    Future makeRequest(Uri url) {
+      return client.getUrl(url)
+        .then((HttpClientRequest request) => request.close())
+        .then((HttpClientResponse response) {
+            Expect.equals(HttpStatus.OK, response.statusCode);
+            Expect.equals(1, response.headers["Authentication-Info"].length);
+          return response.fold(null, (x, y) {});
+        });
+    }
+
+    client.addCredentials(
+        Uri.parse("http://127.0.0.1:${server.port}/digest"),
+        "test",
+        new HttpClientDigestCredentials("dart", "password"));
+
+    var futures = [];
+    for (int i = 0; i < 5; i++) {
+      futures.add(
+          makeRequest(
+              Uri.parse("http://127.0.0.1:${server.port}/digest")));
+    }
+    Future.wait(futures).then((_) {
+      server.shutdown();
+      client.close();
+    });
+  });
+}
+
+void testAuthenticateCallback(String algorithm, String qop) {
+  Server.start(algorithm, qop).then((server) {
+    HttpClient client = new HttpClient();
+
+    client.authenticate = (Uri url, String scheme, String realm) {
+      Expect.equals("Digest", scheme);
+      Expect.equals("test", realm);
+      Completer completer = new Completer();
+      new Timer(const Duration(milliseconds: 10), () {
+          client.addCredentials(
+              Uri.parse("http://127.0.0.1:${server.port}/digest"),
+              "test",
+              new HttpClientDigestCredentials("dart", "password"));
+        completer.complete(true);
+      });
+      return completer.future;
+    };
+
+    Future makeRequest(Uri url) {
+      return client.getUrl(url)
+        .then((HttpClientRequest request) => request.close())
+        .then((HttpClientResponse response) {
+            Expect.equals(HttpStatus.OK, response.statusCode);
+            Expect.equals(1, response.headers["Authentication-Info"].length);
+          return response.fold(null, (x, y) {});
+        });
+    }
+
+    var futures = [];
+    for (int i = 0; i < 5; i++) {
+      futures.add(
+          makeRequest(
+              Uri.parse("http://127.0.0.1:${server.port}/digest")));
+    }
+    Future.wait(futures).then((_) {
+      server.shutdown();
+      client.close();
+    });
+  });
+}
+
+void testStaleNonce() {
+  Server.start("MD5", "auth", nonceStaleAfter: 2).then((server) {
+    HttpClient client = new HttpClient();
+
+    Future makeRequest(Uri url) {
+      return client.getUrl(url)
+        .then((HttpClientRequest request) => request.close())
+        .then((HttpClientResponse response) {
+            Expect.equals(HttpStatus.OK, response.statusCode);
+            Expect.equals(1, response.headers["Authentication-Info"].length);
+          return response.fold(null, (x, y) {});
+        });
+    }
+
+    Uri uri = Uri.parse("http://127.0.0.1:${server.port}/digest");
+    var credentials = new HttpClientDigestCredentials("dart", "password");
+    client.addCredentials(uri, "test", credentials);
+
+    makeRequest(uri)
+        .then((_) => makeRequest(uri))
+        .then((_) => makeRequest(uri))
+        .then((_) => makeRequest(uri))
+        .then((_) {
+          Expect.equals(2, server.unauthCount);
+          Expect.equals(4, server.successCount);
+          server.shutdown();
+          client.close();
+        });
+  });
+}
+
+void testNextNonce() {
+  Server.start("MD5",
+               "auth",
+               nonceStaleAfter: 2,
+               useNextNonce: true).then((server) {
+    HttpClient client = new HttpClient();
+
+    Future makeRequest(Uri url) {
+      return client.getUrl(url)
+        .then((HttpClientRequest request) => request.close())
+        .then((HttpClientResponse response) {
+            Expect.equals(HttpStatus.OK, response.statusCode);
+            Expect.equals(1, response.headers["Authentication-Info"].length);
+          return response.fold(null, (x, y) {});
+        });
+    }
+
+    Uri uri = Uri.parse("http://127.0.0.1:${server.port}/digest");
+    var credentials = new HttpClientDigestCredentials("dart", "password");
+    client.addCredentials(uri, "test", credentials);
+
+    makeRequest(uri)
+        .then((_) => makeRequest(uri))
+        .then((_) => makeRequest(uri))
+        .then((_) => makeRequest(uri))
+        .then((_) {
+          Expect.equals(1, server.unauthCount);
+          Expect.equals(4, server.successCount);
+          server.shutdown();
+          client.close();
+        });
+  });
+}
+
+// An Apache virtual directory configuration like this can be used for
+// running the local server tests.
+//
+//  <Directory "/usr/local/prj/website/digest/">
+//    AllowOverride None
+//    Order deny,allow
+//    Deny from all
+//    Allow from 127.0.0.0/255.0.0.0 ::1/128
+//    AuthType Digest
+//    AuthName "test"
+//    AuthDigestDomain /digest/
+//    AuthDigestAlgorithm MD5
+//    AuthDigestQop auth
+//    AuthDigestNonceLifetime 10
+//    AuthDigestProvider file
+//    AuthUserFile /usr/local/prj/apache/passwd/digest-passwd
+//    Require valid-user
+//  </Directory>
+//
+
+void testLocalServerDigest() {
+  int count = 0;
+  HttpClient client = new HttpClient();
+
+  Future makeRequest() {
+    return client.getUrl(Uri.parse("http://127.0.0.1/digest/test"))
+        .then((HttpClientRequest request) => request.close())
+        .then((HttpClientResponse response) {
+            count++;
+            if (count % 100 == 0) print(count);
+            Expect.equals(HttpStatus.OK, response.statusCode);
+            return response.fold(null, (x, y) {});
+        });
+  }
+
+  client.addCredentials(
+        Uri.parse("http://127.0.0.1/digest"),
+        "test",
+        new HttpClientDigestCredentials("dart", "password"));
+
+  client.authenticate = (Uri url, String scheme, String realm) {
+    client.addCredentials(
+        Uri.parse("http://127.0.0.1/digest"),
+        "test",
+        new HttpClientDigestCredentials("dart", "password"));
+    return new Future.value(true);
+  };
+
+  next() {
+    makeRequest().then((_) => next());
+  }
+  next();
+}
+
+main() {
+  testNoCredentials(null, null);
+  testNoCredentials("MD5", null);
+  testNoCredentials("MD5", "auth");
+  testCredentials(null, null);
+  testCredentials("MD5", null);
+  testCredentials("MD5", "auth");
+  testCredentials("MD5", "auth-int");
+  testAuthenticateCallback(null, null);
+  testAuthenticateCallback("MD5", null);
+  testAuthenticateCallback("MD5", "auth");
+  testAuthenticateCallback("MD5", "auth-int");
+  testStaleNonce();
+  testNextNonce();
+  // These teste are not normally run. They can be used for locally
+  // testing with another web server (e.g. Apache).
+  //testLocalServerDigest();
+}
diff --git a/tests/standalone/io/http_body_test.dart b/tests/standalone/io/http_body_test.dart
index b036da2..cd1c4b5 100644
--- a/tests/standalone/io/http_body_test.dart
+++ b/tests/standalone/io/http_body_test.dart
@@ -19,7 +19,7 @@
             (_) {},
             onDone: () {
               request.response.headers.contentType =
-                  new ContentType.fromString(mimeType);
+                  ContentType.parse(mimeType);
               request.response.add(content);
               request.response.close();
             });
@@ -125,7 +125,7 @@
           .then((request) {
             if (mimeType != null) {
               request.headers.contentType =
-                  new ContentType.fromString(mimeType);
+                  ContentType.parse(mimeType);
             }
             request.add(content);
             return request.close();
diff --git a/tests/standalone/io/http_headers_test.dart b/tests/standalone/io/http_headers_test.dart
index 111379c..88faa65 100644
--- a/tests/standalone/io/http_headers_test.dart
+++ b/tests/standalone/io/http_headers_test.dart
@@ -203,14 +203,14 @@
   }
 
   HeaderValue headerValue;
-  headerValue = new HeaderValue.fromString(
+  headerValue = HeaderValue.parse(
       "xxx; aaa=bbb; ccc=\"\\\";\\a\"; ddd=\"    \"");
   check(headerValue, "xxx", {"aaa": "bbb", "ccc": '\";a', "ddd": "    "});
   headerValue = new HeaderValue("xxx",
                                 {"aaa": "bbb", "ccc": '\";a', "ddd": "    "});
   check(headerValue, "xxx", {"aaa": "bbb", "ccc": '\";a', "ddd": "    "});
 
-  headerValue = new HeaderValue.fromString(
+  headerValue = HeaderValue.parse(
     "attachment; filename=genome.jpeg;"
     "modification-date=\"Wed, 12 February 1997 16:29:51 -0500\"");
   var parameters = {
@@ -220,7 +220,7 @@
   check(headerValue, "attachment", parameters);
   headerValue = new HeaderValue("attachment", parameters);
   check(headerValue, "attachment", parameters);
-  headerValue = new HeaderValue.fromString(
+  headerValue = HeaderValue.parse(
     "  attachment  ;filename=genome.jpeg  ;"
     "modification-date = \"Wed, 12 February 1997 16:29:51 -0500\""  );
   check(headerValue, "attachment", parameters);
@@ -250,7 +250,7 @@
   Expect.equals("", contentType.subType);
   Expect.equals("/", contentType.value);
 
-  contentType = new ContentType.fromString("text/html");
+  contentType = ContentType.parse("text/html");
   check(contentType, "text", "html");
   Expect.equals("text/html", contentType.toString());
   contentType = new ContentType("text", "html", charset: "utf-8");
@@ -276,25 +276,25 @@
                       s == "text/html; xxx=yyy; charset=iso-8859-1");
   Expect.isTrue(expectedToString);
 
-  contentType = new ContentType.fromString("text/html");
+  contentType = ContentType.parse("text/html");
   check(contentType, "text", "html");
-  contentType = new ContentType.fromString(" text/html  ");
+  contentType = ContentType.parse(" text/html  ");
   check(contentType, "text", "html");
-  contentType = new ContentType.fromString("text/html; charset=utf-8");
+  contentType = ContentType.parse("text/html; charset=utf-8");
   check(contentType, "text", "html", {"charset": "utf-8"});
-  contentType = new ContentType.fromString(
+  contentType = ContentType.parse(
       "  text/html  ;  charset  =  utf-8  ");
   check(contentType, "text", "html", {"charset": "utf-8"});
-  contentType = new ContentType.fromString(
+  contentType = ContentType.parse(
       "text/html; charset=utf-8; xxx=yyy");
   check(contentType, "text", "html", {"charset": "utf-8", "xxx": "yyy"});
-  contentType = new ContentType.fromString(
+  contentType = ContentType.parse(
       "  text/html  ;  charset  =  utf-8  ;  xxx=yyy  ");
   check(contentType, "text", "html", {"charset": "utf-8", "xxx": "yyy"});
-  contentType = new ContentType.fromString(
+  contentType = ContentType.parse(
       'text/html; charset=utf-8; xxx="yyy"');
   check(contentType, "text", "html", {"charset": "utf-8", "xxx": "yyy"});
-  contentType = new ContentType.fromString(
+  contentType = ContentType.parse(
       "  text/html  ;  charset  =  utf-8  ;  xxx=yyy  ");
   check(contentType, "text", "html", {"charset": "utf-8", "xxx": "yyy"});
 }
diff --git a/tests/standalone/io/http_redirect_test.dart b/tests/standalone/io/http_redirect_test.dart
index 363f8d0..b3caef5 100644
--- a/tests/standalone/io/http_redirect_test.dart
+++ b/tests/standalone/io/http_redirect_test.dart
@@ -57,6 +57,69 @@
        }
     );
 
+    // Setup redirects with relative url.
+    addRequestHandler(
+       "/redirectUrl",
+       (HttpRequest request, HttpResponse response) {
+         response.headers.set(HttpHeaders.LOCATION, "/some/relativeUrl");
+         response.statusCode = HttpStatus.MOVED_PERMANENTLY;
+         response.close();
+       }
+    );
+
+    addRequestHandler(
+       "/some/redirectUrl",
+       (HttpRequest request, HttpResponse response) {
+         response.headers.set(HttpHeaders.LOCATION, "relativeUrl");
+         response.statusCode = HttpStatus.MOVED_PERMANENTLY;
+         response.close();
+       }
+    );
+
+    addRequestHandler(
+       "/some/relativeUrl",
+       (HttpRequest request, HttpResponse response) {
+         response.close();
+       }
+    );
+
+    addRequestHandler(
+       "/redirectUrl2",
+       (HttpRequest request, HttpResponse response) {
+         response.headers.set(HttpHeaders.LOCATION, "location");
+         response.statusCode = HttpStatus.MOVED_PERMANENTLY;
+         response.close();
+       }
+    );
+
+    addRequestHandler(
+       "/redirectUrl3",
+       (HttpRequest request, HttpResponse response) {
+         response.headers.set(HttpHeaders.LOCATION, "./location");
+         response.statusCode = HttpStatus.MOVED_PERMANENTLY;
+         response.close();
+       }
+    );
+
+    addRequestHandler(
+       "/redirectUrl4",
+       (HttpRequest request, HttpResponse response) {
+         response.headers.set(HttpHeaders.LOCATION, "./a/b/../../location");
+         response.statusCode = HttpStatus.MOVED_PERMANENTLY;
+         response.close();
+       }
+    );
+
+    addRequestHandler(
+       "/redirectUrl5",
+       (HttpRequest request, HttpResponse response) {
+         response.headers.set(HttpHeaders.LOCATION,
+                              "//127.0.0.1:${server.port}/location");
+         response.statusCode = HttpStatus.MOVED_PERMANENTLY;
+         response.close();
+       }
+    );
+
     // Setup redirect chain.
     int n = 1;
     addRedirectHandler(n++, HttpStatus.MOVED_PERMANENTLY);
@@ -370,6 +433,34 @@
   });
 }
 
+void testRedirectRelativeUrl() {
+  testPath(String path) {
+    setupServer().then((server) {
+      HttpClient client = new HttpClient();
+
+      print(path);
+      client.getUrl(Uri.parse("http://127.0.0.1:${server.port}$path"))
+          .then((request) => request.close())
+          .then((response) {
+            response.listen(
+                (_) {},
+                onDone: () {
+                  Expect.equals(HttpStatus.OK, response.statusCode);
+                  Expect.equals(1, response.redirects.length);
+                  server.close();
+                  client.close();
+                });
+            });
+    });
+  }
+  testPath("/redirectUrl");
+  testPath("/some/redirectUrl");
+  testPath("/redirectUrl2");
+  testPath("/redirectUrl3");
+  testPath("/redirectUrl4");
+  testPath("/redirectUrl5");
+}
+
 main() {
   testManualRedirect();
   testManualRedirectWithHeaders();
@@ -380,4 +471,5 @@
   testAutoRedirectLimit();
   testRedirectLoop();
   testRedirectClosingConnection();
+  testRedirectRelativeUrl();
 }
diff --git a/tests/standalone/io/link_async_test.dart b/tests/standalone/io/link_async_test.dart
new file mode 100644
index 0000000..0cc4a7a
--- /dev/null
+++ b/tests/standalone/io/link_async_test.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.
+
+import "package:expect/expect.dart";
+import "dart:async";
+import "dart:io";
+import "dart:isolate";
+
+// Test the dart:io Link class.
+
+class FutureExpect {
+  static Future isTrue(Future<bool> result) =>
+      result.then((value) => Expect.isTrue(value));
+  static Future isFalse(Future<bool> result) =>
+      result.then((value) => Expect.isFalse(value));
+  static Future equals(expected, Future result) =>
+      result.then((value) => Expect.equals(expected, value));
+  static Future listEquals(expected, Future result) =>
+      result.then((value) => Expect.listEquals(expected, value));
+  static Future throws(Future result) =>
+      result.then((value) {
+        throw new ExpectException(
+            "FutureExpect.throws received $value instead of an exception");
+        }, onError: (_) => null);
+}
+
+
+Future testCreate() {
+  return new Directory('').createTemp().then((temp) {
+    Path base = new Path(temp.path);
+    Directory baseDir = new Directory.fromPath(base);
+    String link = base.append('link').toNativePath();
+    String target = base.append('target').toNativePath();
+    return new Directory(target).create()
+    .then((_) => new Link(link).create(target))
+
+    .then((_) => FutureExpect.equals(FileSystemEntityType.DIRECTORY,
+                                     FileSystemEntity.type(link)))
+    .then((_) => FutureExpect.equals(FileSystemEntityType.DIRECTORY,
+                                     FileSystemEntity.type(target)))
+    .then((_) => FutureExpect.equals(FileSystemEntityType.LINK,
+                     FileSystemEntity.type(link, followLinks: false)))
+    .then((_) => FutureExpect.equals(FileSystemEntityType.DIRECTORY,
+                     FileSystemEntity.type(target, followLinks: false)))
+    .then((_) => FutureExpect.isTrue(FileSystemEntity.isLink(link)))
+    .then((_) => FutureExpect.isFalse(FileSystemEntity.isLink(target)))
+    .then((_) => FutureExpect.isTrue(new Directory(link).exists()))
+    .then((_) => FutureExpect.isTrue(new Directory(target).exists()))
+    .then((_) => FutureExpect.isTrue(new Link(link).exists()))
+    .then((_) => FutureExpect.isFalse(new Link(target).exists()))
+    .then((_) => FutureExpect.equals(target, new Link(link).target()))
+    .then((_) => FutureExpect.throws(new Link(target).target()))
+    .then((_) {
+      String createdThroughLink =
+          base.append('link/createdThroughLink').toNativePath();
+      String createdDirectly =
+          base.append('target/createdDirectly').toNativePath();
+      String createdFile =
+          base.append('target/createdFile').toNativePath();
+      return new Directory(createdThroughLink).create()
+      .then((_) => new Directory(createdDirectly).create())
+      .then((_) => new File(createdFile).create())
+      .then((_) => FutureExpect.isTrue(
+          new Directory(createdThroughLink).exists()))
+      .then((_) => FutureExpect.isTrue(
+          new Directory(createdDirectly).exists()))
+      .then((_) => FutureExpect.isTrue(
+          new Directory.fromPath(base.append('link/createdDirectly')).exists()))
+      .then((_) => FutureExpect.isTrue(new Directory.fromPath(
+          base.append('target/createdThroughLink')).exists()))
+      .then((_) => FutureExpect.equals(FileSystemEntityType.DIRECTORY,
+          FileSystemEntity.type(createdThroughLink, followLinks: false)))
+      .then((_) => FutureExpect.equals(FileSystemEntityType.DIRECTORY,
+          FileSystemEntity.type(createdDirectly, followLinks: false)))
+
+      // Test FileSystemEntity.identical on files, directories, and links,
+      // reached by different paths.
+      .then((_) => FutureExpect.isTrue(FileSystemEntity.identical(
+          createdDirectly,
+          createdDirectly)))
+      .then((_) => FutureExpect.isFalse(FileSystemEntity.identical(
+          createdDirectly,
+          createdThroughLink)))
+      .then((_) => FutureExpect.isTrue(FileSystemEntity.identical(
+          createdDirectly,
+          base.append('link/createdDirectly').toNativePath())))
+      .then((_) => FutureExpect.isTrue(FileSystemEntity.identical(
+          createdThroughLink,
+          base.append('target/createdThroughLink').toNativePath())))
+      .then((_) => FutureExpect.isFalse(FileSystemEntity.identical(
+          target,
+          link)))
+      .then((_) => FutureExpect.isTrue(FileSystemEntity.identical(
+          link,
+          link)))
+      .then((_) => FutureExpect.isTrue(FileSystemEntity.identical(
+          target,
+          target)))
+      .then((_) => new Link(link).target())
+      .then((linkTarget) => FutureExpect.isTrue(FileSystemEntity.identical(
+          target,
+          linkTarget)))
+      .then((_) => new File(".").fullPath())
+      .then((fullCurrentDir) => FutureExpect.isTrue(FileSystemEntity.identical(
+          ".",
+          fullCurrentDir)))
+      .then((_) => FutureExpect.isTrue(FileSystemEntity.identical(
+          createdFile,
+          createdFile)))
+      .then((_) => FutureExpect.isFalse(FileSystemEntity.identical(
+          createdFile,
+          createdDirectly)))
+      .then((_) => FutureExpect.isTrue(FileSystemEntity.identical(
+          createdFile,
+          base.append('link/createdFile').toNativePath())))
+      .then((_) => FutureExpect.throws(FileSystemEntity.identical(
+          createdFile,
+          base.append('link/foo').toNativePath())))
+
+      .then((_) => testDirectoryListing(base, baseDir))
+      .then((_) => new Directory(target).delete(recursive: true))
+      .then((_) {
+        List<Future> futures = [];
+        for (bool recursive in [true, false]) {
+          for (bool followLinks in [true, false]) {
+            var result = baseDir.listSync(recursive: recursive,
+                                          followLinks: followLinks);
+            Expect.equals(1, result.length);
+            Expect.isTrue(result[0] is Link);
+            futures.add(FutureExpect.isTrue(
+              baseDir.list(recursive: recursive,
+                           followLinks: followLinks)
+              .single.then((element) => element is Link)));
+          }
+        }
+        return Future.wait(futures);
+      })
+      .then((_) => baseDir.delete(recursive: true));
+    });
+  });
+}
+
+
+Future testCreateLoopingLink() {
+  return new Directory('').createTemp()
+  .then((dir) => new Path(dir.path))
+  .then((Path base) =>
+    new Directory.fromPath(base.append('a/b/c')).create(recursive: true)
+    .then((_) => new Link.fromPath(base.append('a/b/c/d'))
+        .create(base.append('a/b').toNativePath()))
+    .then((_) => new Link.fromPath(base.append('a/b/c/e'))
+        .create(base.append('a').toNativePath()))
+    .then((_) => new Directory.fromPath(base.append('a'))
+        .list(recursive: true, followLinks: false).last)
+    // This directory listing must terminate, even though it contains loops.
+    .then((_) => new Directory.fromPath(base.append('a'))
+        .list(recursive: true, followLinks: true).last)
+    // This directory listing must terminate, even though it contains loops.
+    .then((_) => new Directory.fromPath(base.append('a/b/c'))
+        .list(recursive: true, followLinks: true).last)
+    .then((_) => new Directory.fromPath(base).delete(recursive: true))
+  );
+}
+
+
+Future testDirectoryListing(Path base, Directory baseDir) {
+  Map makeExpected(bool recursive, bool followLinks) {
+    Map expected = new Map();
+    expected['target'] = 'Directory';
+    expected['link'] = followLinks ? 'Directory' : 'Link';
+    if (recursive) {
+      expected['target/createdDirectly'] = 'Directory';
+      expected['target/createdThroughLink'] = 'Directory';
+      expected['target/createdFile'] = 'File';
+      if (followLinks) {
+        expected['link/createdDirectly'] = 'Directory';
+        expected['link/createdThroughLink'] = 'Directory';
+        expected['link/createdFile'] = 'File';
+      }
+    }
+    return expected;
+  }
+
+  void checkEntity(FileSystemEntity x, Map expected) {
+    String ending = new Path(x.path).relativeTo(base).toString();
+    Expect.isNotNull(expected[ending]);
+    Expect.isTrue(x.toString().startsWith(expected[ending]));
+    expected[ending] = 'Found';
+  }
+
+  List futures = [];
+  for (bool recursive in [true, false]) {
+    for (bool followLinks in [true, false]) {
+      Map expected = makeExpected(recursive, followLinks);
+      for (var x in baseDir.listSync(recursive: recursive,
+                                     followLinks: followLinks)) {
+        checkEntity(x, expected);
+      }
+      for (var v in expected.values) {
+        Expect.equals('Found', v);
+      }
+      expected = makeExpected(recursive, followLinks);
+      futures.add(
+        baseDir.list(recursive: recursive, followLinks: followLinks)
+        .forEach((entity) => checkEntity(entity, expected))
+        .then((_) {
+          for (var v in expected.values) {
+            Expect.equals('Found', v);
+          }
+        })
+      );
+    }
+  }
+  return Future.wait(futures);
+}
+
+main() {
+  ReceivePort keepAlive = new ReceivePort();
+  testCreate()
+  .then((_) => testCreateLoopingLink())
+  .then((_) => keepAlive.close());
+}
diff --git a/tests/standalone/io/mime_multipart_parser_test.dart b/tests/standalone/io/mime_multipart_parser_test.dart
index e8635aa..1045b5a 100644
--- a/tests/standalone/io/mime_multipart_parser_test.dart
+++ b/tests/standalone/io/mime_multipart_parser_test.dart
@@ -5,79 +5,53 @@
 import "package:expect/expect.dart";
 import 'dart:async';
 import 'dart:math';
-
-part '../../../sdk/lib/io/io_sink.dart';
-part "../../../sdk/lib/io/http.dart";
-part "../../../sdk/lib/io/http_impl.dart";
-part "../../../sdk/lib/io/http_parser.dart";
-part "../../../sdk/lib/io/mime_multipart_parser.dart";
-part '../../../sdk/lib/io/socket.dart';
+import 'dart:io';
+import 'dart:isolate';
 
 void testParse(String message,
                String boundary,
                [List<Map> expectedHeaders,
-               List expectedParts]) {
-  _MimeMultipartParser parser;
-  int partCount;
-  Map headers;
-  List<int> currentPart;
-  bool lastPartCalled;
-
-  void reset() {
-    parser = new _MimeMultipartParser(boundary);
-    parser.partStart = (f, v) {
-    };
-    parser.headerReceived = (f, v) {
-      headers[f] = v;
-    };
-    parser.headersComplete = () {
-      if (expectedHeaders != null) {
-        expectedHeaders[partCount].forEach(
-            (String name, String value) {
-              Expect.equals(value, headers[name]);
-            });
-      }
-    };
-    parser.partDataReceived = (List<int> data) {
-      if (currentPart == null) currentPart = new List<int>();
-      currentPart.addAll(data);
-    };
-    parser.partEnd = (lastPart) {
-      Expect.isFalse(lastPartCalled);
-      lastPartCalled = lastPart;
-      if (expectedParts[partCount] != null) {
-        List<int> expectedPart;
-        if (expectedParts[partCount] is String) {
-          expectedPart = expectedParts[partCount].codeUnits;
-        } else {
-          expectedPart = expectedParts[partCount];
-        }
-        Expect.listEquals(expectedPart, currentPart);
-      }
-      currentPart = null;
-      partCount++;
-      if (lastPart) Expect.equals(expectedParts.length, partCount);
-    };
-
-    partCount = 0;
-    headers = new Map();
-    currentPart = null;
-    lastPartCalled = false;
-  }
-
+               List expectedParts,
+               bool expectError = false]) {
   void testWrite(List<int> data, [int chunkSize = -1]) {
+    StreamController controller = new StreamController();
+
+    var stream = controller.stream.transform(
+        new MimeMultipartTransformer(boundary));
+    int i = 0;
+    var port = new ReceivePort();
+    stream.listen((multipart) {
+      int part = i++;
+      if (expectedHeaders != null) {
+        Expect.mapEquals(expectedHeaders[part], multipart.headers);
+      }
+      var partPort = new ReceivePort();
+      multipart.fold([], (buffer, data) => buffer..addAll(data))
+          .then((data) {
+            if (expectedParts[part] != null) {
+              Expect.listEquals(expectedParts[part].codeUnits, data);
+            }
+            partPort.close();
+          });
+    }, onError: (error) {
+      if (!expectError) throw error;
+    }, onDone: () {
+      if (expectedParts != null) {
+        Expect.equals(expectedParts.length, i);
+      }
+      port.close();
+    });
+
     if (chunkSize == -1) chunkSize = data.length;
-    reset();
+
     int written = 0;
     for (int pos = 0; pos < data.length; pos += chunkSize) {
       int remaining = data.length - pos;
       int writeLength = min(chunkSize, remaining);
-      int parsed =
-          parser.update(data.sublist(pos, pos + writeLength), 0, writeLength);
-      Expect.equals(writeLength, parsed);
+      controller.add(data.sublist(pos, pos + writeLength));
       written += writeLength;
     }
-    Expect.isTrue(lastPartCalled);
+    controller.close();
   }
 
   // Test parsing the data three times delivering the data in
@@ -195,7 +169,7 @@
   body3 = "on";
   body4 = "on";
   testParse(message,
-            "----webkitformboundaryq3cgyamgrf8yoeyb",
+            "----WebKitFormBoundaryQ3cgYAmGRF8yOeYB",
             [headers1, headers2, headers3, headers4],
             [body1, body2, body3, body4]);
 
@@ -321,7 +295,7 @@
 \r
 Body2\r
 --xxx--\r\n""";
-  Expect.throws(() => testParse(message, "xxx", null, [null, null]));
+  testParse(message, "xxx", null, ["\r\nBody2"]);
 
   // Missing end boundary.
   message = """
@@ -335,7 +309,7 @@
 \r
 Body2\r
 --xxx\r\n""";
-  Expect.throws(() => testParse(message, "xxx", null, [null, null]));
+  testParse(message, "xxx", null, [null, null], true);
 }
 
 void main() {
diff --git a/tests/standalone/io/windows_file_system_async_links_test.dart b/tests/standalone/io/windows_file_system_async_links_test.dart
new file mode 100644
index 0000000..5560776
--- /dev/null
+++ b/tests/standalone/io/windows_file_system_async_links_test.dart
@@ -0,0 +1,105 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "dart:async";
+import 'package:expect/expect.dart';
+import "dart:io";
+import "dart:isolate";
+
+
+class FutureExpect {
+  static Future isTrue(Future<bool> result) =>
+      result.then((value) => Expect.isTrue(value));
+  static Future isFalse(Future<bool> result) =>
+      result.then((value) => Expect.isFalse(value));
+  static Future equals(expected, Future result) =>
+      result.then((value) => Expect.equals(expected, value));
+  static Future listEquals(expected, Future result) =>
+      result.then((value) => Expect.listEquals(expected, value));
+  static Future throws(Future result) =>
+      result.then((value) {
+        throw new ExpectException(
+            "FutureExpect.throws received $value instead of an exception");
+        }, onError: (_) => null);
+}
+
+
+Future testJunctionTypeDelete() {
+  return new Directory('').createTemp().then((temp) {
+    var x = '${temp.path}${Platform.pathSeparator}x';
+    var y = '${temp.path}${Platform.pathSeparator}y';
+    return new Directory(x).create()
+    .then((_) => new Link(y).create(x))
+    .then((_) => FutureExpect.isTrue(new Directory(y).exists()))
+    .then((_) => FutureExpect.isTrue(new Directory(x).exists()))
+    .then((_) => FutureExpect.isTrue(FileSystemEntity.isLink(y)))
+    .then((_) => FutureExpect.isFalse(FileSystemEntity.isLink(x)))
+    .then((_) => FutureExpect.isTrue(FileSystemEntity.isDirectory(y)))
+    .then((_) => FutureExpect.isTrue(FileSystemEntity.isDirectory(x)))
+    .then((_) => FutureExpect.equals(FileSystemEntityType.DIRECTORY,
+                  FileSystemEntity.type(y)))
+    .then((_) => FutureExpect.equals(FileSystemEntityType.DIRECTORY,
+                  FileSystemEntity.type(x)))
+    .then((_) => FutureExpect.equals(FileSystemEntityType.LINK,
+                  FileSystemEntity.type(y, followLinks: false)))
+    .then((_) => FutureExpect.equals(FileSystemEntityType.DIRECTORY,
+                  FileSystemEntity.type(x, followLinks: false)))
+    .then((_) => FutureExpect.equals(x, new Link(y).target()))
+
+    // Test Junction pointing to a missing directory.
+    .then((_) => new Directory(x).delete())
+    .then((_) => FutureExpect.isTrue(new Link(y).exists()))
+    .then((_) => FutureExpect.isFalse(new Directory(x).exists()))
+    .then((_) => FutureExpect.isTrue(FileSystemEntity.isLink(y)))
+    .then((_) => FutureExpect.isFalse(FileSystemEntity.isLink(x)))
+    .then((_) => FutureExpect.isFalse(FileSystemEntity.isDirectory(y)))
+    .then((_) => FutureExpect.isFalse(FileSystemEntity.isDirectory(x)))
+    .then((_) => FutureExpect.equals(FileSystemEntityType.LINK,
+                                     FileSystemEntity.type(y)))
+    .then((_) => FutureExpect.equals(FileSystemEntityType.NOT_FOUND,
+                                     FileSystemEntity.type(x)))
+    .then((_) => FutureExpect.equals(FileSystemEntityType.LINK,
+                     FileSystemEntity.type(y, followLinks: false)))
+    .then((_) => FutureExpect.equals(FileSystemEntityType.NOT_FOUND,
+                     FileSystemEntity.type(x, followLinks: false)))
+    .then((_) => FutureExpect.equals(x, new Link(y).target()))
+
+    // Delete Junction pointing to a missing directory.
+    .then((_) => new Link(y).delete())
+    .then((_) => FutureExpect.isFalse(FileSystemEntity.isLink(y)))
+    .then((_) => FutureExpect.equals(FileSystemEntityType.NOT_FOUND,
+                  FileSystemEntity.type(y)))
+    .then((_) => FutureExpect.throws(new Link(y).target()))
+
+    .then((_) => new Directory(x).create())
+    .then((_) => new Link(y).create(x))
+    .then((_) => FutureExpect.equals(FileSystemEntityType.LINK,
+                     FileSystemEntity.type(y, followLinks: false)))
+    .then((_) => FutureExpect.equals(FileSystemEntityType.DIRECTORY,
+                     FileSystemEntity.type(x, followLinks: false)))
+    .then((_) => FutureExpect.equals(x, new Link(y).target()))
+
+    // Delete Junction pointing to an existing directory.
+    .then((_) => new Directory(y).delete())
+    .then((_) => FutureExpect.equals(FileSystemEntityType.NOT_FOUND,
+                                     FileSystemEntity.type(y)))
+    .then((_) => FutureExpect.equals(FileSystemEntityType.NOT_FOUND,
+                     FileSystemEntity.type(y, followLinks: false)))
+    .then((_) => FutureExpect.equals(FileSystemEntityType.DIRECTORY,
+                                     FileSystemEntity.type(x)))
+    .then((_) => FutureExpect.equals(FileSystemEntityType.DIRECTORY,
+                     FileSystemEntity.type(x, followLinks: false)))
+    .then((_) => FutureExpect.throws(new Link(y).target()))
+    .then((_) => temp.delete(recursive: true));
+  });
+}
+
+
+main() {
+  // Links on other platforms are tested by file_system_[async_]links_test.
+  if (Platform.operatingSystem == 'windows') {
+    ReceivePort keepAlive = new ReceivePort();
+    testJunctionTypeDelete().then((_) => keepAlive.close());
+  }
+}
diff --git a/tests/standalone/io/windows_file_system_links_test.dart b/tests/standalone/io/windows_file_system_links_test.dart
index 7775be8..e20dd24 100644
--- a/tests/standalone/io/windows_file_system_links_test.dart
+++ b/tests/standalone/io/windows_file_system_links_test.dart
@@ -81,6 +81,7 @@
 
 
 main() {
+  // Links on other platforms are tested by file_system_[async_]links_test.
   if (Platform.operatingSystem == 'windows') {
     testJunctionTypeDelete();
   }
diff --git a/tests/standalone/standalone.status b/tests/standalone/standalone.status
index f342f31..98e86d9 100644
--- a/tests/standalone/standalone.status
+++ b/tests/standalone/standalone.status
@@ -47,10 +47,6 @@
 io/directory_non_ascii_test: Pass, Fail
 io/process_non_ascii_test: Pass, Fail
 
-[ $runtime == vm && $system == windows ]
-io/file_system_links_test: Skip  # No links on Windows.
-io/file_read_special_device_test: Skip  # No special unix devices on Windows.
-
 [ $compiler == none && $runtime == drt ]
 typed_data_isolate_test: Skip # This test uses dart:io
 io/*: Skip # Don't run tests using dart:io in the browser
@@ -70,7 +66,6 @@
 # members and methods of dart:io.
 # Dartc spots the misuse of 'part' directives in these unit tests.
 crypto/*: Skip  # dartc cannot parse dart:io unit tests.
-io/mime_multipart_parser_test: Skip  # dartc cannot parse dart:io unit tests.
 io/http_headers_test: Skip  # dartc cannot parse dart:io unit tests.
 io/http_date_test: Skip  # dartc cannot parse dart:io unit tests.
 io/url_encoding_test: Skip  # dartc cannot parse dart:io unit tests.
diff --git a/tools/VERSION b/tools/VERSION
index 8b16f58..3671ff7 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -1,4 +1,4 @@
 MAJOR 0
 MINOR 5
-BUILD 4
+BUILD 5
 PATCH 0
diff --git a/tools/dom/docs/lib/docs.dart b/tools/dom/docs/lib/docs.dart
index bdd9809..0b52b22 100644
--- a/tools/dom/docs/lib/docs.dart
+++ b/tools/dom/docs/lib/docs.dart
@@ -12,6 +12,7 @@
 
 import '../../../../sdk/lib/_internal/dartdoc/lib/src/dart2js_mirrors.dart';
 import '../../../../sdk/lib/_internal/compiler/implementation/mirrors/mirrors.dart';
+import '../../../../sdk/lib/_internal/compiler/implementation/mirrors/mirrors_util.dart';
 import '../../../../sdk/lib/_internal/dartdoc/lib/dartdoc.dart';
 import '../../../../sdk/lib/_internal/dartdoc/lib/src/json_serializer.dart';
 import '../../../../utils/apidoc/lib/metadata.dart';
@@ -87,7 +88,7 @@
         y.uri.toString().toUpperCase()));
 
   for (LibraryMirror libMirror in sortedLibraries) {
-    print('Extracting documentation from ${libMirror.displayName}.');
+    print('Extracting documentation from ${libMirror.simpleName}.');
 
     var libraryJson = {};
     var sortedClasses = _sortAndFilterMirrors(
@@ -134,7 +135,7 @@
     }
 
     if (!libraryJson.isEmpty) {
-      convertedJson.putIfAbsent(libMirror.displayName, () =>
+      convertedJson.putIfAbsent(libMirror.simpleName, () =>
           libraryJson);
     }
   }
@@ -152,7 +153,7 @@
 
   var filteredMirrors = mirrors.where((DeclarationMirror c) =>
       !domNames(c).isEmpty &&
-      !c.displayName.startsWith('_') &&
+      !displayName(c).startsWith('_') &&
       (!ignoreDocsEditable ? (findMetadata(c.metadata, 'DocsEditable') != null)
           : true))
       .toList();
diff --git a/tools/dom/dom.py b/tools/dom/dom.py
index 5832af4..15697b3 100755
--- a/tools/dom/dom.py
+++ b/tools/dom/dom.py
@@ -20,6 +20,10 @@
 else:
   dart_bin = os.path.join(dart_out_dir, 'dart')
 
+dart_dir = os.path.abspath(os.path.join(
+    os.path.dirname(os.path.realpath(__file__)),
+    os.path.pardir, os.path.pardir))
+
 def help():
   print('Helper script to make it easy to perform common tasks encountered '
      'during the life of a Dart DOM developer.\n'
@@ -166,13 +170,6 @@
     print error
   return pipe.returncode
 
-def init_dir():
-  ''' Makes sure that we're always rooted in the dart root folder.'''
-  dart_dir = os.path.abspath(os.path.join(
-      os.path.dirname(os.path.realpath(__file__)),
-      os.path.pardir, os.path.pardir))
-  os.chdir(dart_dir)
-
 commands = {
   'analyze': [analyze, 'Run the dart analyzer'],
   'build': [build, 'Build dart in release mode'],
@@ -201,7 +198,8 @@
     success = False
 
   while (argv):
-    init_dir()
+    # Make sure that we're always rooted in the dart root folder.
+    os.chdir(dart_dir)
     command = argv.pop(0)
 
     if not command in commands:
diff --git a/tools/testing/dart/test_suite.dart b/tools/testing/dart/test_suite.dart
index ea8877b..bd0ddbd 100644
--- a/tools/testing/dart/test_suite.dart
+++ b/tools/testing/dart/test_suite.dart
@@ -200,8 +200,9 @@
 
   String get d8FileName {
     var suffix = getExecutableSuffix('d8');
-    var d8Dir = '${TestUtils.dartDir()}/third_party/d8';
-    var d8 = '$d8Dir/${Platform.operatingSystem}/d8$suffix';
+    var d8Dir = TestUtils.dartDir().append('third_party/d8');
+    var d8Path = d8Dir.append('${Platform.operatingSystem}/d8$suffix');
+    var d8 = d8Path.toNativePath();
     TestUtils.ensureExists(d8, configuration);
     return d8;
   }