diff --git a/sdk/lib/_internal/lib/isolate_helper.dart b/sdk/lib/_internal/lib/isolate_helper.dart
index ce6b5d3..bf3caa2 100644
--- a/sdk/lib/_internal/lib/isolate_helper.dart
+++ b/sdk/lib/_internal/lib/isolate_helper.dart
@@ -1133,7 +1133,6 @@
     if (x is List) return visitList(x);
     if (x is Map) return visitMap(x);
     if (x is SendPort) return visitSendPort(x);
-    if (x is SendPortSync) return visitSendPortSync(x);
 
     // Overridable fallback.
     return visitObject(x);
@@ -1143,7 +1142,6 @@
   visitList(List x);
   visitMap(Map x);
   visitSendPort(SendPort x);
-  visitSendPortSync(SendPortSync x);
 
   visitObject(Object x) {
     // TODO(floitsch): make this a real exception. (which one)?
diff --git a/sdk/lib/_internal/pub/lib/src/barback/dart2js_transformer.dart b/sdk/lib/_internal/pub/lib/src/barback/dart2js_transformer.dart
index 293ac2f..8eca860 100644
--- a/sdk/lib/_internal/pub/lib/src/barback/dart2js_transformer.dart
+++ b/sdk/lib/_internal/pub/lib/src/barback/dart2js_transformer.dart
@@ -34,6 +34,16 @@
   // TODO(rnystrom): Do something cleaner for this, or eliminate those files.
   final entrypoints = new Set<AssetId>();
 
+  /// If this is non-null, then the transformer is currently being applied, so
+  /// subsequent calls to [apply] will wait for this to finish before
+  /// proceeding.
+  ///
+  /// Dart2js uses lots of memory, so if we try to actually run compiles in
+  /// parallel, it takes down the VM. Instead, the transformer will force
+  /// all applies to be sequential. The tracking bug to do something better
+  /// is here: https://code.google.com/p/dart/issues/detail?id=14730.
+  Future _running;
+
   Dart2JSTransformer(this._graph, {bool minify})
       : _minify = minify == true ? true : false;
 
@@ -45,6 +55,18 @@
   }
 
   Future apply(Transform transform) {
+    // Wait for any ongoing apply to finish first.
+    // TODO(rnystrom): If there are multiple simultaneous compiles, this will
+    // resume and pause them repeatedly. It still serializes them correctly,
+    // but it might be cleaner to use a real queue.
+    // TODO(rnystrom): Add a test that this is functionality is helpful.
+    if (_running != null) {
+      return _running.then((_) => apply(transform));
+    }
+
+    var completer = new Completer();
+    _running = completer.future;
+
     var stopwatch = new Stopwatch();
     stopwatch.start();
 
@@ -96,6 +118,9 @@
         if (error is CompilerException) return;
         throw error;
       });
+    }).whenComplete(() {
+      completer.complete();
+      _running = null;
     });
   }
 }
diff --git a/sdk/lib/html/dart2js/html_dart2js.dart b/sdk/lib/html/dart2js/html_dart2js.dart
index d1a106a..c2a2227 100644
--- a/sdk/lib/html/dart2js/html_dart2js.dart
+++ b/sdk/lib/html/dart2js/html_dart2js.dart
@@ -102,19 +102,6 @@
 // older Chrome versions.
 // Issue #12573.
 abstract class _EntryArray implements List<Entry> native "EntryArray" {}
-
-// Support for Send/ReceivePortSync.
-int _getNewIsolateId() {
-  if (JS('bool', r'!window.$dart$isolate$counter')) {
-    JS('void', r'window.$dart$isolate$counter = 1');
-  }
-  return JS('int', r'window.$dart$isolate$counter++');
-}
-
-// Fast path to invoke JS send port.
-_callPortSync(int id, message) {
-  return JS('var', r'ReceivePortSync.dispatchCall(#, #)', id, message);
-}
 // Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
@@ -26276,39 +26263,6 @@
 class Window extends EventTarget implements WindowBase, _WindowTimers, WindowBase64 native "Window,DOMWindow" {
 
   /**
-   * Lookup a port by its [name].  Return null if no port is
-   * registered under [name].
-   */
-  SendPortSync lookupPort(String name) {
-    var portStr = document.documentElement.attributes['dart-port:$name'];
-    if (portStr == null) {
-      return null;
-    }
-    var port = JSON.decode(portStr);
-    return _deserialize(port);
-  }
-
-  /**
-   * Register a [port] on this window under the given [name].  This
-   * port may be retrieved by any isolate (or JavaScript script)
-   * running in this window.
-   */
-  void registerPort(String name, var port) {
-    var serialized = _serialize(port);
-    document.documentElement.attributes['dart-port:$name'] =
-        JSON.encode(serialized);
-  }
-
-  /**
-   * Deregister a [port] on this window under the given [name].  This
-   * port may be retrieved by any isolate (or JavaScript script)
-   * running in this window.
-   */
-  void deregisterPort(String name) {
-    document.documentElement.attributes.remove('dart-port:$name');
-  }
-
-  /**
    * Returns a Future that completes just before the window is about to
    * repaint so the user can draw an animation frame.
    *
@@ -31356,227 +31310,6 @@
 // BSD-style license that can be found in the LICENSE file.
 
 
-_serialize(var message) {
-  return new _JsSerializer().traverse(message);
-}
-
-class _JsSerializer extends _Serializer {
-
-  visitSendPortSync(SendPortSync x) {
-    if (x is _JsSendPortSync) return visitJsSendPortSync(x);
-    if (x is _LocalSendPortSync) return visitLocalSendPortSync(x);
-    if (x is _RemoteSendPortSync) return visitRemoteSendPortSync(x);
-    throw "Unknown port type $x";
-  }
-
-  visitJsSendPortSync(_JsSendPortSync x) {
-    return [ 'sendport', 'nativejs', x._id ];
-  }
-
-  visitLocalSendPortSync(_LocalSendPortSync x) {
-    return [ 'sendport', 'dart',
-             ReceivePortSync._isolateId, x._receivePort._portId ];
-  }
-
-  visitSendPort(SendPort x) {
-    throw new UnimplementedError('Asynchronous send port not yet implemented.');
-  }
-
-  visitRemoteSendPortSync(_RemoteSendPortSync x) {
-    return [ 'sendport', 'dart', x._isolateId, x._portId ];
-  }
-}
-
-_deserialize(var message) {
-  return new _JsDeserializer().deserialize(message);
-}
-
-
-class _JsDeserializer extends _Deserializer {
-
-  static const _UNSPECIFIED = const Object();
-
-  deserializeSendPort(List x) {
-    String tag = x[1];
-    switch (tag) {
-      case 'nativejs':
-        num id = x[2];
-        return new _JsSendPortSync(id);
-      case 'dart':
-        num isolateId = x[2];
-        num portId = x[3];
-        return ReceivePortSync._lookup(isolateId, portId);
-      default:
-        throw 'Illegal SendPortSync type: $tag';
-    }
-  }
-}
-
-// The receiver is JS.
-class _JsSendPortSync implements SendPortSync {
-
-  final num _id;
-  _JsSendPortSync(this._id);
-
-  callSync(var message) {
-    var serialized = _serialize(message);
-    var result = _callPortSync(_id, serialized);
-    return _deserialize(result);
-  }
-
-  bool operator==(var other) {
-    return (other is _JsSendPortSync) && (_id == other._id);
-  }
-
-  int get hashCode => _id;
-}
-
-// TODO(vsm): Differentiate between Dart2Js and Dartium isolates.
-// The receiver is a different Dart isolate, compiled to JS.
-class _RemoteSendPortSync implements SendPortSync {
-
-  int _isolateId;
-  int _portId;
-  _RemoteSendPortSync(this._isolateId, this._portId);
-
-  callSync(var message) {
-    var serialized = _serialize(message);
-    var result = _call(_isolateId, _portId, serialized);
-    return _deserialize(result);
-  }
-
-  static _call(int isolateId, int portId, var message) {
-    var target = 'dart-port-$isolateId-$portId';
-    // TODO(vsm): Make this re-entrant.
-    // TODO(vsm): Set this up set once, on the first call.
-    var source = '$target-result';
-    var result = null;
-    window.on[source].first.then((Event e) {
-      result = JSON.decode(_getPortSyncEventData(e));
-    });
-    _dispatchEvent(target, [source, message]);
-    return result;
-  }
-
-  bool operator==(var other) {
-    return (other is _RemoteSendPortSync) && (_isolateId == other._isolateId)
-      && (_portId == other._portId);
-  }
-
-  int get hashCode => _isolateId >> 16 + _portId;
-}
-
-// The receiver is in the same Dart isolate, compiled to JS.
-class _LocalSendPortSync implements SendPortSync {
-
-  ReceivePortSync _receivePort;
-
-  _LocalSendPortSync._internal(this._receivePort);
-
-  callSync(var message) {
-    // TODO(vsm): Do a more efficient deep copy.
-    var copy = _deserialize(_serialize(message));
-    var result = _receivePort._callback(copy);
-    return _deserialize(_serialize(result));
-  }
-
-  bool operator==(var other) {
-    return (other is _LocalSendPortSync)
-      && (_receivePort == other._receivePort);
-  }
-
-  int get hashCode => _receivePort.hashCode;
-}
-
-// TODO(vsm): Move this to dart:isolate.  This will take some
-// refactoring as there are dependences here on the DOM.  Users
-// interact with this class (or interface if we change it) directly -
-// new ReceivePortSync.  I think most of the DOM logic could be
-// delayed until the corresponding SendPort is registered on the
-// window.
-
-// A Dart ReceivePortSync (tagged 'dart' when serialized) is
-// identifiable / resolvable by the combination of its isolateid and
-// portid.  When a corresponding SendPort is used within the same
-// isolate, the _portMap below can be used to obtain the
-// ReceivePortSync directly.  Across isolates (or from JS), an
-// EventListener can be used to communicate with the port indirectly.
-class ReceivePortSync {
-
-  static Map<int, ReceivePortSync> _portMap;
-  static int _portIdCount;
-  static int _cachedIsolateId;
-
-  num _portId;
-  Function _callback;
-  StreamSubscription _portSubscription;
-
-  ReceivePortSync() {
-    if (_portIdCount == null) {
-      _portIdCount = 0;
-      _portMap = new Map<int, ReceivePortSync>();
-    }
-    _portId = _portIdCount++;
-    _portMap[_portId] = this;
-  }
-
-  static int get _isolateId {
-    // TODO(vsm): Make this coherent with existing isolate code.
-    if (_cachedIsolateId == null) {
-      _cachedIsolateId = _getNewIsolateId();
-    }
-    return _cachedIsolateId;
-  }
-
-  static String _getListenerName(isolateId, portId) =>
-      'dart-port-$isolateId-$portId';
-  String get _listenerName => _getListenerName(_isolateId, _portId);
-
-  void receive(callback(var message)) {
-    _callback = callback;
-    if (_portSubscription == null) {
-      _portSubscription = window.on[_listenerName].listen((Event e) {
-        var data = JSON.decode(_getPortSyncEventData(e));
-        var replyTo = data[0];
-        var message = _deserialize(data[1]);
-        var result = _callback(message);
-        _dispatchEvent(replyTo, _serialize(result));
-      });
-    }
-  }
-
-  void close() {
-    _portMap.remove(_portId);
-    if (_portSubscription != null) _portSubscription.cancel();
-  }
-
-  SendPortSync toSendPort() {
-    return new _LocalSendPortSync._internal(this);
-  }
-
-  static SendPortSync _lookup(int isolateId, int portId) {
-    if (isolateId == _isolateId) {
-      return _portMap[portId].toSendPort();
-    } else {
-      return new _RemoteSendPortSync(isolateId, portId);
-    }
-  }
-}
-
-get _isolateId => ReceivePortSync._isolateId;
-
-void _dispatchEvent(String receiver, var message) {
-  var event = new CustomEvent(receiver, canBubble: false, cancelable:false,
-    detail: JSON.encode(message));
-  window.dispatchEvent(event);
-}
-
-String _getPortSyncEventData(CustomEvent event) => event.detail;
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-
 /**
  * Defines the keycode values for keys that are returned by
  * KeyboardEvent.keyCode.
@@ -33266,185 +32999,6 @@
    */
   static const String COMPLETE = "complete";
 }
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// Patch file for the dart:isolate library.
-
-
-/********************************************************
-  Inserted from lib/isolate/serialization.dart
- ********************************************************/
-
-class _MessageTraverserVisitedMap {
-
-  operator[](var object) => null;
-  void operator[]=(var object, var info) { }
-
-  void reset() { }
-  void cleanup() { }
-
-}
-
-/** Abstract visitor for dart objects that can be sent as isolate messages. */
-abstract class _MessageTraverser {
-
-  _MessageTraverserVisitedMap _visited;
-  _MessageTraverser() : _visited = new _MessageTraverserVisitedMap();
-
-  /** Visitor's entry point. */
-  traverse(var x) {
-    if (isPrimitive(x)) return visitPrimitive(x);
-    _visited.reset();
-    var result;
-    try {
-      result = _dispatch(x);
-    } finally {
-      _visited.cleanup();
-    }
-    return result;
-  }
-
-  _dispatch(var x) {
-    if (isPrimitive(x)) return visitPrimitive(x);
-    if (x is List) return visitList(x);
-    if (x is Map) return visitMap(x);
-    if (x is SendPort) return visitSendPort(x);
-    if (x is SendPortSync) return visitSendPortSync(x);
-
-    // Overridable fallback.
-    return visitObject(x);
-  }
-
-  visitPrimitive(x);
-  visitList(List x);
-  visitMap(Map x);
-  visitSendPort(SendPort x);
-  visitSendPortSync(SendPortSync x);
-
-  visitObject(Object x) {
-    // TODO(floitsch): make this a real exception. (which one)?
-    throw "Message serialization: Illegal value $x passed";
-  }
-
-  static bool isPrimitive(x) {
-    return (x == null) || (x is String) || (x is num) || (x is bool);
-  }
-}
-
-
-/** Visitor that serializes a message as a JSON array. */
-abstract class _Serializer extends _MessageTraverser {
-  int _nextFreeRefId = 0;
-
-  visitPrimitive(x) => x;
-
-  visitList(List list) {
-    int copyId = _visited[list];
-    if (copyId != null) return ['ref', copyId];
-
-    int id = _nextFreeRefId++;
-    _visited[list] = id;
-    var jsArray = _serializeList(list);
-    // TODO(floitsch): we are losing the generic type.
-    return ['list', id, jsArray];
-  }
-
-  visitMap(Map map) {
-    int copyId = _visited[map];
-    if (copyId != null) return ['ref', copyId];
-
-    int id = _nextFreeRefId++;
-    _visited[map] = id;
-    var keys = _serializeList(map.keys.toList());
-    var values = _serializeList(map.values.toList());
-    // TODO(floitsch): we are losing the generic type.
-    return ['map', id, keys, values];
-  }
-
-  _serializeList(List list) {
-    int len = list.length;
-    var result = new List(len);
-    for (int i = 0; i < len; i++) {
-      result[i] = _dispatch(list[i]);
-    }
-    return result;
-  }
-}
-
-/** Deserializes arrays created with [_Serializer]. */
-abstract class _Deserializer {
-  Map<int, dynamic> _deserialized;
-
-  _Deserializer();
-
-  static bool isPrimitive(x) {
-    return (x == null) || (x is String) || (x is num) || (x is bool);
-  }
-
-  deserialize(x) {
-    if (isPrimitive(x)) return x;
-    // TODO(floitsch): this should be new HashMap<int, dynamic>()
-    _deserialized = new HashMap();
-    return _deserializeHelper(x);
-  }
-
-  _deserializeHelper(x) {
-    if (isPrimitive(x)) return x;
-    assert(x is List);
-    switch (x[0]) {
-      case 'ref': return _deserializeRef(x);
-      case 'list': return _deserializeList(x);
-      case 'map': return _deserializeMap(x);
-      case 'sendport': return deserializeSendPort(x);
-      default: return deserializeObject(x);
-    }
-  }
-
-  _deserializeRef(List x) {
-    int id = x[1];
-    var result = _deserialized[id];
-    assert(result != null);
-    return result;
-  }
-
-  List _deserializeList(List x) {
-    int id = x[1];
-    // We rely on the fact that Dart-lists are directly mapped to Js-arrays.
-    List dartList = x[2];
-    _deserialized[id] = dartList;
-    int len = dartList.length;
-    for (int i = 0; i < len; i++) {
-      dartList[i] = _deserializeHelper(dartList[i]);
-    }
-    return dartList;
-  }
-
-  Map _deserializeMap(List x) {
-    Map result = new Map();
-    int id = x[1];
-    _deserialized[id] = result;
-    List keys = x[2];
-    List values = x[3];
-    int len = keys.length;
-    assert(len == values.length);
-    for (int i = 0; i < len; i++) {
-      var key = _deserializeHelper(keys[i]);
-      var value = _deserializeHelper(values[i]);
-      result[key] = value;
-    }
-    return result;
-  }
-
-  deserializeSendPort(List x);
-
-  deserializeObject(List x) {
-    // TODO(floitsch): Use real exception (which one?).
-    throw "Unexpected serialized object";
-  }
-}
-
 // Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
diff --git a/sdk/lib/html/dartium/html_dartium.dart b/sdk/lib/html/dartium/html_dartium.dart
index 047cafc..85ca975 100644
--- a/sdk/lib/html/dartium/html_dartium.dart
+++ b/sdk/lib/html/dartium/html_dartium.dart
@@ -93,25 +93,6 @@
   _document = window.document;
   return _document;
 }
-
-int _getNewIsolateId() => _Utils._getNewIsolateId();
-
-bool _callPortInitialized = false;
-var _callPortLastResult = null;
-
-_callPortSync(num id, var message) {
-  if (!_callPortInitialized) {
-    window.on['js-result'].listen((event) {
-      _callPortLastResult = JSON.decode(_getPortSyncEventData(event));
-    });
-    _callPortInitialized = true;
-  }
-  assert(_callPortLastResult == null);
-  _dispatchEvent('js-sync-message', {'id': id, 'message': message});
-  var result = _callPortLastResult;
-  _callPortLastResult = null;
-  return result;
-}
 // Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
@@ -28063,39 +28044,6 @@
 class Window extends EventTarget implements WindowBase, _WindowTimers, WindowBase64 {
 
   /**
-   * Lookup a port by its [name].  Return null if no port is
-   * registered under [name].
-   */
-  SendPortSync lookupPort(String name) {
-    var portStr = document.documentElement.attributes['dart-port:$name'];
-    if (portStr == null) {
-      return null;
-    }
-    var port = JSON.decode(portStr);
-    return _deserialize(port);
-  }
-
-  /**
-   * Register a [port] on this window under the given [name].  This
-   * port may be retrieved by any isolate (or JavaScript script)
-   * running in this window.
-   */
-  void registerPort(String name, var port) {
-    var serialized = _serialize(port);
-    document.documentElement.attributes['dart-port:$name'] =
-        JSON.encode(serialized);
-  }
-
-  /**
-   * Deregister a [port] on this window under the given [name].  This
-   * port may be retrieved by any isolate (or JavaScript script)
-   * running in this window.
-   */
-  void deregisterPort(String name) {
-    document.documentElement.attributes.remove('dart-port:$name');
-  }
-
-  /**
    * Returns a Future that completes just before the window is about to
    * repaint so the user can draw an animation frame.
    *
@@ -33259,227 +33207,6 @@
 // BSD-style license that can be found in the LICENSE file.
 
 
-_serialize(var message) {
-  return new _JsSerializer().traverse(message);
-}
-
-class _JsSerializer extends _Serializer {
-
-  visitSendPortSync(SendPortSync x) {
-    if (x is _JsSendPortSync) return visitJsSendPortSync(x);
-    if (x is _LocalSendPortSync) return visitLocalSendPortSync(x);
-    if (x is _RemoteSendPortSync) return visitRemoteSendPortSync(x);
-    throw "Unknown port type $x";
-  }
-
-  visitJsSendPortSync(_JsSendPortSync x) {
-    return [ 'sendport', 'nativejs', x._id ];
-  }
-
-  visitLocalSendPortSync(_LocalSendPortSync x) {
-    return [ 'sendport', 'dart',
-             ReceivePortSync._isolateId, x._receivePort._portId ];
-  }
-
-  visitSendPort(SendPort x) {
-    throw new UnimplementedError('Asynchronous send port not yet implemented.');
-  }
-
-  visitRemoteSendPortSync(_RemoteSendPortSync x) {
-    return [ 'sendport', 'dart', x._isolateId, x._portId ];
-  }
-}
-
-_deserialize(var message) {
-  return new _JsDeserializer().deserialize(message);
-}
-
-
-class _JsDeserializer extends _Deserializer {
-
-  static const _UNSPECIFIED = const Object();
-
-  deserializeSendPort(List x) {
-    String tag = x[1];
-    switch (tag) {
-      case 'nativejs':
-        num id = x[2];
-        return new _JsSendPortSync(id);
-      case 'dart':
-        num isolateId = x[2];
-        num portId = x[3];
-        return ReceivePortSync._lookup(isolateId, portId);
-      default:
-        throw 'Illegal SendPortSync type: $tag';
-    }
-  }
-}
-
-// The receiver is JS.
-class _JsSendPortSync implements SendPortSync {
-
-  final num _id;
-  _JsSendPortSync(this._id);
-
-  callSync(var message) {
-    var serialized = _serialize(message);
-    var result = _callPortSync(_id, serialized);
-    return _deserialize(result);
-  }
-
-  bool operator==(var other) {
-    return (other is _JsSendPortSync) && (_id == other._id);
-  }
-
-  int get hashCode => _id;
-}
-
-// TODO(vsm): Differentiate between Dart2Js and Dartium isolates.
-// The receiver is a different Dart isolate, compiled to JS.
-class _RemoteSendPortSync implements SendPortSync {
-
-  int _isolateId;
-  int _portId;
-  _RemoteSendPortSync(this._isolateId, this._portId);
-
-  callSync(var message) {
-    var serialized = _serialize(message);
-    var result = _call(_isolateId, _portId, serialized);
-    return _deserialize(result);
-  }
-
-  static _call(int isolateId, int portId, var message) {
-    var target = 'dart-port-$isolateId-$portId';
-    // TODO(vsm): Make this re-entrant.
-    // TODO(vsm): Set this up set once, on the first call.
-    var source = '$target-result';
-    var result = null;
-    window.on[source].first.then((Event e) {
-      result = JSON.decode(_getPortSyncEventData(e));
-    });
-    _dispatchEvent(target, [source, message]);
-    return result;
-  }
-
-  bool operator==(var other) {
-    return (other is _RemoteSendPortSync) && (_isolateId == other._isolateId)
-      && (_portId == other._portId);
-  }
-
-  int get hashCode => _isolateId >> 16 + _portId;
-}
-
-// The receiver is in the same Dart isolate, compiled to JS.
-class _LocalSendPortSync implements SendPortSync {
-
-  ReceivePortSync _receivePort;
-
-  _LocalSendPortSync._internal(this._receivePort);
-
-  callSync(var message) {
-    // TODO(vsm): Do a more efficient deep copy.
-    var copy = _deserialize(_serialize(message));
-    var result = _receivePort._callback(copy);
-    return _deserialize(_serialize(result));
-  }
-
-  bool operator==(var other) {
-    return (other is _LocalSendPortSync)
-      && (_receivePort == other._receivePort);
-  }
-
-  int get hashCode => _receivePort.hashCode;
-}
-
-// TODO(vsm): Move this to dart:isolate.  This will take some
-// refactoring as there are dependences here on the DOM.  Users
-// interact with this class (or interface if we change it) directly -
-// new ReceivePortSync.  I think most of the DOM logic could be
-// delayed until the corresponding SendPort is registered on the
-// window.
-
-// A Dart ReceivePortSync (tagged 'dart' when serialized) is
-// identifiable / resolvable by the combination of its isolateid and
-// portid.  When a corresponding SendPort is used within the same
-// isolate, the _portMap below can be used to obtain the
-// ReceivePortSync directly.  Across isolates (or from JS), an
-// EventListener can be used to communicate with the port indirectly.
-class ReceivePortSync {
-
-  static Map<int, ReceivePortSync> _portMap;
-  static int _portIdCount;
-  static int _cachedIsolateId;
-
-  num _portId;
-  Function _callback;
-  StreamSubscription _portSubscription;
-
-  ReceivePortSync() {
-    if (_portIdCount == null) {
-      _portIdCount = 0;
-      _portMap = new Map<int, ReceivePortSync>();
-    }
-    _portId = _portIdCount++;
-    _portMap[_portId] = this;
-  }
-
-  static int get _isolateId {
-    // TODO(vsm): Make this coherent with existing isolate code.
-    if (_cachedIsolateId == null) {
-      _cachedIsolateId = _getNewIsolateId();
-    }
-    return _cachedIsolateId;
-  }
-
-  static String _getListenerName(isolateId, portId) =>
-      'dart-port-$isolateId-$portId';
-  String get _listenerName => _getListenerName(_isolateId, _portId);
-
-  void receive(callback(var message)) {
-    _callback = callback;
-    if (_portSubscription == null) {
-      _portSubscription = window.on[_listenerName].listen((Event e) {
-        var data = JSON.decode(_getPortSyncEventData(e));
-        var replyTo = data[0];
-        var message = _deserialize(data[1]);
-        var result = _callback(message);
-        _dispatchEvent(replyTo, _serialize(result));
-      });
-    }
-  }
-
-  void close() {
-    _portMap.remove(_portId);
-    if (_portSubscription != null) _portSubscription.cancel();
-  }
-
-  SendPortSync toSendPort() {
-    return new _LocalSendPortSync._internal(this);
-  }
-
-  static SendPortSync _lookup(int isolateId, int portId) {
-    if (isolateId == _isolateId) {
-      return _portMap[portId].toSendPort();
-    } else {
-      return new _RemoteSendPortSync(isolateId, portId);
-    }
-  }
-}
-
-get _isolateId => ReceivePortSync._isolateId;
-
-void _dispatchEvent(String receiver, var message) {
-  var event = new CustomEvent(receiver, canBubble: false, cancelable:false,
-    detail: JSON.encode(message));
-  window.dispatchEvent(event);
-}
-
-String _getPortSyncEventData(CustomEvent event) => event.detail;
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-
 /**
  * Defines the keycode values for keys that are returned by
  * KeyboardEvent.keyCode.
@@ -35169,185 +34896,6 @@
    */
   static const String COMPLETE = "complete";
 }
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// Patch file for the dart:isolate library.
-
-
-/********************************************************
-  Inserted from lib/isolate/serialization.dart
- ********************************************************/
-
-class _MessageTraverserVisitedMap {
-
-  operator[](var object) => null;
-  void operator[]=(var object, var info) { }
-
-  void reset() { }
-  void cleanup() { }
-
-}
-
-/** Abstract visitor for dart objects that can be sent as isolate messages. */
-abstract class _MessageTraverser {
-
-  _MessageTraverserVisitedMap _visited;
-  _MessageTraverser() : _visited = new _MessageTraverserVisitedMap();
-
-  /** Visitor's entry point. */
-  traverse(var x) {
-    if (isPrimitive(x)) return visitPrimitive(x);
-    _visited.reset();
-    var result;
-    try {
-      result = _dispatch(x);
-    } finally {
-      _visited.cleanup();
-    }
-    return result;
-  }
-
-  _dispatch(var x) {
-    if (isPrimitive(x)) return visitPrimitive(x);
-    if (x is List) return visitList(x);
-    if (x is Map) return visitMap(x);
-    if (x is SendPort) return visitSendPort(x);
-    if (x is SendPortSync) return visitSendPortSync(x);
-
-    // Overridable fallback.
-    return visitObject(x);
-  }
-
-  visitPrimitive(x);
-  visitList(List x);
-  visitMap(Map x);
-  visitSendPort(SendPort x);
-  visitSendPortSync(SendPortSync x);
-
-  visitObject(Object x) {
-    // TODO(floitsch): make this a real exception. (which one)?
-    throw "Message serialization: Illegal value $x passed";
-  }
-
-  static bool isPrimitive(x) {
-    return (x == null) || (x is String) || (x is num) || (x is bool);
-  }
-}
-
-
-/** Visitor that serializes a message as a JSON array. */
-abstract class _Serializer extends _MessageTraverser {
-  int _nextFreeRefId = 0;
-
-  visitPrimitive(x) => x;
-
-  visitList(List list) {
-    int copyId = _visited[list];
-    if (copyId != null) return ['ref', copyId];
-
-    int id = _nextFreeRefId++;
-    _visited[list] = id;
-    var jsArray = _serializeList(list);
-    // TODO(floitsch): we are losing the generic type.
-    return ['list', id, jsArray];
-  }
-
-  visitMap(Map map) {
-    int copyId = _visited[map];
-    if (copyId != null) return ['ref', copyId];
-
-    int id = _nextFreeRefId++;
-    _visited[map] = id;
-    var keys = _serializeList(map.keys.toList());
-    var values = _serializeList(map.values.toList());
-    // TODO(floitsch): we are losing the generic type.
-    return ['map', id, keys, values];
-  }
-
-  _serializeList(List list) {
-    int len = list.length;
-    var result = new List(len);
-    for (int i = 0; i < len; i++) {
-      result[i] = _dispatch(list[i]);
-    }
-    return result;
-  }
-}
-
-/** Deserializes arrays created with [_Serializer]. */
-abstract class _Deserializer {
-  Map<int, dynamic> _deserialized;
-
-  _Deserializer();
-
-  static bool isPrimitive(x) {
-    return (x == null) || (x is String) || (x is num) || (x is bool);
-  }
-
-  deserialize(x) {
-    if (isPrimitive(x)) return x;
-    // TODO(floitsch): this should be new HashMap<int, dynamic>()
-    _deserialized = new HashMap();
-    return _deserializeHelper(x);
-  }
-
-  _deserializeHelper(x) {
-    if (isPrimitive(x)) return x;
-    assert(x is List);
-    switch (x[0]) {
-      case 'ref': return _deserializeRef(x);
-      case 'list': return _deserializeList(x);
-      case 'map': return _deserializeMap(x);
-      case 'sendport': return deserializeSendPort(x);
-      default: return deserializeObject(x);
-    }
-  }
-
-  _deserializeRef(List x) {
-    int id = x[1];
-    var result = _deserialized[id];
-    assert(result != null);
-    return result;
-  }
-
-  List _deserializeList(List x) {
-    int id = x[1];
-    // We rely on the fact that Dart-lists are directly mapped to Js-arrays.
-    List dartList = x[2];
-    _deserialized[id] = dartList;
-    int len = dartList.length;
-    for (int i = 0; i < len; i++) {
-      dartList[i] = _deserializeHelper(dartList[i]);
-    }
-    return dartList;
-  }
-
-  Map _deserializeMap(List x) {
-    Map result = new Map();
-    int id = x[1];
-    _deserialized[id] = result;
-    List keys = x[2];
-    List values = x[3];
-    int len = keys.length;
-    assert(len == values.length);
-    for (int i = 0; i < len; i++) {
-      var key = _deserializeHelper(keys[i]);
-      var value = _deserializeHelper(values[i]);
-      result[key] = value;
-    }
-    return result;
-  }
-
-  deserializeSendPort(List x);
-
-  deserializeObject(List x) {
-    // TODO(floitsch): Use real exception (which one?).
-    throw "Unexpected serialized object";
-  }
-}
-
 // Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
@@ -36029,7 +35577,6 @@
 
   static window() native "Utils_window";
   static forwardingPrint(String message) native "Utils_forwardingPrint";
-  static int _getNewIsolateId() native "Utils_getNewIsolateId";
 
   // The following methods were added for debugger integration to make working
   // with the Dart C mirrors API simpler.
diff --git a/sdk/lib/isolate/isolate.dart b/sdk/lib/isolate/isolate.dart
index fef7ff4..f7d1aed 100644
--- a/sdk/lib/isolate/isolate.dart
+++ b/sdk/lib/isolate/isolate.dart
@@ -206,35 +206,6 @@
 }
 
 /**
- * [SendPortSync]s are created from [ReceivePortSync]s. Any message sent through
- * a [SendPortSync] is delivered to its respective [ReceivePortSync]. There
- * might be many [SendPortSync]s for the same [ReceivePortSync].
- *
- * [SendPortSync]s can be transmitted to other isolates.
- *
- * *DEPRECATED*.
- */
-@deprecated
-abstract class SendPortSync {
-  /**
-   * Sends a synchronous message to this send port and returns the result.
-   */
-  callSync(var message);
-
-  /**
-   * Tests whether [other] is a [SendPortSync] pointing to the same
-   * [ReceivePortSync] as this one.
-   */
-  bool operator==(var other);
-
-  /**
-   * Returns an immutable hash code for this send port that is
-   * consistent with the == operator.
-   */
-  int get hashCode;
-}
-
-/**
  * Wraps unhandled exceptions thrown during isolate execution. It is
  * used to show both the error message and the stack trace for unhandled
  * exceptions.
diff --git a/tests/html/js_interop_4_test.dart b/tests/html/js_interop_4_test.dart
deleted file mode 100644
index 3aee526..0000000
--- a/tests/html/js_interop_4_test.dart
+++ /dev/null
@@ -1,32 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file
-
-library JsInterop4Test;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
-import 'dart:async';
-import 'dart:html';
-import 'dart:isolate';
-
-const testData = const [1, '2', 'true'];
-
-main() {
-  useHtmlConfiguration();
-
-  // Test that our interop scheme also works from Dart to Dart.
-  test('dart-to-dart-same-isolate', () {
-    var fun = expectAsync1((message) {
-      expect(message, orderedEquals(testData));
-      return message.length;
-    });
-
-    var port1 = new ReceivePortSync();
-    port1.receive(fun);
-    window.registerPort('fun', port1.toSendPort());
-
-    var port2 = window.lookupPort('fun');
-    var result = port2.callSync(testData);
-    expect(result, 3);
-  });
-}
diff --git a/tests/isolate/browser/ports_compilation_browser_test.dart b/tests/isolate/browser/ports_compilation_browser_test.dart
deleted file mode 100644
index 5eb76d7..0000000
--- a/tests/isolate/browser/ports_compilation_browser_test.dart
+++ /dev/null
@@ -1,42 +0,0 @@
-// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// Regression test for dart2js that used to crash when compiling
-// [foo]. See http://code.google.com/p/dart/issues/detail?id=7448.
-
-library ports_compilation;
-import 'dart:html';
-import 'dart:isolate';
-import 'package:unittest/unittest.dart';
-import 'package:unittest/html_config.dart';
-
-void foo() {
-  // Create a "SendPortSync" object and access one of its members.
-  SendPortSync s_port;
-  s_port.callSync;
-
-  // Create a "ReceivePortSync" object (with the constructor) and
-  // access one of its members.
-  var r_port = new ReceivePortSync();
-  r_port.receive;
-
-  // Call getComputedStyle() from the HTML library.
-  query("").getComputedStyle("");
-}
-
-int inscrutable(int x) => x == 0 ? 0 : x | inscrutable(x & (x - 1));
-
-void main() {
-  // Generate the call, but don't execute it.
-  if (inscrutable(1) != 1) foo();
-  useHtmlConfiguration();
-  bar();
-  // Also generate it here in case the compiler's worklist goes from
-  // last seen to first seen.
-  if (inscrutable(1) != 1) foo();
-}
-
-bar() {
-  test('compile', () { });
-}
diff --git a/tools/VERSION b/tools/VERSION
index 8ce1702..a2eb097 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -1,4 +1,4 @@
 MAJOR 0
 MINOR 8
 BUILD 10
-PATCH 1
+PATCH 2
diff --git a/tools/dom/src/Isolates.dart b/tools/dom/src/Isolates.dart
deleted file mode 100644
index 3eb4003..0000000
--- a/tools/dom/src/Isolates.dart
+++ /dev/null
@@ -1,222 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-part of html;
-
-_serialize(var message) {
-  return new _JsSerializer().traverse(message);
-}
-
-class _JsSerializer extends _Serializer {
-
-  visitSendPortSync(SendPortSync x) {
-    if (x is _JsSendPortSync) return visitJsSendPortSync(x);
-    if (x is _LocalSendPortSync) return visitLocalSendPortSync(x);
-    if (x is _RemoteSendPortSync) return visitRemoteSendPortSync(x);
-    throw "Unknown port type $x";
-  }
-
-  visitJsSendPortSync(_JsSendPortSync x) {
-    return [ 'sendport', 'nativejs', x._id ];
-  }
-
-  visitLocalSendPortSync(_LocalSendPortSync x) {
-    return [ 'sendport', 'dart',
-             ReceivePortSync._isolateId, x._receivePort._portId ];
-  }
-
-  visitSendPort(SendPort x) {
-    throw new UnimplementedError('Asynchronous send port not yet implemented.');
-  }
-
-  visitRemoteSendPortSync(_RemoteSendPortSync x) {
-    return [ 'sendport', 'dart', x._isolateId, x._portId ];
-  }
-}
-
-_deserialize(var message) {
-  return new _JsDeserializer().deserialize(message);
-}
-
-
-class _JsDeserializer extends _Deserializer {
-
-  static const _UNSPECIFIED = const Object();
-
-  deserializeSendPort(List x) {
-    String tag = x[1];
-    switch (tag) {
-      case 'nativejs':
-        num id = x[2];
-        return new _JsSendPortSync(id);
-      case 'dart':
-        num isolateId = x[2];
-        num portId = x[3];
-        return ReceivePortSync._lookup(isolateId, portId);
-      default:
-        throw 'Illegal SendPortSync type: $tag';
-    }
-  }
-}
-
-// The receiver is JS.
-class _JsSendPortSync implements SendPortSync {
-
-  final num _id;
-  _JsSendPortSync(this._id);
-
-  callSync(var message) {
-    var serialized = _serialize(message);
-    var result = _callPortSync(_id, serialized);
-    return _deserialize(result);
-  }
-
-  bool operator==(var other) {
-    return (other is _JsSendPortSync) && (_id == other._id);
-  }
-
-  int get hashCode => _id;
-}
-
-// TODO(vsm): Differentiate between Dart2Js and Dartium isolates.
-// The receiver is a different Dart isolate, compiled to JS.
-class _RemoteSendPortSync implements SendPortSync {
-
-  int _isolateId;
-  int _portId;
-  _RemoteSendPortSync(this._isolateId, this._portId);
-
-  callSync(var message) {
-    var serialized = _serialize(message);
-    var result = _call(_isolateId, _portId, serialized);
-    return _deserialize(result);
-  }
-
-  static _call(int isolateId, int portId, var message) {
-    var target = 'dart-port-$isolateId-$portId';
-    // TODO(vsm): Make this re-entrant.
-    // TODO(vsm): Set this up set once, on the first call.
-    var source = '$target-result';
-    var result = null;
-    window.on[source].first.then((Event e) {
-      result = JSON.decode(_getPortSyncEventData(e));
-    });
-    _dispatchEvent(target, [source, message]);
-    return result;
-  }
-
-  bool operator==(var other) {
-    return (other is _RemoteSendPortSync) && (_isolateId == other._isolateId)
-      && (_portId == other._portId);
-  }
-
-  int get hashCode => _isolateId >> 16 + _portId;
-}
-
-// The receiver is in the same Dart isolate, compiled to JS.
-class _LocalSendPortSync implements SendPortSync {
-
-  ReceivePortSync _receivePort;
-
-  _LocalSendPortSync._internal(this._receivePort);
-
-  callSync(var message) {
-    // TODO(vsm): Do a more efficient deep copy.
-    var copy = _deserialize(_serialize(message));
-    var result = _receivePort._callback(copy);
-    return _deserialize(_serialize(result));
-  }
-
-  bool operator==(var other) {
-    return (other is _LocalSendPortSync)
-      && (_receivePort == other._receivePort);
-  }
-
-  int get hashCode => _receivePort.hashCode;
-}
-
-// TODO(vsm): Move this to dart:isolate.  This will take some
-// refactoring as there are dependences here on the DOM.  Users
-// interact with this class (or interface if we change it) directly -
-// new ReceivePortSync.  I think most of the DOM logic could be
-// delayed until the corresponding SendPort is registered on the
-// window.
-
-// A Dart ReceivePortSync (tagged 'dart' when serialized) is
-// identifiable / resolvable by the combination of its isolateid and
-// portid.  When a corresponding SendPort is used within the same
-// isolate, the _portMap below can be used to obtain the
-// ReceivePortSync directly.  Across isolates (or from JS), an
-// EventListener can be used to communicate with the port indirectly.
-class ReceivePortSync {
-
-  static Map<int, ReceivePortSync> _portMap;
-  static int _portIdCount;
-  static int _cachedIsolateId;
-
-  num _portId;
-  Function _callback;
-  StreamSubscription _portSubscription;
-
-  ReceivePortSync() {
-    if (_portIdCount == null) {
-      _portIdCount = 0;
-      _portMap = new Map<int, ReceivePortSync>();
-    }
-    _portId = _portIdCount++;
-    _portMap[_portId] = this;
-  }
-
-  static int get _isolateId {
-    // TODO(vsm): Make this coherent with existing isolate code.
-    if (_cachedIsolateId == null) {
-      _cachedIsolateId = _getNewIsolateId();
-    }
-    return _cachedIsolateId;
-  }
-
-  static String _getListenerName(isolateId, portId) =>
-      'dart-port-$isolateId-$portId';
-  String get _listenerName => _getListenerName(_isolateId, _portId);
-
-  void receive(callback(var message)) {
-    _callback = callback;
-    if (_portSubscription == null) {
-      _portSubscription = window.on[_listenerName].listen((Event e) {
-        var data = JSON.decode(_getPortSyncEventData(e));
-        var replyTo = data[0];
-        var message = _deserialize(data[1]);
-        var result = _callback(message);
-        _dispatchEvent(replyTo, _serialize(result));
-      });
-    }
-  }
-
-  void close() {
-    _portMap.remove(_portId);
-    if (_portSubscription != null) _portSubscription.cancel();
-  }
-
-  SendPortSync toSendPort() {
-    return new _LocalSendPortSync._internal(this);
-  }
-
-  static SendPortSync _lookup(int isolateId, int portId) {
-    if (isolateId == _isolateId) {
-      return _portMap[portId].toSendPort();
-    } else {
-      return new _RemoteSendPortSync(isolateId, portId);
-    }
-  }
-}
-
-get _isolateId => ReceivePortSync._isolateId;
-
-void _dispatchEvent(String receiver, var message) {
-  var event = new CustomEvent(receiver, canBubble: false, cancelable:false,
-    detail: JSON.encode(message));
-  window.dispatchEvent(event);
-}
-
-String _getPortSyncEventData(CustomEvent event) => event.detail;
diff --git a/tools/dom/src/Serialization.dart b/tools/dom/src/Serialization.dart
deleted file mode 100644
index df29f58..0000000
--- a/tools/dom/src/Serialization.dart
+++ /dev/null
@@ -1,180 +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.
-
-// Patch file for the dart:isolate library.
-
-part of html;
-
-/********************************************************
-  Inserted from lib/isolate/serialization.dart
- ********************************************************/
-
-class _MessageTraverserVisitedMap {
-
-  operator[](var object) => null;
-  void operator[]=(var object, var info) { }
-
-  void reset() { }
-  void cleanup() { }
-
-}
-
-/** Abstract visitor for dart objects that can be sent as isolate messages. */
-abstract class _MessageTraverser {
-
-  _MessageTraverserVisitedMap _visited;
-  _MessageTraverser() : _visited = new _MessageTraverserVisitedMap();
-
-  /** Visitor's entry point. */
-  traverse(var x) {
-    if (isPrimitive(x)) return visitPrimitive(x);
-    _visited.reset();
-    var result;
-    try {
-      result = _dispatch(x);
-    } finally {
-      _visited.cleanup();
-    }
-    return result;
-  }
-
-  _dispatch(var x) {
-    if (isPrimitive(x)) return visitPrimitive(x);
-    if (x is List) return visitList(x);
-    if (x is Map) return visitMap(x);
-    if (x is SendPort) return visitSendPort(x);
-    if (x is SendPortSync) return visitSendPortSync(x);
-
-    // Overridable fallback.
-    return visitObject(x);
-  }
-
-  visitPrimitive(x);
-  visitList(List x);
-  visitMap(Map x);
-  visitSendPort(SendPort x);
-  visitSendPortSync(SendPortSync x);
-
-  visitObject(Object x) {
-    // TODO(floitsch): make this a real exception. (which one)?
-    throw "Message serialization: Illegal value $x passed";
-  }
-
-  static bool isPrimitive(x) {
-    return (x == null) || (x is String) || (x is num) || (x is bool);
-  }
-}
-
-
-/** Visitor that serializes a message as a JSON array. */
-abstract class _Serializer extends _MessageTraverser {
-  int _nextFreeRefId = 0;
-
-  visitPrimitive(x) => x;
-
-  visitList(List list) {
-    int copyId = _visited[list];
-    if (copyId != null) return ['ref', copyId];
-
-    int id = _nextFreeRefId++;
-    _visited[list] = id;
-    var jsArray = _serializeList(list);
-    // TODO(floitsch): we are losing the generic type.
-    return ['list', id, jsArray];
-  }
-
-  visitMap(Map map) {
-    int copyId = _visited[map];
-    if (copyId != null) return ['ref', copyId];
-
-    int id = _nextFreeRefId++;
-    _visited[map] = id;
-    var keys = _serializeList(map.keys.toList());
-    var values = _serializeList(map.values.toList());
-    // TODO(floitsch): we are losing the generic type.
-    return ['map', id, keys, values];
-  }
-
-  _serializeList(List list) {
-    int len = list.length;
-    var result = new List(len);
-    for (int i = 0; i < len; i++) {
-      result[i] = _dispatch(list[i]);
-    }
-    return result;
-  }
-}
-
-/** Deserializes arrays created with [_Serializer]. */
-abstract class _Deserializer {
-  Map<int, dynamic> _deserialized;
-
-  _Deserializer();
-
-  static bool isPrimitive(x) {
-    return (x == null) || (x is String) || (x is num) || (x is bool);
-  }
-
-  deserialize(x) {
-    if (isPrimitive(x)) return x;
-    // TODO(floitsch): this should be new HashMap<int, dynamic>()
-    _deserialized = new HashMap();
-    return _deserializeHelper(x);
-  }
-
-  _deserializeHelper(x) {
-    if (isPrimitive(x)) return x;
-    assert(x is List);
-    switch (x[0]) {
-      case 'ref': return _deserializeRef(x);
-      case 'list': return _deserializeList(x);
-      case 'map': return _deserializeMap(x);
-      case 'sendport': return deserializeSendPort(x);
-      default: return deserializeObject(x);
-    }
-  }
-
-  _deserializeRef(List x) {
-    int id = x[1];
-    var result = _deserialized[id];
-    assert(result != null);
-    return result;
-  }
-
-  List _deserializeList(List x) {
-    int id = x[1];
-    // We rely on the fact that Dart-lists are directly mapped to Js-arrays.
-    List dartList = x[2];
-    _deserialized[id] = dartList;
-    int len = dartList.length;
-    for (int i = 0; i < len; i++) {
-      dartList[i] = _deserializeHelper(dartList[i]);
-    }
-    return dartList;
-  }
-
-  Map _deserializeMap(List x) {
-    Map result = new Map();
-    int id = x[1];
-    _deserialized[id] = result;
-    List keys = x[2];
-    List values = x[3];
-    int len = keys.length;
-    assert(len == values.length);
-    for (int i = 0; i < len; i++) {
-      var key = _deserializeHelper(keys[i]);
-      var value = _deserializeHelper(values[i]);
-      result[key] = value;
-    }
-    return result;
-  }
-
-  deserializeSendPort(List x);
-
-  deserializeObject(List x) {
-    // TODO(floitsch): Use real exception (which one?).
-    throw "Unexpected serialized object";
-  }
-}
-
diff --git a/tools/dom/src/native_DOMImplementation.dart b/tools/dom/src/native_DOMImplementation.dart
index 46b4e71..43d542f 100644
--- a/tools/dom/src/native_DOMImplementation.dart
+++ b/tools/dom/src/native_DOMImplementation.dart
@@ -125,7 +125,6 @@
 
   static window() native "Utils_window";
   static forwardingPrint(String message) native "Utils_forwardingPrint";
-  static int _getNewIsolateId() native "Utils_getNewIsolateId";
 
   // The following methods were added for debugger integration to make working
   // with the Dart C mirrors API simpler.
diff --git a/tools/dom/templates/html/dart2js/html_dart2js.darttemplate b/tools/dom/templates/html/dart2js/html_dart2js.darttemplate
index 146645c..0d2150d 100644
--- a/tools/dom/templates/html/dart2js/html_dart2js.darttemplate
+++ b/tools/dom/templates/html/dart2js/html_dart2js.darttemplate
@@ -72,14 +72,12 @@
 part '$AUXILIARY_DIR/EventStreamProvider.dart';
 part '$AUXILIARY_DIR/Html5NodeValidator.dart';
 part '$AUXILIARY_DIR/ImmutableListMixin.dart';
-part '$AUXILIARY_DIR/Isolates.dart';
 part '$AUXILIARY_DIR/KeyCode.dart';
 part '$AUXILIARY_DIR/KeyLocation.dart';
 part '$AUXILIARY_DIR/KeyName.dart';
 part '$AUXILIARY_DIR/KeyboardEventStream.dart';
 part '$AUXILIARY_DIR/NodeValidatorBuilder.dart';
 part '$AUXILIARY_DIR/ReadyState.dart';
-part '$AUXILIARY_DIR/Serialization.dart';
 part '$AUXILIARY_DIR/WrappedEvent.dart';
 part '$AUXILIARY_DIR/WrappedList.dart';
 part '$AUXILIARY_DIR/_HttpRequestUtils.dart';
@@ -131,16 +129,3 @@
 // older Chrome versions.
 // Issue #12573.
 abstract class _EntryArray implements List<Entry> native "EntryArray" {}
-
-// Support for Send/ReceivePortSync.
-int _getNewIsolateId() {
-  if (JS('bool', r'!window.$dart$isolate$counter')) {
-    JS('void', r'window.$dart$isolate$counter = 1');
-  }
-  return JS('int', r'window.$dart$isolate$counter++');
-}
-
-// Fast path to invoke JS send port.
-_callPortSync(int id, message) {
-  return JS('var', r'ReceivePortSync.dispatchCall(#, #)', id, message);
-}
diff --git a/tools/dom/templates/html/dartium/html_dartium.darttemplate b/tools/dom/templates/html/dartium/html_dartium.darttemplate
index 0ee99a3..44b1990 100644
--- a/tools/dom/templates/html/dartium/html_dartium.darttemplate
+++ b/tools/dom/templates/html/dartium/html_dartium.darttemplate
@@ -66,14 +66,12 @@
 part '$AUXILIARY_DIR/EventStreamProvider.dart';
 part '$AUXILIARY_DIR/Html5NodeValidator.dart';
 part '$AUXILIARY_DIR/ImmutableListMixin.dart';
-part '$AUXILIARY_DIR/Isolates.dart';
 part '$AUXILIARY_DIR/KeyCode.dart';
 part '$AUXILIARY_DIR/KeyLocation.dart';
 part '$AUXILIARY_DIR/KeyName.dart';
 part '$AUXILIARY_DIR/KeyboardEventStream.dart';
 part '$AUXILIARY_DIR/NodeValidatorBuilder.dart';
 part '$AUXILIARY_DIR/ReadyState.dart';
-part '$AUXILIARY_DIR/Serialization.dart';
 part '$AUXILIARY_DIR/Validators.dart';
 part '$AUXILIARY_DIR/WrappedList.dart';
 part '$AUXILIARY_DIR/_HttpRequestUtils.dart';
@@ -119,22 +117,3 @@
   _document = window.document;
   return _document;
 }
-
-int _getNewIsolateId() => _Utils._getNewIsolateId();
-
-bool _callPortInitialized = false;
-var _callPortLastResult = null;
-
-_callPortSync(num id, var message) {
-  if (!_callPortInitialized) {
-    window.on['js-result'].listen((event) {
-      _callPortLastResult = JSON.decode(_getPortSyncEventData(event));
-    });
-    _callPortInitialized = true;
-  }
-  assert(_callPortLastResult == null);
-  _dispatchEvent('js-sync-message', {'id': id, 'message': message});
-  var result = _callPortLastResult;
-  _callPortLastResult = null;
-  return result;
-}
diff --git a/tools/dom/templates/html/impl/impl_Window.darttemplate b/tools/dom/templates/html/impl/impl_Window.darttemplate
index a0211c8..499694f 100644
--- a/tools/dom/templates/html/impl/impl_Window.darttemplate
+++ b/tools/dom/templates/html/impl/impl_Window.darttemplate
@@ -12,39 +12,6 @@
 $endif
 
   /**
-   * Lookup a port by its [name].  Return null if no port is
-   * registered under [name].
-   */
-  SendPortSync lookupPort(String name) {
-    var portStr = document.documentElement.attributes['dart-port:$name'];
-    if (portStr == null) {
-      return null;
-    }
-    var port = JSON.decode(portStr);
-    return _deserialize(port);
-  }
-
-  /**
-   * Register a [port] on this window under the given [name].  This
-   * port may be retrieved by any isolate (or JavaScript script)
-   * running in this window.
-   */
-  void registerPort(String name, var port) {
-    var serialized = _serialize(port);
-    document.documentElement.attributes['dart-port:$name'] =
-        JSON.encode(serialized);
-  }
-
-  /**
-   * Deregister a [port] on this window under the given [name].  This
-   * port may be retrieved by any isolate (or JavaScript script)
-   * running in this window.
-   */
-  void deregisterPort(String name) {
-    document.documentElement.attributes.remove('dart-port:$name');
-  }
-
-  /**
    * Returns a Future that completes just before the window is about to
    * repaint so the user can draw an animation frame.
    *
