Merge pull request #827 from jamesr/mojo_roll_d259eb58aa59e14a13d5e0dc3984b855b475ba09

Update to mojo d259eb58aa59e14a13d5e0dc3984b855b475ba09
diff --git a/.gitignore b/.gitignore
index ed086d9..8719095 100644
--- a/.gitignore
+++ b/.gitignore
@@ -67,6 +67,8 @@
 /examples/**/pubspec.lock
 /mojo/common/dart/packages
 /mojo/dart/apptest/packages
+/mojo/dart/http_load_test/bin/packages
+/mojo/dart/http_load_test/packages/
 /mojo/dart/mojo_services/packages
 /mojo/dart/mojo_services/pubspec.lock
 /mojo/dart/mojom/bin/packages
diff --git a/DEPS b/DEPS
index b7e418a..c67163d 100644
--- a/DEPS
+++ b/DEPS
@@ -19,7 +19,7 @@
 
 vars = {
   'chromium_git': 'https://chromium.googlesource.com',
-  'mojo_sdk_revision': '9a5f81a3d2a6d027677366edb5de3ae85f6dbf16',
+  'mojo_sdk_revision': '76ff57433b48527dc491dac4c52c9d71a7c3a0e3',
   'skia_revision': '29ccdf86ab0a1649fd775c9431891bacb1391e99',
   'dart_revision': '95c951ad190f156eb61b99203c2e4948211c44a7',
   'dart_observatory_packages_revision': 'cdc4b3d4c15b9c0c8e7702dff127b440afbb7485',
diff --git a/gpu/command_buffer/build_gles2_cmd_buffer.py b/gpu/command_buffer/build_gles2_cmd_buffer.py
index 9887d8f..6c1f622 100755
--- a/gpu/command_buffer/build_gles2_cmd_buffer.py
+++ b/gpu/command_buffer/build_gles2_cmd_buffer.py
@@ -32,6 +32,17 @@
 
 """
 
+_MOJO_EXPOSED_EXTENSIONS = ["CHROMIUM_bind_uniform_location",
+                            "CHROMIUM_map_sub",
+                            "CHROMIUM_miscellaneous",
+                            "CHROMIUM_resize",
+                            "CHROMIUM_sync_point",
+                            "CHROMIUM_texture_mailbox",
+                            "EXT_debug_marker",
+                            "OES_vertex_array_object",
+                            "occlusion_query_EXT"]
+
+
 # This string is copied directly out of the gl2.h file from GLES2.0
 #
 # Edits:
@@ -2803,14 +2814,14 @@
   },
   'MapBufferSubDataCHROMIUM': {
     'gen_cmd': False,
-    'extension': True,
+    'extension': "CHROMIUM_map_sub",
     'chromium': True,
     'client_test': False,
     'pepper_interface': 'ChromiumMapSub',
   },
   'MapTexSubImage2DCHROMIUM': {
     'gen_cmd': False,
-    'extension': "CHROMIUM_sub_image",
+    'extension': "CHROMIUM_map_sub",
     'chromium': True,
     'client_test': False,
     'pepper_interface': 'ChromiumMapSub',
@@ -3205,7 +3216,7 @@
   },
   'UnmapBufferSubDataCHROMIUM': {
     'gen_cmd': False,
-    'extension': True,
+    'extension': "CHROMIUM_map_sub",
     'chromium': True,
     'client_test': False,
     'pepper_interface': 'ChromiumMapSub',
@@ -3216,7 +3227,7 @@
   },
   'UnmapTexSubImage2DCHROMIUM': {
     'gen_cmd': False,
-    'extension': "CHROMIUM_sub_image",
+    'extension': "CHROMIUM_map_sub",
     'chromium': True,
     'client_test': False,
     'pepper_interface': 'ChromiumMapSub',
@@ -3454,7 +3465,7 @@
   },
   'BindUniformLocationCHROMIUM': {
     'type': 'GLchar',
-    'extension': True,
+    'extension': "CHROMIUM_bind_uniform_location",
     'data_transfer_methods': ['bucket'],
     'needs_size': True,
     'gl_test_func': 'DoBindUniformLocationCHROMIUM',
@@ -4350,25 +4361,15 @@
     file.Write("%s MojoGLES2Impl::%s(%s) {\n" %
                (func.return_type, func.original_name,
                 func.MakeTypedOriginalArgString("")))
-    # TODO(alhaad): Add Mojo C thunk for each of the following methods and
-    # remove this.
-    func_list = ["GenQueriesEXT", "BeginQueryEXT", "MapTexSubImage2DCHROMIUM",
-                 "UnmapTexSubImage2DCHROMIUM", "DeleteQueriesEXT",
-                 "EndQueryEXT", "GetQueryObjectuivEXT", "ShallowFlushCHROMIUM"]
-    if func.original_name in func_list:
-      file.Write("return static_cast<gpu::gles2::GLES2Interface*>"
-                 "(MojoGLES2GetGLES2Interface(context_))->" +
-                 func.original_name + "(" + func.MakeOriginalArgString("") +
-                 ");")
-      file.Write("}")
-      return
 
-    extensions = ["CHROMIUM_sync_point", "CHROMIUM_texture_mailbox"]
-    if func.IsCoreGLFunction() or func.GetInfo("extension") in extensions:
+    is_mojo_extension = func.GetInfo("extension") in _MOJO_EXPOSED_EXTENSIONS
+    if func.IsCoreGLFunction() or is_mojo_extension:
       file.Write("MojoGLES2MakeCurrent(context_);");
       func_return = "gl" + func.original_name + "(" + \
           func.MakeOriginalArgString("") + ");"
-      if func.return_type == "void":
+      if func.original_name == "ResizeCHROMIUM":
+          file.Write("MGLResizeSurface(width, height);");
+      elif func.return_type == "void":
         file.Write(func_return);
       else:
         file.Write("return " + func_return);
@@ -10186,9 +10187,16 @@
 #include "mojo/gpu/mojo_gles2_impl_autogen.h"
 
 #include "base/logging.h"
+#include "mojo/public/c/gles2/chromium_bind_uniform_location.h"
+#include "mojo/public/c/gles2/chromium_map_sub.h"
+#include "mojo/public/c/gles2/chromium_miscellaneous.h"
 #include "mojo/public/c/gles2/chromium_sync_point.h"
 #include "mojo/public/c/gles2/chromium_texture_mailbox.h"
+#include "mojo/public/c/gles2/ext_debug_marker.h"
 #include "mojo/public/c/gles2/gles2.h"
+#include "mojo/public/c/gles2/occlusion_query_ext.h"
+#include "mojo/public/c/gles2/oes_vertex_array_object.h"
+#include "mojo/public/c/gpu/MGL/mgl_onscreen.h"
 
 namespace mojo {
 
@@ -10585,10 +10593,6 @@
     "gpu/command_buffer/common/gles2_cmd_format_test_autogen.h")
   gen.WriteGLES2InterfaceHeader(
     "gpu/command_buffer/client/gles2_interface_autogen.h")
-  gen.WriteMojoGLES2ImplHeader(
-    "mojo/gpu/mojo_gles2_impl_autogen.h")
-  gen.WriteMojoGLES2Impl(
-    "mojo/gpu/mojo_gles2_impl_autogen.cc")
   gen.WriteGLES2InterfaceStub(
     "gpu/command_buffer/client/gles2_interface_stub_autogen.h")
   gen.WriteGLES2InterfaceStubImpl(
@@ -10632,16 +10636,18 @@
   gen.WriteCommonUtilsImpl(
     "gpu/command_buffer/common/gles2_cmd_utils_implementation_autogen.h")
   gen.WriteGLES2Header("gpu/GLES2/gl2chromium_autogen.h")
+
   mojo_gles2_prefix = ("mojo/public/c/gles2/gles2_call_visitor")
   gen.WriteMojoGLCallVisitor(mojo_gles2_prefix + "_autogen.h")
-  mojo_extensions = ["CHROMIUM_texture_mailbox", "CHROMIUM_sync_point",
-                     "CHROMIUM_sub_image", "CHROMIUM_miscellaneous",
-                     "CHROMIUM_resize", "EXT_debug_marker",
-                     "OES_vertex_array_object", "occlusion_query_EXT"]
-  for extension in mojo_extensions:
+  for extension in _MOJO_EXPOSED_EXTENSIONS:
     gen.WriteMojoGLCallVisitorForExtension(
         mojo_gles2_prefix + "_" + extension.lower() + "_autogen.h", extension)
 
+  gen.WriteMojoGLES2ImplHeader(
+    "mojo/gpu/mojo_gles2_impl_autogen.h")
+  gen.WriteMojoGLES2Impl(
+    "mojo/gpu/mojo_gles2_impl_autogen.cc")
+
   Format(gen.generated_cpp_filenames)
 
   if gen.errors > 0:
diff --git a/gpu/command_buffer/service/gl_surface_mock.h b/gpu/command_buffer/service/gl_surface_mock.h
index 0652be6..97c8a09 100644
--- a/gpu/command_buffer/service/gl_surface_mock.h
+++ b/gpu/command_buffer/service/gl_surface_mock.h
@@ -5,8 +5,9 @@
 #ifndef GPU_COMMAND_BUFFER_SERVICE_GL_SURFACE_MOCK_H_
 #define GPU_COMMAND_BUFFER_SERVICE_GL_SURFACE_MOCK_H_
 
-#include "ui/gl/gl_surface.h"
 #include "testing/gmock/include/gmock/gmock.h"
+#include "ui/gfx/swap_result.h"
+#include "ui/gl/gl_surface.h"
 
 namespace gpu {
 
@@ -18,8 +19,8 @@
   MOCK_METHOD0(Destroy, void());
   MOCK_METHOD1(Resize, bool(const gfx::Size& size));
   MOCK_METHOD0(IsOffscreen, bool());
-  MOCK_METHOD0(SwapBuffers, bool());
-  MOCK_METHOD4(PostSubBuffer, bool(int x, int y, int width, int height));
+  MOCK_METHOD0(SwapBuffers, gfx::SwapResult());
+  MOCK_METHOD4(PostSubBuffer, gfx::SwapResult(int x, int y, int width, int height));
   MOCK_METHOD0(SupportsPostSubBuffer, bool());
   MOCK_METHOD0(GetSize, gfx::Size());
   MOCK_METHOD0(GetHandle, void*());
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc
index f782d52..61ad037 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc
@@ -8222,7 +8222,8 @@
     gpu_state_tracer_->TakeSnapshotWithCurrentFramebuffer(
         is_offscreen ? offscreen_size_ : surface_->GetSize());
   }
-  if (surface_->PostSubBuffer(c.x, c.y, c.width, c.height)) {
+  if (surface_->PostSubBuffer(c.x, c.y, c.width, c.height) !=
+      gfx::SwapResult::SWAP_FAILED) {
     return error::kNoError;
   } else {
     LOG(ERROR) << "Context lost because PostSubBuffer failed.";
@@ -10347,7 +10348,7 @@
         glFlush();
     }
   } else {
-    if (!surface_->SwapBuffers()) {
+    if (surface_->SwapBuffers() == gfx::SwapResult::SWAP_FAILED) {
       LOG(ERROR) << "Context lost because SwapBuffers failed.";
       if (!CheckResetStatus()) {
         MarkContextLost(error::kUnknown);
diff --git a/mojo/BUILD.gn b/mojo/BUILD.gn
deleted file mode 100644
index 7f55975..0000000
--- a/mojo/BUILD.gn
+++ /dev/null
@@ -1,111 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import("//build/config/ui.gni")
-import("//build/module_args/mojo.gni")
-import("//mojo/public/mojo.gni")
-
-# TODO(beng): this meta target should probably move to the root dir's BUILD.gn.
-group("mojo") {
-  # Meta-target, don't link into production code.
-  testonly = true
-  declare_args() {
-    mojo_use_go = false
-
-    # TODO(ncbray): support ASAN once NaCl's GN build is unforked.
-    mojo_use_nacl = is_linux && !is_asan
-  }
-  deps = [
-    ":tests",
-    "//benchmarks",
-    "//examples",
-    "//mojo/common",
-    "//mojo/dart/apptest",
-    "//mojo/dart/apptest:apptest_pkg",
-    "//mojo/dart/mojom",
-    "//mojo/dart/mojo_services",
-    "//mojo/dart/observatory_test",
-    "//mojo/public",
-    "//mojo/services",
-    "//services",
-  ]
-
-  if (is_android) {
-    deps += [
-      "//mojo/android",
-      "//mojo/java",
-      "//mojo/tools/android_shortcuts",
-      "//mojo/tools:remote_file_reader",
-    ]
-  }
-
-  if (is_linux && mojo_use_go) {
-    deps += [ "//mojo/go" ]
-  }
-
-  if (is_linux) {
-    deps += [ "//mojo/python" ]
-  }
-
-  if (mojo_use_nacl) {
-    deps += [
-      "//mojo/nacl:mojo_nacl",
-      "//mojo/nacl:mojo_nacl_tests",
-    ]
-  }
-}
-
-group("tests") {
-  testonly = true
-  deps = [
-    "//mojo/common:mojo_common_unittests",
-    "//mojo/converters/surfaces/tests:mojo_surfaces_lib_unittests",
-    "//mojo/edk/system:tests",
-    "//mojo/edk/test:public_tests",
-    "//mojo/dart/embedder/test:dart_unittests",
-    "//mojo/public/cpp/bindings/tests:versioning_apptests",
-    "//mojo/services/view_manager/public/cpp/tests:mojo_view_manager_lib_unittests",
-    "//mojo/tests:mojo_task_tracker_perftests",
-    "//mojo/tools:message_generator",
-    "//services/asset_bundle:apptests",
-    "//services/clipboard:apptests",
-    "//services/dart/dart_apptests",
-    "//services/files:apptests",
-    "//mojo/gpu:apptests",
-    "//mojo/services/files/public/c:apptests",
-    "//services/authenticating_url_loader_interceptor:apptests",
-    "//services/http_server:apptests",
-    "//services/prediction:apptests",
-    "//services/reaper:tests",
-    "//services/url_response_disk_cache:tests",
-    "//services/view_manager:mojo_view_manager_client_apptests",
-    "//services/view_manager:view_manager_service_apptests",
-    "//services/view_manager:view_manager_service_unittests",
-    "//services/window_manager:window_manager_apptests",
-    "//services/window_manager:window_manager_unittests",
-    "//shell:apptests",
-  ]
-
-  if (is_linux) {
-    deps += [ "//services/python:python_apptests" ]
-  }
-
-  if (is_android) {
-    deps += [ "//services/notifications:apptests" ]
-  }
-
-  # TODO(jamesr): We only support building V8 snapshot data on a linux host since it
-  # needs a 32 bit toolchain and we don't have one configured for mac hosts.
-  if (host_os == "linux") {
-    deps += [
-      "//mojo/edk/js:tests",
-      "//services/js:js_apptests",
-      "//services/js:js_services_unittests",
-    ]
-  }
-
-  if (mojo_use_prebuilt_network_service) {
-    deps += [ "//mojo/public/tools:copy_network_service_apptests" ]
-  }
-}
diff --git a/mojo/OWNERS b/mojo/OWNERS
deleted file mode 100644
index b864087..0000000
--- a/mojo/OWNERS
+++ /dev/null
@@ -1,11 +0,0 @@
-aa@chromium.org
-abarth@chromium.org
-ben@chromium.org
-darin@chromium.org
-davemoore@chromium.org
-jamesr@chromium.org
-mpcomplete@chromium.org
-qsr@chromium.org
-sky@chromium.org
-viettrungluu@chromium.org
-yzshen@chromium.org
diff --git a/mojo/PRESUBMIT.py b/mojo/PRESUBMIT.py
deleted file mode 100644
index 444a372..0000000
--- a/mojo/PRESUBMIT.py
+++ /dev/null
@@ -1,288 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Presubmit script for mojo
-
-See http://dev.chromium.org/developers/how-tos/depottools/presubmit-scripts
-for more details about the presubmit API built into depot_tools.
-"""
-
-import os.path
-import re
-
-# NOTE: The EDK allows all external paths, so doesn't need a whitelist.
-_PACKAGE_WHITELISTED_EXTERNAL_PATHS = {
-    "SDK": ["//build/module_args/mojo.gni",
-            "//build/module_args/dart.gni",
-            "//testing/gtest",
-            "//third_party/cython",
-            "//third_party/khronos"],
-    "services": ["//build/module_args/mojo.gni",
-                 "//testing/gtest"],
-}
-
-# These files are not part of the exported package.
-_PACKAGE_IGNORED_BUILD_FILES = {
-    "SDK": {},
-    "EDK": {},
-    "services": {"mojo/services/BUILD.gn"},
-}
-
-
-_PACKAGE_PATH_PREFIXES = {"SDK": "mojo/public/",
-                          "EDK": "mojo/edk/",
-                          "services": "mojo/services"}
-
-# TODO(etiennej): python_binary_source_set added due to crbug.com/443147
-_PACKAGE_SOURCE_SET_TYPES = {"SDK": ["mojo_sdk_source_set",
-                                     "python_binary_source_set"],
-                             "EDK": ["mojo_edk_source_set"],
-                             "services": ["mojo_sdk_source_set"]}
-
-_ILLEGAL_EXTERNAL_PATH_WARNING_MESSAGE = \
-    "Found disallowed external paths within SDK buildfiles."
-
-_ILLEGAL_SERVICES_ABSOLUTE_PATH_WARNING_MESSAGE = \
-    "Found references to services' public buildfiles via absolute paths " \
-    "within services' public buildfiles."
-
-_ILLEGAL_EDK_ABSOLUTE_PATH_WARNING_MESSAGE = \
-    "Found references to the EDK via absolute paths within EDK buildfiles."
-
-_ILLEGAL_SDK_ABSOLUTE_PATH_WARNING_MESSAGE_TEMPLATE = \
-    "Found references to the SDK via absolute paths within %s buildfiles."
-
-_ILLEGAL_SDK_ABSOLUTE_PATH_WARNING_MESSAGES = {
-  "SDK": _ILLEGAL_SDK_ABSOLUTE_PATH_WARNING_MESSAGE_TEMPLATE % "SDK",
-  "EDK": _ILLEGAL_SDK_ABSOLUTE_PATH_WARNING_MESSAGE_TEMPLATE % "EDK",
-  "services": _ILLEGAL_SDK_ABSOLUTE_PATH_WARNING_MESSAGE_TEMPLATE
-      % "services' public",
-}
-
-_INCORRECT_SOURCE_SET_TYPE_WARNING_MESSAGE_TEMPLATE = \
-    "All source sets in %s must be constructed via %s."
-
-_INCORRECT_SOURCE_SET_TYPE_WARNING_MESSAGES = {
-  "SDK": _INCORRECT_SOURCE_SET_TYPE_WARNING_MESSAGE_TEMPLATE
-      % ("the SDK", _PACKAGE_SOURCE_SET_TYPES["SDK"]),
-  "EDK": _INCORRECT_SOURCE_SET_TYPE_WARNING_MESSAGE_TEMPLATE
-      % ("the EDK", _PACKAGE_SOURCE_SET_TYPES["EDK"]),
-  "services": _INCORRECT_SOURCE_SET_TYPE_WARNING_MESSAGE_TEMPLATE
-      % ("services' client libs", _PACKAGE_SOURCE_SET_TYPES["services"]),
-}
-
-def _IsBuildFileWithinPackage(f, package):
-  """Returns whether |f| specifies a GN build file within |package|."""
-  assert package in _PACKAGE_PATH_PREFIXES
-  package_path_prefix = _PACKAGE_PATH_PREFIXES[package]
-
-  if not f.LocalPath().startswith(package_path_prefix):
-    return False
-  if (not f.LocalPath().endswith("/BUILD.gn") and
-      not f.LocalPath().endswith(".gni")):
-    return False
-  if f.LocalPath() in _PACKAGE_IGNORED_BUILD_FILES[package]:
-    return False
-  return True
-
-def _AffectedBuildFilesWithinPackage(input_api, package):
-  """Returns all the affected build files within |package|."""
-  return [f for f in input_api.AffectedFiles()
-      if _IsBuildFileWithinPackage(f, package)]
-
-def _FindIllegalAbsolutePathsInBuildFiles(input_api, package):
-  """Finds illegal absolute paths within the build files in
-  |input_api.AffectedFiles()| that are within |package|.
-  An illegal absolute path within the SDK or a service's SDK is one that is to
-  the SDK itself or a non-whitelisted external path. An illegal absolute path
-  within the EDK is one that is to the SDK or the EDK.
-  Returns any such references in a list of (file_path, line_number,
-  referenced_path) tuples."""
-  illegal_references = []
-  for f in _AffectedBuildFilesWithinPackage(input_api, package):
-    for line_num, line in f.ChangedContents():
-      # Determine if this is a reference to an absolute path.
-      m = re.search(r'"(//[^"]*)"', line)
-      if not m:
-        continue
-      referenced_path = m.group(1)
-
-      if not referenced_path.startswith("//mojo"):
-        # In the EDK, all external absolute paths are allowed.
-        if package == "EDK":
-          continue
-
-        # Determine if this is a whitelisted external path.
-        if referenced_path in _PACKAGE_WHITELISTED_EXTERNAL_PATHS[package]:
-          continue
-
-      illegal_references.append((f.LocalPath(), line_num, referenced_path))
-
-  return illegal_references
-
-def _PathReferenceInBuildFileWarningItem(build_file, line_num, referenced_path):
-  """Returns a string expressing a warning item that |referenced_path| is
-  referenced at |line_num| in |build_file|."""
-  return "%s, line %d (%s)" % (build_file, line_num, referenced_path)
-
-def _IncorrectSourceSetTypeWarningItem(build_file, line_num):
-  """Returns a string expressing that the error occurs at |line_num| in
-  |build_file|."""
-  return "%s, line %d" % (build_file, line_num)
-
-def _CheckNoIllegalAbsolutePathsInBuildFiles(input_api, output_api, package):
-  """Makes sure that the BUILD.gn files within |package| do not reference the
-  SDK/EDK via absolute paths, and do not reference disallowed external
-  dependencies."""
-  sdk_references = []
-  edk_references = []
-  external_deps_references = []
-  services_references = []
-
-  # Categorize any illegal references.
-  illegal_references = _FindIllegalAbsolutePathsInBuildFiles(input_api, package)
-  for build_file, line_num, referenced_path in illegal_references:
-    reference_string = _PathReferenceInBuildFileWarningItem(build_file,
-                                                            line_num,
-                                                            referenced_path)
-    if referenced_path.startswith("//mojo/public"):
-      sdk_references.append(reference_string)
-    elif package == "SDK":
-      external_deps_references.append(reference_string)
-    elif package == "services":
-      if referenced_path.startswith("//mojo/services"):
-        services_references.append(reference_string)
-      else:
-        external_deps_references.append(reference_string)
-    elif referenced_path.startswith("//mojo/edk"):
-      edk_references.append(reference_string)
-
-  # Package up categorized illegal references into results.
-  results = []
-  if sdk_references:
-    results.extend([output_api.PresubmitError(
-        _ILLEGAL_SDK_ABSOLUTE_PATH_WARNING_MESSAGES[package],
-        items=sdk_references)])
-
-  if external_deps_references:
-    assert package == "SDK" or package == "services"
-    results.extend([output_api.PresubmitError(
-        _ILLEGAL_EXTERNAL_PATH_WARNING_MESSAGE,
-        items=external_deps_references)])
-
-  if services_references:
-    assert package == "services"
-    results.extend([output_api.PresubmitError(
-        _ILLEGAL_SERVICES_ABSOLUTE_PATH_WARNING_MESSAGE,
-        items=services_references)])
-
-  if edk_references:
-    assert package == "EDK"
-    results.extend([output_api.PresubmitError(
-        _ILLEGAL_EDK_ABSOLUTE_PATH_WARNING_MESSAGE,
-        items=edk_references)])
-
-  return results
-
-def _CheckSourceSetsAreOfCorrectType(input_api, output_api, package):
-  """Makes sure that the BUILD.gn files always use the correct wrapper type for
-  |package|, which can be one of ["SDK", "EDK"], to construct source_set
-  targets."""
-  assert package in _PACKAGE_SOURCE_SET_TYPES
-  required_source_set_type = _PACKAGE_SOURCE_SET_TYPES[package]
-
-  problems = []
-  for f in _AffectedBuildFilesWithinPackage(input_api, package):
-    for line_num, line in f.ChangedContents():
-      m = re.search(r"[a-z_]*source_set\(", line)
-      if not m:
-        continue
-      source_set_type = m.group(0)[:-1]
-      if source_set_type in required_source_set_type:
-        continue
-      problems.append(_IncorrectSourceSetTypeWarningItem(f.LocalPath(),
-                                                         line_num))
-
-  if not problems:
-    return []
-  return [output_api.PresubmitError(
-      _INCORRECT_SOURCE_SET_TYPE_WARNING_MESSAGES[package],
-      items=problems)]
-
-def _CheckChangePylintsClean(input_api, output_api):
-  # Additional python module paths (we're in src/mojo/); not everyone needs
-  # them, but it's easiest to add them to everyone's path.
-  # For ply and jinja2:
-  third_party_path = os.path.join(
-      input_api.PresubmitLocalPath(), "..", "third_party")
-  # For the bindings generator:
-  mojo_public_bindings_pylib_path = os.path.join(
-      input_api.PresubmitLocalPath(), "public", "tools", "bindings", "pylib")
-  # For the python bindings:
-  mojo_python_bindings_path = os.path.join(
-      input_api.PresubmitLocalPath(), "public", "python")
-  # For the python bindings tests:
-  mojo_python_bindings_tests_path = os.path.join(
-      input_api.PresubmitLocalPath(), "python", "tests")
-  # For the roll tools scripts:
-  mojo_roll_tools_path = os.path.join(
-      input_api.PresubmitLocalPath(), "tools", "roll")
-  # For all mojo/tools scripts:
-  mopy_path = os.path.join(input_api.PresubmitLocalPath(), "tools")
-  # For all mojo/devtools scripts:
-  devtools_path = os.path.join(input_api.PresubmitLocalPath(), "devtools")
-  # TODO(vtl): Don't lint these files until the (many) problems are fixed
-  # (possibly by deleting/rewriting some files).
-  temporary_black_list = (
-      r".*\bpublic[\\\/]tools[\\\/]bindings[\\\/]pylib[\\\/]mojom[\\\/]"
-          r"generate[\\\/].+\.py$",
-      r".*\bpublic[\\\/]tools[\\\/]bindings[\\\/]generators[\\\/].+\.py$")
-  black_list = input_api.DEFAULT_BLACK_LIST + temporary_black_list + (
-      # Imported from Android tools, we might want not to fix the warnings
-      # raised for it to make it easier to compare the code with the original.
-      r".*\bdevtools[\\\/]common[\\\/]android_stack_parser[\\\/].+\.py$",)
-
-  results = []
-  pylint_extra_paths = [
-      third_party_path,
-      mojo_public_bindings_pylib_path,
-      mojo_python_bindings_path,
-      mojo_python_bindings_tests_path,
-      mojo_roll_tools_path,
-      mopy_path,
-      devtools_path
-  ]
-  results.extend(input_api.canned_checks.RunPylint(
-      input_api, output_api, extra_paths_list=pylint_extra_paths,
-      black_list=black_list))
-  return results
-
-def _BuildFileChecks(input_api, output_api):
-  """Performs checks on SDK, EDK, and services' public buildfiles."""
-  results = []
-  for package in ["SDK", "EDK", "services"]:
-    results.extend(_CheckNoIllegalAbsolutePathsInBuildFiles(input_api,
-                                                            output_api,
-                                                            package))
-    results.extend(_CheckSourceSetsAreOfCorrectType(input_api,
-                                                    output_api,
-                                                    package))
-  return results
-
-def _CommonChecks(input_api, output_api):
-  """Checks common to both upload and commit."""
-  results = []
-  results.extend(_BuildFileChecks(input_api, output_api))
-  return results
-
-def CheckChangeOnUpload(input_api, output_api):
-  results = []
-  results.extend(_CommonChecks(input_api, output_api))
-  results.extend(_CheckChangePylintsClean(input_api, output_api))
-  return results
-
-def CheckChangeOnCommit(input_api, output_api):
-  results = []
-  results.extend(_CommonChecks(input_api, output_api))
-  return results
diff --git a/mojo/PRESUBMIT_test.py b/mojo/PRESUBMIT_test.py
deleted file mode 100755
index 3e2443c..0000000
--- a/mojo/PRESUBMIT_test.py
+++ /dev/null
@@ -1,310 +0,0 @@
-#!/usr/bin/env python
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import os
-import sys
-import unittest
-
-import PRESUBMIT
-
-sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
-from PRESUBMIT_test_mocks import MockFile
-from PRESUBMIT_test_mocks import MockInputApi, MockOutputApi
-
-_SDK_BUILD_FILE = 'mojo/public/some/path/BUILD.gn'
-_EDK_BUILD_FILE = 'mojo/edk/some/path/BUILD.gn'
-_SERVICE_BUILD_FILE = 'mojo/services/some_service/public/BUILD.gn'
-_IRRELEVANT_BUILD_FILE = 'mojo/foo/some/path/BUILD.gn'
-
-_PACKAGE_BUILDFILES = {
-    'SDK' : _SDK_BUILD_FILE,
-    'EDK' : _EDK_BUILD_FILE,
-    'services' : _SERVICE_BUILD_FILE
-}
-
-class AbsoluteReferencesInBuildFilesTest(unittest.TestCase):
-  """Tests the checking for illegal absolute paths within SDK/EDK buildfiles.
-  """
-  def setUp(self):
-    self.sdk_absolute_path = '//mojo/public/some/absolute/path'
-    self.sdk_relative_path = 'mojo/public/some/relative/path'
-    self.edk_absolute_path = '//mojo/edk/some/absolute/path'
-    self.edk_relative_path = 'mojo/edk/some/relative/path'
-    self.service_absolute_path = '//mojo/services/some/service'
-    self.service_relative_path = '../../../some/service'
-    self.whitelisted_external_path = '//testing/gtest'
-    self.non_whitelisted_external_path = '//base'
-
-  def inputApiContainingFileWithPaths(self, filename, paths):
-    """Returns a MockInputApi object with a single file having |filename| as
-    its name and |paths| as its contents, with each path being wrapped in a
-    pair of double-quotes to match the syntax for strings within BUILD.gn
-    files."""
-    contents = [ '"%s"' % path for path in paths ]
-    mock_file = MockFile(filename, contents)
-    mock_input_api = MockInputApi()
-    mock_input_api.files.append(mock_file)
-    return mock_input_api
-
-  def checkWarningWithSingleItem(self,
-                                 warning,
-                                 expected_message,
-                                 build_file,
-                                 line_num,
-                                 referenced_path):
-    """Checks that |warning| has a message of |expected_message| and a single
-    item whose contents are the absolute path warning item for
-    (build_file, line_num, referenced_path)."""
-    self.assertEqual(expected_message, warning.message)
-    self.assertEqual(1, len(warning.items))
-    expected_item = PRESUBMIT._PathReferenceInBuildFileWarningItem(
-        build_file, line_num, referenced_path)
-    self.assertEqual(expected_item, warning.items[0])
-
-  def checkSDKAbsolutePathWarningWithSingleItem(self,
-                                                warning,
-                                                package,
-                                                build_file,
-                                                line_num,
-                                                referenced_path):
-    """Checks that |warning| has the message for an absolute SDK path within
-    |package| and a single item whose contents are the absolute path warning
-    item for (build_file, line_num, referenced_path)."""
-    expected_message = \
-        PRESUBMIT._ILLEGAL_SDK_ABSOLUTE_PATH_WARNING_MESSAGES[package]
-    self.checkWarningWithSingleItem(warning,
-                                    expected_message,
-                                    build_file,
-                                    line_num,
-                                    referenced_path)
-
-  def _testAbsoluteSDKReferenceInPackage(self, package):
-    """Tests that an absolute SDK path within |package| is flagged."""
-    buildfile = _PACKAGE_BUILDFILES[package]
-    mock_input_api = self.inputApiContainingFileWithPaths(
-        buildfile,
-        [ self.sdk_relative_path, self.sdk_absolute_path ])
-    warnings = PRESUBMIT._BuildFileChecks(mock_input_api, MockOutputApi())
-
-    self.assertEqual(1, len(warnings))
-    self.checkSDKAbsolutePathWarningWithSingleItem(warnings[0],
-                                                   package,
-                                                   buildfile,
-                                                   2,
-                                                   self.sdk_absolute_path)
-
-  def _testExternalReferenceInPackage(self, package):
-    """Tests that an illegal external path within |package| is flagged."""
-    buildfile = _PACKAGE_BUILDFILES[package]
-    mock_input_api = self.inputApiContainingFileWithPaths(
-        buildfile,
-        [ self.non_whitelisted_external_path, self.whitelisted_external_path ])
-    warnings = PRESUBMIT._BuildFileChecks(mock_input_api, MockOutputApi())
-
-    if package == 'EDK':
-      # All external paths are allowed in the EDK.
-      self.assertEqual(0, len(warnings))
-      return
-
-    self.assertEqual(1, len(warnings))
-    expected_message = PRESUBMIT._ILLEGAL_EXTERNAL_PATH_WARNING_MESSAGE
-    self.checkWarningWithSingleItem(warnings[0],
-                                    expected_message,
-                                    buildfile,
-                                    1,
-                                    self.non_whitelisted_external_path)
-
-  def testAbsoluteSDKReferenceInSDKBuildFile(self):
-    """Tests that an absolute SDK path within an SDK buildfile is flagged."""
-    self._testAbsoluteSDKReferenceInPackage('SDK')
-
-  def testExternalReferenceInSDKBuildFile(self):
-    """Tests that an illegal external path in an SDK buildfile is flagged."""
-    self._testExternalReferenceInPackage('SDK')
-
-  def testAbsoluteEDKReferenceInSDKBuildFile(self):
-    """Tests that an absolute EDK path in an SDK buildfile is flagged."""
-    mock_input_api = self.inputApiContainingFileWithPaths(
-        _SDK_BUILD_FILE,
-        [ self.edk_absolute_path ])
-    warnings = PRESUBMIT._BuildFileChecks(mock_input_api, MockOutputApi())
-
-    self.assertEqual(1, len(warnings))
-    expected_message = PRESUBMIT._ILLEGAL_EXTERNAL_PATH_WARNING_MESSAGE
-    self.checkWarningWithSingleItem(warnings[0],
-                                    expected_message,
-                                    _SDK_BUILD_FILE,
-                                    1,
-                                    self.edk_absolute_path)
-
-  def testAbsoluteSDKReferenceInEDKBuildFile(self):
-    """Tests that an absolute SDK path within an EDK buildfile is flagged."""
-    self._testAbsoluteSDKReferenceInPackage('EDK')
-
-  def testAbsoluteEDKReferenceInEDKBuildFile(self):
-    """Tests that an absolute EDK path in an EDK buildfile is flagged."""
-    mock_input_api = self.inputApiContainingFileWithPaths(
-        _EDK_BUILD_FILE,
-        [ self.edk_absolute_path, self.edk_relative_path ])
-    warnings = PRESUBMIT._BuildFileChecks(mock_input_api, MockOutputApi())
-
-    self.assertEqual(1, len(warnings))
-    expected_message = PRESUBMIT._ILLEGAL_EDK_ABSOLUTE_PATH_WARNING_MESSAGE
-    self.checkWarningWithSingleItem(warnings[0],
-                                    expected_message,
-                                    _EDK_BUILD_FILE,
-                                    1,
-                                    self.edk_absolute_path)
-
-  def testExternalReferenceInEDKBuildFile(self):
-    """Tests that an external path in an EDK buildfile is not flagged."""
-    self._testExternalReferenceInPackage('EDK')
-
-  def testAbsoluteSDKReferenceInServiceBuildFile(self):
-    """Tests that an absolute SDK path within a service's public buildfile is
-    flagged."""
-    self._testAbsoluteSDKReferenceInPackage("services")
-
-  def testAbsoluteServiceReferenceInServiceBuildFile(self):
-    """Tests that an absolute path to a service within a service's public
-    buildfile is flagged."""
-    mock_input_api = self.inputApiContainingFileWithPaths(
-        _SERVICE_BUILD_FILE,
-        [ self.service_relative_path, self.service_absolute_path ])
-    warnings = PRESUBMIT._BuildFileChecks(mock_input_api, MockOutputApi())
-
-    self.assertEqual(1, len(warnings))
-    expected_message = \
-        PRESUBMIT._ILLEGAL_SERVICES_ABSOLUTE_PATH_WARNING_MESSAGE
-    self.checkWarningWithSingleItem(warnings[0],
-                                    expected_message,
-                                    _SERVICE_BUILD_FILE,
-                                    2,
-                                    self.service_absolute_path)
-
-  def testExternalReferenceInServiceBuildFile(self):
-    """Tests that an illegal external path in a service's buildfile is flagged
-    ."""
-    self._testExternalReferenceInPackage("services")
-
-  def testIrrelevantBuildFile(self):
-    """Tests that nothing is flagged in a non SDK/EDK buildfile."""
-    mock_input_api = self.inputApiContainingFileWithPaths(
-        _IRRELEVANT_BUILD_FILE,
-        [ self.sdk_absolute_path,
-          self.sdk_relative_path,
-          self.edk_absolute_path,
-          self.edk_relative_path,
-          self.non_whitelisted_external_path,
-          self.whitelisted_external_path ])
-    warnings = PRESUBMIT._BuildFileChecks(mock_input_api, MockOutputApi())
-    self.assertEqual(0, len(warnings))
-
-class SourceSetTypesInBuildFilesTest(unittest.TestCase):
-  """Tests checking of correct source set types within SDK/EDK buildfiles."""
-
-  def inputApiContainingFileWithSourceSets(self, filename, source_sets):
-    """Returns a MockInputApi object containing a single file having |filename|
-    as its name and |source_sets| as its contents."""
-    mock_file = MockFile(filename, source_sets)
-    mock_input_api = MockInputApi()
-    mock_input_api.files.append(mock_file)
-    return mock_input_api
-
-  def checkWarningWithSingleItem(self,
-                                 warning,
-                                 package,
-                                 build_file,
-                                 line_num):
-    """Checks that warning has the expected incorrect source set type message
-    for |package| and a single item whose contents are the incorrect source
-    set type item for (build_file, line_num)."""
-    expected_message = \
-        PRESUBMIT._INCORRECT_SOURCE_SET_TYPE_WARNING_MESSAGES[package]
-    self.assertEqual(expected_message, warning.message)
-    self.assertEqual(1, len(warning.items))
-    expected_item = PRESUBMIT._IncorrectSourceSetTypeWarningItem(
-        build_file, line_num)
-    self.assertEqual(expected_item, warning.items[0])
-
-  def _testNakedSourceSetInPackage(self, package):
-    """Tests that a source_set within |package| is flagged."""
-    buildfile = _PACKAGE_BUILDFILES[package]
-    naked_source_set = 'source_set('
-    correct_source_set = 'mojo_sdk_source_set('
-    if package == 'EDK':
-      correct_source_set = 'mojo_edk_source_set('
-    mock_input_api = self.inputApiContainingFileWithSourceSets(
-        buildfile,
-        [ correct_source_set, naked_source_set ])
-    warnings = PRESUBMIT._BuildFileChecks(mock_input_api, MockOutputApi())
-
-    self.assertEqual(1, len(warnings))
-    self.checkWarningWithSingleItem(warnings[0], package, buildfile, 2)
-
-  def _testWrongTypeOfWrapperSourceSetInPackage(self, package):
-    """Tests that the wrong type of wrapper source_set in |package| is flagged
-    (e.g., mojo_edk_source_set within the SDK)."""
-    buildfile = _PACKAGE_BUILDFILES[package]
-    mock_input_api = self.inputApiContainingFileWithSourceSets(
-        buildfile,
-        [ 'mojo_sdk_source_set(', 'mojo_edk_source_set(' ])
-    warnings = PRESUBMIT._BuildFileChecks(mock_input_api, MockOutputApi())
-
-    self.assertEqual(1, len(warnings))
-    warning_line = 2
-    if package == 'EDK':
-      warning_line = 1
-    self.checkWarningWithSingleItem(warnings[0],
-                                    package,
-                                    buildfile,
-                                    warning_line)
-
-  def testNakedSourceSetInSDKBuildFile(self):
-    """Tests that a source_set within the SDK is flagged."""
-    self._testNakedSourceSetInPackage('SDK')
-
-  def testPythonSourceSetInSDKBuildFile(self):
-    """Tests that a python_binary_source_set within an SDK buildfile is
-    accepted."""
-    mock_input_api = self.inputApiContainingFileWithSourceSets(
-        _SDK_BUILD_FILE,
-        [ 'mojo_sdk_source_set(', 'python_binary_source_set(' ])
-    warnings = PRESUBMIT._BuildFileChecks(mock_input_api, MockOutputApi())
-
-    self.assertEqual(0, len(warnings))
-
-  def testEDKSourceSetInSDKBuildFile(self):
-    """Tests that a mojo_edk_source_set within an SDK buildfile is flagged."""
-    self._testWrongTypeOfWrapperSourceSetInPackage('SDK')
-
-  def testNakedSourceSetInEDKBuildFile(self):
-    """Tests that a source_set within the EDK is flagged."""
-    self._testNakedSourceSetInPackage('EDK')
-
-  def testSDKSourceSetInEDKBuildFile(self):
-    """Tests that a mojo_sdk_source_set within an EDK buildfile is flagged."""
-    self._testWrongTypeOfWrapperSourceSetInPackage('EDK')
-
-  def testNakedSourceSetInServiceBuildFile(self):
-    """Tests that a source_set within a service's public buildfile is flagged.
-    """
-    self._testNakedSourceSetInPackage("services")
-
-  def testEDKSourceSetInServiceBuildFile(self):
-    """Tests that a mojo_edk_source_set within a service's public buildfile is
-    flagged."""
-    self._testWrongTypeOfWrapperSourceSetInPackage("services")
-
-  def testIrrelevantBuildFile(self):
-    """Tests that a source_set in a non-SDK/EDK buildfile isn't flagged."""
-    mock_input_api = self.inputApiContainingFileWithSourceSets(
-        _IRRELEVANT_BUILD_FILE,
-        [ 'source_set(' ])
-    warnings = PRESUBMIT._BuildFileChecks(mock_input_api, MockOutputApi())
-    self.assertEqual(0, len(warnings))
-
-if __name__ == '__main__':
-  unittest.main()
diff --git a/mojo/README.md b/mojo/README.md
deleted file mode 100644
index 5af1dcb..0000000
--- a/mojo/README.md
+++ /dev/null
@@ -1,6 +0,0 @@
-Mojo
-====
-
-Mojo is an effort to extract a common platform out of Chrome's renderer and
-plugin processes that can support multiple types of sandboxed content, such as
-HTML, Pepper, or NaCl.
diff --git a/mojo/android/BUILD.gn b/mojo/android/BUILD.gn
index 8e0aacd..746a156 100644
--- a/mojo/android/BUILD.gn
+++ b/mojo/android/BUILD.gn
@@ -45,10 +45,10 @@
   deps = [
     ":system_java_jni_headers",
     "//base",
-    "//mojo/public/cpp/environment",
-    "//mojo/common:common",
+    "//mojo/message_pump",
     "//mojo/public/c/system:system",
     "//mojo/public/cpp/bindings:callback",
+    "//mojo/public/cpp/environment",
   ]
 }
 
@@ -125,13 +125,12 @@
     ":system_java_jni_headers",
     "//base",
     "//base/test/:test_support",
-    "//mojo/common",
-    "//mojo/edk/system",
-    "//mojo/public/cpp/bindings/tests:mojo_public_bindings_test_utils",
-    "//mojo/public/cpp/test_support:test_utils",
-    "//mojo/public/cpp/environment",
     "//mojo/edk/system",
     "//mojo/environment:chromium",
+    "//mojo/message_pump",
+    "//mojo/public/cpp/bindings/tests:mojo_public_bindings_test_utils",
+    "//mojo/public/cpp/environment",
+    "//mojo/public/cpp/test_support:test_utils",
   ]
   defines = [ "UNIT_TEST" ]
 }
diff --git a/mojo/android/javatests/mojo_test_case.cc b/mojo/android/javatests/mojo_test_case.cc
index 419d14d..2df0bc7 100644
--- a/mojo/android/javatests/mojo_test_case.cc
+++ b/mojo/android/javatests/mojo_test_case.cc
@@ -13,7 +13,7 @@
 #include "base/run_loop.h"
 #include "base/test/test_support_android.h"
 #include "jni/MojoTestCase_jni.h"
-#include "mojo/common/message_pump_mojo.h"
+#include "mojo/message_pump/message_pump_mojo.h"
 
 #include "mojo/public/cpp/environment/environment.h"
 
diff --git a/mojo/android/system/base_run_loop.cc b/mojo/android/system/base_run_loop.cc
index 3d05e30..f361a94 100644
--- a/mojo/android/system/base_run_loop.cc
+++ b/mojo/android/system/base_run_loop.cc
@@ -12,7 +12,7 @@
 #include "base/bind.h"
 #include "base/message_loop/message_loop.h"
 #include "jni/BaseRunLoop_jni.h"
-#include "mojo/common/message_pump_mojo.h"
+#include "mojo/message_pump/message_pump_mojo.h"
 
 namespace mojo {
 namespace android {
diff --git a/mojo/application/BUILD.gn b/mojo/application/BUILD.gn
index f28c13b..35cb345 100644
--- a/mojo/application/BUILD.gn
+++ b/mojo/application/BUILD.gn
@@ -13,7 +13,7 @@
   ]
   deps = [
     "//base",
-    "//mojo/common",
+    "//mojo/message_pump",
     "//mojo/public/cpp/system",
     "//mojo/environment:chromium",
   ]
@@ -27,8 +27,8 @@
   deps = [
     ":application",
     "//base",
-    "//mojo/common",
     "//mojo/environment:chromium",
+    "//mojo/message_pump",
     "//mojo/public/interfaces/application",
     "//mojo/services/content_handler/public/interfaces",
     "//mojo/services/network/public/interfaces",
diff --git a/mojo/application/application_runner_chromium.cc b/mojo/application/application_runner_chromium.cc
index 451d448..d54f4b2 100644
--- a/mojo/application/application_runner_chromium.cc
+++ b/mojo/application/application_runner_chromium.cc
@@ -9,7 +9,7 @@
 #include "base/debug/stack_trace.h"
 #include "base/memory/scoped_ptr.h"
 #include "base/message_loop/message_loop.h"
-#include "mojo/common/message_pump_mojo.h"
+#include "mojo/message_pump/message_pump_mojo.h"
 #include "mojo/public/cpp/application/application_delegate.h"
 #include "mojo/public/cpp/application/application_impl.h"
 
diff --git a/mojo/application/content_handler_factory.cc b/mojo/application/content_handler_factory.cc
index 1231001..9594fdb 100644
--- a/mojo/application/content_handler_factory.cc
+++ b/mojo/application/content_handler_factory.cc
@@ -13,7 +13,7 @@
 #include "base/threading/platform_thread.h"
 #include "base/trace_event/trace_event.h"
 #include "mojo/application/application_runner_chromium.h"
-#include "mojo/common/message_pump_mojo.h"
+#include "mojo/message_pump/message_pump_mojo.h"
 #include "mojo/public/cpp/application/application_connection.h"
 #include "mojo/public/cpp/application/application_delegate.h"
 #include "mojo/public/cpp/application/application_impl.h"
diff --git a/mojo/common/BUILD.gn b/mojo/common/BUILD.gn
index 460471b..2420060 100644
--- a/mojo/common/BUILD.gn
+++ b/mojo/common/BUILD.gn
@@ -5,54 +5,25 @@
 import("//mojo/public/tools/bindings/mojom.gni")
 import("//testing/test.gni")
 
-component("common") {
-  output_name = "mojo_common_lib"
-
+source_set("common") {
   sources = [
     "binding_set.h",
-    "common_type_converters.cc",
-    "common_type_converters.h",
-    "data_pipe_drainer.cc",
-    "data_pipe_drainer.h",
-    "data_pipe_file_utils.cc",
-    "data_pipe_utils.cc",
-    "data_pipe_utils.h",
-    "data_pipe_utils_internal.h",
-    "handle_watcher.cc",
-    "handle_watcher.h",
     "interface_ptr_set.h",
-    "message_pump_mojo.cc",
-    "message_pump_mojo.h",
-    "message_pump_mojo_handler.h",
     "task_tracker.cc",
     "task_tracker.h",
-    "time_helper.cc",
-    "time_helper.h",
   ]
 
-  if (is_nacl) {
-    sources -= [ "data_pipe_file_utils.cc" ]
-  }
-
   deps = [
     "//base",
-    "//base/third_party/dynamic_annotations",
-    "//mojo/public/c/system",
     "//mojo/public/cpp/bindings",
-    "//mojo/public/cpp/environment:environment",
-    "//mojo/public/cpp/system",
-    "//url",
   ]
 }
 
 test("mojo_common_unittests") {
   sources = [
     "binding_set_unittest.cc",
-    "common_type_converters_unittest.cc",
-    "data_pipe_utils_unittest.cc",
-    "handle_watcher_unittest.cc",
+    "callback_binding_unittest.cc",
     "interface_ptr_set_unittest.cc",
-    "message_pump_mojo_unittest.cc",
     "task_tracker_unittest.cc",
   ]
 
@@ -61,10 +32,15 @@
     ":test_interfaces",
     "//base",
     "//base/test:test_support",
-    "//base:message_loop_tests",
+    "//mojo/converters/array_string:tests",
+    "//mojo/converters/base:tests",
+    "//mojo/converters/url:tests",
+    "//mojo/data_pipe_utils:tests",
     "//mojo/edk/test:run_all_unittests",
     "//mojo/edk/test:test_support",
     "//mojo/environment:chromium",
+    "//mojo/message_pump",
+    "//mojo/message_pump:tests",
     "//mojo/public/cpp/bindings",
     "//mojo/public/cpp/bindings:callback",
     "//mojo/public/cpp/system",
@@ -83,8 +59,8 @@
 
 source_set("tracing_impl") {
   sources = [
-    "trace_controller_impl.cc",
-    "trace_controller_impl.h",
+    "trace_provider_impl.cc",
+    "trace_provider_impl.h",
     "tracing_impl.cc",
     "tracing_impl.h",
   ]
diff --git a/mojo/common/binding_set_unittest.cc b/mojo/common/binding_set_unittest.cc
index 421a405..c37053e 100644
--- a/mojo/common/binding_set_unittest.cc
+++ b/mojo/common/binding_set_unittest.cc
@@ -5,8 +5,8 @@
 #include "mojo/common/binding_set.h"
 
 #include "base/message_loop/message_loop.h"
-#include "mojo/common/message_pump_mojo.h"
 #include "mojo/common/test_interfaces.mojom.h"
+#include "mojo/message_pump/message_pump_mojo.h"
 #include "mojo/public/cpp/bindings/binding.h"
 #include "mojo/public/cpp/bindings/interface_request.h"
 #include "testing/gtest/include/gtest/gtest.h"
diff --git a/mojo/common/callback_binding_unittest.cc b/mojo/common/callback_binding_unittest.cc
new file mode 100644
index 0000000..aa59856
--- /dev/null
+++ b/mojo/common/callback_binding_unittest.cc
@@ -0,0 +1,104 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/bind.h"
+#include "mojo/public/cpp/bindings/callback.h"
+#include "mojo/public/cpp/bindings/map.h"
+#include "mojo/public/cpp/bindings/string.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace {
+
+struct RunnableNoArgs {
+  RunnableNoArgs(int* calls) : calls(calls) {}
+  void Run() const { (*calls)++; }
+
+  int* calls;
+};
+
+TEST(CallbackBindingTest, BaseBindToMojoCallbackNoParams) {
+  mojo::Callback<void()> cb;
+  int calls = 0;
+  RunnableNoArgs r(&calls);
+  cb = r;
+  cb.Run();
+  EXPECT_EQ(1, calls);
+
+  cb = base::Bind(&RunnableNoArgs::Run, base::Unretained(&r));
+  cb.Run();
+  EXPECT_EQ(2, calls);
+}
+
+struct RunnableOnePrimitiveArg {
+  explicit RunnableOnePrimitiveArg(int* calls) : calls(calls) {}
+  void Run(int a) const { (*calls)++; }
+
+  int* calls;
+};
+
+TEST(CallbackBindingTest, BaseBindToMojoCallbackPrimitiveParam) {
+  mojo::Callback<void(int)> mojo_callback;
+  int calls = 0;
+  RunnableOnePrimitiveArg r(&calls);
+  mojo_callback = r;
+  mojo_callback.Run(0);
+  EXPECT_EQ(1, calls);
+
+  base::Callback<void(int)> base_callback =
+      base::Bind(&RunnableOnePrimitiveArg::Run, base::Unretained(&r));
+  mojo_callback = base_callback;
+  mojo_callback.Run(0);
+  EXPECT_EQ(2, calls);
+}
+
+struct RunnableOneMojoStringParam {
+  explicit RunnableOneMojoStringParam(int* calls) : calls(calls) {}
+  void Run(const mojo::String& s) const { (*calls)++; }
+
+  int* calls;
+};
+
+TEST(CallbackBindingTest, BaseBindToMojoCallbackMojoStringParam) {
+  // The mojo type is a callback on mojo::String, but it'll expect to invoke
+  // callbacks with a parameter of type 'const Mojo::String&'.
+  mojo::Callback<void(mojo::String)> mojo_callback;
+  int calls = 0;
+  RunnableOneMojoStringParam r(&calls);
+  mojo_callback = r;
+  mojo_callback.Run(0);
+  EXPECT_EQ(1, calls);
+
+  base::Callback<void(const mojo::String&)> base_callback =
+      base::Bind(&RunnableOneMojoStringParam::Run, base::Unretained(&r));
+  mojo_callback = base_callback;
+  mojo_callback.Run(0);
+  EXPECT_EQ(2, calls);
+}
+
+using ExampleMoveOnlyType = mojo::Map<int, int>;
+
+struct RunnableOneMoveOnlyParam {
+  explicit RunnableOneMoveOnlyParam(int* calls) : calls(calls) {}
+
+  void Run(ExampleMoveOnlyType m) const { (*calls)++; }
+  int* calls;
+};
+
+TEST(CallbackBindingTest, BaseBindToMoveOnlyParam) {
+  mojo::Callback<void(ExampleMoveOnlyType)> mojo_callback;
+  int calls = 0;
+  RunnableOneMoveOnlyParam r(&calls);
+  mojo_callback = r;
+  ExampleMoveOnlyType m;
+  mojo_callback.Run(m.Clone());
+  EXPECT_EQ(1, calls);
+
+  base::Callback<void(ExampleMoveOnlyType)> base_callback =
+      base::Bind(&RunnableOneMoveOnlyParam::Run, base::Unretained(&r));
+  mojo_callback = base_callback;
+  mojo_callback.Run(m.Clone());
+  EXPECT_EQ(2, calls);
+}
+
+}  // namespace
diff --git a/mojo/common/common_type_converters.cc b/mojo/common/common_type_converters.cc
deleted file mode 100644
index 114b409..0000000
--- a/mojo/common/common_type_converters.cc
+++ /dev/null
@@ -1,65 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "mojo/common/common_type_converters.h"
-
-#include <string>
-
-#include "base/strings/utf_string_conversions.h"
-#include "url/gurl.h"
-
-namespace mojo {
-
-// static
-String TypeConverter<String, base::StringPiece>::Convert(
-    const base::StringPiece& input) {
-  if (input.empty()) {
-    char c = 0;
-    return String(&c, 0);
-  }
-  return String(input.data(), input.size());
-}
-// static
-base::StringPiece TypeConverter<base::StringPiece, String>::Convert(
-    const String& input) {
-  return input.get();
-}
-
-// static
-String TypeConverter<String, base::string16>::Convert(
-    const base::string16& input) {
-  return TypeConverter<String, base::StringPiece>::Convert(
-      base::UTF16ToUTF8(input));
-}
-// static
-base::string16 TypeConverter<base::string16, String>::Convert(
-    const String& input) {
-  return base::UTF8ToUTF16(input.To<base::StringPiece>());
-}
-
-String TypeConverter<String, GURL>::Convert(const GURL& input) {
-  return String(input.spec());
-}
-
-GURL TypeConverter<GURL, String>::Convert(const String& input) {
-  return GURL(input.get());
-}
-
-std::string TypeConverter<std::string, Array<uint8_t> >::Convert(
-    const Array<uint8_t>& input) {
-  if (input.is_null())
-    return std::string();
-
-  return std::string(reinterpret_cast<const char*>(&input.front()),
-                     input.size());
-}
-
-Array<uint8_t> TypeConverter<Array<uint8_t>, std::string>::Convert(
-    const std::string& input) {
-  Array<uint8_t> result(input.size());
-  memcpy(&result.front(), input.c_str(), input.size());
-  return result.Pass();
-}
-
-}  // namespace mojo
diff --git a/mojo/common/common_type_converters.h b/mojo/common/common_type_converters.h
deleted file mode 100644
index 9bd21e8..0000000
--- a/mojo/common/common_type_converters.h
+++ /dev/null
@@ -1,64 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef MOJO_COMMON_COMMON_TYPE_CONVERTERS_H_
-#define MOJO_COMMON_COMMON_TYPE_CONVERTERS_H_
-
-#include "base/strings/string16.h"
-#include "base/strings/string_piece.h"
-#include "mojo/public/cpp/bindings/array.h"
-#include "mojo/public/cpp/bindings/string.h"
-#include "mojo/public/cpp/bindings/type_converter.h"
-
-class GURL;
-
-namespace mojo {
-
-template <>
-struct TypeConverter<String, base::StringPiece> {
-  static String Convert(const base::StringPiece& input);
-};
-
-template <>
-struct TypeConverter<base::StringPiece, String> {
-  static base::StringPiece Convert(const String& input);
-};
-
-template <>
-struct TypeConverter<String, base::string16> {
-  static String Convert(const base::string16& input);
-};
-
-template <>
-struct TypeConverter<base::string16, String> {
-  static base::string16 Convert(const String& input);
-};
-
-template <>
-struct TypeConverter<String, GURL> {
-  static String Convert(const GURL& input);
-};
-
-template <>
-struct TypeConverter<GURL, String> {
-  static GURL Convert(const String& input);
-};
-
-// TODO(erg): In the very long term, we will want to remove conversion between
-// std::strings and arrays of unsigned bytes. However, there is too much code
-// across chrome which uses std::string as a bag of bytes that we probably
-// don't want to roll this function at each callsite.
-template <>
-struct TypeConverter<std::string, Array<uint8_t>> {
-  static std::string Convert(const Array<uint8_t>& input);
-};
-
-template <>
-struct TypeConverter<Array<uint8_t>, std::string> {
-  static Array<uint8_t> Convert(const std::string& input);
-};
-
-}  // namespace mojo
-
-#endif  // MOJO_COMMON_COMMON_TYPE_CONVERTERS_H_
diff --git a/mojo/common/common_type_converters_unittest.cc b/mojo/common/common_type_converters_unittest.cc
deleted file mode 100644
index 4a360bd..0000000
--- a/mojo/common/common_type_converters_unittest.cc
+++ /dev/null
@@ -1,203 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "mojo/common/common_type_converters.h"
-
-#include "base/bind.h"
-#include "base/strings/utf_string_conversions.h"
-#include "mojo/public/cpp/bindings/callback.h"
-#include "mojo/public/cpp/bindings/map.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "url/gurl.h"
-
-namespace mojo {
-namespace common {
-namespace test {
-namespace {
-
-void ExpectEqualsStringPiece(const std::string& expected,
-                             const base::StringPiece& str) {
-  EXPECT_EQ(expected, str.as_string());
-}
-
-void ExpectEqualsMojoString(const std::string& expected,
-                            const String& str) {
-  EXPECT_EQ(expected, str.get());
-}
-
-void ExpectEqualsString16(const base::string16& expected,
-                          const base::string16& actual) {
-  EXPECT_EQ(expected, actual);
-}
-
-void ExpectEqualsMojoString(const base::string16& expected,
-                            const String& str) {
-  EXPECT_EQ(expected, str.To<base::string16>());
-}
-
-TEST(CommonTypeConvertersTest, StringPiece) {
-  std::string kText("hello world");
-
-  base::StringPiece string_piece(kText);
-  String mojo_string(String::From(string_piece));
-
-  ExpectEqualsMojoString(kText, mojo_string);
-  ExpectEqualsStringPiece(kText, mojo_string.To<base::StringPiece>());
-
-  // Test implicit construction and conversion:
-  ExpectEqualsMojoString(kText, String::From(string_piece));
-  ExpectEqualsStringPiece(kText, mojo_string.To<base::StringPiece>());
-
-  // Test null String:
-  base::StringPiece empty_string_piece = String().To<base::StringPiece>();
-  EXPECT_TRUE(empty_string_piece.empty());
-}
-
-TEST(CommonTypeConvertersTest, String16) {
-  const base::string16 string16(base::ASCIIToUTF16("hello world"));
-  const String mojo_string(String::From(string16));
-
-  ExpectEqualsMojoString(string16, mojo_string);
-  EXPECT_EQ(string16, mojo_string.To<base::string16>());
-
-  // Test implicit construction and conversion:
-  ExpectEqualsMojoString(string16, String::From(string16));
-  ExpectEqualsString16(string16, mojo_string.To<base::string16>());
-
-  // Test empty string conversion.
-  ExpectEqualsMojoString(base::string16(), String::From(base::string16()));
-}
-
-TEST(CommonTypeConvertersTest, URL) {
-  GURL url("mojo:foo");
-  String mojo_string(String::From(url));
-
-  ASSERT_EQ(url.spec(), mojo_string);
-  EXPECT_EQ(url.spec(), mojo_string.To<GURL>().spec());
-  EXPECT_EQ(url.spec(), String::From(url));
-
-  GURL invalid = String().To<GURL>();
-  ASSERT_TRUE(invalid.spec().empty());
-
-  String string_from_invalid = String::From(invalid);
-  EXPECT_FALSE(string_from_invalid.is_null());
-  ASSERT_EQ(0U, string_from_invalid.size());
-}
-
-TEST(CommonTypeConvertersTest, ArrayUint8ToStdString) {
-  Array<uint8_t> data(4);
-  data[0] = 'd';
-  data[1] = 'a';
-  data[2] = 't';
-  data[3] = 'a';
-
-  EXPECT_EQ("data", data.To<std::string>());
-}
-
-TEST(CommonTypeConvertersTest, StdStringToArrayUint8) {
-  std::string input("data");
-  Array<uint8_t> data = Array<uint8_t>::From(input);
-
-  ASSERT_EQ(4ul, data.size());
-  EXPECT_EQ('d', data[0]);
-  EXPECT_EQ('a', data[1]);
-  EXPECT_EQ('t', data[2]);
-  EXPECT_EQ('a', data[3]);
-}
-
-struct RunnableNoArgs {
-  RunnableNoArgs(int* calls) : calls(calls) {}
-  void Run() const { (*calls)++; }
-
-  int* calls;
-};
-
-TEST(CommonTypeConvertersTest, BaseBindToMojoCallbackNoParams) {
-  mojo::Callback<void()> cb;
-  int calls = 0;
-  RunnableNoArgs r(&calls);
-  cb = r;
-  cb.Run();
-  EXPECT_EQ(1, calls);
-
-  cb = base::Bind(&RunnableNoArgs::Run, base::Unretained(&r));
-  cb.Run();
-  EXPECT_EQ(2, calls);
-}
-
-struct RunnableOnePrimitiveArg {
-  explicit RunnableOnePrimitiveArg(int* calls) : calls(calls) {}
-  void Run(int a) const { (*calls)++; }
-
-  int* calls;
-};
-
-TEST(CommonTypeConvertersTest, BaseBindToMojoCallbackPrimitiveParam) {
-  mojo::Callback<void(int)> mojo_callback;
-  int calls = 0;
-  RunnableOnePrimitiveArg r(&calls);
-  mojo_callback = r;
-  mojo_callback.Run(0);
-  EXPECT_EQ(1, calls);
-
-  base::Callback<void(int)> base_callback =
-      base::Bind(&RunnableOnePrimitiveArg::Run, base::Unretained(&r));
-  mojo_callback = base_callback;
-  mojo_callback.Run(0);
-  EXPECT_EQ(2, calls);
-}
-
-struct RunnableOneMojoStringParam {
-  explicit RunnableOneMojoStringParam(int* calls) : calls(calls) {}
-  void Run(const String& s) const { (*calls)++; }
-
-  int* calls;
-};
-
-TEST(CommonTypeConvertersTest, BaseBindToMojoCallbackMojoStringParam) {
-  // The mojo type is a callback on mojo::String, but it'll expect to invoke
-  // callbacks with a parameter of type 'const Mojo::String&'.
-  mojo::Callback<void(mojo::String)> mojo_callback;
-  int calls = 0;
-  RunnableOneMojoStringParam r(&calls);
-  mojo_callback = r;
-  mojo_callback.Run(0);
-  EXPECT_EQ(1, calls);
-
-  base::Callback<void(const mojo::String&)> base_callback =
-      base::Bind(&RunnableOneMojoStringParam::Run, base::Unretained(&r));
-  mojo_callback = base_callback;
-  mojo_callback.Run(0);
-  EXPECT_EQ(2, calls);
-}
-
-using ExampleMoveOnlyType = Map<int, int>;
-
-struct RunnableOneMoveOnlyParam {
-  explicit RunnableOneMoveOnlyParam(int* calls) : calls(calls) {}
-
-  void Run(ExampleMoveOnlyType m) const { (*calls)++; }
-  int* calls;
-};
-
-TEST(CommonTypeConvertersTest, BaseBindToMoveOnlyParam) {
-  mojo::Callback<void(ExampleMoveOnlyType)> mojo_callback;
-  int calls = 0;
-  RunnableOneMoveOnlyParam r(&calls);
-  mojo_callback = r;
-  ExampleMoveOnlyType m;
-  mojo_callback.Run(m.Clone());
-  EXPECT_EQ(1, calls);
-
-  base::Callback<void(ExampleMoveOnlyType)> base_callback =
-      base::Bind(&RunnableOneMoveOnlyParam::Run, base::Unretained(&r));
-  mojo_callback = base_callback;
-  mojo_callback.Run(m.Clone());
-  EXPECT_EQ(2, calls);
-}
-
-}  // namespace
-}  // namespace test
-}  // namespace common
-}  // namespace mojo
diff --git a/mojo/common/dart/BUILD.gn b/mojo/common/dart/BUILD.gn
index 296e3c9..e296077 100644
--- a/mojo/common/dart/BUILD.gn
+++ b/mojo/common/dart/BUILD.gn
@@ -4,14 +4,14 @@
 
 import("//mojo/public/dart/rules.gni")
 
-dartzip_package("dart") {
+dart_pkg("dart") {
+  libs = [ "lib/tracing_helper.dart" ]
   sources = [
-    "lib/trace_controller_impl.dart",
-    "lib/tracing_helper.dart",
+    "lib/trace_provider_impl.dart",
     "pubspec.yaml",
   ]
   deps = [
     "//mojo/public/dart",
-    "//mojo/services/tracing/public/interfaces",
+    "//mojo/dart/mojo_services",
   ]
 }
diff --git a/mojo/common/dart/lib/trace_controller_impl.dart b/mojo/common/dart/lib/trace_controller_impl.dart
deleted file mode 100644
index 6cbc634..0000000
--- a/mojo/common/dart/lib/trace_controller_impl.dart
+++ /dev/null
@@ -1,46 +0,0 @@
-// Copyright 2015 The Chromium Authors. 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:mojo/application.dart';
-import 'package:mojo/bindings.dart';
-import 'package:mojo/core.dart';
-import 'package:mojom/tracing/tracing.mojom.dart';
-
-class TraceControllerImpl implements TraceController {
-  TraceControllerStub _stub;
-  TraceDataCollectorProxy _collector;
-  // TODO(rudominer) We currently ignore _categories.
-  String _categories;
-
-  TraceControllerImpl.fromEndpoint(MojoMessagePipeEndpoint e) {
-    _stub = TraceControllerStub.newFromEndpoint(e);
-    _stub.impl = this;
-  }
-
-  @override
-  void startTracing(String categories, TraceDataCollectorProxy collector) {
-    assert(_collector == null);
-    _collector = collector;
-    _categories = categories;
-  }
-
-  @override
-  void stopTracing() {
-    assert(_collector != null);
-    _collector.close();
-    _collector = null;
-  }
-
-  bool isActive() {
-    return _collector != null;
-  }
-
-  void sendTraceMessage(String message) {
-    if (_collector != null) {
-      _collector.ptr.dataCollected(message);
-    }
-  }
-}
diff --git a/mojo/common/dart/lib/trace_provider_impl.dart b/mojo/common/dart/lib/trace_provider_impl.dart
new file mode 100644
index 0000000..13901e0
--- /dev/null
+++ b/mojo/common/dart/lib/trace_provider_impl.dart
@@ -0,0 +1,46 @@
+// Copyright 2015 The Chromium Authors. 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:mojo/application.dart';
+import 'package:mojo/bindings.dart';
+import 'package:mojo/core.dart';
+import 'package:mojo_services/tracing/tracing.mojom.dart';
+
+class TraceProviderImpl implements TraceProvider {
+  TraceProviderStub _stub;
+  TraceRecorderProxy _recorder;
+  // TODO(rudominer) We currently ignore _categories.
+  String _categories;
+
+  TraceProviderImpl.fromEndpoint(MojoMessagePipeEndpoint e) {
+    _stub = TraceProviderStub.newFromEndpoint(e);
+    _stub.impl = this;
+  }
+
+  @override
+  void startTracing(String categories, TraceRecorderProxy recorder) {
+    assert(_recorder == null);
+    _recorder = recorder;
+    _categories = categories;
+  }
+
+  @override
+  void stopTracing() {
+    assert(_recorder != null);
+    _recorder.close();
+    _recorder = null;
+  }
+
+  bool isActive() {
+    return _recorder != null;
+  }
+
+  void sendTraceMessage(String message) {
+    if (_recorder != null) {
+      _recorder.ptr.record(message);
+    }
+  }
+}
diff --git a/mojo/common/dart/lib/tracing_helper.dart b/mojo/common/dart/lib/tracing_helper.dart
index f776d9a..23c121b 100644
--- a/mojo/common/dart/lib/tracing_helper.dart
+++ b/mojo/common/dart/lib/tracing_helper.dart
@@ -4,7 +4,7 @@
 
 library tracing;
 
-import 'trace_controller_impl.dart';
+import 'trace_provider_impl.dart';
 
 import 'dart:async';
 import 'dart:convert';
@@ -15,12 +15,12 @@
 import 'package:mojo/application.dart';
 import 'package:mojo/bindings.dart';
 import 'package:mojo/core.dart';
-import 'package:mojom/tracing/tracing.mojom.dart';
+import 'package:mojo_services/tracing/tracing.mojom.dart';
 
 // TracingHelper is used by Dart code running in the Mojo shell in order
 // to perform tracing.
 class TracingHelper {
-  TraceControllerImpl _impl;
+  TraceProviderImpl _impl;
   String _tid;
 
   // Construct an instance of TracingHelper from within your application's
@@ -36,9 +36,9 @@
     }
     _tid = "${appName}/${Isolate.current.hashCode.toString()}";
     ApplicationConnection connection = app.connectToApplication("mojo:tracing");
-    connection.provideService(TraceControllerName, (e) {
+    connection.provideService(TraceProviderName, (e) {
       assert(_impl == null);
-      _impl = new TraceControllerImpl.fromEndpoint(e);
+      _impl = new TraceProviderImpl.fromEndpoint(e);
     });
   }
 
diff --git a/mojo/common/interface_ptr_set_unittest.cc b/mojo/common/interface_ptr_set_unittest.cc
index 8edd4ca..848b268 100644
--- a/mojo/common/interface_ptr_set_unittest.cc
+++ b/mojo/common/interface_ptr_set_unittest.cc
@@ -5,8 +5,8 @@
 #include "mojo/common/interface_ptr_set.h"
 
 #include "base/message_loop/message_loop.h"
-#include "mojo/common/message_pump_mojo.h"
 #include "mojo/common/test_interfaces.mojom.h"
+#include "mojo/message_pump/message_pump_mojo.h"
 #include "mojo/public/cpp/bindings/binding.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
diff --git a/mojo/common/trace_controller_impl.cc b/mojo/common/trace_provider_impl.cc
similarity index 62%
rename from mojo/common/trace_controller_impl.cc
rename to mojo/common/trace_provider_impl.cc
index e08f88c..cc4fd77 100644
--- a/mojo/common/trace_controller_impl.cc
+++ b/mojo/common/trace_provider_impl.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "mojo/common/trace_controller_impl.h"
+#include "mojo/common/trace_provider_impl.h"
 
 #include "base/logging.h"
 #include "base/trace_event/trace_config.h"
@@ -12,19 +12,18 @@
 
 namespace mojo {
 
-TraceControllerImpl::TraceControllerImpl(
-    InterfaceRequest<tracing::TraceController> request)
+TraceProviderImpl::TraceProviderImpl(
+    InterfaceRequest<tracing::TraceProvider> request)
     : tracing_already_started_(false), binding_(this, request.Pass()) {
 }
 
-TraceControllerImpl::~TraceControllerImpl() {
+TraceProviderImpl::~TraceProviderImpl() {
 }
 
-void TraceControllerImpl::StartTracing(
-    const String& categories,
-    tracing::TraceDataCollectorPtr collector) {
-  DCHECK(!collector_.get());
-  collector_ = collector.Pass();
+void TraceProviderImpl::StartTracing(const String& categories,
+                                     tracing::TraceRecorderPtr collector) {
+  DCHECK(!recorder_.get());
+  recorder_ = collector.Pass();
   if (!tracing_already_started_) {
     std::string categories_str = categories.To<std::string>();
     base::trace_event::TraceLog::GetInstance()->SetEnabled(
@@ -34,21 +33,21 @@
   }
 }
 
-void TraceControllerImpl::StopTracing() {
-  DCHECK(collector_);
+void TraceProviderImpl::StopTracing() {
+  DCHECK(recorder_);
   base::trace_event::TraceLog::GetInstance()->SetDisabled();
 
   base::trace_event::TraceLog::GetInstance()->Flush(
-      base::Bind(&TraceControllerImpl::SendChunk, base::Unretained(this)));
+      base::Bind(&TraceProviderImpl::SendChunk, base::Unretained(this)));
 }
 
-void TraceControllerImpl::SendChunk(
+void TraceProviderImpl::SendChunk(
     const scoped_refptr<base::RefCountedString>& events_str,
     bool has_more_events) {
-  DCHECK(collector_);
-  collector_->DataCollected(mojo::String(events_str->data()));
+  DCHECK(recorder_);
+  recorder_->Record(mojo::String(events_str->data()));
   if (!has_more_events) {
-    collector_.reset();
+    recorder_.reset();
   }
 }
 
diff --git a/mojo/common/trace_controller_impl.h b/mojo/common/trace_provider_impl.h
similarity index 63%
rename from mojo/common/trace_controller_impl.h
rename to mojo/common/trace_provider_impl.h
index 482f709..82735a5 100644
--- a/mojo/common/trace_controller_impl.h
+++ b/mojo/common/trace_provider_impl.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef MOJO_COMMON_TRACING_CONTROLLER_IMPL_H_
-#define MOJO_COMMON_TRACING_CONTROLLER_IMPL_H_
+#ifndef MOJO_COMMON_TRACE_PROVIDER_IMPL_H_
+#define MOJO_COMMON_TRACE_PROVIDER_IMPL_H_
 
 #include "base/memory/ref_counted_memory.h"
 #include "mojo/public/cpp/bindings/interface_request.h"
@@ -12,11 +12,10 @@
 
 namespace mojo {
 
-class TraceControllerImpl : public tracing::TraceController {
+class TraceProviderImpl : public tracing::TraceProvider {
  public:
-  explicit TraceControllerImpl(
-      InterfaceRequest<tracing::TraceController> request);
-  ~TraceControllerImpl() override;
+  explicit TraceProviderImpl(InterfaceRequest<tracing::TraceProvider> request);
+  ~TraceProviderImpl() override;
 
   // Set to true if base::trace_event::TraceLog is enabled externally to this
   // class. If this is set to true this class will save the collector but not
@@ -27,21 +26,21 @@
   }
 
  private:
-  // tracing::TraceController implementation:
+  // tracing::TraceProvider implementation:
   void StartTracing(const String& categories,
-                    tracing::TraceDataCollectorPtr collector) override;
+                    tracing::TraceRecorderPtr collector) override;
   void StopTracing() override;
 
   void SendChunk(const scoped_refptr<base::RefCountedString>& events_str,
                  bool has_more_events);
 
   bool tracing_already_started_;
-  tracing::TraceDataCollectorPtr collector_;
-  StrongBinding<tracing::TraceController> binding_;
+  tracing::TraceRecorderPtr recorder_;
+  StrongBinding<tracing::TraceProvider> binding_;
 
-  DISALLOW_COPY_AND_ASSIGN(TraceControllerImpl);
+  DISALLOW_COPY_AND_ASSIGN(TraceProviderImpl);
 };
 
 }  // namespace mojo
 
-#endif  // MOJO_COMMON_TRACING_CONTROLLER_IMPL_H_
+#endif  // MOJO_COMMON_TRACE_PROVIDER_IMPL_H_
diff --git a/mojo/common/tracing_impl.cc b/mojo/common/tracing_impl.cc
index ec5dfa3..2a6eac1 100644
--- a/mojo/common/tracing_impl.cc
+++ b/mojo/common/tracing_impl.cc
@@ -5,7 +5,7 @@
 #include "mojo/common/tracing_impl.h"
 
 #include "base/trace_event/trace_event_impl.h"
-#include "mojo/common/trace_controller_impl.h"
+#include "mojo/common/trace_provider_impl.h"
 #include "mojo/public/cpp/application/application_connection.h"
 #include "mojo/public/cpp/application/application_impl.h"
 
@@ -23,8 +23,8 @@
 }
 
 void TracingImpl::Create(ApplicationConnection* connection,
-                         InterfaceRequest<tracing::TraceController> request) {
-  new TraceControllerImpl(request.Pass());
+                         InterfaceRequest<tracing::TraceProvider> request) {
+  new TraceProviderImpl(request.Pass());
 }
 
 }  // namespace mojo
diff --git a/mojo/common/tracing_impl.h b/mojo/common/tracing_impl.h
index e245bd6..a996d5c 100644
--- a/mojo/common/tracing_impl.h
+++ b/mojo/common/tracing_impl.h
@@ -13,7 +13,7 @@
 
 class ApplicationImpl;
 
-class TracingImpl : public InterfaceFactory<tracing::TraceController> {
+class TracingImpl : public InterfaceFactory<tracing::TraceProvider> {
  public:
   TracingImpl();
   ~TracingImpl() override;
@@ -23,9 +23,9 @@
   void Initialize(ApplicationImpl* app);
 
  private:
-  // InterfaceFactory<tracing::TraceController> implementation.
+  // InterfaceFactory<tracing::TraceProvider> implementation.
   void Create(ApplicationConnection* connection,
-              InterfaceRequest<tracing::TraceController> request) override;
+              InterfaceRequest<tracing::TraceProvider> request) override;
 
   DISALLOW_COPY_AND_ASSIGN(TracingImpl);
 };
diff --git a/mojo/converters/array_string/BUILD.gn b/mojo/converters/array_string/BUILD.gn
new file mode 100644
index 0000000..8a36103
--- /dev/null
+++ b/mojo/converters/array_string/BUILD.gn
@@ -0,0 +1,28 @@
+# Copyright 2015 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+source_set("array_string") {
+  sources = [
+    "array_string_type_converters.cc",
+    "array_string_type_converters.h",
+  ]
+
+  deps = [
+    "//base",
+    "//mojo/public/cpp/bindings",
+  ]
+}
+
+source_set("tests") {
+  testonly = true
+  sources = [
+    "array_string_type_converters_unittest.cc",
+  ]
+
+  deps = [
+    ":array_string",
+    "//base",
+    "//testing/gtest",
+  ]
+}
diff --git a/mojo/converters/array_string/array_string_type_converters.cc b/mojo/converters/array_string/array_string_type_converters.cc
new file mode 100644
index 0000000..02019f0
--- /dev/null
+++ b/mojo/converters/array_string/array_string_type_converters.cc
@@ -0,0 +1,29 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "mojo/converters/array_string/array_string_type_converters.h"
+
+#include <string>
+
+#include "base/strings/utf_string_conversions.h"
+
+namespace mojo {
+
+std::string TypeConverter<std::string, Array<uint8_t>>::Convert(
+    const Array<uint8_t>& input) {
+  if (input.is_null())
+    return std::string();
+
+  return std::string(reinterpret_cast<const char*>(&input.front()),
+                     input.size());
+}
+
+Array<uint8_t> TypeConverter<Array<uint8_t>, std::string>::Convert(
+    const std::string& input) {
+  Array<uint8_t> result(input.size());
+  memcpy(&result.front(), input.c_str(), input.size());
+  return result.Pass();
+}
+
+}  // namespace mojo
diff --git a/mojo/converters/array_string/array_string_type_converters.h b/mojo/converters/array_string/array_string_type_converters.h
new file mode 100644
index 0000000..f5e1996
--- /dev/null
+++ b/mojo/converters/array_string/array_string_type_converters.h
@@ -0,0 +1,32 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef MOJO_CONVERTERS_ARRAY_STRING_ARRAY_STRING_TYPE_CONVERTERS_H_
+#define MOJO_CONVERTERS_ARRAY_STRING_ARRAY_STRING_TYPE_CONVERTERS_H_
+
+#include "base/strings/string16.h"
+#include "base/strings/string_piece.h"
+#include "mojo/public/cpp/bindings/array.h"
+#include "mojo/public/cpp/bindings/string.h"
+#include "mojo/public/cpp/bindings/type_converter.h"
+
+namespace mojo {
+
+// TODO(erg): In the very long term, we will want to remove conversion between
+// std::strings and arrays of unsigned bytes. However, there is too much code
+// across chrome which uses std::string as a bag of bytes that we probably
+// don't want to roll this function at each callsite.
+template <>
+struct TypeConverter<std::string, Array<uint8_t>> {
+  static std::string Convert(const Array<uint8_t>& input);
+};
+
+template <>
+struct TypeConverter<Array<uint8_t>, std::string> {
+  static Array<uint8_t> Convert(const std::string& input);
+};
+
+}  // namespace mojo
+
+#endif  // MOJO_CONVERTERS_ARRAY_STRING_ARRAY_STRING_TYPE_CONVERTERS_H_
diff --git a/mojo/converters/array_string/array_string_type_converters_unittest.cc b/mojo/converters/array_string/array_string_type_converters_unittest.cc
new file mode 100644
index 0000000..a28f571
--- /dev/null
+++ b/mojo/converters/array_string/array_string_type_converters_unittest.cc
@@ -0,0 +1,38 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "mojo/converters/array_string/array_string_type_converters.h"
+
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace mojo {
+namespace common {
+namespace test {
+namespace {
+
+TEST(CommonTypeConvertersTest, ArrayUint8ToStdString) {
+  Array<uint8_t> data(4);
+  data[0] = 'd';
+  data[1] = 'a';
+  data[2] = 't';
+  data[3] = 'a';
+
+  EXPECT_EQ("data", data.To<std::string>());
+}
+
+TEST(CommonTypeConvertersTest, StdStringToArrayUint8) {
+  std::string input("data");
+  Array<uint8_t> data = Array<uint8_t>::From(input);
+
+  ASSERT_EQ(4ul, data.size());
+  EXPECT_EQ('d', data[0]);
+  EXPECT_EQ('a', data[1]);
+  EXPECT_EQ('t', data[2]);
+  EXPECT_EQ('a', data[3]);
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace common
+}  // namespace mojo
diff --git a/mojo/converters/base/BUILD.gn b/mojo/converters/base/BUILD.gn
new file mode 100644
index 0000000..3779edf
--- /dev/null
+++ b/mojo/converters/base/BUILD.gn
@@ -0,0 +1,30 @@
+# Copyright 2015 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+source_set("base") {
+  sources = [
+    "base_type_converters.cc",
+    "base_type_converters.h",
+  ]
+
+  deps = [
+    "//base",
+    "//mojo/public/cpp/bindings",
+  ]
+}
+
+source_set("tests") {
+  testonly = true
+
+  sources = [
+    "base_type_converters_unittest.cc",
+  ]
+
+  deps = [
+    ":base",
+    "//base",
+    "//mojo/public/cpp/bindings",
+    "//testing/gtest",
+  ]
+}
diff --git a/mojo/converters/base/base_type_converters.cc b/mojo/converters/base/base_type_converters.cc
new file mode 100644
index 0000000..d4649ce
--- /dev/null
+++ b/mojo/converters/base/base_type_converters.cc
@@ -0,0 +1,40 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "mojo/converters/base/base_type_converters.h"
+
+#include <string>
+
+#include "base/strings/utf_string_conversions.h"
+
+namespace mojo {
+
+// static
+String TypeConverter<String, base::StringPiece>::Convert(
+    const base::StringPiece& input) {
+  if (input.empty()) {
+    char c = 0;
+    return String(&c, 0);
+  }
+  return String(input.data(), input.size());
+}
+// static
+base::StringPiece TypeConverter<base::StringPiece, String>::Convert(
+    const String& input) {
+  return input.get();
+}
+
+// static
+String TypeConverter<String, base::string16>::Convert(
+    const base::string16& input) {
+  return TypeConverter<String, base::StringPiece>::Convert(
+      base::UTF16ToUTF8(input));
+}
+// static
+base::string16 TypeConverter<base::string16, String>::Convert(
+    const String& input) {
+  return base::UTF8ToUTF16(input.To<base::StringPiece>());
+}
+
+}  // namespace mojo
diff --git a/mojo/converters/base/base_type_converters.h b/mojo/converters/base/base_type_converters.h
new file mode 100644
index 0000000..c83bc90
--- /dev/null
+++ b/mojo/converters/base/base_type_converters.h
@@ -0,0 +1,38 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef MOJO_CONVERTERS_BASE_BASE_TYPE_CONVERTERS_H_
+#define MOJO_CONVERTERS_BASE_BASE_TYPE_CONVERTERS_H_
+
+#include "base/strings/string16.h"
+#include "base/strings/string_piece.h"
+#include "mojo/public/cpp/bindings/array.h"
+#include "mojo/public/cpp/bindings/string.h"
+#include "mojo/public/cpp/bindings/type_converter.h"
+
+namespace mojo {
+
+template <>
+struct TypeConverter<String, base::StringPiece> {
+  static String Convert(const base::StringPiece& input);
+};
+
+template <>
+struct TypeConverter<base::StringPiece, String> {
+  static base::StringPiece Convert(const String& input);
+};
+
+template <>
+struct TypeConverter<String, base::string16> {
+  static String Convert(const base::string16& input);
+};
+
+template <>
+struct TypeConverter<base::string16, String> {
+  static base::string16 Convert(const String& input);
+};
+
+}  // namespace mojo
+
+#endif  // MOJO_CONVERTERS_BASE_BASE_TYPE_CONVERTERS_H_
diff --git a/mojo/converters/base/base_type_converters_unittest.cc b/mojo/converters/base/base_type_converters_unittest.cc
new file mode 100644
index 0000000..351eebc
--- /dev/null
+++ b/mojo/converters/base/base_type_converters_unittest.cc
@@ -0,0 +1,66 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "mojo/converters/base/base_type_converters.h"
+
+#include "base/bind.h"
+#include "base/strings/utf_string_conversions.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace mojo {
+namespace {
+
+void ExpectEqualsStringPiece(const std::string& expected,
+                             const base::StringPiece& str) {
+  EXPECT_EQ(expected, str.as_string());
+}
+
+void ExpectEqualsMojoString(const std::string& expected, const String& str) {
+  EXPECT_EQ(expected, str.get());
+}
+
+void ExpectEqualsString16(const base::string16& expected,
+                          const base::string16& actual) {
+  EXPECT_EQ(expected, actual);
+}
+
+void ExpectEqualsMojoString(const base::string16& expected, const String& str) {
+  EXPECT_EQ(expected, str.To<base::string16>());
+}
+
+TEST(BaseTypeConvertersTest, StringPiece) {
+  std::string kText("hello world");
+
+  base::StringPiece string_piece(kText);
+  String mojo_string(String::From(string_piece));
+
+  ExpectEqualsMojoString(kText, mojo_string);
+  ExpectEqualsStringPiece(kText, mojo_string.To<base::StringPiece>());
+
+  // Test implicit construction and conversion:
+  ExpectEqualsMojoString(kText, String::From(string_piece));
+  ExpectEqualsStringPiece(kText, mojo_string.To<base::StringPiece>());
+
+  // Test null String:
+  base::StringPiece empty_string_piece = String().To<base::StringPiece>();
+  EXPECT_TRUE(empty_string_piece.empty());
+}
+
+TEST(BaseTypeConvertersTest, String16) {
+  const base::string16 string16(base::ASCIIToUTF16("hello world"));
+  const String mojo_string(String::From(string16));
+
+  ExpectEqualsMojoString(string16, mojo_string);
+  EXPECT_EQ(string16, mojo_string.To<base::string16>());
+
+  // Test implicit construction and conversion:
+  ExpectEqualsMojoString(string16, String::From(string16));
+  ExpectEqualsString16(string16, mojo_string.To<base::string16>());
+
+  // Test empty string conversion.
+  ExpectEqualsMojoString(base::string16(), String::From(base::string16()));
+}
+
+}  // namespace
+}  // namespace mojo
diff --git a/mojo/converters/url/BUILD.gn b/mojo/converters/url/BUILD.gn
new file mode 100644
index 0000000..4082c67
--- /dev/null
+++ b/mojo/converters/url/BUILD.gn
@@ -0,0 +1,30 @@
+# Copyright 2015 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+source_set("url") {
+  sources = [
+    "url_type_converters.cc",
+    "url_type_converters.h",
+  ]
+
+  deps = [
+    "//mojo/public/cpp/bindings",
+    "//url",
+  ]
+}
+
+source_set("tests") {
+  testonly = true
+
+  sources = [
+    "url_type_converters_unittest.cc",
+  ]
+
+  deps = [
+    ":url",
+    "//mojo/public/cpp/bindings",
+    "//testing/gtest",
+    "//url",
+  ]
+}
diff --git a/mojo/converters/url/url_type_converters.cc b/mojo/converters/url/url_type_converters.cc
new file mode 100644
index 0000000..8b504ff
--- /dev/null
+++ b/mojo/converters/url/url_type_converters.cc
@@ -0,0 +1,19 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "mojo/converters/url/url_type_converters.h"
+
+#include "url/gurl.h"
+
+namespace mojo {
+
+String TypeConverter<String, GURL>::Convert(const GURL& input) {
+  return String(input.spec());
+}
+
+GURL TypeConverter<GURL, String>::Convert(const String& input) {
+  return GURL(input.get());
+}
+
+}  // namespace mojo
diff --git a/mojo/converters/url/url_type_converters.h b/mojo/converters/url/url_type_converters.h
new file mode 100644
index 0000000..7842d54
--- /dev/null
+++ b/mojo/converters/url/url_type_converters.h
@@ -0,0 +1,26 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef MOJO_CONVERTERS_URL_URL_TYPE_CONVERTERS_H_
+#define MOJO_CONVERTERS_URL_URL_TYPE_CONVERTERS_H_
+
+#include "mojo/public/cpp/bindings/type_converter.h"
+#include "mojo/public/cpp/bindings/string.h"
+
+class GURL;
+
+namespace mojo {
+template <>
+struct TypeConverter<String, GURL> {
+  static String Convert(const GURL& input);
+};
+
+template <>
+struct TypeConverter<GURL, String> {
+  static GURL Convert(const String& input);
+};
+
+}  // namespace mojo
+
+#endif  // MOJO_CONVERTERS_URL_URL_TYPE_CONVERTERS_H_
diff --git a/mojo/converters/url/url_type_converters_unittest.cc b/mojo/converters/url/url_type_converters_unittest.cc
new file mode 100644
index 0000000..bc94074
--- /dev/null
+++ b/mojo/converters/url/url_type_converters_unittest.cc
@@ -0,0 +1,31 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "mojo/converters/url/url_type_converters.h"
+
+#include "mojo/public/cpp/bindings/string.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "url/gurl.h"
+
+namespace mojo {
+namespace {
+
+TEST(UrlTypeConvertersTest, URL) {
+  GURL url("mojo:foo");
+  String mojo_string(String::From(url));
+
+  ASSERT_EQ(url.spec(), mojo_string);
+  EXPECT_EQ(url.spec(), mojo_string.To<GURL>().spec());
+  EXPECT_EQ(url.spec(), String::From(url));
+
+  GURL invalid = String().To<GURL>();
+  ASSERT_TRUE(invalid.spec().empty());
+
+  String string_from_invalid = String::From(invalid);
+  EXPECT_FALSE(string_from_invalid.is_null());
+  ASSERT_EQ(0U, string_from_invalid.size());
+}
+
+}  // namespace
+}  // namespace mojo
diff --git a/mojo/dart/BUILD.gn b/mojo/dart/BUILD.gn
new file mode 100644
index 0000000..88cc7fe
--- /dev/null
+++ b/mojo/dart/BUILD.gn
@@ -0,0 +1,14 @@
+# Copyright 2014 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+group("dart") {
+  deps = [
+    "//mojo/dart/apptest",
+    "//mojo/dart/dart_snapshotter($host_toolchain)",
+    "//mojo/dart/http_load_test",
+    "//mojo/dart/mojom",
+    "//mojo/dart/mojo_services",
+    "//mojo/dart/observatory_test",
+  ]
+}
diff --git a/mojo/dart/apptest/BUILD.gn b/mojo/dart/apptest/BUILD.gn
index 8d4092f..36e25c4 100644
--- a/mojo/dart/apptest/BUILD.gn
+++ b/mojo/dart/apptest/BUILD.gn
@@ -4,24 +4,13 @@
 
 import("//mojo/public/dart/rules.gni")
 
-dartzip_package("apptest") {
-  uses_pub = true
+dart_pkg("apptest") {
+  libs = [ "lib/apptest.dart" ]
   sources = [
-    "lib/apptest.dart",
     "pubspec.yaml",
   ]
   deps = [
     "//mojo/public/dart",
-  ]
-}
-
-dart_pkg("apptest_pkg") {
-  entrypoints = [ "lib/apptest.dart" ]
-  sources = [
-    "pubspec.yaml",
-  ]
-  deps = [
-    "//mojo/public/dart:mojo",
     "//third_party/dart-pkg",
   ]
 }
diff --git a/mojo/dart/apptest/lib/apptest.dart b/mojo/dart/apptest/lib/apptest.dart
index 9d02309..96c76f0 100644
--- a/mojo/dart/apptest/lib/apptest.dart
+++ b/mojo/dart/apptest/lib/apptest.dart
@@ -10,8 +10,7 @@
 import 'package:mojo/bindings.dart';
 import 'package:mojo/core.dart';
 
-// Import and reexport the test package. We are a *.dartzip file designed to
-// be linked into your_apptest.mojo file and are your main entrypoint.
+// Import and reexport the test package.
 import 'package:test/test.dart';
 export 'package:test/test.dart';
 
diff --git a/mojo/dart/dart_snapshotter/BUILD.gn b/mojo/dart/dart_snapshotter/BUILD.gn
new file mode 100644
index 0000000..4174569
--- /dev/null
+++ b/mojo/dart/dart_snapshotter/BUILD.gn
@@ -0,0 +1,27 @@
+# Copyright 2014 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+executable("dart_snapshotter") {
+  sources = [
+    "main.cc",
+    "vm.cc",
+    "vm.h",
+  ]
+
+  deps = [
+    "//base",
+    "//build/config/sanitizers:deps",
+    "//dart/runtime/vm:libdart_platform",
+    "//dart/runtime:libdart",
+    "//mojo/common",
+    "//mojo/dart/embedder:dart_snapshot_cc",
+    "//mojo/edk/system",
+    "//mojo/environment:chromium",
+    "//mojo/public/cpp/system",
+    "//mojo/public/cpp/utility",
+    "//mojo/public/interfaces/application",
+    "//third_party/zlib",
+    "//tonic",
+  ]
+}
diff --git a/mojo/dart/dart_snapshotter/main.cc b/mojo/dart/dart_snapshotter/main.cc
new file mode 100644
index 0000000..48e5341
--- /dev/null
+++ b/mojo/dart/dart_snapshotter/main.cc
@@ -0,0 +1,100 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <iostream>
+
+#include "base/at_exit.h"
+#include "base/basictypes.h"
+#include "base/command_line.h"
+#include "base/files/file_path.h"
+#include "base/files/file_util.h"
+#include "base/logging.h"
+#include "base/process/memory.h"
+#include "dart/runtime/include/dart_api.h"
+#include "mojo/dart/dart_snapshotter/vm.h"
+#include "mojo/edk/embedder/embedder.h"
+#include "mojo/edk/embedder/simple_platform_support.h"
+#include "tonic/dart_error.h"
+#include "tonic/dart_isolate_scope.h"
+#include "tonic/dart_library_loader.h"
+#include "tonic/dart_library_provider_files.h"
+#include "tonic/dart_script_loader_sync.h"
+#include "tonic/dart_state.h"
+
+const char kHelp[] = "help";
+const char kPackageRoot[] = "package-root";
+const char kSnapshot[] = "snapshot";
+
+const uint8_t magic_number[] = { 0xf5, 0xf5, 0xdc, 0xdc };
+
+void Usage() {
+  std::cerr << "Usage: dart_snapshotter"
+            << " --" << kPackageRoot << " --" << kSnapshot
+            << " <dart-app>" << std::endl;
+}
+
+void WriteSnapshot(base::FilePath path) {
+  uint8_t* buffer;
+  intptr_t size;
+  CHECK(!tonic::LogIfError(Dart_CreateScriptSnapshot(&buffer, &size)));
+
+  intptr_t magic_number_len = sizeof(magic_number);
+  CHECK_EQ(base::WriteFile(
+      path, reinterpret_cast<const char*>(magic_number), sizeof(magic_number)),
+      magic_number_len);
+  CHECK(base::AppendToFile(
+      path, reinterpret_cast<const char*>(buffer), size));
+}
+
+int main(int argc, const char* argv[]) {
+  base::AtExitManager exit_manager;
+  base::EnableTerminationOnHeapCorruption();
+  base::CommandLine::Init(argc, argv);
+
+  const base::CommandLine& command_line =
+      *base::CommandLine::ForCurrentProcess();
+
+  if (command_line.HasSwitch(kHelp) || command_line.GetArgs().empty()) {
+    Usage();
+    return 0;
+  }
+
+  // Initialize mojo.
+  mojo::embedder::Init(
+      make_scoped_ptr(new mojo::embedder::SimplePlatformSupport()));
+
+  InitDartVM();
+
+  CHECK(command_line.HasSwitch(kPackageRoot)) << "Need --package-root";
+  CHECK(command_line.HasSwitch(kSnapshot)) << "Need --snapshot";
+  auto args = command_line.GetArgs();
+  CHECK(args.size() == 1);
+
+  Dart_Isolate isolate = CreateDartIsolate();
+  CHECK(isolate);
+
+  tonic::DartIsolateScope scope(isolate);
+  tonic::DartApiScope api_scope;
+
+  auto isolate_data = SnapshotterDartState::Current();
+  CHECK(isolate_data != nullptr);
+
+  // Use tonic's library tag handler.
+  CHECK(!tonic::LogIfError(Dart_SetLibraryTagHandler(
+            tonic::DartLibraryLoader::HandleLibraryTag)));
+
+  // Use tonic's file system library provider.
+  isolate_data->set_library_provider(
+      new tonic::DartLibraryProviderFiles(
+          command_line.GetSwitchValuePath(kPackageRoot)));
+
+  // Load script.
+  tonic::DartScriptLoaderSync::LoadScript(args[0],
+                                          isolate_data->library_provider());
+
+  // Write snapshot.
+  WriteSnapshot(command_line.GetSwitchValuePath(kSnapshot));
+
+  return 0;
+}
diff --git a/mojo/dart/dart_snapshotter/test/dart_snapshotter_test.py b/mojo/dart/dart_snapshotter/test/dart_snapshotter_test.py
new file mode 100755
index 0000000..60fb145
--- /dev/null
+++ b/mojo/dart/dart_snapshotter/test/dart_snapshotter_test.py
@@ -0,0 +1,83 @@
+#!/usr/bin/env python
+# Copyright 2015 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import argparse
+import hashlib
+import os
+import subprocess
+import sys
+import tempfile
+
+SNAPSHOT_TEST_DIR = os.path.dirname(os.path.abspath(__file__))
+SRC_ROOT = os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(
+    SNAPSHOT_TEST_DIR))))
+DART_DIR = os.path.join(SRC_ROOT, 'dart')
+
+VM_SNAPSHOT_FILES=[
+  # Header files.
+  'datastream.h',
+  'object.h',
+  'raw_object.h',
+  'snapshot.h',
+  'snapshot_ids.h',
+  'symbols.h',
+  # Source files.
+  'dart.cc',
+  'dart_api_impl.cc',
+  'object.cc',
+  'raw_object.cc',
+  'raw_object_snapshot.cc',
+  'snapshot.cc',
+  'symbols.cc',
+]
+
+def makeSnapshotHashString():
+  vmhash = hashlib.md5()
+  for vmfilename in VM_SNAPSHOT_FILES:
+    vmfilepath = os.path.join(DART_DIR, 'runtime', 'vm', vmfilename)
+    with open(vmfilepath) as vmfile:
+      vmhash.update(vmfile.read())
+  return vmhash.hexdigest()
+
+def main():
+  parser = argparse.ArgumentParser(description='Tests Dart snapshotting')
+  parser.add_argument("--build-dir",
+                      dest="build_dir",
+                      metavar="<build-directory>",
+                      type=str,
+                      required=True,
+                      help="The directory containing the Mojo build.")
+  args = parser.parse_args()
+  dart_snapshotter = os.path.join(args.build_dir, 'dart_snapshotter')
+  package_root = os.path.join(args.build_dir, 'gen', 'dart-pkg', 'packages')
+  main_dart = os.path.join(
+      args.build_dir, 'gen', 'dart-pkg', 'mojo_dart_hello', 'lib', 'main.dart')
+  snapshot = tempfile.mktemp()
+
+  if not os.path.isfile(dart_snapshotter):
+    print "file not found: " + dart_snapshotter
+    return 1
+  subprocess.check_call([
+    dart_snapshotter,
+    main_dart,
+    '--package-root=%s' % package_root,
+    '--snapshot=%s' % snapshot,
+  ])
+  if not os.path.isfile(snapshot):
+    return 1
+
+  expected_hash = makeSnapshotHashString()
+  actual_hash = ""
+  with open(snapshot) as snapshot_file:
+    snapshot_file.seek(20)
+    actual_hash = snapshot_file.read(32)
+  if not actual_hash == expected_hash:
+    print ('wrong hash: actual = %s, expected = %s'
+           % (actual_hash, expected_hash))
+    return 1
+  return 0
+
+if __name__ == '__main__':
+  sys.exit(main())
diff --git a/mojo/dart/dart_snapshotter/vm.cc b/mojo/dart/dart_snapshotter/vm.cc
new file mode 100644
index 0000000..f95cf5a
--- /dev/null
+++ b/mojo/dart/dart_snapshotter/vm.cc
@@ -0,0 +1,44 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "mojo/dart/dart_snapshotter/vm.h"
+
+#include "base/logging.h"
+#include "tonic/dart_error.h"
+#include "tonic/dart_state.h"
+
+namespace mojo {
+namespace dart {
+extern const uint8_t* vm_isolate_snapshot_buffer;
+extern const uint8_t* isolate_snapshot_buffer;
+}
+}
+
+static const char* kDartArgs[] = {
+    "--enable_mirrors=false",
+};
+
+void InitDartVM() {
+  CHECK(Dart_SetVMFlags(arraysize(kDartArgs), kDartArgs));
+  CHECK(Dart_Initialize(mojo::dart::vm_isolate_snapshot_buffer, nullptr,
+                        nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
+                        nullptr, nullptr));
+}
+
+Dart_Isolate CreateDartIsolate() {
+  CHECK(mojo::dart::isolate_snapshot_buffer);
+  char* error = nullptr;
+  auto isolate_data = new SnapshotterDartState();
+  CHECK(isolate_data != nullptr);
+  Dart_Isolate isolate = Dart_CreateIsolate("dart:snapshot",
+                                            "main",
+                                            mojo::dart::isolate_snapshot_buffer,
+                                            nullptr,
+                                            isolate_data,
+                                            &error);
+  CHECK(isolate) << error;
+  Dart_ExitIsolate();
+  isolate_data->SetIsolate(isolate);
+  return isolate;
+}
diff --git a/mojo/dart/dart_snapshotter/vm.h b/mojo/dart/dart_snapshotter/vm.h
new file mode 100644
index 0000000..f6330dc
--- /dev/null
+++ b/mojo/dart/dart_snapshotter/vm.h
@@ -0,0 +1,45 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef MOJO_DART_DART_SNAPSHOTTER_VM_H_
+#define MOJO_DART_DART_SNAPSHOTTER_VM_H_
+
+#include "dart/runtime/include/dart_api.h"
+#include "tonic/dart_library_provider.h"
+#include "tonic/dart_state.h"
+
+class SnapshotterDartState : public tonic::DartState {
+ public:
+  SnapshotterDartState() : library_provider_(nullptr) {
+  };
+
+  tonic::DartLibraryProvider* library_provider() const {
+    return library_provider_.get();
+  }
+
+  void set_library_provider(tonic::DartLibraryProvider* library_provider) {
+    library_provider_.reset(library_provider);
+    DCHECK(library_provider_.get() == library_provider);
+  }
+
+  static SnapshotterDartState* From(Dart_Isolate isolate) {
+    return reinterpret_cast<SnapshotterDartState*>(DartState::From(isolate));
+  }
+
+  static SnapshotterDartState* Current() {
+    return reinterpret_cast<SnapshotterDartState*>(DartState::Current());
+  }
+
+  static SnapshotterDartState* Cast(void* data) {
+    return reinterpret_cast<SnapshotterDartState*>(data);
+  }
+
+ private:
+  std::unique_ptr<tonic::DartLibraryProvider> library_provider_;
+};
+
+void InitDartVM();
+Dart_Isolate CreateDartIsolate();
+
+#endif  // MOJO_DART_DART_SNAPSHOTTER_VM_H_
diff --git a/mojo/dart/embedder/BUILD.gn b/mojo/dart/embedder/BUILD.gn
index ba1e858..d21d1ae 100644
--- a/mojo/dart/embedder/BUILD.gn
+++ b/mojo/dart/embedder/BUILD.gn
@@ -43,7 +43,7 @@
     "//dart/runtime:libdart",
     "//dart/runtime/bin:libdart_embedder_noio",
     "//third_party/dart-pkg",
-    "//mojo/common",
+    "//mojo/message_pump",
     "//mojo/public/c/system",
     "//mojo/public/cpp/system",
     "//mojo/services/network/public/interfaces",
@@ -410,3 +410,13 @@
     rebase_path(output),
   ]
 }
+
+source_set("dart_snapshot_cc") {
+  sources = [
+    "$root_gen_dir/dart_snapshot.cc",
+  ]
+
+  deps = [
+    ":generate_snapshot_file",
+  ]
+}
diff --git a/mojo/dart/embedder/dart_controller.cc b/mojo/dart/embedder/dart_controller.cc
index ff64c9c..ad86db9 100644
--- a/mojo/dart/embedder/dart_controller.cc
+++ b/mojo/dart/embedder/dart_controller.cc
@@ -13,11 +13,11 @@
 #include "base/sys_info.h"
 #include "dart/runtime/include/dart_api.h"
 #include "dart/runtime/include/dart_native_api.h"
-#include "mojo/common/message_pump_mojo.h"
 #include "mojo/dart/embedder/builtin.h"
 #include "mojo/dart/embedder/dart_controller.h"
 #include "mojo/dart/embedder/mojo_dart_state.h"
 #include "mojo/dart/embedder/vmservice.h"
+#include "mojo/message_pump/message_pump_mojo.h"
 #include "mojo/public/c/system/core.h"
 #include "tonic/dart_converter.h"
 #include "tonic/dart_debugger.h"
@@ -27,6 +27,7 @@
 #include "tonic/dart_library_provider.h"
 #include "tonic/dart_library_provider_files.h"
 #include "tonic/dart_library_provider_network.h"
+#include "tonic/dart_script_loader_sync.h"
 
 namespace mojo {
 namespace dart {
@@ -39,6 +40,8 @@
 static const char* kIsolateLibURL = "dart:isolate";
 static const char* kCoreLibURL = "dart:core";
 
+static uint8_t snapshot_magic_number[] = { 0xf5, 0xf5, 0xdc, 0xdc };
+
 static Dart_Handle SetWorkingDirectory(Dart_Handle builtin_lib) {
   base::FilePath current_dir;
   PathService::Get(base::DIR_CURRENT, &current_dir);
@@ -299,6 +302,8 @@
     } else {
       package_root_str = package_root.c_str();
     }
+    isolate_data->library_loader().set_magic_number(
+        snapshot_magic_number, sizeof(snapshot_magic_number));
     if (use_network_loader) {
       mojo::NetworkService* network_service = isolate_data->network_service();
       isolate_data->set_library_provider(
@@ -349,12 +354,21 @@
       // Special case for starting and stopping the the handle watcher isolate.
       LoadEmptyScript(script_uri);
     } else {
-      LoadScript(script_uri, isolate_data->library_provider());
+      tonic::DartScriptLoaderSync::LoadScript(
+          script_uri,
+          isolate_data->library_provider());
     }
 
     InitializeDartMojoIo();
   }
 
+  if (isolate_data->library_loader().error_during_loading()) {
+    *error = strdup("Library loader reported error during loading. See log.");
+    Dart_EnterIsolate(isolate);
+    Dart_ShutdownIsolate();
+    return nullptr;
+  }
+
   // Make the isolate runnable so that it is ready to handle messages.
   bool retval = Dart_IsolateMakeRunnable(isolate);
   if (!retval) {
@@ -606,34 +620,24 @@
                            nullptr, nullptr, nullptr, nullptr,
                            entropy);
   CHECK(result);
+  initialized_ = true;
+}
+
+void DartController::BlockForServiceIsolate() {
+  base::AutoLock al(lock_);
+  BlockForServiceIsolateLocked();
+}
+
+void DartController::BlockForServiceIsolateLocked() {
+  if (service_isolate_running_) {
+    return;
+  }
   // By waiting for the load port, we ensure that the service isolate is fully
   // running before returning.
   Dart_ServiceWaitForLoadPort();
-  initialized_ = true;
   service_isolate_running_ = true;
 }
 
-void DartController::BlockWaitingForDependencies(
-      tonic::DartLibraryLoader* loader,
-      const std::unordered_set<tonic::DartDependency*>& dependencies) {
-  {
-    scoped_refptr<base::SingleThreadTaskRunner> task_runner =
-        base::MessageLoop::current()->task_runner();
-    base::RunLoop run_loop;
-    task_runner->PostTask(
-        FROM_HERE,
-        base::Bind(
-            &tonic::DartLibraryLoader::WaitForDependencies,
-            base::Unretained(loader),
-            dependencies,
-            base::Bind(
-               base::IgnoreResult(&base::SingleThreadTaskRunner::PostTask),
-               task_runner.get(), FROM_HERE,
-               run_loop.QuitClosure())));
-    run_loop.Run();
-  }
-}
-
 void DartController::LoadEmptyScript(const std::string& script_uri) {
   Dart_Handle uri = Dart_NewStringFromUTF8(
       reinterpret_cast<const uint8_t*>(script_uri.c_str()),
@@ -646,60 +650,11 @@
   tonic::LogIfError(Dart_FinalizeLoading(true));
 }
 
-void DartController::InnerLoadScript(
-    const std::string& script_uri,
-    tonic::DartLibraryProvider* library_provider) {
-  // When spawning isolates, Dart expects the script loading to be completed
-  // before returning from the isolate creation callback. The mojo dart
-  // controller also expects the isolate to be finished loading a script
-  // before the isolate creation callback returns.
-
-  // We block here by creating a nested message pump and waiting for the load
-  // to complete.
-
-  DCHECK(base::MessageLoop::current() != nullptr);
-  base::MessageLoop::ScopedNestableTaskAllower allow(
-      base::MessageLoop::current());
-
-  // Initiate the load.
-  auto dart_state = tonic::DartState::Current();
-  DCHECK(library_provider != nullptr);
-  tonic::DartLibraryLoader& loader = dart_state->library_loader();
-  loader.set_library_provider(library_provider);
-  std::unordered_set<tonic::DartDependency*> dependencies;
-  {
-    tonic::DartDependencyCatcher dependency_catcher(loader);
-    loader.LoadScript(script_uri);
-    // Copy dependencies before dependency_catcher goes out of scope.
-    dependencies = std::unordered_set<tonic::DartDependency*>(
-        dependency_catcher.dependencies());
-  }
-
-  // Run inner message loop.
-  BlockWaitingForDependencies(&loader, dependencies);
-
-  // Finalize loading.
-  tonic::LogIfError(Dart_FinalizeLoading(true));
-}
-
-void DartController::LoadScript(const std::string& script_uri,
-                                tonic::DartLibraryProvider* library_provider) {
-  if (base::MessageLoop::current() == nullptr) {
-    // Threads running on the Dart thread pool may not have a message loop,
-    // we rely on a message loop during loading. Create a temporary one
-    // here.
-    base::MessageLoop message_loop(common::MessagePumpMojo::Create());
-    InnerLoadScript(script_uri, library_provider);
-  } else {
-    // Thread has a message loop, use it.
-    InnerLoadScript(script_uri, library_provider);
-  }
-}
-
 bool DartController::RunSingleDartScript(const DartControllerConfig& config) {
   InitVmIfNeeded(config.entropy,
                  config.vm_flags,
                  config.vm_flags_count);
+  BlockForServiceIsolate();
   Dart_Isolate isolate = CreateIsolateHelper(config.application_data,
                                              config.strict_compilation,
                                              config.callbacks,
@@ -735,6 +690,7 @@
 }
 
 bool DartController::RunDartScript(const DartControllerConfig& config) {
+  BlockForServiceIsolate();
   CHECK(service_isolate_running_);
   const bool strict = strict_compilation_ || config.strict_compilation;
   Dart_Isolate isolate = CreateIsolateHelper(config.application_data,
@@ -762,6 +718,7 @@
   if (!initialized_) {
     return;
   }
+  BlockForServiceIsolateLocked();
   StopHandleWatcherIsolate();
   Dart_Cleanup();
   service_isolate_running_ = false;
diff --git a/mojo/dart/embedder/dart_controller.h b/mojo/dart/embedder/dart_controller.h
index b0b53a9..4664680 100644
--- a/mojo/dart/embedder/dart_controller.h
+++ b/mojo/dart/embedder/dart_controller.h
@@ -156,14 +156,10 @@
                              const char** arguments,
                              int arguments_count);
 
-  static void BlockWaitingForDependencies(
-      tonic::DartLibraryLoader* loader,
-      const std::unordered_set<tonic::DartDependency*>& dependencies);
+  static void BlockForServiceIsolate();
+  static void BlockForServiceIsolateLocked();
+
   static void LoadEmptyScript(const std::string& script_uri);
-  static void InnerLoadScript(const std::string& script_uri,
-                              tonic::DartLibraryProvider* library_provider);
-  static void LoadScript(const std::string& script_uri,
-                         tonic::DartLibraryProvider* library_provider);
 
   static tonic::DartLibraryProvider* library_provider_;
   static base::Lock lock_;
diff --git a/mojo/dart/embedder/io/mojo_patch.dart b/mojo/dart/embedder/io/mojo_patch.dart
index c31c5fb..d49c6c4 100644
--- a/mojo/dart/embedder/io/mojo_patch.dart
+++ b/mojo/dart/embedder/io/mojo_patch.dart
@@ -91,9 +91,14 @@
         r += '${digit}${divider}';
       }
     } else {
-      for (var i = 0; i < 16; i++) {
-        var digit = address[i].toRadixString(16);
-        var divider = (i != 15) ? ':' : '';
+      for (var i = 0; i < 16; i += 2) {
+        var first = '';
+        if (address[i] != 0) {
+          first = address[i].toRadixString(16).padLeft(2, '0');
+        }
+        var second = address[i + 1].toRadixString(16).padLeft(2, '0');
+        var digit = '$first$second';
+        var divider = (i != 14) ? ':' : '';
         r += '${digit}${divider}';
       }
     }
diff --git a/mojo/dart/embedder/mojo_dart_state.h b/mojo/dart/embedder/mojo_dart_state.h
index 6ebd27c..a0792ee 100644
--- a/mojo/dart/embedder/mojo_dart_state.h
+++ b/mojo/dart/embedder/mojo_dart_state.h
@@ -111,4 +111,4 @@
 }  // namespace dart
 }  // namespace mojo
 
-#endif  // MOJO_DART_EMBEDDER_DART_STATE_H_
\ No newline at end of file
+#endif  // MOJO_DART_EMBEDDER_DART_STATE_H_
diff --git a/mojo/dart/embedder/test/BUILD.gn b/mojo/dart/embedder/test/BUILD.gn
index 87395a3..2b2d429 100644
--- a/mojo/dart/embedder/test/BUILD.gn
+++ b/mojo/dart/embedder/test/BUILD.gn
@@ -22,7 +22,7 @@
     "validation_unittest.cc",
   ]
   deps = [
-    "//mojo/public/dart:mojo",
+    "//mojo/public/dart",
     "//mojo/dart/testing",
     ":dart_controller_for_test",
     ":dart_to_cpp_unittests",
diff --git a/mojo/dart/http_load_test/BUILD.gn b/mojo/dart/http_load_test/BUILD.gn
new file mode 100644
index 0000000..67b1688
--- /dev/null
+++ b/mojo/dart/http_load_test/BUILD.gn
@@ -0,0 +1,20 @@
+# Copyright 2015 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import("//mojo/public/dart/rules.gni")
+
+dart_pkg("http_load_test") {
+  apps = [ [
+        "dart_http_load_test",
+        "lib/main.dart",
+      ] ]
+  sources = [
+    "lib/src/part0.dart",
+    "pubspec.yaml",
+  ]
+  deps = [
+    "//mojo/public/dart",
+    "//mojo/dart/mojo_services",
+  ]
+}
diff --git a/mojo/dart/http_load_test/tester.dart b/mojo/dart/http_load_test/bin/tester.dart
similarity index 79%
rename from mojo/dart/http_load_test/tester.dart
rename to mojo/dart/http_load_test/bin/tester.dart
index 70eb61b..e269272 100644
--- a/mojo/dart/http_load_test/tester.dart
+++ b/mojo/dart/http_load_test/bin/tester.dart
@@ -17,19 +17,20 @@
 
     // Completer completes once the child process exits.
     var completer = new Completer();
-    String stdout = '';
+    String output = '';
     process.stdout.transform(UTF8.decoder)
                   .transform(new LineSplitter()).listen((line) {
-      stdout = '$stdout\n$line';
+      output = '$output\n$line';
       print(line);
     });
     process.stderr.transform(UTF8.decoder)
                   .transform(new LineSplitter()).listen((line) {
+      output = '$output\n$line';
       print(line);
     });
     process.exitCode.then((ec) {
-      stdout = '$stdout\nEXIT_CODE=$ec\n';
-      completer.complete(stdout);
+      output = '$output\nEXIT_CODE=$ec\n';
+      completer.complete(output);
     });
     return completer.future;
   }
@@ -56,15 +57,18 @@
     }
   });
 
-  var launchUrl = 'http://127.0.0.1:${server.port}/main.dart';
-  var stdout = await Launcher.launch(mojo_shell_executable, [launchUrl]);
+  var launchUrl = 'http://127.0.0.1:${server.port}/lib/main.dart';
+  var output = await Launcher.launch(mojo_shell_executable, [launchUrl]);
 
   server.close();
 
-  if (!stdout.contains("\nPASS")) {
+  if (output.contains("ERROR")) {
+    throw "test failed.";
+  }
+  if (!output.contains("\nEXIT_CODE=0\n")) {
     throw "Test failed.";
   }
-  if (!stdout.contains("\nEXIT_CODE=0\n")) {
+  if (!output.contains("\nPASS")) {
     throw "Test failed.";
   }
 }
diff --git a/mojo/dart/http_load_test/main.dart b/mojo/dart/http_load_test/lib/main.dart
similarity index 75%
rename from mojo/dart/http_load_test/main.dart
rename to mojo/dart/http_load_test/lib/main.dart
index 6e35e69..7e779d7 100644
--- a/mojo/dart/http_load_test/main.dart
+++ b/mojo/dart/http_load_test/lib/main.dart
@@ -5,7 +5,9 @@
 import 'dart:async';
 import 'dart:mojo.internal';
 
-part 'part0.dart';
+import 'package:mojo_services/tracing/tracing.mojom.dart' as tracing;
+
+part 'src/part0.dart';
 
 main(List args) {
   // Hang around for a sec and then close the shell handle.
diff --git a/mojo/dart/http_load_test/part0.dart b/mojo/dart/http_load_test/lib/src/part0.dart
similarity index 100%
rename from mojo/dart/http_load_test/part0.dart
rename to mojo/dart/http_load_test/lib/src/part0.dart
diff --git a/mojo/dart/http_load_test/pubspec.lock b/mojo/dart/http_load_test/pubspec.lock
new file mode 100644
index 0000000..e7b03b5
--- /dev/null
+++ b/mojo/dart/http_load_test/pubspec.lock
@@ -0,0 +1,3 @@
+# Generated by pub
+# See http://pub.dartlang.org/doc/glossary.html#lockfile
+packages: {}
diff --git a/mojo/dart/http_load_test/pubspec.yaml b/mojo/dart/http_load_test/pubspec.yaml
new file mode 100644
index 0000000..335f54a
--- /dev/null
+++ b/mojo/dart/http_load_test/pubspec.yaml
@@ -0,0 +1 @@
+name: mojo_dart_http_load_test
diff --git a/mojo/dart/http_load_test/runner.py b/mojo/dart/http_load_test/runner.py
index 3f72f39..b3c4785 100755
--- a/mojo/dart/http_load_test/runner.py
+++ b/mojo/dart/http_load_test/runner.py
@@ -40,6 +40,8 @@
                       help="Path to dart executable.")
   args = parser.parse_args()
   tester_directory = os.path.dirname(os.path.realpath(__file__))
-  tester_dart_script = os.path.join(tester_directory, 'tester.dart')
+  tester_dart_script = os.path.join(tester_directory, 'bin', 'tester.dart')
+  package_directory = os.path.join(
+      args.build_dir, 'gen', 'dart-pkg', 'mojo_dart_http_load_test')
   sys.exit(main(args.build_dir, args.dart_exe, tester_dart_script,
-                tester_directory))
+                package_directory))
diff --git a/mojo/dart/mojo_services/BUILD.gn b/mojo/dart/mojo_services/BUILD.gn
index abf2437..bda57f8 100644
--- a/mojo/dart/mojo_services/BUILD.gn
+++ b/mojo/dart/mojo_services/BUILD.gn
@@ -3,6 +3,7 @@
 # found in the LICENSE file.
 
 import("//mojo/public/dart/rules.gni")
+import("//mojo/services/mojo_services.gni")
 
 dart_pkg("mojo_services") {
   sources = [
diff --git a/mojo/dart/mojo_services/CHANGELOG.md b/mojo/dart/mojo_services/CHANGELOG.md
index ef62915..899759c 100644
--- a/mojo/dart/mojo_services/CHANGELOG.md
+++ b/mojo/dart/mojo_services/CHANGELOG.md
@@ -1,3 +1,7 @@
+## 0.0.22
+
+  - 58 changes: https://github.com/domokit/mojo/compare/e172885...35de44e
+
 ## 0.0.16
 
   - 89 changes: https://github.com/domokit/mojo/compare/0fd4d06...c3119f6
diff --git a/mojo/dart/mojo_services/pubspec.yaml b/mojo/dart/mojo_services/pubspec.yaml
index 271ae40..0015636 100644
--- a/mojo/dart/mojo_services/pubspec.yaml
+++ b/mojo/dart/mojo_services/pubspec.yaml
@@ -4,4 +4,4 @@
 description: Generated bindings for mojo services
 homepage: https://github.com/domokit/mojo
 name: mojo_services
-version: 0.0.21
+version: 0.0.22
diff --git a/mojo/dart/mojom/BUILD.gn b/mojo/dart/mojom/BUILD.gn
index c29b19a..70ff7da 100644
--- a/mojo/dart/mojom/BUILD.gn
+++ b/mojo/dart/mojom/BUILD.gn
@@ -5,7 +5,7 @@
 import("//mojo/public/dart/rules.gni")
 
 dart_pkg("mojom") {
-  entrypoints = [ "lib/generate.dart" ]
+  libs = [ "lib/generate.dart" ]
   sources = [
     "CHANGELOG.md",
     "README.md",
diff --git a/mojo/dart/mojom/CHANGELOG.md b/mojo/dart/mojom/CHANGELOG.md
index fe7b30f..3188f5b 100644
--- a/mojo/dart/mojom/CHANGELOG.md
+++ b/mojo/dart/mojom/CHANGELOG.md
@@ -1,3 +1,7 @@
+## 0.0.22
+
+  - 59 changes: https://github.com/domokit/mojo/compare/c73419d...35de44e
+
 ## 0.0.18
 
   - 89 changes: https://github.com/domokit/mojo/compare/0fd4d06...c3119f6
diff --git a/mojo/dart/mojom/pubspec.yaml b/mojo/dart/mojom/pubspec.yaml
index 6e53e1f..bf53665 100644
--- a/mojo/dart/mojom/pubspec.yaml
+++ b/mojo/dart/mojom/pubspec.yaml
@@ -9,4 +9,4 @@
   sdk: '>=1.9.0 <2.0.0'
 homepage: https://github.com/domokit/mojo
 name: mojom
-version: 0.0.21
+version: 0.0.22
diff --git a/mojo/dart/observatory_test/BUILD.gn b/mojo/dart/observatory_test/BUILD.gn
index 4401b35..b845c9f 100644
--- a/mojo/dart/observatory_test/BUILD.gn
+++ b/mojo/dart/observatory_test/BUILD.gn
@@ -4,9 +4,13 @@
 
 import("//mojo/public/dart/rules.gni")
 
-dartzip_packaged_application("observatory_test") {
+dart_pkg("observatory_test") {
+  apps = [ [
+        "dart_observatory_test",
+        "lib/main.dart",
+      ] ]
   sources = [
-    "main.dart",
+    "pubspec.yaml",
   ]
   deps = [
     "//mojo/public/dart",
diff --git a/mojo/dart/observatory_test/main.dart b/mojo/dart/observatory_test/lib/main.dart
similarity index 100%
rename from mojo/dart/observatory_test/main.dart
rename to mojo/dart/observatory_test/lib/main.dart
diff --git a/mojo/dart/observatory_tester/runner.py b/mojo/dart/observatory_tester/runner.py
index d78ec7d..4cd1b4b 100755
--- a/mojo/dart/observatory_tester/runner.py
+++ b/mojo/dart/observatory_tester/runner.py
@@ -11,7 +11,7 @@
 import sys
 
 MOJO_SHELL = 'mojo_shell'
-TESTEE = 'mojo:observatory_test'
+TESTEE = 'mojo:dart_observatory_test'
 
 def main(build_dir, dart_exe, tester_script):
   shell_exe = os.path.join(build_dir, MOJO_SHELL)
diff --git a/mojo/dart/testing/BUILD.gn b/mojo/dart/testing/BUILD.gn
index 5bf79a5..e4cbe05 100644
--- a/mojo/dart/testing/BUILD.gn
+++ b/mojo/dart/testing/BUILD.gn
@@ -5,7 +5,7 @@
 import("//mojo/public/dart/rules.gni")
 
 dart_pkg("testing") {
-  entrypoints = [
+  libs = [
     "lib/async_helper.dart",
     "lib/expect.dart",
     "lib/validation_test_input_parser.dart",
diff --git a/mojo/data_pipe_utils/BUILD.gn b/mojo/data_pipe_utils/BUILD.gn
new file mode 100644
index 0000000..d9b5dea
--- /dev/null
+++ b/mojo/data_pipe_utils/BUILD.gn
@@ -0,0 +1,39 @@
+# Copyright 2015 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+source_set("data_pipe_utils") {
+  sources = [
+    "data_pipe_drainer.cc",
+    "data_pipe_drainer.h",
+    "data_pipe_file_utils.cc",
+    "data_pipe_utils.cc",
+    "data_pipe_utils.h",
+    "data_pipe_utils_internal.h",
+  ]
+
+  if (is_nacl) {
+    sources -= [ "data_pipe_file_utils.cc" ]
+  }
+
+  deps = [
+    "//base",
+    "//mojo/message_pump",
+    "//mojo/public/cpp/environment:environment",
+    "//mojo/public/cpp/system",
+  ]
+}
+
+source_set("tests") {
+  testonly = true
+
+  sources = [
+    "data_pipe_utils_unittest.cc",
+  ]
+
+  deps = [
+    ":data_pipe_utils",
+    "//base",
+    "//testing/gtest",
+  ]
+}
diff --git a/mojo/common/data_pipe_drainer.cc b/mojo/data_pipe_utils/data_pipe_drainer.cc
similarity index 73%
rename from mojo/common/data_pipe_drainer.cc
rename to mojo/data_pipe_utils/data_pipe_drainer.cc
index 5477109..8ed8b2d 100644
--- a/mojo/common/data_pipe_drainer.cc
+++ b/mojo/data_pipe_utils/data_pipe_drainer.cc
@@ -2,7 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "mojo/common/data_pipe_drainer.h"
+#include "mojo/data_pipe_utils/data_pipe_drainer.h"
+
 #include "base/bind.h"
 
 namespace mojo {
@@ -10,21 +11,18 @@
 
 DataPipeDrainer::DataPipeDrainer(Client* client,
                                  mojo::ScopedDataPipeConsumerHandle source)
-    : client_(client),
-      source_(source.Pass()),
-      weak_factory_(this) {
+    : client_(client), source_(source.Pass()), weak_factory_(this) {
   DCHECK(client_);
   ReadData();
 }
 
-DataPipeDrainer::~DataPipeDrainer() {
-}
+DataPipeDrainer::~DataPipeDrainer() {}
 
 void DataPipeDrainer::ReadData() {
   const void* buffer = nullptr;
   uint32_t num_bytes = 0;
-  MojoResult rv = BeginReadDataRaw(source_.get(),
-      &buffer, &num_bytes, MOJO_READ_DATA_FLAG_NONE);
+  MojoResult rv = BeginReadDataRaw(source_.get(), &buffer, &num_bytes,
+                                   MOJO_READ_DATA_FLAG_NONE);
   if (rv == MOJO_RESULT_OK) {
     client_->OnDataAvailable(buffer, num_bytes);
     EndReadDataRaw(source_.get(), num_bytes);
@@ -39,8 +37,8 @@
 }
 
 void DataPipeDrainer::WaitForData() {
-  handle_watcher_.Start(source_.get(),
-      MOJO_HANDLE_SIGNAL_READABLE, MOJO_DEADLINE_INDEFINITE,
+  handle_watcher_.Start(
+      source_.get(), MOJO_HANDLE_SIGNAL_READABLE, MOJO_DEADLINE_INDEFINITE,
       base::Bind(&DataPipeDrainer::WaitComplete, weak_factory_.GetWeakPtr()));
 }
 
diff --git a/mojo/common/data_pipe_drainer.h b/mojo/data_pipe_utils/data_pipe_drainer.h
similarity index 80%
rename from mojo/common/data_pipe_drainer.h
rename to mojo/data_pipe_utils/data_pipe_drainer.h
index c9669be..80cb933 100644
--- a/mojo/common/data_pipe_drainer.h
+++ b/mojo/data_pipe_utils/data_pipe_drainer.h
@@ -2,11 +2,11 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef MOJO_COMMON_DATA_PIPE_DRAINER_H_
-#define MOJO_COMMON_DATA_PIPE_DRAINER_H_
+#ifndef MOJO_DATA_PIPE_UTILS_DATA_PIPE_DRAINER_H_
+#define MOJO_DATA_PIPE_UTILS_DATA_PIPE_DRAINER_H_
 
 #include "base/memory/weak_ptr.h"
-#include "mojo/common/handle_watcher.h"
+#include "mojo/message_pump/handle_watcher.h"
 #include "mojo/public/cpp/system/core.h"
 
 namespace mojo {
@@ -20,7 +20,7 @@
     virtual void OnDataComplete() = 0;
 
    protected:
-    virtual ~Client() { }
+    virtual ~Client() {}
   };
 
   DataPipeDrainer(Client*, mojo::ScopedDataPipeConsumerHandle source);
@@ -43,4 +43,4 @@
 }  // namespace common
 }  // namespace mojo
 
-#endif  // MOJO_COMMON_DATA_PIPE_DRAINER_H_
+#endif  // MOJO_DATA_PIPE_UTILS_DATA_PIPE_DRAINER_H_
diff --git a/mojo/common/data_pipe_file_utils.cc b/mojo/data_pipe_utils/data_pipe_file_utils.cc
similarity index 98%
rename from mojo/common/data_pipe_file_utils.cc
rename to mojo/data_pipe_utils/data_pipe_file_utils.cc
index aa14225..e37c8df 100644
--- a/mojo/common/data_pipe_file_utils.cc
+++ b/mojo/data_pipe_utils/data_pipe_file_utils.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "mojo/common/data_pipe_utils.h"
+#include "mojo/data_pipe_utils/data_pipe_utils.h"
 
 #include <stdio.h>
 
@@ -14,7 +14,7 @@
 #include "base/files/scoped_file.h"
 #include "base/location.h"
 #include "base/trace_event/trace_event.h"
-#include "mojo/common/data_pipe_utils_internal.h"
+#include "mojo/data_pipe_utils/data_pipe_utils_internal.h"
 #include "mojo/public/cpp/environment/async_waiter.h"
 
 namespace mojo {
diff --git a/mojo/common/data_pipe_utils.cc b/mojo/data_pipe_utils/data_pipe_utils.cc
similarity index 82%
rename from mojo/common/data_pipe_utils.cc
rename to mojo/data_pipe_utils/data_pipe_utils.cc
index daaef2c..af9f206 100644
--- a/mojo/common/data_pipe_utils.cc
+++ b/mojo/data_pipe_utils/data_pipe_utils.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "mojo/common/data_pipe_utils.h"
+#include "mojo/data_pipe_utils/data_pipe_utils.h"
 
 #include <stdio.h>
 
@@ -10,18 +10,19 @@
 #include "base/task_runner_util.h"
 #include "base/threading/platform_thread.h"
 #include "base/trace_event/trace_event.h"
-#include "mojo/common/data_pipe_utils_internal.h"
+#include "mojo/data_pipe_utils/data_pipe_utils_internal.h"
 
 namespace mojo {
 namespace common {
 
-bool BlockingCopyHelper(ScopedDataPipeConsumerHandle source,
+bool BlockingCopyHelper(
+    ScopedDataPipeConsumerHandle source,
     const base::Callback<size_t(const void*, uint32_t)>& write_bytes) {
   for (;;) {
     const void* buffer = nullptr;
     uint32_t num_bytes = 0;
-    MojoResult result = BeginReadDataRaw(
-        source.get(), &buffer, &num_bytes, MOJO_READ_DATA_FLAG_NONE);
+    MojoResult result = BeginReadDataRaw(source.get(), &buffer, &num_bytes,
+                                         MOJO_READ_DATA_FLAG_NONE);
     if (result == MOJO_RESULT_OK) {
       size_t bytes_written = write_bytes.Run(buffer, num_bytes);
       if (bytes_written < num_bytes) {
@@ -39,10 +40,8 @@
         return false;
       }
     } else if (result == MOJO_RESULT_SHOULD_WAIT) {
-      result = Wait(source.get(),
-                    MOJO_HANDLE_SIGNAL_READABLE,
-                    MOJO_DEADLINE_INDEFINITE,
-                    nullptr);
+      result = Wait(source.get(), MOJO_HANDLE_SIGNAL_READABLE,
+                    MOJO_DEADLINE_INDEFINITE, nullptr);
       if (result != MOJO_RESULT_OK) {
         // If the producer handle was closed, then treat as EOF.
         return result == MOJO_RESULT_FAILED_PRECONDITION;
@@ -60,13 +59,14 @@
 
 namespace {
 
-size_t CopyToStringHelper(
-    std::string* result, const void* buffer, uint32_t num_bytes) {
+size_t CopyToStringHelper(std::string* result,
+                          const void* buffer,
+                          uint32_t num_bytes) {
   result->append(static_cast<const char*>(buffer), num_bytes);
   return num_bytes;
 }
 
-} // namespace
+}  // namespace
 
 // TODO(hansmuller): Add a max_size parameter.
 bool BlockingCopyToString(ScopedDataPipeConsumerHandle source,
@@ -74,8 +74,8 @@
   TRACE_EVENT0("data_pipe_utils", "BlockingCopyToString");
   CHECK(result);
   result->clear();
-  return BlockingCopyHelper(
-      source.Pass(), base::Bind(&CopyToStringHelper, result));
+  return BlockingCopyHelper(source.Pass(),
+                            base::Bind(&CopyToStringHelper, result));
 }
 
 bool BlockingCopyFromString(const std::string& source,
diff --git a/mojo/common/data_pipe_utils.h b/mojo/data_pipe_utils/data_pipe_utils.h
similarity index 92%
rename from mojo/common/data_pipe_utils.h
rename to mojo/data_pipe_utils/data_pipe_utils.h
index 08e6fa0..289fe12 100644
--- a/mojo/common/data_pipe_utils.h
+++ b/mojo/data_pipe_utils/data_pipe_utils.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef MOJO_SHELL_DATA_PIPE_UTILS_H_
-#define MOJO_SHELL_DATA_PIPE_UTILS_H_
+#ifndef MOJO_DATA_PIPE_UTILS_DATA_PIPE_UTILS_H_
+#define MOJO_DATA_PIPE_UTILS_DATA_PIPE_UTILS_H_
 
 #include <string>
 
@@ -51,4 +51,4 @@
 }  // namespace common
 }  // namespace mojo
 
-#endif  // MOJO_SHELL_DATA_PIPE_UTILS_H_
+#endif  // MOJO_DATA_PIPE_UTILS_DATA_PIPE_UTILS_H_
diff --git a/mojo/common/data_pipe_utils_internal.h b/mojo/data_pipe_utils/data_pipe_utils_internal.h
similarity index 75%
rename from mojo/common/data_pipe_utils_internal.h
rename to mojo/data_pipe_utils/data_pipe_utils_internal.h
index 26164ec..40086fb 100644
--- a/mojo/common/data_pipe_utils_internal.h
+++ b/mojo/data_pipe_utils/data_pipe_utils_internal.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef MOJO_COMMON_DATA_PIPE_UTILS_INTERNAL_H_
-#define MOJO_COMMON_DATA_PIPE_UTILS_INTERNAL_H_
+#ifndef MOJO_DATA_PIPE_UTILS_DATA_PIPE_UTILS_INTERNAL_H_
+#define MOJO_DATA_PIPE_UTILS_DATA_PIPE_UTILS_INTERNAL_H_
 
 #include "base/callback_forward.h"
 #include "mojo/public/cpp/system/core.h"
@@ -19,4 +19,4 @@
 }  // namespace common
 }  // namespace mojo
 
-#endif  // MOJO_COMMON_DATA_PIPE_UTILS_INTERNAL_H_
+#endif  // MOJO_DATA_PIPE_UTILS_DATA_PIPE_UTILS_INTERNAL_H_
diff --git a/mojo/common/data_pipe_utils_unittest.cc b/mojo/data_pipe_utils/data_pipe_utils_unittest.cc
similarity index 97%
rename from mojo/common/data_pipe_utils_unittest.cc
rename to mojo/data_pipe_utils/data_pipe_utils_unittest.cc
index edfc2c4..6c0f600 100644
--- a/mojo/common/data_pipe_utils_unittest.cc
+++ b/mojo/data_pipe_utils/data_pipe_utils_unittest.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "mojo/common/data_pipe_utils.h"
+#include "mojo/data_pipe_utils/data_pipe_utils.h"
 
 #include "base/bind.h"
 #include "base/files/file_util.h"
diff --git a/mojo/devtools/README.md b/mojo/devtools/README.md
deleted file mode 100644
index ff70d86..0000000
--- a/mojo/devtools/README.md
+++ /dev/null
@@ -1,11 +0,0 @@
-# Devtools packages
-
-The `common` subdirectory contains what we currently expose as "devtools",
-mirroring it as a [separate repository](https://github.com/domokit/devtools) for
-consumption without a Mojo checkout.
-
-Further subdirectories TBD might be added in the future, to contain heavy
-language-specific tooling which we will mirror / expose separately.
-
-The toolsets are intended for consumption by Mojo consumers as **separate
-checkouts**. No dependencies on files outside of devtools are allowed.
diff --git a/mojo/devtools/common/README.md b/mojo/devtools/common/README.md
deleted file mode 100644
index eb7d5c6..0000000
--- a/mojo/devtools/common/README.md
+++ /dev/null
@@ -1,136 +0,0 @@
-# Devtools
-
-Unopinionated tools for **running**, **debugging** and **testing** Mojo apps.
-
-## Install
-
-```
-git clone https://github.com/domokit/devtools.git
-```
-
-## Contents
-
-Devtools offers the following tools:
-
- - `mojo_run` - shell runner
- - `mojo_test` - apptest runner
- - `mojo_debug` - debugger supporting interactive tracing and debugging of a
-   running mojo shell
-
-Additionally, `remote_adb_setup` script helps to configure adb on a remote
-machine to communicate with a device attached to a local machine, forwarding the
-ports used by `mojo_run`.
-
-### Runner
-
-`mojo_run` allows you to run a Mojo shell either on the host, or on an attached
-Android device.
-
-```sh
-mojo_run APP_URL  # Run on the host.
-mojo_run APP_URL --android  # Run on Android device.
-mojo_run "APP_URL APP_ARGUMENTS"  # Run an app with startup arguments
-```
-
-Unless running within a Mojo checkout, we need to indicate the path to the shell
-binary:
-
-```sh
-mojo_run --shell-path path/to/shell/binary APP_URL
-```
-
-Some applications are running embedded inside a window manager. To start such an
-app, you have to first start the window manager app, then have it embed the app
-you are interested in. It is done as follows using the default window manager:
-
-```sh
-mojo_run "mojo:window_manager APP_URL"
-```
-
-By default, `mojo_run` uses `mojo:kiosk_wm` as the default window manager. It
-can be changed using the `--window-manager` flag.
-
-#### Sky apps
-
-To run a [Sky](https://github.com/domokit/sky_engine) app, you need to build
-`sky_viewer.mojo` in a Sky checkout, and indicate the path to the binary using
-the `--map-url` parameter:
-
-```sh
-mojo_run --map-url mojo:sky_viewer=/path/to/sky/viewer "mojo:window_manager APP_URL"
-```
-
-If the app does not declare a shebang indicating that it needs to be run in
-`sky_viewer`, pass `--sky` to map `sky_viewer` as a default content handler for
-dart apps:
-
-```sh
-mojo_run --map-url mojo:sky_viewer=/path/to/sky/viewer "mojo:window_manager APP_URL" --sky
-```
-
-Note that Sky apps will need the --use-osmesa flag to run
-over [chromoting](https://support.google.com/chrome/answer/1649523?hl=en):
-
-### Debugger
-
-`mojo_debug` allows you to interactively inspect a running shell, collect
-performance traces and attach a gdb debugger.
-
-#### Tracing
-To collect [performance
-traces](https://www.chromium.org/developers/how-tos/trace-event-profiling-tool)
-and retrieve the result:
-
-```sh
-mojo_debug tracing start
-mojo_debug tracing stop [result.json]
-```
-
-The trace file can be then loaded using the trace viewer in Chrome available at
-`about://tracing`.
-
-#### GDB
-It is possible to inspect a Mojo Shell process using GDB. The `mojo_debug`
-script can be used to launch GDB and attach it to a running shell process
-(android only):
-
-```sh
-mojo_debug gdb attach
-```
-
-Once started, GDB will first stop the Mojo Shell execution, then load symbols
-from loaded Mojo applications. Please note that this initial step can take some
-time (up to several minutes in the worst case).
-
-After each execution pause, GDB will update the set of loaded symbols based on
-the selected thread only. If you need symbols for all threads, use the
-`update-symbols` GDB command:
-```sh
-(gdb) update-symbols
-```
-
-If you only want to update symbols for the current selected thread (for example,
-after changing threads), use the `current` option:
-```sh
-(gdb) update-symbols current
-```
-
-If you want to debug the startup of your application, you can pass
-`--wait-for-debugger` to `mojo_run` to have the Mojo Shell stop and wait to be
-attached by `gdb` before continuing.
-
-#### Android crash stacks
-When Mojo shell crashes on Android ("Unfortunately, Mojo shell has stopped.")
-due to a crash in native code, `mojo_debug` can be used to find and symbolize
-the stack trace present in the device log:
-
-```sh
-mojo_debug device stack
-```
-
-## Development
-
-The library is canonically developed [in the mojo
-repository](https://github.com/domokit/mojo/tree/master/mojo/devtools/common),
-https://github.com/domokit/devtools is a mirror allowing to consume it
-separately.
diff --git a/mojo/devtools/common/android_gdb/__init__.py b/mojo/devtools/common/android_gdb/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/mojo/devtools/common/android_gdb/__init__.py
+++ /dev/null
diff --git a/mojo/devtools/common/android_gdb/config.py b/mojo/devtools/common/android_gdb/config.py
deleted file mode 100644
index 4ddaeae..0000000
--- a/mojo/devtools/common/android_gdb/config.py
+++ /dev/null
@@ -1,9 +0,0 @@
-# Copyright 2015 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-# Path where remote_file_reader should be installed on the device.
-REMOTE_FILE_READER_DEVICE_PATH = '/data/local/tmp/remote_file_reader'
-
-# Path where remote_file_reader is available on Cloud Storage.
-REMOTE_FILE_READER_CLOUD_PATH = 'gs://mojo/devtools/remote_file_reader'
diff --git a/mojo/devtools/common/android_gdb/install_remote_file_reader.py b/mojo/devtools/common/android_gdb/install_remote_file_reader.py
deleted file mode 100644
index 07ba7f7..0000000
--- a/mojo/devtools/common/android_gdb/install_remote_file_reader.py
+++ /dev/null
@@ -1,20 +0,0 @@
-# Copyright 2015 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import android_gdb.config as config
-import subprocess
-import tempfile
-
-
-def install(gsutil, adb='adb'):
-  verification_call_output = subprocess.check_output(
-      [adb, 'shell', 'ls', config.REMOTE_FILE_READER_DEVICE_PATH])
-  if config.REMOTE_FILE_READER_DEVICE_PATH != verification_call_output.strip():
-    with tempfile.NamedTemporaryFile() as temp_file:
-      subprocess.check_call([gsutil, 'cp', config.REMOTE_FILE_READER_CLOUD_PATH,
-                             temp_file.name])
-      subprocess.check_call([adb, 'push', temp_file.name,
-                             config.REMOTE_FILE_READER_DEVICE_PATH])
-      subprocess.check_call([adb, 'shell', 'chmod', '777',
-                             config.REMOTE_FILE_READER_DEVICE_PATH])
diff --git a/mojo/devtools/common/android_gdb/remote_file_connection.py b/mojo/devtools/common/android_gdb/remote_file_connection.py
deleted file mode 100644
index 9759cdb..0000000
--- a/mojo/devtools/common/android_gdb/remote_file_connection.py
+++ /dev/null
@@ -1,69 +0,0 @@
-# Copyright 2015 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import socket
-import struct
-
-
-class RemoteFileConnectionException(Exception):
-  def __init__(self, *args, **kwargs):
-    Exception.__init__(self, *args, **kwargs)
-
-
-class RemoteFileConnection(object):
-  """Client for remote_file_reader server, allowing to read files on an
-  remote device.
-  """
-  def __init__(self, host, port):
-    self._host = host
-    self._port = port
-    self._socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
-    self._size_struct = struct.Struct("!i")
-
-  def __del__(self):
-    self.disconnect()
-
-  def connect(self):
-    self._socket.connect((self._host, self._port))
-
-  def disconnect(self):
-    self._socket.close()
-
-  def open(self, filename):
-    self._send("O %s\n" % filename)
-    result = self._receive(1)
-    if result != 'O':
-      raise RemoteFileConnectionException("Unable to open file " + filename)
-
-  def seek(self, pos, mode=0):
-    self._send("S %d %d\n" % (pos, mode))
-    result = self._receive(1)
-    if result != 'O':
-      raise RemoteFileConnectionException("Unable to seek in file.")
-
-  def read(self, size=0):
-    assert size > 0
-    self._send("R %d\n" % size)
-    result = self._receive(1)
-    if result != 'O':
-      raise RemoteFileConnectionException("Unable to read file.")
-    read_size = self._size_struct.unpack(self._receive(4))[0]
-    return self._receive(read_size)
-
-  def _send(self, data):
-    while len(data) > 0:
-      sent = self._socket.send(data)
-      if sent == 0:
-        raise RemoteFileConnectionException("Socket connection broken.")
-      data = data[sent:]
-
-  def _receive(self, length):
-    result = []
-    while length > 0:
-      chunk = self._socket.recv(length)
-      if chunk == '':
-        raise RemoteFileConnectionException("Socket connection broken.")
-      result.append(chunk)
-      length -= len(chunk)
-    return ''.join(result)
diff --git a/mojo/devtools/common/android_gdb/session.py b/mojo/devtools/common/android_gdb/session.py
deleted file mode 100644
index e425c40..0000000
--- a/mojo/devtools/common/android_gdb/session.py
+++ /dev/null
@@ -1,317 +0,0 @@
-# Copyright 2015 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""
-Manages a debugging session with GDB.
-
-This module is meant to be imported from inside GDB. Once loaded, the
-|DebugSession| attaches GDB to a running Mojo Shell process on an Android
-device using a remote gdbserver.
-
-At startup and each time the execution stops, |DebugSession| associates
-debugging symbols for every frame. For more information, see |DebugSession|
-documentation.
-"""
-
-import gdb
-import glob
-import itertools
-import logging
-import os
-import os.path
-import shutil
-import subprocess
-import sys
-import tempfile
-import traceback
-import urllib2
-
-sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
-import android_gdb.config as config
-from android_gdb.remote_file_connection import RemoteFileConnection
-from android_gdb.signatures import get_signature
-
-
-logging.getLogger().setLevel(logging.INFO)
-
-
-def _gdb_execute(command):
-  """Executes a GDB command."""
-  return gdb.execute(command, to_string=True)
-
-
-class Mapping(object):
-  """Represents a mapped memory region."""
-  def __init__(self, line):
-    self.start = int(line[0], 16)
-    self.end = int(line[1], 16)
-    self.size = int(line[2], 16)
-    self.offset = int(line[3], 16)
-    self.filename = line[4]
-
-
-def _get_mapped_files():
-  """Retrieves all the files mapped into the debugged process memory.
-
-  Returns:
-    List of mapped memory regions grouped by files.
-  """
-  # info proc map returns a space-separated table with the following fields:
-  # start address, end address, size, offset, file path.
-  mappings = [Mapping(x) for x in
-              [x.split() for x in
-               _gdb_execute("info proc map").split('\n')]
-              if len(x) == 5 and x[4][0] == '/']
-  res = {}
-  for m in mappings:
-    libname = m.filename[m.filename.rfind('/') + 1:]
-    res[libname] = res.get(libname, []) + [m]
-  return res.values()
-
-
-class DebugSession(object):
-  def __init__(self, build_directory, package_name, pyelftools_dir, adb):
-    self._build_directory = build_directory
-    if not os.path.exists(self._build_directory):
-      logging.fatal("Please pass a valid build directory")
-      sys.exit(1)
-    self._package_name = package_name
-    self._adb = adb
-    self._remote_file_cache = os.path.join(os.getenv('HOME'), '.mojosymbols')
-
-    if pyelftools_dir != None:
-      sys.path.append(pyelftools_dir)
-    try:
-      import elftools.elf.elffile as elffile
-    except ImportError:
-      logging.fatal("Unable to find elftools module; please install pyelftools "
-                    "and specify its path on the command line using "
-                    "--pyelftools-dir.")
-      sys.exit(1)
-
-    self._elffile_module = elffile
-
-    self._libraries = self._find_libraries(build_directory)
-    self._rfc = RemoteFileConnection('localhost', 10000)
-    self._remote_file_reader_process = None
-    if not os.path.exists(self._remote_file_cache):
-      os.makedirs(self._remote_file_cache)
-    self._done_mapping = set()
-    self._downloaded_files = []
-
-  def __del__(self):
-    # Note that, per python interpreter documentation, __del__ is not
-    # guaranteed to be called when the interpreter (GDB, in our case) quits.
-    # Also, most (all?) globals are no longer available at this time (launching
-    # a subprocess does not work).
-    self.stop()
-
-  def stop(self, _unused_return_value=None):
-    if self._remote_file_reader_process != None:
-      self._remote_file_reader_process.kill()
-
-  def _find_libraries(self, lib_dir):
-    """Finds all libraries in |lib_dir| and key them by their signatures.
-    """
-    res = {}
-    for fn in glob.glob('%s/*.so' % lib_dir):
-      with open(fn, 'r') as f:
-        s = get_signature(f, self._elffile_module)
-        if s is not None:
-          res[s] = fn
-    return res
-
-  def _associate_symbols(self, mapping, local_file):
-    with open(local_file, "r") as f:
-      elf = self._elffile_module.ELFFile(f)
-      s = elf.get_section_by_name(".text")
-      text_address = mapping[0].start + s['sh_offset']
-      _gdb_execute("add-symbol-file %s 0x%x" % (local_file, text_address))
-
-  def _download_file(self, signature, remote):
-    """Downloads a remote file either from the cloud or through GDB connection.
-
-    Returns:
-      The filename of the downloaded file
-    """
-    temp_file = tempfile.NamedTemporaryFile()
-    logging.info("Trying to download symbols from the cloud.")
-    symbols_url = "http://storage.googleapis.com/mojo/symbols/%s" % signature
-    try:
-      symbol_file = urllib2.urlopen(symbols_url)
-      try:
-        with open(temp_file.name, "w") as dst:
-          shutil.copyfileobj(symbol_file, dst)
-          logging.info("Getting symbols for %s at %s." % (remote, symbols_url))
-          # This allows the deletion of temporary files on disk when the
-          # debugging session terminates.
-          self._downloaded_files.append(temp_file)
-          return temp_file.name
-      finally:
-        symbol_file.close()
-    except urllib2.HTTPError:
-      pass
-    logging.info("Downloading file %s" % remote)
-    _gdb_execute("remote get %s %s" % (remote, temp_file.name))
-    # This allows the deletion of temporary files on disk when the debugging
-    # session terminates.
-    self._downloaded_files.append(temp_file)
-    return temp_file.name
-
-  def _find_mapping_for_address(self, mappings, address):
-    """Returns the list of all mappings of the file occupying the |address|
-    memory address.
-    """
-    for file_mappings in mappings:
-      for mapping in file_mappings:
-        if address >= mapping.start and address <= mapping.end:
-          return file_mappings
-    return None
-
-  def _try_to_map(self, mapping):
-    remote_file = mapping[0].filename
-    if remote_file in self._done_mapping:
-      return False
-    self._done_mapping.add(remote_file)
-    self._rfc.open(remote_file)
-    signature = get_signature(self._rfc, self._elffile_module)
-    if signature is not None:
-      if signature in self._libraries:
-        self._associate_symbols(mapping, self._libraries[signature])
-      else:
-        # This library file is not known locally. Download it from the device or
-        # the cloud and put it in cache so, if it got symbols, we can see them.
-        local_file = os.path.join(self._remote_file_cache, signature)
-        if not os.path.exists(local_file):
-          tmp_output = self._download_file(signature, remote_file)
-          shutil.move(tmp_output, local_file)
-        self._associate_symbols(mapping, local_file)
-      return True
-    return False
-
-  def _map_symbols_on_current_thread(self, mapped_files):
-    """Updates the symbols for the current thread using files from mapped_files.
-    """
-    frame = gdb.newest_frame()
-    while frame and frame.is_valid():
-      if frame.name() is None:
-        m = self._find_mapping_for_address(mapped_files, frame.pc())
-        if m is not None and self._try_to_map(m):
-          # Force gdb to recompute its frames.
-          _gdb_execute("info threads")
-          frame = gdb.newest_frame()
-          assert frame.is_valid()
-      if (frame.older() is not None and
-          frame.older().is_valid() and
-          frame.older().pc() != frame.pc()):
-        frame = frame.older()
-      else:
-        frame = None
-
-  def update_symbols(self, current_thread_only):
-    """Updates the mapping between symbols as seen from GDB and local library
-    files.
-
-    If current_thread_only is True, only update symbols for the current thread.
-    """
-    logging.info("Updating symbols")
-    mapped_files = _get_mapped_files()
-    # Map all symbols from native libraries packages with the APK.
-    for file_mappings in mapped_files:
-      filename = file_mappings[0].filename
-      if ((filename.startswith('/data/data/') or
-           filename.startswith('/data/app')) and
-          not filename.endswith('.apk') and
-          not filename.endswith('.dex')):
-        logging.info('Pre-mapping: %s' % file_mappings[0].filename)
-        self._try_to_map(file_mappings)
-
-    if current_thread_only:
-      self._map_symbols_on_current_thread(mapped_files)
-    else:
-      logging.info('Updating all threads\' symbols')
-      current_thread = gdb.selected_thread()
-      nb_threads = len(_gdb_execute("info threads").split("\n")) - 2
-      for i in xrange(nb_threads):
-        try:
-          _gdb_execute("thread %d" % (i + 1))
-          self._map_symbols_on_current_thread(mapped_files)
-        except gdb.error:
-          traceback.print_exc()
-      current_thread.switch()
-
-  def _get_device_application_pid(self, application):
-    """Gets the PID of an application running on a device."""
-    output = subprocess.check_output([self._adb, 'shell', 'ps'])
-    for line in output.split('\n'):
-      elements = line.split()
-      if len(elements) > 0 and elements[-1] == application:
-        return elements[1]
-    return None
-
-  def start(self):
-    """Starts a debugging session."""
-    gdbserver_pid = self._get_device_application_pid('gdbserver')
-    if gdbserver_pid is not None:
-      subprocess.check_call([self._adb, 'shell', 'kill', gdbserver_pid])
-    shell_pid = self._get_device_application_pid(self._package_name)
-    if shell_pid is None:
-      raise Exception('Unable to find a running mojo shell.')
-    subprocess.check_call([self._adb, 'forward', 'tcp:9999', 'tcp:9999'])
-    subprocess.Popen(
-        [self._adb, 'shell', 'gdbserver', '--attach', ':9999', shell_pid],
-        # os.setpgrp ensures signals passed to this file (such as SIGINT) are
-        # not propagated to child processes.
-        preexec_fn = os.setpgrp)
-
-    # Kill stray remote reader processes. See __del__ comment for more info.
-    remote_file_reader_pid = self._get_device_application_pid(
-        config.REMOTE_FILE_READER_DEVICE_PATH)
-    if remote_file_reader_pid is not None:
-      subprocess.check_call([self._adb, 'shell', 'kill',
-                             remote_file_reader_pid])
-    self._remote_file_reader_process = subprocess.Popen(
-        [self._adb, 'shell', config.REMOTE_FILE_READER_DEVICE_PATH],
-        stdout=subprocess.PIPE, preexec_fn = os.setpgrp)
-    port = int(self._remote_file_reader_process.stdout.readline())
-    subprocess.check_call([self._adb, 'forward', 'tcp:10000', 'tcp:%d' % port])
-    self._rfc.connect()
-
-    _gdb_execute('target remote localhost:9999')
-
-    self.update_symbols(current_thread_only=False)
-    def on_stop(_):
-      self.update_symbols(current_thread_only=True)
-    gdb.events.stop.connect(on_stop)
-    gdb.events.exited.connect(self.stop)
-
-    # Register the update-symbols command.
-    UpdateSymbols(self)
-
-class UpdateSymbols(gdb.Command):
-  """Command to update symbols loaded into GDB.
-
-  GDB usage: update-symbols [all|current]
-  """
-  _UPDATE_COMMAND = "update-symbols"
-
-  def __init__(self, session):
-    super(UpdateSymbols, self).__init__(self._UPDATE_COMMAND, gdb.COMMAND_STACK)
-    self._session = session
-
-  def invoke(self, arg, _unused_from_tty):
-    if arg == 'current':
-      self._session.update_symbols(current_thread_only=True)
-    else:
-      self._session.update_symbols(current_thread_only=False)
-
-  def complete(self, text, _unused_word):
-    if text == self._UPDATE_COMMAND:
-      return ('all', 'current')
-    elif text in self._UPDATE_COMMAND + ' all':
-      return ['all']
-    elif text in self._UPDATE_COMMAND + ' current':
-      return ['current']
-    else:
-      return []
diff --git a/mojo/devtools/common/android_gdb/signatures.py b/mojo/devtools/common/android_gdb/signatures.py
deleted file mode 100644
index d1cc593..0000000
--- a/mojo/devtools/common/android_gdb/signatures.py
+++ /dev/null
@@ -1,30 +0,0 @@
-# Copyright 2015 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import itertools
-
-
-def get_signature(file_object, elffile_module):
-  """Computes a unique signature of a library file.
-
-  We only hash the .text section of the library in order to make the hash
-  resistant to stripping (we want the same hash for the same library with debug
-  symbols kept or stripped).
-  """
-  try:
-      elf = elffile_module.ELFFile(file_object)
-      text_section = elf.get_section_by_name('.text')
-  except elffile_module.common.ELFError:
-      return None
-  file_object.seek(text_section['sh_offset'])
-  data = file_object.read(min(4096, text_section['sh_size']))
-  def combine((i, c)):
-    return i ^ ord(c)
-  result = 16 * [0]
-  for i in xrange(0, len(data), len(result)):
-    result = map(combine,
-                 itertools.izip_longest(result,
-                                        data[i:i + len(result)],
-                                        fillvalue='\0'))
-  return ''.join(["%02x" % x for x in result])
diff --git a/mojo/devtools/common/android_stack_parser/LICENSE b/mojo/devtools/common/android_stack_parser/LICENSE
deleted file mode 100644
index d645695..0000000
--- a/mojo/devtools/common/android_stack_parser/LICENSE
+++ /dev/null
@@ -1,202 +0,0 @@
-
-                                 Apache License
-                           Version 2.0, January 2004
-                        http://www.apache.org/licenses/
-
-   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
-   1. Definitions.
-
-      "License" shall mean the terms and conditions for use, reproduction,
-      and distribution as defined by Sections 1 through 9 of this document.
-
-      "Licensor" shall mean the copyright owner or entity authorized by
-      the copyright owner that is granting the License.
-
-      "Legal Entity" shall mean the union of the acting entity and all
-      other entities that control, are controlled by, or are under common
-      control with that entity. For the purposes of this definition,
-      "control" means (i) the power, direct or indirect, to cause the
-      direction or management of such entity, whether by contract or
-      otherwise, or (ii) ownership of fifty percent (50%) or more of the
-      outstanding shares, or (iii) beneficial ownership of such entity.
-
-      "You" (or "Your") shall mean an individual or Legal Entity
-      exercising permissions granted by this License.
-
-      "Source" form shall mean the preferred form for making modifications,
-      including but not limited to software source code, documentation
-      source, and configuration files.
-
-      "Object" form shall mean any form resulting from mechanical
-      transformation or translation of a Source form, including but
-      not limited to compiled object code, generated documentation,
-      and conversions to other media types.
-
-      "Work" shall mean the work of authorship, whether in Source or
-      Object form, made available under the License, as indicated by a
-      copyright notice that is included in or attached to the work
-      (an example is provided in the Appendix below).
-
-      "Derivative Works" shall mean any work, whether in Source or Object
-      form, that is based on (or derived from) the Work and for which the
-      editorial revisions, annotations, elaborations, or other modifications
-      represent, as a whole, an original work of authorship. For the purposes
-      of this License, Derivative Works shall not include works that remain
-      separable from, or merely link (or bind by name) to the interfaces of,
-      the Work and Derivative Works thereof.
-
-      "Contribution" shall mean any work of authorship, including
-      the original version of the Work and any modifications or additions
-      to that Work or Derivative Works thereof, that is intentionally
-      submitted to Licensor for inclusion in the Work by the copyright owner
-      or by an individual or Legal Entity authorized to submit on behalf of
-      the copyright owner. For the purposes of this definition, "submitted"
-      means any form of electronic, verbal, or written communication sent
-      to the Licensor or its representatives, including but not limited to
-      communication on electronic mailing lists, source code control systems,
-      and issue tracking systems that are managed by, or on behalf of, the
-      Licensor for the purpose of discussing and improving the Work, but
-      excluding communication that is conspicuously marked or otherwise
-      designated in writing by the copyright owner as "Not a Contribution."
-
-      "Contributor" shall mean Licensor and any individual or Legal Entity
-      on behalf of whom a Contribution has been received by Licensor and
-      subsequently incorporated within the Work.
-
-   2. Grant of Copyright License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      copyright license to reproduce, prepare Derivative Works of,
-      publicly display, publicly perform, sublicense, and distribute the
-      Work and such Derivative Works in Source or Object form.
-
-   3. Grant of Patent License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      (except as stated in this section) patent license to make, have made,
-      use, offer to sell, sell, import, and otherwise transfer the Work,
-      where such license applies only to those patent claims licensable
-      by such Contributor that are necessarily infringed by their
-      Contribution(s) alone or by combination of their Contribution(s)
-      with the Work to which such Contribution(s) was submitted. If You
-      institute patent litigation against any entity (including a
-      cross-claim or counterclaim in a lawsuit) alleging that the Work
-      or a Contribution incorporated within the Work constitutes direct
-      or contributory patent infringement, then any patent licenses
-      granted to You under this License for that Work shall terminate
-      as of the date such litigation is filed.
-
-   4. Redistribution. You may reproduce and distribute copies of the
-      Work or Derivative Works thereof in any medium, with or without
-      modifications, and in Source or Object form, provided that You
-      meet the following conditions:
-
-      (a) You must give any other recipients of the Work or
-          Derivative Works a copy of this License; and
-
-      (b) You must cause any modified files to carry prominent notices
-          stating that You changed the files; and
-
-      (c) You must retain, in the Source form of any Derivative Works
-          that You distribute, all copyright, patent, trademark, and
-          attribution notices from the Source form of the Work,
-          excluding those notices that do not pertain to any part of
-          the Derivative Works; and
-
-      (d) If the Work includes a "NOTICE" text file as part of its
-          distribution, then any Derivative Works that You distribute must
-          include a readable copy of the attribution notices contained
-          within such NOTICE file, excluding those notices that do not
-          pertain to any part of the Derivative Works, in at least one
-          of the following places: within a NOTICE text file distributed
-          as part of the Derivative Works; within the Source form or
-          documentation, if provided along with the Derivative Works; or,
-          within a display generated by the Derivative Works, if and
-          wherever such third-party notices normally appear. The contents
-          of the NOTICE file are for informational purposes only and
-          do not modify the License. You may add Your own attribution
-          notices within Derivative Works that You distribute, alongside
-          or as an addendum to the NOTICE text from the Work, provided
-          that such additional attribution notices cannot be construed
-          as modifying the License.
-
-      You may add Your own copyright statement to Your modifications and
-      may provide additional or different license terms and conditions
-      for use, reproduction, or distribution of Your modifications, or
-      for any such Derivative Works as a whole, provided Your use,
-      reproduction, and distribution of the Work otherwise complies with
-      the conditions stated in this License.
-
-   5. Submission of Contributions. Unless You explicitly state otherwise,
-      any Contribution intentionally submitted for inclusion in the Work
-      by You to the Licensor shall be under the terms and conditions of
-      this License, without any additional terms or conditions.
-      Notwithstanding the above, nothing herein shall supersede or modify
-      the terms of any separate license agreement you may have executed
-      with Licensor regarding such Contributions.
-
-   6. Trademarks. This License does not grant permission to use the trade
-      names, trademarks, service marks, or product names of the Licensor,
-      except as required for reasonable and customary use in describing the
-      origin of the Work and reproducing the content of the NOTICE file.
-
-   7. Disclaimer of Warranty. Unless required by applicable law or
-      agreed to in writing, Licensor provides the Work (and each
-      Contributor provides its Contributions) on an "AS IS" BASIS,
-      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-      implied, including, without limitation, any warranties or conditions
-      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
-      PARTICULAR PURPOSE. You are solely responsible for determining the
-      appropriateness of using or redistributing the Work and assume any
-      risks associated with Your exercise of permissions under this License.
-
-   8. Limitation of Liability. In no event and under no legal theory,
-      whether in tort (including negligence), contract, or otherwise,
-      unless required by applicable law (such as deliberate and grossly
-      negligent acts) or agreed to in writing, shall any Contributor be
-      liable to You for damages, including any direct, indirect, special,
-      incidental, or consequential damages of any character arising as a
-      result of this License or out of the use or inability to use the
-      Work (including but not limited to damages for loss of goodwill,
-      work stoppage, computer failure or malfunction, or any and all
-      other commercial damages or losses), even if such Contributor
-      has been advised of the possibility of such damages.
-
-   9. Accepting Warranty or Additional Liability. While redistributing
-      the Work or Derivative Works thereof, You may choose to offer,
-      and charge a fee for, acceptance of support, warranty, indemnity,
-      or other liability obligations and/or rights consistent with this
-      License. However, in accepting such obligations, You may act only
-      on Your own behalf and on Your sole responsibility, not on behalf
-      of any other Contributor, and only if You agree to indemnify,
-      defend, and hold each Contributor harmless for any liability
-      incurred by, or claims asserted against, such Contributor by reason
-      of your accepting any such warranty or additional liability.
-
-   END OF TERMS AND CONDITIONS
-
-   APPENDIX: How to apply the Apache License to your work.
-
-      To apply the Apache License to your work, attach the following
-      boilerplate notice, with the fields enclosed by brackets "[]"
-      replaced with your own identifying information. (Don't include
-      the brackets!)  The text should be enclosed in the appropriate
-      comment syntax for the file format. We also recommend that a
-      file or class name and description of purpose be included on the
-      same "printed page" as the copyright notice for easier
-      identification within third-party archives.
-
-   Copyright [yyyy] [name of copyright owner]
-
-   Licensed under the Apache License, Version 2.0 (the "License");
-   you may not use this file except in compliance with the License.
-   You may obtain a copy of the License at
-
-       http://www.apache.org/licenses/LICENSE-2.0
-
-   Unless required by applicable law or agreed to in writing, software
-   distributed under the License is distributed on an "AS IS" BASIS,
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-   See the License for the specific language governing permissions and
-   limitations under the License.
diff --git a/mojo/devtools/common/android_stack_parser/README.chromium b/mojo/devtools/common/android_stack_parser/README.chromium
deleted file mode 100644
index 58f7c9b..0000000
--- a/mojo/devtools/common/android_stack_parser/README.chromium
+++ /dev/null
@@ -1,30 +0,0 @@
-Name: Android Platform engineering tools
-Short Name: android platform development
-URL: https://android.googlesource.com/platform/development
-Version: 0
-Date: 2014/05/02
-Revision: 1b10ec4
-License: Apache 2.0
-License File: NOT_SHIPPED
-Security Critical: no
-
-Description:
-Android Platform engineering tools, specifically stack symbolization scripts
-and a jar containing the AOSP framework to compile the Android WebView
-glue layer against. The sources used to build the AOSP framework jar can be
-checked out using repo on the corresponding manifest file. The AOSP framework
-jar is built by invoking make on the android_system_stubs target.
-
-Local Modifications:
-Only picked the few scripts needed by chrome.
-Updated output directories to use environment variable.
-When calling addr2line, check the symbol is a file (and not a directory).
-Added support for parsing LOG(FATAL) and DCHECK errors and their
-    stack traces, as emitted by src/base/debug/stack_trace_android.cc
-Added support for finding symbols when library is loaded directly from the APK.
-Changed the toolchain to remove references to 4.6 toolchains.
-Added support for arch=x64 as an alias to arch=x86_64
-Added support for mojo. Specifically detection of mojo apps downloaded
-    to temporary files which are in crash stacks.
-Taught `stack` to find the output directory and android_tools regardless of
-    where under the checkout root it is placed.
diff --git a/mojo/devtools/common/android_stack_parser/stack b/mojo/devtools/common/android_stack_parser/stack
deleted file mode 100755
index 97913ab..0000000
--- a/mojo/devtools/common/android_stack_parser/stack
+++ /dev/null
@@ -1,255 +0,0 @@
-#!/usr/bin/env python
-#
-# Copyright (C) 2013 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-"""stack symbolizes native crash dumps."""
-
-import getopt
-import glob
-import os
-import re
-import sys
-
-import stack_core
-import subprocess
-import symbol
-
-_DEFAULT_SYMROOT = '/tmp/symbols'
-_DEFAULT_BUILD_DIR = 'out/android_Debug'
-_DEFAULT_NDK_DIR = 'third_party/android_tools/ndk'
-
-
-def PrintUsage():
-  """Print usage and exit with error."""
-  # pylint: disable-msg=C6310
-  print
-  print "  usage: " + sys.argv[0] + " [options] [FILE]"
-  print
-  print "  --symbols-dir=path"
-  print "       the path to a symbols dir, this is generally for system level"
-  print "       symbols"
-  print
-  print "  --build-dir=path"
-  print "       the path to a directory containing Mojo symbols (can be"
-  print "       absolute or relative to src), such as =out/android_Debug"
-
-  print "  --ndk-dir=path"
-  print "       the path to a directory containing Android NDK"
-  print
-  print "  --symbols-zip=path"
-  print "       the path to a symbols zip file, such as =dream-symbols-12345.zip"
-  print
-  print "  --more-info"
-  print "  --less-info"
-  print "       Change the level of detail in the output."
-  print "       --more-info is slower and more verbose, but more functions will"
-  print "       be fully qualified with namespace/classname and have full"
-  print "       argument information. Also, the 'stack data' section will be"
-  print "       printed."
-  print
-  print "  --arch=arm|arm64|x64|x86|mips"
-  print "       the target architecture"
-  print
-  print "  FILE should contain a stack trace in it somewhere"
-  print "       the tool will find that and re-print it with"
-  print "       source files and line numbers.  If you don't"
-  print "       pass FILE, or if file is -, it reads from"
-  print "       stdin."
-  print
-  # pylint: enable-msg=C6310
-  sys.exit(1)
-
-def UnzipSymbols(symbolfile, symdir=None):
-  """Unzips a file to _DEFAULT_SYMROOT and returns the unzipped location.
-
-  Args:
-    symbolfile: The .zip file to unzip
-    symdir: Optional temporary directory to use for extraction
-
-  Returns:
-    A tuple containing (the directory into which the zip file was unzipped,
-    the path to the "symbols" directory in the unzipped file).  To clean
-    up, the caller can delete the first element of the tuple.
-
-  Raises:
-    SymbolDownloadException: When the unzip fails.
-  """
-  if not symdir:
-    symdir = "%s/%s" % (_DEFAULT_SYMROOT, hash(symbolfile))
-  if not os.path.exists(symdir):
-    os.makedirs(symdir)
-
-  print "extracting %s..." % symbolfile
-  saveddir = os.getcwd()
-  os.chdir(symdir)
-  try:
-    unzipcode = subprocess.call(["unzip", "-qq", "-o", symbolfile])
-    if unzipcode > 0:
-      os.remove(symbolfile)
-      raise SymbolDownloadException("failed to extract symbol files (%s)."
-                                    % symbolfile)
-  finally:
-    os.chdir(saveddir)
-
-  android_symbols = glob.glob("%s/out/target/product/*/symbols" % symdir)
-  if android_symbols:
-    return (symdir, android_symbols[0])
-  else:
-    # This is a zip of Chrome symbols, so symbol.CHROME_SYMBOLS_DIR needs to be
-    # updated to point here.
-    symbol.CHROME_SYMBOLS_DIR = symdir
-    return (symdir, symdir)
-
-
-def GetBasenameFromMojoApp(url):
-  """Used by GetSymbolMapping() to extract the basename from the location the
-  mojo app was downloaded from. The location is a URL, e.g.
-  http://foo/bar/x.so."""
-  index = url.rfind('/')
-  return url[(index + 1):] if index != -1 else url
-
-
-def GetSymboledNameForMojoApp(path):
-  """Used by GetSymbolMapping to get the non-stripped library name for an
-  installed mojo app."""
-  # e.g. tracing.mojo -> libtracing_library.so
-  name, ext = os.path.splitext(path)
-  if ext != '.mojo':
-    return path
-  return 'lib%s_library.so' % name
-
-
-def GetSymbolMapping(lines):
-  """Returns a mapping (dictionary) from download file to .so."""
-  regex = re.compile('Caching mojo app (\S+) at (\S+)')
-  mappings = {}
-  for line in lines:
-    result = regex.search(line)
-    if result:
-      url = GetBasenameFromMojoApp(result.group(1))
-      mappings[result.group(2)] = GetSymboledNameForMojoApp(url)
-  return mappings
-
-
-def _LowestAncestorContainingRelpath(dir_path, relpath):
-  """Returns the lowest ancestor dir of |dir_path| that contains |relpath|.
-  """
-  cur_dir_path = os.path.abspath(dir_path)
-  while True:
-    if os.path.exists(os.path.join(cur_dir_path, relpath)):
-      return cur_dir_path
-
-    next_dir_path = os.path.dirname(cur_dir_path)
-    if next_dir_path != cur_dir_path:
-      cur_dir_path = next_dir_path
-    else:
-      return None
-
-
-def _GuessDir(relpath):
-  """Returns absolute path to location |relpath| in the lowest ancestor of this
-  file that contains it."""
-  lowest_ancestor = _LowestAncestorContainingRelpath(
-      os.path.dirname(__file__), relpath)
-  if not lowest_ancestor:
-    return None
-  return os.path.join(lowest_ancestor, relpath)
-
-
-
-def main():
-  try:
-    options, arguments = getopt.getopt(sys.argv[1:], "",
-                                       ["more-info",
-                                        "less-info",
-                                        "build-dir=",
-                                        "ndk-dir=",
-                                        "symbols-dir=",
-                                        "symbols-zip=",
-                                        "arch=",
-                                        "help"])
-  except getopt.GetoptError, unused_error:
-    PrintUsage()
-
-  zip_arg = None
-  more_info = False
-  for option, value in options:
-    if option == "--help":
-      PrintUsage()
-    elif option == "--symbols-dir":
-      symbol.SYMBOLS_DIR = os.path.expanduser(value)
-    elif option == "--symbols-zip":
-      zip_arg = os.path.expanduser(value)
-    elif option == "--arch":
-      symbol.ARCH = value
-    elif option == "--build-dir":
-      symbol.BUILD_DIR = value
-    elif option == "--ndk-dir":
-      symbol.NDK_DIR = value
-    elif option == "--more-info":
-      more_info = True
-    elif option == "--less-info":
-      more_info = False
-
-  if not symbol.BUILD_DIR:
-    guess = _GuessDir(_DEFAULT_BUILD_DIR)
-    if not guess:
-      print "Couldn't find the build directory, please pass --build-dir."
-      return 1
-    print "Inferring the build directory path as " + guess
-    symbol.BUILD_DIR = guess
-
-  if not symbol.NDK_DIR:
-    guess = _GuessDir(_DEFAULT_NDK_DIR)
-    if not guess:
-      print "Couldn't find the Android NDK, please pass --ndk-dir."
-      return 1
-    print "Inferring the Android NDK path as " + guess
-    symbol.NDK_DIR = guess
-
-
-  if len(arguments) > 1:
-    PrintUsage()
-
-  if not arguments or arguments[0] == "-":
-    print "Reading native crash info from stdin"
-    f = sys.stdin
-  else:
-    print "Searching for native crashes in %s" % arguments[0]
-    f = open(arguments[0], "r")
-
-  lines = f.readlines()
-  f.close()
-
-  rootdir = None
-  if zip_arg:
-    rootdir, symbol.SYMBOLS_DIR = UnzipSymbols(zip_arg)
-
-  if symbol.SYMBOLS_DIR:
-    print "Reading Android symbols from", symbol.SYMBOLS_DIR
-
-  print "Reading Mojo symbols from", symbol.BUILD_DIR
-  stack_core.ConvertTrace(lines, more_info, GetSymbolMapping(lines))
-
-  if rootdir:
-    # be a good citizen and clean up...os.rmdir and os.removedirs() don't work
-    cmd = "rm -rf \"%s\"" % rootdir
-    print "\ncleaning up (%s)" % cmd
-    os.system(cmd)
-
-if __name__ == "__main__":
-  main()
-
-# vi: ts=2 sw=2
diff --git a/mojo/devtools/common/android_stack_parser/stack_core.py b/mojo/devtools/common/android_stack_parser/stack_core.py
deleted file mode 100644
index 2148e9d..0000000
--- a/mojo/devtools/common/android_stack_parser/stack_core.py
+++ /dev/null
@@ -1,262 +0,0 @@
-# Copyright (C) 2013 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-"""stack symbolizes native crash dumps."""
-
-import re
-
-import symbol
-
-def PrintTraceLines(trace_lines):
-  """Print back trace."""
-  maxlen = max(map(lambda tl: len(tl[1]), trace_lines))
-  print
-  print "Stack Trace:"
-  print "  RELADDR   " + "FUNCTION".ljust(maxlen) + "  FILE:LINE"
-  for tl in trace_lines:
-    (addr, symbol_with_offset, location) = tl
-    print "  %8s  %s  %s" % (addr, symbol_with_offset.ljust(maxlen), location)
-  return
-
-
-def PrintValueLines(value_lines):
-  """Print stack data values."""
-  maxlen = max(map(lambda tl: len(tl[2]), value_lines))
-  print
-  print "Stack Data:"
-  print "  ADDR      VALUE     " + "FUNCTION".ljust(maxlen) + "  FILE:LINE"
-  for vl in value_lines:
-    (addr, value, symbol_with_offset, location) = vl
-    print "  %8s  %8s  %s  %s" % (addr, value, symbol_with_offset.ljust(maxlen), location)
-  return
-
-UNKNOWN = "<unknown>"
-HEAP = "[heap]"
-STACK = "[stack]"
-
-
-def PrintOutput(trace_lines, value_lines, more_info):
-  if trace_lines:
-    PrintTraceLines(trace_lines)
-  if value_lines:
-    # TODO(cjhopman): it seems that symbol.SymbolInformation always fails to
-    # find information for addresses in value_lines in chrome libraries, and so
-    # value_lines have little value to us and merely clutter the output.
-    # Since information is sometimes contained in these lines (from system
-    # libraries), don't completely disable them.
-    if more_info:
-      PrintValueLines(value_lines)
-
-def PrintDivider():
-  print
-  print "-----------------------------------------------------\n"
-
-def ConvertTrace(lines, more_info, symbol_file_mappings):
-  """Convert strings containing native crash to a stack.
-
-  Args:
-    symbol_file_mappings: maps from library pathname to base name of file
-      containing symbols. If |symbol_file_mappings| doesn't contain a path than
-      the library pathname is used. See TranslatePathFromDeviceToLocal() for
-      more information.
-  """
-  process_info_line = re.compile("(pid: [0-9]+, tid: [0-9]+.*)")
-  signal_line = re.compile("(signal [0-9]+ \(.*\).*)")
-  register_line = re.compile("(([ ]*[0-9a-z]{2} [0-9a-f]{8}){4})")
-  thread_line = re.compile("(.*)(\-\-\- ){15}\-\-\-")
-  dalvik_jni_thread_line = re.compile("(\".*\" prio=[0-9]+ tid=[0-9]+ NATIVE.*)")
-  dalvik_native_thread_line = re.compile("(\".*\" sysTid=[0-9]+ nice=[0-9]+.*)")
-
-  width = "{8}"
-  if symbol.ARCH == "arm64" or symbol.ARCH == "x86_64" or symbol.ARCH == "x64":
-    width = "{16}"
-
-  # Matches LOG(FATAL) lines, like the following example:
-  #   [FATAL:source_file.cc(33)] Check failed: !instances_.empty()
-  log_fatal_line = re.compile("(\[FATAL\:.*\].*)$")
-
-  # Note that both trace and value line matching allow for variable amounts of
-  # whitespace (e.g. \t). This is because the we want to allow for the stack
-  # tool to operate on AndroidFeedback provided system logs. AndroidFeedback
-  # strips out double spaces that are found in tombsone files and logcat output.
-  #
-  # Examples of matched trace lines include lines from tombstone files like:
-  #   #00  pc 001cf42e  /data/data/com.my.project/lib/libmyproject.so
-  #   #00  pc 001cf42e  /data/data/com.my.project/lib/libmyproject.so (symbol)
-  # Or lines from AndroidFeedback crash report system logs like:
-  #   03-25 00:51:05.520 I/DEBUG ( 65): #00 pc 001cf42e /data/data/com.my.project/lib/libmyproject.so
-  # Please note the spacing differences.
-  trace_line = re.compile("(.*)\#(?P<frame>[0-9]+)[ \t]+(..)[ \t]+(0x)?(?P<address>[0-9a-f]{0,16})[ \t]+(?P<lib>[^\r\n \t]*)(?P<symbol_present> \((?P<symbol_name>.*)\))?")  # pylint: disable-msg=C6310
-
-  # Matches lines emitted by src/base/debug/stack_trace_android.cc, like:
-  #   #00 0x7324d92d /data/app-lib/org.chromium.native_test-1/libbase.cr.so+0x0006992d
-  # This pattern includes the unused named capture groups <symbol_present> and
-  # <symbol_name> so that it can interoperate with the |trace_line| regex.
-  debug_trace_line = re.compile(
-      '(.*)(?P<frame>\#[0-9]+ 0x[0-9a-f]' + width + ') '
-      '(?P<lib>[^+]+)( \(deleted\))+\+0x(?P<address>[0-9a-f]' + width + ')'
-      '(?P<symbol_present>)(?P<symbol_name>)')
-
-  # Examples of matched value lines include:
-  #   bea4170c  8018e4e9  /data/data/com.my.project/lib/libmyproject.so
-  #   bea4170c  8018e4e9  /data/data/com.my.project/lib/libmyproject.so (symbol)
-  #   03-25 00:51:05.530 I/DEBUG ( 65): bea4170c 8018e4e9 /data/data/com.my.project/lib/libmyproject.so
-  # Again, note the spacing differences.
-  value_line = re.compile("(.*)([0-9a-f]" + width + ")[ \t]+([0-9a-f]" + width + ")[ \t]+([^\r\n \t]*)( \((.*)\))?")
-  # Lines from 'code around' sections of the output will be matched before
-  # value lines because otheriwse the 'code around' sections will be confused as
-  # value lines.
-  #
-  # Examples include:
-  #   801cf40c ffffc4cc 00b2f2c5 00b2f1c7 00c1e1a8
-  #   03-25 00:51:05.530 I/DEBUG ( 65): 801cf40c ffffc4cc 00b2f2c5 00b2f1c7 00c1e1a8
-  code_line = re.compile("(.*)[ \t]*[a-f0-9]" + width +
-                         "[ \t]*[a-f0-9]" + width +
-                         "[ \t]*[a-f0-9]" + width +
-                         "[ \t]*[a-f0-9]" + width +
-                         "[ \t]*[a-f0-9]" + width +
-                         "[ \t]*[ \r\n]")  # pylint: disable-msg=C6310
-
-  trace_lines = []
-  value_lines = []
-  last_frame = -1
-
-  # It is faster to get symbol information with a single call rather than with
-  # separate calls for each line. Since symbol.SymbolInformation caches results,
-  # we can extract all the addresses that we will want symbol information for
-  # from the log and call symbol.SymbolInformation so that the results are
-  # cached in the following lookups.
-  code_addresses = {}
-  for ln in lines:
-    line = unicode(ln, errors='ignore')
-    lib, address = None, None
-
-    match = trace_line.match(line) or debug_trace_line.match(line)
-    if match:
-      address, lib = match.group('address', 'lib')
-
-    match = value_line.match(line)
-    if match and not code_line.match(line):
-      (_0, _1, address, lib, _2, _3) = match.groups()
-
-    if lib:
-      code_addresses.setdefault(lib, set()).add(address)
-
-  for lib in code_addresses:
-    symbol.SymbolInformationForSet(
-        symbol.TranslatePathFromDeviceToLocal(
-            symbol_file_mappings.get(lib, lib)),
-        code_addresses[lib], more_info)
-
-  for ln in lines:
-    # AndroidFeedback adds zero width spaces into its crash reports. These
-    # should be removed or the regular expresssions will fail to match.
-    line = unicode(ln, errors='ignore')
-    process_header = process_info_line.search(line)
-    signal_header = signal_line.search(line)
-    register_header = register_line.search(line)
-    thread_header = thread_line.search(line)
-    dalvik_jni_thread_header = dalvik_jni_thread_line.search(line)
-    dalvik_native_thread_header = dalvik_native_thread_line.search(line)
-    log_fatal_header = log_fatal_line.search(line)
-    if (process_header or signal_header or register_header or thread_header or
-        dalvik_jni_thread_header or dalvik_native_thread_header or
-        log_fatal_header) :
-      if trace_lines or value_lines:
-        PrintOutput(trace_lines, value_lines, more_info)
-        PrintDivider()
-        trace_lines = []
-        value_lines = []
-        last_frame = -1
-      if process_header:
-        print process_header.group(1)
-      if signal_header:
-        print signal_header.group(1)
-      if register_header:
-        print register_header.group(1)
-      if thread_header:
-        print thread_header.group(1)
-      if dalvik_jni_thread_header:
-        print dalvik_jni_thread_header.group(1)
-      if dalvik_native_thread_header:
-        print dalvik_native_thread_header.group(1)
-      if log_fatal_header:
-        print log_fatal_header.group(1)
-      continue
-
-    match = trace_line.match(line) or debug_trace_line.match(line)
-    if match:
-      frame, code_addr, area, symbol_present, symbol_name = match.group(
-          'frame', 'address', 'lib', 'symbol_present', 'symbol_name')
-
-      if frame <= last_frame and (trace_lines or value_lines):
-        PrintOutput(trace_lines, value_lines, more_info)
-        PrintDivider()
-        trace_lines = []
-        value_lines = []
-      last_frame = frame
-
-      if area == UNKNOWN or area == HEAP or area == STACK:
-        trace_lines.append((code_addr, "", area))
-      else:
-        # If a calls b which further calls c and c is inlined to b, we want to
-        # display "a -> b -> c" in the stack trace instead of just "a -> c"
-        info = symbol.SymbolInformation(symbol_file_mappings.get(area, area),
-                                        code_addr, more_info)
-        nest_count = len(info) - 1
-        for (source_symbol, source_location, object_symbol_with_offset) in info:
-          if not source_symbol:
-            if symbol_present:
-              source_symbol = symbol.CallCppFilt(symbol_name)
-            else:
-              source_symbol = UNKNOWN
-          if not source_location:
-            source_location = area
-          if nest_count > 0:
-            nest_count = nest_count - 1
-            trace_lines.append(("v------>", source_symbol, source_location))
-          else:
-            if not object_symbol_with_offset:
-              object_symbol_with_offset = source_symbol
-            trace_lines.append((code_addr,
-                                object_symbol_with_offset,
-                                source_location))
-    if code_line.match(line):
-      # Code lines should be ignored. If this were exluded the 'code around'
-      # sections would trigger value_line matches.
-      continue;
-    match = value_line.match(line)
-    if match:
-      (unused_, addr, value, area, symbol_present, symbol_name) = match.groups()
-      if area == UNKNOWN or area == HEAP or area == STACK or not area:
-        value_lines.append((addr, value, "", area))
-      else:
-        info = symbol.SymbolInformation(symbol_file_mappings.get(area, area),
-                                        value, more_info)
-        (source_symbol, source_location, object_symbol_with_offset) = info.pop()
-        if not source_symbol:
-          if symbol_present:
-            source_symbol = symbol.CallCppFilt(symbol_name)
-          else:
-            source_symbol = UNKNOWN
-        if not source_location:
-          source_location = area
-        if not object_symbol_with_offset:
-          object_symbol_with_offset = source_symbol
-        value_lines.append((addr,
-                            value,
-                            object_symbol_with_offset,
-                            source_location))
-
-  PrintOutput(trace_lines, value_lines, more_info)
diff --git a/mojo/devtools/common/android_stack_parser/symbol.py b/mojo/devtools/common/android_stack_parser/symbol.py
deleted file mode 100644
index 797326c..0000000
--- a/mojo/devtools/common/android_stack_parser/symbol.py
+++ /dev/null
@@ -1,563 +0,0 @@
-# Copyright (C) 2013 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-"""Module for looking up symbolic debugging information.
-
-The information can include symbol names, offsets, and source locations.
-"""
-
-import glob
-import itertools
-import os
-import re
-import subprocess
-import zipfile
-
-NDK_DIR = ""
-BUILD_DIR = ""
-SYMBOLS_DIR = ""
-
-ARCH = "arm"
-
-TOOLCHAIN_INFO = None
-
-def Uname():
-  """'uname' for constructing prebuilt/<...> and out/host/<...> paths."""
-  uname = os.uname()[0]
-  proc = os.uname()[-1]
-  if uname == "Darwin":
-    if proc == "i386":
-      return "darwin-x86"
-    elif proc == "x86_64":
-      return "darwin-x86_64"
-    return "darwin-ppc"
-  if uname == "Linux":
-    if proc == "i386":
-      return "linux-x86"
-    else:
-      return "linux-x86_64"
-  return uname
-
-def ToolPath(tool, toolchain_info=None):
-  """Return a full qualified path to the specified tool"""
-  # ToolPath looks for the tools in the completely incorrect directory.
-  # This looks in the checked in android_tools.
-  if ARCH == "arm":
-    toolchain_source = "arm-linux-androideabi-4.9"
-    toolchain_prefix = "arm-linux-androideabi"
-  elif ARCH == "arm64":
-    toolchain_source = "aarch64-linux-android-4.9"
-    toolchain_prefix = "aarch64-linux-android"
-  elif ARCH == "x86":
-    toolchain_source = "x86-4.9"
-    toolchain_prefix = "i686-linux-android"
-  elif ARCH == "x86_64" or ARCH == "x64":
-    toolchain_source = "x86_64-4.9"
-    toolchain_prefix = "x86_64-linux-android"
-  elif ARCH == "mips":
-    toolchain_source = "mipsel-linux-android-4.9"
-    toolchain_prefix = "mipsel-linux-android"
-  else:
-    raise Exception("Could not find tool chain")
-
-  toolchain_subdir = ("toolchains/%s/prebuilt/%s/bin" % (
-                      toolchain_source, Uname()))
-
-  return os.path.join(NDK_DIR,
-                      toolchain_subdir,
-                      toolchain_prefix + "-" + tool)
-
-def FindToolchain():
-  """Look for the latest available toolchain
-
-  Args:
-    None
-
-  Returns:
-    A pair of strings containing toolchain label and target prefix.
-  """
-  global TOOLCHAIN_INFO
-  if TOOLCHAIN_INFO is not None:
-    return TOOLCHAIN_INFO
-
-  ## Known toolchains, newer ones in the front.
-  gcc_version = "4.9"
-  if ARCH == "arm64":
-    known_toolchains = [
-      ("aarch64-linux-android-" + gcc_version, "aarch64", "aarch64-linux-android")
-    ]
-  elif ARCH == "arm":
-    known_toolchains = [
-      ("arm-linux-androideabi-" + gcc_version, "arm", "arm-linux-androideabi")
-    ]
-  elif ARCH =="x86":
-    known_toolchains = [
-      ("x86-" + gcc_version, "x86", "i686-linux-android")
-    ]
-  elif ARCH =="x86_64" or ARCH =="x64":
-    known_toolchains = [
-      ("x86_64-" + gcc_version, "x86_64", "x86_64-linux-android")
-    ]
-  elif ARCH == "mips":
-    known_toolchains = [
-      ("mipsel-linux-android-" + gcc_version, "mips", "mipsel-linux-android")
-    ]
-  else:
-    known_toolchains = []
-
-  # Look for addr2line to check for valid toolchain path.
-  for (label, platform, target) in known_toolchains:
-    toolchain_info = (label, platform, target);
-    if os.path.exists(ToolPath("addr2line", toolchain_info)):
-      TOOLCHAIN_INFO = toolchain_info
-      print "Using toolchain from :" + ToolPath("", TOOLCHAIN_INFO)
-      return toolchain_info
-
-  raise Exception("Could not find tool chain")
-
-def GetAapt():
-  """Returns the path to aapt.
-
-  Args:
-    None
-
-  Returns:
-    the pathname of the 'aapt' executable.
-  """
-  sdk_home = os.path.join('third_party', 'android_tools', 'sdk')
-  sdk_home = os.environ.get('SDK_HOME', sdk_home)
-  aapt_exe = glob.glob(os.path.join(sdk_home, 'build-tools', '*', 'aapt'))
-  if not aapt_exe:
-    return None
-  return sorted(aapt_exe, key=os.path.getmtime, reverse=True)[0]
-
-def ApkMatchPackageName(aapt, apk_path, package_name):
-  """Returns true the APK's package name matches package_name.
-
-  Args:
-    aapt: pathname for the 'aapt' executable.
-    apk_path: pathname of the APK file.
-    package_name: package name to match.
-
-  Returns:
-    True if the package name matches or aapt is None, False otherwise.
-  """
-  if not aapt:
-    # Allow false positives
-    return True
-  aapt_output = subprocess.check_output(
-      [aapt, 'dump', 'badging', apk_path]).split('\n')
-  package_name_re = re.compile(r'package: .*name=\'(\S*)\'')
-  for line in aapt_output:
-    match = package_name_re.match(line)
-    if match:
-      return package_name == match.group(1)
-  return False
-
-def PathListJoin(prefix_list, suffix_list):
-   """Returns each prefix in prefix_list joined with each suffix in suffix list.
-
-   Args:
-     prefix_list: list of path prefixes.
-     suffix_list: list of path suffixes.
-
-   Returns:
-     List of paths each of which joins a prefix with a suffix.
-   """
-   return [
-       os.path.join(prefix, suffix)
-       for prefix in prefix_list for suffix in suffix_list ]
-
-def GetCandidates(filepart, candidate_fun, relative_dirs=None):
-  """Returns a list of candidate filenames.
-
-  Args:
-    filepart: the file part of the pathname.
-    candidate_fun: a function to apply to each candidate, returns a list.
-    relative_dirs: a list of relative directory names to search from.
-
-  Returns:
-    A list of candidate files ordered by modification time, newest first.
-  """
-  candidates = [BUILD_DIR]
-
-  if relative_dirs:
-    candidates = PathListJoin(candidates, relative_dirs)
-
-  candidates = PathListJoin(candidates, [filepart])
-  candidates = list(
-      itertools.chain.from_iterable(map(candidate_fun, candidates)))
-  candidates = sorted(candidates, key=os.path.getmtime, reverse=True)
-  return candidates
-
-def GetCandidateApks():
-  """Returns a list of APKs which could contain the library.
-
-  Args:
-    None
-
-  Returns:
-    list of APK filename which could contain the library.
-  """
-  return GetCandidates('*.apk', glob.glob, relative_dirs=['apks'])
-
-def GetCrazyLib(apk_filename):
-  """Returns the name of the first crazy library from this APK.
-
-  Args:
-    apk_filename: name of an APK file.
-
-  Returns:
-    Name of the first library which would be crazy loaded from this APK.
-  """
-  zip_file = zipfile.ZipFile(apk_filename, 'r')
-  for filename in zip_file.namelist():
-    match = re.match('lib/[^/]*/crazy.(lib.*[.]so)', filename)
-    if match:
-      return match.group(1)
-
-def GetMatchingApks(device_apk_name):
-  """Find any APKs which match the package indicated by the device_apk_name.
-
-  Args:
-     device_apk_name: name of the APK on the device.
-
-  Returns:
-     A list of APK filenames which could contain the desired library.
-  """
-  match = re.match('(.*)-[0-9]+[.]apk$', device_apk_name)
-  if not match:
-    return None
-  package_name = match.group(1)
-  return filter(
-      lambda candidate_apk:
-          ApkMatchPackageName(GetAapt(), candidate_apk, package_name),
-      GetCandidateApks())
-
-def MapDeviceApkToLibrary(device_apk_name):
-  """Provide a library name which corresponds with device_apk_name.
-
-  Args:
-    device_apk_name: name of the APK on the device.
-
-  Returns:
-    Name of the library which corresponds to that APK.
-  """
-  matching_apks = GetMatchingApks(device_apk_name)
-  for matching_apk in matching_apks:
-    crazy_lib = GetCrazyLib(matching_apk)
-    if crazy_lib:
-      return crazy_lib
-
-def GetCandidateLibraries(library_name):
-  """Returns a list of candidate library filenames.
-
-  Args:
-    library_name: basename of the library to match.
-
-  Returns:
-    A list of matching library filenames for library_name.
-  """
-  return GetCandidates(
-      library_name,
-      lambda filename: filter(os.path.exists, [filename]))
-
-def TranslatePathFromDeviceToLocal(lib):
-  """Maps a path as seen on the device to a path on the local file system
-  containing symbols.
-
-  Args:
-    lib: library (or executable) pathname from device.
-  """
-
-  # SymbolInformation(lib, addr) receives lib that is either a basename or
-  # the path from symbols root to the symbols file. This needs to be translated
-  # to point to the correct .so path. If the user doesn't explicitly specify
-  # which directory to use, then use the most recently updated one in one of
-  # the known directories.
-  library_name = os.path.basename(lib)
-
-  # The filename in the stack trace maybe an APK name rather than a library
-  # name. This happens when the library was loaded directly from inside the
-  # APK. If this is the case we try to figure out the library name by looking
-  # for a matching APK file and finding the name of the library in contains.
-  # The name of the APK file on the device is of the form
-  # <package_name>-<number>.apk. The APK file on the host may have any name
-  # so we look at the APK badging to see if the package name matches.
-  if re.search('-[0-9]+[.]apk$', library_name):
-    mapping = MapDeviceApkToLibrary(library_name)
-    if mapping:
-      library_name = mapping
-
-  candidate_libraries = GetCandidateLibraries(library_name)
-  return (candidate_libraries[0] if candidate_libraries else
-      os.path.join(SYMBOLS_DIR, lib))
-
-def SymbolInformation(lib, addr, get_detailed_info):
-  """Look up symbol information about an address.
-
-  Args:
-    lib: library (or executable) pathname containing symbols
-    addr: string hexidecimal address
-
-  Returns:
-    A list of the form [(source_symbol, source_location,
-    object_symbol_with_offset)].
-
-    If the function has been inlined then the list may contain
-    more than one element with the symbols for the most deeply
-    nested inlined location appearing first.  The list is
-    always non-empty, even if no information is available.
-
-    Usually you want to display the source_location and
-    object_symbol_with_offset from the last element in the list.
-  """
-  lib = TranslatePathFromDeviceToLocal(lib)
-  info = SymbolInformationForSet(lib, set([addr]), get_detailed_info)
-  return (info and info.get(addr)) or [(None, None, None)]
-
-
-def SymbolInformationForSet(lib, unique_addrs, get_detailed_info):
-  """Look up symbol information for a set of addresses from the given library.
-
-  Args:
-    lib: library (or executable) pathname containing symbols
-    unique_addrs: set of hexidecimal addresses
-
-  Returns:
-    A dictionary of the form {addr: [(source_symbol, source_location,
-    object_symbol_with_offset)]} where each address has a list of
-    associated symbols and locations.  The list is always non-empty.
-
-    If the function has been inlined then the list may contain
-    more than one element with the symbols for the most deeply
-    nested inlined location appearing first.  The list is
-    always non-empty, even if no information is available.
-
-    Usually you want to display the source_location and
-    object_symbol_with_offset from the last element in the list.
-  """
-  if not lib:
-    return None
-
-  addr_to_line = CallAddr2LineForSet(lib, unique_addrs)
-  if not addr_to_line:
-    return None
-
-  if get_detailed_info:
-    addr_to_objdump = CallObjdumpForSet(lib, unique_addrs)
-    if not addr_to_objdump:
-      return None
-  else:
-    addr_to_objdump = dict((addr, ("", 0)) for addr in unique_addrs)
-
-  result = {}
-  for addr in unique_addrs:
-    source_info = addr_to_line.get(addr)
-    if not source_info:
-      source_info = [(None, None)]
-    if addr in addr_to_objdump:
-      (object_symbol, object_offset) = addr_to_objdump.get(addr)
-      object_symbol_with_offset = FormatSymbolWithOffset(object_symbol,
-                                                         object_offset)
-    else:
-      object_symbol_with_offset = None
-    result[addr] = [(source_symbol, source_location, object_symbol_with_offset)
-        for (source_symbol, source_location) in source_info]
-
-  return result
-
-
-class MemoizedForSet(object):
-  def __init__(self, fn):
-    self.fn = fn
-    self.cache = {}
-
-  def __call__(self, lib, unique_addrs):
-    lib_cache = self.cache.setdefault(lib, {})
-
-    no_cache = filter(lambda x: x not in lib_cache, unique_addrs)
-    if no_cache:
-      lib_cache.update((k, None) for k in no_cache)
-      result = self.fn(lib, no_cache)
-      if result:
-        lib_cache.update(result)
-
-    return dict((k, lib_cache[k]) for k in unique_addrs if lib_cache[k])
-
-
-@MemoizedForSet
-def CallAddr2LineForSet(lib, unique_addrs):
-  """Look up line and symbol information for a set of addresses.
-
-  Args:
-    lib: library (or executable) pathname containing symbols
-    unique_addrs: set of string hexidecimal addresses look up.
-
-  Returns:
-    A dictionary of the form {addr: [(symbol, file:line)]} where
-    each address has a list of associated symbols and locations
-    or an empty list if no symbol information was found.
-
-    If the function has been inlined then the list may contain
-    more than one element with the symbols for the most deeply
-    nested inlined location appearing first.
-  """
-  if not lib or not os.path.isfile(lib):
-    return None
-
-  (label, platform, target) = FindToolchain()
-  cmd = [ToolPath("addr2line"), "--functions", "--inlines",
-         "--demangle", "--exe=" + lib]
-  child = subprocess.Popen(cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE)
-
-  result = {}
-  addrs = sorted(unique_addrs)
-  for addr in addrs:
-    child.stdin.write("0x%s\n" % addr)
-    child.stdin.flush()
-    records = []
-    first = True
-    while True:
-      symbol = child.stdout.readline().strip()
-      if symbol == "??":
-        symbol = None
-      location = child.stdout.readline().strip()
-      if location == "??:0":
-        location = None
-      if symbol is None and location is None:
-        break
-      records.append((symbol, location))
-      if first:
-        # Write a blank line as a sentinel so we know when to stop
-        # reading inlines from the output.
-        # The blank line will cause addr2line to emit "??\n??:0\n".
-        child.stdin.write("\n")
-        first = False
-    result[addr] = records
-  child.stdin.close()
-  child.stdout.close()
-  return result
-
-
-def StripPC(addr):
-  """Strips the Thumb bit a program counter address when appropriate.
-
-  Args:
-    addr: the program counter address
-
-  Returns:
-    The stripped program counter address.
-  """
-  global ARCH
-
-  if ARCH == "arm":
-    return addr & ~1
-  return addr
-
-@MemoizedForSet
-def CallObjdumpForSet(lib, unique_addrs):
-  """Use objdump to find out the names of the containing functions.
-
-  Args:
-    lib: library (or executable) pathname containing symbols
-    unique_addrs: set of string hexidecimal addresses to find the functions for.
-
-  Returns:
-    A dictionary of the form {addr: (string symbol, offset)}.
-  """
-  if not lib:
-    return None
-
-  symbols = SYMBOLS_DIR + lib
-  if not os.path.exists(symbols):
-    return None
-
-  symbols = SYMBOLS_DIR + lib
-  if not os.path.exists(symbols):
-    return None
-
-  result = {}
-
-  # Function lines look like:
-  #   000177b0 <android::IBinder::~IBinder()+0x2c>:
-  # We pull out the address and function first. Then we check for an optional
-  # offset. This is tricky due to functions that look like "operator+(..)+0x2c"
-  func_regexp = re.compile("(^[a-f0-9]*) \<(.*)\>:$")
-  offset_regexp = re.compile("(.*)\+0x([a-f0-9]*)")
-
-  # A disassembly line looks like:
-  #   177b2:  b510        push  {r4, lr}
-  asm_regexp = re.compile("(^[ a-f0-9]*):[ a-f0-0]*.*$")
-
-  for target_addr in unique_addrs:
-    start_addr_dec = str(StripPC(int(target_addr, 16)))
-    stop_addr_dec = str(StripPC(int(target_addr, 16)) + 8)
-    cmd = [ToolPath("objdump"),
-           "--section=.text",
-           "--demangle",
-           "--disassemble",
-           "--start-address=" + start_addr_dec,
-           "--stop-address=" + stop_addr_dec,
-           symbols]
-
-    current_symbol = None    # The current function symbol in the disassembly.
-    current_symbol_addr = 0  # The address of the current function.
-
-    stream = subprocess.Popen(cmd, stdout=subprocess.PIPE).stdout
-    for line in stream:
-      # Is it a function line like:
-      #   000177b0 <android::IBinder::~IBinder()>:
-      components = func_regexp.match(line)
-      if components:
-        # This is a new function, so record the current function and its address.
-        current_symbol_addr = int(components.group(1), 16)
-        current_symbol = components.group(2)
-
-        # Does it have an optional offset like: "foo(..)+0x2c"?
-        components = offset_regexp.match(current_symbol)
-        if components:
-          current_symbol = components.group(1)
-          offset = components.group(2)
-          if offset:
-            current_symbol_addr -= int(offset, 16)
-
-      # Is it an disassembly line like:
-      #   177b2:  b510        push  {r4, lr}
-      components = asm_regexp.match(line)
-      if components:
-        addr = components.group(1)
-        i_addr = int(addr, 16)
-        i_target = StripPC(int(target_addr, 16))
-        if i_addr == i_target:
-          result[target_addr] = (current_symbol, i_target - current_symbol_addr)
-    stream.close()
-
-  return result
-
-
-def CallCppFilt(mangled_symbol):
-  cmd = [ToolPath("c++filt")]
-  process = subprocess.Popen(cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE)
-  process.stdin.write(mangled_symbol)
-  process.stdin.write("\n")
-  process.stdin.close()
-  demangled_symbol = process.stdout.readline().strip()
-  process.stdout.close()
-  return demangled_symbol
-
-def FormatSymbolWithOffset(symbol, offset):
-  if offset == 0:
-    return symbol
-  return "%s+%d" % (symbol, offset)
diff --git a/mojo/devtools/common/devtoolslib/__init__.py b/mojo/devtools/common/devtoolslib/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/mojo/devtools/common/devtoolslib/__init__.py
+++ /dev/null
diff --git a/mojo/devtools/common/devtoolslib/android_shell.py b/mojo/devtools/common/devtoolslib/android_shell.py
deleted file mode 100644
index e07ce77..0000000
--- a/mojo/devtools/common/devtoolslib/android_shell.py
+++ /dev/null
@@ -1,430 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import atexit
-import hashlib
-import json
-import logging
-import os
-import os.path
-import random
-import re
-import subprocess
-import sys
-import tempfile
-import threading
-import time
-
-from devtoolslib.http_server import start_http_server
-from devtoolslib.shell import Shell
-from devtoolslib.utils import overrides
-
-
-# Tags used by mojo shell Java logging.
-_LOGCAT_JAVA_TAGS = [
-    'AndroidHandler',
-    'MojoFileHelper',
-    'MojoMain',
-    'MojoShellActivity',
-    'MojoShellApplication',
-]
-
-# Tags used by native logging reflected in the logcat.
-_LOGCAT_NATIVE_TAGS = [
-    'chromium',
-    'sky',
-]
-
-_MOJO_SHELL_PACKAGE_NAME = 'org.chromium.mojo.shell'
-
-
-_logger = logging.getLogger()
-
-
-def _exit_if_needed(process):
-  """Exits |process| if it is still alive."""
-  if process.poll() is None:
-    process.kill()
-
-
-def _find_available_port(netstat_output, max_attempts=10000):
-  opened = [int(x.strip().split()[3].split(':')[1])
-            for x in netstat_output if x.startswith(' tcp')]
-  for _ in xrange(max_attempts):
-    port = random.randint(4096, 16384)
-    if port not in opened:
-      return port
-  else:
-    raise Exception('Failed to identify an available port.')
-
-
-def _find_available_host_port():
-  netstat_output = subprocess.check_output(['netstat'])
-  return _find_available_port(netstat_output)
-
-
-class AndroidShell(Shell):
-  """Wrapper around Mojo shell running on an Android device.
-
-  Args:
-    adb_path: Path to adb, optional if adb is in PATH.
-    target_device: Device to run on, if multiple devices are connected.
-    logcat_tags: Comma-separated list of additional logcat tags to use.
-  """
-
-  def __init__(self, adb_path="adb", target_device=None, logcat_tags=None,
-               verbose_pipe=None):
-    self.adb_path = adb_path
-    self.target_device = target_device
-    self.stop_shell_registered = False
-    self.adb_running_as_root = None
-    self.additional_logcat_tags = logcat_tags
-    self.verbose_pipe = verbose_pipe if verbose_pipe else open(os.devnull, 'w')
-
-  def _adb_command(self, args):
-    """Forms an adb command from the given arguments, prepending the adb path
-    and adding a target device specifier, if needed.
-    """
-    adb_command = [self.adb_path]
-    if self.target_device:
-      adb_command.extend(['-s', self.target_device])
-    adb_command.extend(args)
-    return adb_command
-
-  def _read_fifo(self, fifo_path, pipe, on_fifo_closed, max_attempts=5):
-    """Reads |fifo_path| on the device and write the contents to |pipe|.
-
-    Calls |on_fifo_closed| when the fifo is closed. This method will try to find
-    the path up to |max_attempts|, waiting 1 second between each attempt. If it
-    cannot find |fifo_path|, a exception will be raised.
-    """
-    fifo_command = self._adb_command(
-        ['shell', 'test -e "%s"; echo $?' % fifo_path])
-
-    def _run():
-      def _wait_for_fifo():
-        for _ in xrange(max_attempts):
-          if subprocess.check_output(fifo_command)[0] == '0':
-            return
-          time.sleep(1)
-        if on_fifo_closed:
-          on_fifo_closed()
-        raise Exception("Unable to find fifo.")
-      _wait_for_fifo()
-      stdout_cat = subprocess.Popen(
-          self._adb_command(['shell', 'cat', fifo_path]), stdout=pipe)
-      atexit.register(_exit_if_needed, stdout_cat)
-      stdout_cat.wait()
-      if on_fifo_closed:
-        on_fifo_closed()
-
-    thread = threading.Thread(target=_run, name="StdoutRedirector")
-    thread.start()
-
-  def _find_available_device_port(self):
-    netstat_output = subprocess.check_output(
-        self._adb_command(['shell', 'netstat']))
-    return _find_available_port(netstat_output)
-
-  def _forward_device_port_to_host(self, device_port, host_port):
-    """Maps the device port to the host port. If |device_port| is 0, a random
-    available port is chosen.
-
-    Returns:
-      The device port.
-    """
-    assert host_port
-    # Root is not required for `adb forward` (hence we don't check the return
-    # value), but if we can run adb as root, we have to do it now, because
-    # restarting adbd as root clears any port mappings. See
-    # https://github.com/domokit/devtools/issues/20.
-    self._run_adb_as_root()
-
-    if device_port == 0:
-      # TODO(ppi): Should we have a retry loop to handle the unlikely races?
-      device_port = self._find_available_device_port()
-    subprocess.check_call(self._adb_command([
-        "reverse", "tcp:%d" % device_port, "tcp:%d" % host_port]))
-
-    def _unmap_port():
-      unmap_command = self._adb_command([
-          "reverse", "--remove", "tcp:%d" % device_port])
-      subprocess.Popen(unmap_command)
-    atexit.register(_unmap_port)
-    return device_port
-
-  def _forward_host_port_to_device(self, host_port, device_port):
-    """Maps the host port to the device port. If |host_port| is 0, a random
-    available port is chosen.
-
-    Returns:
-      The host port.
-    """
-    assert device_port
-    self._run_adb_as_root()
-
-    if host_port == 0:
-      # TODO(ppi): Should we have a retry loop to handle the unlikely races?
-      host_port = _find_available_host_port()
-    subprocess.check_call(self._adb_command([
-        "forward", 'tcp:%d' % host_port, 'tcp:%d' % device_port]))
-
-    def _unmap_port():
-      unmap_command = self._adb_command([
-          "forward", "--remove", "tcp:%d" % device_port])
-      subprocess.Popen(unmap_command)
-    atexit.register(_unmap_port)
-    return host_port
-
-  def _run_adb_as_root(self):
-    if self.adb_running_as_root is not None:
-      return self.adb_running_as_root
-
-    if ('cannot run as root' not in subprocess.check_output(
-        self._adb_command(['root']))):
-      # Wait for adbd to restart.
-      subprocess.check_call(
-          self._adb_command(['wait-for-device']),
-          stdout=self.verbose_pipe)
-      self.adb_running_as_root = True
-    else:
-      self.adb_running_as_root = False
-
-    return self.adb_running_as_root
-
-  def _is_shell_package_installed(self):
-    # Adb should print one line if the package is installed and return empty
-    # string otherwise.
-    return len(subprocess.check_output(self._adb_command([
-        'shell', 'pm', 'list', 'packages', _MOJO_SHELL_PACKAGE_NAME]))) > 0
-
-  def check_device(self):
-    """Verifies if the device configuration allows adb to run.
-
-    If a target device was indicated in the constructor, it checks that the
-    device is available. Otherwise, it checks that there is exactly one
-    available device.
-
-    Returns:
-      A tuple of (result, msg). |result| is True iff if the device is correctly
-      configured and False otherwise. |msg| is the reason for failure if
-      |result| is False and None otherwise.
-    """
-    adb_devices_output = subprocess.check_output(
-        self._adb_command(['devices']))
-    # Skip the header line, strip empty lines at the end.
-    device_list = [line.strip() for line in adb_devices_output.split('\n')[1:]
-                   if line.strip()]
-
-    if self.target_device:
-      if any([line.startswith(self.target_device) and
-              line.endswith('device') for line in device_list]):
-        return True, None
-      else:
-        return False, 'Cannot connect to the selected device.'
-
-    if len(device_list) > 1:
-      return False, ('More than one device connected and target device not '
-                     'specified.')
-
-    if not len(device_list):
-      return False, 'No devices connected.'
-
-    if not device_list[0].endswith('device'):
-      return False, 'Connected device is not available.'
-
-    return True, None
-
-  def install_apk(self, shell_apk_path):
-    """Installs the apk on the device.
-
-    This method computes checksum of the APK and skips the installation if the
-    fingerprint matches the one saved on the device upon the previous
-    installation.
-
-    Args:
-      shell_apk_path: Path to the shell Android binary.
-    """
-    device_sha1_path = '/sdcard/%s/%s.sha1' % (_MOJO_SHELL_PACKAGE_NAME,
-                                               'MojoShell')
-    apk_sha1 = hashlib.sha1(open(shell_apk_path, 'rb').read()).hexdigest()
-    device_apk_sha1 = subprocess.check_output(self._adb_command([
-        'shell', 'cat', device_sha1_path]))
-    do_install = (apk_sha1 != device_apk_sha1 or
-                  not self._is_shell_package_installed())
-
-    if do_install:
-      subprocess.check_call(
-          self._adb_command(['install', '-r', shell_apk_path, '-i',
-                            _MOJO_SHELL_PACKAGE_NAME]),
-          stdout=self.verbose_pipe)
-
-      # Update the stamp on the device.
-      with tempfile.NamedTemporaryFile() as fp:
-        fp.write(apk_sha1)
-        fp.flush()
-        subprocess.check_call(self._adb_command(['push', fp.name,
-                                                device_sha1_path]),
-                              stdout=self.verbose_pipe)
-    else:
-      # To ensure predictable state after running install_apk(), we need to stop
-      # the shell here, as this is what "adb install" implicitly does.
-      self.stop_shell()
-
-  def start_shell(self,
-                 arguments,
-                 stdout=None,
-                 on_application_stop=None):
-    """Starts the mojo shell, passing it the given arguments.
-
-    Args:
-      arguments: List of arguments for the shell. It must contain the
-          "--origin=" arg. shell_arguments.configure_local_origin() can be used
-          to set up a local directory on the host machine as origin.
-      stdout: Valid argument for subprocess.Popen() or None.
-    """
-    if not self.stop_shell_registered:
-      atexit.register(self.stop_shell)
-      self.stop_shell_registered = True
-
-    STDOUT_PIPE = "/data/data/%s/stdout.fifo" % _MOJO_SHELL_PACKAGE_NAME
-
-    cmd = self._adb_command(['shell', 'am', 'start',
-                            '-S',
-                            '-a', 'android.intent.action.VIEW',
-                            '-n', '%s/.MojoShellActivity' %
-                            _MOJO_SHELL_PACKAGE_NAME])
-
-    parameters = []
-    if stdout or on_application_stop:
-      # We need to run as root to access the fifo file we use for stdout
-      # redirection.
-      if self._run_adb_as_root():
-        # Remove any leftover fifo file after the previous run.
-        subprocess.check_call(self._adb_command(
-            ['shell', 'rm', '-f', STDOUT_PIPE]))
-
-        parameters.append('--fifo-path=%s' % STDOUT_PIPE)
-        self._read_fifo(STDOUT_PIPE, stdout, on_application_stop)
-      else:
-        _logger.warning("Running without root access, full stdout of the "
-                        "shell won't be available.")
-    # The origin has to be specified whether it's local or external.
-    assert any("--origin=" in arg for arg in arguments)
-    parameters.extend(arguments)
-
-    if parameters:
-      encodedParameters = json.dumps(parameters)
-      cmd += ['--es', 'encodedParameters', encodedParameters]
-
-    subprocess.check_call(cmd, stdout=self.verbose_pipe)
-
-  def stop_shell(self):
-    """Stops the mojo shell."""
-    subprocess.check_call(self._adb_command(['shell',
-                                            'am',
-                                            'force-stop',
-                                            _MOJO_SHELL_PACKAGE_NAME]))
-
-  def clean_logs(self):
-    """Cleans the logs on the device."""
-    subprocess.check_call(self._adb_command(['logcat', '-c']))
-
-  def show_logs(self, include_native_logs=True):
-    """Displays the log for the mojo shell.
-
-    Returns:
-      The process responsible for reading the logs.
-    """
-    tags = _LOGCAT_JAVA_TAGS
-    if include_native_logs:
-      tags.extend(_LOGCAT_NATIVE_TAGS)
-    if self.additional_logcat_tags is not None:
-      tags.extend(self.additional_logcat_tags.split(","))
-    logcat = subprocess.Popen(
-        self._adb_command(['logcat', '-s', ' '.join(tags)]),
-        stdout=sys.stdout)
-    atexit.register(_exit_if_needed, logcat)
-    return logcat
-
-  def forward_observatory_ports(self):
-    """Forwards the ports used by the dart observatories to the host machine.
-    """
-    logcat = subprocess.Popen(self._adb_command(['logcat']),
-                              stdout=subprocess.PIPE)
-    atexit.register(_exit_if_needed, logcat)
-
-    def _forward_observatories_as_needed():
-      while True:
-        line = logcat.stdout.readline()
-        if not line:
-          break
-        match = re.search(r'Observatory listening on http://127.0.0.1:(\d+)',
-                          line)
-        if match:
-          device_port = int(match.group(1))
-          host_port = self._forward_host_port_to_device(0, device_port)
-          print ("Dart observatory available at the host at http://127.0.0.1:%d"
-                 % host_port)
-
-    logcat_watch_thread = threading.Thread(
-        target=_forward_observatories_as_needed)
-    logcat_watch_thread.start()
-
-  @overrides(Shell)
-  def serve_local_directory(self, local_dir_path, port=0):
-    assert local_dir_path
-    mappings = [('', [local_dir_path])]
-    server_address = start_http_server(mappings, host_port=port)
-
-    return 'http://127.0.0.1:%d/' % self._forward_device_port_to_host(
-        port, server_address[1])
-
-  @overrides(Shell)
-  def serve_local_directories(self, mappings, port=0):
-    assert mappings
-    server_address = start_http_server(mappings, host_port=port)
-
-    return 'http://127.0.0.1:%d/' % self._forward_device_port_to_host(
-        port, server_address[1])
-
-  @overrides(Shell)
-  def forward_host_port_to_shell(self, host_port):
-    self._forward_host_port_to_device(host_port, host_port)
-
-  @overrides(Shell)
-  def run(self, arguments):
-    self.clean_logs()
-    self.forward_observatory_ports()
-
-    # If we are running as root, don't carry over the native logs from logcat -
-    # we will have these in the stdout.
-    p = self.show_logs(include_native_logs=(not self._run_adb_as_root()))
-    self.start_shell(arguments, sys.stdout, p.terminate)
-    p.wait()
-    return None
-
-  @overrides(Shell)
-  def run_and_get_output(self, arguments, timeout=None):
-    class Results:
-      """Workaround for Python scoping rules that prevent assigning to variables
-      from the outer scope.
-      """
-      output = None
-
-    def do_run():
-      (r, w) = os.pipe()
-      with os.fdopen(r, "r") as rf:
-        with os.fdopen(w, "w") as wf:
-          self.start_shell(arguments, wf, wf.close)
-          Results.output = rf.read()
-
-    run_thread = threading.Thread(target=do_run)
-    run_thread.start()
-    run_thread.join(timeout)
-
-    if run_thread.is_alive():
-      self.stop_shell()
-      return None, Results.output, True
-    return None, Results.output, False
diff --git a/mojo/devtools/common/devtoolslib/apptest.py b/mojo/devtools/common/devtoolslib/apptest.py
deleted file mode 100644
index 59e23e2..0000000
--- a/mojo/devtools/common/devtoolslib/apptest.py
+++ /dev/null
@@ -1,77 +0,0 @@
-# Copyright 2015 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Apptest is a Mojo application that interacts with another Mojo application
-and verifies assumptions about behavior of the app being tested.
-"""
-
-import logging
-import time
-
-
-_logger = logging.getLogger()
-
-
-def _build_shell_arguments(shell_args, apptest_url, apptest_args):
-  """Builds the list of arguments for the shell.
-
-  Args:
-    shell_args: List of arguments for the shell run.
-    apptest_url: Url of the apptest app to run.
-    apptest_args: Parameters to be passed to the apptest app.
-
-  Returns:
-    Single list of shell arguments.
-  """
-  result = list(shell_args)
-  if apptest_args:
-    result.append("--args-for=%s %s" % (apptest_url, " ".join(apptest_args)))
-  result.append(apptest_url)
-  return result
-
-
-def run_apptest(shell, shell_args, apptest_url, apptest_args, timeout,
-                output_test):
-  """Runs shell with the given arguments, retrieves the output and applies
-  |output_test| to determine if the run was successful.
-
-  Args:
-    shell: Wrapper around concrete Mojo shell, implementing devtools Shell
-        interface.
-    shell_args: List of arguments for the shell run.
-    apptest_url: Url of the apptest app to run.
-    apptest_args: Parameters to be passed to the apptest app.
-    output_test: Function accepting the shell output and returning True iff
-        the output indicates a successful run.
-
-  Returns:
-    True iff the test succeeded, False otherwise.
-  """
-  arguments = _build_shell_arguments(shell_args, apptest_url, apptest_args)
-  command_line = "mojo_shell " + " ".join(["%r" % x for x in arguments])
-
-  _logger.debug("Starting: " + command_line)
-  start_time = time.time()
-  (exit_code, output, did_time_out) = shell.run_and_get_output(arguments,
-                                                               timeout)
-  run_time = time.time() - start_time
-  _logger.debug("Completed: " + command_line)
-
-  # Only log if it took more than 3 second.
-  if run_time >= 3:
-    _logger.info("Test took %.3f seconds: %s" % (run_time, command_line))
-
-  if exit_code or did_time_out or not output_test(output):
-    print 'Failed test: %r' % command_line
-    if exit_code:
-      print '  due to shell exit code %d' % exit_code
-    elif did_time_out:
-      print '  due to exceeded timeout of %fs' % timeout
-    else:
-      print '  due to test results'
-    print 72 * '-'
-    print output
-    print 72 * '-'
-    return False
-  return True
diff --git a/mojo/devtools/common/devtoolslib/apptest_dart.py b/mojo/devtools/common/devtoolslib/apptest_dart.py
deleted file mode 100644
index fe6131f..0000000
--- a/mojo/devtools/common/devtoolslib/apptest_dart.py
+++ /dev/null
@@ -1,35 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Apptest runner specific to the particular Dart apptest framework in
-/mojo/dart/apptests, built on top of the general apptest runner."""
-
-import logging
-import re
-
-_logging = logging.getLogger()
-
-from devtoolslib.apptest import run_apptest
-
-SUCCESS_PATTERN = re.compile('^.+ .+: All tests passed!', re.MULTILINE)
-
-
-def _dart_apptest_output_test(output):
-  return SUCCESS_PATTERN.search(output) is not None
-
-
-# TODO(erg): Support android, launched services and fixture isolation.
-def run_dart_apptest(shell, shell_args, apptest_url, apptest_args, timeout):
-  """Runs a dart apptest.
-
-  Args:
-    shell_args: The arguments for mojo_shell.
-    apptest_url: Url of the apptest app to run.
-    apptest_args: Parameters to be passed to the apptest app.
-
-  Returns:
-    True iff the test succeeded, False otherwise.
-  """
-  return run_apptest(shell, shell_args, apptest_url, apptest_args, timeout,
-                     _dart_apptest_output_test)
diff --git a/mojo/devtools/common/devtoolslib/apptest_gtest.py b/mojo/devtools/common/devtoolslib/apptest_gtest.py
deleted file mode 100644
index fefeab7..0000000
--- a/mojo/devtools/common/devtoolslib/apptest_gtest.py
+++ /dev/null
@@ -1,120 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Apptest runner specific to the particular gtest-based apptest framework in
-/mojo/public/cpp/application/tests/, built on top of the general apptest
-runner."""
-
-import logging
-import re
-
-from devtoolslib.apptest import run_apptest
-
-
-_logger = logging.getLogger()
-
-
-def _gtest_apptest_output_test(output):
-  # Fail on output with gtest's "[  FAILED  ]" or a lack of "[  PASSED  ]".
-  # The latter condition ensures failure on broken command lines or output.
-  # Check output instead of exit codes because mojo_shell always exits with 0.
-  if (output is None or
-      (output.find("[  FAILED  ]") != -1 or output.find("[  PASSED  ]") == -1)):
-    return False
-  return True
-
-
-def run_gtest_apptest(shell, shell_args, apptest_url, apptest_args, timeout,
-                      isolate):
-  """Runs a gtest apptest.
-
-  Args:
-    shell: Wrapper around concrete Mojo shell, implementing devtools Shell
-        interface.
-    shell_args: The arguments for mojo_shell.
-    apptest_url: Url of the apptest app to run.
-    apptest_args: Parameters to be passed to the apptest app.
-    isolate: Iff True, each test in the app will be run in a separate shell run.
-
-  Returns:
-    True iff the test succeeded, False otherwise.
-  """
-
-  if not isolate:
-    return run_apptest(shell, shell_args, apptest_url, apptest_args, timeout,
-                       _gtest_apptest_output_test)
-
-  # List the apptest fixtures so they can be run independently for isolation.
-  fixtures = get_fixtures(shell, shell_args, apptest_url)
-  if not fixtures:
-    print "No tests to run found in %s." % apptest_url
-    return False
-
-  apptest_result = True
-  for fixture in fixtures:
-    isolated_apptest_args = apptest_args + ["--gtest_filter=%s" % fixture]
-    success = run_apptest(shell, shell_args, apptest_url, isolated_apptest_args,
-                          timeout, _gtest_apptest_output_test)
-
-    if not success:
-      apptest_result = False
-
-  return apptest_result
-
-
-def get_fixtures(shell, shell_args, apptest):
-  """Returns the "Test.Fixture" list from an apptest using mojo_shell.
-
-  Tests are listed by running the given apptest in mojo_shell and passing
-  --gtest_list_tests. The output is parsed and reformatted into a list like
-  [TestSuite.TestFixture, ... ]
-  An empty list is returned on failure, with errors logged.
-
-  Args:
-    apptest: The URL of the test application to run.
-  """
-  arguments = []
-  arguments.extend(shell_args)
-  arguments.append("--args-for=%s %s" % (apptest, "--gtest_list_tests"))
-  arguments.append(apptest)
-
-  (exit_code, output, did_time_out) = shell.run_and_get_output(arguments)
-  if exit_code or did_time_out:
-    command_line = "mojo_shell " + " ".join(["%r" % x for x in arguments])
-    print "Failed to get test fixtures: %r" % command_line
-    print 72 * '-'
-    print output
-    print 72 * '-'
-    return []
-
-  _logger.debug("Tests listed:\n%s" % output)
-  return _gtest_list_tests(output)
-
-
-def _gtest_list_tests(gtest_list_tests_output):
-  """Returns a list of strings formatted as TestSuite.TestFixture from the
-  output of running --gtest_list_tests on a GTEST application."""
-
-  # Remove log lines.
-  gtest_list_tests_output = re.sub("^(\[|WARNING: linker:).*\n",
-                                   "",
-                                   gtest_list_tests_output,
-                                   flags=re.MULTILINE)
-
-  if not re.match("^(\w*\.\r?\n(  \w*\r?\n)+)+", gtest_list_tests_output):
-    raise Exception("Unrecognized --gtest_list_tests output:\n%s" %
-                    gtest_list_tests_output)
-
-  output_lines = gtest_list_tests_output.split("\n")
-
-  test_list = []
-  for line in output_lines:
-    if not line:
-      continue
-    if line[0] != " ":
-      suite = line.strip()
-      continue
-    test_list.append(suite + line.strip())
-
-  return test_list
diff --git a/mojo/devtools/common/devtoolslib/apptest_gtest_unittest.py b/mojo/devtools/common/devtoolslib/apptest_gtest_unittest.py
deleted file mode 100644
index db55a30..0000000
--- a/mojo/devtools/common/devtoolslib/apptest_gtest_unittest.py
+++ /dev/null
@@ -1,57 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import imp
-import os.path
-import sys
-import unittest
-
-try:
-  imp.find_module("devtoolslib")
-except ImportError:
-  sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
-from devtoolslib.apptest_gtest import _gtest_list_tests
-
-
-class GTestListTestsTest(unittest.TestCase):
-  """Tests |_gtest_list_tests()| handling of --gtest_list_tests output."""
-
-  def testSingleSuiteAndFixture(self):
-    """Tests a single suite with a single fixture."""
-    gtest_output = "TestSuite.\n  TestFixture\n"
-    expected_test_list = ["TestSuite.TestFixture"]
-    self.assertEquals(_gtest_list_tests(gtest_output), expected_test_list)
-
-  def testWindowsNewlines(self):
-    """Tests handling of \r\n newlines."""
-    gtest_output = "TestSuite.\r\n  TestFixture1\r\n"
-    expected_test_list = ["TestSuite.TestFixture1"]
-    self.assertEquals(_gtest_list_tests(gtest_output), expected_test_list)
-
-  def testSingleSuiteAndMultipleFixtures(self):
-    """Tests a single suite with multiple fixtures."""
-    gtest_output = "TestSuite.\n  TestFixture1\n  TestFixture2\n"
-    expected_test_list = ["TestSuite.TestFixture1", "TestSuite.TestFixture2"]
-    self.assertEquals(_gtest_list_tests(gtest_output), expected_test_list)
-
-  def testMultipleSuitesAndFixtures(self):
-    """Tests multiple suites each with multiple fixtures."""
-    gtest_output = ("TestSuite1.\n  TestFixture1\n  TestFixture2\n"
-                    "TestSuite2.\n  TestFixtureA\n  TestFixtureB\n")
-    expected_test_list = ["TestSuite1.TestFixture1", "TestSuite1.TestFixture2",
-                          "TestSuite2.TestFixtureA", "TestSuite2.TestFixtureB"]
-    self.assertEquals(_gtest_list_tests(gtest_output), expected_test_list)
-
-  def testUnrecognizedFormats(self):
-    """Tests examples of unrecognized --gtest_list_tests output."""
-    self.assertRaises(Exception, _gtest_list_tests, "Foo")
-    self.assertRaises(Exception, _gtest_list_tests, "Foo\n")
-    self.assertRaises(Exception, _gtest_list_tests, "Foo.Bar\n")
-    self.assertRaises(Exception, _gtest_list_tests, "Foo.\nBar\n")
-    self.assertRaises(Exception, _gtest_list_tests, "Foo.\r\nBar\r\nGaz\r\n")
-    self.assertRaises(Exception, _gtest_list_tests, "Foo.\nBar.\n  Gaz\n")
-
-
-if __name__ == "__main__":
-  unittest.main()
diff --git a/mojo/devtools/common/devtoolslib/http_server.py b/mojo/devtools/common/devtoolslib/http_server.py
deleted file mode 100644
index 482e2db..0000000
--- a/mojo/devtools/common/devtoolslib/http_server.py
+++ /dev/null
@@ -1,223 +0,0 @@
-# Copyright 2015 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import atexit
-import datetime
-import email.utils
-import errno
-import gzip
-import hashlib
-import logging
-import math
-import os.path
-import shutil
-import socket
-import threading
-import tempfile
-
-import SimpleHTTPServer
-import SocketServer
-
-_ZERO = datetime.timedelta(0)
-
-
-class UTC_TZINFO(datetime.tzinfo):
-  """UTC time zone representation."""
-
-  def utcoffset(self, _):
-    return _ZERO
-
-  def tzname(self, _):
-    return "UTC"
-
-  def dst(self, _):
-     return _ZERO
-
-_UTC = UTC_TZINFO()
-
-
-class _SilentTCPServer(SocketServer.TCPServer):
-  """A TCPServer that won't display any error, unless debugging is enabled. This
-  is useful because the client might stop while it is fetching an URL, which
-  causes spurious error messages.
-  """
-  allow_reuse_address = True
-
-  def handle_error(self, request, client_address):
-    """Override the base class method to have conditional logging."""
-    if logging.getLogger().isEnabledFor(logging.DEBUG):
-      SocketServer.TCPServer.handle_error(self, request, client_address)
-
-
-def _get_handler_class_for_path(mappings):
-  """Creates a handler override for SimpleHTTPServer.
-
-  Args:
-    mappings: List of tuples (prefix, local_base_path_list) mapping URLs that
-        start with |prefix| to one or more local directories enumerated in
-        |local_base_path_list|. The prefixes should skip the leading slash.
-        The first matching prefix and the first location that contains the
-        requested file will be used each time.
-  """
-  for prefix, _ in mappings:
-    assert not prefix.startswith('/'), ('Prefixes for the http server mappings '
-                                        'should skip the leading slash.')
-
-  class RequestHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):
-    """Handler for SocketServer.TCPServer that will serve the files from
-    local directiories over http.
-
-    A new instance is created for each request.
-    """
-
-    def __init__(self, *args, **kwargs):
-      self.etag = None
-      self.gzipped_file = None
-      SimpleHTTPServer.SimpleHTTPRequestHandler.__init__(self, *args, **kwargs)
-
-    def get_etag(self):
-      if self.etag:
-        return self.etag
-
-      path = self.translate_path(self.path, False)
-      if not os.path.isfile(path):
-        return None
-
-      sha256 = hashlib.sha256()
-      BLOCKSIZE = 65536
-      with open(path, 'rb') as hashed:
-        buf = hashed.read(BLOCKSIZE)
-        while len(buf) > 0:
-          sha256.update(buf)
-          buf = hashed.read(BLOCKSIZE)
-      self.etag = '"%s"' % sha256.hexdigest()
-      return self.etag
-
-    def send_head(self):
-      # Always close the connection after each request, as the keep alive
-      # support from SimpleHTTPServer doesn't like when the client requests to
-      # close the connection before downloading the full response content.
-      # pylint: disable=W0201
-      self.close_connection = 1
-
-      path = self.translate_path(self.path)
-      if os.path.isfile(path):
-        # Handle If-None-Match
-        etag = self.get_etag()
-        if ('If-None-Match' in self.headers and
-            etag == self.headers['If-None-Match']):
-          self.send_response(304)
-          return None
-
-        # Handle If-Modified-Since
-        if ('If-None-Match' not in self.headers and
-            'If-Modified-Since' in self.headers):
-          last_modified = datetime.datetime.fromtimestamp(
-              math.floor(os.stat(path).st_mtime), tz=_UTC)
-          ims = datetime.datetime(
-              *email.utils.parsedate(self.headers['If-Modified-Since'])[:6],
-              tzinfo=_UTC)
-          if last_modified <= ims:
-            self.send_response(304)
-            return None
-
-      return SimpleHTTPServer.SimpleHTTPRequestHandler.send_head(self)
-
-    def end_headers(self):
-      path = self.translate_path(self.path)
-
-      if os.path.isfile(path):
-        self.send_header('Content-Encoding', 'gzip')
-        etag = self.get_etag()
-        if etag:
-          self.send_header('ETag', etag)
-          self.send_header('Cache-Control', 'must-revalidate')
-
-      return SimpleHTTPServer.SimpleHTTPRequestHandler.end_headers(self)
-
-    # pylint: disable=W0221
-    def translate_path(self, path, gzipped=True):
-      # Parent translate_path() will strip away the query string and fragment
-      # identifier, but also will prepend the cwd to the path. relpath() gives
-      # us the relative path back.
-      normalized_path = os.path.relpath(
-          SimpleHTTPServer.SimpleHTTPRequestHandler.translate_path(self, path))
-
-      for prefix, local_base_path_list in mappings:
-        if normalized_path.startswith(prefix):
-          for local_base_path in local_base_path_list:
-            candidate = os.path.join(local_base_path,
-                                     normalized_path[len(prefix):])
-            if os.path.isfile(candidate):
-              if gzipped:
-                if not self.gzipped_file:
-                  self.gzipped_file = tempfile.NamedTemporaryFile(delete=False)
-                  with open(candidate, 'rb') as source:
-                    with gzip.GzipFile(fileobj=self.gzipped_file) as target:
-                      shutil.copyfileobj(source, target)
-                  self.gzipped_file.close()
-                return self.gzipped_file.name
-              return candidate
-          else:
-            self.send_response(404)
-            return None
-      self.send_response(404)
-      return None
-
-    def guess_type(self, path):
-      # This is needed so that exploded Sky apps without shebang can still run
-      # thanks to content-type mappings.
-      # TODO(ppi): drop this part once we can rely on the Sky files declaring
-      # correct shebang.
-      if path.endswith('.dart') or path.endswith('.dart.gz'):
-        return 'application/dart'
-      return SimpleHTTPServer.SimpleHTTPRequestHandler.guess_type(self, path)
-
-    def log_message(self, *_):
-      """Override the base class method to disable logging."""
-      pass
-
-    def __del__(self):
-      if self.gzipped_file:
-        os.remove(self.gzipped_file.name)
-
-  RequestHandler.protocol_version = 'HTTP/1.1'
-  return RequestHandler
-
-
-def start_http_server(mappings, host_port=0):
-  """Starts an http server serving files from |local_dir_path| on |host_port|.
-
-  Args:
-    mappings: List of tuples (prefix, local_base_path_list) mapping URLs that
-        start with |prefix| to one or more local directories enumerated in
-        |local_base_path_list|. The prefixes should skip the leading slash.
-        The first matching prefix and the first location that contains the
-        requested file will be used each time.
-    host_port: Port on the host machine to run the server on. Pass 0 to use a
-        system-assigned port.
-
-  Returns:
-    Tuple of the server address and the port on which it runs.
-  """
-  assert mappings
-  handler_class = _get_handler_class_for_path(mappings)
-
-  try:
-    httpd = _SilentTCPServer(('127.0.0.1', host_port), handler_class)
-    atexit.register(httpd.shutdown)
-
-    http_thread = threading.Thread(target=httpd.serve_forever)
-    http_thread.daemon = True
-    http_thread.start()
-    return httpd.server_address
-  except socket.error as v:
-    error_code = v[0]
-    print 'Failed to start http server for %s on port %d: %s.' % (
-        str(mappings), host_port, os.strerror(error_code))
-    if error_code == errno.EADDRINUSE:
-      print ('  Run `fuser %d/tcp` to find out which process is using the port.'
-             % host_port)
-    print '---'
-    raise
diff --git a/mojo/devtools/common/devtoolslib/http_server_unittest.py b/mojo/devtools/common/devtoolslib/http_server_unittest.py
deleted file mode 100644
index f279712..0000000
--- a/mojo/devtools/common/devtoolslib/http_server_unittest.py
+++ /dev/null
@@ -1,140 +0,0 @@
-# Copyright 2015 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import StringIO
-import gzip
-import imp
-import os.path
-import shutil
-import sys
-import tempfile
-import unittest
-import urllib2
-
-try:
-  imp.find_module('devtoolslib')
-except ImportError:
-  sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
-
-from devtoolslib import http_server
-
-
-class HttpServerTest(unittest.TestCase):
-  """Tests for the http_server module."""
-
-  def setUp(self):
-    """Creates a tree of temporary directories and files of the form described
-    below.
-
-      parent_dir
-        hello_dir
-          hello_subdir
-            hello_file
-        other_dir
-          other_file
-    """
-    self.parent_dir = tempfile.mkdtemp()
-    self.parent_file = tempfile.NamedTemporaryFile(delete=False,
-                                                   dir=self.parent_dir)
-    self.hello_dir = tempfile.mkdtemp(dir=self.parent_dir)
-    self.hello_subdir = tempfile.mkdtemp(dir=self.hello_dir)
-    self.hello_file = tempfile.NamedTemporaryFile(delete=False,
-                                                  dir=self.hello_subdir)
-    self.hello_file.write('hello')
-    self.hello_file.close()
-
-    self.other_dir = tempfile.mkdtemp(dir=self.parent_dir)
-    self.other_file = tempfile.NamedTemporaryFile(delete=False,
-                                                  dir=self.other_dir)
-
-  def tearDown(self):
-    shutil.rmtree(self.parent_dir)
-
-  def test_mappings(self):
-    """Maps two directories and verifies that the server serves files placed
-    there.
-    """
-    mappings = [
-        ('hello/', [self.hello_dir]),
-        ('other/', [self.other_dir]),
-    ]
-    server_address = ('http://%s:%u/' %
-                      http_server.start_http_server(mappings))
-
-    hello_relpath = os.path.relpath(self.hello_file.name, self.hello_dir)
-    hello_response = urllib2.urlopen(server_address + 'hello/' +
-                                     hello_relpath)
-    self.assertEquals(200, hello_response.getcode())
-
-    other_relpath = os.path.relpath(self.other_file.name, self.other_dir)
-    other_response = urllib2.urlopen(server_address + 'other/' +
-                                     other_relpath)
-    self.assertEquals(200, other_response.getcode())
-
-  def test_unmapped_path(self):
-    """Verifies that the server returns 404 when a request for unmapped url
-    prefix is made.
-    """
-    mappings = [
-        ('hello/', [self.hello_dir]),
-    ]
-    server_address = ('http://%s:%u/' %
-                      http_server.start_http_server(mappings))
-
-    error_code = None
-    try:
-      urllib2.urlopen(server_address + 'unmapped/abc')
-    except urllib2.HTTPError as error:
-      error_code = error.code
-    self.assertEquals(404, error_code)
-
-  def test_multiple_paths(self):
-    """Verfies mapping multiple local paths under the same url prefix."""
-    mappings = [
-        ('singularity/', [self.hello_dir, self.other_dir]),
-    ]
-    server_address = ('http://%s:%u/' %
-                      http_server.start_http_server(mappings))
-
-    hello_relpath = os.path.relpath(self.hello_file.name, self.hello_dir)
-    hello_response = urllib2.urlopen(server_address + 'singularity/' +
-                                     hello_relpath)
-    self.assertEquals(200, hello_response.getcode())
-
-    other_relpath = os.path.relpath(self.other_file.name, self.other_dir)
-    other_response = urllib2.urlopen(server_address + 'singularity/' +
-                                     other_relpath)
-    self.assertEquals(200, other_response.getcode())
-
-    # Verify that a request for a file not present under any of the mapped
-    # directories results in 404.
-    error_code = None
-    try:
-      urllib2.urlopen(server_address + 'singularity/unavailable')
-    except urllib2.HTTPError as error:
-      error_code = error.code
-    self.assertEquals(404, error_code)
-
-  def test_gzip(self):
-    """Verifies the gzip content encoding of the files being served."""
-    mappings = [
-        ('hello/', [self.hello_dir]),
-    ]
-    server_address = ('http://%s:%u/' %
-                      http_server.start_http_server(mappings))
-
-    hello_relpath = os.path.relpath(self.hello_file.name, self.hello_dir)
-    hello_response = urllib2.urlopen(server_address + 'hello/' +
-                                     hello_relpath)
-    self.assertEquals(200, hello_response.getcode())
-    self.assertTrue('Content-Encoding' in hello_response.info())
-    self.assertEquals('gzip', hello_response.info().get('Content-Encoding'))
-
-    content = gzip.GzipFile(
-        fileobj=StringIO.StringIO(hello_response.read())).read()
-    self.assertEquals('hello', content)
-
-
-if __name__ == "__main__":
-  unittest.main()
diff --git a/mojo/devtools/common/devtoolslib/linux_shell.py b/mojo/devtools/common/devtoolslib/linux_shell.py
deleted file mode 100644
index dedee5b..0000000
--- a/mojo/devtools/common/devtoolslib/linux_shell.py
+++ /dev/null
@@ -1,66 +0,0 @@
-# Copyright 2015 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import subprocess
-import threading
-
-from devtoolslib import http_server
-from devtoolslib.shell import Shell
-from devtoolslib.utils import overrides
-
-
-class LinuxShell(Shell):
-  """Wrapper around Mojo shell running on Linux.
-
-  Args:
-    executable_path: path to the shell binary
-    command_prefix: optional list of arguments to prepend to the shell command,
-        allowing e.g. to run the shell under debugger.
-  """
-
-  def __init__(self, executable_path, command_prefix=None):
-    self.executable_path = executable_path
-    self.command_prefix = command_prefix if command_prefix else []
-
-  @overrides(Shell)
-  def serve_local_directory(self, local_dir_path, port=0):
-    mappings = [('', [local_dir_path])]
-    return 'http://%s:%d/' % http_server.start_http_server(mappings, port)
-
-  @overrides(Shell)
-  def serve_local_directories(self, mappings, port=0):
-    return 'http://%s:%d/' % http_server.start_http_server(mappings, port)
-
-  @overrides(Shell)
-  def forward_host_port_to_shell(self, host_port):
-    pass
-
-  @overrides(Shell)
-  def run(self, arguments):
-    command = self.command_prefix + [self.executable_path] + arguments
-    return subprocess.call(command, stderr=subprocess.STDOUT)
-
-  @overrides(Shell)
-  def run_and_get_output(self, arguments, timeout=None):
-    command = self.command_prefix + [self.executable_path] + arguments
-    p = subprocess.Popen(command, stdout=subprocess.PIPE,
-                         stderr=subprocess.STDOUT)
-
-    class Results:
-      """Workaround for Python scoping rules that prevent assigning to variables
-      from the outer scope.
-      """
-      output = None
-
-    def do_run():
-      (Results.output, _) = p.communicate()
-
-    run_thread = threading.Thread(target=do_run)
-    run_thread.start()
-    run_thread.join(timeout)
-
-    if run_thread.is_alive():
-      p.terminate()
-      return p.returncode, Results.output, True
-    return p.returncode, Results.output, False
diff --git a/mojo/devtools/common/devtoolslib/paths.py b/mojo/devtools/common/devtoolslib/paths.py
deleted file mode 100644
index 502636a..0000000
--- a/mojo/devtools/common/devtoolslib/paths.py
+++ /dev/null
@@ -1,96 +0,0 @@
-# Copyright 2015 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Supports inferring locations of files in default checkout layouts.
-
-These functions allow devtools scripts to work out-of-the-box with regular Mojo
-checkouts.
-"""
-
-import collections
-import os.path
-import sys
-
-
-def find_ancestor_with(relpath, start_path=None):
-  """Returns the lowest ancestor of this file that contains |relpath|."""
-  cur_dir_path = start_path or os.path.abspath(os.path.dirname(__file__))
-  while True:
-    if os.path.exists(os.path.join(cur_dir_path, relpath)):
-      return cur_dir_path
-
-    next_dir_path = os.path.dirname(cur_dir_path)
-    if next_dir_path != cur_dir_path:
-      cur_dir_path = next_dir_path
-    else:
-      return None
-
-
-def find_within_ancestors(target_relpath, start_path=None):
-  """Returns the absolute path to |target_relpath| in the lowest ancestor of
-  |start_path| that contains it.
-  """
-  ancestor = find_ancestor_with(target_relpath, start_path)
-  if not ancestor:
-    return None
-  return os.path.join(ancestor, target_relpath)
-
-
-def infer_paths(is_android, is_debug, target_cpu):
-  """Infers the locations of select build output artifacts in a regular
-  Chromium-like checkout. This should grow thinner or disappear as we introduce
-  per-repo config files, see https://github.com/domokit/devtools/issues/28.
-
-  Returns:
-    Defaultdict with the inferred paths.
-  """
-  build_dir = (('android_' if is_android else '') +
-               (target_cpu + '_' if target_cpu else '') +
-               ('Debug' if is_debug else 'Release'))
-  out_build_dir = os.path.join('out', build_dir)
-
-  root_path = find_ancestor_with(out_build_dir)
-  paths = collections.defaultdict(lambda: None)
-  if not root_path:
-    return paths
-
-  build_dir_path = os.path.join(root_path, out_build_dir)
-  paths['build_dir_path'] = build_dir_path
-  if is_android:
-    paths['shell_path'] = os.path.join(build_dir_path, 'apks', 'MojoShell.apk')
-    paths['adb_path'] = os.path.join(root_path, 'third_party', 'android_tools',
-                                'sdk', 'platform-tools', 'adb')
-  else:
-    paths['shell_path'] = os.path.join(build_dir_path, 'mojo_shell')
-  return paths
-
-
-# Based on Chromium //tools/find_depot_tools.py.
-def find_depot_tools():
-  """Searches for depot_tools.
-
-  Returns:
-    Path to the depot_tools checkout present on the machine, None if not found.
-  """
-  def _is_real_depot_tools(path):
-    return os.path.isfile(os.path.join(path, 'gclient.py'))
-
-  # First look if depot_tools is already in PYTHONPATH.
-  for i in sys.path:
-    if i.rstrip(os.sep).endswith('depot_tools') and _is_real_depot_tools(i):
-      return i
-  # Then look if depot_tools is in PATH, common case.
-  for i in os.environ['PATH'].split(os.pathsep):
-    if _is_real_depot_tools(i):
-      return i
-  # Rare case, it's not even in PATH, look upward up to root.
-  root_dir = os.path.dirname(os.path.abspath(__file__))
-  previous_dir = os.path.abspath(__file__)
-  while root_dir and root_dir != previous_dir:
-    i = os.path.join(root_dir, 'depot_tools')
-    if _is_real_depot_tools(i):
-      return i
-    previous_dir = root_dir
-    root_dir = os.path.dirname(root_dir)
-  return None
diff --git a/mojo/devtools/common/devtoolslib/shell.py b/mojo/devtools/common/devtoolslib/shell.py
deleted file mode 100644
index c142611..0000000
--- a/mojo/devtools/common/devtoolslib/shell.py
+++ /dev/null
@@ -1,79 +0,0 @@
-# Copyright 2015 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-
-class Shell(object):
-  """Represents an abstract Mojo shell."""
-
-  def serve_local_directory(self, local_dir_path, port=0):
-    """Serves the content of the local (host) directory, making it available to
-    the shell under the url returned by the function.
-
-    The server will run on a separate thread until the program terminates. The
-    call returns immediately.
-
-    Args:
-      local_dir_path: path to the directory to be served
-      port: port at which the server will be available to the shell
-
-    Returns:
-      The url that the shell can use to access the content of |local_dir_path|.
-    """
-    raise NotImplementedError()
-
-  def serve_local_directories(self, mappings, port=0):
-    """Serves the content of the local (host) directories, making it available
-    to the shell under the url returned by the function.
-
-    The server will run on a separate thread until the program terminates. The
-    call returns immediately.
-
-    Args:
-      mappings: List of tuples (prefix, local_base_path_list) mapping URLs that
-          start with |prefix| to one or more local directories enumerated in
-          |local_base_path_list|. The prefixes should skip the leading slash.
-          The first matching prefix and the first location that contains the
-          requested file will be used each time.
-      port: port at which the server will be available to the shell
-
-    Returns:
-      The url that the shell can use to access the server.
-    """
-    raise NotImplementedError()
-
-  def forward_host_port_to_shell(self, host_port):
-    """Forwards a port on the host machine to the same port wherever the shell
-    is running.
-
-    This is a no-op if the shell is running locally.
-    """
-    raise NotImplementedError()
-
-  def run(self, arguments):
-    """Runs the shell with given arguments until shell exits, passing the stdout
-    mingled with stderr produced by the shell onto the stdout.
-
-    Returns:
-      Exit code retured by the shell or None if the exit code cannot be
-      retrieved.
-    """
-    raise NotImplementedError()
-
-  def run_and_get_output(self, arguments, timeout=None):
-    """Runs the shell with given arguments until shell exits and returns the
-    output.
-
-    Args:
-      arguments: list of arguments for the shell
-      timeout: maximum running time in seconds, after which the shell will be
-          terminated
-
-    Returns:
-      A tuple of (return_code, output, did_time_out). |return_code| is the exit
-      code returned by the shell or None if the exit code cannot be retrieved.
-      |output| is the stdout mingled with the stderr produced by the shell.
-      |did_time_out| is True iff the shell was terminated because it exceeded
-      the |timeout| and False otherwise.
-    """
-    raise NotImplementedError()
diff --git a/mojo/devtools/common/devtoolslib/shell_arguments.py b/mojo/devtools/common/devtoolslib/shell_arguments.py
deleted file mode 100644
index 3863935..0000000
--- a/mojo/devtools/common/devtoolslib/shell_arguments.py
+++ /dev/null
@@ -1,243 +0,0 @@
-# Copyright 2015 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Produces configured shell abstractions.
-
-This module knows how to produce a configured shell abstraction based on
-shell_config.ShellConfig.
-"""
-
-import os.path
-import sys
-import urlparse
-
-from devtoolslib.android_shell import AndroidShell
-from devtoolslib.linux_shell import LinuxShell
-from devtoolslib.shell_config import ShellConfigurationException
-
-# When spinning up servers for local origins, we want to use predictable ports
-# so that caching works between subsequent runs with the same command line.
-_LOCAL_ORIGIN_PORT = 31840
-_MAPPINGS_BASE_PORT = 31841
-
-
-def _is_web_url(dest):
-  return True if urlparse.urlparse(dest).scheme else False
-
-
-def _host_local_url_destination(shell, dest_file, port):
-  """Starts a local server to host |dest_file|.
-
-  Returns:
-    Url of the hosted file.
-  """
-  directory = os.path.dirname(dest_file)
-  if not os.path.exists(directory):
-    raise ValueError('local path passed as --map-url destination '
-                     'does not exist')
-  server_url = shell.serve_local_directory(directory, port)
-  return server_url + os.path.relpath(dest_file, directory)
-
-
-def _host_local_origin_destination(shell, dest_dir, port):
-  """Starts a local server to host |dest_dir|.
-
-  Returns:
-    Url of the hosted directory.
-  """
-  return shell.serve_local_directory(dest_dir, port)
-
-
-def _rewrite(mapping, host_destination_functon, shell, port):
-  """Takes a mapping given as <src>=<dest> and rewrites the <dest> part to be
-  hosted locally using the given function if <dest> is not a web url.
-  """
-  parts = mapping.split('=')
-  if len(parts) != 2:
-    raise ValueError('each mapping value should be in format '
-                     '"<url>=<url-or-local-path>"')
-  if _is_web_url(parts[1]):
-    # The destination is a web url, do nothing.
-    return mapping
-
-  src = parts[0]
-  dest = host_destination_functon(shell, parts[1], port)
-  return src + '=' + dest
-
-
-def _apply_mappings(shell, original_arguments, map_urls, map_origins):
-  """Applies mappings for specified urls and origins. For each local path
-  specified as destination a local server will be spawned and the mapping will
-  be rewritten accordingly.
-
-  Args:
-    shell: The shell that is being configured.
-    original_arguments: Current list of shell arguments.
-    map_urls: List of url mappings, each in the form of
-      <url>=<url-or-local-path>.
-    map_origins: List of origin mappings, each in the form of
-        <origin>=<url-or-local-path>.
-
-  Returns:
-    The updated argument list.
-  """
-  next_port = _MAPPINGS_BASE_PORT
-  args = original_arguments
-  if map_urls:
-    # Sort the mappings to preserve caching regardless of argument order.
-    for map_url in sorted(map_urls):
-      mapping = _rewrite(map_url, _host_local_url_destination, shell, next_port)
-      next_port += 1
-      # All url mappings need to be coalesced into one shell argument.
-      args = append_to_argument(args, '--url-mappings=', mapping)
-
-  if map_origins:
-    for map_origin in sorted(map_origins):
-      mapping = _rewrite(map_origin, _host_local_origin_destination, shell,
-                         next_port)
-      next_port += 1
-      # Origin mappings are specified as separate, repeated shell arguments.
-      args.append('--map-origin=' + mapping)
-  return args
-
-
-def _configure_sky(shell_args):
-  """Maps mojo:sky_viewer as a content handler for dart applications.
-  app.
-
-  Args:
-    shell_args: Current list of shell arguments.
-
-  Returns:
-    Updated list of shell arguments.
-  """
-  # Configure the content type mappings for the sky_viewer. This is needed
-  # only for the Sky apps that do not declare mojo:sky_viewer in a shebang.
-  # TODO(ppi): drop this part once we can rely on the Sky files declaring
-  # correct shebang.
-  shell_args = append_to_argument(shell_args, '--content-handlers=',
-                                            'text/sky,mojo:sky_viewer')
-  shell_args = append_to_argument(shell_args, '--content-handlers=',
-                                            'application/dart,mojo:sky_viewer')
-  return shell_args
-
-
-def configure_local_origin(shell, local_dir, fixed_port=True):
-  """Sets up a local http server to serve files in |local_dir| along with
-  device port forwarding if needed.
-
-  Returns:
-    The list of arguments to be appended to the shell argument list.
-  """
-
-  origin_url = shell.serve_local_directory(
-      local_dir, _LOCAL_ORIGIN_PORT if fixed_port else 0)
-  return ["--origin=" + origin_url]
-
-
-def append_to_argument(arguments, key, value, delimiter=","):
-  """Looks for an argument of the form "key=val1,val2" within |arguments| and
-  appends |value| to it.
-
-  If the argument is not present in |arguments| it is added.
-
-  Args:
-    arguments: List of arguments for the shell.
-    key: Identifier of the argument, including the equal sign, eg.
-        "--content-handlers=".
-    value: The value to be appended, after |delimeter|, to the argument.
-    delimiter: The string used to separate values within the argument.
-
-  Returns:
-    The updated argument list.
-  """
-  assert key and key.endswith('=')
-  assert value
-
-  for i, argument in enumerate(arguments):
-    if not argument.startswith(key):
-      continue
-    arguments[i] = argument + delimiter + value
-    break
-  else:
-    arguments.append(key + value)
-
-  return arguments
-
-
-def _configure_dev_server(shell, shell_args, dev_server_config):
-  """Sets up a dev server on the host according to |dev_server_config|.
-
-  Args:
-    shell: The shell that is being configured.
-    shell_arguments: Current list of shell arguments.
-    dev_server_config: Instance of shell_config.DevServerConfig describing the
-        dev server to be set up.
-
-  Returns:
-    The updated argument list.
-  """
-  server_url = shell.serve_local_directories(dev_server_config.mappings)
-  shell_args.append('--map-origin=%s=%s' % (dev_server_config.host, server_url))
-  print "Configured %s locally to serve:" % (dev_server_config.host)
-  for mapping_prefix, mapping_path in dev_server_config.mappings:
-    print "  /%s -> %s" % (mapping_prefix, mapping_path)
-  return shell_args
-
-
-def get_shell(shell_config, shell_args):
-  """
-  Produces a shell abstraction configured according to |shell_config|.
-
-  Args:
-    shell_config: Instance of shell_config.ShellConfig.
-    shell_args: Additional raw shell arguments to be passed to the shell. We
-        need to take these into account as some parameters need to appear only
-        once on the argument list (e.g. url-mappings) so we need to coalesce any
-        overrides and the existing value into just one argument.
-
-  Returns:
-    A tuple of (shell, shell_args). |shell| is the configured shell abstraction,
-    |shell_args| is updated list of shell arguments.
-
-  Throws:
-    ShellConfigurationException if shell abstraction could not be configured.
-  """
-  if shell_config.android:
-    verbose_pipe = sys.stdout if shell_config.verbose else None
-
-    shell = AndroidShell(shell_config.adb_path, shell_config.target_device,
-                         logcat_tags=shell_config.logcat_tags,
-                         verbose_pipe=verbose_pipe)
-
-    device_status, error = shell.check_device()
-    if not device_status:
-      raise ShellConfigurationException('Device check failed: ' + error)
-    if shell_config.shell_path:
-      shell.install_apk(shell_config.shell_path)
-  else:
-    if not shell_config.shell_path:
-      raise ShellConfigurationException('Can not run without a shell binary. '
-                                        'Please pass --shell-path.')
-    shell = LinuxShell(shell_config.shell_path)
-    if shell_config.use_osmesa:
-      shell_args.append('--args-for=mojo:native_viewport_service --use-osmesa')
-
-  shell_args = _apply_mappings(shell, shell_args, shell_config.map_url_list,
-                               shell_config.map_origin_list)
-
-  if shell_config.origin:
-    if _is_web_url(shell_config.origin):
-      shell_args.append('--origin=' + shell_config.origin)
-    else:
-      shell_args.extend(configure_local_origin(shell, shell_config.origin,
-                                               fixed_port=True))
-
-  if shell_config.sky:
-    shell_args = _configure_sky(shell_args)
-
-  for dev_server_config in shell_config.dev_servers:
-    shell_args = _configure_dev_server(shell, shell_args, dev_server_config)
-
-  return shell, shell_args
diff --git a/mojo/devtools/common/devtoolslib/shell_arguments_unittest.py b/mojo/devtools/common/devtoolslib/shell_arguments_unittest.py
deleted file mode 100644
index f86b163..0000000
--- a/mojo/devtools/common/devtoolslib/shell_arguments_unittest.py
+++ /dev/null
@@ -1,46 +0,0 @@
-# Copyright 2015 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import imp
-import os.path
-import sys
-import unittest
-
-try:
-  imp.find_module("devtoolslib")
-except ImportError:
-  sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
-from devtoolslib import shell_arguments
-
-
-class AppendToArgumentTest(unittest.TestCase):
-  """Tests AppendToArgument()."""
-
-  def test_append_to_empty(self):
-    arguments = []
-    key = '--something='
-    value = 'val'
-    expected_result = ['--something=val']
-    self.assertEquals(expected_result, shell_arguments.append_to_argument(
-        arguments, key, value))
-
-  def test_append_to_non_empty(self):
-    arguments = ['--other']
-    key = '--something='
-    value = 'val'
-    expected_result = ['--other', '--something=val']
-    self.assertEquals(expected_result, shell_arguments.append_to_argument(
-        arguments, key, value))
-
-  def test_append_to_existing(self):
-    arguments = ['--something=old_val']
-    key = '--something='
-    value = 'val'
-    expected_result = ['--something=old_val,val']
-    self.assertEquals(expected_result, shell_arguments.append_to_argument(
-        arguments, key, value))
-
-
-if __name__ == "__main__":
-  unittest.main()
diff --git a/mojo/devtools/common/devtoolslib/shell_config.py b/mojo/devtools/common/devtoolslib/shell_config.py
deleted file mode 100644
index 2b55d54..0000000
--- a/mojo/devtools/common/devtoolslib/shell_config.py
+++ /dev/null
@@ -1,196 +0,0 @@
-# Copyright 2015 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Configuration for the shell abstraction.
-
-This module declares ShellConfig and knows how to compute it from command-line
-arguments, applying any default paths inferred from the checkout, configuration
-file, etc.
-"""
-
-import ast
-
-from devtoolslib import paths
-
-
-class ShellConfigurationException(Exception):
-  """Represents an error preventing creating a functional shell abstraction."""
-  pass
-
-
-class ShellConfig(object):
-  """Configuration for the shell abstraction."""
-
-  def __init__(self):
-    self.android = None
-    self.shell_path = None
-    self.origin = None
-    self.map_url_list = []
-    self.map_origin_list = []
-    self.dev_servers = []
-    self.sky = None
-    self.verbose = None
-
-    # Android-only.
-    self.adb_path = None
-    self.target_device = None
-    self.logcat_tags = None
-
-    # Desktop-only.
-    self.use_osmesa = None
-
-
-class DevServerConfig(object):
-  """Configuration for a development server running on a host and available to
-  the shell.
-  """
-  def __init__(self):
-    self.host = None
-    self.mappings = None
-
-
-def add_shell_arguments(parser):
-  """Adds argparse arguments allowing to configure shell abstraction using
-  configure_shell() below.
-  """
-  # Arguments configuring the shell run.
-  parser.add_argument('--android', help='Run on Android',
-                      action='store_true')
-  parser.add_argument('--shell-path', help='Path of the Mojo shell binary.')
-  parser.add_argument('--origin', help='Origin for mojo: URLs. This can be a '
-                      'web url or a local directory path.')
-  parser.add_argument('--map-url', action='append',
-                      help='Define a mapping for a url in the format '
-                      '<url>=<url-or-local-file-path>')
-  parser.add_argument('--map-origin', action='append',
-                      help='Define a mapping for a url origin in the format '
-                      '<origin>=<url-or-local-file-path>')
-  parser.add_argument('--sky', action='store_true',
-                      help='Maps mojo:sky_viewer as the content handler for '
-                           'dart apps.')
-  parser.add_argument('-v', '--verbose', action="store_true",
-                      help="Increase output verbosity")
-
-  android_group = parser.add_argument_group('Android-only',
-      'These arguments apply only when --android is passed.')
-  android_group.add_argument('--adb-path', help='Path of the adb binary.')
-  android_group.add_argument('--target-device', help='Device to run on.')
-  android_group.add_argument('--logcat-tags', help='Comma-separated list of '
-                             'additional logcat tags to display.')
-
-  desktop_group = parser.add_argument_group('Desktop-only',
-      'These arguments apply only when running on desktop.')
-  desktop_group.add_argument('--use-osmesa', action='store_true',
-                             help='Configure the native viewport service '
-                             'for off-screen rendering.')
-
-  config_file_group = parser.add_argument_group('Configuration file',
-      'These arguments allow to modify the behavior regarding the mojoconfig '
-      'file.')
-  config_file_group.add_argument('--config-file', type=file,
-                                 help='Path of the configuration file to use.')
-  config_file_group.add_argument('--no-config-file', action='store_true',
-                                 help='Pass to skip automatic discovery of the '
-                                 'mojoconfig file.')
-
-  # Arguments allowing to indicate the build directory we are targeting when
-  # running within a Chromium-like checkout (e.g. Mojo checkout). These will go
-  # away once we have devtools config files, see
-  # https://github.com/domokit/devtools/issues/28.
-  chromium_checkout_group = parser.add_argument_group(
-      'Chromium-like checkout configuration',
-      'These arguments allow to infer paths to tools and build results '
-      'when running within a Chromium-like checkout')
-  debug_group = chromium_checkout_group.add_mutually_exclusive_group()
-  debug_group.add_argument('--debug', help='Debug build (default)',
-                           default=True, action='store_true')
-  debug_group.add_argument('--release', help='Release build', default=False,
-                           dest='debug', action='store_false')
-  chromium_checkout_group.add_argument('--target-cpu',
-                                     help='CPU architecture to run for.',
-                                     choices=['x64', 'x86', 'arm'])
-
-
-def _discover_config_file():
-  config_file_path = paths.find_within_ancestors('mojoconfig')
-  if not config_file_path:
-    return None
-  return open(config_file_path, 'r')
-
-
-def _read_config_file(config_file, aliases):
-  spec = config_file.read()
-  for alias_pattern, alias_value in aliases:
-    spec = spec.replace(alias_pattern, alias_value)
-  return ast.literal_eval(spec)
-
-
-def get_shell_config(script_args):
-  """Processes command-line options defined in add_shell_arguments(), applying
-  any inferred default paths and produces an instance of ShellConfig.
-
-  Returns:
-    An instance of ShellConfig.
-  """
-  # Infer paths based on the Chromium configuration options
-  # (--debug/--release, etc.), if running within a Chromium-like checkout.
-  inferred_paths = paths.infer_paths(script_args.android, script_args.debug,
-                                     script_args.target_cpu)
-  shell_config = ShellConfig()
-
-  shell_config.android = script_args.android
-  shell_config.shell_path = (script_args.shell_path or
-                             inferred_paths['shell_path'])
-  shell_config.origin = script_args.origin
-  shell_config.map_url_list = script_args.map_url
-  shell_config.map_origin_list = script_args.map_origin
-  shell_config.sky = script_args.sky
-  shell_config.verbose = script_args.verbose
-
-  # Android-only.
-  shell_config.adb_path = (script_args.adb_path or inferred_paths['adb_path'])
-  shell_config.target_device = script_args.target_device
-  shell_config.logcat_tags = script_args.logcat_tags
-
-  # Desktop-only.
-  shell_config.use_osmesa = script_args.use_osmesa
-
-  if (shell_config.android and not shell_config.origin and
-      inferred_paths['build_dir_path']):
-    shell_config.origin = inferred_paths['build_dir_path']
-
-  # Read the mojoconfig file.
-  config_file = script_args.config_file
-  if not script_args.no_config_file:
-    config_file = config_file or _discover_config_file()
-
-  if config_file:
-    with config_file:
-      config_file_aliases = []
-      if inferred_paths['build_dir_path']:
-        config_file_aliases.append(('@{BUILD_DIR}',
-                                    inferred_paths['build_dir_path']))
-
-      config = None
-      try:
-        if script_args.verbose:
-          print 'Reading config file from: ' + config_file.name
-        config = _read_config_file(config_file, config_file_aliases)
-      except SyntaxError:
-        raise ShellConfigurationException('Failed to parse the mojoconfig '
-                                          'file.')
-
-    if 'dev_servers' in config:
-      try:
-        for dev_server_spec in config['dev_servers']:
-          dev_server_config = DevServerConfig()
-          dev_server_config.host = dev_server_spec['host']
-          dev_server_config.mappings = []
-          for prefix, path in dev_server_spec['mappings']:
-            dev_server_config.mappings.append((prefix, path))
-          shell_config.dev_servers.append(dev_server_config)
-      except (ValueError, KeyError):
-        raise ShellConfigurationException('Failed to parse dev_servers in '
-                                          'the mojoconfig file.')
-  return shell_config
diff --git a/mojo/devtools/common/devtoolslib/utils.py b/mojo/devtools/common/devtoolslib/utils.py
deleted file mode 100644
index 7bf2e1c..0000000
--- a/mojo/devtools/common/devtoolslib/utils.py
+++ /dev/null
@@ -1,16 +0,0 @@
-# Copyright 2015 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Python utils."""
-
-
-def overrides(parent_class):
-  """Inherits the docstring from the method of the same name in the indicated
-  parent class.
-  """
-  def overriding(method):
-    assert(method.__name__ in dir(parent_class))
-    method.__doc__ = getattr(parent_class, method.__name__).__doc__
-    return method
-  return overriding
diff --git a/mojo/devtools/common/mojo_debug b/mojo/devtools/common/mojo_debug
deleted file mode 100755
index fb4459f..0000000
--- a/mojo/devtools/common/mojo_debug
+++ /dev/null
@@ -1,330 +0,0 @@
-#!/usr/bin/env python
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import argparse
-import codecs
-import logging
-import os.path
-import requests
-import signal
-import subprocess
-import sys
-import tempfile
-
-
-from android_gdb.install_remote_file_reader import install
-from devtoolslib import paths
-
-
-_MOJO_DEBUGGER_PORT = 7777
-_DEFAULT_PACKAGE_NAME = 'org.chromium.mojo.shell'
-
-
-# TODO(etiennej): Refactor with similar methods in subdirectories
-class DirectoryNotFoundException(Exception):
-  """Directory has not been found."""
-  pass
-
-
-def _get_dir_above(dirname):
-  """Returns the directory "above" this file containing |dirname|."""
-  path = paths.find_ancestor_with(dirname)
-  if not path:
-    raise DirectoryNotFoundException(dirname)
-  return path
-
-
-def _send_request(request, payload=None):
-  """Sends a request to mojo:debugger."""
-  try:
-    url = 'http://localhost:%s/%s' % (_MOJO_DEBUGGER_PORT, request)
-    if payload:
-      return requests.post(url, payload)
-    else:
-      return requests.get(url)
-  except requests.exceptions.ConnectionError:
-    print 'Failed to connect to mojo:debugger, make sure the shell is running.'
-    return None
-
-
-def _tracing_start(_):
-  """Starts tracing."""
-  if not _send_request('start_tracing'):
-    return 1
-  print "Started tracing."
-  return 0
-
-
-def _tracing_stop(args):
-  """Stops tracing and writes trace to file."""
-  if args.file_name:
-    file_name = args.file_name
-  else:
-    for i in xrange(1000):
-      candidate_file_name = 'mojo_trace_%03d.json' % i
-      if not os.path.exists(candidate_file_name):
-        file_name = candidate_file_name
-        break
-    else:
-      print 'Failed to pick a name for the trace output file.'
-      return 1
-
-  response = _send_request('stop_tracing')
-  if not response:
-    return 1
-
-  # https://github.com/domokit/mojo/issues/253
-  if int(response.headers['content-length']) != len(response.content):
-    print 'Response is truncated.'
-    return 1
-
-  with open(file_name, "wb") as trace_file:
-    trace_file.write('{"traceEvents":[')
-    trace_file.write(response.content)
-    trace_file.write(']}')
-  print "Trace saved in %s" % file_name
-  return 0
-
-
-def _add_tracing_command(subparsers):
-  """Sets up the command line parser to manage tracing."""
-  tracing_parser = subparsers.add_parser('tracing',
-      help='trace event profiler')
-  tracing_subparser = tracing_parser.add_subparsers(
-      help='the command to run')
-
-  start_tracing_parser = tracing_subparser.add_parser('start',
-      help='start tracing')
-  start_tracing_parser.set_defaults(func=_tracing_start)
-
-  stop_tracing_parser = tracing_subparser.add_parser('stop',
-      help='stop tracing and retrieve the result')
-  stop_tracing_parser.add_argument('file_name', type=str, nargs='?',
-      help='name of the output file (optional)')
-  stop_tracing_parser.set_defaults(func=_tracing_stop)
-
-
-def _wm_load(args):
-  """Loads (embeds) the given url in the window manager."""
-  if not _send_request('load', args.url):
-    return 1
-  return 0
-
-
-def _add_wm_command(subparsers):
-  """Sets up the parser for the 'wm' command."""
-  wm_parser = subparsers.add_parser('wm', help='window manager')
-  wm_subparser = wm_parser.add_subparsers(
-      help='the command to run')
-
-  wm_load_parser = wm_subparser.add_parser('load',
-      help='load (embed) the given url')
-  wm_load_parser.add_argument('url', type=str,
-      help='the url to load')
-  wm_load_parser.set_defaults(func=_wm_load)
-
-
-def _device_stack(args):
-  """Runs the device logcat through android_stack_parser."""
-  adb_path = args.adb_path if args.adb_path else 'adb'
-  logcat_cmd = [adb_path, 'logcat', '-d']
-  try:
-    logcat = subprocess.Popen(logcat_cmd, stdout=subprocess.PIPE)
-  except OSError:
-    print 'failed to call adb, make sure it is in PATH or pass --adb-path'
-    return 1
-
-  devtools_dir = os.path.dirname(os.path.abspath(__file__))
-  stack_command = [os.path.join(devtools_dir, 'android_stack_parser', 'stack')]
-  if args.build_dir:
-    stack_command.append('--build-dir=' + os.path.abspath(args.build_dir))
-  if args.ndk_dir:
-    stack_command.append('--ndk-dir=' + os.path.abspath(args.ndk_dir))
-  stack_command.append('-')
-  stack = subprocess.Popen(stack_command, stdin=logcat.stdout)
-
-  logcat.wait()
-  stack.wait()
-
-  if logcat.returncode:
-    print 'adb logcat failed, make sure the device is connected and available'
-    return logcat.returncode
-  if stack.returncode:
-    return stack.returncode
-  return 0
-
-
-def _gdb_attach(args):
-  """Run GDB on an instance of Mojo Shell on an android device."""
-  if args.ndk_dir:
-    ndk_dir = args.ndk_dir
-  else:
-    try:
-      ndk_dir = os.path.join(_get_dir_above('third_party'), 'third_party',
-                             'android_tools', 'ndk')
-      if not os.path.exists(ndk_dir):
-        raise DirectoryNotFoundException()
-    except DirectoryNotFoundException:
-      logging.fatal("Unable to find the Android NDK, please specify its path "
-          "with --ndk-dir.")
-      return
-
-  install_args = {}
-  if args.gsutil_dir:
-    install_args['gsutil'] = os.path.join(args.gsutil_dir, 'gsutil')
-  else:
-    try:
-      depot_tools_path = paths.find_depot_tools()
-      if not depot_tools_path:
-        raise DirectoryNotFoundException()
-      install_args['gsutil'] = os.path.join(depot_tools_path, 'third_party',
-                                            'gsutil', 'gsutil')
-      if not os.path.exists(install_args['gsutil']):
-        raise DirectoryNotFoundException()
-    except DirectoryNotFoundException:
-      logging.fatal("Unable to find gsutil, please specify its path with "
-                    "--gsutil-dir.")
-      return
-
-  if args.adb_path:
-    install_args['adb'] = args.adb_path
-  else:
-    install_args['adb'] = 'adb'
-
-  try:
-    install(**install_args)
-  except OSError as e:
-    if e.errno == 2:
-      # ADB not found in path, print an error message
-      logging.fatal("Unable to find ADB, please specify its path with "
-                    "--adb-path.")
-      return
-    else:
-      raise
-
-  gdb_path = os.path.join(
-      ndk_dir,
-      'toolchains',
-      # TODO(etiennej): Always select the most recent toolchain?
-      'arm-linux-androideabi-4.9',
-      'prebuilt',
-      # TODO(etiennej): DEPS mac NDK and use it on macs.
-      'linux-x86_64',
-      'bin',
-      'arm-linux-androideabi-gdb')
-  python_gdb_script_path = os.path.join(os.path.dirname(__file__),
-                                        'android_gdb', 'session.py')
-  debug_session_arguments = {}
-  if args.build_dir:
-    debug_session_arguments["build_directory"] = args.build_dir
-  else:
-    try:
-      debug_session_arguments["build_directory"] = os.path.join(
-          _get_dir_above('out'), 'out', 'android_Debug')
-      if not os.path.exists(debug_session_arguments["build_directory"]):
-        raise DirectoryNotFoundException()
-    except DirectoryNotFoundException:
-      logging.fatal("Unable to find the build directory, please specify it "
-                    "using --build-dir.")
-      return
-
-  if args.package_name:
-    debug_session_arguments["package_name"] = args.package_name
-  else:
-    debug_session_arguments["package_name"] = _DEFAULT_PACKAGE_NAME
-  debug_session_arguments['adb'] = install_args['adb']
-  if args.pyelftools_dir:
-    debug_session_arguments["pyelftools_dir"] = args.pyelftools_dir
-  else:
-    try:
-      debug_session_arguments["pyelftools_dir"] = os.path.join(
-          _get_dir_above('third_party'), 'third_party', 'pyelftools')
-      if not os.path.exists(debug_session_arguments["pyelftools_dir"]):
-        raise DirectoryNotFoundException()
-    except DirectoryNotFoundException:
-      logging.fatal("Unable to find pyelftools python module, please specify "
-          "its path using --pyelftools-dir.")
-      return
-
-  debug_session_arguments_str = ', '.join(
-      [k + '="' + codecs.encode(v, 'string_escape') + '"'
-       for k, v in debug_session_arguments.items()])
-
-  # We need to pass some commands to GDB at startup.
-  gdb_commands_file = tempfile.NamedTemporaryFile()
-  gdb_commands_file.write('source ' + python_gdb_script_path + '\n')
-  gdb_commands_file.write('py d = DebugSession(' + debug_session_arguments_str
-                          + ')\n')
-  gdb_commands_file.write('py d.start()\n')
-  gdb_commands_file.flush()
-
-  gdb_proc = subprocess.Popen([gdb_path, '-x', gdb_commands_file.name],
-                              stdin=sys.stdin,
-                              stdout=sys.stdout,
-                              stderr=sys.stderr)
-
-  # We don't want SIGINT to stop this program. It is automatically propagated by
-  # the system to gdb.
-  signal.signal(signal.SIGINT, signal.SIG_IGN)
-  gdb_proc.wait()
-  signal.signal(signal.SIGINT, signal.SIG_DFL)
-
-
-def _add_device_command(subparsers):
-  """Sets up the parser for the 'device' command."""
-  device_parser = subparsers.add_parser('device',
-      help='interact with the Android device (requires adb in PATH or passing '
-           '--adb-path)')
-  device_parser.add_argument('--adb-path', type=str,
-      help='path to the adb tool from the Android SDK (optional)')
-  device_subparser = device_parser.add_subparsers(
-      help='the command to run')
-
-  device_stack_parser = device_subparser.add_parser('stack',
-      help='symbolize the crash stacktraces from the device log')
-  device_stack_parser.add_argument('--ndk-dir', type=str,
-      help='path to the directory containing the Android NDK')
-  device_stack_parser.add_argument('--build-dir', type=str,
-      help='path to the build directory')
-  device_stack_parser.set_defaults(func=_device_stack)
-
-
-def _add_gdb_command(subparsers):
-  gdb_parser = subparsers.add_parser(
-      'gdb', help='Debug Mojo Shell and its apps using GDB')
-  gdb_subparser = gdb_parser.add_subparsers(
-      help='Commands to GDB')
-
-  gdb_attach_parser = gdb_subparser.add_parser(
-      'attach', help='Attach GDB to a running Mojo Shell process')
-  gdb_attach_parser.add_argument('--adb-path', type=str,
-      help='path to the adb tool from the Android SDK (optional)')
-  gdb_attach_parser.add_argument('--ndk-dir', type=str,
-      help='path to the directory containing the Android NDK')
-  gdb_attach_parser.add_argument('--build-dir', type=str,
-      help='path to the build directory')
-  gdb_attach_parser.add_argument('--pyelftools-dir', type=str,
-      help='Path to a directory containing third party libraries')
-  gdb_attach_parser.add_argument('--gsutil-dir', type=str,
-      help='Path to a directory containing gsutil')
-  gdb_attach_parser.add_argument('--package-name', type=str,
-      help='Name of the Mojo Shell android package to debug')
-  gdb_attach_parser.set_defaults(func=_gdb_attach)
-
-
-def main():
-  parser = argparse.ArgumentParser(description='Command-line interface for '
-                                                'mojo:debugger')
-  subparsers = parser.add_subparsers(help='the tool to run')
-  _add_device_command(subparsers)
-  _add_tracing_command(subparsers)
-  _add_wm_command(subparsers)
-  _add_gdb_command(subparsers)
-
-  args = parser.parse_args()
-  return args.func(args)
-
-if __name__ == '__main__':
-  sys.exit(main())
diff --git a/mojo/devtools/common/mojo_run b/mojo/devtools/common/mojo_run
deleted file mode 100755
index 554eeab..0000000
--- a/mojo/devtools/common/mojo_run
+++ /dev/null
@@ -1,95 +0,0 @@
-#!/usr/bin/env python
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import argparse
-import logging
-import sys
-
-from devtoolslib import shell_arguments
-from devtoolslib import shell_config
-
-_USAGE = ("mojo_run "
-         "[--args-for=<mojo-app>] "
-         "[--content-handlers=<handlers>] "
-         "[--enable-external-applications] "
-         "[--disable-cache] "
-         "[--enable-multiprocess] "
-         "[--wait-for-debugger] "
-         "[--sky <mojo-app>|<mojo-app>] "
-         """
-
-A <mojo-app> is a Mojo URL or a Mojo URL and arguments within quotes.
-Example: mojo_run "mojo:js_standalone test.js".
-<url-lib-path> is searched for shared libraries named by mojo URLs.
-The value of <handlers> is a comma separated list like:
-text/html,mojo:html_viewer,application/javascript,mojo:js_content_handler
-""")
-
-_DESCRIPTION = """Runner for Mojo applications.
-
-Any arguments not recognized by the script will be passed on as shell arguments.
-"""
-
-
-# Port on which the mojo:debugger http server will be available on the host
-# machine.
-_MOJO_DEBUGGER_PORT = 7777
-_DEFAULT_WINDOW_MANAGER = "mojo:kiosk_wm"
-
-
-def _configure_debugger(shell):
-  """Configures mojo:debugger to run and sets up port forwarding for its http
-  server if the shell is running on a device.
-
-  Returns:
-    Arguments that need to be appended to the shell argument list in order to
-    run with the debugger.
-  """
-  shell.forward_host_port_to_shell(_MOJO_DEBUGGER_PORT)
-  return ['mojo:debugger %d' % _MOJO_DEBUGGER_PORT]
-
-
-def main():
-  logging.basicConfig()
-
-  parser = argparse.ArgumentParser(usage=_USAGE, description=_DESCRIPTION)
-  shell_config.add_shell_arguments(parser)
-
-  parser.add_argument('--no-debugger', action="store_true",
-                      help='Do not spawn mojo:debugger.')
-  parser.add_argument('--window-manager', default=_DEFAULT_WINDOW_MANAGER,
-                      help='Window manager app to be mapped as '
-                      'mojo:window_manager. By default it is ' +
-                      _DEFAULT_WINDOW_MANAGER)
-
-  script_args, shell_args = parser.parse_known_args()
-
-  try:
-    config = shell_config.get_shell_config(script_args)
-    shell, shell_args = shell_arguments.get_shell(config, shell_args)
-  except shell_config.ShellConfigurationException as e:
-    print e
-    return 1
-
-  if not script_args.no_debugger:
-    if script_args.verbose:
-      print 'Spawning mojo:debugger, use `mojo_debug` to inspect the shell.'
-      print 'Note that mojo:debugger will prevent the shell from terminating,'
-      print '  pass --no-debugger to skip spawning mojo:debugger.'
-    shell_args.extend(_configure_debugger(shell))
-
-  shell_args = shell_arguments.append_to_argument(shell_args, '--url-mappings=',
-                                                  'mojo:window_manager=%s' %
-                                                  script_args.window_manager)
-
-  if script_args.verbose:
-    print "Shell arguments: " + str(shell_args)
-
-  shell.run(shell_args)
-  return 0
-
-
-if __name__ == "__main__":
-  sys.exit(main())
diff --git a/mojo/devtools/common/mojo_test b/mojo/devtools/common/mojo_test
deleted file mode 100755
index 2cf84b9..0000000
--- a/mojo/devtools/common/mojo_test
+++ /dev/null
@@ -1,110 +0,0 @@
-#!/usr/bin/env python
-# Copyright 2015 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Test runner for Mojo application tests.
-
-TODO(vtl|msw): Add a way of specifying data dependencies.
-"""
-
-import argparse
-import logging
-import sys
-
-from devtoolslib import apptest_dart
-from devtoolslib import apptest_gtest
-from devtoolslib import shell_arguments
-from devtoolslib import shell_config
-
-_DESCRIPTION = """Runner for Mojo application tests.
-
-|test_list_file| has to be a valid Python program that sets a |tests| global
-variable, containing entries of the following form:
-
- {
-   # Required URL for apptest.
-   "test": "mojo:test_app_url",
-   # Optional display name (otherwise the entry for "test" above is used).
-   "name": "mojo:test_app_url (more details)",
-   # Optional test type. Valid values:
-   #   * "gtest" (default)
-   #   * "gtest_isolated": like "gtest", but run with fixture isolation,
-   #      i.e., each test in a fresh mojo_shell
-   #   * "dart"
-   "type": "gtest",
-   # Optional arguments to be passed to the apptest.
-   "test-args": ["--an_arg", "another_arg"],
-   # Optional shell arguments.
-   "shell-args": ["--some-flag-for-the-shell", "--another-flag"],
-   # Optional timeout in seconds, 60 by default.
-   "timeout": 120,
- }
-
-|test_list_file| may reference the |target_os| global that will be any of
-['android', 'linux'], indicating the system on which the tests are to be run.
-
-Any arguments not recognized by the script will be passed on as shell arguments.
-"""
-
-_logger = logging.getLogger()
-
-
-def main():
-  parser = argparse.ArgumentParser(
-      formatter_class=argparse.RawDescriptionHelpFormatter,
-      description=_DESCRIPTION)
-  parser.add_argument("test_list_file", type=file,
-                      help="a file listing apptests to run")
-  shell_config.add_shell_arguments(parser)
-
-  script_args, shell_args = parser.parse_known_args()
-
-  try:
-    config = shell_config.get_shell_config(script_args)
-    shell, common_shell_args = shell_arguments.get_shell(config, shell_args)
-  except shell_config.ShellConfigurationException as e:
-    print e
-    return 1
-
-  target_os = "android" if script_args.android else "linux"
-  test_list_globals = {"target_os": target_os}
-  exec script_args.test_list_file in test_list_globals
-  test_list = test_list_globals["tests"]
-
-  succeeded = True
-  for test_dict in test_list:
-    test = test_dict["test"]
-    test_name = test_dict.get("name", test)
-    test_type = test_dict.get("type", "gtest")
-    test_args = test_dict.get("test-args", [])
-    shell_args = test_dict.get("shell-args", []) + common_shell_args
-    timeout = test_dict.get("timeout", 60)
-
-    _logger.info("Will start: %s" % test_name)
-    print "Running %s...." % test_name,
-    sys.stdout.flush()
-
-    if test_type == "dart":
-      apptest_result = apptest_dart.run_dart_apptest(shell, shell_args, test,
-                                                     test_args, timeout)
-    elif test_type == "gtest":
-      apptest_result = apptest_gtest.run_gtest_apptest(shell, shell_args, test,
-                                                       test_args, timeout,
-                                                       False)
-    elif test_type == "gtest_isolated":
-      apptest_result = apptest_gtest.run_gtest_apptest(shell, shell_args, test,
-                                                       test_args, timeout,
-                                                       True)
-    else:
-      apptest_result = False
-      print "Unrecognized test type in %r" % test_dict
-
-    print "Succeeded" if apptest_result else "Failed"
-    _logger.info("Completed: %s" % test_name)
-    if not apptest_result:
-      succeeded = False
-  return 0 if succeeded else 1
-
-if __name__ == '__main__':
-  sys.exit(main())
diff --git a/mojo/devtools/common/remote_adb_setup b/mojo/devtools/common/remote_adb_setup
deleted file mode 100755
index d275ff6..0000000
--- a/mojo/devtools/common/remote_adb_setup
+++ /dev/null
@@ -1,51 +0,0 @@
-#!/bin/bash
-# Copyright 2015 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-if [[ $# -ne 1 && $# -ne 2 ]]; then
-  cat <<'EOF'
-Usage: remote_adb_setup REMOTE_HOST [REMOTE_ADB]
-
-Configures adb on a remote machine to communicate with a device attached to the
-local machine. This is useful for installing APKs, running tests, etc while
-working remotely.
-
-Arguments:
-  REMOTE_HOST  hostname of remote machine
-  REMOTE_ADB   path to adb on the remote machine (you can omit this if adb is in
-               the remote host's path)
-EOF
-  exit 1
-fi
-
-remote_host="$1"
-remote_adb="${2:-adb}"
-
-# Ensure adb is in the local machine's path.
-if ! which adb >/dev/null; then
-  echo "error: adb must be in your local machine's path."
-  exit 1
-fi
-
-if which kinit >/dev/null; then
-  # Allow ssh to succeed without typing your password multiple times.
-  kinit -R || kinit
-fi
-
-# Kill the adb server on the remote host.
-ssh "$remote_host" "$remote_adb kill-server"
-
-# Start the adb server locally.
-adb start-server
-
-# Forward various ports from the remote host to the local host:
-#   5037: adb
-# and from the local host to the remote host:
-#   9998: http server for Sky
-#   31840: http server for the local mojo: origin
-ssh -C \
-    -R 5037:127.0.0.1:5037 \
-    -L 9998:127.0.0.1:9998 \
-    -L 31840:127.0.0.1:31840 \
-    "$remote_host"
diff --git a/mojo/edk/system/BUILD.gn b/mojo/edk/system/BUILD.gn
index ac292d5..5367be1 100644
--- a/mojo/edk/system/BUILD.gn
+++ b/mojo/edk/system/BUILD.gn
@@ -204,6 +204,7 @@
     "simple_dispatcher_unittest.cc",
     "test_channel_endpoint_client.cc",
     "test_channel_endpoint_client.h",
+    "test_utils_unittest.cc",
     "thread_annotations_unittest.cc",
     "unique_identifier_unittest.cc",
     "waiter_test_utils.cc",
diff --git a/mojo/edk/system/channel_endpoint.cc b/mojo/edk/system/channel_endpoint.cc
index 038de8d..e7e17b4 100644
--- a/mojo/edk/system/channel_endpoint.cc
+++ b/mojo/edk/system/channel_endpoint.cc
@@ -16,9 +16,9 @@
 ChannelEndpoint::ChannelEndpoint(ChannelEndpointClient* client,
                                  unsigned client_port,
                                  MessageInTransitQueue* message_queue)
-    : client_(client),
+    : state_(State::PAUSED),
+      client_(client),
       client_port_(client_port),
-      channel_state_(ChannelState::NOT_YET_ATTACHED),
       channel_(nullptr) {
   DCHECK(client_ || message_queue);
 
@@ -31,18 +31,14 @@
 
   MutexLocker locker(&mutex_);
 
-  switch (channel_state_) {
-    case ChannelState::NOT_YET_ATTACHED:
-    case ChannelState::DETACHED:
-      // We may reach here if we haven't been attached/run yet.
-      // TODO(vtl): We may also reach here if the channel is shut down early for
-      // some reason (with live message pipes on it). Ideally, we'd return false
-      // (and not enqueue the message), but we currently don't have a way to
-      // check this.
+  switch (state_) {
+    case State::PAUSED:
       channel_message_queue_.AddMessage(message.Pass());
       return true;
-    case ChannelState::ATTACHED:
+    case State::RUNNING:
       return WriteMessageNoLock(message.Pass());
+    case State::DEAD:
+      return false;
   }
 
   NOTREACHED();
@@ -58,7 +54,7 @@
   DCHECK(client != client_.get() || client_port != client_port_);
   client_ = client;
   client_port_ = client_port;
-  return channel_state_ != ChannelState::DETACHED;
+  return state_ != State::DEAD;
 }
 
 void ChannelEndpoint::DetachFromClient() {
@@ -69,7 +65,7 @@
   if (!channel_)
     return;
   channel_->DetachEndpoint(this, local_id_, remote_id_);
-  ResetChannelNoLock();
+  DieNoLock();
 }
 
 void ChannelEndpoint::AttachAndRun(Channel* channel,
@@ -80,11 +76,11 @@
   DCHECK(remote_id.is_valid());
 
   MutexLocker locker(&mutex_);
-  DCHECK(channel_state_ == ChannelState::NOT_YET_ATTACHED);
+  DCHECK(state_ == State::PAUSED);
   DCHECK(!channel_);
   DCHECK(!local_id_.is_valid());
   DCHECK(!remote_id_.is_valid());
-  channel_state_ = ChannelState::ATTACHED;
+  state_ = State::RUNNING;
   channel_ = channel;
   local_id_ = local_id;
   remote_id_ = remote_id;
@@ -96,7 +92,7 @@
 
   if (!client_) {
     channel_->DetachEndpoint(this, local_id_, remote_id_);
-    ResetChannelNoLock();
+    DieNoLock();
   }
 }
 
@@ -131,9 +127,9 @@
     // |DetachFromClient()| by calling |Channel::DetachEndpoint()| (and there
     // are racing detaches).
     if (channel_)
-      ResetChannelNoLock();
+      DieNoLock();
     else
-      DCHECK(channel_state_ == ChannelState::DETACHED);
+      DCHECK(state_ == State::DEAD);
   }
 
   // If |ReplaceClient()| is called (from another thread) after the above locked
@@ -190,7 +186,7 @@
       MutexLocker locker(&mutex_);
       if (!channel_ || !client_) {
         // This isn't a failure per se. (It just means that, e.g., the other end
-        // of the message point closed first.)
+        // of the message pipe closed first.)
         return;
       }
 
@@ -212,13 +208,13 @@
   }
 }
 
-void ChannelEndpoint::ResetChannelNoLock() {
-  DCHECK(channel_state_ == ChannelState::ATTACHED);
+void ChannelEndpoint::DieNoLock() {
+  DCHECK(state_ == State::RUNNING);
   DCHECK(channel_);
   DCHECK(local_id_.is_valid());
   DCHECK(remote_id_.is_valid());
 
-  channel_state_ = ChannelState::DETACHED;
+  state_ = State::DEAD;
   channel_ = nullptr;
   local_id_ = ChannelEndpointId();
   remote_id_ = ChannelEndpointId();
diff --git a/mojo/edk/system/channel_endpoint.h b/mojo/edk/system/channel_endpoint.h
index c70e66e..3ebe386 100644
--- a/mojo/edk/system/channel_endpoint.h
+++ b/mojo/edk/system/channel_endpoint.h
@@ -168,13 +168,23 @@
   // Helper for |OnReadMessage()|, handling messages for the client.
   void OnReadMessageForClient(scoped_ptr<MessageInTransit> message);
 
-  // Resets |channel_| to null (and sets |channel_state_| to
-  // |ChannelState::DETACHED|). This may only be called if |channel_| is
-  // non-null.
-  void ResetChannelNoLock() MOJO_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
+  // Moves |state_| from |RUNNING| to |DEAD|. |channel_| must be non-null, but
+  // this does not call |channel_->DetachEndpoint()|.
+  void DieNoLock() MOJO_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
 
   Mutex mutex_;
 
+  enum class State {
+    // |AttachAndRun()| has not been called yet (|channel_| is null).
+    PAUSED,
+    // |AttachAndRun()| has been called, but not |DetachFromChannel()|
+    // (|channel_| is non-null and valid).
+    RUNNING,
+    // |DetachFromChannel()| has been called (|channel_| is null).
+    DEAD
+  };
+  State state_ MOJO_GUARDED_BY(mutex_);
+
   // |client_| must be valid whenever it is non-null. Before |*client_| gives up
   // its reference to this object, it must call |DetachFromClient()|.
   // NOTE: This is a |scoped_refptr<>|, rather than a raw pointer, since the
@@ -193,17 +203,6 @@
   scoped_refptr<ChannelEndpointClient> client_ MOJO_GUARDED_BY(mutex_);
   unsigned client_port_ MOJO_GUARDED_BY(mutex_);
 
-  // State with respect to interaction with the |Channel|.
-  enum class ChannelState {
-    // |AttachAndRun()| has not been called yet (|channel_| is null).
-    NOT_YET_ATTACHED,
-    // |AttachAndRun()| has been called, but not |DetachFromChannel()|
-    // (|channel_| is non-null and valid).
-    ATTACHED,
-    // |DetachFromChannel()| has been called (|channel_| is null).
-    DETACHED
-  };
-  ChannelState channel_state_ MOJO_GUARDED_BY(mutex_);
   // |channel_| must be valid whenever it is non-null. Before |*channel_| gives
   // up its reference to this object, it must call |DetachFromChannel()|.
   // |local_id_| and |remote_id_| are valid if and only |channel_| is non-null.
diff --git a/mojo/edk/system/channel_manager.cc b/mojo/edk/system/channel_manager.cc
index a2e4bf9..097ffa2 100644
--- a/mojo/edk/system/channel_manager.cc
+++ b/mojo/edk/system/channel_manager.cc
@@ -87,6 +87,13 @@
   return dispatcher;
 }
 
+scoped_refptr<Channel> ChannelManager::CreateChannelWithoutBootstrapOnIOThread(
+    ChannelId channel_id,
+    embedder::ScopedPlatformHandle platform_handle) {
+  return CreateChannelOnIOThreadHelper(channel_id, platform_handle.Pass(),
+                                       nullptr);
+}
+
 scoped_refptr<MessagePipeDispatcher> ChannelManager::CreateChannel(
     ChannelId channel_id,
     embedder::ScopedPlatformHandle platform_handle,
@@ -163,19 +170,19 @@
   }
 }
 
-void ChannelManager::CreateChannelOnIOThreadHelper(
+scoped_refptr<Channel> ChannelManager::CreateChannelOnIOThreadHelper(
     ChannelId channel_id,
     embedder::ScopedPlatformHandle platform_handle,
     scoped_refptr<system::ChannelEndpoint> bootstrap_channel_endpoint) {
   DCHECK_NE(channel_id, kInvalidChannelId);
   DCHECK(platform_handle.is_valid());
-  DCHECK(bootstrap_channel_endpoint);
 
   // Create and initialize a |system::Channel|.
   scoped_refptr<system::Channel> channel =
       new system::Channel(platform_support_);
   channel->Init(system::RawChannel::Create(platform_handle.Pass()));
-  channel->SetBootstrapEndpoint(bootstrap_channel_endpoint);
+  if (bootstrap_channel_endpoint)
+    channel->SetBootstrapEndpoint(bootstrap_channel_endpoint);
 
   {
     MutexLocker locker(&mutex_);
@@ -183,6 +190,7 @@
     channels_[channel_id] = channel;
   }
   channel->SetChannelManager(this);
+  return channel;
 }
 
 void ChannelManager::CreateChannelHelper(
diff --git a/mojo/edk/system/channel_manager.h b/mojo/edk/system/channel_manager.h
index 014c1b3..1ff958d 100644
--- a/mojo/edk/system/channel_manager.h
+++ b/mojo/edk/system/channel_manager.h
@@ -72,6 +72,14 @@
       ChannelId channel_id,
       embedder::ScopedPlatformHandle platform_handle);
 
+  // Like |CreateChannelOnIOThread()|, but doesn't create a bootstrap message
+  // pipe. Returns the newly-created |Channel|.
+  // TODO(vtl): Maybe get rid of the others (and bootstrap message pipes in
+  // general).
+  scoped_refptr<Channel> CreateChannelWithoutBootstrapOnIOThread(
+      ChannelId channel_id,
+      embedder::ScopedPlatformHandle platform_handle);
+
   // Like |CreateChannelOnIOThread()|, but may be called from any thread. On
   // completion, will call |callback| (using |callback_thread_task_runner| if it
   // is non-null, else on the I/O thread). Note: This will always post a task to
@@ -116,8 +124,9 @@
       scoped_refptr<base::TaskRunner> callback_thread_task_runner);
 
   // Used by |CreateChannelOnIOThread()| and |CreateChannelHelper()|. Called on
-  // the I/O thread.
-  void CreateChannelOnIOThreadHelper(
+  // the I/O thread. |bootstrap_channel_endpoint| is optional and may be null.
+  // Returns the newly-created |Channel|.
+  scoped_refptr<Channel> CreateChannelOnIOThreadHelper(
       ChannelId channel_id,
       embedder::ScopedPlatformHandle platform_handle,
       scoped_refptr<system::ChannelEndpoint> bootstrap_channel_endpoint);
diff --git a/mojo/edk/system/channel_manager_unittest.cc b/mojo/edk/system/channel_manager_unittest.cc
index afa9b15..2d38b61 100644
--- a/mojo/edk/system/channel_manager_unittest.cc
+++ b/mojo/edk/system/channel_manager_unittest.cc
@@ -168,6 +168,9 @@
   EXPECT_EQ(MOJO_RESULT_OK, d->Close());
 }
 
+// TODO(vtl): Test |CreateChannelWithoutBootstrapOnIOThread()|. (This will
+// require additional functionality in |Channel|.)
+
 }  // namespace
 }  // namespace system
 }  // namespace mojo
diff --git a/mojo/edk/system/data_pipe_impl_unittest.cc b/mojo/edk/system/data_pipe_impl_unittest.cc
index 3b0470b..0bc7506 100644
--- a/mojo/edk/system/data_pipe_impl_unittest.cc
+++ b/mojo/edk/system/data_pipe_impl_unittest.cc
@@ -2394,6 +2394,67 @@
   this->ConsumerClose();
 }
 
+// Tests the behavior of writing, closing the producer, and then doing a
+// two-phase read of all the data.
+// Note: If this test fails/crashes flakily, this is almost certainly an
+// indication of a problem in the implementation and not the test.
+TYPED_TEST(DataPipeImplTest, WriteCloseProducerTwoPhaseReadAllData) {
+  const char kTestData[] = "hello world";
+  const uint32_t kTestDataSize = static_cast<uint32_t>(sizeof(kTestData));
+
+  const MojoCreateDataPipeOptions options = {
+      kSizeOfOptions,                           // |struct_size|.
+      MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_NONE,  // |flags|.
+      1u,                                       // |element_num_bytes|.
+      1000u                                     // |capacity_num_bytes|.
+  };
+  this->Create(options);
+  this->DoTransfer();
+
+  // Write some data, so we'll have something to read.
+  uint32_t num_bytes = kTestDataSize;
+  EXPECT_EQ(MOJO_RESULT_OK,
+            this->ProducerWriteData(UserPointer<const void>(kTestData),
+                                    MakeUserPointer(&num_bytes), false));
+  EXPECT_EQ(kTestDataSize, num_bytes);
+
+  // TODO(vtl): Hack: We can't currently wait for a specified amount of data to
+  // be available, so poll.
+  for (size_t i = 0; i < kMaxPoll; i++) {
+    num_bytes = 0u;
+    EXPECT_EQ(MOJO_RESULT_OK,
+              this->ConsumerQueryData(MakeUserPointer(&num_bytes)));
+    if (num_bytes >= kTestDataSize)
+      break;
+
+    test::Sleep(test::EpsilonDeadline());
+  }
+  EXPECT_EQ(kTestDataSize, num_bytes);
+
+  const void* read_buffer_ptr = nullptr;
+  num_bytes = 0u;
+  EXPECT_EQ(MOJO_RESULT_OK,
+            this->ConsumerBeginReadData(MakeUserPointer(&read_buffer_ptr),
+                                        MakeUserPointer(&num_bytes), false));
+  EXPECT_EQ(kTestDataSize, num_bytes);
+  EXPECT_EQ(0, memcmp(read_buffer_ptr, kTestData, kTestDataSize));
+
+  // Close the producer.
+  this->ProducerClose();
+
+  // Note: This tiny sleep is to allow/encourage a certain race. In particular,
+  // for the remote producer case in
+  // |RemoteProducerDataPipeImpl::MarkDataAsConsumed()| (caused by
+  // |ConsumerEndReadData()| below) we want |producer_open()| to be false but
+  // the call to |channel_endpoint_->EnqueueMessage()| to fail. (This race can
+  // occur without the sleep, but is much less likely.)
+  test::Sleep(10u);
+
+  EXPECT_EQ(MOJO_RESULT_OK, this->ConsumerEndReadData(num_bytes));
+
+  this->ConsumerClose();
+}
+
 }  // namespace
 }  // namespace system
 }  // namespace mojo
diff --git a/mojo/edk/system/ipc_support_unittest.cc b/mojo/edk/system/ipc_support_unittest.cc
index 823f6b9..695c4ec 100644
--- a/mojo/edk/system/ipc_support_unittest.cc
+++ b/mojo/edk/system/ipc_support_unittest.cc
@@ -11,6 +11,7 @@
 #include "base/command_line.h"
 #include "base/location.h"
 #include "base/logging.h"
+#include "base/memory/scoped_ptr.h"
 #include "base/synchronization/waitable_event.h"
 #include "base/test/test_io_thread.h"
 #include "base/test/test_timeouts.h"
@@ -37,6 +38,84 @@
 
 const char kConnectionIdFlag[] = "test-connection-id";
 
+// Tests writing a message (containing just data) to |write_mp| and then reading
+// it from |read_mp| (it should be the next message, i.e., there should be no
+// other messages already enqueued in that direction).
+void TestWriteReadMessage(scoped_refptr<MessagePipeDispatcher> write_mp,
+                          scoped_refptr<MessagePipeDispatcher> read_mp) {
+  // Set up waiting on the read end first (to avoid racing).
+  Waiter waiter;
+  waiter.Init();
+  ASSERT_EQ(
+      MOJO_RESULT_OK,
+      read_mp->AddAwakable(&waiter, MOJO_HANDLE_SIGNAL_READABLE, 0, nullptr));
+
+  // Write a message with just 'x' through the write end.
+  EXPECT_EQ(MOJO_RESULT_OK,
+            write_mp->WriteMessage(UserPointer<const void>("x"), 1, nullptr,
+                                   MOJO_WRITE_MESSAGE_FLAG_NONE));
+
+  // Wait for it to arrive.
+  EXPECT_EQ(MOJO_RESULT_OK, waiter.Wait(test::ActionDeadline(), nullptr));
+  read_mp->RemoveAwakable(&waiter, nullptr);
+
+  // Read the message from the read end.
+  char buffer[10] = {};
+  uint32_t buffer_size = static_cast<uint32_t>(sizeof(buffer));
+  EXPECT_EQ(MOJO_RESULT_OK,
+            read_mp->ReadMessage(UserPointer<void>(buffer),
+                                 MakeUserPointer(&buffer_size), 0, nullptr,
+                                 MOJO_READ_MESSAGE_FLAG_NONE));
+  EXPECT_EQ(1u, buffer_size);
+  EXPECT_EQ('x', buffer[0]);
+}
+
+// Writes a message pipe dispatcher (in a message) to |write_mp| and reads it
+// from |read_mp| (it should be the next message, i.e., there should be no other
+// other messages already enqueued in that direction).
+scoped_refptr<MessagePipeDispatcher> SendMessagePipeDispatcher(
+    scoped_refptr<MessagePipeDispatcher> write_mp,
+    scoped_refptr<MessagePipeDispatcher> read_mp,
+    scoped_refptr<MessagePipeDispatcher> mp_to_send) {
+  CHECK_NE(mp_to_send, write_mp);
+  CHECK_NE(mp_to_send, read_mp);
+
+  // Set up waiting on the read end first (to avoid racing).
+  Waiter waiter;
+  waiter.Init();
+  CHECK_EQ(
+      read_mp->AddAwakable(&waiter, MOJO_HANDLE_SIGNAL_READABLE, 0, nullptr),
+      MOJO_RESULT_OK);
+
+  // Write a message with just |mp_to_send| through the write end.
+  DispatcherTransport transport(
+      test::DispatcherTryStartTransport(mp_to_send.get()));
+  CHECK(transport.is_valid());
+  std::vector<DispatcherTransport> transports;
+  transports.push_back(transport);
+  CHECK_EQ(write_mp->WriteMessage(NullUserPointer(), 0, &transports,
+                                  MOJO_WRITE_MESSAGE_FLAG_NONE),
+           MOJO_RESULT_OK);
+  transport.End();
+
+  // Wait for it to arrive.
+  CHECK_EQ(waiter.Wait(test::ActionDeadline(), nullptr), MOJO_RESULT_OK);
+  read_mp->RemoveAwakable(&waiter, nullptr);
+
+  // Read the message from the read end.
+  DispatcherVector dispatchers;
+  uint32_t num_dispatchers = 10;
+  CHECK_EQ(
+      read_mp->ReadMessage(NullUserPointer(), NullUserPointer(), &dispatchers,
+                           &num_dispatchers, MOJO_READ_MESSAGE_FLAG_NONE),
+      MOJO_RESULT_OK);
+  CHECK_EQ(dispatchers.size(), 1u);
+  CHECK_EQ(num_dispatchers, 1u);
+  CHECK_EQ(dispatchers[0]->GetType(), Dispatcher::Type::MESSAGE_PIPE);
+  return scoped_refptr<MessagePipeDispatcher>(
+      static_cast<MessagePipeDispatcher*>(dispatchers[0].get()));
+}
+
 class TestMasterProcessDelegate : public embedder::MasterProcessDelegate {
  public:
   TestMasterProcessDelegate()
@@ -203,12 +282,95 @@
   MOJO_DISALLOW_COPY_AND_ASSIGN(TestSlave);
 };
 
+// Encapsulates both the master and slave sides for each slave.
+class TestSlaveSetup {
+ public:
+  TestSlaveSetup(embedder::SimplePlatformSupport* platform_support,
+                 base::TestIOThread* test_io_thread,
+                 TestMasterProcessDelegate* master_process_delegate,
+                 IPCSupport* master_ipc_support)
+      : platform_support_(platform_support),
+        test_io_thread_(test_io_thread),
+        master_process_delegate_(master_process_delegate),
+        master_ipc_support_(master_ipc_support) {}
+  ~TestSlaveSetup() {
+    CHECK(!slave_connection_);
+    CHECK(!slave_);
+  }
+
+  void Init() {
+    // Set up the master side entirely before the slave side, since this
+    // simulates what's likely to happen "in reality" more closely.
+    slave_connection_.reset(
+        new TestSlaveConnection(test_io_thread_, master_ipc_support_));
+    master_mp_ = slave_connection_->ConnectToSlave();
+
+    slave_.reset(new TestSlave(platform_support_, test_io_thread_,
+                               slave_connection_->PassSlavePlatformHandle()));
+    slave_mp_ = slave_->ConnectToMaster(slave_connection_->connection_id());
+  }
+
+  void TestConnection() {
+    TestWriteReadMessage(master_mp_, slave_mp_);
+    TestWriteReadMessage(slave_mp_, master_mp_);
+  }
+
+  scoped_refptr<MessagePipeDispatcher> PassMasterMessagePipe() {
+    return master_mp_.Pass();
+  }
+
+  scoped_refptr<MessagePipeDispatcher> PassSlaveMessagePipe() {
+    return slave_mp_.Pass();
+  }
+
+  void Shutdown() {
+    if (master_mp_) {
+      master_mp_->Close();
+      master_mp_ = nullptr;
+    }
+    if (slave_mp_) {
+      slave_mp_->Close();
+      slave_mp_ = nullptr;
+    }
+
+    slave_->ShutdownChannelToMaster();
+    slave_->ShutdownIPCSupport();
+    EXPECT_TRUE(master_process_delegate_->TryWaitForOnSlaveDisconnect());
+    slave_connection_->ShutdownChannelToSlave();
+
+    slave_.reset();
+    slave_connection_.reset();
+  }
+
+  TestSlaveConnection* slave_connection() { return slave_connection_.get(); }
+  // Note: To close the master message pipe, use |PassMasterMessagePipe()|.
+  MessagePipeDispatcher* master_mp() { return master_mp_.get(); }
+
+  TestSlave* slave() { return slave_.get(); }
+  // Note: To close the slave message pipe, use |PassSlaveMessagePipe()|.
+  MessagePipeDispatcher* slave_mp() { return slave_mp_.get(); }
+
+ private:
+  embedder::SimplePlatformSupport* const platform_support_;
+  base::TestIOThread* const test_io_thread_;
+  TestMasterProcessDelegate* const master_process_delegate_;
+  IPCSupport* const master_ipc_support_;
+
+  scoped_ptr<TestSlaveConnection> slave_connection_;
+  scoped_refptr<MessagePipeDispatcher> master_mp_;
+
+  scoped_ptr<TestSlave> slave_;
+  scoped_refptr<MessagePipeDispatcher> slave_mp_;
+
+  MOJO_DISALLOW_COPY_AND_ASSIGN(TestSlaveSetup);
+};
+
 class IPCSupportTest : public testing::Test {
  public:
   // Note: Run master process delegate methods on the I/O thread.
   IPCSupportTest()
       : test_io_thread_(base::TestIOThread::kAutoStart),
-        master_ipc_support_(&platform_support(),
+        master_ipc_support_(&platform_support_,
                             embedder::ProcessType::MASTER,
                             test_io_thread_.task_runner(),
                             &master_process_delegate_,
@@ -216,6 +378,14 @@
                             embedder::ScopedPlatformHandle()) {}
   ~IPCSupportTest() override {}
 
+  scoped_ptr<TestSlaveSetup> SetupSlave() {
+    scoped_ptr<TestSlaveSetup> s(
+        new TestSlaveSetup(&platform_support_, &test_io_thread_,
+                           &master_process_delegate_, &master_ipc_support_));
+    s->Init();
+    return s;
+  }
+
   void ShutdownMasterIPCSupport() {
     test_io_thread_.PostTaskAndWait(
         FROM_HERE, base::Bind(&IPCSupport::ShutdownOnIOThread,
@@ -242,38 +412,6 @@
   MOJO_DISALLOW_COPY_AND_ASSIGN(IPCSupportTest);
 };
 
-// Tests writing a message (containing just data) to |write_mp| and then reading
-// it from |read_mp| (it should be the next message, i.e., there should be no
-// other messages already enqueued in that direction).
-void TestWriteReadMessage(scoped_refptr<MessagePipeDispatcher> write_mp,
-                          scoped_refptr<MessagePipeDispatcher> read_mp) {
-  // Set up waiting on the read end first (to avoid racing).
-  Waiter waiter;
-  waiter.Init();
-  ASSERT_EQ(
-      MOJO_RESULT_OK,
-      read_mp->AddAwakable(&waiter, MOJO_HANDLE_SIGNAL_READABLE, 0, nullptr));
-
-  // Write a message with just 'x' through the write end.
-  EXPECT_EQ(MOJO_RESULT_OK,
-            write_mp->WriteMessage(UserPointer<const void>("x"), 1, nullptr,
-                                   MOJO_WRITE_MESSAGE_FLAG_NONE));
-
-  // Wait for it to arrive.
-  EXPECT_EQ(MOJO_RESULT_OK, waiter.Wait(test::ActionDeadline(), nullptr));
-  read_mp->RemoveAwakable(&waiter, nullptr);
-
-  // Read the message from the read end.
-  char buffer[10] = {};
-  uint32_t buffer_size = static_cast<uint32_t>(sizeof(buffer));
-  EXPECT_EQ(MOJO_RESULT_OK,
-            read_mp->ReadMessage(UserPointer<void>(buffer),
-                                 MakeUserPointer(&buffer_size), 0, nullptr,
-                                 MOJO_READ_MESSAGE_FLAG_NONE));
-  EXPECT_EQ(1u, buffer_size);
-  EXPECT_EQ('x', buffer[0]);
-}
-
 using MessagePipeDispatcherPair =
     std::pair<scoped_refptr<MessagePipeDispatcher>,
               scoped_refptr<MessagePipeDispatcher>>;
@@ -289,83 +427,23 @@
   return rv;
 }
 
-// Writes a message pipe dispatcher (in a message) to |write_mp| and reads it
-// from |read_mp| (it should be the next message, i.e., there should be no other
-// other messages already enqueued in that direction).
-scoped_refptr<MessagePipeDispatcher> SendMessagePipeDispatcher(
-    scoped_refptr<MessagePipeDispatcher> write_mp,
-    scoped_refptr<MessagePipeDispatcher> read_mp,
-    scoped_refptr<MessagePipeDispatcher> mp_to_send) {
-  CHECK_NE(mp_to_send, write_mp);
-  CHECK_NE(mp_to_send, read_mp);
-
-  // Set up waiting on the read end first (to avoid racing).
-  Waiter waiter;
-  waiter.Init();
-  CHECK_EQ(
-      read_mp->AddAwakable(&waiter, MOJO_HANDLE_SIGNAL_READABLE, 0, nullptr),
-      MOJO_RESULT_OK);
-
-  // Write a message with just |mp_to_send| through the write end.
-  DispatcherTransport transport(
-      test::DispatcherTryStartTransport(mp_to_send.get()));
-  CHECK(transport.is_valid());
-  std::vector<DispatcherTransport> transports;
-  transports.push_back(transport);
-  CHECK_EQ(write_mp->WriteMessage(NullUserPointer(), 0, &transports,
-                                  MOJO_WRITE_MESSAGE_FLAG_NONE),
-           MOJO_RESULT_OK);
-  transport.End();
-
-  // Wait for it to arrive.
-  CHECK_EQ(waiter.Wait(test::ActionDeadline(), nullptr), MOJO_RESULT_OK);
-  read_mp->RemoveAwakable(&waiter, nullptr);
-
-  // Read the message from the read end.
-  DispatcherVector dispatchers;
-  uint32_t num_dispatchers = 10;
-  CHECK_EQ(
-      read_mp->ReadMessage(NullUserPointer(), NullUserPointer(), &dispatchers,
-                           &num_dispatchers, MOJO_READ_MESSAGE_FLAG_NONE),
-      MOJO_RESULT_OK);
-  CHECK_EQ(dispatchers.size(), 1u);
-  CHECK_EQ(num_dispatchers, 1u);
-  CHECK_EQ(dispatchers[0]->GetType(), Dispatcher::Type::MESSAGE_PIPE);
-  return scoped_refptr<MessagePipeDispatcher>(
-      static_cast<MessagePipeDispatcher*>(dispatchers[0].get()));
-}
-
 TEST_F(IPCSupportTest, MasterSlave) {
-  TestSlaveConnection slave_connection(&test_io_thread(),
-                                       &master_ipc_support());
-  scoped_refptr<MessagePipeDispatcher> master_mp =
-      slave_connection.ConnectToSlave();
+  scoped_ptr<TestSlaveSetup> s(SetupSlave());
 
-  TestSlave slave(&platform_support(), &test_io_thread(),
-                  slave_connection.PassSlavePlatformHandle());
-  scoped_refptr<MessagePipeDispatcher> slave_mp =
-      slave.ConnectToMaster(slave_connection.connection_id());
-
-  // Test that we can send a message from the master to the slave.
-  TestWriteReadMessage(master_mp, slave_mp);
-  // And vice versa.
-  TestWriteReadMessage(slave_mp, master_mp);
+  s->TestConnection();
 
   // Don't need the message pipe anymore.
-  master_mp->Close();
-  slave_mp->Close();
+  s->PassMasterMessagePipe()->Close();
+  s->PassSlaveMessagePipe()->Close();
 
   // A message was sent through the message pipe, |Channel|s must have been
   // established on both sides. The events have thus almost certainly been
   // signalled, but we'll wait just to be sure.
-  slave_connection.WaitForChannelToSlave();
-  slave.WaitForChannelToMaster();
+  s->slave_connection()->WaitForChannelToSlave();
+  s->slave()->WaitForChannelToMaster();
 
-  slave.ShutdownChannelToMaster();
-  slave.ShutdownIPCSupport();
-  EXPECT_TRUE(master_process_delegate().TryWaitForOnSlaveDisconnect());
+  s->Shutdown();
 
-  slave_connection.ShutdownChannelToSlave();
   ShutdownMasterIPCSupport();
 }
 
@@ -378,47 +456,28 @@
 // TODO(vtl): In this scenario, we can't test the intermediary (the master)
 // going away.
 TEST_F(IPCSupportTest, ConnectTwoSlaves) {
-  TestSlaveConnection slave1_connection(&test_io_thread(),
-                                        &master_ipc_support());
-  scoped_refptr<MessagePipeDispatcher> master_mp1 =
-      slave1_connection.ConnectToSlave();
-
-  TestSlave slave1(&platform_support(), &test_io_thread(),
-                   slave1_connection.PassSlavePlatformHandle());
-  scoped_refptr<MessagePipeDispatcher> slave1_mp =
-      slave1.ConnectToMaster(slave1_connection.connection_id());
-
-  TestSlaveConnection slave2_connection(&test_io_thread(),
-                                        &master_ipc_support());
-  scoped_refptr<MessagePipeDispatcher> master_mp2 =
-      slave2_connection.ConnectToSlave();
-
-  TestSlave slave2(&platform_support(), &test_io_thread(),
-                   slave2_connection.PassSlavePlatformHandle());
-  scoped_refptr<MessagePipeDispatcher> slave2_mp =
-      slave2.ConnectToMaster(slave2_connection.connection_id());
-
-  TestWriteReadMessage(master_mp1, slave1_mp);
-  TestWriteReadMessage(slave1_mp, master_mp1);
-  TestWriteReadMessage(master_mp2, slave2_mp);
-  TestWriteReadMessage(slave2_mp, master_mp2);
+  scoped_ptr<TestSlaveSetup> s1(SetupSlave());
+  scoped_ptr<TestSlaveSetup> s2(SetupSlave());
+  s1->TestConnection();
+  s2->TestConnection();
 
   // Make a message pipe (logically "in" the master) and send one end to each
   // slave.
-  MessagePipeDispatcherPair send_mps = CreateMessagePipe();
+  MessagePipeDispatcherPair send_mp = CreateMessagePipe();
   scoped_refptr<MessagePipeDispatcher> slave1_received_mp =
-      SendMessagePipeDispatcher(master_mp1, slave1_mp, send_mps.first);
+      SendMessagePipeDispatcher(s1->master_mp(), s1->slave_mp(), send_mp.first);
   scoped_refptr<MessagePipeDispatcher> slave2_received_mp =
-      SendMessagePipeDispatcher(master_mp2, slave2_mp, send_mps.second);
+      SendMessagePipeDispatcher(s2->master_mp(), s2->slave_mp(),
+                                send_mp.second);
 
   // These should be connected.
   TestWriteReadMessage(slave1_received_mp, slave2_received_mp);
   TestWriteReadMessage(slave2_received_mp, slave1_received_mp);
 
-  master_mp1->Close();
-  master_mp2->Close();
-  slave1_mp->Close();
-  slave2_mp->Close();
+  s1->PassMasterMessagePipe()->Close();
+  s2->PassMasterMessagePipe()->Close();
+  s1->PassSlaveMessagePipe()->Close();
+  s2->PassSlaveMessagePipe()->Close();
 
   // They should still be connected.
   TestWriteReadMessage(slave1_received_mp, slave2_received_mp);
@@ -427,15 +486,95 @@
   slave1_received_mp->Close();
   slave2_received_mp->Close();
 
-  slave1.ShutdownChannelToMaster();
-  slave1.ShutdownIPCSupport();
-  EXPECT_TRUE(master_process_delegate().TryWaitForOnSlaveDisconnect());
-  slave1_connection.ShutdownChannelToSlave();
+  s1->Shutdown();
+  s2->Shutdown();
 
-  slave2.ShutdownChannelToMaster();
-  slave2.ShutdownIPCSupport();
-  EXPECT_TRUE(master_process_delegate().TryWaitForOnSlaveDisconnect());
-  slave2_connection.ShutdownChannelToSlave();
+  ShutdownMasterIPCSupport();
+}
+
+// Like |ConnectTwoSlaves|, but does it twice, to test reusing a connection.
+TEST_F(IPCSupportTest, ConnectTwoSlavesTwice) {
+  scoped_ptr<TestSlaveSetup> s1(SetupSlave());
+  scoped_ptr<TestSlaveSetup> s2(SetupSlave());
+  s1->TestConnection();
+  s2->TestConnection();
+
+  MessagePipeDispatcherPair send_mp1 = CreateMessagePipe();
+  scoped_refptr<MessagePipeDispatcher> slave1_received_mp1 =
+      SendMessagePipeDispatcher(s1->master_mp(), s1->slave_mp(),
+                                send_mp1.first);
+  scoped_refptr<MessagePipeDispatcher> slave2_received_mp1 =
+      SendMessagePipeDispatcher(s2->master_mp(), s2->slave_mp(),
+                                send_mp1.second);
+
+  MessagePipeDispatcherPair send_mp2 = CreateMessagePipe();
+  scoped_refptr<MessagePipeDispatcher> slave1_received_mp2 =
+      SendMessagePipeDispatcher(s1->master_mp(), s1->slave_mp(),
+                                send_mp2.first);
+  scoped_refptr<MessagePipeDispatcher> slave2_received_mp2 =
+      SendMessagePipeDispatcher(s2->master_mp(), s2->slave_mp(),
+                                send_mp2.second);
+
+  s1->PassMasterMessagePipe()->Close();
+  s2->PassMasterMessagePipe()->Close();
+  s1->PassSlaveMessagePipe()->Close();
+  s2->PassSlaveMessagePipe()->Close();
+
+  TestWriteReadMessage(slave1_received_mp1, slave2_received_mp1);
+  TestWriteReadMessage(slave2_received_mp1, slave1_received_mp1);
+
+  TestWriteReadMessage(slave1_received_mp2, slave2_received_mp2);
+  TestWriteReadMessage(slave2_received_mp2, slave1_received_mp2);
+
+  slave1_received_mp1->Close();
+  slave2_received_mp1->Close();
+
+  TestWriteReadMessage(slave1_received_mp2, slave2_received_mp2);
+  TestWriteReadMessage(slave2_received_mp2, slave1_received_mp2);
+
+  slave1_received_mp2->Close();
+  slave2_received_mp2->Close();
+
+  s1->Shutdown();
+  s2->Shutdown();
+
+  ShutdownMasterIPCSupport();
+}
+
+// Creates a message pipe in the slave, which sends both ends (in separate
+// messages) to the master.
+TEST_F(IPCSupportTest, SlavePassBackToMaster) {
+  scoped_ptr<TestSlaveSetup> s(SetupSlave());
+
+  s->TestConnection();
+
+  // Make a message pipe (logically "in" the slave) and send both ends
+  // (separately) to the master.
+  MessagePipeDispatcherPair send_mp = CreateMessagePipe();
+  scoped_refptr<MessagePipeDispatcher> received_mp1 =
+      SendMessagePipeDispatcher(s->slave_mp(), s->master_mp(), send_mp.first);
+
+  TestWriteReadMessage(received_mp1, send_mp.second);
+  TestWriteReadMessage(send_mp.second, received_mp1);
+
+  scoped_refptr<MessagePipeDispatcher> received_mp2 =
+      SendMessagePipeDispatcher(s->slave_mp(), s->master_mp(), send_mp.second);
+
+  s->PassMasterMessagePipe()->Close();
+  s->PassSlaveMessagePipe()->Close();
+
+  TestWriteReadMessage(received_mp1, received_mp2);
+  TestWriteReadMessage(received_mp2, received_mp1);
+
+  s->Shutdown();
+
+  // These should still be connected.
+  // TODO(vtl): This is not yet implemented, thus will fail here!
+  // TestWriteReadMessage(received_mp1, received_mp2);
+  // TestWriteReadMessage(received_mp2, received_mp1);
+
+  received_mp1->Close();
+  received_mp2->Close();
 
   ShutdownMasterIPCSupport();
 }
diff --git a/mojo/edk/system/message_pipe_dispatcher_unittest.cc b/mojo/edk/system/message_pipe_dispatcher_unittest.cc
index f93cd90..aebc439 100644
--- a/mojo/edk/system/message_pipe_dispatcher_unittest.cc
+++ b/mojo/edk/system/message_pipe_dispatcher_unittest.cc
@@ -15,7 +15,6 @@
 
 #include "base/memory/ref_counted.h"
 #include "base/memory/scoped_vector.h"
-#include "base/rand_util.h"
 #include "base/threading/simple_thread.h"
 #include "mojo/edk/system/message_pipe.h"
 #include "mojo/edk/system/test_utils.h"
@@ -504,12 +503,12 @@
       buffer[i] = static_cast<unsigned char>(i);
 
     // Number of messages to write.
-    *messages_written_ = static_cast<size_t>(base::RandInt(1000, 6000));
+    *messages_written_ = static_cast<size_t>(test::RandomInt(1000, 6000));
 
     // Write messages.
     for (size_t i = 0; i < *messages_written_; i++) {
       uint32_t bytes_to_write = static_cast<uint32_t>(
-          base::RandInt(1, static_cast<int>(kMaxMessageSize)));
+          test::RandomInt(1, static_cast<int>(kMaxMessageSize)));
       EXPECT_EQ(MOJO_RESULT_OK,
                 write_dispatcher_->WriteMessage(UserPointer<const void>(buffer),
                                                 bytes_to_write, nullptr,
diff --git a/mojo/edk/system/raw_channel_unittest.cc b/mojo/edk/system/raw_channel_unittest.cc
index a901791..2fa3f7b 100644
--- a/mojo/edk/system/raw_channel_unittest.cc
+++ b/mojo/edk/system/raw_channel_unittest.cc
@@ -18,7 +18,6 @@
 #include "base/logging.h"
 #include "base/memory/scoped_ptr.h"
 #include "base/memory/scoped_vector.h"
-#include "base/rand_util.h"
 #include "base/synchronization/waitable_event.h"
 #include "base/test/test_io_thread.h"
 #include "base/threading/simple_thread.h"
@@ -325,7 +324,7 @@
 
     while (left_to_write_-- > 0) {
       EXPECT_TRUE(raw_channel_->WriteMessage(MakeTestMessage(
-          static_cast<uint32_t>(base::RandInt(1, kMaxRandomMessageSize)))));
+          static_cast<uint32_t>(test::RandomInt(1, kMaxRandomMessageSize)))));
     }
   }
 
diff --git a/mojo/edk/system/remote_producer_data_pipe_impl.cc b/mojo/edk/system/remote_producer_data_pipe_impl.cc
index 8d7fa26..833c505 100644
--- a/mojo/edk/system/remote_producer_data_pipe_impl.cc
+++ b/mojo/edk/system/remote_producer_data_pipe_impl.cc
@@ -348,15 +348,20 @@
 
 bool RemoteProducerDataPipeImpl::OnReadMessage(unsigned /*port*/,
                                                MessageInTransit* message) {
-  // Always take ownership of the message. (This means that we should always
-  // return true.)
-  scoped_ptr<MessageInTransit> msg(message);
-
   if (!producer_open()) {
+    // This will happen only on the rare occasion that the call to
+    // |OnReadMessage()| is racing with us calling
+    // |ChannelEndpoint::ReplaceClient()|, in which case we reject the message,
+    // and the |ChannelEndpoint| can retry (calling the new client's
+    // |OnReadMessage()|).
     DCHECK(!channel_endpoint_);
-    return true;
+    return false;
   }
 
+  // Otherwise, we take ownership of the message. (This means that we should
+  // always return true below.)
+  scoped_ptr<MessageInTransit> msg(message);
+
   if (!ValidateIncomingMessage(element_num_bytes(), capacity_num_bytes(),
                                current_num_bytes_, msg.get())) {
     Disconnect();
@@ -462,12 +467,8 @@
   // buffer around. Currently, we won't free it even if it empties later. (We
   // could do this -- requiring a check on every read -- but that seems to be
   // optimizing for the uncommon case.)
-  if (!consumer_open() || !current_num_bytes_) {
-    // Note: There can only be a two-phase *read* (by the consumer) if we still
-    // have data.
-    DCHECK(!consumer_in_two_phase_read());
+  if (!consumer_open() || !current_num_bytes_)
     DestroyBuffer();
-  }
 }
 
 }  // namespace system
diff --git a/mojo/edk/system/simple_dispatcher_unittest.cc b/mojo/edk/system/simple_dispatcher_unittest.cc
index 051e108..9e1bd7b 100644
--- a/mojo/edk/system/simple_dispatcher_unittest.cc
+++ b/mojo/edk/system/simple_dispatcher_unittest.cc
@@ -12,7 +12,6 @@
 #include "base/logging.h"
 #include "base/memory/ref_counted.h"
 #include "base/memory/scoped_vector.h"
-#include "base/synchronization/lock.h"
 #include "mojo/edk/system/test_utils.h"
 #include "mojo/edk/system/waiter.h"
 #include "mojo/edk/system/waiter_test_utils.h"
diff --git a/mojo/edk/system/test_utils.cc b/mojo/edk/system/test_utils.cc
index 8bd16eb..823bcf4 100644
--- a/mojo/edk/system/test_utils.cc
+++ b/mojo/edk/system/test_utils.cc
@@ -4,6 +4,9 @@
 
 #include "mojo/edk/system/test_utils.h"
 
+#include <stdint.h>
+#include <stdlib.h>
+
 #include <limits>
 
 #include "base/logging.h"
@@ -52,6 +55,23 @@
       base::TimeDelta::FromMicroseconds(static_cast<int64_t>(deadline)));
 }
 
+// TODO(vtl): Replace all of this implementation with suitable use of C++11
+// <random> when we can.
+int RandomInt(int min, int max) {
+  DCHECK_LE(min, max);
+  DCHECK_LE(static_cast<int64_t>(max) - min, RAND_MAX);
+  DCHECK_LT(static_cast<int64_t>(max) - min, std::numeric_limits<int>::max());
+
+  // This is in-range for an |int| due to the above.
+  int range = max - min + 1;
+  int max_valid = (RAND_MAX / range) * range - 1;
+  int value;
+  do {
+    value = rand();
+  } while (value > max_valid);
+  return min + (value % range);
+}
+
 Stopwatch::Stopwatch() {
 }
 
diff --git a/mojo/edk/system/test_utils.h b/mojo/edk/system/test_utils.h
index 144e07b..59f9dd5 100644
--- a/mojo/edk/system/test_utils.h
+++ b/mojo/edk/system/test_utils.h
@@ -13,6 +13,8 @@
 namespace system {
 namespace test {
 
+// Deadlines/timeouts and sleeping ---------------------------------------------
+
 MojoDeadline DeadlineFromMilliseconds(unsigned milliseconds);
 
 // A timeout smaller than |TestTimeouts::tiny_timeout()|, as a |MojoDeadline|.
@@ -32,6 +34,13 @@
 // Sleeps for at least the specified duration.
 void Sleep(MojoDeadline deadline);
 
+// Pseudorandom numbers for testing --------------------------------------------
+
+// Returns a (uniformly) (pseudo)random integer in the interval [min, max].
+// Currently, |max - min| must be at most |RAND_MAX| and must also be (strictly)
+// less than |INT_MAX|.
+int RandomInt(int min, int max);
+
 // Stopwatch -------------------------------------------------------------------
 
 // A simple "stopwatch" for measuring time elapsed from a given starting point.
diff --git a/mojo/edk/system/test_utils_unittest.cc b/mojo/edk/system/test_utils_unittest.cc
new file mode 100644
index 0000000..5a3eda5
--- /dev/null
+++ b/mojo/edk/system/test_utils_unittest.cc
@@ -0,0 +1,53 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "mojo/edk/system/test_utils.h"
+
+#include <limits>
+
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace mojo {
+namespace system {
+namespace test {
+namespace {
+
+TEST(TestUtilsTest, RandomInt) {
+  static const int kMin = -3;
+  static const int kMax = 6;
+  static const unsigned kNumBuckets = kMax - kMin + 1;
+  unsigned buckets[kNumBuckets];
+
+  static const unsigned kIterations = 10000;
+  for (unsigned i = 0; i < kIterations; i++) {
+    int value = RandomInt(kMin, kMax);
+    ASSERT_GE(value, kMin);
+    ASSERT_LE(value, kMax);
+    buckets[value - kMin]++;
+  }
+
+  for (unsigned i = 0; i < kNumBuckets; i++) {
+    // The odds that a value in any bucket is less than the expected value
+    // should be very  small (if |kIterations| is sufficiently large compared to
+    // |kNumBuckets|).
+    // TODO(vtl): Actually calculate these odds, and maybe raise the proportion
+    // to something (much) larger than "half".
+    EXPECT_GE(buckets[i], kIterations / kNumBuckets / 2);
+  }
+}
+
+TEST(TestUtilsTest, RandomIntSameValues) {
+  static const int kIntMin = std::numeric_limits<int>::min();
+  EXPECT_EQ(kIntMin, RandomInt(kIntMin, kIntMin));
+
+  static const int kIntMax = std::numeric_limits<int>::max();
+  EXPECT_EQ(kIntMax, RandomInt(kIntMax, kIntMax));
+
+  EXPECT_EQ(0, RandomInt(0, 0));
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace system
+}  // namespace mojo
diff --git a/mojo/edk/system/unique_identifier.cc b/mojo/edk/system/unique_identifier.cc
index 6e036c8..984fb52 100644
--- a/mojo/edk/system/unique_identifier.cc
+++ b/mojo/edk/system/unique_identifier.cc
@@ -4,16 +4,25 @@
 
 #include "mojo/edk/system/unique_identifier.h"
 
-#include <stdint.h>
-
-#include <vector>
-
-#include "base/strings/string_number_conversions.h"
 #include "mojo/edk/embedder/platform_support.h"
 
 namespace mojo {
 namespace system {
 
+namespace {
+
+bool CapitalizedHexDigitToNumber(char c, unsigned char* number) {
+  if (c >= '0' && c <= '9')
+    *number = static_cast<unsigned char>(c - '0');
+  else if (c >= 'A' && c <= 'F')
+    *number = static_cast<unsigned char>(c - 'A' + 10);
+  else
+    return false;
+  return true;
+}
+
+}  // namespace
+
 // static
 UniqueIdentifier UniqueIdentifier::Generate(
     embedder::PlatformSupport* platform_support) {
@@ -25,20 +34,39 @@
 // static
 UniqueIdentifier UniqueIdentifier::FromString(const std::string& s,
                                               bool* success) {
-  UniqueIdentifier rv;
-  std::vector<uint8_t> bytes;
-  if (base::HexStringToBytes(s, &bytes) && bytes.size() == sizeof(rv.data_)) {
-    memcpy(rv.data_, &bytes[0], sizeof(rv.data_));
-    *success = true;
-  } else {
+  if (s.size() != 2 * sizeof(UniqueIdentifier::data_)) {
     *success = false;
+    return UniqueIdentifier();
   }
+
+  UniqueIdentifier rv;
+  for (size_t i = 0; i < sizeof(rv.data_); i++) {
+    unsigned char high_digit;
+    unsigned char low_digit;
+    // Note: |ToString()| always produces capitalized hex digits, so we should
+    // never get 'a' through 'f'.
+    if (!CapitalizedHexDigitToNumber(s[2 * i], &high_digit) ||
+        !CapitalizedHexDigitToNumber(s[2 * i + 1], &low_digit)) {
+      *success = false;
+      return UniqueIdentifier();
+    }
+    rv.data_[i] = (high_digit << 4) | low_digit;
+  }
+
+  *success = true;
   return rv;
 }
 
 std::string UniqueIdentifier::ToString() const {
+  // Currently, we encode as hexadecimal (using capitalized digits).
   // TODO(vtl): Maybe we should base-64 encode instead?
-  return base::HexEncode(data_, sizeof(data_));
+  static const char kHexDigits[] = "0123456789ABCDEF";
+  std::string rv(sizeof(data_) * 2, '\0');
+  for (size_t i = 0; i < sizeof(data_); i++) {
+    rv[2 * i] = kHexDigits[data_[i] >> 4];
+    rv[2 * i + 1] = kHexDigits[data_[i] & 0xf];
+  }
+  return rv;
 }
 
 }  // namespace system
diff --git a/mojo/edk/system/unique_identifier.h b/mojo/edk/system/unique_identifier.h
index 7db5e38..52ca57d 100644
--- a/mojo/edk/system/unique_identifier.h
+++ b/mojo/edk/system/unique_identifier.h
@@ -74,7 +74,7 @@
 
   explicit UniqueIdentifier() {}
 
-  char data_[16];
+  unsigned char data_[16];
 
   // Copying and assignment allowed.
 };
diff --git a/mojo/edk/system/unique_identifier_unittest.cc b/mojo/edk/system/unique_identifier_unittest.cc
index 1522446..1914af2 100644
--- a/mojo/edk/system/unique_identifier_unittest.cc
+++ b/mojo/edk/system/unique_identifier_unittest.cc
@@ -93,19 +93,23 @@
   // encoding. So first check something that we know should succeed, to roughly
   // confirm our knowledge.
   success = false;
-  UniqueIdentifier::FromString("0123456789abcdef0123456789ABCDEF", &success);
+  UniqueIdentifier::FromString("0123456789ABCDEF0123456789ABCDEF", &success);
   EXPECT_TRUE(success);
 
   success = true;
+  UniqueIdentifier::FromString("0123456789abcdef0123456789abcdef", &success);
+  EXPECT_FALSE(success);
+
+  success = true;
   UniqueIdentifier::FromString("!@#$%^&*()_+-=/\\,.<>[]{};':\"|", &success);
   EXPECT_FALSE(success);
 
   success = true;
-  UniqueIdentifier::FromString("0123456789abcdef0123456789ABCDE", &success);
+  UniqueIdentifier::FromString("0123456789ABCDEF0123456789ABCDE", &success);
   EXPECT_FALSE(success);
 
   success = true;
-  UniqueIdentifier::FromString("0123456789abcdef0123456789ABCD", &success);
+  UniqueIdentifier::FromString("0123456789ABCDEF0123456789ABCD", &success);
   EXPECT_FALSE(success);
 }
 
diff --git a/mojo/environment/BUILD.gn b/mojo/environment/BUILD.gn
index 5371935..5c7a9f0 100644
--- a/mojo/environment/BUILD.gn
+++ b/mojo/environment/BUILD.gn
@@ -3,8 +3,6 @@
 # found in the LICENSE file.
 
 source_set("chromium") {
-  output_name = "mojo_environment_chromium"
-
   sources = [
     "default_async_waiter.cc",
     "default_async_waiter.h",
@@ -27,6 +25,7 @@
     "//base",
     "//base/third_party/dynamic_annotations",
     "//mojo/common",
+    "//mojo/message_pump",
     "//mojo/public/c/environment",
     "//mojo/public/cpp/bindings:callback",
     "//mojo/public/cpp/environment",
diff --git a/mojo/environment/default_async_waiter.cc b/mojo/environment/default_async_waiter.cc
index 863cfe3..014e5c1 100644
--- a/mojo/environment/default_async_waiter.cc
+++ b/mojo/environment/default_async_waiter.cc
@@ -5,7 +5,7 @@
 #include "mojo/environment/default_async_waiter.h"
 
 #include "base/bind.h"
-#include "mojo/common/handle_watcher.h"
+#include "mojo/message_pump/handle_watcher.h"
 #include "mojo/public/c/environment/async_waiter.h"
 
 namespace mojo {
diff --git a/mojo/gles2/BUILD.gn b/mojo/gles2/BUILD.gn
index 92b2375..196ee6e 100644
--- a/mojo/gles2/BUILD.gn
+++ b/mojo/gles2/BUILD.gn
@@ -12,15 +12,38 @@
   defines = [ "GLES2_USE_MOJO" ]
 }
 
-source_set("gles2") {
+source_set("control_thunks") {
   sources = [
     "command_buffer_client_impl.cc",
     "command_buffer_client_impl.h",
-    "gles2_impl.cc",
+    "control_thunks_impl.cc",
+    "control_thunks_impl.h",
     "gles2_context.cc",
     "gles2_context.h",
   ]
 
+  deps = [
+    "//base",
+    "//mojo/public/c/system",
+    "//gpu/command_buffer/client",
+    "//gpu/command_buffer/client:gles2_cmd_helper",
+    "//gpu/command_buffer/client:gles2_implementation",
+    "//gpu/command_buffer/common",
+    "//mojo/public/c/gles2:headers",
+    "//mojo/public/c/gpu:MGL",
+    "//mojo/public/c/gpu:MGL_onscreen",
+    "//mojo/public/cpp/bindings",
+    "//mojo/public/cpp/system",
+    "//services/gles2:lib",
+    "//mojo/services/gpu/public/interfaces",
+  ]
+}
+
+source_set("gles2") {
+  sources = [
+    "gles2_impl.cc",
+  ]
+
   defines = [
     "GL_GLEXT_PROTOTYPES",
     "MOJO_GLES2_IMPLEMENTATION",
@@ -34,19 +57,26 @@
   all_dependent_configs = [ ":mojo_use_gles2" ]
 
   deps = [
-    "//base",
-    "//base/third_party/dynamic_annotations",
-    "//gpu/command_buffer/client",
-    "//gpu/command_buffer/client:gles2_cmd_helper",
-    "//gpu/command_buffer/client:gles2_implementation",
+    ":control_thunks",
     "//gpu/command_buffer/client:gles2_interface",
-    "//gpu/command_buffer/common",
-    "//mojo/environment:chromium",
     "//mojo/public/c/gles2:headers",
-    "//mojo/public/c/system",
-    "//mojo/public/cpp/bindings",
+    "//mojo/public/c/gpu:MGL",
+  ]
+}
+
+source_set("mgl") {
+  sources = [
+    "mgl_impl.cc",
+  ]
+
+  configs += [ ":gles2_use_mojo" ]
+
+  deps = [
+    ":control_thunks",
+    ":gles2",
+    "//mojo/public/c/gles2:headers",
+    "//mojo/public/c/gpu:MGL",
+    "//mojo/public/c/gpu:MGL_onscreen",
     "//mojo/public/cpp/system",
-    "//mojo/services/gpu/public/interfaces",
-    "//services/gles2:lib",
   ]
 }
diff --git a/mojo/gles2/control_thunks_impl.cc b/mojo/gles2/control_thunks_impl.cc
new file mode 100644
index 0000000..d428607
--- /dev/null
+++ b/mojo/gles2/control_thunks_impl.cc
@@ -0,0 +1,82 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "mojo/gles2/control_thunks_impl.h"
+
+#include "mojo/gles2/gles2_context.h"
+#include "mojo/public/cpp/system/message_pipe.h"
+
+namespace gles2 {
+
+// static
+ControlThunksImpl* ControlThunksImpl::Get() {
+  static base::LazyInstance<ControlThunksImpl>::Leaky thunks;
+  return thunks.Pointer();
+}
+
+MGLContext ControlThunksImpl::CreateContext(
+    MGLOpenGLAPIVersion version,
+    MojoHandle command_buffer_handle,
+    MGLContext share_group,
+    MGLContextLostCallback lost_callback,
+    void* lost_callback_closure,
+    const struct MojoAsyncWaiter* async_waiter) {
+  mojo::MessagePipeHandle mph(command_buffer_handle);
+  mojo::ScopedMessagePipeHandle scoped_handle(mph);
+  scoped_ptr<GLES2Context> client(
+      new GLES2Context(async_waiter, scoped_handle.Pass(), lost_callback,
+                       lost_callback_closure));
+  if (!client->Initialize())
+    client.reset();
+  return client.release();
+}
+
+void ControlThunksImpl::DestroyContext(MGLContext context) {
+  delete static_cast<GLES2Context*>(context);
+}
+
+void ControlThunksImpl::MakeCurrent(MGLContext context) {
+  current_context_tls_.Set(static_cast<GLES2Context*>(context));
+}
+
+MGLContext ControlThunksImpl::GetCurrentContext() {
+  return current_context_tls_.Get();
+}
+
+void ControlThunksImpl::ResizeSurface(uint32_t width, uint32_t height) {
+  current_context_tls_.Get()->interface()->ResizeCHROMIUM(width, height, 1.f);
+}
+
+void ControlThunksImpl::SwapBuffers() {
+  current_context_tls_.Get()->interface()->SwapBuffers();
+}
+
+void* ControlThunksImpl::GetGLES2Interface(MojoGLES2Context context) {
+  GLES2Context* client = reinterpret_cast<GLES2Context*>(context);
+  DCHECK(client);
+  return client->interface();
+}
+
+void ControlThunksImpl::SignalSyncPoint(
+    MojoGLES2Context context,
+    uint32_t sync_point,
+    MojoGLES2SignalSyncPointCallback callback,
+    void* closure) {
+  current_context_tls_.Get()->context_support()->SignalSyncPoint(
+      sync_point, base::Bind(callback, closure));
+}
+
+gpu::gles2::GLES2Interface* ControlThunksImpl::CurrentGLES2Interface() {
+  if (!current_context_tls_.Get())
+    return nullptr;
+  return current_context_tls_.Get()->interface();
+}
+
+ControlThunksImpl::ControlThunksImpl() {
+}
+
+ControlThunksImpl::~ControlThunksImpl() {
+}
+
+}  // namespace gles2
diff --git a/mojo/gles2/control_thunks_impl.h b/mojo/gles2/control_thunks_impl.h
new file mode 100644
index 0000000..0543adf
--- /dev/null
+++ b/mojo/gles2/control_thunks_impl.h
@@ -0,0 +1,69 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef MOJO_GLES2_CONTROL_THUNKS_IMPL_H_
+#define MOJO_GLES2_CONTROL_THUNKS_IMPL_H_
+
+#include "base/lazy_instance.h"
+#include "base/macros.h"
+#include "base/threading/thread_local.h"
+#include "gpu/GLES2/gl2extchromium.h"
+#include "mojo/gles2/gles2_context.h"
+#include "mojo/public/c/gles2/gles2.h"
+#include "mojo/public/c/gpu/MGL/mgl.h"
+
+namespace gpu {
+namespace gles2 {
+class GLES2Interface;
+}
+}
+
+namespace gles2 {
+
+// ControlThunksImpl is a singleton class that implements the MGL and MojoGLES2
+// control functions. The class maintains a lazily allocated TLS slot on each
+// thread for the current GL context.
+class ControlThunksImpl {
+ public:
+  static ControlThunksImpl* Get();
+
+  MGLContext CreateContext(MGLOpenGLAPIVersion version,
+                           MojoHandle command_buffer_handle,
+                           MGLContext share_group,
+                           MGLContextLostCallback lost_callback,
+                           void* lost_callback_closure,
+                           const struct MojoAsyncWaiter* async_waiter);
+
+  void DestroyContext(MGLContext context);
+
+  void MakeCurrent(MGLContext context);
+
+  MGLContext GetCurrentContext();
+
+  void ResizeSurface(uint32_t width, uint32_t height);
+
+  void SwapBuffers();
+
+  void* GetGLES2Interface(MojoGLES2Context context);
+
+  void SignalSyncPoint(MojoGLES2Context context,
+                       uint32_t sync_point,
+                       MojoGLES2SignalSyncPointCallback callback,
+                       void* closure);
+
+  gpu::gles2::GLES2Interface* CurrentGLES2Interface();
+
+ private:
+  friend base::DefaultLazyInstanceTraits<gles2::ControlThunksImpl>;
+  ControlThunksImpl();
+  ~ControlThunksImpl();
+
+  base::ThreadLocalPointer<GLES2Context> current_context_tls_;
+
+  DISALLOW_COPY_AND_ASSIGN(ControlThunksImpl);
+};
+
+}  // namespace gles2
+
+#endif  // MOJO_GLES2_CONTROL_THUNKS_IMPL_H_
diff --git a/mojo/gles2/gles2_context.cc b/mojo/gles2/gles2_context.cc
index 27b7c09..dff790c 100644
--- a/mojo/gles2/gles2_context.cc
+++ b/mojo/gles2/gles2_context.cc
@@ -21,7 +21,7 @@
 
 GLES2Context::GLES2Context(const MojoAsyncWaiter* async_waiter,
                            mojo::ScopedMessagePipeHandle command_buffer_handle,
-                           MojoGLES2ContextLost lost_callback,
+                           MGLContextLostCallback lost_callback,
                            void* closure)
     : command_buffer_(this, async_waiter, command_buffer_handle.Pass()),
       lost_callback_(lost_callback),
diff --git a/mojo/gles2/gles2_context.h b/mojo/gles2/gles2_context.h
index 87ccfd6..f725e25 100644
--- a/mojo/gles2/gles2_context.h
+++ b/mojo/gles2/gles2_context.h
@@ -10,8 +10,9 @@
 #include "gpu/command_buffer/client/gles2_implementation.h"
 #include "mojo/gles2/command_buffer_client_impl.h"
 #include "mojo/public/c/gles2/gles2.h"
+#include "mojo/public/c/gpu/MGL/mgl_types.h"
 
-struct MojoGLES2ContextPrivate {};
+struct MGLContextPrivate {};
 
 namespace gpu {
 class TransferBuffer;
@@ -23,12 +24,11 @@
 
 namespace gles2 {
 
-class GLES2Context : public CommandBufferDelegate,
-                     public MojoGLES2ContextPrivate {
+class GLES2Context : public CommandBufferDelegate, public MGLContextPrivate {
  public:
   explicit GLES2Context(const MojoAsyncWaiter* async_waiter,
                         mojo::ScopedMessagePipeHandle command_buffer_handle,
-                        MojoGLES2ContextLost lost_callback,
+                        MGLContextLostCallback lost_callback,
                         void* closure);
   ~GLES2Context() override;
   bool Initialize();
@@ -49,7 +49,7 @@
   scoped_ptr<gpu::gles2::GLES2CmdHelper> gles2_helper_;
   scoped_ptr<gpu::TransferBuffer> transfer_buffer_;
   scoped_ptr<gpu::gles2::GLES2Implementation> implementation_;
-  MojoGLES2ContextLost lost_callback_;
+  MGLContextLostCallback lost_callback_;
   void* closure_;
 
   MOJO_DISALLOW_COPY_AND_ASSIGN(GLES2Context);
diff --git a/mojo/gles2/gles2_impl.cc b/mojo/gles2/gles2_impl.cc
index 50e1d3f..dac1a00 100644
--- a/mojo/gles2/gles2_impl.cc
+++ b/mojo/gles2/gles2_impl.cc
@@ -2,78 +2,63 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "mojo/public/c/gles2/gles2.h"
-
-#include "base/lazy_instance.h"
-#include "base/threading/thread_local.h"
-#include "gpu/GLES2/gl2extchromium.h"
 #include "gpu/command_buffer/client/gles2_interface.h"
-#include "mojo/gles2/gles2_context.h"
-
-using gles2::GLES2Context;
-
-namespace {
-
-base::LazyInstance<base::ThreadLocalPointer<gpu::gles2::GLES2Interface> >::Leaky
-    g_gpu_interface;
-
-}  // namespace
+#include "mojo/gles2/control_thunks_impl.h"
+#include "mojo/public/c/gles2/gles2.h"
+#include "mojo/public/c/gpu/MGL/mgl.h"
 
 extern "C" {
+
 MojoGLES2Context MojoGLES2CreateContext(MojoHandle handle,
                                         MojoGLES2ContextLost lost_callback,
                                         void* closure,
                                         const MojoAsyncWaiter* async_waiter) {
-  mojo::MessagePipeHandle mph(handle);
-  mojo::ScopedMessagePipeHandle scoped_handle(mph);
-  scoped_ptr<GLES2Context> client(new GLES2Context(
-      async_waiter, scoped_handle.Pass(), lost_callback, closure));
-  if (!client->Initialize())
-    client.reset();
-  return client.release();
+  MGLContext context = gles2::ControlThunksImpl::Get()->CreateContext(
+      MGL_API_VERSION_GLES2,  // version
+      handle,                 // command_buffer_handle
+      MGL_NO_CONTEXT,         // share_group
+      static_cast<MGLContextLostCallback>(lost_callback), closure,
+      async_waiter);
+  return reinterpret_cast<MojoGLES2Context>(context);
 }
 
 void MojoGLES2DestroyContext(MojoGLES2Context context) {
-  delete static_cast<GLES2Context*>(context);
+  gles2::ControlThunksImpl::Get()->DestroyContext(
+      reinterpret_cast<MGLContext>(context));
 }
 
 void MojoGLES2MakeCurrent(MojoGLES2Context context) {
-  gpu::gles2::GLES2Interface* interface = NULL;
-  if (context) {
-    GLES2Context* client = static_cast<GLES2Context*>(context);
-    interface = client->interface();
-    DCHECK(interface);
-  }
-  g_gpu_interface.Get().Set(interface);
+  gles2::ControlThunksImpl::Get()->MakeCurrent(
+      reinterpret_cast<MGLContext>(context));
 }
 
 void MojoGLES2SwapBuffers() {
-  DCHECK(g_gpu_interface.Get().Get());
-  g_gpu_interface.Get().Get()->SwapBuffers();
+  gles2::ControlThunksImpl::Get()->SwapBuffers();
 }
 
 void* MojoGLES2GetGLES2Interface(MojoGLES2Context context) {
-  return static_cast<GLES2Context*>(context)->interface();
+  return gles2::ControlThunksImpl::Get()->GetGLES2Interface(context);
 }
 
 void MojoGLES2SignalSyncPoint(MojoGLES2Context context,
                               uint32_t sync_point,
                               MojoGLES2SignalSyncPointCallback callback,
                               void* closure) {
-  DCHECK(context);
-  GLES2Context* client = static_cast<GLES2Context*>(context);
-  client->SignalSyncPoint(sync_point, callback, closure);
+  gles2::ControlThunksImpl::Get()->SignalSyncPoint(context, sync_point,
+                                                   callback, closure);
 }
 
-#define VISIT_GL_CALL(Function, ReturnType, PARAMETERS, ARGUMENTS) \
-  ReturnType gl##Function PARAMETERS {                             \
-    DCHECK(g_gpu_interface.Get().Get());                           \
-    return g_gpu_interface.Get().Get()->Function ARGUMENTS;        \
+#define VISIT_GL_CALL(Function, ReturnType, PARAMETERS, ARGUMENTS)             \
+  ReturnType GL_APIENTRY gl##Function PARAMETERS {                             \
+    auto interface = gles2::ControlThunksImpl::Get()->CurrentGLES2Interface(); \
+    DCHECK(interface);                                                         \
+    return interface->Function ARGUMENTS;                                      \
   }
 #include "mojo/public/c/gles2/gles2_call_visitor_autogen.h"
+#include "mojo/public/c/gles2/gles2_call_visitor_chromium_bind_uniform_location_autogen.h"
+#include "mojo/public/c/gles2/gles2_call_visitor_chromium_map_sub_autogen.h"
 #include "mojo/public/c/gles2/gles2_call_visitor_chromium_miscellaneous_autogen.h"
 #include "mojo/public/c/gles2/gles2_call_visitor_chromium_resize_autogen.h"
-#include "mojo/public/c/gles2/gles2_call_visitor_chromium_sub_image_autogen.h"
 #include "mojo/public/c/gles2/gles2_call_visitor_chromium_sync_point_autogen.h"
 #include "mojo/public/c/gles2/gles2_call_visitor_chromium_texture_mailbox_autogen.h"
 #include "mojo/public/c/gles2/gles2_call_visitor_ext_debug_marker_autogen.h"
diff --git a/mojo/gles2/mgl_impl.cc b/mojo/gles2/mgl_impl.cc
new file mode 100644
index 0000000..95eb093
--- /dev/null
+++ b/mojo/gles2/mgl_impl.cc
@@ -0,0 +1,46 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// This file implements the MGL and MGL onscreen entry points exposed to the
+// Mojo application by the shell.
+
+#include "mojo/gles2/control_thunks_impl.h"
+#include "mojo/public/c/gles2/gles2.h"
+#include "mojo/public/c/gpu/MGL/mgl.h"
+#include "mojo/public/c/gpu/MGL/mgl_onscreen.h"
+
+extern "C" {
+
+MGLContext MGLCreateContext(MGLOpenGLAPIVersion version,
+                            MojoHandle command_buffer_handle,
+                            MGLContext share_group,
+                            MGLContextLostCallback lost_callback,
+                            void* lost_callback_closure,
+                            const struct MojoAsyncWaiter* async_waiter) {
+  return gles2::ControlThunksImpl::Get()->CreateContext(
+      version, command_buffer_handle, share_group, lost_callback,
+      lost_callback_closure, async_waiter);
+}
+
+void MGLDestroyContext(MGLContext context) {
+  return gles2::ControlThunksImpl::Get()->DestroyContext(context);
+}
+
+void MGLMakeCurrent(MGLContext context) {
+  return gles2::ControlThunksImpl::Get()->MakeCurrent(context);
+}
+
+MGLContext MGLGetCurrentContext() {
+  return gles2::ControlThunksImpl::Get()->GetCurrentContext();
+}
+
+void MGLResizeSurface(uint32_t width, uint32_t height) {
+  return gles2::ControlThunksImpl::Get()->ResizeSurface(width, height);
+}
+
+void MGLSwapBuffers() {
+  return gles2::ControlThunksImpl::Get()->SwapBuffers();
+}
+
+}  // extern "C"
diff --git a/mojo/go/BUILD.gn b/mojo/go/BUILD.gn
deleted file mode 100644
index 9b3ef62..0000000
--- a/mojo/go/BUILD.gn
+++ /dev/null
@@ -1,92 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import("rules.gni")
-
-go_library("application") {
-  sources = [
-    "//mojo/public/go/application/application_impl.go",
-    "//mojo/public/go/application/connection.go",
-  ]
-  deps = [
-    ":bindings",
-    ":system",
-  ]
-}
-
-go_library("bindings") {
-  sources = [
-    "//mojo/public/go/bindings/async_waiter.go",
-    "//mojo/public/go/bindings/connector.go",
-    "//mojo/public/go/bindings/decoder.go",
-    "//mojo/public/go/bindings/encoder.go",
-    "//mojo/public/go/bindings/interface.go",
-    "//mojo/public/go/bindings/invalid_handle.go",
-    "//mojo/public/go/bindings/message.go",
-    "//mojo/public/go/bindings/router.go",
-    "//mojo/public/go/bindings/stub.go",
-    "//mojo/public/go/bindings/util.go",
-  ]
-  deps = [
-    ":system",
-  ]
-}
-
-go_library("system") {
-  sources = [
-    "//mojo/public/go/system/core.go",
-    "//mojo/public/go/system/data_pipe.go",
-    "//mojo/public/go/system/handle.go",
-    "//mojo/public/go/system/message_pipe.go",
-    "//mojo/public/go/system/mojo_types.go",
-    "//mojo/public/go/system/shared_buffer.go",
-    "//mojo/public/go/system/system.go",
-    "//mojo/public/go/system/system_android.go",
-    "//mojo/public/go/system/system_linux.go",
-    "//mojo/public/go/system/system_nacl.go",
-  ]
-}
-
-go_library("platform_cgo") {
-  sources = [
-    "//mojo/public/platform/native_cgo/system_cgo.go",
-  ]
-}
-
-if (is_linux) {
-  group("go") {
-    testonly = true
-    deps = [
-      ":system_test",
-    ]
-  }
-  go_test_binary("system_test") {
-    sources = [
-      "tests/application_impl_test.go",
-      "tests/async_waiter_test.go",
-      "tests/encoding_test.go",
-      "tests/interface_test.go",
-      "tests/message_test.go",
-      "tests/request_response_test.go",
-      "tests/router_test.go",
-      "tests/system_test.go",
-      "tests/testutil.go",
-      "tests/testutil_test.go",
-      "tests/union_test.go",
-      "tests/validation_test.go",
-    ]
-    static_library_sources = [
-      "c_embedder/c_embedder.cc",
-      "c_embedder/c_embedder.h",
-    ]
-    deps = [
-      ":application",
-      ":platform_cgo",
-      "//examples/echo",
-      "//mojo/edk/system",
-      "//mojo/public/interfaces/bindings/tests:test_interfaces",
-      "//mojo/public/interfaces/bindings/tests:test_interfaces_experimental",
-    ]
-  }
-}
diff --git a/mojo/go/c_embedder/c_embedder.cc b/mojo/go/c_embedder/c_embedder.cc
deleted file mode 100644
index c0fa111..0000000
--- a/mojo/go/c_embedder/c_embedder.cc
+++ /dev/null
@@ -1,19 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "mojo/go/c_embedder/c_embedder.h"
-
-#include "mojo/edk/embedder/test_embedder.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-void InitializeMojoEmbedder() {
-  mojo::embedder::test::InitWithSimplePlatformSupport();
-}
-
-#ifdef __cplusplus
-}  // extern "C"
-#endif
diff --git a/mojo/go/c_embedder/c_embedder.h b/mojo/go/c_embedder/c_embedder.h
deleted file mode 100644
index f2961d6..0000000
--- a/mojo/go/c_embedder/c_embedder.h
+++ /dev/null
@@ -1,18 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef MOJO_GO_C_EMBEDDER_C_EMBEDDER_H_
-#define MOJO_GO_C_EMBEDDER_C_EMBEDDER_H_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-__attribute__((visibility("default"))) void InitializeMojoEmbedder();
-
-#ifdef __cplusplus
-}  // extern "C"
-#endif
-
-#endif  // MOJO_GO_C_EMBEDDER_C_EMBEDDER_H__
diff --git a/mojo/go/go.py b/mojo/go/go.py
deleted file mode 100755
index a0f93f2..0000000
--- a/mojo/go/go.py
+++ /dev/null
@@ -1,98 +0,0 @@
-#!/usr/bin/env python
-# Copyright (c) 2012 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""
-This script invokes the go build tool.
-Must be called as follows:
-python go.py [--android] <go-tool> <build directory> <output file>
-<src directory> <CGO_CFLAGS> <CGO_LDFLAGS> <go-binary options>
-eg.
-python go.py /usr/lib/google-golang/bin/go out/build out/a.out .. "-I."
-"-L. -ltest" test -c test/test.go
-"""
-
-import argparse
-import os
-import shutil
-import subprocess
-import sys
-
-NDK_PLATFORM = 'android-16'
-NDK_TOOLCHAIN = 'arm-linux-androideabi-4.9'
-
-def main():
-  parser = argparse.ArgumentParser()
-  parser.add_argument('--android', action='store_true')
-  parser.add_argument('go_tool')
-  parser.add_argument('build_directory')
-  parser.add_argument('output_file')
-  parser.add_argument('src_root')
-  parser.add_argument('out_root')
-  parser.add_argument('cgo_cflags')
-  parser.add_argument('cgo_ldflags')
-  parser.add_argument('go_option', nargs='*')
-  args = parser.parse_args()
-  go_tool = os.path.abspath(args.go_tool)
-  build_dir = args.build_directory
-  out_file = os.path.abspath(args.output_file)
-  # The src directory specified is relative. We need this as an absolute path.
-  src_root = os.path.abspath(args.src_root)
-  # GOPATH must be absolute, and point to one directory up from |src_Root|
-  go_path = os.path.abspath(os.path.join(src_root, '..'))
-  # GOPATH also includes any third_party/go libraries that have been imported
-  go_path += ':' +  os.path.join(src_root, 'third_party', 'go')
-  go_path += ':' +  os.path.abspath(os.path.join(args.out_root, 'gen', 'go'))
-  if 'MOJO_GOPATH' in os.environ:
-    go_path += ':' + os.environ['MOJO_GOPATH']
-  go_options = args.go_option
-  try:
-    shutil.rmtree(build_dir, True)
-    os.mkdir(build_dir)
-  except Exception:
-    pass
-  old_directory = os.getcwd()
-  os.chdir(build_dir)
-  env = os.environ.copy()
-  env['GOPATH'] = go_path
-  env['GOROOT'] = os.path.dirname(os.path.dirname(go_tool))
-  env['CGO_CFLAGS'] = args.cgo_cflags
-  env['CGO_LDFLAGS'] = args.cgo_ldflags
-  if args.android:
-    env['CGO_ENABLED'] = '1'
-    env['GOOS'] = 'android'
-    env['GOARCH'] = 'arm'
-    env['GOARM'] = '7'
-    # The Android go tool prebuilt binary has a default path to the compiler,
-    # which with high probability points to an invalid path, so we override the
-    # CC env var that will be used by the go tool.
-    if 'CC' not in env:
-      ndk_path = os.path.join(src_root, 'third_party', 'android_tools', 'ndk')
-      if sys.platform.startswith('linux'):
-        arch = 'linux-x86_64'
-      elif sys.platform == 'darwin':
-        arch = 'darwin-x86_64'
-      else:
-        raise Exception('unsupported platform: ' + sys.platform)
-      ndk_cc = os.path.join(ndk_path, 'toolchains', NDK_TOOLCHAIN,
-          'prebuilt', arch, 'bin', 'arm-linux-androideabi-gcc')
-      sysroot = os.path.join(ndk_path, 'platforms', NDK_PLATFORM, 'arch-arm')
-      env['CGO_CFLAGS'] += ' --sysroot %s' % sysroot
-      env['CGO_LDFLAGS'] += ' --sysroot %s' % sysroot
-      env['CC'] = '%s --sysroot %s' % (ndk_cc, sysroot)
-
-  call_result = subprocess.call([go_tool] + go_options, env=env)
-  if call_result != 0:
-    return call_result
-  out_files = sorted([ f for f in os.listdir('.') if os.path.isfile(f)])
-  if (len(out_files) > 0):
-    shutil.move(out_files[0], out_file)
-  os.chdir(old_directory)
-  try:
-    shutil.rmtree(build_dir, True)
-  except Exception:
-    pass
-
-if __name__ == '__main__':
-  sys.exit(main())
diff --git a/mojo/go/rules.gni b/mojo/go/rules.gni
deleted file mode 100644
index 60714f0..0000000
--- a/mojo/go/rules.gni
+++ /dev/null
@@ -1,156 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-declare_args() {
-  # By default, there is no go build tool, because go builds are not supported.
-  go_build_tool = ""
-}
-
-# Declare a go library.
-#
-# The target only writes a time stamp for input sources as the build is manages
-# by the go tool.
-#
-# Variables:
-#   sources(required): list of .go files
-#   deps: dependencies for the go library
-
-template("go_library") {
-  action(target_name) {
-    sources = invoker.sources
-    script = "//mojo/go/stamp.py"
-    outputs = [
-      "${target_out_dir}/${target_name}.script.stamp",
-    ]
-    if (defined(invoker.deps)) {
-      deps = invoker.deps
-    }
-    args = [ rebase_path(target_out_dir, root_build_dir) +
-             "/${target_name}.script.stamp" ]
-  }
-}
-
-# Declare a go test binary target.
-#
-# The target generates a go test executable, linking against other C code,
-# which is compiled into a static library and linked against Go.
-#
-# Only works on linux. |go_build_tool| must be set to the absolute path
-# of the go build tool.
-#
-# Variables (all required)
-#   sources: list of .go files to compile
-#   static_library_sources: list of C sources needed for the static library
-#   deps: dependencies for the static library
-
-template("go_test_binary") {
-  # Only available on linux for now.
-  assert(is_linux)
-  assert(defined(invoker.sources))
-  assert(go_build_tool != "")
-
-  static_library_name = target_name + "_static_library"
-
-  static_library(static_library_name) {
-    testonly = true
-    sources = invoker.static_library_sources
-    deps = invoker.deps
-    complete_static_lib = true
-  }
-
-  action(target_name) {
-    testonly = true
-    deps = [
-      ":$static_library_name",
-    ]
-    script = "//mojo/go/go.py"
-    inputs = invoker.sources
-    outputs = [
-      "${target_out_dir}/${target_name}",
-    ]
-
-    # Since go test does not permit specifying an output directory or output
-    # binary name, we create a temporary build directory, and the python
-    # script will later identify the output, copy it to the target location,
-    # and clean up the temporary build directory.
-    build_dir = "${target_out_dir}/${target_name}_build"
-    args = [
-             "--",
-             "${go_build_tool}",
-             rebase_path(build_dir, root_build_dir),
-             rebase_path(target_out_dir, root_build_dir) + "/${target_name}",
-             rebase_path("//", root_build_dir),
-             rebase_path(root_out_dir, root_build_dir),
-             "-I" + rebase_path("//"),
-             "-L" + rebase_path(target_out_dir) + " -l" + static_library_name +
-                 " -lstdc++ -lpthread -lm -lglib-2.0 -lrt",
-             "test",
-             "-c",
-           ] + rebase_path(invoker.sources, build_dir)
-  }
-}
-
-template("go_mojo_application") {
-  assert(is_android || is_linux)
-  assert(defined(invoker.sources))
-  assert(go_build_tool != "")
-
-  static_library_name = target_name + "_static_library"
-  static_library(static_library_name) {
-    complete_static_lib = true
-    deps = [
-      "//mojo/public/platform/native:system",
-    ]
-  }
-
-  go_library_name = target_name + "_go"
-  action(go_library_name) {
-    deps = invoker.deps + [
-             ":${static_library_name}",
-             "//mojo/go:application",
-             "//mojo/go:platform_cgo",
-             "//mojo/public/c/system",
-           ]
-    script = "//mojo/go/go.py"
-    inputs = invoker.sources
-    outputs = [
-      "${target_out_dir}/${target_name}",
-    ]
-
-    # Since go test does not permit specifying an output directory or output
-    # binary name, we create a temporary build directory, and the python
-    # script will later identify the output, copy it to the target location,
-    # and clean up the temporary build directory.
-    build_dir = "${target_out_dir}/${target_name}_build"
-    args = []
-    if (is_android) {
-      args += [ "--android" ]
-    }
-    args += [
-      "--",
-      "${go_build_tool}",
-      rebase_path(build_dir, root_build_dir),
-      rebase_path(target_out_dir, root_build_dir) + "/${target_name}",
-      rebase_path("//", root_build_dir),
-      rebase_path(root_out_dir, root_build_dir),
-      "-I" + rebase_path("//"),
-      "-L" + rebase_path(target_out_dir) + " -l" + static_library_name + "",
-      "build",
-    ]
-    args += [ "-buildmode=c-shared" ]
-    args += rebase_path(invoker.sources, build_dir)
-  }
-
-  copy(target_name) {
-    deps = [
-      ":${go_library_name}",
-    ]
-    sources = [
-      "${target_out_dir}/${go_library_name}",
-    ]
-    outputs = [
-      "${root_out_dir}/${target_name}.mojo",
-    ]
-  }
-}
diff --git a/mojo/go/stamp.py b/mojo/go/stamp.py
deleted file mode 100644
index 78db987..0000000
--- a/mojo/go/stamp.py
+++ /dev/null
@@ -1,24 +0,0 @@
-# Copyright 2015 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""
-This script writes a time stamp.
-Has one argument - time stamp file. Usage:
-python stamp.py path/to/file
-"""
-
-import sys
-
-def WriteStampFile(stamp_file):
-  with open(stamp_file, "w"):
-    pass
-
-
-def main(argv):
-  stamp_file = argv[1]
-  WriteStampFile(stamp_file)
-  return 0
-
-if __name__ == '__main__':
-  sys.exit(main(sys.argv))
diff --git a/mojo/go/system/embedder/embedder.go b/mojo/go/system/embedder/embedder.go
deleted file mode 100644
index c0e4aae..0000000
--- a/mojo/go/system/embedder/embedder.go
+++ /dev/null
@@ -1,14 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package embedder
-
-/*
-#include "mojo/go/c_embedder/c_embedder.h"
-*/
-import "C"
-
-func InitializeMojoEmbedder() {
-	C.InitializeMojoEmbedder()
-}
diff --git a/mojo/go/tests/README.txt b/mojo/go/tests/README.txt
deleted file mode 100644
index 6cdda94..0000000
--- a/mojo/go/tests/README.txt
+++ /dev/null
@@ -1,10 +0,0 @@
-Instructions to run system_test (Linux-only)
-
-1) Follow instructions in src/README.md file
-
-2) Build
-$ mojo/tools/mojob.py gn
-$ mojo/tools/mojob.py build
-
-3) Run
-$ out/Debug/obj/mojo/go/system_test -test.v
diff --git a/mojo/go/tests/application_impl_test.go b/mojo/go/tests/application_impl_test.go
deleted file mode 100644
index b28c95f..0000000
--- a/mojo/go/tests/application_impl_test.go
+++ /dev/null
@@ -1,161 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package tests
-
-import (
-	"fmt"
-	"sync"
-	"testing"
-
-	"mojo/public/go/application"
-	"mojo/public/go/bindings"
-
-	"examples/echo/echo"
-	mojoApp "mojo/public/interfaces/application/application"
-	sp "mojo/public/interfaces/application/service_provider"
-	"mojo/public/interfaces/application/shell"
-)
-
-var urls = [2]string{"first.example.com", "second.example.com"}
-
-func pairedURL(url string) string {
-	switch url {
-	case urls[0]:
-		return urls[1]
-	case urls[1]:
-		return urls[0]
-	default:
-		panic(fmt.Sprintf("unexpected URL %v", url))
-	}
-}
-
-func checkEcho(echoPointer echo.Echo_Pointer) {
-	echo := echo.NewEchoProxy(echoPointer, bindings.GetAsyncWaiter())
-	str := fmt.Sprintf("Hello, world")
-	response, err := echo.EchoString(&str)
-	if err != nil {
-		panic(err)
-	}
-	if *response != str {
-		panic(fmt.Sprintf("invalid response: want %v, got %v", str, *response))
-	}
-	echo.Close_Proxy()
-}
-
-type EchoImpl struct{}
-
-func (echo *EchoImpl) EchoString(inValue *string) (outValue *string, err error) {
-	return inValue, nil
-}
-
-// EchoDelegate implements mojo application. In this test configuration we
-// have two instances of this implementation that talk to each other.
-type EchoDelegate struct {
-	Wg       *sync.WaitGroup
-	localURL string
-}
-
-func (delegate *EchoDelegate) Create(request echo.Echo_Request) {
-	stub := echo.NewEchoStub(request, &EchoImpl{}, bindings.GetAsyncWaiter())
-	go func() {
-		if err := stub.ServeRequest(); err != nil {
-			panic(err)
-		}
-		stub.Close()
-		delegate.Wg.Done()
-	}()
-}
-
-// Initialize connects to other instance, providing and asking for echo service.
-func (delegate *EchoDelegate) Initialize(ctx application.Context) {
-	if ctx.URL() != delegate.localURL {
-		panic(fmt.Sprintf("invalid URL: want %v, got %v", delegate.localURL, ctx.URL()))
-	}
-	if len(ctx.Args()) != 1 || ctx.Args()[0] != delegate.localURL {
-		panic(fmt.Sprintf("invalid args: want %v, got %v", []string{delegate.localURL}, ctx.Args()))
-	}
-	go func() {
-		echoRequest, echoPointer := echo.CreateMessagePipeForEcho()
-		conn := ctx.ConnectToApplication(pairedURL(delegate.localURL), &echo.Echo_ServiceFactory{delegate})
-		if conn.RequestorURL() != delegate.localURL {
-			panic(fmt.Sprintf("invalid requestor URL: want %v, got %v", delegate.localURL, conn.RequestorURL()))
-		}
-		if conn.ConnectionURL() != pairedURL(delegate.localURL) {
-			panic(fmt.Sprintf("invalid connection URL: want %v, got %v", pairedURL(delegate.localURL), conn.ConnectionURL()))
-		}
-		conn.ConnectToService(&echoRequest)
-		checkEcho(echoPointer)
-	}()
-}
-
-// AcceptConnection accepts incoming connection, providing and asking for echo
-// service.
-func (delegate *EchoDelegate) AcceptConnection(conn *application.Connection) {
-	if conn.RequestorURL() != pairedURL(delegate.localURL) {
-		panic(fmt.Sprintf("invalid requestor URL: want %v, got %v", pairedURL(delegate.localURL), conn.RequestorURL()))
-	}
-	if conn.ConnectionURL() != delegate.localURL {
-		panic(fmt.Sprintf("invalid connection URL: want %v, got %v", delegate.localURL, conn.ConnectionURL()))
-	}
-	echoRequest, echoPointer := echo.CreateMessagePipeForEcho()
-	conn.ProvideServices(&echo.Echo_ServiceFactory{delegate}).ConnectToService(&echoRequest)
-	checkEcho(echoPointer)
-}
-
-func (delegate *EchoDelegate) Quit() {}
-
-// shellImpl forward connection from local EchoDelegate instance to remote.
-type shellImpl struct {
-	remoteApp *mojoApp.Application_Proxy
-	localURL  string
-}
-
-func (s *shellImpl) ConnectToApplication(URL string, services *sp.ServiceProvider_Request, exposedServices *sp.ServiceProvider_Pointer) error {
-	if URL != pairedURL(s.localURL) {
-		return fmt.Errorf("invalid URL: want %v, got %v", pairedURL(s.localURL), URL)
-	}
-	s.remoteApp.AcceptConnection(s.localURL, services, exposedServices, pairedURL(s.localURL))
-	return nil
-}
-
-func TestApplication(t *testing.T) {
-	var apps []*mojoApp.Application_Proxy
-	var responsesSent, appsTerminated sync.WaitGroup
-	// Create and run applications.
-	for i := 0; i < 2; i++ {
-		request, pointer := mojoApp.CreateMessagePipeForApplication()
-		apps = append(apps, mojoApp.NewApplicationProxy(pointer, bindings.GetAsyncWaiter()))
-		// Each app instance provides echo service once when it creates
-		// a connection and once other instance creates a connection.
-		responsesSent.Add(2)
-		appsTerminated.Add(1)
-		delegate := &EchoDelegate{&responsesSent, urls[i]}
-		go func() {
-			application.Run(delegate, request.PassMessagePipe().ReleaseNativeHandle())
-			appsTerminated.Done()
-		}()
-	}
-	// Provide a shell for each application.
-	for i := 0; i < 2; i++ {
-		shellRequest, shellPointer := shell.CreateMessagePipeForShell()
-		shellStub := shell.NewShellStub(shellRequest, &shellImpl{apps[i^1], urls[i]}, bindings.GetAsyncWaiter())
-		go func() {
-			if err := shellStub.ServeRequest(); err != nil {
-				panic(err)
-			}
-			shellStub.Close()
-		}()
-		apps[i].Initialize(shellPointer, &[]string{urls[i]}, urls[i])
-	}
-	// Wait and then close pipes.
-	responsesSent.Wait()
-	for i := 0; i < 2; i++ {
-		apps[i].RequestQuit()
-	}
-	appsTerminated.Wait()
-	for i := 0; i < 2; i++ {
-		apps[i].Close_Proxy()
-	}
-}
diff --git a/mojo/go/tests/async_waiter_test.go b/mojo/go/tests/async_waiter_test.go
deleted file mode 100644
index 8f137f8..0000000
--- a/mojo/go/tests/async_waiter_test.go
+++ /dev/null
@@ -1,92 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package tests
-
-import (
-	"fmt"
-	"sync"
-	"testing"
-
-	"mojo/public/go/bindings"
-	"mojo/public/go/system"
-)
-
-func checkWait(handle system.Handle, signals system.MojoHandleSignals, expected system.MojoResult, wg *sync.WaitGroup) {
-	wg.Add(1)
-	responseChan := make(chan bindings.WaitResponse)
-	bindings.GetAsyncWaiter().AsyncWait(handle, signals, responseChan)
-	go func() {
-		response := <-responseChan
-		if expected != response.Result {
-			panic(fmt.Sprintf("unexpected wait result: expected %v, got %v", expected, response.Result))
-		}
-		wg.Done()
-	}()
-}
-
-func checkCancel(handle system.Handle, wg *sync.WaitGroup) {
-	wg.Add(1)
-	responseChan := make(chan bindings.WaitResponse)
-	id := waiter.AsyncWait(handle, system.MOJO_HANDLE_SIGNAL_READABLE, responseChan)
-	go func() {
-		waiter.CancelWait(id)
-		response := <-responseChan
-		if expected := system.MOJO_RESULT_ABORTED; expected != response.Result {
-			panic(fmt.Sprintf("unexpected wait result: expected %v, got %v", expected, response.Result))
-		}
-		wg.Done()
-	}()
-}
-
-func TestAsyncWait(t *testing.T) {
-	r, h0, h1 := core.CreateMessagePipe(nil)
-	defer h0.Close()
-	defer h1.Close()
-	if r != system.MOJO_RESULT_OK {
-		t.Fatalf("error creating a message pipe %v", r)
-	}
-	var wg sync.WaitGroup
-	h0.WriteMessage([]byte{0}, nil, system.MOJO_WRITE_MESSAGE_FLAG_NONE)
-	checkWait(h0, system.MOJO_HANDLE_SIGNAL_WRITABLE, system.MOJO_RESULT_OK, &wg)
-	checkWait(h1, system.MOJO_HANDLE_SIGNAL_READABLE, system.MOJO_RESULT_OK, &wg)
-
-	if r, h0, h1 = core.CreateMessagePipe(nil); r != system.MOJO_RESULT_OK {
-		t.Fatalf("error creating a message pipe %v", r)
-	}
-	defer h1.Close()
-	h0.Close()
-	checkWait(h0, system.MOJO_HANDLE_SIGNAL_PEER_CLOSED, system.MOJO_RESULT_INVALID_ARGUMENT, &wg)
-	checkWait(h1, system.MOJO_HANDLE_SIGNAL_PEER_CLOSED, system.MOJO_RESULT_OK, &wg)
-
-	if r, h0, h1 = core.CreateMessagePipe(nil); r != system.MOJO_RESULT_OK {
-		t.Fatalf("error creating a message pipe %v", r)
-	}
-	defer h1.Close()
-	h0.Close()
-	checkWait(h0, system.MOJO_HANDLE_SIGNAL_PEER_CLOSED, system.MOJO_RESULT_INVALID_ARGUMENT, &wg)
-	checkWait(h1, system.MOJO_HANDLE_SIGNAL_READABLE, system.MOJO_RESULT_FAILED_PRECONDITION, &wg)
-	wg.Wait()
-}
-
-func TestAsyncWaitCancel(t *testing.T) {
-	r, h0, h1 := core.CreateMessagePipe(nil)
-	defer h0.Close()
-	defer h1.Close()
-	if r != system.MOJO_RESULT_OK {
-		t.Fatalf("error creating a message pipe %v", r)
-	}
-	var wg sync.WaitGroup
-	checkCancel(h0, &wg)
-	checkCancel(h1, &wg)
-
-	if r, h0, h1 = core.CreateMessagePipe(nil); r != system.MOJO_RESULT_OK {
-		t.Fatalf("error creating a message pipe %v", r)
-	}
-	defer h0.Close()
-	defer h1.Close()
-	checkCancel(h0, &wg)
-	checkCancel(h1, &wg)
-	wg.Wait()
-}
diff --git a/mojo/go/tests/encoding_test.go b/mojo/go/tests/encoding_test.go
deleted file mode 100644
index 41a3355..0000000
--- a/mojo/go/tests/encoding_test.go
+++ /dev/null
@@ -1,196 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package tests
-
-import (
-	"reflect"
-	"testing"
-
-	"mojo/public/go/bindings"
-	"mojo/public/go/system"
-	"mojo/public/interfaces/bindings/tests/rect"
-	test "mojo/public/interfaces/bindings/tests/serialization_test_structs"
-	"mojo/public/interfaces/bindings/tests/test_structs"
-)
-
-func check(t *testing.T, value, zeroValue bindings.Payload) {
-	message, err := bindings.EncodeMessage(bindings.MessageHeader{}, value)
-	if err != nil {
-		t.Fatalf("error encoding value %v: %v", value, err)
-	}
-	decodedMessage, err := bindings.ParseMessage(message.Bytes, message.Handles)
-	if err != nil {
-		t.Fatalf("error decoding message header from bytes %v for tested value %v: %v", message.Bytes, value, err)
-	}
-	if err = decodedMessage.DecodePayload(zeroValue); err != nil {
-		t.Fatalf("error decoding message payload from bytes %v for tested value %v: %v", message.Payload, value, err)
-	}
-	if !reflect.DeepEqual(value, zeroValue) {
-		t.Fatalf("unexpected value after decoding: expected %v, got %v", value, zeroValue)
-	}
-}
-
-func TestSerializationTestStructs(t *testing.T) {
-	check(t, &test.Struct1{1}, &test.Struct1{})
-	check(t, &test.Struct2{&mockHandle{handle: 1}}, &test.Struct2{})
-	check(t, &test.Struct3{test.Struct1{2}}, &test.Struct3{})
-	check(t, &test.Struct4{[]test.Struct1{test.Struct1{1}, test.Struct1{2}}}, &test.Struct4{})
-	check(t, &test.Struct5{[2]test.Struct1{test.Struct1{1}, test.Struct1{2}}}, &test.Struct5{})
-	check(t, &test.Struct6{"hello, world!"}, &test.Struct6{})
-
-	check(t, &test.StructOfNullables{nil, nil, nil}, &test.StructOfNullables{})
-	handle := system.Handle(&mockHandle{handle: 1})
-	s := "hello, world"
-	check(t, &test.StructOfNullables{&handle, nil, nil}, &test.StructOfNullables{})
-	check(t, &test.StructOfNullables{&handle, &test.Struct1{3}, nil}, &test.StructOfNullables{})
-	check(t, &test.StructOfNullables{&handle, &test.Struct1{3}, &s}, &test.StructOfNullables{})
-	check(t, &test.StructOfNullables{&handle, nil, &s}, &test.StructOfNullables{})
-}
-
-func TestStructs(t *testing.T) {
-	s1 := "hello, world!"
-	s2 := "world, hello!"
-	handle := system.Handle(&mockHandle{handle: 1})
-	messagePipeHandle := system.MessagePipeHandle(&mockHandle{handle: 2})
-	consumerHandle := system.ConsumerHandle(&mockHandle{handle: 3})
-	producerHandle := system.ProducerHandle(&mockHandle{handle: 4})
-	sharedBufferHandle := system.SharedBufferHandle(&mockHandle{handle: 5})
-	value := bindings.Payload(&test_structs.NoDefaultFieldValues{
-		F0:  true,                        // bool
-		F1:  -2,                          // int8
-		F2:  3,                           // uint8
-		F3:  -4000,                       // int16
-		F4:  5000,                        // uint16
-		F5:  -6000000,                    // int32
-		F6:  7000000,                     // uint32
-		F7:  -8000000000000,              // int64
-		F8:  9000000000000,               // uint64
-		F9:  1e-45,                       // float
-		F10: -1e45,                       // double
-		F11: s1,                          // string
-		F12: &s2,                         // string?
-		F13: messagePipeHandle,           // handle<message_pipe>
-		F14: consumerHandle,              // handle<data_pipe_consumer>
-		F15: producerHandle,              // handle<data_pipe_producer>
-		F16: &messagePipeHandle,          // handle<message_pipe>?
-		F17: &consumerHandle,             // handle<data_pipe_consumer>?
-		F18: &producerHandle,             // handle<data_pipe_producer>?
-		F19: handle,                      // handle
-		F20: &handle,                     // handle?
-		F21: sharedBufferHandle,          // handle<shared_buffer>
-		F22: &sharedBufferHandle,         // handle<shared_buffer>?
-		F23: []string{s1, s2},            // array<string>
-		F24: []*string{&s1, &s2},         // array<string?>
-		F25: &[]string{s1, s2},           // array<string>?
-		F26: &[]*string{&s1, &s2},        // array<string?>?
-		F27: test_structs.EmptyStruct{},  // EmptyStruct
-		F28: &test_structs.EmptyStruct{}, // EmptyStruct?
-	})
-	check(t, value, &test_structs.NoDefaultFieldValues{})
-
-	value = &test_structs.ScopedConstants{
-		test_structs.ScopedConstants_EType_E0,
-		test_structs.ScopedConstants_EType_E1,
-		test_structs.ScopedConstants_EType_E2,
-		test_structs.ScopedConstants_EType_E3,
-		test_structs.ScopedConstants_EType_E4,
-		10,
-		25,
-	}
-	check(t, value, &test_structs.ScopedConstants{})
-
-	value = &test_structs.MapKeyTypes{
-		F0:  map[bool]bool{false: true, true: false},
-		F1:  map[int8]int8{15: -45, -42: 50},
-		F2:  map[uint8]uint8{15: 45, 42: 50},
-		F3:  map[int16]int16{-15: 45, -42: 50},
-		F4:  map[uint16]uint16{15: 45, 42: 50},
-		F5:  map[int32]int32{15: -45, 42: 50},
-		F6:  map[uint32]uint32{15: 45, 42: 50},
-		F7:  map[int64]int64{15: 45, 42: -50},
-		F8:  map[uint64]uint64{15: 45, 42: 50},
-		F9:  map[float32]float32{1.5: 2.5, 3.5: 1e-9},
-		F10: map[float64]float64{1.5: 2.5, 3.5: 1e-9},
-		F11: map[string]string{s1: s2, s2: s1},
-	}
-	check(t, value, &test_structs.MapKeyTypes{})
-
-	value = &test_structs.MapValueTypes{
-		F0: map[string][]string{
-			s1: []string{s1, s2},
-			s2: []string{s2, s1},
-		},
-		F1: map[string]*[]string{
-			s1: &[]string{s1, s2},
-			s2: &[]string{s2, s1},
-		},
-		F2: map[string][]*string{
-			s1: []*string{&s1, &s2},
-			s2: []*string{&s2, &s1},
-		},
-		F3: map[string][2]string{
-			s1: [2]string{s1, s2},
-			s2: [2]string{s2, s1},
-		},
-		F4: map[string][]*[2]string{
-			s1: []*[2]string{&[2]string{s1, s2}},
-			s2: []*[2]string{&[2]string{s1, s2}},
-		},
-		F5: map[string][1][2]string{
-			s1: [1][2]string{[2]string{s1, s2}},
-			s2: [1][2]string{[2]string{s1, s2}},
-		},
-		F6: map[string]*rect.Rect{
-			s1: &rect.Rect{},
-			s2: &rect.Rect{3, 4, 5, 6},
-		},
-		F7: map[string]map[string]string{
-			s1: map[string]string{s1: s1, s2: s2},
-			s2: map[string]string{s1: s2, s2: s1},
-		},
-		F8: map[string][]map[string]string{
-			s1: []map[string]string{
-				map[string]string{s1: s1, s2: s2},
-				map[string]string{s1: s2, s2: s1},
-			},
-			s2: []map[string]string{
-				map[string]string{s1: s1, s2: s2},
-				map[string]string{s1: s2, s2: s1},
-			},
-		},
-		F9: map[string]system.Handle{
-			s1: handle,
-			s2: handle,
-		},
-		F10: map[string][]system.Handle{
-			s1: []system.Handle{handle},
-			s2: []system.Handle{},
-		},
-		F11: map[string]map[string]system.Handle{
-			s1: map[string]system.Handle{s1: handle},
-			s2: map[string]system.Handle{s2: handle},
-		},
-  }
-	check(t, value, &test_structs.MapValueTypes{})
-
-	value = &test_structs.BitArrayValues{
-		F0: [1]bool{true},
-		F1: [7]bool{true, false, true, false, true, false, true},
-		F2: [9]bool{true, true, true, false, false, false, true, true, true},
-		F3: []bool{true, false, true, false},
-		F4: [][]bool{[]bool{true}},
-		F5: []*[]bool{
-			&[]bool{true, false, true},
-			&[]bool{false, true},
-		},
-		F6: []*[2]bool{
-			&[2]bool{false, false},
-			&[2]bool{false, true},
-			&[2]bool{true, false},
-			&[2]bool{true, true},
-		},
-	}
-	check(t, value, &test_structs.BitArrayValues{})
-}
diff --git a/mojo/go/tests/interface_test.go b/mojo/go/tests/interface_test.go
deleted file mode 100644
index a3f8f90..0000000
--- a/mojo/go/tests/interface_test.go
+++ /dev/null
@@ -1,25 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package tests
-
-import (
-	"testing"
-
-	"mojo/public/go/bindings"
-)
-
-func TestPassMessagePipe(t *testing.T) {
-	r, p := bindings.CreateMessagePipeForMojoInterface()
-	r1, p1 := r, p
-	handle := r1.PassMessagePipe()
-	defer handle.Close()
-	p1.Close()
-	rhandle, phandle := r.PassMessagePipe(), p.PassMessagePipe()
-	if rhandle.IsValid() || phandle.IsValid() {
-		t.Fatal("message pipes should be invalid after PassMessagePipe() or Close()")
-	}
-	rhandle.Close()
-	phandle.Close()
-}
diff --git a/mojo/go/tests/message_test.go b/mojo/go/tests/message_test.go
deleted file mode 100644
index 0b0d63e..0000000
--- a/mojo/go/tests/message_test.go
+++ /dev/null
@@ -1,45 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package tests
-
-import (
-	"testing"
-
-	"mojo/public/go/bindings"
-)
-
-func checkMessageEncoding(t *testing.T, header, payload bindings.MessageHeader) {
-	var encodedMessage, decodedMessage *bindings.Message
-	var err error
-	var decodedHeader, decodedPayload bindings.MessageHeader
-
-	if encodedMessage, err = bindings.EncodeMessage(header, &payload); err != nil {
-		t.Fatalf("Failed encoding message: %v", err)
-	}
-
-	if decodedMessage, err = bindings.ParseMessage(encodedMessage.Bytes, nil); err != nil {
-		t.Fatalf("Failed decoding message header: %v", err)
-	}
-	if decodedHeader = decodedMessage.Header; decodedHeader != header {
-		t.Fatalf("Unexpected header decoded: got %v, want %v", decodedHeader, header)
-	}
-	if err = decodedMessage.DecodePayload(&decodedPayload); err != nil {
-		t.Fatalf("Failed decoding message payload: %v", err)
-	}
-	if decodedPayload != payload {
-		t.Fatalf("Unexpected header with request id decoded: got %v, want %v", decodedPayload, payload)
-	}
-}
-
-// TestMessageHeader tests that headers are identical after being
-// encoded/decoded.
-func TestMessageHeader(t *testing.T) {
-	header := bindings.MessageHeader{2, 0, 0}
-	headerWithId := bindings.MessageHeader{1, 2, 3}
-	checkMessageEncoding(t, header, headerWithId)
-	checkMessageEncoding(t, headerWithId, header)
-	headerWithZeroId := bindings.MessageHeader{1, 2, 0}
-	checkMessageEncoding(t, headerWithZeroId, header)
-}
diff --git a/mojo/go/tests/request_response_test.go b/mojo/go/tests/request_response_test.go
deleted file mode 100644
index 0b79f69..0000000
--- a/mojo/go/tests/request_response_test.go
+++ /dev/null
@@ -1,78 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package tests
-
-import (
-	"testing"
-
-	"examples/echo/echo"
-	"mojo/public/go/bindings"
-	"mojo/public/go/system"
-)
-
-func TestProxyClosesPipe(t *testing.T) {
-	request, pointer := echo.CreateMessagePipeForEcho()
-	// Create a message with valid header and invalid payload and send it.
-	header := bindings.MessageHeader{0, bindings.MessageIsResponseFlag, 1}
-	message, err := bindings.EncodeMessage(header, &header)
-	if err != nil {
-		t.Fatalf("Error encoding message: %v", err)
-	}
-	requestPipe := request.PassMessagePipe()
-	if r := requestPipe.WriteMessage(message.Bytes, nil, system.MOJO_WRITE_MESSAGE_FLAG_NONE); r != system.MOJO_RESULT_OK {
-		t.Fatalf("Can't send a message: %v", r)
-	}
-
-	// Make echo request with response (that is already sent).
-	echoProxy := echo.NewEchoProxy(pointer, waiter)
-	_, err = echoProxy.EchoString(bindings.StringPointer("hello, world"))
-	if err == nil {
-		t.Fatalf("Message is invalid, error expected")
-	}
-
-	// Wait for the pipe to be closed.
-	waitResponseChan := make(chan bindings.WaitResponse)
-	waiter.AsyncWait(requestPipe, system.MOJO_HANDLE_SIGNAL_PEER_CLOSED, waitResponseChan)
-	waitResponse := <-waitResponseChan
-	if waitResponse.Result != system.MOJO_RESULT_OK {
-		t.Fatalf("Error waiting on pipe to be closed: %v", waitResponse.Result)
-	}
-	requestPipe.Close()
-}
-
-type echoImpl struct{}
-
-func (impl *echoImpl) EchoString(in *string) (*string, error) {
-	return nil, nil
-}
-
-func TestStubClosesPipe(t *testing.T) {
-	request, pointer := echo.CreateMessagePipeForEcho()
-	// Create a message with valid header and invalid payload and send it.
-	header := bindings.MessageHeader{0, bindings.MessageIsResponseFlag, 1}
-	message, err := bindings.EncodeMessage(header, &header)
-	if err != nil {
-		t.Fatalf("Error encoding message: %v", err)
-	}
-	pointerPipe := pointer.PassMessagePipe()
-	if r := pointerPipe.WriteMessage(message.Bytes, nil, system.MOJO_WRITE_MESSAGE_FLAG_NONE); r != system.MOJO_RESULT_OK {
-		t.Fatalf("Can't send a message: %v", r)
-	}
-
-	// Make echo request with response (that is already sent).
-	echoStub := echo.NewEchoStub(request, &echoImpl{}, waiter)
-	if err := echoStub.ServeRequest(); err == nil {
-		t.Fatalf("Message is invalid, error expected")
-	}
-
-	// Wait for the pipe to be closed.
-	waitResponseChan := make(chan bindings.WaitResponse)
-	waiter.AsyncWait(pointerPipe, system.MOJO_HANDLE_SIGNAL_PEER_CLOSED, waitResponseChan)
-	waitResponse := <-waitResponseChan
-	if waitResponse.Result != system.MOJO_RESULT_OK {
-		t.Fatalf("Error waiting on pipe to be closed: %v", waitResponse.Result)
-	}
-	pointerPipe.Close()
-}
diff --git a/mojo/go/tests/router_test.go b/mojo/go/tests/router_test.go
deleted file mode 100644
index ec8ebb3..0000000
--- a/mojo/go/tests/router_test.go
+++ /dev/null
@@ -1,148 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package tests
-
-import (
-	"regexp"
-	"sync"
-	"testing"
-
-	"mojo/public/go/bindings"
-	"mojo/public/go/system"
-)
-
-func expectError(t *testing.T, expected string, err error) {
-	if err == nil {
-		t.Fatalf("unexpected nil error, expected %v", expected)
-	}
-	if ok, _ := regexp.MatchString(expected, err.Error()); !ok {
-		t.Fatalf("unexpected error: expected %v, got %v", expected, err.Error())
-	}
-}
-
-func encodeMessage(header bindings.MessageHeader, payload bindings.Payload) *bindings.Message {
-	message, err := bindings.EncodeMessage(header, payload)
-	if err != nil {
-		panic(err)
-	}
-	return message
-}
-
-func TestAccept(t *testing.T) {
-	r, h0, h1 := core.CreateMessagePipe(nil)
-	defer h1.Close()
-	if r != system.MOJO_RESULT_OK {
-		t.Fatalf("can't create a message pipe: %v", r)
-	}
-	router := bindings.NewRouter(h0, bindings.GetAsyncWaiter())
-	header := bindings.MessageHeader{0, 0, 0}
-	if err := router.Accept(encodeMessage(header, &header)); err != nil {
-		t.Fatal(err)
-	}
-	header = bindings.MessageHeader{0, bindings.MessageExpectsResponseFlag, 1}
-	err := router.Accept(encodeMessage(header, &header))
-	expectError(t, "message header should have a zero request ID", err)
-	router.Close()
-}
-
-func TestAcceptWithResponse(t *testing.T) {
-	r, h0, h1 := core.CreateMessagePipe(nil)
-	defer h1.Close()
-	if r != system.MOJO_RESULT_OK {
-		t.Fatalf("can't create a message pipe: %v", r)
-	}
-	router := bindings.NewRouter(h0, bindings.GetAsyncWaiter())
-	header := bindings.MessageHeader{0, bindings.MessageIsResponseFlag, 1}
-	bindings.WriteMessage(h1, encodeMessage(header, &header))
-	header = bindings.MessageHeader{0, bindings.MessageExpectsResponseFlag, 1}
-	if result := <-router.AcceptWithResponse(encodeMessage(header, &header)); result.Error != nil {
-		t.Fatal(result.Error)
-	}
-	header = bindings.MessageHeader{0, 0, 0}
-	err := (<-router.AcceptWithResponse(encodeMessage(header, &header))).Error
-	expectError(t, "message header should have a request ID", err)
-	router.Close()
-}
-
-const numberOfRequests = 50
-
-func TestAcceptWithResponseMultiple(t *testing.T) {
-	r, h0, h1 := core.CreateMessagePipe(nil)
-	defer h1.Close()
-	if r != system.MOJO_RESULT_OK {
-		t.Fatalf("can't create a message pipe: %v", r)
-	}
-	router := bindings.NewRouter(h0, bindings.GetAsyncWaiter())
-	var wg sync.WaitGroup
-	wg.Add(numberOfRequests + 1)
-	// Serve requests.
-	go func() {
-		for i := 0; i < numberOfRequests; i++ {
-			c := make(chan bindings.WaitResponse, 1)
-			bindings.GetAsyncWaiter().AsyncWait(h1, system.MOJO_HANDLE_SIGNAL_READABLE, c)
-			r, bytes, handles := h1.ReadMessage(system.MOJO_READ_MESSAGE_FLAG_NONE)
-			if r != system.MOJO_RESULT_OK {
-				t.Fatalf("can't read from a message pipe: %v", r)
-			}
-			r = h1.WriteMessage(bytes, handles, system.MOJO_WRITE_MESSAGE_FLAG_NONE)
-			if r != system.MOJO_RESULT_OK {
-				t.Fatalf("can't write to a message pipe: %v", r)
-			}
-		}
-		wg.Done()
-	}()
-	// Send concurrent requests.
-	for i := 0; i < numberOfRequests; i++ {
-		go func(i int) {
-			header := bindings.MessageHeader{0, bindings.MessageExpectsResponseFlag, uint64(i + 1)}
-			err := (<-router.AcceptWithResponse(encodeMessage(header, &header))).Error
-			if err != nil {
-				panic(err)
-			}
-			wg.Done()
-		}(i)
-	}
-	wg.Wait()
-	router.Close()
-}
-
-func TestClose(t *testing.T) {
-	r, h0, h1 := core.CreateMessagePipe(nil)
-	defer h1.Close()
-	if r != system.MOJO_RESULT_OK {
-		t.Fatalf("can't create a message pipe: %v", r)
-	}
-	router := bindings.NewRouter(h0, bindings.GetAsyncWaiter())
-	var wg sync.WaitGroup
-	wg.Add(numberOfRequests*2 + 1)
-
-	// Send requests from the same go routine.
-	for i := 0; i < numberOfRequests; i++ {
-		header := bindings.MessageHeader{0, bindings.MessageExpectsResponseFlag, uint64(i + 1)}
-		c := router.AcceptWithResponse(encodeMessage(header, &header))
-		go func() {
-			if err := (<-c).Error; err == nil {
-				panic("unexpected nil error")
-			}
-			wg.Done()
-		}()
-	}
-	// Send requests from different go routines.
-	for i := 0; i < numberOfRequests; i++ {
-		go func(i int) {
-			header := bindings.MessageHeader{0, bindings.MessageExpectsResponseFlag, uint64(i + 1)}
-			err := (<-router.AcceptWithResponse(encodeMessage(header, &header))).Error
-			if err == nil {
-				panic("unexpected nil error")
-			}
-			wg.Done()
-		}(i + numberOfRequests)
-	}
-	go func() {
-		router.Close()
-		wg.Done()
-	}()
-	wg.Wait()
-}
diff --git a/mojo/go/tests/system_test.go b/mojo/go/tests/system_test.go
deleted file mode 100644
index 77b80fe..0000000
--- a/mojo/go/tests/system_test.go
+++ /dev/null
@@ -1,302 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package tests
-
-import (
-	"bytes"
-	"testing"
-
-	"mojo/public/go/system"
-)
-
-const (
-	MOJO_HANDLE_SIGNAL_READWRITABLE = system.MojoHandleSignals(system.MOJO_HANDLE_SIGNAL_READABLE |
-		system.MOJO_HANDLE_SIGNAL_WRITABLE)
-	MOJO_HANDLE_SIGNAL_ALL = system.MojoHandleSignals(system.MOJO_HANDLE_SIGNAL_READABLE |
-		system.MOJO_HANDLE_SIGNAL_WRITABLE |
-		system.MOJO_HANDLE_SIGNAL_PEER_CLOSED)
-)
-
-func TestGetTimeTicksNow(t *testing.T) {
-	x := core.GetTimeTicksNow()
-	if x < 10 {
-		t.Error("Invalid GetTimeTicksNow return value")
-	}
-}
-
-func TestHandle(t *testing.T) {
-	var handle system.SharedBufferHandle
-	var r system.MojoResult
-
-	if r, handle = core.CreateSharedBuffer(nil, 1); r != system.MOJO_RESULT_OK {
-		t.Fatalf("CreateSharedBuffer failed:%v", r)
-	}
-	if !handle.IsValid() {
-		t.Fatalf("CreateSharedBuffer returned invalid handle:%v", handle)
-	}
-	duplicate := handle
-	if duplicate.NativeHandle() != handle.NativeHandle() {
-		t.Fatalf("duplicate(%v) and handle(%v) point to different handles", duplicate.NativeHandle(), handle.NativeHandle())
-	}
-	releasedHandle := handle.ReleaseNativeHandle()
-	if duplicate.IsValid() || handle.IsValid() {
-		t.Fatalf("duplicate(%v) and handle(%v) should be invalid after releasing native handle", duplicate.NativeHandle(), handle.NativeHandle())
-	}
-	handle = core.AcquireNativeHandle(releasedHandle).ToSharedBufferHandle()
-	if handle.NativeHandle() != releasedHandle || !handle.IsValid() {
-		t.Fatalf("handle(%v) should be valid after AcquireNativeHandle", handle.NativeHandle())
-	}
-	untypedHandle := handle.ToUntypedHandle()
-	if handle.IsValid() {
-		t.Fatalf("handle(%v) should be invalid after call ToUntypedHandle", handle.NativeHandle())
-	}
-	handle = untypedHandle.ToSharedBufferHandle()
-	if untypedHandle.IsValid() {
-		t.Fatalf("untypedHandle(%v) should be invalid after call ToSharedBufferHandle", untypedHandle.NativeHandle())
-	}
-	if handle.NativeHandle() != releasedHandle {
-		t.Fatalf("handle(%v) should be wrapping %v", handle.NativeHandle(), releasedHandle)
-	}
-	if r = handle.Close(); r != system.MOJO_RESULT_OK {
-		t.Fatalf("Close on handle failed:%v", r)
-	}
-}
-
-func TestMessagePipe(t *testing.T) {
-	var h0, h1 system.MessagePipeHandle
-	var r system.MojoResult
-	var state system.MojoHandleSignalsState
-
-	if r, h0, h1 = core.CreateMessagePipe(nil); r != system.MOJO_RESULT_OK {
-		t.Fatalf("CreateMessagePipe failed:%v", r)
-	}
-	if !h0.IsValid() || !h1.IsValid() {
-		t.Fatalf("CreateMessagePipe returned invalid handles h0:%v h1:%v", h0, h1)
-	}
-
-	r, state = h0.Wait(system.MOJO_HANDLE_SIGNAL_READABLE, 0)
-	if r != system.MOJO_RESULT_DEADLINE_EXCEEDED {
-		t.Fatalf("h0 should not be readable:%v", r)
-	}
-	if state.SatisfiedSignals != system.MOJO_HANDLE_SIGNAL_WRITABLE {
-		t.Fatalf("state should be not be signaled readable after CreateMessagePipe:%v", state.SatisfiedSignals)
-	}
-	if state.SatisfiableSignals != MOJO_HANDLE_SIGNAL_ALL {
-		t.Fatalf("state should allow all signals after CreateMessagePipe:%v", state.SatisfiableSignals)
-	}
-
-	r, state = h0.Wait(system.MOJO_HANDLE_SIGNAL_WRITABLE, system.MOJO_DEADLINE_INDEFINITE)
-	if r != system.MOJO_RESULT_OK {
-		t.Fatalf("h0 should be writable:%v", r)
-	}
-	if state.SatisfiedSignals != system.MOJO_HANDLE_SIGNAL_WRITABLE {
-		t.Fatalf("state should be signaled writable after core.Wait:%v", state.SatisfiedSignals)
-	}
-	if state.SatisfiableSignals != MOJO_HANDLE_SIGNAL_ALL {
-		t.Fatalf("state should allow all signals after core.Wait:%v", state.SatisfiableSignals)
-	}
-
-	if r, _, _ = h0.ReadMessage(system.MOJO_READ_MESSAGE_FLAG_NONE); r != system.MOJO_RESULT_SHOULD_WAIT {
-		t.Fatalf("Read on h0 did not return wait:%v", r)
-	}
-	kHello := []byte("hello")
-	if r = h1.WriteMessage(kHello, nil, system.MOJO_WRITE_MESSAGE_FLAG_NONE); r != system.MOJO_RESULT_OK {
-		t.Fatalf("Failed WriteMessage on h1:%v", r)
-	}
-
-	r, state = h0.Wait(system.MOJO_HANDLE_SIGNAL_READABLE, system.MOJO_DEADLINE_INDEFINITE)
-	if r != system.MOJO_RESULT_OK {
-		t.Fatalf("h0 should be readable after WriteMessage to h1:%v", r)
-	}
-	if state.SatisfiedSignals != MOJO_HANDLE_SIGNAL_READWRITABLE {
-		t.Fatalf("h0 should be signaled readable after WriteMessage to h1:%v", state.SatisfiedSignals)
-	}
-	if state.SatisfiableSignals != MOJO_HANDLE_SIGNAL_ALL {
-		t.Fatalf("h0 should be readable/writable after WriteMessage to h1:%v", state.SatisfiableSignals)
-	}
-	if !state.SatisfiableSignals.IsReadable() || !state.SatisfiableSignals.IsWritable() || !state.SatisfiableSignals.IsClosed() {
-		t.Fatalf("Helper functions are misbehaving")
-	}
-
-	r, msg, _ := h0.ReadMessage(system.MOJO_READ_MESSAGE_FLAG_NONE)
-	if r != system.MOJO_RESULT_OK {
-		t.Fatalf("Failed ReadMessage on h0:%v", r)
-	}
-	if !bytes.Equal(msg, kHello) {
-		t.Fatalf("Invalid message expected:%s, got:%s", kHello, msg)
-	}
-
-	r, index, states := core.WaitMany([]system.Handle{h0}, []system.MojoHandleSignals{system.MOJO_HANDLE_SIGNAL_READABLE}, 10)
-	if r != system.MOJO_RESULT_DEADLINE_EXCEEDED {
-		t.Fatalf("h0 should not be readable after reading message:%v", r)
-	}
-	if index != -1 {
-		t.Fatalf("should be no index after MOJO_RESULT_DEADLINE_EXCEEDED:%v", index)
-	}
-	if len(states) != 1 {
-		t.Fatalf("states should be set after WaitMany:%v", states)
-	}
-	if states[0].SatisfiedSignals != system.MOJO_HANDLE_SIGNAL_WRITABLE {
-		t.Fatalf("h0 should be signaled readable WaitMany:%v", states[0].SatisfiedSignals)
-	}
-	if states[0].SatisfiableSignals != MOJO_HANDLE_SIGNAL_ALL {
-		t.Fatalf("h0 should be readable/writable after WaitMany:%v", states[0].SatisfiableSignals)
-	}
-
-	if r = h0.Close(); r != system.MOJO_RESULT_OK {
-		t.Fatalf("Close on h0 failed:%v", r)
-	}
-
-	r, state = h1.Wait(MOJO_HANDLE_SIGNAL_READWRITABLE, system.MOJO_DEADLINE_INDEFINITE)
-	if r != system.MOJO_RESULT_FAILED_PRECONDITION {
-		t.Fatalf("h1 should not be readable/writable after Close(h0):%v", r)
-	}
-	if state.SatisfiedSignals != system.MOJO_HANDLE_SIGNAL_PEER_CLOSED {
-		t.Fatalf("state should be signaled closed after Close(h0):%v", state.SatisfiedSignals)
-	}
-	if state.SatisfiableSignals != system.MOJO_HANDLE_SIGNAL_PEER_CLOSED {
-		t.Fatalf("state should only be closable after Close(h0):%v", state.SatisfiableSignals)
-	}
-
-	if r = h1.Close(); r != system.MOJO_RESULT_OK {
-		t.Fatalf("Close on h1 failed:%v", r)
-	}
-}
-
-func TestDataPipe(t *testing.T) {
-	var hp system.ProducerHandle
-	var hc system.ConsumerHandle
-	var r system.MojoResult
-
-	if r, hp, hc = core.CreateDataPipe(nil); r != system.MOJO_RESULT_OK {
-		t.Fatalf("CreateDataPipe failed:%v", r)
-	}
-	if !hp.IsValid() || !hc.IsValid() {
-		t.Fatalf("CreateDataPipe returned invalid handles hp:%v hc:%v", hp, hc)
-	}
-	if r, _ = hc.Wait(system.MOJO_HANDLE_SIGNAL_READABLE, 0); r != system.MOJO_RESULT_DEADLINE_EXCEEDED {
-		t.Fatalf("hc should not be readable:%v", r)
-	}
-	if r, _ = hp.Wait(system.MOJO_HANDLE_SIGNAL_WRITABLE, system.MOJO_DEADLINE_INDEFINITE); r != system.MOJO_RESULT_OK {
-		t.Fatalf("hp should be writeable:%v", r)
-	}
-
-	// Test one-phase read/write.
-	// Writing.
-	kHello := []byte("hello")
-	r, numBytes := hp.WriteData(kHello, system.MOJO_WRITE_DATA_FLAG_NONE)
-	if r != system.MOJO_RESULT_OK || numBytes != len(kHello) {
-		t.Fatalf("Failed WriteData on hp:%v numBytes:%d", r, numBytes)
-	}
-	// Reading.
-	if r, _ = hc.Wait(system.MOJO_HANDLE_SIGNAL_READABLE, system.MOJO_DEADLINE_INDEFINITE); r != system.MOJO_RESULT_OK {
-		t.Fatalf("hc should be readable after WriteData on hp:%v", r)
-	}
-	r, data := hc.ReadData(system.MOJO_READ_DATA_FLAG_NONE)
-	if r != system.MOJO_RESULT_OK {
-		t.Fatalf("Failed ReadData on hc:%v", r)
-	}
-	if !bytes.Equal(data, kHello) {
-		t.Fatalf("Invalid data expected:%s, got:%s", kHello, data)
-	}
-
-	// Test two-phase read/write.
-	// Writing.
-	kHello = []byte("Hello, world!")
-	r, buf := hp.BeginWriteData(len(kHello), system.MOJO_WRITE_DATA_FLAG_ALL_OR_NONE)
-	if r != system.MOJO_RESULT_OK {
-		t.Fatalf("Failed BeginWriteData on hp:%v numBytes:%d", r, len(kHello))
-	}
-	if len(buf) < len(kHello) {
-		t.Fatalf("Buffer size(%d) should be at least %d", len(buf), len(kHello))
-	}
-	copy(buf, kHello)
-	if r, _ := hp.WriteData(kHello, system.MOJO_WRITE_DATA_FLAG_NONE); r != system.MOJO_RESULT_BUSY {
-		t.Fatalf("hp should be busy during a two-phase write: %v", r)
-	}
-	if r, _ = hc.Wait(system.MOJO_HANDLE_SIGNAL_READABLE, 0); r != system.MOJO_RESULT_DEADLINE_EXCEEDED {
-		t.Fatalf("hc shouldn't be readable before EndWriteData on hp:%v", r)
-	}
-	if r := hp.EndWriteData(len(kHello)); r != system.MOJO_RESULT_OK {
-		t.Fatalf("Failed EndWriteData on hp:%v", r)
-	}
-	// Reading.
-	if r, _ = hc.Wait(system.MOJO_HANDLE_SIGNAL_READABLE, system.MOJO_DEADLINE_INDEFINITE); r != system.MOJO_RESULT_OK {
-		t.Fatalf("hc should be readable after EndWriteData on hp:%v", r)
-	}
-	if r, buf = hc.BeginReadData(len(kHello), system.MOJO_READ_DATA_FLAG_ALL_OR_NONE); r != system.MOJO_RESULT_OK {
-		t.Fatalf("Failed BeginReadData on hc:%v numBytes:%d", r, len(kHello))
-	}
-	if len(buf) != len(kHello) {
-		t.Fatalf("Buffer size(%d) should be equal to %d", len(buf), len(kHello))
-	}
-	if r, _ := hc.ReadData(system.MOJO_READ_DATA_FLAG_NONE); r != system.MOJO_RESULT_BUSY {
-		t.Fatalf("hc should be busy during a two-phase read: %v", r)
-	}
-	if !bytes.Equal(buf, kHello) {
-		t.Fatalf("Invalid data expected:%s, got:%s", kHello, buf)
-	}
-	if r := hc.EndReadData(len(buf)); r != system.MOJO_RESULT_OK {
-		t.Fatalf("Failed EndReadData on hc:%v", r)
-	}
-
-	if r = hp.Close(); r != system.MOJO_RESULT_OK {
-		t.Fatalf("Close on hp failed:%v", r)
-	}
-	if r, _ = hc.Wait(system.MOJO_HANDLE_SIGNAL_READABLE, system.MOJO_DEADLINE_INDEFINITE); r != system.MOJO_RESULT_FAILED_PRECONDITION {
-		t.Fatalf("hc should not be readable after hp closed:%v", r)
-	}
-	if r = hc.Close(); r != system.MOJO_RESULT_OK {
-		t.Fatalf("Close on hc failed:%v", r)
-	}
-}
-
-func TestSharedBuffer(t *testing.T) {
-	var h0, h1 system.SharedBufferHandle
-	var buf []byte
-	var r system.MojoResult
-
-	if r, h0 = core.CreateSharedBuffer(nil, 100); r != system.MOJO_RESULT_OK {
-		t.Fatalf("CreateSharedBuffer failed:%v", r)
-	}
-	if !h0.IsValid() {
-		t.Fatalf("CreateSharedBuffer returned an invalid handle h0:%v", h0)
-	}
-	if r, buf = h0.MapBuffer(0, 100, system.MOJO_MAP_BUFFER_FLAG_NONE); r != system.MOJO_RESULT_OK {
-		t.Fatalf("MapBuffer failed to map buffer with h0:%v", r)
-	}
-	if len(buf) != 100 || cap(buf) != 100 {
-		t.Fatalf("Buffer length(%d) and capacity(%d) should be %d", len(buf), cap(buf), 100)
-	}
-	buf[50] = 'x'
-	if r, h1 = h0.DuplicateBufferHandle(nil); r != system.MOJO_RESULT_OK {
-		t.Fatalf("DuplicateBufferHandle of h0 failed:%v", r)
-	}
-	if !h1.IsValid() {
-		t.Fatalf("DuplicateBufferHandle returned an invalid handle h1:%v", h1)
-	}
-	if r = h0.Close(); r != system.MOJO_RESULT_OK {
-		t.Fatalf("Close on h0 failed:%v", r)
-	}
-	buf[51] = 'y'
-	if r = h1.UnmapBuffer(buf); r != system.MOJO_RESULT_OK {
-		t.Fatalf("UnmapBuffer failed:%v", r)
-	}
-	if r, buf = h1.MapBuffer(50, 50, system.MOJO_MAP_BUFFER_FLAG_NONE); r != system.MOJO_RESULT_OK {
-		t.Fatalf("MapBuffer failed to map buffer with h1:%v", r)
-	}
-	if len(buf) != 50 || cap(buf) != 50 {
-		t.Fatalf("Buffer length(%d) and capacity(%d) should be %d", len(buf), cap(buf), 50)
-	}
-	if buf[0] != 'x' || buf[1] != 'y' {
-		t.Fatalf("Failed to validate shared buffer. expected:x,y got:%s,%s", buf[0], buf[1])
-	}
-	if r = h1.UnmapBuffer(buf); r != system.MOJO_RESULT_OK {
-		t.Fatalf("UnmapBuffer failed:%v", r)
-	}
-	if r = h1.Close(); r != system.MOJO_RESULT_OK {
-		t.Fatalf("Close on h1 failed:%v", r)
-	}
-}
diff --git a/mojo/go/tests/testutil.go b/mojo/go/tests/testutil.go
deleted file mode 100644
index 99d33f7..0000000
--- a/mojo/go/tests/testutil.go
+++ /dev/null
@@ -1,203 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package tests
-
-import (
-	"encoding/binary"
-	"fmt"
-	"math"
-	"strings"
-
-	"mojo/go/system/embedder"
-	"mojo/public/go/bindings"
-	"mojo/public/go/system"
-)
-
-var core system.Core
-var waiter bindings.AsyncWaiter
-
-func init() {
-	embedder.InitializeMojoEmbedder()
-	core = system.GetCore()
-	waiter = bindings.GetAsyncWaiter()
-}
-
-type mockHandle struct {
-	bindings.InvalidHandle
-	handle system.MojoHandle
-}
-
-func (h *mockHandle) IsValid() bool {
-	return true
-}
-
-func (h *mockHandle) ReleaseNativeHandle() system.MojoHandle {
-	return h.handle
-}
-
-func (h *mockHandle) ToUntypedHandle() system.UntypedHandle {
-	return h
-}
-
-func (h *mockHandle) ToConsumerHandle() system.ConsumerHandle {
-	return h
-}
-
-func (h *mockHandle) ToProducerHandle() system.ProducerHandle {
-	return h
-}
-
-func (h *mockHandle) ToMessagePipeHandle() system.MessagePipeHandle {
-	return h
-}
-
-func (h *mockHandle) ToSharedBufferHandle() system.SharedBufferHandle {
-	return h
-}
-
-// inputParser parses validation tests input format as described in
-// |mojo/public/cpp/bindings/tests/validation_test_input_parser.h|
-type inputParser struct {
-}
-
-type dataItem struct {
-	Type  string
-	Value string
-}
-
-type pointerPlaceholder struct {
-	Position int
-	Size     int
-}
-
-func (p *inputParser) parseToDataItems(s string) []dataItem {
-	var items []dataItem
-	s = strings.TrimSpace(s)
-	for len(s) > 0 {
-		// Parsing data item type.
-		var itemType string
-		if s[0] == '[' {
-			closeBracket := strings.Index(s, "]")
-			if closeBracket == -1 {
-				panic("unmatched left [")
-			}
-			itemType = strings.TrimSpace(s[1:closeBracket])
-			s = strings.TrimSpace(s[closeBracket+1:])
-		} else {
-			itemType = "u1"
-		}
-
-		// Parsing data item value.
-		itemEnd := strings.IndexAny(s, "[ \t\n\r")
-		if itemEnd == -1 {
-			items = append(items, dataItem{itemType, strings.TrimSpace(s)})
-			s = ""
-		} else {
-			items = append(items, dataItem{itemType, strings.TrimSpace(s[:itemEnd])})
-			s = strings.TrimSpace(s[itemEnd:])
-		}
-	}
-	return items
-}
-
-// Parse parses a validation tests input string that has no comments.
-// Panics if input has errors.
-func (p *inputParser) Parse(s string) ([]byte, []system.UntypedHandle) {
-	var bytes []byte
-	var buf [8]byte
-	// We need non-nil slice for comparing values with reflect.DeepEqual.
-	handles := []system.UntypedHandle{}
-	pointers := make(map[string]pointerPlaceholder)
-	for _, item := range p.parseToDataItems(s) {
-		switch item.Type {
-		case "u1":
-			var value uint8
-			fmt.Sscan(item.Value, &value)
-			bytes = append(bytes, byte(value))
-		case "u2":
-			var value uint16
-			fmt.Sscan(item.Value, &value)
-			binary.LittleEndian.PutUint16(buf[:2], value)
-			bytes = append(bytes, buf[:2]...)
-		case "u4":
-			var value uint32
-			fmt.Sscan(item.Value, &value)
-			binary.LittleEndian.PutUint32(buf[:4], value)
-			bytes = append(bytes, buf[:4]...)
-		case "u8":
-			var value uint64
-			fmt.Sscan(item.Value, &value)
-			binary.LittleEndian.PutUint64(buf[:8], value)
-			bytes = append(bytes, buf[:8]...)
-		case "s1":
-			var value int8
-			fmt.Sscan(item.Value, &value)
-			bytes = append(bytes, byte(value))
-		case "s2":
-			var value int16
-			fmt.Sscan(item.Value, &value)
-			binary.LittleEndian.PutUint16(buf[:2], uint16(value))
-			bytes = append(bytes, buf[:2]...)
-		case "s4":
-			var value int32
-			fmt.Sscan(item.Value, &value)
-			binary.LittleEndian.PutUint32(buf[:4], uint32(value))
-			bytes = append(bytes, buf[:4]...)
-		case "s8":
-			var value int64
-			fmt.Sscan(item.Value, &value)
-			binary.LittleEndian.PutUint64(buf[:8], uint64(value))
-			bytes = append(bytes, buf[:8]...)
-		case "b":
-			var value byte
-			for i := 0; i < 8; i++ {
-				value <<= 1
-				if item.Value[i] == '1' {
-					value++
-				}
-			}
-			bytes = append(bytes, value)
-		case "f":
-			var value float32
-			fmt.Sscan(item.Value, &value)
-			binary.LittleEndian.PutUint32(buf[:4], math.Float32bits(value))
-			bytes = append(bytes, buf[:4]...)
-		case "d":
-			var value float64
-			fmt.Sscan(item.Value, &value)
-			binary.LittleEndian.PutUint64(buf[:8], math.Float64bits(value))
-			bytes = append(bytes, buf[:8]...)
-		case "dist4":
-			pointers[item.Value] = pointerPlaceholder{len(bytes), 4}
-			bytes = append(bytes, buf[:4]...)
-		case "dist8":
-			pointers[item.Value] = pointerPlaceholder{len(bytes), 8}
-			bytes = append(bytes, buf[:8]...)
-		case "anchr":
-			placeholder := pointers[item.Value]
-			dist := len(bytes) - placeholder.Position
-			switch placeholder.Size {
-			case 4:
-				binary.LittleEndian.PutUint32(bytes[placeholder.Position:], uint32(dist))
-			case 8:
-				binary.LittleEndian.PutUint64(bytes[placeholder.Position:], uint64(dist))
-			}
-			delete(pointers, item.Value)
-		case "handles":
-			var value int
-			fmt.Sscan(item.Value, &value)
-			handles = make([]system.UntypedHandle, value)
-			for i, _ := range handles {
-				handles[i] = &mockHandle{handle: system.MojoHandle(i + 1)}
-			}
-		default:
-			panic(fmt.Sprintf("unsupported item type: %v", item.Type))
-		}
-	}
-	if len(pointers) != 0 {
-		panic(fmt.Sprintf("unmatched pointers: %v", pointers))
-	}
-	return bytes, handles
-}
diff --git a/mojo/go/tests/testutil_test.go b/mojo/go/tests/testutil_test.go
deleted file mode 100644
index 36c0e7c..0000000
--- a/mojo/go/tests/testutil_test.go
+++ /dev/null
@@ -1,64 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package tests
-
-import (
-	"bytes"
-	"encoding/binary"
-	"math"
-	"testing"
-)
-
-func verifyInputParser(t *testing.T, s string, expected []byte, handlesCount int) {
-	parser := &inputParser{}
-	b, h := parser.Parse(s)
-	if !bytes.Equal(b, expected) {
-		t.Fatalf("unexpected byte slice after parsing %v: expected %v, got %v", s, expected, b)
-	}
-	if len(h) != handlesCount {
-		t.Fatalf("unexpected handles count after parsing %v: expected %v, got %v", s, handlesCount, len(h))
-	}
-}
-
-func TestInputParser(t *testing.T) {
-	var buf []byte
-	buf = make([]byte, 1+2+4+8+1+1)
-	buf[0] = 0x10
-	binary.LittleEndian.PutUint16(buf[1:], 65535)
-	binary.LittleEndian.PutUint32(buf[3:], 65536)
-	binary.LittleEndian.PutUint64(buf[7:], 0xFFFFFFFFFFFFFFFF)
-	buf[15] = 0
-	buf[16] = 0xFF
-	verifyInputParser(t, "[u1]0x10 [u2]65535 [u4]65536 [u8]0xFFFFFFFFFFFFFFFF 0 0Xff", buf, 0)
-
-	buf = make([]byte, 8+1+2+4)
-	binary.LittleEndian.PutUint64(buf[0:], math.MaxUint64-0x800+1)
-	buf[8] = math.MaxUint8 - 128 + 1
-	binary.LittleEndian.PutUint16(buf[9:], 0)
-	binary.LittleEndian.PutUint32(buf[11:], math.MaxUint32-40+1)
-	verifyInputParser(t, "[s8]-0x800 [s1]-128\t[s2]+0 [s4]-40", buf, 0)
-
-	buf = make([]byte, 1+1+1)
-	buf[0] = 11
-	buf[1] = 0x80
-	buf[2] = 0
-	verifyInputParser(t, "[b]00001011 [b]10000000  \r [b]00000000", buf, 0)
-
-	buf = make([]byte, 4+8)
-	binary.LittleEndian.PutUint32(buf[0:], math.Float32bits(+.3e9))
-	binary.LittleEndian.PutUint64(buf[4:], math.Float64bits(-10.03))
-	verifyInputParser(t, "[f]+.3e9 [d]-10.03", buf, 0)
-
-	buf = make([]byte, 4+1+8+1)
-	binary.LittleEndian.PutUint32(buf[0:], 14)
-	buf[4] = 0
-	binary.LittleEndian.PutUint64(buf[5:], 9)
-	buf[13] = 0
-	verifyInputParser(t, "[dist4]foo 0 [dist8]bar 0 [anchr]foo [anchr]bar", buf, 0)
-
-	buf = make([]byte, 8)
-	binary.LittleEndian.PutUint64(buf[0:], 2)
-	verifyInputParser(t, "[handles]50 [u8]2", buf, 50)
-}
diff --git a/mojo/go/tests/union_test.go b/mojo/go/tests/union_test.go
deleted file mode 100644
index 9e8847c..0000000
--- a/mojo/go/tests/union_test.go
+++ /dev/null
@@ -1,184 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package tests
-
-import (
-	"testing"
-
-	"mojo/public/go/bindings"
-	"mojo/public/go/system"
-	"mojo/public/interfaces/bindings/tests/test_unions"
-)
-
-type Encodable interface {
-	Encode(encoder *bindings.Encoder) error
-}
-
-func TestPodUnion(t *testing.T) {
-	tests := []test_unions.PodUnion{
-		&test_unions.PodUnionFInt8{8},
-		&test_unions.PodUnionFInt16{16},
-		&test_unions.PodUnionFUint64{64},
-		&test_unions.PodUnionFBool{true},
-		&test_unions.PodUnionFEnum{test_unions.AnEnum_Second},
-	}
-
-	for _, union := range tests {
-		var wrapper, zeroWrapper test_unions.WrapperStruct
-		wrapper.PodUnion = union
-		check(t, &wrapper, &zeroWrapper)
-	}
-}
-
-func TestHandleUnion(t *testing.T) {
-	tests := []test_unions.HandleUnion{
-		&test_unions.HandleUnionFHandle{system.Handle(&mockHandle{handle: 1})},
-		&test_unions.HandleUnionFMessagePipe{system.MessagePipeHandle(&mockHandle{handle: 2})},
-		&test_unions.HandleUnionFDataPipeConsumer{system.ConsumerHandle(&mockHandle{handle: 3})},
-		&test_unions.HandleUnionFDataPipeProducer{system.ProducerHandle(&mockHandle{handle: 4})},
-		&test_unions.HandleUnionFSharedBuffer{system.SharedBufferHandle(&mockHandle{handle: 5})},
-	}
-
-	for _, union := range tests {
-		var wrapper, zeroWrapper test_unions.WrapperStruct
-		wrapper.HandleUnion = union
-		check(t, &wrapper, &zeroWrapper)
-	}
-}
-
-func TestObjectUnion(t *testing.T) {
-	tests := []test_unions.ObjectUnion{
-		&test_unions.ObjectUnionFDummy{test_unions.DummyStruct{10}},
-		&test_unions.ObjectUnionFArrayInt8{[]int8{1, 2, 3, 4}},
-		&test_unions.ObjectUnionFMapInt8{map[string]int8{"hello": 1, "world": 2}},
-		&test_unions.ObjectUnionFNullable{},
-		&test_unions.ObjectUnionFPodUnion{&test_unions.PodUnionFInt8{8}},
-		&test_unions.ObjectUnionFPodUnion{&test_unions.PodUnionFInt64{64}},
-		&test_unions.ObjectUnionFPodUnion{&test_unions.PodUnionFBool{true}},
-		&test_unions.ObjectUnionFPodUnion{&test_unions.PodUnionFEnum{test_unions.AnEnum_Second}},
-	}
-
-	for _, union := range tests {
-		var wrapper, zeroWrapper test_unions.WrapperStruct
-		wrapper.ObjectUnion = union
-		check(t, &wrapper, &zeroWrapper)
-	}
-}
-
-func encode(t *testing.T, value Encodable) ([]byte, []system.UntypedHandle, error) {
-	encoder := bindings.NewEncoder()
-	err := value.Encode(encoder)
-	if err != nil {
-		return nil, nil, err
-	}
-
-	bytes, handles, err := encoder.Data()
-	if err != nil {
-		return nil, nil, err
-	}
-
-	return bytes, handles, nil
-}
-
-func TestNonNullableNullInUnion(t *testing.T) {
-	var wrapper test_unions.WrapperStruct
-	fdummy := test_unions.ObjectUnionFDummy{test_unions.DummyStruct{10}}
-	wrapper.ObjectUnion = &fdummy
-
-	bytes, handles, _ := encode(t, &wrapper)
-	bytes[16] = 0
-
-	var decoded test_unions.WrapperStruct
-	decoder := bindings.NewDecoder(bytes, handles)
-
-	if err := decoded.Decode(decoder); err == nil {
-		t.Fatalf("Null non-nullable should have failed validation.")
-	}
-}
-
-func TestUnionInStruct(t *testing.T) {
-	var ss, out test_unions.SmallStruct
-	ss.PodUnion = &test_unions.PodUnionFInt8{10}
-	check(t, &ss, &out)
-
-	bytes, _, _ := encode(t, &ss)
-	if int(bytes[8*2]) != 16 {
-		t.Fatalf("Union does not start at the correct location in struct.")
-	}
-}
-
-func TestUnionInArray(t *testing.T) {
-	var ss, out test_unions.SmallStruct
-	ss.PodUnionArray = &[]test_unions.PodUnion{
-		&test_unions.PodUnionFInt8{8},
-		&test_unions.PodUnionFInt16{16},
-		&test_unions.PodUnionFUint64{64},
-		&test_unions.PodUnionFBool{true},
-		&test_unions.PodUnionFEnum{test_unions.AnEnum_Second},
-	}
-	check(t, &ss, &out)
-}
-
-func TestUnionInArrayNullNullable(t *testing.T) {
-	var ss, out test_unions.SmallStruct
-	ss.NullablePodUnionArray = &[]test_unions.PodUnion{
-		nil,
-		&test_unions.PodUnionFInt8{8},
-		&test_unions.PodUnionFInt16{16},
-		&test_unions.PodUnionFUint64{64},
-		&test_unions.PodUnionFBool{true},
-		&test_unions.PodUnionFEnum{test_unions.AnEnum_Second},
-	}
-	check(t, &ss, &out)
-}
-
-func TestUnionInArrayNonNullableNull(t *testing.T) {
-	// Encoding should fail
-	var ss test_unions.SmallStruct
-	ss.PodUnionArray = &[]test_unions.PodUnion{
-		nil,
-		&test_unions.PodUnionFInt8{8},
-		&test_unions.PodUnionFInt16{16},
-		&test_unions.PodUnionFUint64{64},
-		&test_unions.PodUnionFBool{true},
-		&test_unions.PodUnionFEnum{test_unions.AnEnum_Second},
-	}
-
-	_, _, err := encode(t, &ss)
-	if typedErr := err.(*bindings.ValidationError); typedErr.ErrorCode != bindings.UnexpectedNullUnion {
-		t.Fatalf("Non-nullable null should have failed to encode.")
-	}
-
-	// Decoding should also fail
-	ss.PodUnionArray = &[]test_unions.PodUnion{
-		&test_unions.PodUnionFInt8{8},
-		&test_unions.PodUnionFInt16{16},
-		&test_unions.PodUnionFUint64{64},
-		&test_unions.PodUnionFBool{true},
-		&test_unions.PodUnionFEnum{test_unions.AnEnum_Second},
-	}
-	bytes, handles, _ := encode(t, &ss)
-
-	// Set first union to null.
-	bytes[8*10] = 0
-	var decoded test_unions.SmallStruct
-	decoder := bindings.NewDecoder(bytes, handles)
-	err = decoded.Decode(decoder)
-	if typedErr := err.(*bindings.ValidationError); typedErr.ErrorCode != bindings.UnexpectedNullUnion {
-		t.Fatalf("Null non-nullable should have failed to decode.")
-	}
-}
-
-func TestUnionInMap(t *testing.T) {
-	var ss, out test_unions.SmallStruct
-	ss.PodUnionMap = &map[string]test_unions.PodUnion{
-		"eight":      &test_unions.PodUnionFInt8{8},
-		"sixteen":    &test_unions.PodUnionFInt16{16},
-		"sixty-four": &test_unions.PodUnionFUint64{64},
-		"bool":       &test_unions.PodUnionFBool{true},
-		"enum":       &test_unions.PodUnionFEnum{test_unions.AnEnum_Second},
-	}
-	check(t, &ss, &out)
-}
diff --git a/mojo/go/tests/validation_test.go b/mojo/go/tests/validation_test.go
deleted file mode 100644
index b3120e0..0000000
--- a/mojo/go/tests/validation_test.go
+++ /dev/null
@@ -1,453 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package tests
-
-import (
-	"fmt"
-	"io/ioutil"
-	"os"
-	"path/filepath"
-	"reflect"
-	"strings"
-	"testing"
-
-	"mojo/public/go/bindings"
-	"mojo/public/go/system"
-	test "mojo/public/interfaces/bindings/tests/validation_test_interfaces"
-)
-
-func getTestPath(name string) string {
-	// TODO(rogulenko): try to get a better solution.
-	// This should be .../out/name{Debug|Release}/obj/mojo/go.
-	dir, err := filepath.Abs(filepath.Dir(os.Args[0]))
-	if err != nil {
-		panic(err)
-	}
-	// Go 5 folders up.
-	for i := 0; i < 5; i++ {
-		dir = filepath.Dir(dir)
-	}
-	testsFolder := filepath.Join("mojo", "public", "interfaces", "bindings", "tests", "data", "validation")
-	if name != "" {
-		return filepath.Join(dir, testsFolder, name)
-	} else {
-		return filepath.Join(dir, testsFolder)
-	}
-}
-
-func listTestFiles() []string {
-	files, err := ioutil.ReadDir(getTestPath(""))
-	if err != nil {
-		panic(err)
-	}
-	var fileNames []string
-	for _, file := range files {
-		if file.Mode().IsRegular() {
-			fileNames = append(fileNames, file.Name())
-		}
-	}
-	return fileNames
-}
-
-func getMatchingTests(fileNames []string, prefix string) []string {
-	var result []string
-	extension := ".data"
-	for _, fileName := range fileNames {
-		if strings.HasPrefix(fileName, prefix) && strings.HasSuffix(fileName, extension) {
-			result = append(result, strings.TrimSuffix(fileName, extension))
-		}
-	}
-	if len(result) == 0 {
-		panic("empty test list")
-	}
-	return result
-}
-
-func readTest(testName string) ([]byte, []system.UntypedHandle) {
-	content, err := ioutil.ReadFile(getTestPath(testName + ".data"))
-	if err != nil {
-		panic(err)
-	}
-	lines := strings.Split(strings.Replace(string(content), "\r", "\n", -1), "\n")
-	for i, _ := range lines {
-		lines[i] = strings.Split(lines[i], "//")[0]
-	}
-	parser := &inputParser{}
-	bytes, handles := parser.Parse(strings.Join(lines, " "))
-	return bytes, handles
-}
-
-func readAnswer(testName string) string {
-	content, err := ioutil.ReadFile(getTestPath(testName + ".expected"))
-	if err != nil {
-		panic(err)
-	}
-	return strings.TrimSpace(string(content))
-}
-
-func pipeOwner(h system.MessagePipeHandle) bindings.MessagePipeHandleOwner {
-	return bindings.NewMessagePipeHandleOwner(h)
-}
-
-type rawMessage struct {
-	Bytes   []byte
-	Handles []system.UntypedHandle
-}
-
-type mockMessagePipeHandle struct {
-	bindings.InvalidHandle
-	messages chan rawMessage
-}
-
-func NewMockMessagePipeHandle() *mockMessagePipeHandle {
-	h := &mockMessagePipeHandle{}
-	h.messages = make(chan rawMessage, 10)
-	return h
-}
-
-func (h *mockMessagePipeHandle) reset() {
-	h.messages = make(chan rawMessage, 10)
-}
-
-func (h *mockMessagePipeHandle) IsValid() bool {
-	return true
-}
-
-func (h *mockMessagePipeHandle) ToUntypedHandle() system.UntypedHandle {
-	return h
-}
-
-func (h *mockMessagePipeHandle) ToMessagePipeHandle() system.MessagePipeHandle {
-	return h
-}
-
-func (h *mockMessagePipeHandle) ReadMessage(flags system.MojoReadMessageFlags) (system.MojoResult, []byte, []system.UntypedHandle) {
-	message := <-h.messages
-	return system.MOJO_RESULT_OK, message.Bytes, message.Handles
-}
-
-func (h *mockMessagePipeHandle) WriteMessage(bytes []byte, handles []system.UntypedHandle, flags system.MojoWriteMessageFlags) system.MojoResult {
-	h.messages <- rawMessage{bytes, handles}
-	return system.MOJO_RESULT_OK
-}
-
-type conformanceValidator struct {
-	CheckArgs bool
-	Proxy     test.ConformanceTestInterface
-}
-
-func (v *conformanceValidator) Method0(inParam0 float32) error {
-	if !v.CheckArgs {
-		return nil
-	}
-	param0 := float32(-1)
-	if inParam0 != param0 {
-		return fmt.Errorf("unexpected value (Method0, inParam0): expected %v, got %v", param0, inParam0)
-	}
-	return v.Proxy.Method0(inParam0)
-}
-
-func (v *conformanceValidator) Method1(inParam0 test.StructA) error {
-	if !v.CheckArgs {
-		return nil
-	}
-	param0 := test.StructA{1234}
-	if !reflect.DeepEqual(inParam0, param0) {
-		return fmt.Errorf("unexpected value (Method1, inParam0): expected %v, got %v", param0, inParam0)
-	}
-	return v.Proxy.Method1(inParam0)
-}
-
-func (v *conformanceValidator) Method2(inParam0 test.StructB, inParam1 test.StructA) error {
-	if !v.CheckArgs {
-		return nil
-	}
-	param0 := test.StructB{test.StructA{12345}}
-	param1 := test.StructA{67890}
-	if !reflect.DeepEqual(inParam0, param0) {
-		return fmt.Errorf("unexpected value (Method2, inParam0): expected %v, got %v", param0, inParam0)
-	}
-	if !reflect.DeepEqual(inParam1, param1) {
-		return fmt.Errorf("unexpected value (Method2, inParam1): expected %v, got %v", param1, inParam1)
-	}
-	return v.Proxy.Method2(inParam0, inParam1)
-}
-
-func (v *conformanceValidator) Method3(inParam0 []bool) error {
-	if !v.CheckArgs {
-		return nil
-	}
-	param0 := []bool{true, false, true, false, true, false, true, false, true, true, true, true}
-	if !reflect.DeepEqual(inParam0, param0) {
-		return fmt.Errorf("unexpected value (Method3, inParam0): expected %v, got %v", param0, inParam0)
-	}
-	return v.Proxy.Method3(inParam0)
-}
-
-func (v *conformanceValidator) Method4(inParam0 test.StructC, inParam1 []uint8) error {
-	if !v.CheckArgs {
-		return nil
-	}
-	param0 := test.StructC{[]uint8{0, 1, 2}}
-	param1 := []uint8{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
-	if !reflect.DeepEqual(inParam0, param0) {
-		return fmt.Errorf("unexpected value (Method4, inParam0): expected %v, got %v", param0, inParam0)
-	}
-	if !reflect.DeepEqual(inParam1, param1) {
-		return fmt.Errorf("unexpected value (Method4, inParam1): expected %v, got %v", param1, inParam1)
-	}
-	return v.Proxy.Method4(inParam0, inParam1)
-}
-
-func (v *conformanceValidator) Method5(inParam0 test.StructE, inParam1 system.ProducerHandle) error {
-	if !v.CheckArgs {
-		return nil
-	}
-	param0 := test.StructE{
-		test.StructD{[]system.MessagePipeHandle{
-			&mockHandle{handle: 1},
-			&mockHandle{handle: 2},
-		}},
-		&mockHandle{handle: 4},
-	}
-	param1 := &mockHandle{handle: 5}
-	if !reflect.DeepEqual(inParam0, param0) {
-		return fmt.Errorf("unexpected value (Method5, inParam0): expected %v, got %v", param0, inParam0)
-	}
-	if !reflect.DeepEqual(inParam1, param1) {
-		return fmt.Errorf("unexpected value (Method5, inParam1): expected %v, got %v", param1, inParam1)
-	}
-	return v.Proxy.Method5(inParam0, inParam1)
-}
-
-func (v *conformanceValidator) Method6(inParam0 [][]uint8) error {
-	if !v.CheckArgs {
-		return nil
-	}
-	param0 := [][]uint8{[]uint8{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}}
-	if !reflect.DeepEqual(inParam0, param0) {
-		return fmt.Errorf("unexpected value (Method6, inParam0): expected %v, got %v", param0, inParam0)
-	}
-	return v.Proxy.Method6(inParam0)
-}
-
-func (v *conformanceValidator) Method7(inParam0 test.StructF, inParam1 [2]*[3]uint8) error {
-	if !v.CheckArgs {
-		return nil
-	}
-	param0 := test.StructF{[3]uint8{0, 1, 2}}
-	param1 := [2]*[3]uint8{
-		nil,
-		&[3]uint8{0, 1, 2},
-	}
-	if !reflect.DeepEqual(inParam0, param0) {
-		return fmt.Errorf("unexpected value (Method7, inParam0): expected %v, got %v", param0, inParam0)
-	}
-	if !reflect.DeepEqual(inParam1, param1) {
-		return fmt.Errorf("unexpected value (Method7, inParam1): expected %v, got %v", param1, inParam1)
-	}
-	return v.Proxy.Method7(inParam0, inParam1)
-}
-
-func (v *conformanceValidator) Method8(inParam0 []*[]string) error {
-	if !v.CheckArgs {
-		return nil
-	}
-	param0 := []*[]string{
-		nil,
-		&[]string{string([]byte{0, 1, 2, 3, 4})},
-		nil,
-	}
-	if !reflect.DeepEqual(inParam0, param0) {
-		return fmt.Errorf("unexpected value (Method8, inParam0): expected %v, got %v", param0, inParam0)
-	}
-	return v.Proxy.Method8(inParam0)
-}
-
-func (v *conformanceValidator) Method9(inParam0 *[][]*system.Handle) error {
-	if !v.CheckArgs {
-		return nil
-	}
-	handles := []system.Handle{
-		&mockHandle{handle: 1},
-		&mockHandle{handle: 3},
-		&mockHandle{handle: 4},
-	}
-	param0 := &[][]*system.Handle{
-		[]*system.Handle{&handles[0], nil},
-		[]*system.Handle{&handles[1], nil, &handles[2]},
-	}
-	if !reflect.DeepEqual(inParam0, param0) {
-		return fmt.Errorf("unexpected value (Method9, inParam0): expected %v, got %v", param0, inParam0)
-	}
-	return v.Proxy.Method9(inParam0)
-}
-
-func (v *conformanceValidator) Method10(inParam0 map[string]uint8) error {
-	if !v.CheckArgs {
-		return nil
-	}
-	param0 := map[string]uint8{
-		string([]byte{0, 1, 2, 3, 4}): 1,
-		string([]byte{5, 6, 7, 8, 9}): 2,
-	}
-	if !reflect.DeepEqual(inParam0, param0) {
-		return fmt.Errorf("unexpected value (Method10, inParam0): expected %v, got %v", param0, inParam0)
-	}
-	return v.Proxy.Method10(inParam0)
-}
-
-func (v *conformanceValidator) Method11(test.StructG) error {
-	return nil
-}
-
-func (v *conformanceValidator) Method12(float32) (float32, error) {
-	return 0, nil
-}
-
-func (v *conformanceValidator) Method13(*test.InterfaceA_Pointer, uint32, *test.InterfaceA_Pointer) error {
-	return nil
-}
-
-func verifyValidationError(t *testing.T, test string, err error, answer string) {
-	if (err == nil) != (answer == "PASS") {
-		t.Fatalf("unexpected result for test %v: %v", test, err)
-	}
-	if answer != "PASS" {
-		validationError, ok := err.(*bindings.ValidationError)
-		if !ok {
-			t.Fatalf("can't convert err '%v' to ValidationError in test %v", err, test)
-		}
-		code := validationError.ErrorCode
-		if code != answer {
-			t.Fatalf("unexpected error code in test %v: got %v(%v), want %v", test, code, err, answer)
-		}
-	}
-}
-
-func TestConformanceValidation(t *testing.T) {
-	tests := getMatchingTests(listTestFiles(), "conformance_")
-
-	h := NewMockMessagePipeHandle()
-	proxyIn, proxyOut := h, h
-	interfacePointer := test.ConformanceTestInterface_Pointer{pipeOwner(proxyIn)}
-	impl := &conformanceValidator{false, test.NewConformanceTestInterfaceProxy(interfacePointer, waiter)}
-
-	h = NewMockMessagePipeHandle()
-	stubIn, stubOut := h, h
-	interfaceRequest := test.ConformanceTestInterface_Request{pipeOwner(stubOut)}
-	stub := test.NewConformanceTestInterfaceStub(interfaceRequest, impl, waiter)
-	for _, test := range tests {
-		bytes, handles := readTest(test)
-		answer := readAnswer(test)
-		impl.CheckArgs = strings.HasSuffix(test, "_good")
-		stubIn.WriteMessage(bytes, handles, system.MOJO_WRITE_MESSAGE_FLAG_NONE)
-		err := stub.ServeRequest()
-		verifyValidationError(t, test, err, answer)
-
-		if !impl.CheckArgs {
-			continue
-		}
-		// Decode again to verify correctness of encoding.
-		_, bytes, handles = proxyOut.ReadMessage(system.MOJO_READ_MESSAGE_FLAG_NONE)
-		stubIn.WriteMessage(bytes, handles, system.MOJO_WRITE_MESSAGE_FLAG_NONE)
-		if err := stub.ServeRequest(); err != nil {
-			t.Fatalf("error processing encoded data for test %v: %v", test, err)
-		}
-		proxyOut.ReadMessage(system.MOJO_READ_MESSAGE_FLAG_NONE)
-		// Do not compare encoded bytes, as some tests contain maps, that
-		// can be encoded randomly.
-	}
-}
-
-func runTests(t *testing.T, prefix string, in *mockMessagePipeHandle, check func() error) {
-	tests := getMatchingTests(listTestFiles(), prefix)
-	for _, test := range tests {
-		bytes, handles := readTest(test)
-		answer := readAnswer(test)
-		// Replace request ID to match proxy numbers.
-		if bytes[0] == 24 {
-			bytes[16] = 1
-		}
-		in.WriteMessage(bytes, handles, system.MOJO_WRITE_MESSAGE_FLAG_NONE)
-		verifyValidationError(t, test, check(), answer)
-	}
-}
-
-type integrationStubImpl struct{}
-
-func (s *integrationStubImpl) Method0(test.BasicStruct) ([]uint8, error) {
-	return nil, nil
-}
-
-func TestIntegrationTests(t *testing.T) {
-	h := NewMockMessagePipeHandle()
-	checkStub := func() error {
-		interfaceRequest := test.IntegrationTestInterface_Request{pipeOwner(h)}
-		stub := test.NewIntegrationTestInterfaceStub(interfaceRequest, &integrationStubImpl{}, waiter)
-		err := stub.ServeRequest()
-		stub.Close()
-		h.reset()
-		return err
-	}
-	runTests(t, "integration_intf_rqst_", h, checkStub)
-	runTests(t, "integration_msghdr_", h, checkStub)
-
-	checkProxy := func() error {
-		interfacePointer := test.IntegrationTestInterface_Pointer{pipeOwner(h)}
-		proxy := test.NewIntegrationTestInterfaceProxy(interfacePointer, waiter)
-		_, err := proxy.Method0(test.BasicStruct{})
-		proxy.Close_Proxy()
-		h.reset()
-		return err
-	}
-	runTests(t, "integration_intf_resp_", h, checkProxy)
-	runTests(t, "integration_msghdr_", h, checkProxy)
-}
-
-type boundsCheckStubImpl struct{}
-
-func (s *boundsCheckStubImpl) Method0(uint8) (uint8, error) {
-	return 0, nil
-}
-
-func (s *boundsCheckStubImpl) Method1(uint8) error {
-	return nil
-}
-
-func TestBoundsCheck(t *testing.T) {
-	h := NewMockMessagePipeHandle()
-	checkStub := func() error {
-		interfaceRequest := test.BoundsCheckTestInterface_Request{pipeOwner(h)}
-		stub := test.NewBoundsCheckTestInterfaceStub(interfaceRequest, &boundsCheckStubImpl{}, waiter)
-		err := stub.ServeRequest()
-		stub.Close()
-		return err
-	}
-	runTests(t, "boundscheck_", h, checkStub)
-
-	checkProxy := func() error {
-		interfacePointer := test.BoundsCheckTestInterface_Pointer{pipeOwner(h)}
-		proxy := test.NewBoundsCheckTestInterfaceProxy(interfacePointer, waiter)
-		_, err := proxy.Method0(0)
-		proxy.Close_Proxy()
-		h.reset()
-		return err
-	}
-	runTests(t, "resp_boundscheck_", h, checkProxy)
-}
-
-func TestConformanceResponse(t *testing.T) {
-	h := NewMockMessagePipeHandle()
-	checkProxy := func() error {
-		interfacePointer := test.ConformanceTestInterface_Pointer{pipeOwner(h)}
-		proxy := test.NewConformanceTestInterfaceProxy(interfacePointer, waiter)
-		_, err := proxy.Method12(0)
-		proxy.Close_Proxy()
-		h.reset()
-		return err
-	}
-	runTests(t, "resp_conformance_", h, checkProxy)
-}
diff --git a/mojo/gpu/BUILD.gn b/mojo/gpu/BUILD.gn
index fb0e4d8..44faf91 100644
--- a/mojo/gpu/BUILD.gn
+++ b/mojo/gpu/BUILD.gn
@@ -28,6 +28,7 @@
     "//gpu/command_buffer/common",
     "//mojo/environment:chromium",
     "//mojo/public/c/gles2",
+    "//mojo/public/c/gpu:gpu_onscreen",
     "//mojo/public/c/system",
     "//mojo/public/cpp/application",
     "//mojo/public/cpp/bindings",
diff --git a/mojo/gpu/gl_context.cc b/mojo/gpu/gl_context.cc
index 73941d6..3b4830a 100644
--- a/mojo/gpu/gl_context.cc
+++ b/mojo/gpu/gl_context.cc
@@ -7,6 +7,7 @@
 #include "mojo/public/cpp/application/connect.h"
 #include "mojo/public/interfaces/application/shell.mojom.h"
 #include "mojo/services/gpu/public/interfaces/gpu.mojom.h"
+#include "mojo/gpu/mojo_gles2_impl_autogen.h"
 
 namespace mojo {
 
@@ -24,8 +25,7 @@
   context_ = MojoGLES2CreateContext(
       command_buffer.PassInterface().PassHandle().release().value(),
       &ContextLostThunk, this, Environment::GetDefaultAsyncWaiter());
-  gl_ = static_cast<gpu::gles2::GLES2Interface*>(
-      MojoGLES2GetGLES2Interface(context_));
+  gl_impl_.reset(new MojoGLES2Impl(context_));
 }
 
 GLContext::~GLContext() {
@@ -44,6 +44,10 @@
   delete this;
 }
 
+gpu::gles2::GLES2Interface* GLContext::gl() const {
+  return gl_impl_.get();
+}
+
 void GLContext::AddObserver(Observer* observer) {
   observers_.AddObserver(observer);
 }
diff --git a/mojo/gpu/gl_context.h b/mojo/gpu/gl_context.h
index 79ef518..9c5eb3a 100644
--- a/mojo/gpu/gl_context.h
+++ b/mojo/gpu/gl_context.h
@@ -17,6 +17,7 @@
 }
 
 namespace mojo {
+class MojoGLES2Impl;
 class Shell;
 
 class GLContext {
@@ -34,7 +35,7 @@
   void MakeCurrent();
   void Destroy();
 
-  gpu::gles2::GLES2Interface* gl() const { return gl_; }
+  gpu::gles2::GLES2Interface* gl() const;
 
   void AddObserver(Observer* observer);
   void RemoveObserver(Observer* observer);
@@ -47,7 +48,7 @@
   void OnContextLost();
 
   MojoGLES2Context context_;
-  gpu::gles2::GLES2Interface* gl_;
+  scoped_ptr<MojoGLES2Impl> gl_impl_;
 
   base::ObserverList<Observer> observers_;
   base::WeakPtrFactory<GLContext> weak_factory_;
diff --git a/mojo/gpu/mojo_gles2_impl_autogen.cc b/mojo/gpu/mojo_gles2_impl_autogen.cc
index a716a4d..fb55202 100644
--- a/mojo/gpu/mojo_gles2_impl_autogen.cc
+++ b/mojo/gpu/mojo_gles2_impl_autogen.cc
@@ -11,9 +11,16 @@
 #include "mojo/gpu/mojo_gles2_impl_autogen.h"
 
 #include "base/logging.h"
+#include "mojo/public/c/gles2/chromium_bind_uniform_location.h"
+#include "mojo/public/c/gles2/chromium_map_sub.h"
+#include "mojo/public/c/gles2/chromium_miscellaneous.h"
 #include "mojo/public/c/gles2/chromium_sync_point.h"
 #include "mojo/public/c/gles2/chromium_texture_mailbox.h"
+#include "mojo/public/c/gles2/ext_debug_marker.h"
 #include "mojo/public/c/gles2/gles2.h"
+#include "mojo/public/c/gles2/occlusion_query_ext.h"
+#include "mojo/public/c/gles2/oes_vertex_array_object.h"
+#include "mojo/public/c/gpu/MGL/mgl_onscreen.h"
 
 namespace mojo {
 
@@ -771,8 +778,8 @@
   NOTREACHED() << "Unimplemented ShallowFinishCHROMIUM.";
 }
 void MojoGLES2Impl::ShallowFlushCHROMIUM() {
-  return static_cast<gpu::gles2::GLES2Interface*>(
-             MojoGLES2GetGLES2Interface(context_))->ShallowFlushCHROMIUM();
+  MojoGLES2MakeCurrent(context_);
+  glShallowFlushCHROMIUM();
 }
 void MojoGLES2Impl::OrderingBarrierCHROMIUM() {
   NOTREACHED() << "Unimplemented OrderingBarrierCHROMIUM.";
@@ -1203,63 +1210,68 @@
   NOTREACHED() << "Unimplemented TexStorage2DEXT.";
 }
 void MojoGLES2Impl::GenQueriesEXT(GLsizei n, GLuint* queries) {
-  return static_cast<gpu::gles2::GLES2Interface*>(
-             MojoGLES2GetGLES2Interface(context_))->GenQueriesEXT(n, queries);
+  MojoGLES2MakeCurrent(context_);
+  glGenQueriesEXT(n, queries);
 }
 void MojoGLES2Impl::DeleteQueriesEXT(GLsizei n, const GLuint* queries) {
-  return static_cast<gpu::gles2::GLES2Interface*>(
-             MojoGLES2GetGLES2Interface(context_))
-      ->DeleteQueriesEXT(n, queries);
+  MojoGLES2MakeCurrent(context_);
+  glDeleteQueriesEXT(n, queries);
 }
 GLboolean MojoGLES2Impl::IsQueryEXT(GLuint id) {
-  NOTREACHED() << "Unimplemented IsQueryEXT.";
-  return 0;
+  MojoGLES2MakeCurrent(context_);
+  return glIsQueryEXT(id);
 }
 void MojoGLES2Impl::BeginQueryEXT(GLenum target, GLuint id) {
-  return static_cast<gpu::gles2::GLES2Interface*>(
-             MojoGLES2GetGLES2Interface(context_))->BeginQueryEXT(target, id);
+  MojoGLES2MakeCurrent(context_);
+  glBeginQueryEXT(target, id);
 }
 void MojoGLES2Impl::BeginTransformFeedback(GLenum primitivemode) {
   NOTREACHED() << "Unimplemented BeginTransformFeedback.";
 }
 void MojoGLES2Impl::EndQueryEXT(GLenum target) {
-  return static_cast<gpu::gles2::GLES2Interface*>(
-             MojoGLES2GetGLES2Interface(context_))->EndQueryEXT(target);
+  MojoGLES2MakeCurrent(context_);
+  glEndQueryEXT(target);
 }
 void MojoGLES2Impl::EndTransformFeedback() {
   NOTREACHED() << "Unimplemented EndTransformFeedback.";
 }
 void MojoGLES2Impl::GetQueryivEXT(GLenum target, GLenum pname, GLint* params) {
-  NOTREACHED() << "Unimplemented GetQueryivEXT.";
+  MojoGLES2MakeCurrent(context_);
+  glGetQueryivEXT(target, pname, params);
 }
 void MojoGLES2Impl::GetQueryObjectuivEXT(GLuint id,
                                          GLenum pname,
                                          GLuint* params) {
-  return static_cast<gpu::gles2::GLES2Interface*>(
-             MojoGLES2GetGLES2Interface(context_))
-      ->GetQueryObjectuivEXT(id, pname, params);
+  MojoGLES2MakeCurrent(context_);
+  glGetQueryObjectuivEXT(id, pname, params);
 }
 void MojoGLES2Impl::InsertEventMarkerEXT(GLsizei length, const GLchar* marker) {
-  NOTREACHED() << "Unimplemented InsertEventMarkerEXT.";
+  MojoGLES2MakeCurrent(context_);
+  glInsertEventMarkerEXT(length, marker);
 }
 void MojoGLES2Impl::PushGroupMarkerEXT(GLsizei length, const GLchar* marker) {
-  NOTREACHED() << "Unimplemented PushGroupMarkerEXT.";
+  MojoGLES2MakeCurrent(context_);
+  glPushGroupMarkerEXT(length, marker);
 }
 void MojoGLES2Impl::PopGroupMarkerEXT() {
-  NOTREACHED() << "Unimplemented PopGroupMarkerEXT.";
+  MojoGLES2MakeCurrent(context_);
+  glPopGroupMarkerEXT();
 }
 void MojoGLES2Impl::GenVertexArraysOES(GLsizei n, GLuint* arrays) {
-  NOTREACHED() << "Unimplemented GenVertexArraysOES.";
+  MojoGLES2MakeCurrent(context_);
+  glGenVertexArraysOES(n, arrays);
 }
 void MojoGLES2Impl::DeleteVertexArraysOES(GLsizei n, const GLuint* arrays) {
-  NOTREACHED() << "Unimplemented DeleteVertexArraysOES.";
+  MojoGLES2MakeCurrent(context_);
+  glDeleteVertexArraysOES(n, arrays);
 }
 GLboolean MojoGLES2Impl::IsVertexArrayOES(GLuint array) {
-  NOTREACHED() << "Unimplemented IsVertexArrayOES.";
-  return 0;
+  MojoGLES2MakeCurrent(context_);
+  return glIsVertexArrayOES(array);
 }
 void MojoGLES2Impl::BindVertexArrayOES(GLuint array) {
-  NOTREACHED() << "Unimplemented BindVertexArrayOES.";
+  MojoGLES2MakeCurrent(context_);
+  glBindVertexArrayOES(array);
 }
 void MojoGLES2Impl::SwapBuffers() {
   NOTREACHED() << "Unimplemented SwapBuffers.";
@@ -1287,11 +1299,12 @@
                                               GLintptr offset,
                                               GLsizeiptr size,
                                               GLenum access) {
-  NOTREACHED() << "Unimplemented MapBufferSubDataCHROMIUM.";
-  return 0;
+  MojoGLES2MakeCurrent(context_);
+  return glMapBufferSubDataCHROMIUM(target, offset, size, access);
 }
 void MojoGLES2Impl::UnmapBufferSubDataCHROMIUM(const void* mem) {
-  NOTREACHED() << "Unimplemented UnmapBufferSubDataCHROMIUM.";
+  MojoGLES2MakeCurrent(context_);
+  glUnmapBufferSubDataCHROMIUM(mem);
 }
 void* MojoGLES2Impl::MapBufferRange(GLenum target,
                                     GLintptr offset,
@@ -1313,20 +1326,19 @@
                                               GLenum format,
                                               GLenum type,
                                               GLenum access) {
-  return static_cast<gpu::gles2::GLES2Interface*>(
-             MojoGLES2GetGLES2Interface(context_))
-      ->MapTexSubImage2DCHROMIUM(target, level, xoffset, yoffset, width, height,
-                                 format, type, access);
+  MojoGLES2MakeCurrent(context_);
+  return glMapTexSubImage2DCHROMIUM(target, level, xoffset, yoffset, width,
+                                    height, format, type, access);
 }
 void MojoGLES2Impl::UnmapTexSubImage2DCHROMIUM(const void* mem) {
-  return static_cast<gpu::gles2::GLES2Interface*>(
-             MojoGLES2GetGLES2Interface(context_))
-      ->UnmapTexSubImage2DCHROMIUM(mem);
+  MojoGLES2MakeCurrent(context_);
+  glUnmapTexSubImage2DCHROMIUM(mem);
 }
 void MojoGLES2Impl::ResizeCHROMIUM(GLuint width,
                                    GLuint height,
                                    GLfloat scale_factor) {
-  NOTREACHED() << "Unimplemented ResizeCHROMIUM.";
+  MojoGLES2MakeCurrent(context_);
+  MGLResizeSurface(width, height);
 }
 const GLchar* MojoGLES2Impl::GetRequestableExtensionsCHROMIUM() {
   NOTREACHED() << "Unimplemented GetRequestableExtensionsCHROMIUM.";
@@ -1460,7 +1472,8 @@
 void MojoGLES2Impl::BindUniformLocationCHROMIUM(GLuint program,
                                                 GLint location,
                                                 const char* name) {
-  NOTREACHED() << "Unimplemented BindUniformLocationCHROMIUM.";
+  MojoGLES2MakeCurrent(context_);
+  glBindUniformLocationCHROMIUM(program, location, name);
 }
 void MojoGLES2Impl::GenValuebuffersCHROMIUM(GLsizei n, GLuint* buffers) {
   NOTREACHED() << "Unimplemented GenValuebuffersCHROMIUM.";
diff --git a/mojo/message_pump/BUILD.gn b/mojo/message_pump/BUILD.gn
new file mode 100644
index 0000000..14daad6
--- /dev/null
+++ b/mojo/message_pump/BUILD.gn
@@ -0,0 +1,39 @@
+# Copyright 2015 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+source_set("message_pump") {
+  sources = [
+    "handle_watcher.cc",
+    "handle_watcher.h",
+    "message_pump_mojo.cc",
+    "message_pump_mojo.h",
+    "message_pump_mojo_handler.h",
+    "time_helper.cc",
+    "time_helper.h",
+  ]
+
+  deps = [
+    "//base",
+    "//mojo/public/cpp/system",
+  ]
+}
+
+source_set("tests") {
+  testonly = true
+
+  sources = [
+    "handle_watcher_unittest.cc",
+    "message_pump_mojo_unittest.cc",
+  ]
+
+  deps = [
+    ":message_pump",
+    "//base",
+    "//base/test:test_support",
+    "//base:message_loop_tests",
+    "//mojo/public/cpp/system",
+    "//mojo/public/cpp/test_support:test_utils",
+    "//testing/gtest",
+  ]
+}
diff --git a/mojo/common/handle_watcher.cc b/mojo/message_pump/handle_watcher.cc
similarity index 98%
rename from mojo/common/handle_watcher.cc
rename to mojo/message_pump/handle_watcher.cc
index c7fa81f..2465579 100644
--- a/mojo/common/handle_watcher.cc
+++ b/mojo/message_pump/handle_watcher.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "mojo/common/handle_watcher.h"
+#include "mojo/message_pump/handle_watcher.h"
 
 #include <map>
 
@@ -20,9 +20,9 @@
 #include "base/threading/thread.h"
 #include "base/threading/thread_restrictions.h"
 #include "base/time/time.h"
-#include "mojo/common/message_pump_mojo.h"
-#include "mojo/common/message_pump_mojo_handler.h"
-#include "mojo/common/time_helper.h"
+#include "mojo/message_pump/message_pump_mojo.h"
+#include "mojo/message_pump/message_pump_mojo_handler.h"
+#include "mojo/message_pump/time_helper.h"
 
 namespace mojo {
 namespace common {
diff --git a/mojo/common/handle_watcher.h b/mojo/message_pump/handle_watcher.h
similarity index 92%
rename from mojo/common/handle_watcher.h
rename to mojo/message_pump/handle_watcher.h
index fb89716..f024d94 100644
--- a/mojo/common/handle_watcher.h
+++ b/mojo/message_pump/handle_watcher.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef MOJO_COMMON_HANDLE_WATCHER_H_
-#define MOJO_COMMON_HANDLE_WATCHER_H_
+#ifndef MOJO_MESSAGE_PUMP_HANDLE_WATCHER_H_
+#define MOJO_MESSAGE_PUMP_HANDLE_WATCHER_H_
 
 #include "base/basictypes.h"
 #include "base/callback_forward.h"
@@ -60,4 +60,4 @@
 }  // namespace common
 }  // namespace mojo
 
-#endif  // MOJO_COMMON_HANDLE_WATCHER_H_
+#endif  // MOJO_MESSAGE_PUMP_HANDLE_WATCHER_H_
diff --git a/mojo/common/handle_watcher_unittest.cc b/mojo/message_pump/handle_watcher_unittest.cc
similarity index 98%
rename from mojo/common/handle_watcher_unittest.cc
rename to mojo/message_pump/handle_watcher_unittest.cc
index 46d2a27..36f15ac 100644
--- a/mojo/common/handle_watcher_unittest.cc
+++ b/mojo/message_pump/handle_watcher_unittest.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "mojo/common/handle_watcher.h"
+#include "mojo/message_pump/handle_watcher.h"
 
 #include <string>
 
@@ -13,8 +13,8 @@
 #include "base/run_loop.h"
 #include "base/test/simple_test_tick_clock.h"
 #include "base/threading/thread.h"
-#include "mojo/common/message_pump_mojo.h"
-#include "mojo/common/time_helper.h"
+#include "mojo/message_pump/message_pump_mojo.h"
+#include "mojo/message_pump/time_helper.h"
 #include "mojo/public/cpp/system/core.h"
 #include "mojo/public/cpp/test_support/test_utils.h"
 #include "testing/gtest/include/gtest/gtest.h"
diff --git a/mojo/common/message_pump_mojo.cc b/mojo/message_pump/message_pump_mojo.cc
similarity index 98%
rename from mojo/common/message_pump_mojo.cc
rename to mojo/message_pump/message_pump_mojo.cc
index 544960b..e7f7d10 100644
--- a/mojo/common/message_pump_mojo.cc
+++ b/mojo/message_pump/message_pump_mojo.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "mojo/common/message_pump_mojo.h"
+#include "mojo/message_pump/message_pump_mojo.h"
 
 #include <algorithm>
 #include <vector>
@@ -12,8 +12,8 @@
 #include "base/logging.h"
 #include "base/threading/thread_local.h"
 #include "base/time/time.h"
-#include "mojo/common/message_pump_mojo_handler.h"
-#include "mojo/common/time_helper.h"
+#include "mojo/message_pump/message_pump_mojo_handler.h"
+#include "mojo/message_pump/time_helper.h"
 
 namespace mojo {
 namespace common {
diff --git a/mojo/common/message_pump_mojo.h b/mojo/message_pump/message_pump_mojo.h
similarity index 96%
rename from mojo/common/message_pump_mojo.h
rename to mojo/message_pump/message_pump_mojo.h
index fc1e40b..522b0e5 100644
--- a/mojo/common/message_pump_mojo.h
+++ b/mojo/message_pump/message_pump_mojo.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef MOJO_COMMON_MESSAGE_PUMP_MOJO_H_
-#define MOJO_COMMON_MESSAGE_PUMP_MOJO_H_
+#ifndef MOJO_MESSAGE_PUMP_MESSAGE_PUMP_MOJO_H_
+#define MOJO_MESSAGE_PUMP_MESSAGE_PUMP_MOJO_H_
 
 #include <map>
 #include <utility>
@@ -135,4 +135,4 @@
 }  // namespace common
 }  // namespace mojo
 
-#endif  // MOJO_COMMON_MESSAGE_PUMP_MOJO_H_
+#endif  // MOJO_MESSAGE_PUMP_MESSAGE_PUMP_MOJO_H_
diff --git a/mojo/common/message_pump_mojo_handler.h b/mojo/message_pump/message_pump_mojo_handler.h
similarity index 79%
rename from mojo/common/message_pump_mojo_handler.h
rename to mojo/message_pump/message_pump_mojo_handler.h
index b55132d..3a4eccc 100644
--- a/mojo/common/message_pump_mojo_handler.h
+++ b/mojo/message_pump/message_pump_mojo_handler.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef MOJO_COMMON_MESSAGE_PUMP_MOJO_HANDLER_H_
-#define MOJO_COMMON_MESSAGE_PUMP_MOJO_HANDLER_H_
+#ifndef MOJO_MESSAGE_PUMP_MESSAGE_PUMP_MOJO_HANDLER_H_
+#define MOJO_MESSAGE_PUMP_MESSAGE_PUMP_MOJO_HANDLER_H_
 
 #include "mojo/public/cpp/system/core.h"
 
@@ -25,4 +25,4 @@
 }  // namespace common
 }  // namespace mojo
 
-#endif  // MOJO_COMMON_MESSAGE_PUMP_MOJO_HANDLER_H_
+#endif  // MOJO_MESSAGE_PUMP_MESSAGE_PUMP_MOJO_HANDLER_H_
diff --git a/mojo/common/message_pump_mojo_unittest.cc b/mojo/message_pump/message_pump_mojo_unittest.cc
similarity index 96%
rename from mojo/common/message_pump_mojo_unittest.cc
rename to mojo/message_pump/message_pump_mojo_unittest.cc
index 09cbe54..687d5f3 100644
--- a/mojo/common/message_pump_mojo_unittest.cc
+++ b/mojo/message_pump/message_pump_mojo_unittest.cc
@@ -2,11 +2,11 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "mojo/common/message_pump_mojo.h"
+#include "mojo/message_pump/message_pump_mojo.h"
 
 #include "base/message_loop/message_loop_test.h"
 #include "base/run_loop.h"
-#include "mojo/common/message_pump_mojo_handler.h"
+#include "mojo/message_pump/message_pump_mojo_handler.h"
 #include "mojo/public/cpp/system/core.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
diff --git a/mojo/common/time_helper.cc b/mojo/message_pump/time_helper.cc
similarity index 93%
rename from mojo/common/time_helper.cc
rename to mojo/message_pump/time_helper.cc
index 36fd087..ffd667e 100644
--- a/mojo/common/time_helper.cc
+++ b/mojo/message_pump/time_helper.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "mojo/common/time_helper.h"
+#include "mojo/message_pump/time_helper.h"
 
 #include "base/time/tick_clock.h"
 
diff --git a/mojo/common/time_helper.h b/mojo/message_pump/time_helper.h
similarity index 83%
rename from mojo/common/time_helper.h
rename to mojo/message_pump/time_helper.h
index 84029ec..dfdc7bb 100644
--- a/mojo/common/time_helper.h
+++ b/mojo/message_pump/time_helper.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef MOJO_COMMON_TIME_HELPER_H_
-#define MOJO_COMMON_TIME_HELPER_H_
+#ifndef MOJO_MESSAGE_PUMP_TIME_HELPER_H_
+#define MOJO_MESSAGE_PUMP_TIME_HELPER_H_
 
 #include "base/time/time.h"
 
@@ -30,4 +30,4 @@
 }  // namespace common
 }  // namespace mojo
 
-#endif  // MOJO_COMMON_TIME_HELPER_H_
+#endif  // MOJO_MESSAGE_PUMP_TIME_HELPER_H_
diff --git a/mojo/mojo_apps_js_unittests.isolate b/mojo/mojo_apps_js_unittests.isolate
deleted file mode 100644
index 6921a46..0000000
--- a/mojo/mojo_apps_js_unittests.isolate
+++ /dev/null
@@ -1,50 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-{
-  'includes': [
-    '../third_party/icu/icu.isolate',
-  ],
-  'conditions': [
-    ['OS=="win" or OS=="mac" or OS=="linux"', {
-      'variables': {
-        'command': [
-          '../testing/test_env.py',
-          '<(PRODUCT_DIR)/mojo_apps_js_unittests<(EXECUTABLE_SUFFIX)',
-          '--brave-new-test-launcher',
-          '--test-launcher-bot-mode',
-        ],
-        'files': [
-          '../gin/test/expect.js',
-          '../testing/test_env.py',
-          '<(PRODUCT_DIR)/gen/mojo/public/interfaces/bindings/tests/',
-          '<(PRODUCT_DIR)/mojo_apps_js_unittests<(EXECUTABLE_SUFFIX)',
-          'apps/js/',
-          'bindings/js/',
-          'public/js/bindings/',
-        ],
-      },
-    }],
-    ['OS=="win"', {
-      'variables': {
-        'files': [
-          '<(PRODUCT_DIR)/mojo_test_support.dll',
-        ],
-      },
-    }],
-    ['OS=="linux"', {
-      'variables': {
-        'files': [
-          '<(PRODUCT_DIR)/lib/libmojo_test_support.so',
-        ],
-      },
-    }],
-    ['OS=="mac"', {
-      'variables': {
-        'files': [
-          '<(PRODUCT_DIR)/libmojo_test_support.dylib',
-        ],
-      },
-    }],
-  ],
-}
diff --git a/mojo/mojo_js_unittests.isolate b/mojo/mojo_js_unittests.isolate
deleted file mode 100644
index 2b3131b..0000000
--- a/mojo/mojo_js_unittests.isolate
+++ /dev/null
@@ -1,49 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-{
-  'includes': [
-    '../third_party/icu/icu.isolate',
-  ],
-  'conditions': [
-    ['OS=="win" or OS=="mac" or OS=="linux"', {
-      'variables': {
-        'command': [
-          '../testing/test_env.py',
-          '<(PRODUCT_DIR)/mojo_js_unittests<(EXECUTABLE_SUFFIX)',
-          '--brave-new-test-launcher',
-          '--test-launcher-bot-mode',
-        ],
-        'files': [
-          '../gin/test/expect.js',
-          '../testing/test_env.py',
-          '<(PRODUCT_DIR)/gen/mojo/public/interfaces/bindings/tests/',
-          '<(PRODUCT_DIR)/mojo_js_unittests<(EXECUTABLE_SUFFIX)',
-          'bindings/js/',
-          'public/js/bindings/',
-        ],
-      },
-    }],
-    ['OS=="win"', {
-      'variables': {
-        'files': [
-          '<(PRODUCT_DIR)/mojo_test_support.dll',
-        ],
-      },
-    }],
-    ['OS=="linux"', {
-      'variables': {
-        'files': [
-          '<(PRODUCT_DIR)/lib/libmojo_test_support.so',
-        ],
-      },
-    }],
-    ['OS=="mac"', {
-      'variables': {
-        'files': [
-          '<(PRODUCT_DIR)/libmojo_test_support.dylib',
-        ],
-      },
-    }],
-  ],
-}
diff --git a/mojo/mojo_python_unittests.isolate b/mojo/mojo_python_unittests.isolate
deleted file mode 100644
index 4fea84a..0000000
--- a/mojo/mojo_python_unittests.isolate
+++ /dev/null
@@ -1,22 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-{
-  'conditions': [
-    ['OS=="linux"', {
-      'variables': {
-        'command': [
-          'tools/run_mojo_python_bindings_tests.py',
-          '--build-dir=<(PRODUCT_DIR)',
-        ],
-        'files': [
-          '<(PRODUCT_DIR)/gen/mojo/public/interfaces/bindings/tests/',
-          '<(PRODUCT_DIR)/python/',
-          'python/tests/',
-          'tools/pylib/mojo_python_tests_runner.py',
-          'tools/run_mojo_python_bindings_tests.py',
-        ],
-      },
-    }],
-  ],
-}
diff --git a/mojo/nacl/BUILD.gn b/mojo/nacl/BUILD.gn
deleted file mode 100644
index 0c37c18..0000000
--- a/mojo/nacl/BUILD.gn
+++ /dev/null
@@ -1,75 +0,0 @@
-# Copyright 2015 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-# Trusted code
-if (!is_nacl) {
-  # A simple shell for running untrusted binaries that talk to the Mojo
-  # embedder. (No services.)
-  executable("monacl_shell") {
-    testonly = true
-    sources = [
-      "monacl_shell.cc",
-    ]
-    deps = [
-      "//base:base",
-      "//mojo/edk/system:system",
-      "//nacl_bindings:monacl_sel",
-    ]
-
-    data_deps = [ "//nacl_bindings:irt_mojo(//native_client/build/toolchain/nacl:irt_${target_cpu})" ]
-  }
-}
-
-# Untrusted code
-if (is_nacl) {
-  # Unit test for the Mojo public API.
-  executable("monacl_test") {
-    testonly = true
-    sources = [
-      "//mojo/public/cpp/system/tests/core_unittest.cc",
-      "//mojo/public/cpp/system/tests/macros_unittest.cc",
-    ]
-    deps = [
-      "//mojo/public/c/system/tests:tests",
-      "//mojo/public/cpp/system:system",
-      "//mojo/public/platform/nacl:mojo",
-      "//testing/gtest:gtest",
-      "//testing/gtest:gtest_main",
-    ]
-  }
-
-  group("mojo_nacl_tests_untrusted") {
-    testonly = true
-    deps = [
-      ":monacl_test",
-      "//examples/apptest",
-      "//examples/wget",
-      "//services/clipboard",
-      "//services/clipboard:apptests",
-      "//services/files:apptests",
-
-      # TODO(ncbray): enable when NaCl has pthread rw locks.
-      #"//services/http_server",
-      "//services/http_server:apptests",
-      "//services/view_manager:mojo_view_manager_client_apptests",
-      "//services/view_manager:view_manager_service_apptests",
-      "//services/window_manager:window_manager_apptests",
-      "//shell:apptests",
-    ]
-  }
-}
-
-group("mojo_nacl") {
-  deps = [
-    "//services/nacl:nacl_content_handler",
-  ]
-}
-
-group("mojo_nacl_tests") {
-  testonly = true
-  deps = [
-    ":mojo_nacl_tests_untrusted(//native_client/build/toolchain/nacl:clang_newlib_${current_cpu})",
-    ":monacl_shell",
-  ]
-}
diff --git a/mojo/nacl/README.md b/mojo/nacl/README.md
deleted file mode 100644
index 412c4de..0000000
--- a/mojo/nacl/README.md
+++ /dev/null
@@ -1,37 +0,0 @@
-About
-=====
-
-This is a prototype for plumbing Mojo into the NaCl sandbox.  It is
-currently insecure (see below), does not provide a stable ABI (IRT
-support must be added), and does not support Mojo functions that
-return pointers (for example, `MojoMapBuffer`).
-
-
-Using
-=====
-
-To use this prototype run `mojo/tools/mojob.py gn --nacl` and then build
-and test as usual.
-
-Run `mojo/tools/mojob.py nacltest` for additional nacl-specific tests.
-
-
-Notes
-=====
-
-`generator/interface.py` contains a programmatic description of the
-stable Mojo interface.  This will need to be updated as the interface
-changes.  Run `generator/generate_nacl_bindings.py` to generate the
-bindings that plumb this interface into the NaCl sandbox.
-
-
-Security TODO
-=============
-
-* Separate trusted and untrusted Mojo handles.
-* Validate and copy option structures.
-* Protect untrusted buffers passed into Mojo:
-  * `NaClVmIoWillStart/HasEnded`.
-  * volatile accesses to untrusted memory (untrusted code could race).
-* Overflow checking in array bounds validation.
-
diff --git a/mojo/nacl/monacl_shell.cc b/mojo/nacl/monacl_shell.cc
deleted file mode 100644
index 714c04f..0000000
--- a/mojo/nacl/monacl_shell.cc
+++ /dev/null
@@ -1,48 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <iostream>
-
-#include "base/files/file.h"
-#include "base/files/file_path.h"
-#include "base/logging.h"
-#include "mojo/edk/embedder/embedder.h"
-#include "mojo/edk/embedder/simple_platform_support.h"
-#include "nacl_bindings/monacl_sel_main.h"
-#include "native_client/src/public/nacl_desc.h"
-
-NaClDesc* OpenFile(const char* filename) {
-  base::FilePath path(filename);
-  base::File file(path, base::File::FLAG_OPEN | base::File::FLAG_READ);
-  if (!file.IsValid()) {
-    perror(filename);
-    exit(1);
-  }
-  return NaClDescCreateWithFilePathMetadata(file.TakePlatformFile(), "");
-}
-
-int main(int argc, char* argv[]) {
-  if (argc < 3) {
-    std::cout << "Usage: " << argv[0] << " irt.nexe app.nexe [args for app]" <<
-        std::endl;
-    return 1;
-  }
-
-  const char* irt_file = argv[1];
-  const char* nexe_file = argv[2];
-
-  NaClDesc* irt_desc = OpenFile(irt_file);
-  NaClDesc* nexe_desc = OpenFile(nexe_file);
-
-  mojo::embedder::Init(scoped_ptr<mojo::embedder::PlatformSupport>(
-      new mojo::embedder::SimplePlatformSupport()));
-
-  int exit_code = mojo::LaunchNaCl(nexe_desc, irt_desc, argc - 2, argv + 2,
-                                   MOJO_HANDLE_INVALID);
-
-  // Exits the process cleanly, does not return.
-  mojo::NaClExit(exit_code);
-  NOTREACHED();
-  return 1;
-}
diff --git a/mojo/python/BUILD.gn b/mojo/python/BUILD.gn
deleted file mode 100644
index 92bfd60..0000000
--- a/mojo/python/BUILD.gn
+++ /dev/null
@@ -1,66 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import("//mojo/public/python/rules.gni")
-import("//third_party/cython/rules.gni")
-
-group("python") {
-  deps = [
-    ":mojo_embedder",
-    ":packaged_utils",
-    ":utils",
-    ":validation_util",
-    "//mojo/public/python",
-  ]
-}
-
-copy("utils") {
-  sources = [
-    "mojo_utils/__init__.py",
-    "mojo_utils/data_pipe_utils.py",
-  ]
-  outputs = [
-    "$root_out_dir/python/mojo_utils/{{source_file_part}}",
-  ]
-}
-
-python_package("packaged_utils") {
-  sources = [
-    "mojo_utils/__init__.py",
-    "mojo_utils/data_pipe_utils.py",
-  ]
-  datadeps = [
-    "//mojo/public/python:mojo_system",
-  ]
-}
-
-python_binary_module("mojo_embedder") {
-  cython_sources = [ "system/mojo_embedder.pyx" ]
-  deps = [
-    "//mojo/edk/system",
-  ]
-  datadeps = [
-    "//mojo/public/python:mojo_system",
-  ]
-}
-
-copy("tests_module") {
-  sources = [
-    "system/mojo_tests/__init__.py",
-  ]
-  outputs = [
-    "$root_out_dir/python/mojo_tests/{{source_file_part}}",
-  ]
-}
-
-python_binary_module("validation_util") {
-  python_base_module = "mojo_tests"
-  cython_sources = [ "system/mojo_tests/validation_util.pyx" ]
-  deps = [
-    "//mojo/public/cpp/bindings/tests:mojo_public_bindings_test_utils",
-  ]
-  datadeps = [
-    ":tests_module",
-  ]
-}
diff --git a/mojo/python/mojo_utils/__init__.py b/mojo/python/mojo_utils/__init__.py
deleted file mode 100644
index 50b23df..0000000
--- a/mojo/python/mojo_utils/__init__.py
+++ /dev/null
@@ -1,3 +0,0 @@
-# Copyright 2015 The Chromium Authors. 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/mojo/python/mojo_utils/data_pipe_utils.py b/mojo/python/mojo_utils/data_pipe_utils.py
deleted file mode 100644
index 2a46ea5..0000000
--- a/mojo/python/mojo_utils/data_pipe_utils.py
+++ /dev/null
@@ -1,76 +0,0 @@
-# Copyright 2015 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import itertools
-import sys
-
-import mojo_system
-from mojo_bindings import promise
-
-class DataPipeCopyException(Exception):
-  def __init__(self, *args, **kwargs):
-    Exception.__init__(self, *args, **kwargs)
-    self.__traceback__ = sys.exc_info()[2]
-
-
-def CopyFromDataPipe(data_pipe, deadline):
-  """
-  Returns a Promise that operates as follows:
-  - If |data_pipe| is successfully read from, the promise resolves with the
-    bytes that were read.
-  - Otherwise, the promise rejects with an exception whose message contains the
-    status from the attempted read.
-  """
-  class DataPipeCopyHelper():
-    def __init__(self, data_pipe, deadline, resolve, reject):
-      self.data_pipe = data_pipe
-      self.original_deadline = deadline
-      self.start_time = mojo_system.GetTimeTicksNow()
-      self.resolve = resolve
-      self.reject = reject
-      self.buffer_size = 1024
-      self.data = bytearray(self.buffer_size)
-      self.index = 0
-
-    def _ComputeCurrentDeadline(self):
-      if self.original_deadline == mojo_system.DEADLINE_INDEFINITE:
-        return self.original_deadline
-      elapsed_time = mojo_system.GetTimeTicksNow() - self.start_time
-      return max(0, self.original_deadline - elapsed_time)
-
-    def CopyFromDataPipeAsync(self, result):
-      while result == mojo_system.RESULT_OK:
-        assert self.index <= len(self.data)
-        if self.index == len(self.data):
-          self.buffer_size *= 2
-          self.data.extend(itertools.repeat(0, self.buffer_size))
-
-        # Careful! Have to construct a memoryview object here as otherwise the
-        # slice operation will create a copy of |data| and hence not write into
-        # |data| as desired.
-        result, read_bytes = self.data_pipe.ReadData(
-            memoryview(self.data)[self.index:])
-        if read_bytes:
-          self.index += len(read_bytes)
-        del read_bytes
-
-      if result == mojo_system.RESULT_SHOULD_WAIT:
-        data_pipe.AsyncWait(mojo_system.HANDLE_SIGNAL_READABLE,
-                            self._ComputeCurrentDeadline(),
-                            self.CopyFromDataPipeAsync)
-        return
-
-      # Treat a failed precondition as EOF.
-      if result == mojo_system.RESULT_FAILED_PRECONDITION:
-        self.resolve(self.data[:self.index])
-        return
-
-      self.reject(DataPipeCopyException("Result: %d" % result))
-
-
-  def GenerationMethod(resolve, reject):
-    helper = DataPipeCopyHelper(data_pipe, deadline, resolve, reject)
-    helper.CopyFromDataPipeAsync(mojo_system.RESULT_OK)
-
-  return promise.Promise(GenerationMethod)
diff --git a/mojo/python/system/mojo_embedder.pyx b/mojo/python/system/mojo_embedder.pyx
deleted file mode 100644
index 75ae387..0000000
--- a/mojo/python/system/mojo_embedder.pyx
+++ /dev/null
@@ -1,50 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-# distutils: language = c++
-
-from libc.stdint cimport uintptr_t
-from libcpp cimport bool
-
-import mojo_system
-import mojo_system_impl
-
-cdef extern from "third_party/cython/python_export.h":
-  pass
-
-cdef extern from "base/memory/scoped_ptr.h":
-  cdef cppclass scoped_ptr[T]:
-    scoped_ptr(T*)
-
-cdef extern from "mojo/edk/embedder/platform_support.h" \
-    namespace "mojo::embedder" nogil:
-  cdef cppclass PlatformSupport:
-    pass
-
-cdef extern from "mojo/edk/embedder/simple_platform_support.h" \
-    namespace "mojo::embedder" nogil:
-  cdef cppclass SimplePlatformSupport(PlatformSupport):
-    SimplePlatformSupport()
-
-cdef extern from "mojo/edk/embedder/embedder.h" nogil:
-  cdef void InitCEmbedder "mojo::embedder::Init"(
-      scoped_ptr[PlatformSupport] platform_support)
-
-cdef extern from "mojo/public/platform/native/system_thunks.h" nogil:
-  cdef struct MojoSystemThunks:
-    pass
-  cdef MojoSystemThunks MojoMakeSystemThunks()
-
-cdef extern from "mojo/edk/embedder/test_embedder.h" nogil:
-  cdef bool ShutdownCEmbedderForTest "mojo::embedder::test::Shutdown"()
-
-def Init():
-  InitCEmbedder(scoped_ptr[PlatformSupport](
-      new SimplePlatformSupport()))
-  cdef MojoSystemThunks thunks = MojoMakeSystemThunks()
-  mojo_system.SetSystemThunks(<uintptr_t>(&thunks))
-  mojo_system_impl.SetSystemThunks(<uintptr_t>(&thunks))
-
-def ShutdownForTest():
-  return ShutdownCEmbedderForTest()
diff --git a/mojo/python/system/mojo_tests/__init__.py b/mojo/python/system/mojo_tests/__init__.py
deleted file mode 100644
index 4d6aabb..0000000
--- a/mojo/python/system/mojo_tests/__init__.py
+++ /dev/null
@@ -1,3 +0,0 @@
-# Copyright 2014 The Chromium Authors. 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/mojo/python/system/mojo_tests/validation_util.pyx b/mojo/python/system/mojo_tests/validation_util.pyx
deleted file mode 100644
index e7bdbcd..0000000
--- a/mojo/python/system/mojo_tests/validation_util.pyx
+++ /dev/null
@@ -1,35 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-# distutils: language = c++
-
-from libc.stdint cimport uint8_t
-from libcpp cimport bool
-from libcpp.string cimport string
-from libcpp.vector cimport vector
-
-cdef extern from "third_party/cython/python_export.h":
-  pass
-
-cdef extern from "mojo/public/cpp/bindings/tests/validation_test_input_parser.h":
-  cdef bool ParseValidationTestInput "mojo::test::ParseValidationTestInput"(
-      string input,
-      vector[uint8_t]* data,
-      size_t* num_handles,
-      string* error_message)
-
-class Data(object):
-  def __init__(self, data, num_handles, error_message):
-    self.data = data
-    self.num_handles = num_handles
-    self.error_message = error_message
-
-def ParseData(value):
-  cdef string value_as_string = value
-  cdef vector[uint8_t] data_as_vector
-  cdef size_t num_handles
-  cdef string error_message
-  ParseValidationTestInput(
-      value, &data_as_vector, &num_handles, &error_message)
-  return Data(bytearray(data_as_vector), num_handles, error_message)
diff --git a/mojo/python/tests/async_wait_unittest.py b/mojo/python/tests/async_wait_unittest.py
deleted file mode 100644
index 61b0c2c..0000000
--- a/mojo/python/tests/async_wait_unittest.py
+++ /dev/null
@@ -1,50 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import mojo_unittest
-
-# pylint: disable=E0611
-import mojo_system as system
-
-
-class AsyncWaitTest(mojo_unittest.MojoTestCase):
-
-  def setUp(self):
-    super(AsyncWaitTest, self).setUp()
-    self.array = []
-    self.handles = system.MessagePipe()
-    self.cancel = self.handles.handle0.AsyncWait(system.HANDLE_SIGNAL_READABLE,
-                                                 system.DEADLINE_INDEFINITE,
-                                                 self._OnResult)
-
-  def tearDown(self):
-    self.cancel()
-    self.handles = None
-    self.array = None
-    super(AsyncWaitTest, self).tearDown()
-
-  def _OnResult(self, value):
-    self.array.append(value)
-
-  def _WriteToHandle(self):
-    self.handles.handle1.WriteMessage()
-
-  def _PostWriteAndRun(self):
-    self.loop.PostDelayedTask(self._WriteToHandle, 0)
-    self.loop.RunUntilIdle()
-
-  def testAsyncWait(self):
-    self._PostWriteAndRun()
-    self.assertEquals(len(self.array), 1)
-    self.assertEquals(system.RESULT_OK, self.array[0])
-
-  def testAsyncWaitCancel(self):
-    self.loop.PostDelayedTask(self.cancel, 0)
-    self._PostWriteAndRun()
-    self.assertEquals(len(self.array), 0)
-
-  def testAsyncWaitImmediateCancel(self):
-    self.cancel()
-    self._PostWriteAndRun()
-    self.assertEquals(len(self.array), 0)
diff --git a/mojo/python/tests/bindings_constants_unittest.py b/mojo/python/tests/bindings_constants_unittest.py
deleted file mode 100644
index 4db08c1..0000000
--- a/mojo/python/tests/bindings_constants_unittest.py
+++ /dev/null
@@ -1,38 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import math
-import unittest
-
-# Generated files
-# pylint: disable=F0401
-import sample_service_mojom
-import test_constants_mojom
-
-class ConstantBindingsTest(unittest.TestCase):
-
-  def testConstantGeneration(self):
-    self.assertEquals(test_constants_mojom.INT8_VALUE, -2)
-    self.assertEquals(test_constants_mojom.UINT64_VALUE, 9999999999999999999)
-    self.assertEquals(test_constants_mojom.DOUBLE_INFINITY,
-                      float('inf'))
-    self.assertEquals(test_constants_mojom.DOUBLE_NEGATIVE_INFINITY,
-                      float('-inf'))
-    self.assertTrue(math.isnan(test_constants_mojom.DOUBLE_NA_N))
-    self.assertEquals(test_constants_mojom.FLOAT_INFINITY,
-                      float('inf'))
-    self.assertEquals(test_constants_mojom.FLOAT_NEGATIVE_INFINITY,
-                      float('-inf'))
-    self.assertTrue(math.isnan(test_constants_mojom.FLOAT_NA_N))
-
-  def testConstantOnStructGeneration(self):
-    self.assertEquals(test_constants_mojom.StructWithConstants.INT8_VALUE, 5)
-
-  def testStructImmutability(self):
-    with self.assertRaises(AttributeError):
-      sample_service_mojom.Foo.FOOBY = 0
-    with self.assertRaises(AttributeError):
-      del sample_service_mojom.Foo.FOOBY
-    with self.assertRaises(AttributeError):
-      sample_service_mojom.Foo.BAR = 1
diff --git a/mojo/python/tests/bindings_control_messages_unittest.py b/mojo/python/tests/bindings_control_messages_unittest.py
deleted file mode 100644
index 12dcfe4..0000000
--- a/mojo/python/tests/bindings_control_messages_unittest.py
+++ /dev/null
@@ -1,90 +0,0 @@
-# Copyright 2015 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-# pylint: disable=F0401,E0611
-import mojo_bindings.promise as promise
-import mojo_system as system
-import mojo_unittest
-import sample_interfaces_mojom
-
-
-def _BuildProxy(impl):
-  pipe = system.MessagePipe()
-  impl.__class__.manager.Bind(impl, pipe.handle0)
-  return impl.__class__.manager.Proxy(pipe.handle1)
-
-
-def _ExtractValue(v_promise):
-  container = []
-  @promise.async
-  def GetInternalValue(value):
-    container.append(value)
-  GetInternalValue(v_promise)
-  assert len(container)
-  return container[0]
-
-
-class IntegerAccessorImpl(sample_interfaces_mojom.IntegerAccessor):
-  """
-  Interface definition is in
-  mojo/public/interfaces/bindings/tests/sample_interfaces.mojom
-  """
-  def __init__(self):
-    self.values = {
-      'data': 0,
-      'type': 0,
-    }
-
-  def GetInteger(self):
-    return self.values;
-
-  def SetInteger(self, **values):
-    self.values = values
-
-  def GetInternalValue(self):
-    return self.values['data']
-
-
-class ControlMessagesTest(mojo_unittest.MojoTestCase):
-
-  def testQueryVersion(self):
-    p = _BuildProxy(IntegerAccessorImpl())
-    self.assertEquals(p.manager.version, 0)
-    v_promise = p.manager.QueryVersion()
-    self.loop.RunUntilIdle()
-    self.assertEquals(v_promise.state, promise.Promise.STATE_FULLFILLED)
-    self.assertEquals(_ExtractValue(v_promise), 3)
-    self.assertEquals(p.manager.version, 3)
-
-  def testRequireVersion(self):
-    impl = IntegerAccessorImpl()
-    errors = []
-    p = _BuildProxy(impl)
-    p.manager.AddOnErrorCallback(lambda: errors.append(0))
-
-    self.assertEquals(p.manager.version, 0)
-
-    p.manager.RequireVersion(1)
-    self.assertEquals(p.manager.version, 1)
-    p.SetInteger(123, sample_interfaces_mojom.Enum.VALUE)
-    self.loop.RunUntilIdle()
-    self.assertEquals(len(errors), 0)
-    self.assertEquals(impl.GetInternalValue(), 123)
-
-    p.manager.RequireVersion(3)
-    self.assertEquals(p.manager.version, 3)
-    p.SetInteger(456, sample_interfaces_mojom.Enum.VALUE)
-    self.loop.RunUntilIdle()
-    self.assertEquals(len(errors), 0)
-    self.assertEquals(impl.GetInternalValue(), 456)
-
-    # Require a version that is not supported by the implementation side.
-    p.manager.RequireVersion(4)
-    # version is updated synchronously.
-    self.assertEquals(p.manager.version, 4)
-    p.SetInteger(789, sample_interfaces_mojom.Enum.VALUE)
-    self.loop.RunUntilIdle()
-    self.assertEquals(len(errors), 1)
-    # The call to SetInteger() after RequireVersion() is ignored.
-    self.assertEquals(impl.GetInternalValue(), 456)
diff --git a/mojo/python/tests/bindings_enums_unittest.py b/mojo/python/tests/bindings_enums_unittest.py
deleted file mode 100644
index 6ec5d8c..0000000
--- a/mojo/python/tests/bindings_enums_unittest.py
+++ /dev/null
@@ -1,61 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import unittest
-
-# Generated files
-# pylint: disable=F0401
-import sample_import_mojom
-import sample_service_mojom
-
-
-class EnumBindingsTest(unittest.TestCase):
-
-  # Testing enum classes are in the right module.
-  def testModule(self):
-    self.assertEquals(sample_import_mojom.Shape.__module__,
-                      'sample_import_mojom')
-
-  # Testing that enum class have expected constant values.
-  def testTopLevelEnumGeneration(self):
-    self.assertEquals(sample_import_mojom.Shape.RECTANGLE, 1)
-    self.assertEquals(sample_import_mojom.Shape.CIRCLE, 2)
-    self.assertEquals(sample_import_mojom.Shape.TRIANGLE, 3)
-    self.assertEquals(sample_import_mojom.Shape.LAST,
-                      sample_import_mojom.Shape.TRIANGLE)
-
-    self.assertEquals(sample_import_mojom.AnotherShape.RECTANGLE, 10)
-    self.assertEquals(sample_import_mojom.AnotherShape.CIRCLE, 11)
-    self.assertEquals(sample_import_mojom.AnotherShape.TRIANGLE, 12)
-
-    self.assertEquals(sample_import_mojom.YetAnotherShape.RECTANGLE, 20)
-    self.assertEquals(sample_import_mojom.YetAnotherShape.CIRCLE, 21)
-    self.assertEquals(sample_import_mojom.YetAnotherShape.TRIANGLE, 22)
-
-  # Testing that internal enum class have expected constant values.
-  def testInternalEnumGeneration(self):
-    self.assertEquals(sample_service_mojom.Bar.Type.VERTICAL, 1)
-    self.assertEquals(sample_service_mojom.Bar.Type.HORIZONTAL, 2)
-    self.assertEquals(sample_service_mojom.Bar.Type.BOTH, 3)
-    self.assertEquals(sample_service_mojom.Bar.Type.INVALID, 4)
-
-  # Testing an enum class cannot be instantiated.
-  def testNonInstantiableEnum(self):
-    with self.assertRaises(TypeError):
-      sample_import_mojom.Shape()
-
-  # Testing an enum does not contain the VALUES constant.
-  def testNoVALUESConstant(self):
-    with self.assertRaises(AttributeError):
-      # pylint: disable=W0104
-      sample_import_mojom.Shape.VALUES
-
-  # Testing enum values are frozen.
-  def testEnumFrozen(self):
-    with self.assertRaises(AttributeError):
-      sample_import_mojom.Shape.RECTANGLE = 2
-    with self.assertRaises(AttributeError):
-      del sample_import_mojom.Shape.RECTANGLE
-    with self.assertRaises(AttributeError):
-      sample_import_mojom.Shape.NewShape = 4
diff --git a/mojo/python/tests/bindings_interface_unittest.py b/mojo/python/tests/bindings_interface_unittest.py
deleted file mode 100644
index ac42ed3..0000000
--- a/mojo/python/tests/bindings_interface_unittest.py
+++ /dev/null
@@ -1,123 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import gc
-import weakref
-
-# pylint: disable=F0401,E0611
-import mojo_bindings.promise as promise
-import mojo_system as system
-import mojo_unittest
-import regression_tests_mojom
-import sample_factory_mojom
-import sample_service_mojom
-
-
-def _BuildProxy(impl):
-  pipe = system.MessagePipe()
-  impl.__class__.manager.Bind(impl, pipe.handle0)
-  return impl.__class__.manager.Proxy(pipe.handle1)
-
-
-def _ExtractValue(p):
-  container = []
-  @promise.async
-  def GetValue(value):
-    container.append(value)
-  GetValue(p)
-  assert len(container)
-  return container[0]
-
-
-class EmptyServiceImpl(sample_service_mojom.Service):
-
-  def __init__(self):
-    pass
-
-
-class ServiceImpl(sample_service_mojom.Service):
-
-  def __init__(self):
-    pass
-
-  # pylint: disable=C0102,W0613
-  def Frobinate(self, foo, baz, port):
-    return baz
-
-
-class NamedObjectImpl(sample_factory_mojom.NamedObject):
-
-  def __init__(self):
-    self.name = 'name'
-
-  def SetName(self, name):
-    self.name = name
-
-  def GetName(self):
-    return self.name
-
-
-class DelegatingNamedObject(sample_factory_mojom.NamedObject):
-
-  def __init__(self):
-    self.proxy = _BuildProxy(NamedObjectImpl())
-
-  def SetName(self, name):
-    self.proxy.SetName(name)
-
-  def GetName(self):
-    return self.proxy.GetName()
-
-class InterfaceTest(mojo_unittest.MojoTestCase):
-
-  def testBaseInterface(self):
-    service = sample_service_mojom.Service()
-    with self.assertRaises(AttributeError):
-      service.NotExisting()
-    with self.assertRaises(NotImplementedError):
-      service.Frobinate()
-
-  def testEmpty(self):
-    service = EmptyServiceImpl()
-    with self.assertRaises(NotImplementedError):
-      service.Frobinate()
-
-  def testServiceWithReturnValue(self):
-    proxy = _BuildProxy(DelegatingNamedObject())
-    p1 = proxy.GetName()
-
-    self.assertEquals(p1.state, promise.Promise.STATE_PENDING)
-    self.loop.RunUntilIdle()
-    self.assertEquals(p1.state, promise.Promise.STATE_FULLFILLED)
-    name = _ExtractValue(p1)
-    self.assertEquals(name, 'name')
-
-    proxy.SetName('hello')
-    p2 = proxy.GetName()
-
-    self.assertEquals(p2.state, promise.Promise.STATE_PENDING)
-    self.loop.RunUntilIdle()
-    self.assertEquals(p2.state, promise.Promise.STATE_FULLFILLED)
-    name = _ExtractValue(p2)
-    self.assertEquals(name, 'hello')
-
-  def testCloseProxy(self):
-    named_object_impl = NamedObjectImpl()
-    proxy = _BuildProxy(named_object_impl)
-    response = proxy.GetName()
-    proxy.manager.Close()
-
-    self.assertEquals(response.state, promise.Promise.STATE_REJECTED)
-
-  def testCloseImplementationWithResponse(self):
-    impl = DelegatingNamedObject()
-    proxy = _BuildProxy(impl)
-    p1 = proxy.GetName()
-
-    self.assertEquals(p1.state, promise.Promise.STATE_PENDING)
-
-    impl.manager.Close()
-    self.loop.RunUntilIdle()
-
-    self.assertEquals(p1.state, promise.Promise.STATE_REJECTED)
diff --git a/mojo/python/tests/bindings_serialization_deserialization_unittest.py b/mojo/python/tests/bindings_serialization_deserialization_unittest.py
deleted file mode 100644
index 64397c2..0000000
--- a/mojo/python/tests/bindings_serialization_deserialization_unittest.py
+++ /dev/null
@@ -1,102 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import math
-
-import mojo_unittest
-
-# pylint: disable=E0611,F0401
-import mojo_bindings.serialization as serialization
-import mojo_system
-
-# Generated files
-# pylint: disable=F0401
-import sample_import_mojom
-import sample_import2_mojom
-import sample_service_mojom
-
-
-def _NewHandle():
-  return mojo_system.MessagePipe().handle0
-
-
-def _NewBar():
-  bar_instance = sample_service_mojom.Bar()
-  bar_instance.alpha = 22
-  bar_instance.beta = 87
-  bar_instance.gamma = 122
-  bar_instance.type = sample_service_mojom.Bar.Type.BOTH
-  return bar_instance
-
-
-def _NewFoo():
-  foo_instance = sample_service_mojom.Foo()
-  foo_instance.name = "Foo.name"
-  foo_instance.x = 23
-  foo_instance.y = -23
-  foo_instance.a = False
-  foo_instance.b = True
-  foo_instance.c = True
-  foo_instance.bar = _NewBar()
-  foo_instance.extra_bars = [
-      _NewBar(),
-      _NewBar(),
-  ]
-  foo_instance.data = 'Hello world'
-  foo_instance.source = _NewHandle()
-  foo_instance.input_streams = [ _NewHandle() ]
-  foo_instance.output_streams = [ _NewHandle(), _NewHandle() ]
-  foo_instance.array_of_array_of_bools = [ [ True, False ], [] ]
-  foo_instance.multi_array_of_strings = [
-      [
-          [ "1", "2" ],
-          [],
-          [ "3", "4" ],
-      ],
-      [],
-  ]
-  foo_instance.array_of_bools = [ True, 0, 1, 2, 0, 0, 0, 0, 0, True ]
-  return foo_instance
-
-
-class SerializationDeserializationTest(mojo_unittest.MojoTestCase):
-
-  def testFooSerialization(self):
-    (data, _) = _NewFoo().Serialize()
-    self.assertTrue(len(data))
-    self.assertEquals(len(data) % 8, 0)
-
-  def testFooDeserialization(self):
-    (data, handles) = _NewFoo().Serialize()
-    context = serialization.RootDeserializationContext(data, handles)
-    self.assertTrue(
-        sample_service_mojom.Foo.Deserialize(context))
-
-  def testFooSerializationDeserialization(self):
-    foo1 = _NewFoo()
-    (data, handles) = foo1.Serialize()
-    context = serialization.RootDeserializationContext(data, handles)
-    foo2 = sample_service_mojom.Foo.Deserialize(context)
-    self.assertEquals(foo1, foo2)
-
-  def testDefaultsTestSerializationDeserialization(self):
-    v1 = sample_service_mojom.DefaultsTest()
-    v1.a18 = []
-    v1.a19 = ""
-    v1.a21 = sample_import_mojom.Point()
-    v1.a22.location = sample_import_mojom.Point()
-    v1.a22.size = sample_import2_mojom.Size()
-    (data, handles) = v1.Serialize()
-    context = serialization.RootDeserializationContext(data, handles)
-    v2 = sample_service_mojom.DefaultsTest.Deserialize(context)
-    # NaN needs to be a special case.
-    self.assertNotEquals(v1, v2)
-    self.assertTrue(math.isnan(v2.a28))
-    self.assertTrue(math.isnan(v2.a31))
-    v1.a28 = v2.a28 = v1.a31 = v2.a31 = 0
-    self.assertEquals(v1, v2)
-
-  def testFooDeserializationError(self):
-    with self.assertRaises(Exception):
-      sample_service_mojom.Foo.Deserialize("", [])
diff --git a/mojo/python/tests/bindings_structs_unittest.py b/mojo/python/tests/bindings_structs_unittest.py
deleted file mode 100644
index c53c1a0..0000000
--- a/mojo/python/tests/bindings_structs_unittest.py
+++ /dev/null
@@ -1,217 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import math
-import unittest
-
-# pylint: disable=E0611,F0401
-import mojo_system
-
-# Generated files
-# pylint: disable=F0401
-import regression_tests_mojom
-import sample_import_mojom
-import sample_import2_mojom
-import sample_service_mojom
-
-
-class StructBindingsTest(unittest.TestCase):
-
-  def testModule(self):
-    self.assertEquals(sample_service_mojom.DefaultsTest.__module__,
-                      'sample_service_mojom')
-
-  def testDefaultsTest(self):
-    defaults_test = sample_service_mojom.DefaultsTest()
-    self.assertEquals(defaults_test.a0, -12)
-    self.assertEquals(defaults_test.a1, 12)
-    self.assertEquals(defaults_test.a2, 1234)
-    self.assertEquals(defaults_test.a3, 34567)
-    self.assertEquals(defaults_test.a4, 123456)
-    self.assertEquals(defaults_test.a5, 3456789012)
-    self.assertEquals(defaults_test.a6, -111111111111)
-    self.assertEquals(defaults_test.a7, 9999999999999999999)
-    self.assertEquals(defaults_test.a8, 0x12345)
-    self.assertEquals(defaults_test.a9, -0x12345)
-    self.assertEquals(defaults_test.a10, 1234)
-    self.assertEquals(defaults_test.a11, True)
-    self.assertEquals(defaults_test.a12, False)
-    self.assertEquals(defaults_test.a13, 123.25)
-    self.assertEquals(defaults_test.a14, 1234567890.123)
-    self.assertEquals(defaults_test.a15, 1E10)
-    self.assertEquals(defaults_test.a16, -1.2E+20)
-    self.assertEquals(defaults_test.a17, 1.23E-20)
-    self.assertEquals(defaults_test.a18, None)
-    self.assertEquals(defaults_test.a19, None)
-    self.assertEquals(defaults_test.a20, sample_service_mojom.Bar.Type.BOTH)
-    self.assertEquals(defaults_test.a21, None)
-    self.assertTrue(isinstance(defaults_test.a22, sample_import2_mojom.Thing))
-    self.assertEquals(defaults_test.a23, 0xFFFFFFFFFFFFFFFF)
-    self.assertEquals(defaults_test.a24, 0x123456789)
-    self.assertEquals(defaults_test.a25, -0x123456789)
-    self.assertEquals(defaults_test.a26, float('inf'))
-    self.assertEquals(defaults_test.a27, float('-inf'))
-    self.assertTrue(math.isnan(defaults_test.a28))
-    self.assertEquals(defaults_test.a29, float('inf'))
-    self.assertEquals(defaults_test.a30, float('-inf'))
-    self.assertTrue(math.isnan(defaults_test.a31))
-
-  def testNoAliasing(self):
-    foo1 = sample_service_mojom.Foo()
-    foo2 = sample_service_mojom.Foo()
-    foo1.name = "foo1"
-    foo2.name = "foo2"
-    self.assertEquals(foo1.name, "foo1")
-    self.assertEquals(foo2.name, "foo2")
-
-    defaults_test1 = sample_service_mojom.DefaultsTest()
-    defaults_test2 = sample_service_mojom.DefaultsTest()
-    self.assertIsNot(defaults_test1.a22, defaults_test2.a22)
-
-  def testImmutableAttributeSet(self):
-    foo_instance = sample_service_mojom.Foo()
-    with self.assertRaises(AttributeError):
-      foo_instance.new_attribute = None
-    with self.assertRaises(AttributeError):
-      del foo_instance.name
-
-  def _TestIntegerField(self, entity, field_name, bits, signed):
-    if signed:
-      min_value = -(1 << (bits - 1))
-      max_value = (1 << (bits - 1)) - 1
-    else:
-      min_value = 0
-      max_value = (1 << bits) - 1
-    entity.__setattr__(field_name, min_value)
-    entity.__setattr__(field_name, max_value)
-    with self.assertRaises(TypeError):
-      entity.__setattr__(field_name, None)
-    with self.assertRaises(OverflowError):
-      entity.__setattr__(field_name, min_value - 1)
-    with self.assertRaises(OverflowError):
-      entity.__setattr__(field_name, max_value + 1)
-    with self.assertRaises(TypeError):
-      entity.__setattr__(field_name, 'hello world')
-
-  def testTypes(self):
-    defaults_test = sample_service_mojom.DefaultsTest()
-    # Integer types
-    self._TestIntegerField(defaults_test, 'a0', 8, True)
-    self._TestIntegerField(defaults_test, 'a1', 8, False)
-    self._TestIntegerField(defaults_test, 'a2', 16, True)
-    self._TestIntegerField(defaults_test, 'a3', 16, False)
-    self._TestIntegerField(defaults_test, 'a4', 32, True)
-    self._TestIntegerField(defaults_test, 'a5', 32, False)
-    self._TestIntegerField(defaults_test, 'a6', 64, True)
-    self._TestIntegerField(defaults_test, 'a7', 64, False)
-
-    # Boolean types
-    defaults_test.a11 = False
-    self.assertEquals(defaults_test.a11, False)
-    defaults_test.a11 = None
-    self.assertEquals(defaults_test.a11, False)
-    defaults_test.a11 = []
-    self.assertEquals(defaults_test.a11, False)
-    defaults_test.a12 = True
-    self.assertEquals(defaults_test.a12, True)
-    defaults_test.a12 = 1
-    self.assertEquals(defaults_test.a12, True)
-    defaults_test.a12 = [[]]
-    self.assertEquals(defaults_test.a12, True)
-
-    # Floating point types
-    with self.assertRaises(TypeError):
-      defaults_test.a13 = 'hello'
-    with self.assertRaises(TypeError):
-      defaults_test.a14 = 'hello'
-
-    # Array type
-    defaults_test.a18 = None
-    defaults_test.a18 = []
-    defaults_test.a18 = [ 0 ]
-    defaults_test.a18 = [ 255 ]
-    defaults_test.a18 = [ 0, 255 ]
-    with self.assertRaises(TypeError):
-      defaults_test.a18 = [[]]
-    with self.assertRaises(OverflowError):
-      defaults_test.a18 = [ -1 ]
-    with self.assertRaises(OverflowError):
-      defaults_test.a18 = [ 256 ]
-
-    # String type
-    defaults_test.a19 = None
-    defaults_test.a19 = ''
-    defaults_test.a19 = 'hello world'
-    with self.assertRaises(TypeError):
-      defaults_test.a19 = [[]]
-    with self.assertRaises(TypeError):
-      defaults_test.a19 = [ -1 ]
-    with self.assertRaises(TypeError):
-      defaults_test.a19 = [ 256 ]
-
-    # Structs
-    defaults_test.a21 = None
-    defaults_test.a21 = sample_import_mojom.Point()
-    with self.assertRaises(TypeError):
-      defaults_test.a21 = 1
-    with self.assertRaises(TypeError):
-      defaults_test.a21 = sample_import2_mojom.Thing()
-
-    # Handles
-    foo_instance = sample_service_mojom.Foo()
-    foo_instance.source = None
-    foo_instance.source = mojo_system.Handle()
-    with self.assertRaises(TypeError):
-      foo_instance.source = 1
-    with self.assertRaises(TypeError):
-      foo_instance.source = object()
-
-  def testConstructor(self):
-    bar_instance = sample_service_mojom.Bar()
-    foo_instance = sample_service_mojom.Foo(name="Foo",
-                                            x=-1,
-                                            y=5,
-                                            a=False,
-                                            bar=bar_instance)
-    self.assertEquals(foo_instance.name, "Foo")
-    self.assertEquals(foo_instance.x, -1)
-    self.assertEquals(foo_instance.y, 5)
-    self.assertEquals(foo_instance.a, False)
-    self.assertEquals(foo_instance.bar, bar_instance)
-
-  def testPositionalConstructor(self):
-    p = sample_import_mojom.Point()
-    self.assertEquals(p.x, 0)
-    self.assertEquals(p.y, 0)
-
-    p = sample_import_mojom.Point(34)
-    self.assertEquals(p.x, 34)
-    self.assertEquals(p.y, 0)
-
-    p = sample_import_mojom.Point(34, 12)
-    self.assertEquals(p.x, 34)
-    self.assertEquals(p.y, 12)
-
-    p = sample_import_mojom.Point(x=34, y=12)
-    self.assertEquals(p.x, 34)
-    self.assertEquals(p.y, 12)
-
-    p = sample_import_mojom.Point(34, y=12)
-    self.assertEquals(p.x, 34)
-    self.assertEquals(p.y, 12)
-
-    with self.assertRaises(TypeError):
-      p = sample_import_mojom.Point(0, 0, 0)
-    with self.assertRaises(TypeError):
-      p = sample_import_mojom.Point(0, x=0)
-    with self.assertRaises(TypeError):
-      p = sample_import_mojom.Point(c=0)
-
-  def testCyclicDefinition(self):
-    a = regression_tests_mojom.A()
-    b = regression_tests_mojom.B()
-    self.assertIsNone(a.b)
-    self.assertIsNone(b.a)
-    a.b = b
-    self.assertIs(a.b, b)
diff --git a/mojo/python/tests/bindings_structs_version_unittest.py b/mojo/python/tests/bindings_structs_version_unittest.py
deleted file mode 100644
index 231f240..0000000
--- a/mojo/python/tests/bindings_structs_version_unittest.py
+++ /dev/null
@@ -1,150 +0,0 @@
-# Copyright 2015 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import math
-import unittest
-
-import mojo_unittest
-
-# pylint: disable=E0611,F0401
-import mojo_bindings.serialization as serialization
-import mojo_system
-
-# Generated files
-# pylint: disable=F0401
-import rect_mojom
-import test_structs_mojom
-
-
-class StructVersionBindingsTest(mojo_unittest.MojoTestCase):
-
-  def SerializeAndDeserialize(self, target_class, input_instance):
-    (data, handles) = input_instance.Serialize()
-    context = serialization.RootDeserializationContext(data, handles)
-    return target_class.Deserialize(context)
-
-  def MakeRect(self, factor):
-    return rect_mojom.Rect(
-        x=factor, y=2*factor, width=10*factor, height=20*factor)
-
-  def testOldToNew(self):
-    v0 = test_structs_mojom.MultiVersionStructV0()
-    v0.f_int32 = 123
-    expected = test_structs_mojom.MultiVersionStruct()
-    expected.f_int32 = 123
-
-    output = self.SerializeAndDeserialize(
-        test_structs_mojom.MultiVersionStruct, v0)
-    self.assertEquals(output, expected)
-
-    v1 = test_structs_mojom.MultiVersionStructV1()
-    v1.f_int32 = 123
-    v1.f_rect = self.MakeRect(5)
-    expected = test_structs_mojom.MultiVersionStruct()
-    expected.f_int32 = 123
-    expected.f_rect = self.MakeRect(5)
-
-    output = self.SerializeAndDeserialize(
-        test_structs_mojom.MultiVersionStruct, v1)
-    self.assertEquals(output, expected)
-
-    v3 = test_structs_mojom.MultiVersionStructV3()
-    v3.f_int32 = 123
-    v3.f_rect = self.MakeRect(5)
-    v3.f_string = 'hello'
-    expected = test_structs_mojom.MultiVersionStruct()
-    expected.f_int32 = 123
-    expected.f_rect = self.MakeRect(5)
-    expected.f_string = 'hello'
-
-    output = self.SerializeAndDeserialize(
-        test_structs_mojom.MultiVersionStruct, v3)
-    self.assertEquals(output, expected)
-
-    v5 = test_structs_mojom.MultiVersionStructV5()
-    v5.f_int32 = 123
-    v5.f_rect = self.MakeRect(5)
-    v5.f_string = 'hello'
-    v5.f_array = [10, 9, 8]
-    expected = test_structs_mojom.MultiVersionStruct()
-    expected.f_int32 = 123
-    expected.f_rect = self.MakeRect(5)
-    expected.f_string = 'hello'
-    expected.f_array = [10, 9, 8]
-
-    output = self.SerializeAndDeserialize(
-        test_structs_mojom.MultiVersionStruct, v5)
-    self.assertEquals(output, expected)
-
-    pipe = mojo_system.MessagePipe()
-    v7 = test_structs_mojom.MultiVersionStructV7()
-    v7.f_int32 = 123
-    v7.f_rect = self.MakeRect(5)
-    v7.f_string = 'hello'
-    v7.f_array = [10, 9, 8]
-    v7.f_message_pipe = pipe.handle0
-    v7.f_bool = True
-    expected = test_structs_mojom.MultiVersionStruct()
-    expected.f_int32 = 123
-    expected.f_rect = self.MakeRect(5)
-    expected.f_string = 'hello'
-    expected.f_array = [10, 9, 8]
-    expected.f_message_pipe = pipe.handle0
-    expected.f_bool = True
-
-    output = self.SerializeAndDeserialize(
-        test_structs_mojom.MultiVersionStruct, v7)
-    self.assertEquals(output, expected)
-
-  def testNewToNew(self):
-    pipe = mojo_system.MessagePipe()
-    input_struct = test_structs_mojom.MultiVersionStruct()
-    input_struct.f_int32 = 123
-    input_struct.f_rect = self.MakeRect(5)
-    input_struct.f_string = 'hello'
-    input_struct.f_array = [10, 9, 8]
-    input_struct.f_message_pipe = pipe.handle0
-    input_struct.f_bool = True
-    input_struct.f_int16 = 256
-
-    expected = test_structs_mojom.MultiVersionStructV7()
-    expected.f_int32 = 123
-    expected.f_rect = self.MakeRect(5)
-    expected.f_string = 'hello'
-    expected.f_array = [10, 9, 8]
-    expected.f_message_pipe = pipe.handle0
-    expected.f_bool = True
-    output = self.SerializeAndDeserialize(
-        test_structs_mojom.MultiVersionStructV7, input_struct)
-    self.assertEquals(output, expected)
-
-    expected = test_structs_mojom.MultiVersionStructV5()
-    expected.f_int32 = 123
-    expected.f_rect = self.MakeRect(5)
-    expected.f_string = 'hello'
-    expected.f_array = [10, 9, 8]
-    output = self.SerializeAndDeserialize(
-        test_structs_mojom.MultiVersionStructV5, input_struct)
-    self.assertEquals(output, expected)
-
-    expected = test_structs_mojom.MultiVersionStructV3()
-    expected.f_int32 = 123
-    expected.f_rect = self.MakeRect(5)
-    expected.f_string = 'hello'
-    output = self.SerializeAndDeserialize(
-        test_structs_mojom.MultiVersionStructV3, input_struct)
-    self.assertEquals(output, expected)
-
-    expected = test_structs_mojom.MultiVersionStructV1()
-    expected.f_int32 = 123
-    expected.f_rect = self.MakeRect(5)
-    output = self.SerializeAndDeserialize(
-        test_structs_mojom.MultiVersionStructV1, input_struct)
-    self.assertEquals(output, expected)
-
-    expected = test_structs_mojom.MultiVersionStructV0()
-    expected.f_int32 = 123
-    output = self.SerializeAndDeserialize(
-        test_structs_mojom.MultiVersionStructV0, input_struct)
-    self.assertEquals(output, expected)
diff --git a/mojo/python/tests/bindings_unions_unittest.py b/mojo/python/tests/bindings_unions_unittest.py
deleted file mode 100644
index b1d742f..0000000
--- a/mojo/python/tests/bindings_unions_unittest.py
+++ /dev/null
@@ -1,188 +0,0 @@
-# Copyright 2015 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import struct
-import unittest
-
-# Generated files
-# pylint: disable=F0401
-import test_unions_mojom
-import mojo_bindings.serialization as serialization
-
-class UnionBindingsTest(unittest.TestCase):
-
-  def testBasics(self):
-    u = test_unions_mojom.PodUnion()
-    self.assertTrue(u.IsUnknown())
-
-    u.f_uint32 = 32
-    self.assertEquals(u.f_uint32, 32)
-    self.assertEquals(u.data, 32)
-    self.assertEquals(test_unions_mojom.PodUnion.Tags.f_uint32, u.tag)
-    self.assertFalse(u.IsUnknown())
-
-    u = test_unions_mojom.PodUnion(f_uint8=8)
-    self.assertEquals(u.f_uint8, 8)
-    self.assertEquals(u.data, 8)
-    self.assertEquals(test_unions_mojom.PodUnion.Tags.f_uint8, u.tag)
-
-    with self.assertRaises(TypeError):
-      test_unions_mojom.PodUnion(f_uint8=8, f_int16=10)
-
-    with self.assertRaises(AttributeError):
-      test_unions_mojom.PodUnion(bad_field=10)
-
-    with self.assertRaises(AttributeError):
-      u = test_unions_mojom.PodUnion()
-      u.bad_field = 32
-
-    with self.assertRaises(AttributeError):
-      _ = u.f_uint16
-
-  def testPodUnionSerialization(self):
-    u = test_unions_mojom.PodUnion(f_uint32=32)
-    (data, handles) = u.Serialize()
-    context = serialization.RootDeserializationContext(data, handles)
-    decoded = test_unions_mojom.PodUnion.Deserialize(context)
-
-    self.assertFalse(decoded.IsUnknown())
-    self.assertEquals(u, decoded)
-
-  def testUnionUnknownTag(self):
-    u = test_unions_mojom.NewUnion(f_int16=10)
-    (data, handles) = u.Serialize()
-    context = serialization.RootDeserializationContext(data, handles)
-    decoded = test_unions_mojom.OldUnion.Deserialize(context)
-
-    self.assertTrue(decoded.IsUnknown())
-
-  def testObjectInUnionSerialization(self):
-    u = test_unions_mojom.ObjectUnion(
-        f_dummy=test_unions_mojom.DummyStruct())
-    u.f_dummy.f_int8 = 8
-    (data, handles) = u.Serialize()
-    context = serialization.RootDeserializationContext(data, handles)
-    decoded = test_unions_mojom.ObjectUnion.Deserialize(context)
-
-    self.assertEquals(u, decoded)
-
-  def testObjectInUnionInObjectSerialization(self):
-    s = test_unions_mojom.SmallObjStruct()
-    s.obj_union = test_unions_mojom.ObjectUnion(
-        f_dummy=test_unions_mojom.DummyStruct())
-    s.obj_union.f_dummy.f_int8 = 25
-    (data, handles) = s.Serialize()
-    context = serialization.RootDeserializationContext(data, handles)
-    decoded = test_unions_mojom.SmallObjStruct.Deserialize(context)
-
-    self.assertEquals(s, decoded)
-
-  def testNestedUnionSerialization(self):
-    u = test_unions_mojom.ObjectUnion(
-        f_pod_union=test_unions_mojom.PodUnion(f_int32=32))
-
-    (data, handles) = u.Serialize()
-    context = serialization.RootDeserializationContext(data, handles)
-    decoded = test_unions_mojom.ObjectUnion.Deserialize(context)
-
-    self.assertEquals(u, decoded)
-
-  def testNullableNullObjectInUnionSerialization(self):
-    u =  test_unions_mojom.ObjectUnion(f_nullable=None)
-    (data, handles) = u.Serialize()
-    context = serialization.RootDeserializationContext(data, handles)
-    decoded = test_unions_mojom.ObjectUnion.Deserialize(context)
-
-    self.assertEquals(u, decoded)
-
-  def testNonNullableNullObjectInUnionSerialization(self):
-    u =  test_unions_mojom.ObjectUnion(f_dummy=None)
-    with self.assertRaises(serialization.SerializationException):
-      u.Serialize()
-
-  def testArrayInUnionSerialization(self):
-    u = test_unions_mojom.ObjectUnion(
-        f_array_int8=[1, 2, 3, 4, 5])
-    (data, handles) = u.Serialize()
-    context = serialization.RootDeserializationContext(data, handles)
-    decoded = test_unions_mojom.ObjectUnion.Deserialize(context)
-
-    self.assertEquals(u, decoded)
-
-  def testMapInUnionSerialization(self):
-    u = test_unions_mojom.ObjectUnion(
-        f_map_int8={'one': 1, 'two': 2, 'three': 3})
-    (data, handles) = u.Serialize()
-    context = serialization.RootDeserializationContext(data, handles)
-    decoded = test_unions_mojom.ObjectUnion.Deserialize(context)
-
-    self.assertEquals(u, decoded)
-
-  def testUnionInObject(self):
-    s = test_unions_mojom.SmallStruct()
-    s.pod_union = test_unions_mojom.PodUnion(f_uint32=32)
-    (data, handles) = s.Serialize()
-
-    # This is where the data should be serialized to.
-    size, tag, value = struct.unpack_from('<IIQ', buffer(data), 16)
-    self.assertEquals(16, size)
-    self.assertEquals(6, tag)
-    self.assertEquals(32, value)
-
-    context = serialization.RootDeserializationContext(data, handles)
-    decoded = test_unions_mojom.SmallStruct.Deserialize(context)
-
-    self.assertEquals(s, decoded)
-
-  def testUnionInArray(self):
-    s = test_unions_mojom.SmallStruct()
-    s.pod_union_array = [
-        test_unions_mojom.PodUnion(f_uint32=32),
-        test_unions_mojom.PodUnion(f_uint16=16),
-        test_unions_mojom.PodUnion(f_uint64=64),
-        ]
-    (data, handles) = s.Serialize()
-
-    context = serialization.RootDeserializationContext(data, handles)
-    decoded = test_unions_mojom.SmallStruct.Deserialize(context)
-
-    self.assertEquals(s, decoded)
-
-  def testNonNullableNullUnionInArray(self):
-    s = test_unions_mojom.SmallStruct()
-    s.pod_union_array = [
-        test_unions_mojom.PodUnion(f_uint32=32),
-        None,
-        test_unions_mojom.PodUnion(f_uint64=64),
-        ]
-    with self.assertRaises(serialization.SerializationException):