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):
-      s.Serialize()
-
-  def testNullableNullUnionInArray(self):
-    s = test_unions_mojom.SmallStruct()
-    s.nullable_pod_union_array = [
-        test_unions_mojom.PodUnion(f_uint32=32),
-        None,
-        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 testUnionInMap(self):
-    s = test_unions_mojom.SmallStruct()
-    s.pod_union_map = {
-        'f_uint32': test_unions_mojom.PodUnion(f_uint32=32),
-        'f_uint16': test_unions_mojom.PodUnion(f_uint16=16),
-        'f_uint64': 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)
diff --git a/mojo/python/tests/data_pipe_utils_unittest.py b/mojo/python/tests/data_pipe_utils_unittest.py
deleted file mode 100644
index b6bc9fa..0000000
--- a/mojo/python/tests/data_pipe_utils_unittest.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.
-
-import random
-
-import mojo_unittest
-from mojo_bindings import promise
-
-# pylint: disable=F0401
-import mojo_system as system
-
-# pylint: disable=F0401
-from mojo_utils import data_pipe_utils
-
-
-def _GetRandomBuffer(size):
-  random.seed(size)
-  return bytearray(''.join(chr(random.randint(0, 255)) for i in xrange(size)))
-
-
-class DataPipeCopyTest(mojo_unittest.MojoTestCase):
-  def setUp(self):
-    super(DataPipeCopyTest, self).setUp()
-    self.handles = system.DataPipe()
-    self.error = None
-
-  def tearDown(self):
-    self.handles = None
-    super(DataPipeCopyTest, self).tearDown()
-
-  def _writeDataAndClose(self, handle, data):
-    status, num_bytes_written = handle.WriteData(data)
-    handle.Close()
-    self.assertEquals(system.RESULT_OK, status)
-    self.assertEquals(len(data), num_bytes_written)
-
-  def _copyDataFromPipe(self, handle, expected_data,
-                        deadline=system.DEADLINE_INDEFINITE):
-    self._VerifyDataCopied(data_pipe_utils.CopyFromDataPipe(
-         handle, deadline), expected_data).Catch(self._CatchError)
-
-  def _CatchError(self, error):
-    if self.loop:
-      self.loop.Quit()
-    self.error = error
-
-  @promise.async
-  def _VerifyDataCopied(self, data, expected_data):
-    self.assertEquals(expected_data, data)
-    self.loop.Quit()
-
-  def _runAndCheckError(self):
-    self.loop.Run()
-    if self.error:
-      # pylint: disable=E0702
-      raise self.error
-
-  def _testEagerWrite(self, data):
-    self._writeDataAndClose(self.handles.producer_handle, data)
-    self._copyDataFromPipe(self.handles.consumer_handle, data)
-    self._runAndCheckError()
-
-  def _testDelayedWrite(self, data):
-    self._copyDataFromPipe(self.handles.consumer_handle, data)
-    self._writeDataAndClose(self.handles.producer_handle, data)
-    self._runAndCheckError()
-
-  def testTimeout(self):
-    self._copyDataFromPipe(self.handles.consumer_handle, bytearray(),
-                           deadline=100)
-    with self.assertRaises(data_pipe_utils.DataPipeCopyException):
-      self._runAndCheckError()
-
-  def testCloseProducerWithoutWriting(self):
-    self._copyDataFromPipe(self.handles.consumer_handle, bytearray())
-    self.handles.producer_handle.Close()
-    self._runAndCheckError()
-
-  def testEagerWriteOfEmptyData(self):
-    self._testEagerWrite(bytearray())
-
-  def testDelayedWriteOfEmptyData(self):
-    self._testDelayedWrite(bytearray())
-
-  def testEagerWriteOfNonEmptyData(self):
-    self._testEagerWrite(_GetRandomBuffer(1024))
-
-  def testDelayedWriteOfNonEmptyData(self):
-    self._testDelayedWrite(_GetRandomBuffer(1024))
-
-  def testEagerWriteOfLargeBuffer(self):
-    self._testEagerWrite(_GetRandomBuffer(32 * 1024))
-
-  def testDelayedWriteOfLargeBuffer(self):
-    self._testDelayedWrite(_GetRandomBuffer(32 * 1024))
diff --git a/mojo/python/tests/generation_unittest.py b/mojo/python/tests/generation_unittest.py
deleted file mode 100644
index 0282ae5..0000000
--- a/mojo/python/tests/generation_unittest.py
+++ /dev/null
@@ -1,37 +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
-from mojo_bindings import reflection
-from mojo_bindings import interface_reflection
-
-
-class GenerationTest(mojo_unittest.MojoTestCase):
-
-  TEST_PACKAGES = [
-    'math_calculator_mojom',
-    'no_module_mojom',
-    'rect_mojom',
-    'regression_tests_mojom',
-    'sample_factory_mojom',
-    'sample_import2_mojom',
-    'sample_import_mojom',
-    'sample_interfaces_mojom',
-    'sample_service_mojom',
-    'serialization_test_structs_mojom',
-    'test_structs_mojom',
-    'validation_test_interfaces_mojom',
-  ]
-
-  @staticmethod
-  def testGeneration():
-    buildable_types = (reflection.MojoStructType,
-                       interface_reflection.MojoInterfaceType)
-    for module_name in GenerationTest.TEST_PACKAGES:
-      module = __import__(module_name)
-      for element_name in dir(module):
-        element = getattr(module, element_name)
-        if isinstance(element, buildable_types):
-          # Check struct and interface are buildable
-          element()
diff --git a/mojo/python/tests/messaging_unittest.py b/mojo/python/tests/messaging_unittest.py
deleted file mode 100644
index c5d6a2b..0000000
--- a/mojo/python/tests/messaging_unittest.py
+++ /dev/null
@@ -1,218 +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
-
-import mojo_unittest
-from mojo_bindings import messaging
-
-# pylint: disable=E0611
-import mojo_system as system
-
-
-class _ForwardingConnectionErrorHandler(messaging.ConnectionErrorHandler):
-
-  def __init__(self, callback):
-    messaging.ConnectionErrorHandler.__init__(self)
-    self._callback = callback
-
-  def OnError(self, result):
-    self._callback(result)
-
-
-class ConnectorTest(mojo_unittest.MojoTestCase):
-
-  def setUp(self):
-    super(ConnectorTest, self).setUp()
-    self.received_messages = []
-    self.received_errors = []
-    def _OnMessage(message):
-      self.received_messages.append(message)
-      return True
-    def _OnError(result):
-      self.received_errors.append(result)
-    handles = system.MessagePipe()
-    self.connector = messaging.Connector(handles.handle1)
-    self.connector.SetIncomingMessageReceiver(
-        messaging.ForwardingMessageReceiver(_OnMessage))
-    self.connector.SetErrorHandler(
-        _ForwardingConnectionErrorHandler(_OnError))
-    self.connector.Start()
-    self.handle = handles.handle0
-
-
-  def tearDown(self):
-    self.connector = None
-    self.handle = None
-    self.received_messages = []
-    self.received_errors = []
-    super(ConnectorTest, self).tearDown()
-
-  def testConnectorRead(self):
-    self.handle.WriteMessage()
-    self.loop.RunUntilIdle()
-    self.assertTrue(self.received_messages)
-    self.assertFalse(self.received_errors)
-
-  def testConnectorWrite(self):
-    self.connector.Accept(messaging.Message())
-    (result, _, _) = self.handle.ReadMessage()
-    self.assertEquals(result, system.RESULT_OK)
-    self.assertFalse(self.received_errors)
-
-  def testConnectorCloseRemoteHandle(self):
-    self.handle.Close()
-    self.loop.RunUntilIdle()
-    self.assertFalse(self.received_messages)
-    self.assertTrue(self.received_errors)
-    self.assertEquals(self.received_errors[0],
-                      system.RESULT_FAILED_PRECONDITION)
-
-  def testConnectorDeleteConnector(self):
-    self.connector = None
-    (result, _, _) = self.handle.ReadMessage()
-    self.assertEquals(result, system.RESULT_FAILED_PRECONDITION)
-
-  def testConnectorWriteHandle(self):
-    new_handles = system.MessagePipe()
-    self.handle.WriteMessage(None, [new_handles.handle0])
-    self.loop.RunUntilIdle()
-    self.assertTrue(self.received_messages)
-    self.assertTrue(self.received_messages[0].handles)
-    self.assertFalse(self.received_errors)
-
-
-class HeaderTest(unittest.TestCase):
-
-  def testSimpleMessageHeader(self):
-    header = messaging.MessageHeader(0xdeadbeaf, messaging.NO_FLAG)
-    self.assertEqual(header.message_type, 0xdeadbeaf)
-    self.assertFalse(header.has_request_id)
-    self.assertFalse(header.expects_response)
-    self.assertFalse(header.is_response)
-    data = header.Serialize()
-    other_header = messaging.MessageHeader.Deserialize(data)
-    self.assertEqual(other_header.message_type, 0xdeadbeaf)
-    self.assertFalse(other_header.has_request_id)
-    self.assertFalse(other_header.expects_response)
-    self.assertFalse(other_header.is_response)
-
-  def testMessageHeaderWithRequestID(self):
-    # Request message.
-    header = messaging.MessageHeader(0xdeadbeaf,
-                                     messaging.MESSAGE_EXPECTS_RESPONSE_FLAG)
-
-    self.assertEqual(header.message_type, 0xdeadbeaf)
-    self.assertTrue(header.has_request_id)
-    self.assertTrue(header.expects_response)
-    self.assertFalse(header.is_response)
-    self.assertEqual(header.request_id, 0)
-
-    data = header.Serialize()
-    other_header = messaging.MessageHeader.Deserialize(data)
-
-    self.assertEqual(other_header.message_type, 0xdeadbeaf)
-    self.assertTrue(other_header.has_request_id)
-    self.assertTrue(other_header.expects_response)
-    self.assertFalse(other_header.is_response)
-    self.assertEqual(other_header.request_id, 0)
-
-    header.request_id = 0xdeadbeafdeadbeaf
-    data = header.Serialize()
-    other_header = messaging.MessageHeader.Deserialize(data)
-
-    self.assertEqual(other_header.request_id, 0xdeadbeafdeadbeaf)
-
-    # Response message.
-    header = messaging.MessageHeader(0xdeadbeaf,
-                                     messaging.MESSAGE_IS_RESPONSE_FLAG,
-                                     0xdeadbeafdeadbeaf)
-
-    self.assertEqual(header.message_type, 0xdeadbeaf)
-    self.assertTrue(header.has_request_id)
-    self.assertFalse(header.expects_response)
-    self.assertTrue(header.is_response)
-    self.assertEqual(header.request_id, 0xdeadbeafdeadbeaf)
-
-    data = header.Serialize()
-    other_header = messaging.MessageHeader.Deserialize(data)
-
-    self.assertEqual(other_header.message_type, 0xdeadbeaf)
-    self.assertTrue(other_header.has_request_id)
-    self.assertFalse(other_header.expects_response)
-    self.assertTrue(other_header.is_response)
-    self.assertEqual(other_header.request_id, 0xdeadbeafdeadbeaf)
-
-
-class RouterTest(mojo_unittest.MojoTestCase):
-
-  def setUp(self):
-    super(RouterTest, self).setUp()
-    self.received_messages = []
-    self.received_errors = []
-    def _OnMessage(message):
-      self.received_messages.append(message)
-      return True
-    def _OnError(result):
-      self.received_errors.append(result)
-    handles = system.MessagePipe()
-    self.router = messaging.Router(handles.handle1)
-    self.router.SetIncomingMessageReceiver(
-        messaging.ForwardingMessageReceiver(_OnMessage))
-    self.router.SetErrorHandler(
-        _ForwardingConnectionErrorHandler(_OnError))
-    self.router.Start()
-    self.handle = handles.handle0
-
-  def tearDown(self):
-    self.router = None
-    self.handle = None
-    super(RouterTest, self).tearDown()
-
-  def testSimpleMessage(self):
-    header_data = messaging.MessageHeader(0, messaging.NO_FLAG).Serialize()
-    message = messaging.Message(header_data)
-    self.router.Accept(message)
-    self.loop.RunUntilIdle()
-    self.assertFalse(self.received_errors)
-    self.assertFalse(self.received_messages)
-    (res, data, _) = self.handle.ReadMessage(bytearray(len(header_data)))
-    self.assertEquals(system.RESULT_OK, res)
-    self.assertEquals(data[0], header_data)
-
-  def testSimpleReception(self):
-    header_data = messaging.MessageHeader(0, messaging.NO_FLAG).Serialize()
-    self.handle.WriteMessage(header_data)
-    self.loop.RunUntilIdle()
-    self.assertFalse(self.received_errors)
-    self.assertEquals(len(self.received_messages), 1)
-    self.assertEquals(self.received_messages[0].data, header_data)
-
-  def testRequestResponse(self):
-    header_data = messaging.MessageHeader(
-        0, messaging.MESSAGE_EXPECTS_RESPONSE_FLAG).Serialize()
-    message = messaging.Message(header_data)
-    back_messages = []
-    def OnBackMessage(message):
-      back_messages.append(message)
-      return True
-    self.router.AcceptWithResponder(message,
-                                    messaging.ForwardingMessageReceiver(
-                                        OnBackMessage))
-    self.loop.RunUntilIdle()
-    self.assertFalse(self.received_errors)
-    self.assertFalse(self.received_messages)
-    (res, data, _) = self.handle.ReadMessage(bytearray(len(header_data)))
-    self.assertEquals(system.RESULT_OK, res)
-    message_header = messaging.MessageHeader.Deserialize(data[0])
-    self.assertNotEquals(message_header.request_id, 0)
-    response_header_data = messaging.MessageHeader(
-        0,
-        messaging.MESSAGE_IS_RESPONSE_FLAG,
-        message_header.request_id).Serialize()
-    self.handle.WriteMessage(response_header_data)
-    self.loop.RunUntilIdle()
-    self.assertFalse(self.received_errors)
-    self.assertEquals(len(back_messages), 1)
-    self.assertEquals(back_messages[0].data, response_header_data)
diff --git a/mojo/python/tests/mojo_unittest.py b/mojo/python/tests/mojo_unittest.py
deleted file mode 100644
index fc921ac..0000000
--- a/mojo/python/tests/mojo_unittest.py
+++ /dev/null
@@ -1,24 +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
-
-# pylint: disable=E0611,F0401
-import mojo_embedder
-import mojo_system
-
-
-class MojoTestCase(unittest.TestCase):
-  def __init__(self, *args, **kwargs):
-    unittest.TestCase.__init__(self, *args, **kwargs)
-    self.loop = None
-
-  def run(self, *args, **kwargs):
-    try:
-      mojo_embedder.Init()
-      self.loop = mojo_system.RunLoop()
-      unittest.TestCase.run(self, *args, **kwargs)
-    finally:
-      self.loop = None
-      assert mojo_embedder.ShutdownForTest()
diff --git a/mojo/python/tests/promise_unittest.py b/mojo/python/tests/promise_unittest.py
deleted file mode 100644
index bb85f5a..0000000
--- a/mojo/python/tests/promise_unittest.py
+++ /dev/null
@@ -1,238 +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
-
-# pylint: disable=F0401
-from mojo_bindings import promise
-
-
-class PromiseTest(unittest.TestCase):
-
-  def setUp(self):
-    self.accumulated = []
-
-  def _AddToAccumulated(self, res):
-    self.accumulated.append(res)
-    return res
-
-  def testResolve(self):
-    p = promise.Promise.Resolve(0)
-    self.assertEquals(p.state, promise.Promise.STATE_FULLFILLED)
-    p.Then(self._AddToAccumulated)
-    self.assertEquals(self.accumulated, [0])
-
-  def testResolveToPromise(self):
-    p = promise.Promise.Resolve(0)
-    self.assertEquals(p.state, promise.Promise.STATE_FULLFILLED)
-    q = promise.Promise.Resolve(p)
-    self.assertEquals(p.state, promise.Promise.STATE_FULLFILLED)
-    q.Then(self._AddToAccumulated)
-    self.assertEquals(self.accumulated, [0])
-
-  def testReject(self):
-    p = promise.Promise.Reject(0)
-    self.assertEquals(p.state, promise.Promise.STATE_REJECTED)
-    p.Then(onRejected=self._AddToAccumulated)
-    self.assertEquals(self.accumulated, [0])
-
-  def testGeneratorFunctionResolve(self):
-    (p, resolve, _) = _GetPromiseAndFunctions()
-    self.assertEquals(p.state, promise.Promise.STATE_PENDING)
-    p.Then(self._AddToAccumulated)
-    resolve(0)
-    self.assertEquals(p.state, promise.Promise.STATE_FULLFILLED)
-    self.assertEquals(self.accumulated, [0])
-
-  def testGeneratorFunctionReject(self):
-    (p, _, reject) = _GetPromiseAndFunctions()
-    self.assertEquals(p.state, promise.Promise.STATE_PENDING)
-    p.Then(None, self._AddToAccumulated)
-    reject(0)
-    self.assertEquals(p.state, promise.Promise.STATE_REJECTED)
-    self.assertEquals(self.accumulated, [0])
-
-  def testGeneratorFunctionResolveToPromise(self):
-    (p1, resolve, _) = _GetPromiseAndFunctions()
-    p2 = promise.Promise(lambda x, y: x(p1))
-    self.assertEquals(p2.state, promise.Promise.STATE_PENDING)
-    p2.Then(self._AddToAccumulated)
-    resolve(promise.Promise.Resolve(0))
-    self.assertEquals(self.accumulated, [0])
-
-  def testComputation(self):
-    (p, resolve, _) = _GetPromiseAndFunctions()
-    p.Then(lambda x: x+1).Then(lambda x: x+2).Then(self._AddToAccumulated)
-    self.assertEquals(self.accumulated, [])
-    resolve(0)
-    self.assertEquals(self.accumulated, [3])
-
-  def testRecoverAfterException(self):
-    (p, resolve, _) = _GetPromiseAndFunctions()
-    q = p.Then(_ThrowException).Catch(self._AddToAccumulated)
-    self.assertEquals(self.accumulated, [])
-    resolve(0)
-    self.assertEquals(q.state, promise.Promise.STATE_FULLFILLED)
-    self.assertEquals(len(self.accumulated), 1)
-    self.assertIsInstance(self.accumulated[0], RuntimeError)
-    self.assertEquals(self.accumulated[0].message, 0)
-
-  def testMultipleRejectResolve(self):
-    (p, resolve, reject) = _GetPromiseAndFunctions()
-    p.Then(self._AddToAccumulated, self._AddToAccumulated)
-    resolve(0)
-    self.assertEquals(self.accumulated, [0])
-    resolve(0)
-    self.assertEquals(self.accumulated, [0])
-    reject(0)
-    self.assertEquals(self.accumulated, [0])
-
-    self.accumulated = []
-    (p, resolve, reject) = _GetPromiseAndFunctions()
-    p.Then(self._AddToAccumulated, self._AddToAccumulated)
-    reject(0)
-    self.assertEquals(self.accumulated, [0])
-    resolve(0)
-    self.assertEquals(self.accumulated, [0])
-    reject(0)
-    self.assertEquals(self.accumulated, [0])
-
-  def testAll(self):
-    promises_and_functions = [_GetPromiseAndFunctions() for x in xrange(10)]
-    promises = [x[0] for x in promises_and_functions]
-    all_promise = promise.Promise.All(*promises)
-    res = []
-    def AddToRes(values):
-      res.append(values)
-    all_promise.Then(AddToRes, AddToRes)
-    for i, (_, resolve, _) in enumerate(promises_and_functions):
-      self.assertEquals(len(res), 0)
-      resolve(i)
-    self.assertEquals(len(res), 1)
-    self.assertEquals(res[0], [i for i in xrange(10)])
-    self.assertEquals(all_promise.state, promise.Promise.STATE_FULLFILLED)
-
-  def testAllFailure(self):
-    promises_and_functions = [_GetPromiseAndFunctions() for x in xrange(10)]
-    promises = [x[0] for x in promises_and_functions]
-    all_promise = promise.Promise.All(*promises)
-    res = []
-    def AddToRes(values):
-      res.append(values)
-    all_promise.Then(AddToRes, AddToRes)
-    for i in xrange(10):
-      if i <= 5:
-        self.assertEquals(len(res), 0)
-      else:
-        self.assertEquals(len(res), 1)
-      if i != 5:
-        promises_and_functions[i][1](i)
-      else:
-        promises_and_functions[i][2]('error')
-    self.assertEquals(len(res), 1)
-    self.assertEquals(res[0], 'error')
-    self.assertEquals(all_promise.state, promise.Promise.STATE_REJECTED)
-
-  def testRace(self):
-    promises_and_functions = [_GetPromiseAndFunctions() for x in xrange(10)]
-    promises = [x[0] for x in promises_and_functions]
-    race_promise = promise.Promise.Race(*promises)
-    res = []
-    def AddToRes(values):
-      res.append(values)
-    race_promise.Then(AddToRes, AddToRes)
-    self.assertEquals(len(res), 0)
-    promises_and_functions[7][1]('success')
-    self.assertEquals(len(res), 1)
-    for i, (f) in enumerate(promises_and_functions):
-      f[1 + (i % 2)](i)
-    self.assertEquals(len(res), 1)
-    self.assertEquals(res[0], 'success')
-    self.assertEquals(race_promise.state, promise.Promise.STATE_FULLFILLED)
-
-  def testRaceFailure(self):
-    promises_and_functions = [_GetPromiseAndFunctions() for x in xrange(10)]
-    promises = [x[0] for x in promises_and_functions]
-    race_promise = promise.Promise.Race(*promises)
-    res = []
-    def AddToRes(values):
-      res.append(values)
-    race_promise.Then(AddToRes, AddToRes)
-    self.assertEquals(len(res), 0)
-    promises_and_functions[7][2]('error')
-    self.assertEquals(len(res), 1)
-    for i, (f) in enumerate(promises_and_functions):
-      f[1 + (i % 2)](i)
-    self.assertEquals(len(res), 1)
-    self.assertEquals(res[0], 'error')
-    self.assertEquals(race_promise.state, promise.Promise.STATE_REJECTED)
-
-  def testAsync(self):
-    @promise.async
-    def ComputeAdd(*values, **kwvalues):
-      return sum(values) + sum(kwvalues.values())
-    res = []
-    def AddToRes(values):
-      res.append(values)
-
-    # Simple test.
-    ComputeAdd(1, 2, foo=3).Then(AddToRes)
-    self.assertEquals(res, [6])
-
-    # Resolve promises
-    res = []
-    promises_and_functions = [_GetPromiseAndFunctions() for x in xrange(10)]
-    promises = [x[0] for x in promises_and_functions]
-    dict_promises = dict(zip(map(str, xrange(10)), promises))
-    add_promise = ComputeAdd(*promises, **dict_promises).Then(AddToRes)
-    self.assertEquals(len(res), 0)
-    self.assertEquals(add_promise.state, promise.Promise.STATE_PENDING)
-    for _, r, _ in promises_and_functions:
-      r(1)
-    self.assertEquals(res, [20])
-    self.assertEquals(add_promise.state, promise.Promise.STATE_FULLFILLED)
-
-    # Fail promise
-    res = []
-    promises_and_functions = [_GetPromiseAndFunctions() for x in xrange(10)]
-    promises = [x[0] for x in promises_and_functions]
-    add_promise = ComputeAdd(*promises).Then(AddToRes).Catch(AddToRes)
-    self.assertEquals(len(res), 0)
-    self.assertEquals(add_promise.state, promise.Promise.STATE_PENDING)
-    promises_and_functions[7][2]('error')
-    self.assertEquals(res, ['error'])
-    self.assertEquals(add_promise.state, promise.Promise.STATE_FULLFILLED)
-
-
-  def testAttributeGetter(self):
-    class MyObject(object):
-      def __init__(self):
-        self.value = 0
-      def GetValue(self, value=None):
-        return value
-    p = promise.Promise.Resolve(MyObject())
-    res = []
-    def AddToRes(values):
-      res.append(values)
-
-    p.value.Then(AddToRes)
-    p.GetValue(promise.Promise.Resolve(1)).Then(AddToRes)
-    self.assertEquals(res, [0, 1])
-
-    res = []
-    p.GetTwo().Catch(AddToRes)
-    self.assertEquals(len(res), 1)
-
-
-def _GetPromiseAndFunctions():
-  functions = {}
-  def GeneratorFunction(resolve, reject):
-    functions['resolve'] = resolve
-    functions['reject'] = reject
-  p = promise.Promise(GeneratorFunction)
-  return (p, functions['resolve'], functions['reject'])
-
-
-def _ThrowException(x):
-  raise RuntimeError(x)
diff --git a/mojo/python/tests/runloop_unittest.py b/mojo/python/tests/runloop_unittest.py
deleted file mode 100644
index c471ea9..0000000
--- a/mojo/python/tests/runloop_unittest.py
+++ /dev/null
@@ -1,41 +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
-
-
-def _Increment(array):
-  def _Closure():
-    array.append(0)
-  return _Closure
-
-
-class RunLoopTest(mojo_unittest.MojoTestCase):
-
-  def testRunLoop(self):
-    array = []
-    for _ in xrange(10):
-      self.loop.PostDelayedTask(_Increment(array))
-    self.loop.RunUntilIdle()
-    self.assertEquals(len(array), 10)
-
-  def testRunLoopWithException(self):
-    def Throw():
-      raise Exception("error")
-    array = []
-    self.loop.PostDelayedTask(Throw)
-    self.loop.PostDelayedTask(_Increment(array))
-    with self.assertRaisesRegexp(Exception, '^error$'):
-      self.loop.Run()
-    self.assertEquals(len(array), 0)
-    self.loop.RunUntilIdle()
-    self.assertEquals(len(array), 1)
-
-  def testCurrent(self):
-    self.assertEquals(system.RunLoop.Current(), self.loop)
-    self.loop = None
-    self.assertIsNone(system.RunLoop.Current())
diff --git a/mojo/python/tests/system_unittest.py b/mojo/python/tests/system_unittest.py
deleted file mode 100644
index 7a3febc..0000000
--- a/mojo/python/tests/system_unittest.py
+++ /dev/null
@@ -1,327 +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 random
-import time
-
-import mojo_unittest
-
-# pylint: disable=E0611
-import mojo_system as system
-
-DATA_SIZE = 1024
-
-
-def _GetRandomBuffer(size):
-  random.seed(size)
-  return bytearray(''.join(chr(random.randint(0, 255)) for i in xrange(size)))
-
-
-class CoreTest(mojo_unittest.MojoTestCase):
-
-  HANDLE_SIGNAL_READWRITABLE = (system.HANDLE_SIGNAL_READABLE |
-      system.HANDLE_SIGNAL_WRITABLE)
-  HANDLE_SIGNAL_ALL = (system.HANDLE_SIGNAL_READABLE |
-      system.HANDLE_SIGNAL_WRITABLE | system.HANDLE_SIGNAL_PEER_CLOSED)
-
-  def testResults(self):
-    self.assertEquals(system.RESULT_OK, 0)
-    self.assertGreater(system.RESULT_CANCELLED, 0)
-    self.assertGreater(system.RESULT_UNKNOWN, 0)
-    self.assertGreater(system.RESULT_INVALID_ARGUMENT, 0)
-    self.assertGreater(system.RESULT_DEADLINE_EXCEEDED, 0)
-    self.assertGreater(system.RESULT_NOT_FOUND, 0)
-    self.assertGreater(system.RESULT_ALREADY_EXISTS, 0)
-    self.assertGreater(system.RESULT_PERMISSION_DENIED, 0)
-    self.assertGreater(system.RESULT_RESOURCE_EXHAUSTED, 0)
-    self.assertGreater(system.RESULT_FAILED_PRECONDITION, 0)
-    self.assertGreater(system.RESULT_ABORTED, 0)
-    self.assertGreater(system.RESULT_OUT_OF_RANGE, 0)
-    self.assertGreater(system.RESULT_UNIMPLEMENTED, 0)
-    self.assertGreater(system.RESULT_INTERNAL, 0)
-    self.assertGreater(system.RESULT_UNAVAILABLE, 0)
-    self.assertGreater(system.RESULT_DATA_LOSS, 0)
-    self.assertGreater(system.RESULT_BUSY, 0)
-    self.assertGreater(system.RESULT_SHOULD_WAIT, 0)
-
-  def testConstants(self):
-    self.assertGreaterEqual(system.DEADLINE_INDEFINITE, 0)
-    self.assertGreaterEqual(system.HANDLE_SIGNAL_NONE, 0)
-    self.assertGreaterEqual(system.HANDLE_SIGNAL_READABLE, 0)
-    self.assertGreaterEqual(system.HANDLE_SIGNAL_WRITABLE, 0)
-    self.assertGreaterEqual(system.HANDLE_SIGNAL_PEER_CLOSED, 0)
-    self.assertGreaterEqual(system.WRITE_MESSAGE_FLAG_NONE, 0)
-    self.assertGreaterEqual(system.READ_MESSAGE_FLAG_NONE, 0)
-    self.assertGreaterEqual(system.READ_MESSAGE_FLAG_MAY_DISCARD, 0)
-    self.assertGreaterEqual(system.WRITE_DATA_FLAG_NONE, 0)
-    self.assertGreaterEqual(system.WRITE_DATA_FLAG_ALL_OR_NONE, 0)
-    self.assertGreaterEqual(system.READ_DATA_FLAG_NONE, 0)
-    self.assertGreaterEqual(system.READ_DATA_FLAG_ALL_OR_NONE, 0)
-    self.assertGreaterEqual(system.READ_DATA_FLAG_DISCARD, 0)
-    self.assertGreaterEqual(system.READ_DATA_FLAG_QUERY, 0)
-    self.assertGreaterEqual(system.READ_DATA_FLAG_PEEK, 0)
-    self.assertGreaterEqual(system.MAP_BUFFER_FLAG_NONE, 0)
-
-  def testGetTimeTicksNow(self):
-    v1 = system.GetTimeTicksNow()
-    time.sleep(1e-3)
-    v2 = system.GetTimeTicksNow()
-    self.assertGreater(v1, 0)
-    self.assertGreater(v2, v1 + 1e2)
-    self.assertLess(v2, v1 + 1e5)
-
-  def _testHandlesCreation(self, *args):
-    for handle in args:
-      self.assertTrue(handle.IsValid())
-      handle.Close()
-      self.assertFalse(handle.IsValid())
-
-  def _TestMessageHandleCreation(self, handles):
-    self._testHandlesCreation(handles.handle0, handles.handle1)
-
-  def testCreateMessagePipe(self):
-    self._TestMessageHandleCreation(system.MessagePipe())
-
-  def testCreateMessagePipeWithNoneOptions(self):
-    self._TestMessageHandleCreation(system.MessagePipe(None))
-
-  def testCreateMessagePipeWithOptions(self):
-    self._TestMessageHandleCreation(
-        system.MessagePipe(system.CreateMessagePipeOptions()))
-
-  def testWaitOverMessagePipe(self):
-    handles = system.MessagePipe()
-    handle = handles.handle0
-
-    (res, states) = handle.Wait(
-        system.HANDLE_SIGNAL_WRITABLE, system.DEADLINE_INDEFINITE)
-    self.assertEquals(system.RESULT_OK, res)
-    self.assertEquals(system.HANDLE_SIGNAL_WRITABLE, states[0])
-    self.assertEquals(CoreTest.HANDLE_SIGNAL_ALL, states[1])
-
-    (res, states) = handle.Wait(system.HANDLE_SIGNAL_READABLE, 0)
-    self.assertEquals(system.RESULT_DEADLINE_EXCEEDED, res)
-    self.assertEquals(system.HANDLE_SIGNAL_WRITABLE, states[0])
-    self.assertEquals(CoreTest.HANDLE_SIGNAL_ALL, states[1])
-
-    handles.handle1.WriteMessage()
-
-    (res, states) = handle.Wait(
-            system.HANDLE_SIGNAL_READABLE,
-            system.DEADLINE_INDEFINITE)
-    self.assertEquals(system.RESULT_OK, res)
-    self.assertEquals(CoreTest.HANDLE_SIGNAL_READWRITABLE, states[0])
-    self.assertEquals(CoreTest.HANDLE_SIGNAL_ALL, states[1])
-
-  def testWaitInvalidArgument(self):
-    (res, index, states) = system.WaitMany(
-            [(system.Handle(0), system.HANDLE_SIGNAL_WRITABLE),
-             (system.Handle(0), system.HANDLE_SIGNAL_WRITABLE)],
-            system.DEADLINE_INDEFINITE)
-    self.assertEquals(system.RESULT_INVALID_ARGUMENT, res)
-    self.assertEquals(0, index)
-    self.assertEquals(states, None)
-
-  def testWaitOverManyMessagePipe(self):
-    handles = system.MessagePipe()
-    handle0 = handles.handle0
-    handle1 = handles.handle1
-
-    (res, index, states) = system.WaitMany(
-            [(handle0, system.HANDLE_SIGNAL_WRITABLE),
-             (handle1, system.HANDLE_SIGNAL_WRITABLE)],
-            system.DEADLINE_INDEFINITE)
-    self.assertEquals(system.RESULT_OK, res)
-    self.assertEquals(0, index)
-    self.assertEquals(system.HANDLE_SIGNAL_WRITABLE, states[0][0])
-    self.assertEquals(CoreTest.HANDLE_SIGNAL_ALL, states[0][1])
-    self.assertEquals(system.HANDLE_SIGNAL_WRITABLE, states[1][0])
-    self.assertEquals(CoreTest.HANDLE_SIGNAL_ALL, states[1][1])
-
-    (res, index, states) = system.WaitMany(
-            [(handle0, system.HANDLE_SIGNAL_READABLE),
-             (handle1, system.HANDLE_SIGNAL_READABLE)], 0)
-    self.assertEquals(system.RESULT_DEADLINE_EXCEEDED, res)
-    self.assertEquals(None, index)
-    self.assertEquals(system.HANDLE_SIGNAL_WRITABLE, states[0][0])
-    self.assertEquals(CoreTest.HANDLE_SIGNAL_ALL, states[0][1])
-    self.assertEquals(system.HANDLE_SIGNAL_WRITABLE, states[1][0])
-    self.assertEquals(CoreTest.HANDLE_SIGNAL_ALL, states[1][1])
-
-    handle0.WriteMessage()
-
-    (res, index, states) = system.WaitMany(
-            [(handle0, system.HANDLE_SIGNAL_READABLE),
-             (handle1, system.HANDLE_SIGNAL_READABLE)],
-            system.DEADLINE_INDEFINITE)
-    self.assertEquals(system.RESULT_OK, res)
-    self.assertEquals(1, index)
-    self.assertEquals(system.HANDLE_SIGNAL_WRITABLE, states[0][0])
-    self.assertEquals(CoreTest.HANDLE_SIGNAL_ALL, states[0][1])
-    self.assertEquals(CoreTest.HANDLE_SIGNAL_READWRITABLE, states[1][0])
-    self.assertEquals(CoreTest.HANDLE_SIGNAL_ALL, states[1][1])
-
-  def testSendBytesOverMessagePipe(self):
-    handles = system.MessagePipe()
-    data = _GetRandomBuffer(DATA_SIZE)
-    handles.handle0.WriteMessage(data)
-    (res, buffers, next_message) = handles.handle1.ReadMessage()
-    self.assertEquals(system.RESULT_RESOURCE_EXHAUSTED, res)
-    self.assertEquals(None, buffers)
-    self.assertEquals((DATA_SIZE, 0), next_message)
-    result = bytearray(DATA_SIZE)
-    (res, buffers, next_message) = handles.handle1.ReadMessage(result)
-    self.assertEquals(system.RESULT_OK, res)
-    self.assertEquals(None, next_message)
-    self.assertEquals((data, []), buffers)
-
-  def testSendEmptyDataOverMessagePipe(self):
-    handles = system.MessagePipe()
-    handles.handle0.WriteMessage(None)
-    (res, buffers, next_message) = handles.handle1.ReadMessage()
-
-    self.assertEquals(system.RESULT_OK, res)
-    self.assertEquals(None, next_message)
-    self.assertEquals((None, []), buffers)
-
-  def testSendHandleOverMessagePipe(self):
-    handles = system.MessagePipe()
-    handles_to_send = system.MessagePipe()
-    handles.handle0.WriteMessage(handles=[handles_to_send.handle0,
-                                           handles_to_send.handle1])
-    (res, buffers, next_message) = handles.handle1.ReadMessage(
-        max_number_of_handles=2)
-
-    self.assertFalse(handles_to_send.handle0.IsValid())
-    self.assertFalse(handles_to_send.handle1.IsValid())
-    self.assertEquals(system.RESULT_OK, res)
-    self.assertEquals(None, next_message)
-    self.assertEquals(None, buffers[0])
-    self.assertEquals(2, len(buffers[1]))
-
-    handles = buffers[1]
-    for handle in handles:
-      self.assertTrue(handle.IsValid())
-      (res, buffers, next_message) = handle.ReadMessage()
-      self.assertEquals(system.RESULT_SHOULD_WAIT, res)
-
-    for handle in handles:
-      handle.WriteMessage()
-
-    for handle in handles:
-      (res, buffers, next_message) = handle.ReadMessage()
-      self.assertEquals(system.RESULT_OK, res)
-
-  def _TestDataHandleCreation(self, handles):
-    self._testHandlesCreation(
-        handles.producer_handle, handles.consumer_handle)
-
-  def testCreateDataPipe(self):
-    self._TestDataHandleCreation(system.DataPipe())
-
-  def testCreateDataPipeWithNoneOptions(self):
-    self._TestDataHandleCreation(system.DataPipe(None))
-
-  def testCreateDataPipeWithDefaultOptions(self):
-    self._TestDataHandleCreation(
-        system.DataPipe(system.CreateDataPipeOptions()))
-
-  def testCreateDataPipeWithElementSize(self):
-    options = system.CreateDataPipeOptions()
-    options.element_num_bytes = 5
-    self._TestDataHandleCreation(system.DataPipe(options))
-
-  def testCreateDataPipeWithCapacity(self):
-    options = system.CreateDataPipeOptions()
-    options.element_capacity_num_bytes = DATA_SIZE
-    self._TestDataHandleCreation(system.DataPipe(options))
-
-  def testCreateDataPipeWithIncorrectParameters(self):
-    options = system.CreateDataPipeOptions()
-    options.element_num_bytes = 5
-    options.capacity_num_bytes = DATA_SIZE
-    with self.assertRaises(system.MojoException) as cm:
-      self._TestDataHandleCreation(system.DataPipe(options))
-    self.assertEquals(system.RESULT_INVALID_ARGUMENT, cm.exception.mojo_result)
-
-  def testSendEmptyDataOverDataPipe(self):
-    pipes = system.DataPipe()
-    self.assertEquals((system.RESULT_OK, 0), pipes.producer_handle.WriteData())
-    self.assertEquals(
-        (system.RESULT_OK, None), pipes.consumer_handle.ReadData())
-
-  def testSendDataOverDataPipe(self):
-    pipes = system.DataPipe()
-    data = _GetRandomBuffer(DATA_SIZE)
-    self.assertEquals((system.RESULT_OK, DATA_SIZE),
-                      pipes.producer_handle.WriteData(data))
-    self.assertEquals((system.RESULT_OK, data),
-                      pipes.consumer_handle.ReadData(
-                          bytearray(DATA_SIZE), system.READ_DATA_FLAG_PEEK))
-    self.assertEquals((system.RESULT_OK, data),
-                      pipes.consumer_handle.ReadData(bytearray(DATA_SIZE)))
-
-  def testTwoPhaseWriteOnDataPipe(self):
-    pipes = system.DataPipe()
-    (res, buf) = pipes.producer_handle.BeginWriteData(DATA_SIZE)
-    self.assertEquals(system.RESULT_OK, res)
-    self.assertGreaterEqual(len(buf.buffer), DATA_SIZE)
-    data = _GetRandomBuffer(DATA_SIZE)
-    buf.buffer[0:DATA_SIZE] = data
-    self.assertEquals(system.RESULT_OK, buf.End(DATA_SIZE))
-    self.assertEquals((system.RESULT_OK, data),
-                      pipes.consumer_handle.ReadData(bytearray(DATA_SIZE)))
-
-  def testTwoPhaseReadOnDataPipe(self):
-    pipes = system.DataPipe()
-    data = _GetRandomBuffer(DATA_SIZE)
-    self.assertEquals((system.RESULT_OK, DATA_SIZE),
-                      pipes.producer_handle.WriteData(data))
-    (res, buf) = pipes.consumer_handle.BeginReadData()
-    self.assertEquals(system.RESULT_OK, res)
-    self.assertEquals(DATA_SIZE, len(buf.buffer))
-    self.assertEquals(data, buf.buffer)
-    self.assertEquals(system.RESULT_OK, buf.End(DATA_SIZE))
-
-  def testCreateSharedBuffer(self):
-    self._testHandlesCreation(system.CreateSharedBuffer(DATA_SIZE))
-
-  def testCreateSharedBufferWithNoneOptions(self):
-    self._testHandlesCreation(system.CreateSharedBuffer(DATA_SIZE, None))
-
-  def testCreateSharedBufferWithDefaultOptions(self):
-    self._testHandlesCreation(
-        system.CreateSharedBuffer(
-            DATA_SIZE,
-            system.CreateSharedBufferOptions()))
-
-  def testDuplicateSharedBuffer(self):
-    handle = system.CreateSharedBuffer(DATA_SIZE)
-    self._testHandlesCreation(handle.Duplicate())
-
-  def testDuplicateSharedBufferWithNoneOptions(self):
-    handle = system.CreateSharedBuffer(DATA_SIZE)
-    self._testHandlesCreation(handle.Duplicate(None))
-
-  def testDuplicateSharedBufferWithDefaultOptions(self):
-    handle = system.CreateSharedBuffer(DATA_SIZE)
-    self._testHandlesCreation(
-        handle.Duplicate(system.DuplicateSharedBufferOptions()))
-
-  def testSendBytesOverSharedBuffer(self):
-    handle = system.CreateSharedBuffer(DATA_SIZE)
-    duplicated = handle.Duplicate()
-    data = _GetRandomBuffer(DATA_SIZE)
-    (res1, buf1) = handle.Map(0, DATA_SIZE)
-    (res2, buf2) = duplicated.Map(0, DATA_SIZE)
-    self.assertEquals(system.RESULT_OK, res1)
-    self.assertEquals(system.RESULT_OK, res2)
-    self.assertEquals(DATA_SIZE, len(buf1.buffer))
-    self.assertEquals(DATA_SIZE, len(buf2.buffer))
-    self.assertEquals(buf1.buffer, buf2.buffer)
-
-    buf1.buffer[:] = data
-    self.assertEquals(data, buf1.buffer)
-    self.assertEquals(data, buf2.buffer)
-    self.assertEquals(buf1.buffer, buf2.buffer)
diff --git a/mojo/python/tests/validation_unittest.py b/mojo/python/tests/validation_unittest.py
deleted file mode 100644
index 7b1f07e..0000000
--- a/mojo/python/tests/validation_unittest.py
+++ /dev/null
@@ -1,90 +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 logging
-import os
-import os.path
-
-import mojo_unittest
-import validation_test_interfaces_mojom
-
-# pylint: disable=E0611
-import mojo_system as system
-from mojo_bindings import messaging
-from mojo_tests import validation_util
-from mopy.paths import Paths
-
-logging.basicConfig(level=logging.ERROR)
-paths = Paths()
-
-
-class RoutingMessageReceiver(messaging.MessageReceiver):
-  def __init__(self, request, response):
-    self.request = request
-    self.response = response
-
-  def Accept(self, message):
-    if message.header.is_response:
-      return self.response.Accept(message)
-    else:
-      return self.request.Accept(message)
-
-
-class SinkMessageReceiver(messaging.MessageReceiverWithResponder):
-
-  def Accept(self, message):
-    return False
-
-  def AcceptWithResponder(self, message, responder):
-    return False
-
-  def Close(self):
-    pass
-
-
-class HandleMock(object):
-  def IsValid(self):
-    return True
-
-  def Close(self):
-    pass
-
-
-class ValidationTest(mojo_unittest.MojoTestCase):
-
-  @staticmethod
-  def ParseData(data_dir, filename):
-    data = validation_util.ParseData(
-        open(os.path.join(data_dir, filename), 'r').read())
-    expect_file = filename[:-4] + 'expected'
-    expected_error = open(
-        os.path.join(data_dir, expect_file), 'r').read().strip();
-    success = expected_error == 'PASS'
-    return (filename, data, success)
-
-  @staticmethod
-  def GetData(prefix):
-    data_dir = os.path.join(paths.src_root, 'mojo', 'public', 'interfaces',
-                            'bindings', 'tests', 'data', 'validation')
-
-    # TODO(yzshen): Skip some interface versioning tests.
-    skipped_tests = ["conformance_mthd13_good_2.data"]
-
-    return [ValidationTest.ParseData(data_dir, x) for x in os.listdir(data_dir)
-            if x.startswith(prefix) and x.endswith('.data') and
-               x not in skipped_tests]
-
-  def runTest(self, prefix, message_receiver):
-    for (filename, data, expected) in ValidationTest.GetData(prefix):
-      self.assertEquals(len(data.error_message), 0)
-      handles = [HandleMock() for _ in xrange(data.num_handles)]
-      message = messaging.Message(data.data, handles)
-      self.assertEquals(message_receiver.Accept(message), expected,
-                        'Unexpected result for test: %s' % filename)
-
-  def testConformance(self):
-    manager = validation_test_interfaces_mojom.ConformanceTestInterface.manager
-    proxy = manager._InternalProxy(SinkMessageReceiver(), None, 0)
-    stub = manager._Stub(proxy)
-    self.runTest('conformance_', stub)
diff --git a/mojo/services/BUILD.gn b/mojo/services/BUILD.gn
index b990e92..3b67165 100644
--- a/mojo/services/BUILD.gn
+++ b/mojo/services/BUILD.gn
@@ -3,33 +3,8 @@
 # found in the LICENSE file.
 
 import("//build/config/ui.gni")
+import("//mojo/services/mojo_services.gni")
 
 group("services") {
-  deps = [
-    "//mojo/services/accessibility/public/interfaces",
-    "//mojo/services/asset_bundle/public/interfaces",
-    "//mojo/services/authenticating_url_loader_interceptor/public/interfaces",
-    "//mojo/services/authentication/public/interfaces",
-    "//mojo/services/camera_roll/public/interfaces",
-    "//mojo/services/clipboard/public/interfaces",
-    "//mojo/services/content_handler/public/interfaces",
-    "//mojo/services/device_info/public/interfaces",
-    "//mojo/services/files/public/interfaces",
-    "//mojo/services/geometry/public/interfaces",
-    "//mojo/services/http_server/public/interfaces",
-    "//mojo/services/input_events/public/interfaces",
-    "//mojo/services/location/public/interfaces",
-    "//mojo/services/native_viewport/public/interfaces",
-    "//mojo/services/navigation/public/interfaces",
-    "//mojo/services/network/public/interfaces",
-    "//mojo/services/notifications/public/interfaces",
-    "//mojo/services/nfc/public/interfaces",
-    "//mojo/services/sensors/public/interfaces",
-    "//mojo/services/service_registry/public/interfaces",
-    "//mojo/services/speech_recognizer/public/interfaces",
-    "//mojo/services/surfaces/public/interfaces",
-    "//mojo/services/terminal/public/interfaces",
-    "//mojo/services/view_manager/public/interfaces",
-    "//mojo/services/window_manager/public/interfaces",
-  ]
+  deps = mojo_services
 }
diff --git a/mojo/services/mojo_services.gni b/mojo/services/mojo_services.gni
new file mode 100644
index 0000000..74c0981
--- /dev/null
+++ b/mojo/services/mojo_services.gni
@@ -0,0 +1,33 @@
+# 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.
+
+mojo_services = [
+  "//mojo/services/accessibility/public/interfaces",
+  "//mojo/services/asset_bundle/public/interfaces",
+  "//mojo/services/authenticating_url_loader_interceptor/public/interfaces",
+  "//mojo/services/authentication/public/interfaces",
+  "//mojo/services/camera_roll/public/interfaces",
+  "//mojo/services/clipboard/public/interfaces",
+  "//mojo/services/content_handler/public/interfaces",
+  "//mojo/services/device_info/public/interfaces",
+  "//mojo/services/files/public/interfaces",
+  "//mojo/services/geometry/public/interfaces",
+  "//mojo/services/http_server/public/interfaces",
+  "//mojo/services/input_events/public/interfaces",
+  "//mojo/services/location/public/interfaces",
+  "//mojo/services/native_viewport/public/interfaces",
+  "//mojo/services/navigation/public/interfaces",
+  "//mojo/services/network/public/interfaces",
+  "//mojo/services/notifications/public/interfaces",
+  "//mojo/services/nfc/public/interfaces",
+  "//mojo/services/sensors/public/interfaces",
+  "//mojo/services/service_registry/public/interfaces",
+  "//mojo/services/speech_recognizer/public/interfaces",
+  "//mojo/services/sharing/public/interfaces",
+  "//mojo/services/surfaces/public/interfaces",
+  "//mojo/services/terminal/public/interfaces",
+  "//mojo/services/vanadium/security/public/interfaces",
+  "//mojo/services/view_manager/public/interfaces",
+  "//mojo/services/window_manager/public/interfaces",
+]
diff --git a/mojo/services/sharing/public/interfaces/BUILD.gn b/mojo/services/sharing/public/interfaces/BUILD.gn
new file mode 100644
index 0000000..b5e0c3c
--- /dev/null
+++ b/mojo/services/sharing/public/interfaces/BUILD.gn
@@ -0,0 +1,16 @@
+# 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("//build/module_args/mojo.gni")
+import("$mojo_sdk_root/mojo/public/tools/bindings/mojom.gni")
+
+mojom("interfaces") {
+  sources = [
+    "sharing.mojom",
+  ]
+
+  import_dirs = [ get_path_info("../../../", "abspath") ]
+
+  mojo_sdk_deps = [ "mojo/public/interfaces/application" ]
+}
diff --git a/mojo/services/sharing/public/interfaces/sharing.mojom b/mojo/services/sharing/public/interfaces/sharing.mojom
new file mode 100644
index 0000000..494b552
--- /dev/null
+++ b/mojo/services/sharing/public/interfaces/sharing.mojom
@@ -0,0 +1,10 @@
+// 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.
+
+[DartPackage="mojo_services"]
+module mojo;
+
+interface SharingService {
+  ShareText(string text);
+};
diff --git a/mojo/services/tracing/public/interfaces/tracing.mojom b/mojo/services/tracing/public/interfaces/tracing.mojom
index 6b39e9c..a261e90 100644
--- a/mojo/services/tracing/public/interfaces/tracing.mojom
+++ b/mojo/services/tracing/public/interfaces/tracing.mojom
@@ -5,24 +5,24 @@
 [DartPackage="mojo_services"]
 module tracing;
 
-// To participate in the tracing ecosystem, implement the TraceController
-// interface and connect to the tracing app. Then, when the controller's Start()
+// To participate in the tracing ecosystem, implement the TraceProvider
+// interface and connect to the tracing app. Then, when the provider's Start()
 // function is called collect tracing data and pass it back via the provided
-// TraceDataCollector interface up until Stop() is called.
+// TraceRecorder interface up until Stop() is called.
 
-interface TraceController {
+interface TraceProvider {
   // Categories can either be the empty string to mean the default set of
   // categories or a comma-delimited list of categories to trace.
-  StartTracing(string categories, TraceDataCollector collector);
+  StartTracing(string categories, TraceRecorder recorder);
   StopTracing();
 };
 
-interface TraceDataCollector {
-  DataCollected(string json);
+interface TraceRecorder {
+  Record(string json);
 };
 
-interface TraceCoordinator {
-  // Request tracing data from all connected TraceControllers to stream to
+interface TraceCollector {
+  // Request tracing data from all connected providers to stream to
   // |stream|.
   Start(handle<data_pipe_producer> stream, string categories);
 
diff --git a/mojo/services/vanadium/security/public/interfaces/BUILD.gn b/mojo/services/vanadium/security/public/interfaces/BUILD.gn
new file mode 100644
index 0000000..48eea5b
--- /dev/null
+++ b/mojo/services/vanadium/security/public/interfaces/BUILD.gn
@@ -0,0 +1,12 @@
+# 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("//build/module_args/mojo.gni")
+import("$mojo_sdk_root/mojo/public/tools/bindings/mojom.gni")
+
+mojom("interfaces") {
+  sources = [
+    "principal.mojom",
+  ]
+}
diff --git a/mojo/services/vanadium/security/public/interfaces/principal.mojom b/mojo/services/vanadium/security/public/interfaces/principal.mojom
new file mode 100644
index 0000000..9c58834
--- /dev/null
+++ b/mojo/services/vanadium/security/public/interfaces/principal.mojom
@@ -0,0 +1,49 @@
+// 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.
+
+module vanadium;
+
+// Represents the name of an application. |url| is the url of the
+// application. |qualifier| is a string that allows to tie a specific
+// instance of an application to another.
+struct AppInstanceName {
+  string url;
+  string? qualifier;
+};
+
+// Certificate represents a human-readable name and public-key (DER encoded) pair.
+// The private-key for a certificate is only available for signing operations
+// within the principal service application.
+struct Certificate {
+   string extension;
+   array<uint8>? publickey;
+};
+
+// Blessing is a credential binding a user identity to a public key. The corresponding
+// private key is only available for signing within the PrincipalService application.
+struct Blessing {
+   array<Certificate> chain;
+};
+
+// ChainSeparator is the separator used to join name extensions in a certificate chain.
+const string ChainSeparator = "/";
+
+// A service that binds user identities to an application instance running in Mojo
+interface PrincipalService {
+  // Login is called by an application instance (requestor_url/qualifier) that
+  // wants to get a user blessing. The service may obtain the user blessing
+  // through a third-party authentication flow (eg:oauth2). The user blessing
+  // is bound to a public/private key-pair that this service generates and
+  // persists for this application instance. Returns null if login fails.
+  Login() => (Blessing? user_blessing);
+
+  // Removes the user blessing for the application instance that invokes the
+  // Logout method.
+  Logout();
+
+  // GetUserBlessing returns the user blessing for a given application instance.
+  // It returns an error if the application instance has not invoked Login().
+  GetUserBlessing(AppInstanceName app) => (Blessing? user_blessing);
+};
+
diff --git a/mojo/tests/BUILD.gn b/mojo/tests/BUILD.gn
deleted file mode 100644
index 03411fe..0000000
--- a/mojo/tests/BUILD.gn
+++ /dev/null
@@ -1,32 +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("//testing/test.gni")
-import("//mojo/public/mojo.gni")
-
-test("mojo_task_tracker_perftests") {
-  deps = [
-    "//base/test:test_support",
-    "//mojo/common",
-    "//mojo/edk/system",
-    "//mojo/edk/test:test_support",
-    "//mojo/edk/test:test_support_impl",
-    "//mojo/environment:chromium",
-    "//mojo/public/c/test_support",
-    "//mojo/public/cpp/bindings",
-    "//mojo/public/cpp/bindings:callback",
-    "//mojo/public/cpp/environment",
-    "//mojo/public/cpp/system",
-    "//mojo/public/cpp/test_support:test_utils",
-    "//mojo/public/cpp/utility",
-    "//mojo/public/interfaces/bindings/tests:test_interfaces",
-    "//base",
-    "//testing/gtest",
-  ]
-
-  sources = [
-    "../edk/test/run_all_perftests.cc",
-    "task_tracker_perftest.cc",
-  ]
-}
diff --git a/mojo/tests/task_tracker_perftest.cc b/mojo/tests/task_tracker_perftest.cc
deleted file mode 100644
index a2ffdb3..0000000
--- a/mojo/tests/task_tracker_perftest.cc
+++ /dev/null
@@ -1,135 +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.
-
-#include <numeric>
-
-#include "base/logging.h"
-#include "base/message_loop/message_loop.h"
-#include "base/timer/elapsed_timer.h"
-#include "base/tracked_objects.h"
-#include "mojo/common/message_pump_mojo.h"
-#include "mojo/public/cpp/bindings/binding.h"
-#include "mojo/public/cpp/environment/environment.h"
-#include "mojo/public/cpp/environment/task_tracker.h"
-#include "mojo/public/cpp/test_support/test_support.h"
-#include "mojo/public/cpp/test_support/test_utils.h"
-#include "mojo/public/interfaces/bindings/tests/sample_interfaces.mojom.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace mojo {
-namespace test {
-namespace {
-
-class ProviderImpl : public sample::Provider {
- public:
-  explicit ProviderImpl(InterfaceRequest<sample::Provider> request)
-      : binding_(this, request.Pass()) {}
-
-  void EchoString(const String& a,
-                  const Callback<void(String)>& callback) override {
-    callback.Run(a);
-  }
-
-  void EchoStrings(const String& a,
-                   const String& b,
-                   const Callback<void(String, String)>& callback) override {
-    CHECK(false);
-  }
-
-  void EchoMessagePipeHandle(
-      ScopedMessagePipeHandle a,
-      const Callback<void(ScopedMessagePipeHandle)>& callback) override {
-    CHECK(false);
-  }
-
-  void EchoEnum(sample::Enum a,
-                const Callback<void(sample::Enum)>& callback) override {
-    CHECK(false);
-  }
-
-  void EchoInt(int32_t a, const EchoIntCallback& callback) override {
-    CHECK(false);
-  }
-
-  Binding<sample::Provider> binding_;
-};
-
-class RequestResponsePerfTest : public testing::Test {
- public:
-  RequestResponsePerfTest()
-      : loop_(make_scoped_ptr(new common::MessagePumpMojo())) {}
-
-  ~RequestResponsePerfTest() override { loop_.RunUntilIdle(); }
-
-  void Iterate(size_t count);
-  void Measure(const char* case_nam);
-
-  void SetUp() override {
-    tracked_objects::ThreadData::InitializeAndSetTrackingStatus(
-        tracked_objects::ThreadData::PROFILING_ACTIVE);
-  }
-
-  void TearDown() override {
-    tracked_objects::ThreadData::InitializeAndSetTrackingStatus(
-        tracked_objects::ThreadData::DEACTIVATED);
-  }
-
-  void PumpMessages() { loop_.RunUntilIdle(); }
-
- private:
-  base::MessageLoop loop_;
-};
-
-const size_t kCallsPerIteration = 1000;
-const size_t kIterations = 1000;
-
-void RequestResponsePerfTest::Iterate(size_t count) {
-  sample::ProviderPtr provider;
-  ProviderImpl provider_impl(GetProxy(&provider));
-
-  size_t remaining = count;
-  Callback<void(const String&)> reply =
-      [&provider, &reply, &remaining](const String& a) {
-        if (!remaining)
-          return;
-        remaining--;
-        provider->EchoString(a, reply);
-      };
-
-  provider->EchoString(String::From("hello"), reply);
-  PumpMessages();
-}
-
-void RequestResponsePerfTest::Measure(const char* case_name) {
-  std::vector<double> laps;
-  for (size_t i = 0; i < kIterations; ++i) {
-    base::ElapsedTimer timer;
-    Iterate(kCallsPerIteration);
-    laps.push_back(timer.Elapsed().InMillisecondsF());
-  }
-
-  double avg = std::accumulate(laps.begin(), laps.end(), 0.0) / laps.size();
-  double var = std::accumulate(laps.begin(), laps.end(), 0.0, [avg](double acc,
-                                                                    double x) {
-    return acc + (x - avg) * (x - avg);
-  }) / laps.size();
-
-  double sd = sqrt(var);
-  mojo::test::LogPerfResult(case_name, "Avg", avg, "ms/1000call");
-  mojo::test::LogPerfResult(case_name, "SD", sd, "ms/1000call");
-}
-
-TEST_F(RequestResponsePerfTest, TrackingEnabled) {
-  Environment::GetDefaultTaskTracker()->SetEnabled(true);
-  Measure(__FUNCTION__);
-  Environment::GetDefaultTaskTracker()->SetEnabled(false);
-}
-
-TEST_F(RequestResponsePerfTest, TrackingDisabled) {
-  Measure(__FUNCTION__);
-}
-
-}  // namespace
-}  // namespace test
-}  // namespace mojo
diff --git a/mojo/tools/BUILD.gn b/mojo/tools/BUILD.gn
deleted file mode 100644
index dbeaf7e..0000000
--- a/mojo/tools/BUILD.gn
+++ /dev/null
@@ -1,28 +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.
-
-executable("message_generator") {
-  testonly = true
-  output_name = "mojo_message_generator"
-
-  sources = [
-    "message_generator.cc",
-  ]
-
-  deps = [
-    "//base",
-    "//build/config/sanitizers:deps",
-    "//mojo/common",
-    "//mojo/edk/system",
-    "//mojo/environment:chromium",
-    "//mojo/public/cpp/bindings",
-    "//testing/gtest",
-  ]
-}
-
-executable("remote_file_reader") {
-  sources = [
-    "remote_file_reader.cc",
-  ]
-}
diff --git a/mojo/tools/analyze_bloat.py b/mojo/tools/analyze_bloat.py
deleted file mode 100755
index 90ced08..0000000
--- a/mojo/tools/analyze_bloat.py
+++ /dev/null
@@ -1,93 +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.
-
-import argparse
-import logging
-import os
-import re
-import subprocess
-import sys
-
-from mopy.paths import Paths
-
-ANDROID_TOOLS_DIR = ('third_party/android_tools/ndk/toolchains/' +
-    'arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin')
-
-def binaries(path):
-    for item in os.listdir(path):
-        match = re.match(r'^(\w+)\.mojo$', item)
-        if match:
-            name = match.group(1)
-            if name.endswith('apptests'):
-                continue
-            binary = os.path.join(path, 'lib%s_library.so' % name)
-            if os.path.exists(binary):
-                yield name, binary
-
-def check_deps():
-    success = True
-    if not os.path.exists('bloat'):
-        print ("Can't find bloat.py. Did you " +
-            "'git clone https://github.com/martine/bloat.git' ?")
-        success = False
-    if not os.path.exists('webtreemap'):
-        print ("Can't find webtreemap. Did you " +
-            "'git clone https://github.com/martine/webtreemap.git' ?")
-        success = False
-    if not success:
-        sys.exit(1)
-
-def main():
-    logging.basicConfig(level=logging.WARN)
-    parser = argparse.ArgumentParser(description='Dump bloat treeview.')
-    args = parser.parse_args()
-    check_deps()
-
-    # Always use android release?
-    rel_build_dir = os.path.join('out', 'android_Release')
-    src_root = Paths().src_root
-    build_dir = os.path.join(src_root, rel_build_dir)
-
-    tools_dir = os.path.join(src_root, ANDROID_TOOLS_DIR)
-    tools_prefix = 'arm-linux-androideabi-'
-
-    nm = os.path.join(tools_dir, tools_prefix + 'nm')
-    objdump = os.path.join(tools_dir, tools_prefix + 'objdump')
-
-    for name, binary in binaries(build_dir):
-        print 'Analyzing', name
-
-        nm_path = name + '.nm'
-        objdump_path = name + '.objdump'
-        json_path = name + '.json'
-        html_path = name + '.html'
-
-        with open(nm_path, 'w') as nm_file:
-            args = [nm, '-C', '-S', '-l', binary]
-            subprocess.check_call(args, stdout=nm_file)
-
-        with open(objdump_path, 'w') as objdump_file:
-            subprocess.check_call([objdump, '-h', binary], stdout=objdump_file)
-
-        with open(json_path, 'w') as json_file:
-            subprocess.check_call([
-                sys.executable,
-                'bloat/bloat.py',
-                '--nm-output=' + nm_path,
-                '--objdump-output=' + objdump_path,
-                '--strip-prefix=' + src_root + '/',
-                'syms'
-            ], stdout=json_file)
-
-        source = None
-        with open('bloat/index.html', 'r') as source_file:
-            source = source_file.read().replace('bloat.json', json_path)
-
-        with open(html_path, 'w') as html_file:
-            html_file.write(source)
-
-
-if __name__ == '__main__':
-    main()
diff --git a/mojo/tools/android_shortcuts/BUILD.gn b/mojo/tools/android_shortcuts/BUILD.gn
deleted file mode 100644
index e560661..0000000
--- a/mojo/tools/android_shortcuts/BUILD.gn
+++ /dev/null
@@ -1,41 +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.
-
-assert(is_android)
-
-import("//build/config/android/config.gni")
-import("//build/config/android/rules.gni")
-
-group("android_shortcuts") {
-  deps = [
-    ":java",
-    ":shortcuts_apk",
-  ]
-}
-
-android_library("java") {
-  java_files = [
-    "apk/src/org/chromium/mojo/shortcuts/AlarmReceiver.java",
-    "apk/src/org/chromium/mojo/shortcuts/ApplicationUpdater.java",
-    "apk/src/org/chromium/mojo/shortcuts/ShortcutsActivity.java",
-  ]
-}
-
-android_resources("resources") {
-  resource_dirs = [ "apk/res" ]
-  custom_package = "org.chromium.mojo.shortcuts"
-}
-
-android_apk("shortcuts_apk") {
-  apk_name = "MojoShortcuts"
-
-  android_manifest = "apk/AndroidManifest.xml"
-
-  asset_location = "apk/res"
-
-  deps = [
-    ":java",
-    ":resources",
-  ]
-}
diff --git a/mojo/tools/android_shortcuts/apk/AndroidManifest.xml b/mojo/tools/android_shortcuts/apk/AndroidManifest.xml
deleted file mode 100644
index 12a93fe..0000000
--- a/mojo/tools/android_shortcuts/apk/AndroidManifest.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-
-<!-- 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.
- -->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:tools="http://schemas.android.com/tools"
-    package="org.chromium.mojo.shortcuts">
-
-    <uses-sdk android:minSdkVersion="14" android:targetSdkVersion="21" />
-    <uses-permission android:name="android.permission.DELETE_PACKAGES"
-        tools:ignore="ProtectedPermissions"/>
-    <uses-permission android:name="android.permission.INSTALL_PACKAGES"
-        tools:ignore="ProtectedPermissions"/>
-    <uses-permission android:name="android.permission.INTERNET"/>
-    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
-    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
-    <uses-permission android:name="com.android.launcher.permission.INSTALL_SHORTCUT"/>
-    <uses-permission android:name="com.android.launcher.permission.UNINSTALL_SHORTCUT"/>
-
-    <application android:label="@string/application_name">
-        <activity android:name="ShortcutsActivity">
-            <intent-filter>
-                <action android:name="android.intent.action.MAIN"/>
-                <category android:name="android.intent.category.LAUNCHER"/>
-            </intent-filter>
-        </activity>
-
-        <receiver android:name=".AlarmReceiver"
-                  android:enabled="true">
-            <intent-filter>
-                <action android:name="android.intent.action.BOOT_COMPLETED"></action>
-            </intent-filter>
-        </receiver>
-    </application>
-
-</manifest>
diff --git a/mojo/tools/android_shortcuts/apk/res/values/strings.xml b/mojo/tools/android_shortcuts/apk/res/values/strings.xml
deleted file mode 100644
index fe96745..0000000
--- a/mojo/tools/android_shortcuts/apk/res/values/strings.xml
+++ /dev/null
@@ -1,11 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-
-<!-- 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.
- -->
-
-<resources>
-<string name="application_name">Mojo Shortcuts</string>
-</resources>
diff --git a/mojo/tools/android_shortcuts/apk/src/org/chromium/mojo/shortcuts/AlarmReceiver.java b/mojo/tools/android_shortcuts/apk/src/org/chromium/mojo/shortcuts/AlarmReceiver.java
deleted file mode 100644
index 98f540a..0000000
--- a/mojo/tools/android_shortcuts/apk/src/org/chromium/mojo/shortcuts/AlarmReceiver.java
+++ /dev/null
@@ -1,54 +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 org.chromium.mojo.shortcuts;
-
-import android.app.AlarmManager;
-import android.app.PendingIntent;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-
-import java.util.concurrent.Executors;
-import java.util.concurrent.ScheduledExecutorService;
-
-/**
- * Receives broadcast when device is rebooted or through the {@link AlarmManager}.
- */
-public class AlarmReceiver extends BroadcastReceiver {
-    private static final ScheduledExecutorService EXECUTOR =
-            Executors.newSingleThreadScheduledExecutor();
-
-    public static void setupAlarm(Context context) {
-        AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
-        Intent intent = new Intent(context, AlarmReceiver.class);
-        PendingIntent alarmIntent = PendingIntent.getBroadcast(context, 0, intent, 0);
-        alarmManager.cancel(alarmIntent);
-        alarmManager.setInexactRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP,
-                AlarmManager.INTERVAL_DAY, AlarmManager.INTERVAL_DAY, alarmIntent);
-    }
-
-    /**
-     * @see android.content.BroadcastReceiver#onReceive(android.content.Context,
-     *      android.content.Intent)
-     */
-    @Override
-    public void onReceive(final Context context, Intent intent) {
-        // This receiver listen to android.intent.action.BOOT_COMPLETED through the application
-        // manifest. When this happens, register the alarm.
-        if (intent.getAction() != null
-                && intent.getAction().equals("android.intent.action.BOOT_COMPLETED")) {
-            setupAlarm(context);
-        }
-        // In all cases, whether this is called through the alarm or at boot, check for applications
-        // to update.
-        EXECUTOR.execute(new Runnable() {
-
-            @Override
-            public void run() {
-                ApplicationUpdater.checkAndUpdateApplications(context);
-            }
-        });
-    }
-}
diff --git a/mojo/tools/android_shortcuts/apk/src/org/chromium/mojo/shortcuts/ApplicationUpdater.java b/mojo/tools/android_shortcuts/apk/src/org/chromium/mojo/shortcuts/ApplicationUpdater.java
deleted file mode 100644
index 33d5970..0000000
--- a/mojo/tools/android_shortcuts/apk/src/org/chromium/mojo/shortcuts/ApplicationUpdater.java
+++ /dev/null
@@ -1,157 +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 org.chromium.mojo.shortcuts;
-
-import android.content.Context;
-import android.content.Intent;
-import android.content.pm.PackageInfo;
-import android.content.pm.PackageManager;
-import android.net.Uri;
-import android.os.Environment;
-import android.util.Log;
-
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.UnsupportedEncodingException;
-import java.net.HttpURLConnection;
-import java.net.MalformedURLException;
-import java.net.URL;
-
-/**
- * Helper class to update apks.
- */
-public class ApplicationUpdater {
-    private static final String TAG = "ApplicationUpdater";
-
-    private static class ApplicationLocation {
-        private final String mPackageName;
-        private final String mURL;
-
-        public ApplicationLocation(String packageName, String url) {
-            mPackageName = packageName;
-            mURL = url;
-        }
-
-        /**
-         * Returns the application package.
-         */
-        public String getPackageName() {
-            return mPackageName;
-        }
-
-        /**
-         * Returns the application update URL.
-         */
-        public URL getURL() {
-            try {
-                return new URL(mURL);
-            } catch (MalformedURLException e) {
-                throw new RuntimeException(e);
-            }
-        }
-    }
-
-    private static final ApplicationLocation[] APPLICATIONS = {
-            new ApplicationLocation(
-                    "org.chromium.mojo.shortcuts", "http://domokit.github.io/MojoShortcuts.apk"),
-            new ApplicationLocation(
-                    "org.chromium.mojo.shell", "http://domokit.github.io/MojoShell.apk")};
-
-    private static boolean applicationNeedsUpdate(
-            Context context, ApplicationLocation application) {
-        PackageManager pm = context.getPackageManager();
-        try {
-            PackageInfo pi = pm.getPackageInfo(application.getPackageName(), 0);
-            HttpURLConnection urlConnection =
-                    (HttpURLConnection) application.getURL().openConnection();
-            urlConnection.setRequestMethod("HEAD");
-            urlConnection.connect();
-            long application_timestamp = urlConnection.getHeaderFieldDate("Last-Modified", 0);
-            return application_timestamp > pi.lastUpdateTime;
-        } catch (PackageManager.NameNotFoundException e) {
-            return true;
-        } catch (IOException e) {
-            Log.e(TAG,
-                    "Unable to retrieve information for package: " + application.getPackageName(),
-                    e);
-        }
-        return false;
-    }
-
-    private static String hex(byte bytes[]) {
-        StringBuilder sb = new StringBuilder();
-        for (byte b : bytes) {
-            sb.append(String.format("%02x", b & 0xff));
-        }
-        return sb.toString();
-    }
-
-    private static String getFilename(URL url) {
-        try {
-            return hex(url.toString().getBytes("UTF8"));
-        } catch (UnsupportedEncodingException e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-    private static void cleanDownloadDirectory() {
-        File directory = getDownloadDirectory();
-        for (File file : directory.listFiles()) {
-            file.delete();
-        }
-    }
-
-    private static File getDownloadDirectory() {
-        File directory = new File(Environment.getExternalStorageDirectory(), "mojo_shortcuts");
-        directory.mkdirs();
-        return directory;
-    }
-
-    private static void updateApplication(Context context, ApplicationLocation application) {
-        try {
-            URL url = application.getURL();
-            HttpURLConnection c = (HttpURLConnection) url.openConnection();
-            c.setRequestMethod("GET");
-            c.connect();
-
-            File outputFile = new File(getDownloadDirectory(), getFilename(url));
-
-            FileOutputStream fos = new FileOutputStream(outputFile);
-            try {
-                InputStream is = c.getInputStream();
-                try {
-                    byte[] buffer = new byte[4096];
-                    int len1 = 0;
-                    while ((len1 = is.read(buffer)) != -1) {
-                        fos.write(buffer, 0, len1);
-                    }
-                } finally {
-                    is.close();
-                }
-            } finally {
-                fos.close();
-            }
-
-            Intent intent = new Intent(Intent.ACTION_VIEW);
-            intent.setDataAndType(
-                    Uri.fromFile(outputFile), "application/vnd.android.package-archive");
-            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-            context.startActivity(intent);
-        } catch (IOException e) {
-            Log.e(TAG, "Unable to update package: " + application.getPackageName(), e);
-        }
-    }
-
-    public static void checkAndUpdateApplications(Context context) {
-        cleanDownloadDirectory();
-        for (ApplicationLocation application : APPLICATIONS) {
-            if (applicationNeedsUpdate(context, application)) {
-                updateApplication(context, application);
-            }
-        }
-    }
-}
diff --git a/mojo/tools/android_shortcuts/apk/src/org/chromium/mojo/shortcuts/ShortcutsActivity.java b/mojo/tools/android_shortcuts/apk/src/org/chromium/mojo/shortcuts/ShortcutsActivity.java
deleted file mode 100644
index 4f8fcb6..0000000
--- a/mojo/tools/android_shortcuts/apk/src/org/chromium/mojo/shortcuts/ShortcutsActivity.java
+++ /dev/null
@@ -1,107 +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 org.chromium.mojo.shortcuts;
-
-import android.app.Activity;
-import android.content.ComponentName;
-import android.content.Intent;
-import android.content.SharedPreferences;
-import android.content.SharedPreferences.Editor;
-import android.os.Bundle;
-import android.util.JsonWriter;
-import android.util.Log;
-
-import java.io.IOException;
-import java.io.StringWriter;
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Main activity for the shortcuts application. It installs default shortcuts and sets up the alarm
- * for the auto-update process.
- */
-public class ShortcutsActivity extends Activity {
-    private static final String TAG = "ShortcutsActivity";
-
-    private static class Shortcut {
-        private final String mName;
-        private final String mUrl;
-
-        public Shortcut(String name, String url) {
-            mName = name;
-            mUrl = url;
-        }
-
-        public String getName() {
-            return mName;
-        }
-
-        public String getUrl() {
-            return mUrl;
-        }
-
-        public Intent getIntent() throws IOException {
-            List<String> commandLine = new ArrayList<String>();
-            commandLine.add("--origin=https://domokit.github.io/mojo");
-            commandLine.add("--url-mappings=mojo:window_manager=mojo:kiosk_wm");
-            commandLine.add("--args-for=mojo:window_manager " + getUrl());
-            commandLine.add("mojo:window_manager");
-            Intent intent = new Intent();
-            intent.setComponent(new ComponentName(
-                    "org.chromium.mojo.shell", "org.chromium.mojo.shell.MojoShellActivity"));
-            intent.setAction(Intent.ACTION_VIEW);
-            intent.putExtra("encodedParameters", jsonEncode(commandLine));
-            return intent;
-        }
-
-        private static String jsonEncode(List<String> list) throws IOException {
-            StringWriter sw = new StringWriter();
-            JsonWriter json = new JsonWriter(sw);
-            json.beginArray();
-            for (String p : list) {
-                json.value(p);
-            }
-            json.endArray();
-            json.close();
-            return sw.toString();
-        }
-    }
-
-    private static final Shortcut[] SHORTCUTS = {
-            new Shortcut("Home", "https://domokit.github.io/home")};
-
-    /**
-     * @see android.app.Activity#onCreate(android.os.Bundle)
-     */
-    @Override
-    protected void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-
-        SharedPreferences shortcuts = getSharedPreferences("shortcuts", MODE_PRIVATE);
-        Editor editor = shortcuts.edit();
-
-        for (Shortcut shortcut : SHORTCUTS) {
-            try {
-                Intent intent = new Intent();
-                intent.putExtra(Intent.EXTRA_SHORTCUT_INTENT, shortcut.getIntent());
-                intent.putExtra(Intent.EXTRA_SHORTCUT_NAME, shortcut.getName());
-                intent.setAction("com.android.launcher.action.UNINSTALL_SHORTCUT");
-                sendBroadcast(intent);
-
-                intent = new Intent();
-                intent.putExtra(Intent.EXTRA_SHORTCUT_INTENT, shortcut.getIntent());
-                intent.putExtra(Intent.EXTRA_SHORTCUT_NAME, shortcut.getName());
-                intent.setAction("com.android.launcher.action.INSTALL_SHORTCUT");
-                sendBroadcast(intent);
-            } catch (IOException e) {
-                Log.e(TAG, "Unable to install shortcut", e);
-            }
-            editor.putString(shortcut.getName(), shortcut.getUrl());
-        }
-        editor.apply();
-        AlarmReceiver.setupAlarm(this);
-        finish();
-    }
-}
diff --git a/mojo/tools/apptest_runner.py b/mojo/tools/apptest_runner.py
deleted file mode 100755
index b3378ef..0000000
--- a/mojo/tools/apptest_runner.py
+++ /dev/null
@@ -1,59 +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.
-
-"""A test runner for application tests."""
-
-import argparse
-import logging
-import os.path
-import subprocess
-import sys
-
-from mopy import gtest
-from mopy.config import Config
-from mopy.gn import ConfigForGNArgs, ParseGNConfig
-from mopy.log import InitLogging
-from mopy.paths import Paths
-
-
-_logger = logging.getLogger()
-
-
-def main():
-  parser = argparse.ArgumentParser(description="A test runner for application "
-                                               "tests.")
-
-  parser.add_argument("--verbose", help="be verbose (multiple times for more)",
-                      default=0, dest="verbose_count", action="count")
-  parser.add_argument("test_list_file", type=str,
-                      help="a file listing apptests to run")
-  parser.add_argument("build_dir", type=str,
-                      help="the build output directory")
-  args = parser.parse_args()
-
-  InitLogging(args.verbose_count)
-  config = ConfigForGNArgs(ParseGNConfig(args.build_dir))
-  paths = Paths(config)
-  command_line = [os.path.join(os.path.dirname(__file__), os.path.pardir,
-                               "devtools", "common", "mojo_test"),
-                  str(args.test_list_file)]
-
-  if config.target_os == Config.OS_ANDROID:
-    command_line.append("--android")
-    command_line.append("--adb-path=" + paths.adb_path)
-    command_line.append("--origin=" + paths.build_dir)
-
-  command_line.append("--shell-path=" + paths.target_mojo_shell_path)
-  if args.verbose_count:
-    command_line.append("--verbose")
-
-  gtest.set_color()
-  print "Running " + str(command_line)
-  ret = subprocess.call(command_line)
-  return ret
-
-
-if __name__ == '__main__':
-  sys.exit(main())
diff --git a/mojo/tools/check_mojom_golden_files.py b/mojo/tools/check_mojom_golden_files.py
deleted file mode 100755
index ae80ceb..0000000
--- a/mojo/tools/check_mojom_golden_files.py
+++ /dev/null
@@ -1,103 +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 os.path
-import sys
-from filecmp import dircmp
-from shutil import rmtree
-from tempfile import mkdtemp
-from mopy.paths import Paths
-
-paths = Paths()
-
-sys.path.insert(0, os.path.join(paths.mojo_dir, "public", "tools", "bindings",
-                                "pylib"))
-from mojom_tests.support.find_files import FindFiles
-from mojom_tests.support.run_bindings_generator import RunBindingsGenerator
-
-
-def _ProcessDircmpResults(results, verbose=False):
-  """Prints results of directory comparison and returns true if they are
-  identical (note: the "left" directory should be the golden directory)."""
-  rv = not (bool(results.left_only) or bool(results.right_only) or \
-            bool(results.common_funny) or bool(results.funny_files) or \
-            bool(results.diff_files))
-  if verbose:
-    for f in results.left_only:
-      print "%s exists in golden directory but not in current output" % f
-    for f in results.right_only:
-      print "%s exists in current output but not in golden directory" % f
-    for f in results.common_funny + results.funny_files:
-      print "Unable to compare %s between golden directory and current output" \
-          % f
-    for f in results.diff_files:
-      print "%s differs between golden directory and current output" % f
-  for r in results.subdirs.values():
-    # If we're being verbose, check subdirectories even if we know that there
-    # are differences. Note that it's "... and rv" to avoid the short-circuit.
-    if rv or verbose:
-      rv = _ProcessDircmpResults(r, verbose=verbose) and rv
-  return rv
-
-
-def main():
-  parser = argparse.ArgumentParser()
-  parser.add_argument("--generate_golden_files", action="store_true",
-                      help=("generate golden files (does not obliterate "
-                            "directory"))
-  parser.add_argument("--keep_temp_dir", action="store_true",
-                      help="don't delete the temporary directory")
-  parser.add_argument("--verbose", action="store_true",
-                      help="spew excess verbiage")
-  parser.add_argument("golden_dir", metavar="GOLDEN_DIR",
-                      help="directory with the golden files")
-  args = parser.parse_args()
-
-  if args.generate_golden_files:
-    if os.path.exists(args.golden_dir):
-      print "WARNING: golden directory %s already exists" % args.golden_dir
-    out_dir = args.golden_dir
-  else:
-    if not os.path.exists(args.golden_dir):
-      print "ERROR: golden directory %s does not exist" % args.golden_dir
-      return 1
-    out_dir = mkdtemp()
-  if args.verbose:
-    print "Generating files to %s ..." % out_dir
-
-  mojom_files = FindFiles(paths.mojo_dir, "*.mojom")
-  for mojom_file in mojom_files:
-    if args.verbose:
-      print "  Processing %s ..." % os.path.relpath(mojom_file, paths.mojo_dir)
-    # TODO(vtl): This may wrong, since the path can be overridden in the .gyp
-    # file.
-    RunBindingsGenerator(out_dir, paths.mojo_dir, mojom_file,
-                         ["-I", paths.src_root])
-
-  if args.generate_golden_files:
-    return 0
-
-  identical = _ProcessDircmpResults(dircmp(args.golden_dir, out_dir, ignore=[]),
-                                    verbose=args.verbose)
-
-  if args.keep_temp_dir:
-    if args.verbose:
-      print "Not removing %s ..." % out_dir
-  else:
-    if args.verbose:
-      print "Removing %s ..." % out_dir
-    rmtree(out_dir)
-
-  if not identical:
-    print "FAILURE: current output differs from golden files"
-    return 1
-
-  print "SUCCESS: current output identical to golden files"
-  return 0
-
-
-if __name__ == '__main__':
-  sys.exit(main())
diff --git a/mojo/tools/data/apptests b/mojo/tools/data/apptests
deleted file mode 100644
index 6cada41..0000000
--- a/mojo/tools/data/apptests
+++ /dev/null
@@ -1,127 +0,0 @@
-# This file contains a list of Mojo apptests. For description of the file
-# format, see `mojo_test` in devtools.
-
-tests = [
-  {
-    "test": "mojo:asset_bundle_apptests",
-  },
-  {
-    "test": "mojo:authenticating_url_loader_interceptor_apptests",
-  },
-  {
-    "test": "mojo:clipboard_apptests",
-  },
-  {
-    "test": "mojo:example_apptests",
-    # ExampleApplicationTest.CheckCommandLineArg checks --example_apptest_arg.
-    "test-args": ["--example_apptest_arg"],
-  },
-  {
-    "test": "mojo:example_apptests",
-    "name": "mojo:example_apptests (multiprocess)",
-    # ExampleApplicationTest.CheckCommandLineArg checks --example_apptest_arg.
-    "test-args": ["--example_apptest_arg"],
-    "shell-args": ["--enable-multiprocess"],
-  },
-  {
-    "test": "mojo:files_apptests",
-  },
-  {
-    "test": "mojo:http_server_apptests",
-  },
-  {
-    "test": "mojo:mojio_apptests",
-  },
-  {
-    "test": "mojo:moterm_apptests",
-    "shell-args": ["--args-for=mojo:native_viewport_service --use-headless-config --use-osmesa"],
-  },
-  {
-    "test": "mojo:texture_apptests",
-    "shell-args": ["--args-for=mojo:native_viewport_service --use-headless-config --use-osmesa"],
-  },
-  {
-    "test": "mojo:mojo_view_manager_client_apptests",
-    "shell-args": ["--args-for=mojo:native_viewport_service --use-headless-config --use-osmesa"],
-  },
-  {
-    "test": "mojo:prediction_apptests",
-  },
-  {
-    "test": "mojo:view_manager_service_apptests",
-    "type": "gtest_isolated",
-    "shell-args": ["--args-for=mojo:native_viewport_service --use-headless-config --use-osmesa"],
-  },
-  {
-    "test": "mojo:network_service_apptests",
-  },
-  {
-    "test": "mojo:window_manager_apptests",
-    "shell-args": ["--args-for=mojo:native_viewport_service --use-headless-config --use-osmesa"],
-  },
-  {
-    "test": "mojo:versioning_apptests",
-  },
-  {
-    "test": "mojo:url_response_disk_cache_apptests",
-  },
-]
-
-if target_os == 'linux':
-  tests += [
-    {
-      "test": "mojo:example_apptests",
-      "name": "mojo:example_apptests (python_example_service)",
-      # ExampleApplicationTest.CheckCommandLineArg checks --example_apptest_arg.
-      "test-args": ["--example_apptest_arg"],
-      "shell-args": [
-        "--url-mappings=mojo:example_service=mojo:python_example_service"
-      ],
-    },
-    {
-      "test": "mojo:mojo_url_redirector_apptests",
-      "test-args": ["--redirector_port=49152",
-                    "--app_location_files_port=49153"],
-      "shell-args": ["--args-for=mojo:mojo_url_redirector 0.0.0.0:49152 http://localhost:49153"],
-    }
-  ]
-
-if target_os == 'android':
-  tests += [
-    {
-      "test": "mojo:example_apptests",
-      "name": "mojo:example_apptests (android_example_service)",
-      # ExampleApplicationTest.CheckCommandLineArg checks --example_apptest_arg.
-      "test-args": ["--example_apptest_arg"],
-      "shell-args": [
-        "--url-mappings=mojo:example_service=mojo:android_example_service"
-      ],
-    },
-    {
-      "test": "mojo:notification_apptests",
-    },
-    {
-      "test": "mojo:shell_nfc_apptests",
-    },
-  ]
-
-if target_os != 'android':
-  tests += [
-    {
-      "test": "mojo:js_apptests",
-      "type": "gtest_isolated",
-    },
-    {
-      "test": "mojo:reaper_apptests",
-    },
-    {
-      "test": "mojo:dart_apptests",
-      "type": "dart",
-    },
-    {
-      # https://github.com/domokit/mojo/issues/61
-      # Sometime the shell get a trucated application when exposed through the
-      # http server.
-      "test": "mojo:shell_apptests",
-    },
-  ]
diff --git a/mojo/tools/data/nacl_apptests b/mojo/tools/data/nacl_apptests
deleted file mode 100644
index eeba8ca..0000000
--- a/mojo/tools/data/nacl_apptests
+++ /dev/null
@@ -1,33 +0,0 @@
-# This file contains a list of NaCl Mojo gtest unit tests.
-# This must be a valid python dictionary.
-# TODO(vtl|msw): Add a way of specifying data dependencies.
-tests = [
-  # TODO(ncbray): support other architectures.
-  {
-    "test": "mojo:clipboard_apptests_x64.nexe",
-  },
-  {
-    "test": "mojo:example_apptests_x64.nexe",
-    # ExampleApplicationTest.CheckCommandLineArg checks --example_apptest_arg.
-    "test-args": ["--example_apptest_arg"],
-  },
-  {
-    "test": "mojo:files_apptests_x64.nexe",
-  },
-  {
-    "test": "mojo:mojo_view_manager_client_apptests_x64.nexe",
-    "shell-args": ["--args-for=mojo:native_viewport_service --use-headless-config --use-osmesa"],
-  },
-  {
-    "test": "mojo:view_manager_service_apptests_x64.nexe",
-    "type": "gtest_isolated",
-    "shell-args": ["--args-for=mojo:native_viewport_service --use-headless-config --use-osmesa"],
-  },
-  {
-    "test": "mojo:window_manager_apptests_x64.nexe",
-  },
-  {
-    "test": "mojo:shell_apptests_x64.nexe",
-  },
-  # TODO(ncbray): http_server_apptests (uses two-stage data pipe reads)
-]
diff --git a/mojo/tools/data/unittests b/mojo/tools/data/unittests
deleted file mode 100644
index 39af324..0000000
--- a/mojo/tools/data/unittests
+++ /dev/null
@@ -1,96 +0,0 @@
-# This file contains a list of Mojo gtest unit tests.
-# This must be valid python. It can use the |config| global that will be a
-# mopy.config.Config object and must set a |tests| global that will contain the
-# tests to run.
-# TODO(vtl): Add a way of specifying data dependencies instead of cacheable.
-
-tests = [
-  # System tests:
-  {
-    "test": "mojo_system_unittests",
-  },
-
-  # Public tests:
-  {
-    "test": "mojo_public_bindings_unittests",
-    "cacheable": False,
-  },
-  {
-    "test": "mojo_public_environment_unittests",
-  },
-  {
-    "test": "mojo_public_system_unittests",
-  },
-  {
-    "test": "mojo_public_utility_unittests",
-  },
-  {
-    "test": "mojo_system_impl_private_unittests",
-  },
-
-  # Non-system, non-public tests:
-  {
-    "test": "crypto_unittests",
-  },
-  {
-    "test": "mojo_application_manager_unittests",
-  },
-  {
-    "test": "mojo_common_unittests",
-  },
-  {
-    "test": "mojo_view_manager_lib_unittests",
-  },
-  {
-    "test": "mojo_surfaces_lib_unittests",
-  },
-  {
-    "test": "view_manager_service_unittests",
-  },
-  {
-    "test": "window_manager_unittests",
-  },
-
-  # Shell integration tests:
-  {
-    "test": "mojo_shell_tests",
-    "cacheable": False,
-  },
-  {
-    "test": "crash_unittests",
-  },
-]
-
-if config.target_os != config.OS_ANDROID:
-  tests += [
-    # Tests for components we depend on:
-    {
-      "test": "gfx_unittests",
-    },
-    {
-      "test": "events_unittests",
-    },
-
-    # JavaScript tests:
-    {
-      "test": "js_unittests",
-      "cacheable": False,
-    },
-    {
-      "test": "js_integration_tests",
-      "cacheable": False,
-    },
-    {
-      "test": "js_services_unittests",
-      "cacheable": False,
-    },
-  ]
-
-# TODO: get dart unittests working with android.
-if config.target_os != config.OS_ANDROID:
-  tests += [
-    {
-      "test": "dart_unittests",
-      "cacheable": False,
-    },
-  ]
diff --git a/mojo/tools/deploy_domokit_site.py b/mojo/tools/deploy_domokit_site.py
deleted file mode 100755
index 7175092..0000000
--- a/mojo/tools/deploy_domokit_site.py
+++ /dev/null
@@ -1,157 +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.
-
-"""Deploy domokit.github.io"""
-
-# NOTE: Requires that download_material_design_icons to have been run from
-# $build_dir/gen/dart-dpkg/sky.
-
-import argparse
-import logging
-import os
-import shutil
-import subprocess
-
-from mopy.paths import Paths
-
-
-def git_revision():
-    return subprocess.check_output(['git', 'rev-parse', 'HEAD']).strip()
-
-
-def mojo_filter(path):
-    if not os.path.isfile(path):
-        return False
-    _, ext = os.path.splitext(path)
-    if ext != '.mojo':
-        return False
-    return 'apptests' not in os.path.basename(path)
-
-
-def gen_filter(path):
-    if os.path.isdir(path):
-        return True
-    _, ext = os.path.splitext(path)
-    # Don't include all .dart, just .mojom.dart.
-    return ext == '.sky' or path.endswith('.mojom.dart')
-
-
-def examples_filter(path):
-    if os.path.isdir(path):
-        return True
-    return 'packages' != os.path.basename(path)
-
-
-def sky_or_dart_filter(path):
-    if os.path.isdir(path):
-        return True
-    _, ext = os.path.splitext(path)
-    # .dart includes '.mojom.dart'
-    return ext == '.sky' or ext == '.dart'
-
-
-def assets_filter(path):
-    if os.path.isdir(path):
-        return True
-    if os.path.basename(os.path.dirname(path)) != 'drawable-xxhdpi':
-        return False
-    # We only use the 18 and 24s for now.
-    return '18dp' in path or '24dp' in path
-
-
-def packages_filter(path):
-    if 'packages/sky/assets/material-design-icons/' in path:
-        return assets_filter(path)
-    if '.gitignore' in path:
-        return False
-    return True
-
-
-def ensure_dir_exists(path):
-    if not os.path.exists(path):
-        os.makedirs(path)
-
-
-def copy(from_root, to_root, filter_func=None, followlinks=False):
-    assert os.path.exists(from_root), "%s does not exist!" % from_root
-    if os.path.isfile(from_root):
-        ensure_dir_exists(os.path.dirname(to_root))
-        shutil.copy(from_root, to_root)
-        return
-
-    if os.path.exists(to_root):
-        shutil.rmtree(to_root)
-    os.makedirs(to_root)
-
-    for root, dirs, files in os.walk(from_root, followlinks=followlinks):
-        # filter_func expects paths not names, so wrap it to make them absolute.
-        wrapped_filter = None
-        if filter_func:
-            wrapped_filter = lambda name: filter_func(os.path.join(root, name))
-
-        for name in filter(wrapped_filter, files):
-            from_path = os.path.join(root, name)
-            root_rel_path = os.path.relpath(from_path, from_root)
-            to_path = os.path.join(to_root, root_rel_path)
-            to_dir = os.path.dirname(to_path)
-            if not os.path.exists(to_dir):
-                os.makedirs(to_dir)
-            shutil.copyfile(from_path, to_path)
-
-        dirs[:] = filter(wrapped_filter, dirs)
-
-
-def main():
-    logging.basicConfig(level=logging.WARN)
-    parser = argparse.ArgumentParser(description='Deploy a new build of mojo.')
-    parser.add_argument('deploy_root', type=str)
-    args = parser.parse_args()
-
-    # Always use android release?
-    rel_build_dir = os.path.join('out', 'android_Release')
-    build_dir = os.path.join(Paths().src_root, rel_build_dir)
-    paths = Paths(build_dir=build_dir)
-    dart_pkg_dir = os.path.join(paths.build_dir, 'gen', 'dart-pkg')
-    sky_pkg_dir = os.path.join(dart_pkg_dir, 'sky')
-    sky_pkg_lib_dir = os.path.join(sky_pkg_dir, 'lib')
-    dart_pkg_packages_dir = os.path.join(dart_pkg_dir, 'packages')
-
-    def deploy_path(rel_path):
-        return os.path.join(args.deploy_root, rel_path)
-
-    def src_path(rel_path):
-        return os.path.join(paths.src_root, rel_path)
-
-    # Verify that material-design-icons have been downloaded.
-    icons_dir = os.path.join(dart_pkg_packages_dir,
-                             'sky/assets/material-design-icons')
-    if not os.path.isdir(icons_dir):
-        print('NOTE: Running `download_material_design_icons` for you.');
-        subprocess.check_call([
-                os.path.join(sky_pkg_lib_dir, 'download_material_design_icons')
-            ])
-
-    # Copy sky/sdk/example into example/
-    copy(src_path('sky/sdk/example'), deploy_path('example'), examples_filter)
-
-    # Deep copy packages/. This follows symlinks and flattens them.
-    packages_root = deploy_path('packages')
-    copy(dart_pkg_packages_dir, packages_root, packages_filter, True)
-
-    # Write out license.
-    with open(deploy_path('LICENSES.sky'), 'w') as license_file:
-        subprocess.check_call([src_path('tools/licenses.py'), 'credits'],
-            stdout=license_file)
-
-    # Run git commands.
-    subprocess.check_call(['git', 'add', '.'], cwd=args.deploy_root)
-    subprocess.check_call([
-        'git', 'commit',
-        '-m', '%s from %s' % (rel_build_dir, git_revision())
-        ], cwd=args.deploy_root)
-
-
-if __name__ == '__main__':
-    main()
diff --git a/mojo/tools/devtools.py b/mojo/tools/devtools.py
deleted file mode 100644
index 28a0d91..0000000
--- a/mojo/tools/devtools.py
+++ /dev/null
@@ -1,15 +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 os
-import sys
-
-
-def add_lib_to_path():
-  """ Adds the devtools pylib to path, allowing to use it in the internal
-  /mojo/tools/ tooling. """
-  sys.path.append(os.path.join(os.path.dirname(__file__),
-                               os.pardir,
-                               "devtools",
-                               "common"))
diff --git a/mojo/tools/download_keystore.py b/mojo/tools/download_keystore.py
deleted file mode 100755
index 97ed4b5..0000000
--- a/mojo/tools/download_keystore.py
+++ /dev/null
@@ -1,93 +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.
-
-"""Tool to download keys needed to sign the official Mojo Shell APK build.
-"""
-
-import argparse
-import os
-import subprocess
-import sys
-
-import mopy.gn as gn
-from mopy.config import Config
-from mopy.paths import Paths
-
-
-# Google Storage path of the official keystore to download.
-_KEYSTORE_PATH = "gs://mojo/android/keys/mojo_shell-official.keystore"
-_KEYSTORE_PWD_PATH = "gs://mojo/android/keys/mojo_shell-official.pwd"
-
-
-def _get_gsutil_exe():
-  """Get the path to gsutil executable."""
-  config = Config(target_os=Config.OS_ANDROID, is_debug=False,
-                  is_official_build=True)
-  paths = Paths(config)
-  sys.path.insert(0, os.path.join(paths.src_root, "tools"))
-  # pylint: disable=F0401
-  import find_depot_tools
-  depot_tools_path = find_depot_tools.add_depot_tools_to_path()
-  gsutil_exe = os.path.join(depot_tools_path, "third_party", "gsutil",
-                            "gsutil")
-  return gsutil_exe
-
-
-def _download_keystore(args):
-  """Downloads the keystore file on local disk."""
-  directory_path = args.output[0]
-  if args.verbose:
-    print "Downloading " + _KEYSTORE_PATH + " to " + directory_path
-  gsutil_exe = _get_gsutil_exe()
-  if args.dry_run:
-    print str([gsutil_exe, "cp", _KEYSTORE_PATH, directory_path])
-  else:
-    subprocess.check_call([gsutil_exe, "cp", _KEYSTORE_PATH, directory_path])
-
-
-def _output_password(args):
-  """Outputs the keystore password on the standard output."""
-  # The build system cannot read a file that is generated by a script and
-  # use its content as a variable. It can either 1/ read a file already there
-  # or 2/ put a script output in a variable. Hence the fact that we do not
-  # download the password to a file, but output it on the standard output.
-  gsutil_exe = _get_gsutil_exe()
-
-  if args.dry_run:
-    print str([gsutil_exe, "cat", _KEYSTORE_PWD_PATH])
-  else:
-    subprocess.check_call([gsutil_exe, "cat", _KEYSTORE_PWD_PATH],
-                          stdout=sys.stdout)
-
-
-def main():
-  parser = argparse.ArgumentParser(
-      description="Downloads the keystore used to sign official APK builds.")
-  parser.add_argument("-n", "--dry_run", help="Dry run, do not actually "+
-      "download", action="store_true")
-  parser.add_argument("-v", "--verbose", help="Verbose mode",
-      action="store_true")
-
-  subparsers = parser.add_subparsers()
-
-  keystore_file_parser = subparsers.add_parser(
-      "keystore_file", help="Downloads the keystore file")
-  keystore_file_parser.add_argument("output", nargs=1, type=str,
-                      help="Output path to save the keystore to")
-  keystore_file_parser.set_defaults(func=_download_keystore)
-
-  keystore_pwd_parser = subparsers.add_parser(
-      "keystore_password", help="Outputs the keystore password")
-  keystore_pwd_parser.set_defaults(func=_output_password)
-
-  args = parser.parse_args()
-  args.func(args)
-
-
-  return 0
-
-
-if __name__ == "__main__":
-  sys.exit(main())
diff --git a/mojo/tools/embed/data.h b/mojo/tools/embed/data.h
deleted file mode 100644
index 50bf074..0000000
--- a/mojo/tools/embed/data.h
+++ /dev/null
@@ -1,22 +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.
-
-#ifndef MOJO_TOOLS_EMBED_DATA_H_
-#define MOJO_TOOLS_EMBED_DATA_H_
-
-#include <stddef.h>  // For size_t.
-
-namespace mojo {
-namespace embed {
-
-struct Data {
-  const char* const hash;
-  const char* const data;
-  const size_t size;
-};
-
-}  // namespace embed
-}  // namespace mojo
-
-#endif  // MOJO_TOOLS_EMBED_DATA_H_
diff --git a/mojo/tools/embed/embed_data.py b/mojo/tools/embed/embed_data.py
deleted file mode 100755
index f34348a..0000000
--- a/mojo/tools/embed/embed_data.py
+++ /dev/null
@@ -1,76 +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.
-
-import argparse
-import hashlib
-import os
-import sys
-
-def main():
-  """Command line utility to embed file in a C executable."""
-  parser = argparse.ArgumentParser(
-      description='Generate a source file to embed the content of a file')
-
-  parser.add_argument('source')
-  parser.add_argument('out_dir')
-  parser.add_argument('namespace')
-  parser.add_argument('variable')
-
-  opts = parser.parse_args()
-
-  if not os.path.exists(opts.out_dir):
-    os.makedirs(opts.out_dir)
-
-  header = os.path.join(opts.out_dir, '%s.h' % opts.variable)
-  c_file = os.path.join(opts.out_dir, '%s.cc' % opts.variable)
-  namespaces = opts.namespace.split('::')
-
-  data = None
-  with open(opts.source, "rb") as f:
-    data = f.read()
-
-  with open(header, "w") as f:
-    f.write('// Generated file. Do not modify.\n')
-    f.write('\n')
-    f.write('#include "mojo/tools/embed/data.h"\n')
-    f.write('\n')
-    for n in namespaces:
-      f.write('namespace %s {\n' % n)
-    f.write('extern const mojo::embed::Data %s;\n' % opts.variable);
-    for n in reversed(namespaces):
-      f.write('}  // namespace %s\n' % n)
-
-  sha1hash = hashlib.sha1(data).hexdigest()
-  values = ["0x%02x" % ord(c) for c in data]
-  lines = []
-  chunk_size = 16
-  for i in range(0, len(values), chunk_size):
-    lines.append("  " + ", ".join(values[i: i + chunk_size]))
-
-  with open(c_file, "w") as f:
-    f.write('// Generated file. Do not modify.\n')
-    f.write('\n')
-    f.write('#include "mojo/tools/embed/data.h"\n')
-    f.write('\n')
-    for n in namespaces:
-      f.write('namespace %s {\n' % n)
-    f.write('namespace {\n')
-    f.write("const char data[%d] = {\n" % len(data))
-    f.write(",\n".join(lines))
-    f.write("\n};\n")
-    f.write('}  // namespace\n')
-    f.write('\n')
-    f.write('extern const mojo::embed::Data %s;\n' % opts.variable);
-    f.write('const mojo::embed::Data %s = {\n' % opts.variable);
-    f.write('  "%s",\n' % sha1hash)
-    f.write('  data,\n')
-    f.write('  sizeof(data)\n')
-    f.write('};\n');
-    f.write('\n')
-    for n in reversed(namespaces):
-      f.write('}  // namespace %s\n' % n)
-
-if __name__ == '__main__':
-  main()
diff --git a/mojo/tools/embed/rules.gni b/mojo/tools/embed/rules.gni
deleted file mode 100644
index 6171812..0000000
--- a/mojo/tools/embed/rules.gni
+++ /dev/null
@@ -1,49 +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.
-
-template("embed_file") {
-  assert(defined(invoker.variable))
-  assert(defined(invoker.source))
-  assert(defined(invoker.namespace))
-
-  variable = invoker.variable
-  generator_target_name = "__${target_name}_generator"
-  generator_outputs = [
-    "${target_gen_dir}/${variable}.cc",
-    "${target_gen_dir}/${variable}.h",
-  ]
-
-  action(generator_target_name) {
-    script = "//mojo/tools/embed/embed_data.py"
-    sources = [
-      invoker.source,
-    ]
-    outputs = generator_outputs
-    args = [
-      rebase_path(invoker.source),
-      rebase_path(target_gen_dir),
-      invoker.namespace,
-      variable,
-    ]
-
-    if (defined(invoker.testonly)) {
-      testonly = invoker.testonly
-    }
-    if (defined(invoker.deps)) {
-      deps = invoker.deps
-    }
-  }
-
-  source_set(target_name) {
-    sources = generator_outputs
-
-    if (defined(invoker.testonly)) {
-      testonly = invoker.testonly
-    }
-
-    deps = [
-      ":${generator_target_name}",
-    ]
-  }
-}
diff --git a/mojo/tools/generate_java_callback_interfaces.py b/mojo/tools/generate_java_callback_interfaces.py
deleted file mode 100644
index 257a540..0000000
--- a/mojo/tools/generate_java_callback_interfaces.py
+++ /dev/null
@@ -1,69 +0,0 @@
-"""Generate the org.chromium.mojo.bindings.Callbacks interface"""
-
-import argparse
-import sys
-
-CALLBACK_TEMPLATE = ("""
-    /**
-     * A generic %d-argument callback.
-     *
-     * %s
-     */
-    interface Callback%d<%s> {
-        /**
-         * Call the callback.
-         */
-        public void call(%s);
-    }
-""")
-
-INTERFACE_TEMPLATE = (
-"""// 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.
-
-// This file was generated using
-//     mojo/tools/generate_java_callback_interfaces.py
-
-package org.chromium.mojo.bindings;
-
-/**
- * Contains a generic interface for callbacks.
- */
-public interface Callbacks {
-
-    /**
-     * A generic callback.
-     */
-    interface Callback0 {
-        /**
-         * Call the callback.
-         */
-        public void call();
-    }
-%s
-}""")
-
-def GenerateCallback(nb_args):
-  params = '\n      * '.join(
-      ['@param <T%d> the type of argument %d.' % (i+1, i+1)
-       for i in xrange(nb_args)])
-  template_parameters = ', '.join(['T%d' % (i+1) for i in xrange(nb_args)])
-  callback_parameters = ', '.join(['T%d arg%d' % ((i+1), (i+1))
-                                   for i in xrange(nb_args)])
-  return CALLBACK_TEMPLATE % (nb_args, params, nb_args, template_parameters,
-                              callback_parameters)
-
-def main():
-  parser = argparse.ArgumentParser(
-      description="Generate org.chromium.mojo.bindings.Callbacks")
-  parser.add_argument("max_args", nargs=1, type=int,
-      help="maximal number of arguments to generate callbacks for")
-  args = parser.parse_args()
-  max_args = args.max_args[0]
-  print INTERFACE_TEMPLATE % ''.join([GenerateCallback(i+1)
-                                      for i in xrange(max_args)])
-  return 0
-
-if __name__ == "__main__":
-  sys.exit(main())
diff --git a/mojo/tools/get_test_list.py b/mojo/tools/get_test_list.py
deleted file mode 100755
index 341b3d8..0000000
--- a/mojo/tools/get_test_list.py
+++ /dev/null
@@ -1,243 +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.
-
-"""Central list of tests to run (as appropriate for a given config). Add tests
-to run by modifying this file.
-
-Note that this file is both imported (by mojob.py) and run directly (via a
-recipe)."""
-
-
-import argparse
-import json
-import os
-import sys
-
-from mopy.config import Config
-from mopy.paths import Paths
-
-
-def GetTestList(config, verbose_count=0):
-  """Gets the list of tests to run for the given config. The test list (which is
-  returned) is just a list of dictionaries, each dictionary having two required
-  fields:
-    {
-      "name": "Short name",
-      "command": ["python", "test_runner.py", "--some", "args"]
-    }
-  """
-
-  types_to_run = set(config.test_types)
-
-  # See above for a description of the test list.
-  test_list = []
-
-  paths = Paths(config)
-  build_dir = paths.SrcRelPath(paths.build_dir)
-  target_os = config.target_os
-
-  verbose_flags = verbose_count * ["--verbose"]
-
-  # Utility functions ----------------------------------------------------------
-
-  # Call this to determine if a test matching classes this_tests_types should
-  # run: e.g., ShouldRunTest(Config.TEST_TYPE_DEFAULT, "sky") returns true if
-  # the test list being requested specifies the default set or the "sky" set.
-  def ShouldRunTest(*this_tests_types):
-    return not types_to_run.isdisjoint(this_tests_types)
-
-  # Call this to add the given command to the test list.
-  def AddEntry(name, command):
-    if config.sanitizer == Config.SANITIZER_ASAN:
-      command = (["python", os.path.join("mojo", "tools",
-                                         "run_command_through_symbolizer.py")] +
-                 command)
-    test_list.append({"name": name, "command": command})
-
-  # Call this to add the given command to the test list. If appropriate, the
-  # command will be run under xvfb.
-  def AddXvfbEntry(name, command):
-    real_command = ["python"]
-    if config.target_os == Config.OS_LINUX:
-      real_command += ["./testing/xvfb.py", paths.SrcRelPath(paths.build_dir)]
-    real_command += command
-    AddEntry(name, real_command)
-
-  # ----------------------------------------------------------------------------
-
-  # TODO(vtl): Currently, we only know how to run tests for Android, Linux, or
-  # Windows.
-  if target_os not in (Config.OS_ANDROID, Config.OS_LINUX, Config.OS_WINDOWS,
-                       Config.OS_IOS):
-    return test_list
-
-  # Tests run by default -------------------------------------------------------
-
-  # C++ unit tests:
-  if ShouldRunTest(Config.TEST_TYPE_DEFAULT, Config.TEST_TYPE_UNIT):
-    AddXvfbEntry("Unit tests",
-                 [os.path.join("mojo", "tools", "test_runner.py"),
-                  os.path.join("mojo", "tools", "data", "unittests"),
-                  build_dir] + verbose_flags)
-    # NaCl tests (Linux only):
-    if (target_os == Config.OS_LINUX and
-        config.sanitizer != Config.SANITIZER_ASAN):
-      AddEntry("NaCl tests",
-               [os.path.join(build_dir, "monacl_shell"),
-                os.path.join(build_dir, "irt_" + config.target_cpu,
-                             "irt_mojo.nexe"),
-                os.path.join(build_dir, "clang_newlib_" + config.target_cpu,
-                             "monacl_test.nexe")])
-
-  # C++ app tests:
-  if ShouldRunTest(Config.TEST_TYPE_DEFAULT, "app"):
-    AddXvfbEntry("App tests",
-                 [os.path.join("mojo", "tools", "apptest_runner.py"),
-                  os.path.join("mojo", "tools", "data", "apptests"),
-                  build_dir] + verbose_flags)
-    # NaCl app tests (Linux only):
-    if (target_os == Config.OS_LINUX and
-        config.sanitizer != Config.SANITIZER_ASAN):
-      AddXvfbEntry("NaCl app tests",
-                   [os.path.join("mojo", "tools", "apptest_runner.py"),
-                    os.path.join("mojo", "tools", "data", "nacl_apptests"),
-                    build_dir] + verbose_flags)
-
-  # Go unit tests (Linux-only):
-  if (target_os == Config.OS_LINUX and
-      config.sanitizer != Config.SANITIZER_ASAN and
-      ShouldRunTest(Config.TEST_TYPE_DEFAULT, Config.TEST_TYPE_UNIT, "go")):
-    AddEntry("Go unit tests",
-             [os.path.join(build_dir, "obj", "mojo", "go", "system_test")])
-
-  # Python unit tests:
-  if ShouldRunTest(Config.TEST_TYPE_DEFAULT, Config.TEST_TYPE_UNIT, "python"):
-    AddEntry("Python unit tests",
-             ["python", os.path.join("mojo", "tools",
-              "run_mojo_python_tests.py")])
-
-  # Python bindings tests (Linux-only):
-  # See http://crbug.com/438781 for details on asan exclusion.
-  if (target_os == Config.OS_LINUX and
-      ShouldRunTest(Config.TEST_TYPE_DEFAULT, Config.TEST_TYPE_UNIT,
-                    "python") and
-      config.sanitizer != Config.SANITIZER_ASAN):
-    AddEntry("Python bindings tests",
-             ["python",
-              os.path.join("mojo", "tools",
-                           "run_mojo_python_bindings_tests.py"),
-              "--build-dir=" + build_dir])
-
-  # Sky tests (Linux-only):
-  # TODO(abarth): Re-enabled in ASAN once the DartVM works in ASAN.
-  # See https://code.google.com/p/dart/issues/detail?id=22122
-  if (target_os == Config.OS_LINUX and
-      ShouldRunTest(Config.TEST_TYPE_DEFAULT, "sky") and
-      config.sanitizer != Config.SANITIZER_ASAN):
-    sky_command = ["python",
-                   "sky/tools/test_sky",
-                   "-t", os.path.basename(build_dir),
-                   "--no-new-test-results", "--no-show-results", "--verbose"]
-    if config.values.get("builder_name"):
-      sky_command += ["--builder-name", config.values["builder_name"]]
-    if config.values.get("build_number"):
-      sky_command += ["--build-number", config.values["build_number"]]
-    if config.values.get("master_name"):
-      sky_command += ["--master-name", config.values["master_name"]]
-    if config.values.get("test_results_server"):
-      sky_command += ["--test-results-server",
-                      config.values["test_results_server"]]
-    AddXvfbEntry("Sky tests", sky_command)
-
-  # Observatory tests (Linux-only):
-  if target_os == Config.OS_LINUX:
-    AddEntry("Dart Observatory tests",
-             ["python",
-              os.path.join("mojo", "dart", "observatory_tester", "runner.py"),
-              "--build-dir=" + build_dir,
-              "--dart-exe=third_party/dart-sdk/dart-sdk/bin/dart"])
-
-    AddEntry("Dart HTTP Load test",
-           ["python",
-            os.path.join("mojo", "dart", "http_load_test", "runner.py"),
-            "--build-dir=" + build_dir,
-            "--dart-exe=third_party/dart-sdk/dart-sdk/bin/dart"])
-
-  # mojo tools unit tests:
-  if ShouldRunTest(Config.TEST_TYPE_DEFAULT, Config.TEST_TYPE_UNIT, "tools"):
-    AddEntry("Mojo tools unit tests",
-             ["python", os.path.join("mojo", "tools", "testing",
-                                     "mojom_fetcher",
-                                     "mojom_fetcher_tests.py")])
-
-  # Dart mojom package generate.dart script tests:
-  if target_os == Config.OS_LINUX:
-    AddEntry("Dart mojom package generate tests",
-        [os.path.join("third_party", "dart-sdk", "dart-sdk", "bin", "dart"),
-         "--checked",
-         "-p", os.path.join("mojo", "dart", "mojom", "packages"),
-         os.path.join("mojo", "dart", "mojom", "test", "generate_test.dart")])
-
-  # Perf tests -----------------------------------------------------------------
-
-  if target_os == Config.OS_LINUX and ShouldRunTest(Config.TEST_TYPE_PERF):
-    perf_id = "linux_%s" % ("debug" if config.is_debug else "release")
-    test_names = ["mojo_public_system_perftests",
-                  "mojo_public_bindings_perftests"]
-
-    for test_name in test_names:
-      command = ["python",
-                 os.path.join("mojo", "tools", "perf_test_runner.py"),
-                 "--perf-id", perf_id,
-                 "--test-name", test_name,
-                 "--perf-data-path",
-                 os.path.join(build_dir, test_name + "_perf.log"),
-                 "--production-dashboard"]
-      if config.values.get("builder_name"):
-        command += ["--builder-name", config.values["builder_name"]]
-      if config.values.get("build_number"):
-        command += ["--build-number", config.values["build_number"]]
-      if config.values.get("master_name"):
-        command += ["--master-name", config.values["master_name"]]
-      command += [os.path.join(build_dir, test_name)]
-
-      AddEntry(test_name, command)
-
-  # Integration tests ----------------------------------------------------------
-
-  if target_os == Config.OS_ANDROID and ShouldRunTest(
-      Config.TEST_TYPE_DEFAULT, Config.TEST_TYPE_INTEGRATION):
-    AddEntry("Integration test (MojoTest)",
-             ["python",
-              os.path.join("build", "android", "test_runner.py"),
-              "instrumentation",
-              "--test-apk=MojoTest",
-              "--output-directory=%s" % build_dir,
-              "--test_data=bindings:mojo/public/interfaces/bindings/tests/data"]
-             + verbose_flags)
-
-  return test_list
-
-
-def main():
-  parser = argparse.ArgumentParser(description="Gets tests to execute.")
-  parser.add_argument("config_file", metavar="config.json",
-                      type=argparse.FileType("rb"),
-                      help="Input JSON file with test configuration.")
-  parser.add_argument("test_list_file", metavar="test_list.json", nargs="?",
-                      type=argparse.FileType("wb"), default=sys.stdout,
-                      help="Output JSON file with test list.")
-  args = parser.parse_args()
-
-  config = Config(**json.load(args.config_file))
-  test_list = GetTestList(config)
-  json.dump(test_list, args.test_list_file, indent=2)
-  args.test_list_file.write("\n")
-
-  return 0
-
-
-if __name__ == "__main__":
-  sys.exit(main())
diff --git a/mojo/tools/linux64/dump_syms.sha1 b/mojo/tools/linux64/dump_syms.sha1
deleted file mode 100644
index fd68948..0000000
--- a/mojo/tools/linux64/dump_syms.sha1
+++ /dev/null
@@ -1 +0,0 @@
-4bd8f841d0cebc3f7dac4c5bf2cdf86694605692
diff --git a/mojo/tools/linux64/symupload.sha1 b/mojo/tools/linux64/symupload.sha1
deleted file mode 100644
index d4563e4..0000000
--- a/mojo/tools/linux64/symupload.sha1
+++ /dev/null
@@ -1 +0,0 @@
-5d03513c81fba7f0acdc3ea314c46667d6624eb6
\ No newline at end of file
diff --git a/mojo/tools/message_generator.cc b/mojo/tools/message_generator.cc
deleted file mode 100644
index 08b7dccb..0000000
--- a/mojo/tools/message_generator.cc
+++ /dev/null
@@ -1,63 +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 "base/files/file_path.h"
-#include "base/files/file_util.h"
-#include "base/strings/string_util.h"
-#include "base/strings/stringprintf.h"
-#include "mojo/public/cpp/bindings/lib/message_builder.h"
-#include "mojo/public/cpp/bindings/lib/message_internal.h"
-#include "mojo/public/cpp/bindings/message.h"
-
-// This file is used to generate various files corresponding to mojo
-// messages. The various binding implementations can parse these to verify they
-// correctly decode messages.
-//
-// The output consists of each byte of the message encoded in a hex string with
-// a newline after it.
-namespace mojo {
-namespace {
-
-std::string BinaryToHex(const base::StringPiece& piece) {
-  std::string result("// File generated by mojo_message_generator.\n");;
-  result.reserve(result.size() + (piece.size() * 5));
-  for (size_t i = 0; i < piece.size(); ++i)
-    base::StringAppendF(&result, "0X%.2X\n", static_cast<int>(piece.data()[i]));
-  return result;
-}
-
-void WriteMessageToFile(const Message& message, const base::FilePath& path) {
-  const std::string hex_message(BinaryToHex(
-      base::StringPiece(reinterpret_cast<const char*>(message.data()),
-                        message.data_num_bytes())));
-  CHECK_EQ(static_cast<int>(hex_message.size()),
-           base::WriteFile(path, hex_message.data(),
-                           static_cast<int>(hex_message.size())));
-}
-
-// Generates a message of type MessageData. The message uses the name 21,
-// with 4 bytes of payload: 0x9, 0x8, 0x7, 0x6.
-void GenerateMessageDataMessage() {
-  internal::MessageBuilder builder(static_cast<uint32_t>(21),
-                                   static_cast<size_t>(4));
-  char* data = static_cast<char*>(builder.buffer()->Allocate(4));
-  DCHECK(data);
-  data[0] = 9;
-  data[1] = 8;
-  data[2] = 7;
-  data[3] = 6;
-
-  Message message;
-  builder.Finish(&message);
-  WriteMessageToFile(message,
-                     base::FilePath(FILE_PATH_LITERAL("message_data")));
-}
-
-}  // namespace
-}  // namespace mojo
-
-int main(int argc, char** argv) {
-  mojo::GenerateMessageDataMessage();
-  return 0;
-}
diff --git a/mojo/tools/mojob.py b/mojo/tools/mojob.py
deleted file mode 100755
index e7bda93..0000000
--- a/mojo/tools/mojob.py
+++ /dev/null
@@ -1,318 +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.
-
-"""A simple script to make building/testing Mojo components easier."""
-
-import argparse
-from copy import deepcopy
-import logging
-from multiprocessing import cpu_count
-import os
-import subprocess
-import sys
-
-from get_test_list import GetTestList
-from mopy.config import Config
-from mopy.paths import Paths
-from mopy.gn import GNArgsForConfig, ParseGNConfig, CommandLineForGNArgs
-from mopy.log import InitLogging
-
-
-_logger = logging.getLogger()
-_verbose_count = 0
-
-
-def _args_to_config(args):
-  # Default to host OS.
-  target_os = None
-  if args.android:
-    target_os = Config.OS_ANDROID
-  elif args.ios:
-    target_os = Config.OS_IOS
-
-  target_cpu = args.target_cpu
-
-  additional_args = {}
-
-  if 'clang' in args:
-    additional_args['is_clang'] = args.clang
-
-  if 'asan' in args and args.asan:
-    additional_args['sanitizer'] = Config.SANITIZER_ASAN
-
-  # Additional non-standard config entries:
-
-  if 'goma' in args:
-    goma_dir = os.environ.get('GOMA_DIR')
-    goma_home_dir = os.path.join(os.getenv('HOME', ''), 'goma')
-    if args.goma and goma_dir:
-      additional_args['use_goma'] = True
-      additional_args['goma_dir'] = goma_dir
-    elif args.goma and os.path.exists(goma_home_dir):
-      additional_args['use_goma'] = True
-      additional_args['goma_dir'] = goma_home_dir
-    else:
-      additional_args['use_goma'] = False
-      additional_args['goma_dir'] = None
-
-  if 'nacl' in args:
-    additional_args['use_nacl'] = args.nacl
-
-  if not ('asan' in args and args.asan):
-    go_dir = os.path.join(Paths().src_root, 'third_party', 'go', 'tool')
-    if args.android:
-      additional_args['mojo_use_go'] = True
-      additional_args['go_build_tool'] = os.path.join(
-          go_dir, 'android_arm', 'bin', 'go')
-    elif target_os is None and Config.GetHostOS() == Config.OS_LINUX:
-      additional_args['mojo_use_go'] = True
-      additional_args['go_build_tool'] = os.path.join(
-          go_dir, 'linux_amd64', 'bin', 'go')
-
-  if 'dry_run' in args:
-    additional_args['dry_run'] = args.dry_run
-
-  if 'builder_name' in args:
-    additional_args['builder_name'] = args.builder_name
-  if 'build_number' in args:
-    additional_args['build_number'] = args.build_number
-  if 'master_name' in args:
-    additional_args['master_name'] = args.master_name
-  if 'test_results_server' in args:
-    additional_args['test_results_server'] = args.test_results_server
-
-  if 'gn_args' in args:
-    additional_args['gn_args'] = args.gn_args
-
-  is_debug = args.debug and not args.official
-
-  return Config(target_os=target_os, target_cpu=target_cpu,
-                is_debug=is_debug, is_official_build=args.official,
-                dcheck_always_on=args.dcheck_always_on,
-                is_simulator=args.simulator, **additional_args)
-
-
-def _get_out_dir(config):
-  """Gets the build output directory (e.g., out/Debug), relative to src, for the
-  given config."""
-
-  paths = Paths(config)
-  return paths.SrcRelPath(paths.build_dir)
-
-
-def _sync(config):  # pylint: disable=W0613
-  """Runs gclient sync for the given config."""
-
-  _logger.debug('_sync()')
-  return subprocess.call(['gclient', 'sync'])
-
-
-def _gn(config):
-  """Runs gn gen for the given config."""
-
-  _logger.debug('_gn()')
-
-  command = ['gn', 'gen', '--check']
-
-  gn_args = CommandLineForGNArgs(GNArgsForConfig(config))
-  out_dir = _get_out_dir(config)
-  command.append(out_dir)
-  command.append('--args=%s' % ' '.join(gn_args))
-
-  print 'Running %s %s ...' % (command[0],
-                               ' '.join('\'%s\'' % x for x in command[1:]))
-  return subprocess.call(command)
-
-
-def _build(config):
-  """Builds for the given config."""
-
-  _logger.debug('_build()')
-
-  out_dir = _get_out_dir(config)
-  gn_args = ParseGNConfig(out_dir)
-  print 'Building in %s ...' % out_dir
-  if gn_args.get('use_goma'):
-    # Use the configured goma directory.
-    local_goma_dir = gn_args.get('goma_dir')
-    print 'Ensuring goma (in %s) started ...' % local_goma_dir
-    command = ['python',
-               os.path.join(local_goma_dir, 'goma_ctl.py'),
-               'ensure_start']
-    exit_code = subprocess.call(command)
-    if exit_code:
-      return exit_code
-
-    # Goma allows us to run many more jobs in parallel, say 32 per core/thread
-    # (= 1024 on a 16-core, 32-thread Z620). Limit the load average to 4 per
-    # core/thread (= 128 on said Z620).
-    jobs = cpu_count() * 32
-    limit = cpu_count() * 4
-    return subprocess.call(['ninja', '-j', str(jobs), '-l', str(limit),
-                            '-C', out_dir])
-  else:
-    return subprocess.call(['ninja', '-C', out_dir])
-
-
-def _run_tests(config, test_types):
-  """Runs the tests of the given type(s) for the given config."""
-
-  assert isinstance(test_types, list)
-  config = deepcopy(config)
-  config.values['test_types'] = test_types
-
-  test_list = GetTestList(config, verbose_count=_verbose_count)
-  dry_run = config.values.get('dry_run')
-  final_exit_code = 0
-  failure_list = []
-  for entry in test_list:
-    print 'Running: %s' % entry['name']
-    print 'Command: %s' % ' '.join(entry['command'])
-    if dry_run:
-      continue
-
-    _logger.info('Starting: %s' % ' '.join(entry['command']))
-    exit_code = subprocess.call(entry['command'])
-    _logger.info('Completed: %s' % ' '.join(entry['command']))
-    if exit_code:
-      if not final_exit_code:
-        final_exit_code = exit_code
-      failure_list.append(entry['name'])
-
-  print 72 * '='
-  print 'SUMMARY:',
-  if dry_run:
-    print 'Dry run: no tests run'
-  elif not failure_list:
-    assert not final_exit_code
-    print 'All tests passed'
-  else:
-    assert final_exit_code
-    print 'The following had failures:', ', '.join(failure_list)
-
-  return final_exit_code
-
-
-def _test(config):
-  _logger.debug('_test()')
-  return _run_tests(config, [Config.TEST_TYPE_DEFAULT])
-
-
-def _perftest(config):
-  _logger.debug('_perftest()')
-  return _run_tests(config, [Config.TEST_TYPE_PERF])
-
-
-def _pytest(config):
-  _logger.debug('_pytest()')
-  return _run_tests(config, ['python'])
-
-
-def main():
-  os.chdir(Paths().src_root)
-
-  parser = argparse.ArgumentParser(description='A script to make building'
-      '/testing Mojo components easier.')
-
-  parent_parser = argparse.ArgumentParser(add_help=False)
-
-  parent_parser.add_argument('--verbose',
-                             help='Be verbose (multiple times for more)',
-                             default=0, dest='verbose_count', action='count')
-
-  parent_parser.add_argument('--asan', help='Use Address Sanitizer',
-                             action='store_true')
-  parent_parser.add_argument('--dcheck_always_on',
-                             help='DCHECK and MOJO_DCHECK are fatal even in '
-                             'release builds',
-                             action='store_true')
-
-  debug_group = parent_parser.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')
-  # The official build is a release build suitable for distribution, with a
-  # different package name.
-  debug_group.add_argument('--official', help='Official build', default=False,
-                           dest='official', action='store_true')
-
-  os_group = parent_parser.add_mutually_exclusive_group()
-  os_group.add_argument('--android', help='Build for Android',
-                        action='store_true')
-  os_group.add_argument('--ios', help='Build for iOS',
-                        action='store_true')
-
-  parent_parser.add_argument('--simulator',
-                             help='Build for a simulator of the target',
-                             action='store_true')
-
-  parent_parser.add_argument('--target-cpu',
-                             help='CPU architecture to build for.',
-                             choices=['x64', 'x86', 'arm'])
-
-  subparsers = parser.add_subparsers()
-
-  sync_parser = subparsers.add_parser('sync', parents=[parent_parser],
-      help='Sync using gclient (does not run gn).')
-  sync_parser.set_defaults(func=_sync)
-
-  gn_parser = subparsers.add_parser('gn', parents=[parent_parser],
-                                    help='Run gn for mojo (does not sync).')
-  gn_parser.set_defaults(func=_gn)
-  gn_parser.add_argument('--args', help='Specify extra args',
-                         default=None, dest='gn_args')
-  # Note: no default, if nothing is specified on the command line GN decides.
-  gn_parser.add_argument('--nacl', help='Add in NaCl', action='store_true',
-                         default=argparse.SUPPRESS)
-  gn_parser.add_argument('--no-nacl', help='Remove NaCl', action='store_false',
-                         default=argparse.SUPPRESS, dest='nacl')
-
-  clang_group = gn_parser.add_mutually_exclusive_group()
-  clang_group.add_argument('--clang', help='Use Clang (default)', default=None,
-                           action='store_true')
-  clang_group.add_argument('--gcc', help='Use GCC',
-                           dest='clang', action='store_false')
-  goma_group = gn_parser.add_mutually_exclusive_group()
-  goma_group.add_argument('--goma',
-                          help='Use Goma (if $GOMA_DIR is set or $HOME/goma '
-                               'exists; default)',
-                          default=True,
-                          action='store_true')
-  goma_group.add_argument('--no-goma', help='Don\'t use Goma', default=False,
-                          dest='goma', action='store_false')
-
-  build_parser = subparsers.add_parser('build', parents=[parent_parser],
-                                       help='Build')
-  build_parser.set_defaults(func=_build)
-
-  test_parser = subparsers.add_parser('test', parents=[parent_parser],
-                                      help='Run unit tests (does not build).')
-  test_parser.set_defaults(func=_test)
-  test_parser.add_argument('--dry-run',
-                           help='Print instead of executing commands',
-                           default=False, action='store_true')
-
-  perftest_parser = subparsers.add_parser('perftest', parents=[parent_parser],
-      help='Run perf tests (does not build).')
-  perftest_parser.set_defaults(func=_perftest)
-
-  pytest_parser = subparsers.add_parser('pytest', parents=[parent_parser],
-      help='Run Python unit tests (does not build).')
-  pytest_parser.set_defaults(func=_pytest)
-
-  args = parser.parse_args()
-  global _verbose_count
-  _verbose_count = args.verbose_count
-  InitLogging(_verbose_count)
-
-  if args.simulator and not args.ios:
-    sys.exit("Currently, the simulator target is only configured for iOS")
-
-  return args.func(_args_to_config(args))
-
-
-if __name__ == '__main__':
-  sys.exit(main())
diff --git a/mojo/tools/mopy/__init__.py b/mojo/tools/mopy/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/mojo/tools/mopy/__init__.py
+++ /dev/null
diff --git a/mojo/tools/mopy/config.py b/mojo/tools/mopy/config.py
deleted file mode 100644
index a0df490..0000000
--- a/mojo/tools/mopy/config.py
+++ /dev/null
@@ -1,148 +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.
-
-"""Build/test configurations, which are just dictionaries. This
-"defines" the schema and provides some wrappers."""
-
-
-import platform
-import sys
-
-
-class Config(object):
-  """A Config is basically just a wrapper around a dictionary that species a
-  build/test configuration. The dictionary is accessible through the values
-  member."""
-
-  # Valid values for target_os (None is also valid):
-  OS_ANDROID = "android"
-  OS_IOS = "ios"
-  OS_LINUX = "linux"
-  OS_MAC = "mac"
-  OS_WINDOWS = "windows"
-
-  # Valid values for target_cpu (None is also valid):
-  ARCH_X86 = "x86"
-  ARCH_X64 = "x64"
-  ARCH_ARM = "arm"
-
-  # Valid values for sanitizer (None is also valid):
-  SANITIZER_ASAN = "asan"
-
-  # Standard values for test types (test types are arbitrary strings; other
-  # values are allowed).
-  TEST_TYPE_DEFAULT = "default"
-  TEST_TYPE_UNIT = "unit"
-  TEST_TYPE_PERF = "perf"
-  TEST_TYPE_INTEGRATION = "integration"
-
-  def __init__(self, target_os=None, target_cpu=None, is_debug=True,
-               is_clang=None, sanitizer=None, dcheck_always_on=False,
-               is_simulator=False, is_official_build=False, **kwargs):
-    """Constructs a Config with key-value pairs specified via keyword arguments.
-    If target_os is not specified, it will be set to the host OS."""
-
-    assert target_os in (None, Config.OS_ANDROID, Config.OS_IOS,
-                         Config.OS_LINUX, Config.OS_MAC,
-                         Config.OS_WINDOWS)
-    assert target_cpu in (None, Config.ARCH_X86, Config.ARCH_X64,
-                           Config.ARCH_ARM)
-    assert isinstance(is_debug, bool)
-    assert isinstance(is_official_build, bool)
-    assert is_clang is None or isinstance(is_clang, bool)
-    assert sanitizer in (None, Config.SANITIZER_ASAN)
-    if "test_types" in kwargs:
-      assert isinstance(kwargs["test_types"], list)
-
-    self.values = {}
-    self.values["target_os"] = (self.GetHostOS() if target_os is None else
-                                target_os)
-
-    if target_cpu is None:
-      if target_os == Config.OS_ANDROID:
-        target_cpu = Config.ARCH_ARM
-      elif target_os == Config.OS_IOS:
-        target_cpu = Config.ARCH_X64 if is_simulator else Config.ARCH_ARM
-      else:
-        target_cpu = self.GetHostCPUArch()
-
-    self.values["target_cpu"] = target_cpu
-    self.values["is_simulator"] = is_simulator
-    self.values["is_debug"] = is_debug
-    self.values["is_official_build"] = is_official_build
-    self.values["is_clang"] = is_clang
-    self.values["sanitizer"] = sanitizer
-    self.values["dcheck_always_on"] = dcheck_always_on
-
-    self.values.update(kwargs)
-
-  @staticmethod
-  def GetHostOS():
-    if sys.platform == "linux2":
-      return Config.OS_LINUX
-    if sys.platform == "darwin":
-      return Config.OS_MAC
-    if sys.platform == "win32":
-      return Config.OS_WINDOWS
-    raise NotImplementedError("Unsupported host OS")
-
-  @staticmethod
-  def GetHostCPUArch():
-    # Derived from //native_client/pynacl/platform.py
-    machine = platform.machine()
-    if machine in ("x86", "x86-32", "x86_32", "x8632", "i386", "i686", "ia32",
-                   "32"):
-      return Config.ARCH_X86
-    if machine in ("x86-64", "amd64", "x86_64", "x8664", "64"):
-      return Config.ARCH_X64
-    if machine.startswith("arm"):
-      return Config.ARCH_ARM
-    raise Exception("Cannot identify CPU arch: %s" % machine)
-
-  # Getters for standard fields ------------------------------------------------
-
-  @property
-  def target_os(self):
-    """OS of the build/test target."""
-    return self.values["target_os"]
-
-  @property
-  def target_cpu(self):
-    """CPU arch of the build/test target."""
-    return self.values["target_cpu"]
-
-  @property
-  def is_simulator(self):
-    """Is a simulator build?"""
-    return self.values["is_simulator"]
-
-  @property
-  def is_debug(self):
-    """Is Debug build?"""
-    return self.values["is_debug"]
-
-  @property
-  def is_official_build(self):
-    """Is Official build?"""
-    return self.values["is_official_build"]
-
-  @property
-  def dcheck_always_on(self):
-    """DCHECK and MOJO_DCHECK are fatal even in release builds"""
-    return self.values["dcheck_always_on"]
-
-  @property
-  def is_clang(self):
-    """Should use clang?"""
-    return self.values["is_clang"]
-
-  @property
-  def sanitizer(self):
-    """Sanitizer to use, if any."""
-    return self.values["sanitizer"]
-
-  @property
-  def test_types(self):
-    """List of test types to run."""
-    return self.values.get("test_types", [Config.TEST_TYPE_DEFAULT])
diff --git a/mojo/tools/mopy/file_hash.py b/mojo/tools/mopy/file_hash.py
deleted file mode 100644
index abdd821..0000000
--- a/mojo/tools/mopy/file_hash.py
+++ /dev/null
@@ -1,26 +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 logging
-
-# pylint: disable=E0611
-from hashlib import sha256
-
-from mopy.memoize import memoize
-
-_logging = logging.getLogger()
-
-@memoize
-def file_hash(filename):
-  """Returns a string representing the hash of the given file."""
-  _logging.debug("Hashing %s ...", filename)
-  with open(filename, mode='rb') as f:
-    m = sha256()
-    while True:
-      block = f.read(4096)
-      if not block:
-        break
-      m.update(block)
-  _logging.debug("  => %s", m.hexdigest())
-  return m.hexdigest()
diff --git a/mojo/tools/mopy/gn.py b/mojo/tools/mopy/gn.py
deleted file mode 100644
index 47253ea..0000000
--- a/mojo/tools/mopy/gn.py
+++ /dev/null
@@ -1,157 +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.
-
-"""
-GN-related configuration functions, e.g., to produce a Config object from a GN
-args.gn file).
-"""
-
-
-import ast
-import os.path
-import re
-
-from .config import Config
-
-
-def BuildDirectoryForConfig(config, src_root):
-  """
-  Returns the build directory for the given configuration.
-  """
-  subdir = ""
-  if config.target_os == Config.OS_ANDROID:
-    subdir += "android_"
-    if config.target_cpu != Config.ARCH_ARM:
-      subdir += config.target_cpu + "_"
-  elif config.target_os == Config.OS_IOS:
-    subdir += "ios_"
-  if config.is_simulator:
-    subdir += "sim_"
-  if config.is_official_build:
-    subdir += "Official"
-  elif config.is_debug:
-    subdir += "Debug"
-  else:
-    subdir += "Release"
-  if config.sanitizer == Config.SANITIZER_ASAN:
-    subdir += "_asan"
-  if not(config.is_debug) and config.dcheck_always_on:
-    subdir += "_dcheck"
-  return os.path.join(src_root, "out", subdir)
-
-
-def GNArgsForConfig(config):
-  """
-  Return the arguments for gn for the given configuration. This function returns
-  a dictionary with boolean values as boolean.
-  """
-  gn_args = {}
-
-  gn_args["is_debug"] = bool(config.is_debug)
-  gn_args["is_official_build"] = bool(config.is_official_build)
-  gn_args["is_asan"] = config.sanitizer == Config.SANITIZER_ASAN
-
-  if config.is_clang is not None:
-    gn_args["is_clang"] = bool(config.is_clang)
-  else:
-    gn_args["is_clang"] = config.target_os not in (Config.OS_ANDROID,
-                                                   Config.OS_WINDOWS)
-
-  if config.values.get("use_goma"):
-    gn_args["use_goma"] = True
-    gn_args["goma_dir"] = config.values["goma_dir"]
-  else:
-    gn_args["use_goma"] = False
-
-  gn_args["dcheck_always_on"] = config.dcheck_always_on
-
-  if config.target_os == Config.OS_ANDROID:
-    gn_args["target_os"] = "android"
-  elif config.target_os == Config.OS_IOS:
-    gn_args["target_os"] = "ios"
-    gn_args["ios_deployment_target"] = "7.0"
-    gn_args["clang_use_chrome_plugins"] = False
-    if config.is_simulator:
-      gn_args["use_libjpeg_turbo"] = False
-    gn_args["use_ios_simulator"] = config.is_simulator
-  elif config.target_os == Config.OS_LINUX:
-    gn_args["use_aura"] = False
-    gn_args["use_glib"] = False
-    gn_args["use_system_harfbuzz"] = False
-
-  gn_args["target_cpu"] = config.target_cpu
-
-  if "use_nacl" in config.values:
-    gn_args["mojo_use_nacl"] = config.values.get("use_nacl", False)
-
-  if "mojo_use_go" in config.values:
-    gn_args["mojo_use_go"] = config.values.get("mojo_use_go", False)
-    if gn_args["mojo_use_go"]:
-      gn_args["go_build_tool"] = config.values.get("go_build_tool")
-
-  extra_args = config.values.get("gn_args")
-  if extra_args:
-    for arg in extra_args.split():
-      (name, val) = arg.split('=')
-      gn_args[name] = val
-
-  return gn_args
-
-
-def CommandLineForGNArgs(gn_args):
-  """
-  Returns the list of gn arguments to use with the gn command line.
-  """
-  def _ToCommandLine(key, value):
-    if type(value) is bool:
-      return "%s=%s" % (key, "true" if value else "false")
-    return "%s=\"%s\"" % (key, value)
-  return [_ToCommandLine(x, y) for x, y in gn_args.iteritems()]
-
-
-def ConfigForGNArgs(args):
-  """
-  Return the Config object for the given gn arguments. This function takes a
-  dictionary with boolean values as boolean.
-  """
-  config_args = {}
-  config_args["is_debug"] = args.get("is_debug", True)
-  config_args["is_official_build"] = args.get("is_official_build", False)
-  config_args["sanitizer"] = (
-      Config.SANITIZER_ASAN if args.get("is_asan") else None)
-  config_args["is_clang"] = args.get("is_clang", False)
-  config_args["use_goma"] = args.get("use_goma", False)
-  if config_args["use_goma"]:
-    config_args["goma_dir"] = args.get("goma_dir")
-  config_args["use_nacl"] = args.get("mojo_use_nacl", False)
-  config_args["mojo_use_go"] = args.get("mojo_use_go", False)
-  if config_args["mojo_use_go"]:
-    config_args["go_build_tool"] = args.get("go_build_tool")
-  config_args["target_os"] = args.get("target_os")
-  config_args["target_cpu"] = args.get("target_cpu")
-  config_args["dcheck_always_on"] = args.get("dcheck_always_on")
-  config_args["is_simulator"] = args.get("use_ios_simulator", False)
-  return Config(**config_args)
-
-
-def ParseGNConfig(build_dir):
-  """
-  Parse the gn config file present in |build_dir|. This function returns a
-  dictionary with boolean values as boolean.
-  """
-  TRANSLATIONS = {
-      "true": "True",
-      "false": "False",
-  }
-  gn_file = os.path.join(build_dir, "args.gn")
-  values = {}
-  with open(gn_file, "r") as f:
-    for line in f.readlines():
-      line = re.sub("\s*#.*", "", line)
-      result = re.match("^\s*(\w+)\s*=\s*(.*)\s*$", line)
-      if result:
-        key = result.group(1)
-        value = result.group(2)
-        values[key] = ast.literal_eval(TRANSLATIONS.get(value, value))
-  return values
diff --git a/mojo/tools/mopy/gn_unittest.py b/mojo/tools/mopy/gn_unittest.py
deleted file mode 100644
index b1b29a7..0000000
--- a/mojo/tools/mopy/gn_unittest.py
+++ /dev/null
@@ -1,76 +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 itertools
-import sys
-import unittest
-
-import mopy.gn as gn
-
-from mopy.config import Config
-
-
-class GTestListTestsTest(unittest.TestCase):
-  """Tests mopy.gn."""
-
-  def testConfigToGNToConfig(self):
-    """Tests that config to gn to config is the identity"""
-    configs_to_test = {
-      "target_os": [None, "android", "linux", "ios"],
-      "target_cpu": [None, "x86", "x64", "arm"],
-      "is_simulator": [False, True],
-      "is_debug": [False, True],
-      "is_official_build": [False, True],
-      "is_clang": [False, True],
-      "sanitizer": [None, Config.SANITIZER_ASAN],
-      "use_goma": [False],
-      "use_nacl": [False, True],
-      "mojo_use_go": [False],
-      "dcheck_always_on": [False, True],
-    }
-    if sys.platform == "darwin":
-      configs_to_test["target_os"].remove("linux")
-
-    for args in _iterate_over_config(configs_to_test):
-      if args.get("target_os") != "ios" and args["is_simulator"]:
-        continue
-      config = Config(**args)
-      gn_args = gn.GNArgsForConfig(config)
-      new_config = gn.ConfigForGNArgs(gn_args)
-      self.assertDictEqual(config.values, new_config.values)
-
-  def testGNToConfigToGN(self):
-    """Tests that gn to config to gn is the identity"""
-    # TODO(vtl): Test OSes other than None (== host?) and "android".
-    configs_to_test = {
-      "target_os": [None, "android"],
-      "target_cpu": ["x86", "x64", "arm"],
-      "is_debug": [False, True],
-      "is_official_build": [False, True],
-      "is_clang": [False, True],
-      "is_asan": [False, True],
-      "use_goma": [False],
-      "mojo_use_nacl": [False, True],
-      "mojo_use_go": [False],
-      "dcheck_always_on": [False, True],
-    }
-
-    for args in _iterate_over_config(configs_to_test):
-      if args.get("target_os", None) is None and sys.platform[:5] == "linux":
-        args["use_aura"] = False
-        args["use_glib"] = False
-        args["use_system_harfbuzz"] = False
-      config = gn.ConfigForGNArgs(args)
-      new_args = gn.GNArgsForConfig(config)
-      self.assertDictEqual(args, new_args)
-
-
-def _iterate_over_config(config):
-  def product_to_dict(p):
-    return dict(filter(lambda x: x[1] is not None, zip(config.keys(), p)))
-  return itertools.imap(product_to_dict, itertools.product(*config.values()))
-
-
-if __name__ == "__main__":
-  unittest.main()
diff --git a/mojo/tools/mopy/gtest.py b/mojo/tools/mopy/gtest.py
deleted file mode 100644
index e557937..0000000
--- a/mojo/tools/mopy/gtest.py
+++ /dev/null
@@ -1,17 +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 os
-import sys
-import logging
-
-_logger = logging.getLogger()
-
-
-def set_color():
-  """Run gtests with color if we're on a TTY (and we're not being told
-  explicitly what to do)."""
-  if sys.stdout.isatty() and "GTEST_COLOR" not in os.environ:
-    _logger.debug("Setting GTEST_COLOR=yes")
-    os.environ["GTEST_COLOR"] = "yes"
diff --git a/mojo/tools/mopy/log.py b/mojo/tools/mopy/log.py
deleted file mode 100644
index af57232..0000000
--- a/mojo/tools/mopy/log.py
+++ /dev/null
@@ -1,29 +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.
-
-"""Logging utilities, for use with the standard logging module."""
-
-
-import logging
-
-
-def InitLogging(verbose_count):
-  """Ensures that the logger (obtained via logging.getLogger(), as usual) is
-  initialized, with the log level set as appropriate for |verbose_count|
-  instances of --verbose on the command line."""
-
-  assert(verbose_count >= 0)
-  if verbose_count == 0:
-    level = logging.WARNING
-  elif verbose_count == 1:
-    level = logging.INFO
-  else:  # verbose_count >= 2
-    level = logging.DEBUG
-
-  logging.basicConfig(format="%(relativeCreated).3f:%(levelname)s:%(message)s")
-  logger = logging.getLogger()
-  logger.setLevel(level)
-
-  logger.debug("Initialized logging: verbose_count=%d, level=%d" %
-               (verbose_count, level))
diff --git a/mojo/tools/mopy/memoize.py b/mojo/tools/mopy/memoize.py
deleted file mode 100644
index 765b8a9..0000000
--- a/mojo/tools/mopy/memoize.py
+++ /dev/null
@@ -1,17 +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.
-
-
-# pylint: disable=C0301
-# Based on/taken from
-#   http://code.activestate.com/recipes/578231-probably-the-fastest-memoization-decorator-in-the-/
-# (with cosmetic changes).
-# pylint: enable=C0301
-def memoize(f):
-  """Memoization decorator for a function taking a single argument."""
-  class Memoize(dict):
-    def __missing__(self, key):
-      rv = self[key] = f(key)
-      return rv
-  return Memoize().__getitem__
diff --git a/mojo/tools/mopy/mojo_python_tests_runner.py b/mojo/tools/mopy/mojo_python_tests_runner.py
deleted file mode 100644
index ef9a6b2..0000000
--- a/mojo/tools/mopy/mojo_python_tests_runner.py
+++ /dev/null
@@ -1,52 +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 argparse
-import os
-import sys
-import unittest
-
-import mopy.paths
-
-
-class MojoPythonTestRunner(object):
-  """Helper class to run python tests on the bots."""
-
-  def __init__(self, test_dir):
-    self._test_dir = test_dir
-
-  def run(self):
-    parser = argparse.ArgumentParser()
-    parser.add_argument('-v', '--verbose', action='count', default=0)
-    parser.add_argument('tests', nargs='*')
-
-    self.add_custom_commandline_options(parser)
-    args = parser.parse_args()
-    self.apply_customization(args)
-
-    loader = unittest.loader.TestLoader()
-    print "Running Python unit tests under %s..." % self._test_dir
-
-    src_root = mopy.paths.Paths().src_root
-    pylib_dir = os.path.abspath(os.path.join(src_root, self._test_dir))
-    if args.tests:
-      if pylib_dir not in sys.path:
-        sys.path.append(pylib_dir)
-      suite = unittest.TestSuite()
-      for test_name in args.tests:
-        suite.addTests(loader.loadTestsFromName(test_name))
-    else:
-      suite = loader.discover(pylib_dir, pattern='*_unittest.py')
-
-    runner = unittest.runner.TextTestRunner(verbosity=(args.verbose + 1))
-    result = runner.run(suite)
-    return 0 if result.wasSuccessful() else 1
-
-  def add_custom_commandline_options(self, parser):
-    """Allow to add custom option to the runner script."""
-    pass
-
-  def apply_customization(self, args):
-    """Allow to apply any customization to the runner."""
-    pass
diff --git a/mojo/tools/mopy/paths.py b/mojo/tools/mopy/paths.py
deleted file mode 100644
index 2ba8ec8..0000000
--- a/mojo/tools/mopy/paths.py
+++ /dev/null
@@ -1,77 +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 os
-
-from .config import Config
-from .gn import BuildDirectoryForConfig
-
-class Paths(object):
-  """Provides commonly used paths"""
-
-  def __init__(self, config=None, build_dir=None):
-    """Specify either a config or a build_dir to generate paths to binary
-    artifacts."""
-    self.src_root = os.path.abspath(os.path.join(__file__,
-      os.pardir, os.pardir, os.pardir, os.pardir))
-    self.mojo_dir = os.path.join(self.src_root, "mojo")
-    self.adb_path = os.path.join(self.src_root, 'third_party', 'android_tools',
-                                 'sdk', 'platform-tools', 'adb')
-
-    if config:
-      self.build_dir = BuildDirectoryForConfig(config, self.src_root)
-    elif build_dir is not None:
-      self.build_dir = os.path.abspath(build_dir)
-    else:
-      self.build_dir = None
-
-    if self.build_dir is not None:
-      self.mojo_shell_path = os.path.join(self.build_dir, "mojo_shell")
-      self.sky_shell_path = os.path.join(self.build_dir, "sky_shell")
-      # TODO(vtl): Use the host OS here, since |config| may not be available.
-      # In any case, if the target is Windows, but the host isn't, using
-      # |os.path| isn't correct....
-      if Config.GetHostOS() == Config.OS_WINDOWS:
-        self.mojo_shell_path += ".exe"
-        self.sky_shell_path += ".exe"
-      if config and config.target_os == Config.OS_ANDROID:
-        self.target_mojo_shell_path = os.path.join(self.build_dir,
-                                                   "apks",
-                                                   "MojoShell.apk")
-        self.target_sky_shell_path = os.path.join(self.build_dir,
-                                                  "apks",
-                                                  "SkyDemo.apk")
-      else:
-        self.target_mojo_shell_path = self.mojo_shell_path
-        self.target_sky_shell_path = self.sky_shell_path
-    else:
-      self.mojo_shell_path = None
-      self.sky_shell_path = None
-      self.target_mojo_shell_path = None
-      self.target_sky_shell_path = None
-
-  def RelPath(self, path):
-    """Returns the given path, relative to the current directory."""
-    return os.path.relpath(path)
-
-  def SrcRelPath(self, path):
-    """Returns the given path, relative to self.src_root."""
-    return os.path.relpath(path, self.src_root)
-
-  def FileFromUrl(self, url):
-    """Given an app URL (<scheme>:<appname>), return 'build_dir/appname.mojo'.
-    If self.build_dir is None, just return appname.mojo
-    """
-    (_, name) = url.split(':')
-    if self.build_dir:
-      return os.path.join(self.build_dir, name + '.mojo')
-    return name + '.mojo'
-
-  @staticmethod
-  def IsValidAppUrl(url):
-    """Returns False if url is malformed, True otherwise."""
-    try:
-      return len(url.split(':')) == 2
-    except ValueError:
-      return False
diff --git a/mojo/tools/mopy/perf_data_uploader.py b/mojo/tools/mopy/perf_data_uploader.py
deleted file mode 100755
index 84e5280..0000000
--- a/mojo/tools/mopy/perf_data_uploader.py
+++ /dev/null
@@ -1,200 +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.
-
-"""A tool that uploads data to the performance dashboard."""
-
-import argparse
-import httplib
-import json
-import pprint
-import re
-import sys
-import urllib
-import urllib2
-
-# TODO(yzshen): The following are missing currently:
-#     (1) CL range on the dashboard;
-#     (2) improvement direction on the dashboard;
-#     (3) a link from the build step pointing to the dashboard page.
-
-
-_PERF_LINE_FORMAT = r"""^\s*([^\s/]+)  # chart name
-                        (/([^\s/]+))?  # trace name (optional, separated with
-                                       # the chart name by a '/')
-                        \s+(\S+)       # value
-                        \s+(\S+)       # units
-                        \s*$"""
-
-_PRODUCTION_SERVER = "https://chromeperf.appspot.com"
-_TESTING_SERVER = "https://chrome-perf.googleplex.com"
-
-
-def UploadPerfData(master_name, perf_id, test_name, builder_name, build_number,
-                   revision, perf_data, point_id, dry_run=False,
-                   testing_dashboard=True):
-  """Uploads perf data.
-
-  Args:
-    Please see the help for command-line args.
-
-  Returns:
-    A boolean value indicating whether the operation succeeded or not.
-  """
-
-  def _ConvertToUploadFormat():
-    """Converts perf data to the format that the server understands.
-
-    Returns:
-      A dictionary that (after being converted to JSON) conforms to the server
-      format.
-    """
-    charts = {}
-    line_format = re.compile(_PERF_LINE_FORMAT, re.VERBOSE)
-    for line in perf_data:
-      match = re.match(line_format, line)
-      assert match, "Unable to parse the following input: %s" % line
-
-      chart_name = match.group(1)
-      trace_name = match.group(3) if match.group(3) else "summary"
-
-      if chart_name not in charts:
-        charts[chart_name] = {}
-      charts[chart_name][trace_name] = {
-          "type": "scalar",
-          "value": float(match.group(4)),
-          "units": match.group(5)
-      }
-
-    return {
-        "master": master_name,
-        "bot": perf_id,
-        "masterid": master_name,
-        "buildername": builder_name,
-        "buildnumber": build_number,
-        "versions": {
-            "mojo": revision
-        },
-        "point_id": point_id,
-        "supplemental": {},
-        "chart_data": {
-            "format_version": "1.0",
-            "benchmark_name": test_name,
-            "charts": charts
-        }
-    }
-
-  class _UploadException(Exception):
-    pass
-
-  def _Upload(server_url, json_data):
-    """Make an HTTP POST with the given data to the performance dashboard.
-
-    Args:
-      server_url: URL of the performance dashboard instance.
-      json_data: JSON string that contains the data to be sent.
-
-    Raises:
-      _UploadException: An error occurred during uploading.
-    """
-    # When data is provided to urllib2.Request, a POST is sent instead of GET.
-    # The data must be in the application/x-www-form-urlencoded format.
-    data = urllib.urlencode({"data": json_data})
-    req = urllib2.Request("%s/add_point" % server_url, data)
-    try:
-      urllib2.urlopen(req)
-    except urllib2.HTTPError as e:
-      raise _UploadException("HTTPError: %d. Response: %s\n"
-                             "JSON: %s\n" % (e.code, e.read(), json_data))
-    except urllib2.URLError as e:
-      raise _UploadException("URLError: %s for JSON %s\n" %
-                             (str(e.reason), json_data))
-    except httplib.HTTPException as e:
-      raise _UploadException("HTTPException for JSON %s\n" % json_data)
-
-  formatted_data = _ConvertToUploadFormat()
-
-  server_url = _TESTING_SERVER if testing_dashboard else _PRODUCTION_SERVER
-
-  if dry_run:
-    print "Won't upload because --dry-run is specified."
-    print "Server: %s" % server_url
-    print "Data:"
-    pprint.pprint(formatted_data)
-  else:
-    print "Uploading data to %s ..." % server_url
-    try:
-      _Upload(server_url, json.dumps(formatted_data))
-    except _UploadException as e:
-      print e
-      return False
-
-    print "Done."
-
-    dashboard_params = urllib.urlencode({
-        "masters": master_name,
-        "bots": perf_id,
-        "tests": test_name,
-        "rev": point_id
-    })
-    print "Results Dashboard: %s/report?%s" % (server_url, dashboard_params)
-
-  return True
-
-
-def main():
-  parser = argparse.ArgumentParser(
-      description="A tool that uploads data to the performance dashboard.")
-
-  parser.add_argument(
-      "--master-name", required=True,
-      help="Buildbot master name, used to construct link to buildbot log by "
-           "the dashboard, and also as the top-level category for the data.")
-  parser.add_argument(
-      "--perf-id", required=True,
-      help="Used as the second-level category for the data, usually the "
-           "platform type.")
-  parser.add_argument(
-      "--test-name", required=True,
-      help="Name of the test that the perf data was generated from.")
-  parser.add_argument(
-      "--builder-name", required=True,
-      help="Buildbot builder name, used to construct link to buildbot log by "
-           "the dashboard.")
-  parser.add_argument(
-      "--build-number", required=True, type=int,
-      help="Build number, used to construct link to buildbot log by the "
-           "dashboard.")
-  parser.add_argument(
-      "--revision", required=True, help="The mojo git commit hash.")
-  parser.add_argument(
-      "--perf-data", required=True, metavar="foo_perf.log",
-      type=argparse.FileType("r"),
-      help="A text file containing the perf data. Each line is a data point in "
-           "the following format: chart_name[/trace_name] value units")
-  parser.add_argument(
-      "--point-id", required=True, type=int,
-      help="The x coordinate for the data points.")
-  parser.add_argument(
-      "--dry-run", action="store_true",
-      help="Display the server URL and the data to upload, but not actually "
-           "upload the data.")
-  server_group = parser.add_mutually_exclusive_group()
-  server_group.add_argument(
-      "--testing-dashboard", action="store_true", default=True,
-      help="Upload the data to the testing dashboard (default).")
-  server_group.add_argument(
-      "--production-dashboard", dest="testing_dashboard", action="store_false",
-      default=False, help="Upload the data to the production dashboard.")
-  args = parser.parse_args()
-
-  result = UploadPerfData(args.master_name, args.perf_id, args.test_name,
-                          args.builder_name, args.build_number, args.revision,
-                          args.perf_data, args.point_id, args.dry_run,
-                          args.testing_dashboard)
-  return 0 if result else 1
-
-
-if __name__ == '__main__':
-  sys.exit(main())
diff --git a/mojo/tools/mopy/print_process_error.py b/mojo/tools/mopy/print_process_error.py
deleted file mode 100644
index ec565d1..0000000
--- a/mojo/tools/mopy/print_process_error.py
+++ /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.
-
-def print_process_error(command_line, error):
-  """Properly format an exception raised from a failed command execution."""
-
-  if command_line:
-    print 'Failed command: %r' % command_line
-  else:
-    print 'Failed command:'
-  print 72 * '-'
-
-  if hasattr(error, 'returncode'):
-    print '  with exit code %d' % error.returncode
-    print 72 * '-'
-
-  if hasattr(error, 'output'):
-    print error.output
-  else:
-    print error
-  print 72 * '-'
diff --git a/mojo/tools/mopy/transitive_hash.py b/mojo/tools/mopy/transitive_hash.py
deleted file mode 100644
index 740892b..0000000
--- a/mojo/tools/mopy/transitive_hash.py
+++ /dev/null
@@ -1,80 +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 logging
-import platform
-import subprocess
-import sys
-
-# pylint: disable=E0611
-from hashlib import sha256
-# pylint: enable=E0611
-from os.path import basename, realpath
-
-from mopy.file_hash import file_hash
-from mopy.memoize import memoize
-
-_logging = logging.getLogger()
-
-@memoize
-def _get_dependencies(filename):
-  """Returns a list of filenames for files that the given file depends on."""
-  if platform.system() == 'Windows':
-    # There's no ldd on Windows. We can try to bundle or require depends, but
-    # given that we're not supporting component build this seems low priority.
-    return []
-  _logging.debug("Getting dependencies for %s ...", filename)
-  lines = subprocess.check_output(['ldd', filename]).splitlines()
-  rv = []
-  for line in lines:
-    i = line.find('/')
-    if i < 0:
-      _logging.debug("  => no file found in line: %s", line)
-      continue
-    rv.append(line[i:].split(None, 1)[0])
-  _logging.debug("  => %s", rv)
-  return rv
-
-def transitive_hash(filename):
-  """Returns a string that represents the "transitive" hash of the given
-  file. The transitive hash is a hash of the file and all the shared libraries
-  on which it depends (done in an order-independent way)."""
-  hashes = set()
-  to_hash = [filename]
-  while to_hash:
-    current_filename = realpath(to_hash.pop())
-    current_hash = file_hash(current_filename)
-    if current_hash in hashes:
-      _logging.debug("Already seen %s (%s) ...", current_filename, current_hash)
-      continue
-    _logging.debug("Haven't seen %s (%s) ...", current_filename, current_hash)
-    hashes.add(current_hash)
-    to_hash.extend(_get_dependencies(current_filename))
-  return sha256('|'.join(sorted(hashes))).hexdigest()
-
-def main(argv):
-  logging.basicConfig()
-  # Uncomment to debug:
-  # _logging.setLevel(logging.DEBUG)
-
-  if len(argv) < 2:
-    print """\
-Usage: %s [file] ...
-
-Prints the \"transitive\" hash of each (executable) file. The transitive
-hash is a hash of the file and all the shared libraries on which it
-depends (done in an order-independent way).""" % basename(argv[0])
-    return 0
-
-  rv = 0
-  for filename in argv[1:]:
-    try:
-      print transitive_hash(filename), filename
-    except subprocess.CalledProcessError:
-      print "ERROR", filename
-      rv = 1
-  return rv
-
-if __name__ == '__main__':
-  sys.exit(main(sys.argv))
diff --git a/mojo/tools/mopy/version.py b/mojo/tools/mopy/version.py
deleted file mode 100644
index 8f8e132..0000000
--- a/mojo/tools/mopy/version.py
+++ /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.
-
-import subprocess
-
-import mopy.paths
-
-class Version(object):
-  """Computes the version (git committish) of the mojo repo"""
-
-  def __init__(self):
-    self.version = subprocess.check_output(["git", "rev-parse", "HEAD"],
-        cwd=mopy.paths.Paths().src_root).strip()
diff --git a/mojo/tools/perf_test_runner.py b/mojo/tools/perf_test_runner.py
deleted file mode 100755
index dff6b2d..0000000
--- a/mojo/tools/perf_test_runner.py
+++ /dev/null
@@ -1,85 +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.
-
-"""A tool that runs a perf test and uploads the resulting data to the
-performance dashboard.
-"""
-
-import argparse
-from mopy import perf_data_uploader
-from mopy.version import Version
-import subprocess
-import sys
-
-
-def _GetCurrentCommitCount():
-  return subprocess.check_output(
-      ["git", "rev-list", "HEAD", "--count"]).strip()
-
-
-def main():
-  parser = argparse.ArgumentParser(
-      description="A tool that runs a perf test and uploads the resulting data "
-                  "to the performance dashboard.")
-
-  parser.add_argument(
-      "--master-name",
-      help="Buildbot master name, used to construct link to buildbot log by "
-           "the dashboard, and also as the top-level category for the data.")
-  parser.add_argument(
-      "--perf-id",
-      help="Used as the second-level category for the data, usually the "
-           "platform type.")
-  parser.add_argument(
-      "--test-name",
-      help="Name of the test that the perf data was generated from.")
-  parser.add_argument(
-      "--builder-name",
-      help="Buildbot builder name, used to construct link to buildbot log by "
-           "the dashboard.")
-  parser.add_argument(
-      "--build-number", type=int,
-      help="Build number, used to construct link to buildbot log by the "
-           "dashboard.")
-  parser.add_argument(
-      "--perf-data-path",
-      help="The path to the perf data that the perf test generates.")
-  server_group = parser.add_mutually_exclusive_group()
-  server_group.add_argument(
-      "--testing-dashboard", action="store_true", default=True,
-      help="Upload the data to the testing dashboard (default).")
-  server_group.add_argument(
-      "--production-dashboard", dest="testing_dashboard", action="store_false",
-      default=False, help="Upload the data to the production dashboard.")
-  parser.add_argument("command", nargs=argparse.REMAINDER)
-  args = parser.parse_args()
-
-  subprocess.check_call(args.command)
-
-  if args.master_name is None or \
-     args.perf_id is None or \
-     args.test_name is None or \
-     args.builder_name is None or \
-     args.build_number is None or \
-     args.perf_data_path is None:
-    print "Won't upload perf data to the dashboard because not all of the " \
-          "following values are specified: master-name, perf-id, test-name, " \
-          "builder-name, build-number, perf-data-path."
-    return 0
-
-  revision = Version().version
-  perf_data = open(args.perf_data_path, "r")
-  point_id = _GetCurrentCommitCount()
-
-  result = perf_data_uploader.UploadPerfData(
-      args.master_name, args.perf_id, args.test_name, args.builder_name,
-      args.build_number, revision, perf_data, point_id, False,
-      args.testing_dashboard)
-
-  return 0 if result else 1
-
-
-if __name__ == '__main__':
-  sys.exit(main())
diff --git a/mojo/tools/prepare_pub_packages.py b/mojo/tools/prepare_pub_packages.py
deleted file mode 100755
index e53b0c9..0000000
--- a/mojo/tools/prepare_pub_packages.py
+++ /dev/null
@@ -1,92 +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.
-
-"""Prepares pub packages for upload."""
-
-# NOTE: Requires the following build artifacts:
-# *) out/Config/gen/dart-pkg
-# *) out/Config/apks/
-# By default Config is 'android_Release'
-
-import argparse
-import os
-import shutil
-import tempfile
-
-
-def remove_empty_dirs(root_dir):
-    for root, dirs, _ in os.walk(root_dir):
-         for name in dirs:
-             fname = os.path.join(root, name)
-             if not os.listdir(fname):
-                 os.removedirs(fname)
-
-
-def copy_package(src_dir, dst_dir, ignore=None):
-    # Remove existing destination directory.
-    shutil.rmtree(dst_dir, True)
-    shutil.copytree(src_dir, dst_dir, symlinks=False, ignore=ignore)
-
-
-def install_mojo_license_and_authors_files(src_root, dst_dir):
-    shutil.copy(os.path.join(src_root, 'LICENSE'), dst_dir)
-    shutil.copy(os.path.join(src_root, 'AUTHORS'), dst_dir)
-
-
-def main():
-    parser = argparse.ArgumentParser(
-        description='Prepare pub packages for upload')
-    parser.add_argument('--config',
-                        type=str,
-                        default='android_Release')
-    parser.add_argument('--src-root',
-                        type=str,
-                        default='.')
-    parser.add_argument('--packages',
-                        default=['mojo', 'mojom', 'mojo_services'])
-    parser.add_argument('--out-dir',
-                        default=None)
-    parser.add_argument('build_dir',
-                        type=str)
-    args = parser.parse_args()
-
-    rel_build_dir = os.path.join(args.build_dir, args.config)
-    build_dir = os.path.abspath(rel_build_dir)
-    sdk_dir = os.path.abspath(args.src_root)
-    print('Using SDK in %s' % sdk_dir)
-    print('Using build in %s' % build_dir)
-
-    temp_dir = args.out_dir
-    if temp_dir:
-        try:
-            shutil.rmtree(temp_dir)
-        except OSError:
-            pass
-        os.makedirs(temp_dir)
-    else:
-        # Create a temporary directory to copy files into.
-        temp_dir = tempfile.mkdtemp(prefix='pub_packages-')
-
-    print('Packages ready to be uploaded in %s' % temp_dir)
-
-    # Copy packages
-    dart_pkg_dir = os.path.join(build_dir, 'gen', 'dart-pkg')
-    for package in args.packages:
-        print('Preparing package %s' % package)
-        src_dir = os.path.join(dart_pkg_dir, package)
-        dst_dir = os.path.join(temp_dir, package)
-        ignore = None
-        # Special case 'mojom' package to not copy generated mojom.dart files.
-        if package == 'mojom':
-            ignore = shutil.ignore_patterns('*.mojom.dart')
-        copy_package(src_dir, dst_dir, ignore)
-        # Special case 'mojom' package to remove empty directories.
-        if package == 'mojom':
-            remove_empty_dirs(dst_dir)
-        install_mojo_license_and_authors_files(sdk_dir, dst_dir)
-
-
-if __name__ == '__main__':
-    main()
diff --git a/mojo/tools/publish_pub_packages.py b/mojo/tools/publish_pub_packages.py
deleted file mode 100755
index fcfbeea..0000000
--- a/mojo/tools/publish_pub_packages.py
+++ /dev/null
@@ -1,74 +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.
-
-# See https://github.com/domokit/mojo/wiki/Release-process
-
-import argparse
-import distutils.util
-import os
-import subprocess
-import sys
-import tempfile
-
-MOJO_TOOLS_DIR = os.path.dirname(os.path.abspath(__file__))
-SRC_ROOT = os.path.dirname(os.path.dirname(MOJO_TOOLS_DIR))
-DART_SDK = os.path.join(SRC_ROOT, 'third_party', 'dart-sdk', 'dart-sdk', 'bin')
-PUB = os.path.join(DART_SDK, 'pub')
-
-PACKAGES = [
-  'mojo',
-  'mojom',
-  'mojo_services',
-]
-
-CONFIRM = """This tool is destructive and will revert your current branch to
-origin/master among other things.  Are you sure you wish to continue?"""
-
-
-def run(cwd, args):
-    print 'RUNNING:', ' '.join(args), 'IN:', cwd
-    subprocess.check_call(args, cwd=cwd)
-
-
-def confirm(prompt):
-    user_input = raw_input("%s (y/N) " % prompt)
-    try:
-        return distutils.util.strtobool(user_input) == 1
-    except ValueError:
-        return False
-
-
-def main():
-    parser = argparse.ArgumentParser(description='Deploy!')
-    parser.parse_args()
-
-    if not confirm(CONFIRM):
-        print "Aborted."
-        return 1
-
-    run(SRC_ROOT, ['git', 'fetch', 'origin'])
-    run(SRC_ROOT, ['git', 'reset', 'origin/master', '--hard'])
-    run(SRC_ROOT, ['gclient', 'sync'])
-
-    run(SRC_ROOT, ['mojo/tools/mojob.py', 'gn', '--android', '--release'])
-    run(SRC_ROOT, ['ninja', '-C', 'out/android_Release'])
-
-    package_root = tempfile.mkdtemp(prefix='pub_packages-')
-
-    run(SRC_ROOT, [
-        'mojo/tools/prepare_pub_packages.py',
-        '--out-dir',
-        package_root,
-        'out',
-    ])
-
-    for package in PACKAGES:
-        package_dir = os.path.join(package_root, package)
-        print "PACKAGE", package_dir, "PUB", PUB
-        run(package_dir, [PUB, 'publish', '--force'])
-
-
-if __name__ == '__main__':
-    sys.exit(main())
diff --git a/mojo/tools/remote_file_reader.cc b/mojo/tools/remote_file_reader.cc
deleted file mode 100644
index c12132a..0000000
--- a/mojo/tools/remote_file_reader.cc
+++ /dev/null
@@ -1,325 +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.
-
-#include <fcntl.h>
-#include <inttypes.h>
-#include <netinet/in.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/socket.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <unistd.h>
-
-#include <algorithm>
-#include <memory>
-#include <string>
-#include <vector>
-
-// This utility allows to read a file from the local file system through a
-// network protocol. The protocol is the following request response protocol:
-//
-// Opening a new file:
-// Request: O path_to_file\n
-// Success: O
-// Error: E
-//
-// Seeking on the last opened file:
-// Request: S offset whence\n
-// Success: 0
-// Error: E
-//
-// Reading the last opened file at the current position:
-// Request: R size\n
-// Success: 0{size encoded on 4 bytes in network order}{content}
-// Error: E
-
-namespace {
-
-// Display an error message and exit.
-void error(const char* msg) {
-  perror(msg);
-  exit(1);
-}
-
-// Keep track of an active connection with a client.
-class Connection {
- public:
-  // Takes ownership of the given fd which is an opened socket to the client.
-  explicit Connection(int fd)
-      : fd_(fd), file_fd_(-1), buffer_size_(0), buffer_(nullptr, free) {}
-  ~Connection() { Close(); }
-
-  int fd() { return fd_; };
-
-  void Close() {
-    if (fd_ != -1) {
-      close(fd_);
-      fd_ = -1;
-    }
-    if (file_fd_ != -1) {
-      close(file_fd_);
-      file_fd_ = -1;
-    }
-  }
-
-  // Returns whether this connection has some data to write to the client.
-  bool NeedsWriting() { return write_buffer_.size() > 0; }
-
-  // Try to write buffered data to the client. This should only be called when
-  // the socket is writeable, otherwise this method may block.
-  bool Write() {
-    int nb_written = write(fd_, write_buffer_.data(), write_buffer_.size());
-    if (nb_written <= 0) {
-      Close();
-      return false;
-    }
-    write_buffer_ = std::string(write_buffer_, nb_written);
-    return true;
-  }
-
-  // Read any data available from the client, and send any responses if a full
-  // request has been read. This should only be called when the socket is
-  // readable, otherwise this method may block.
-  bool Read() {
-    char buffer[4096];
-    int nb_read = read(fd_, buffer, sizeof(buffer));
-    if (nb_read <= 0) {
-      Close();
-      return false;
-    }
-    read_buffer_ += std::string(buffer, nb_read);
-    Respond();
-    return true;
-  }
-
- private:
-  // Success message.
-  const char kSuccess = 'O';
-  // Error message.
-  const char kError = 'E';
-
-  // Read any available request in the read buffer and write the responses in
-  // the write buffer.
-  void Respond() {
-    std::string::size_type eol_position = read_buffer_.find('\n');
-    while (eol_position != std::string::npos) {
-      std::string command(read_buffer_, 0, eol_position);
-      read_buffer_ = std::string(read_buffer_, eol_position + 1);
-      std::string argument(command, 2);
-      switch (command[0]) {
-        case 'O':
-          OpenCommand(argument);
-          break;
-        case 'S':
-          SeekCommand(argument);
-          break;
-        case 'R':
-          ReadCommand(argument);
-          break;
-        default:
-          write_buffer_ += kError;
-      }
-      eol_position = read_buffer_.find('\n');
-    }
-  }
-
-  // Handle the open command.
-  void OpenCommand(const std::string& file) {
-    if (file_fd_ != -1) {
-      close(file_fd_);
-      file_fd_ = -1;
-    }
-    file_fd_ = open(file.c_str(), O_RDONLY);
-    if (file_fd_ == -1) {
-      perror("Unable to open file");
-      write_buffer_ += kError;
-      return;
-    }
-    write_buffer_ += kSuccess;
-  }
-
-  // Handle the seek command.
-  void SeekCommand(const std::string& parameters) {
-    if (file_fd_ == -1) {
-      write_buffer_ += kError;
-      return;
-    }
-    int32_t offset;
-    int32_t whence;
-    if (sscanf(parameters.c_str(), "%" SCNd32 " %" SCNd32, &offset, &whence) !=
-        2) {
-      write_buffer_ += kError;
-      return;
-    }
-    if (lseek(file_fd_, offset, whence) == -1) {
-      perror("Unable to seek");
-      write_buffer_ += kError;
-      return;
-    }
-    write_buffer_ += kSuccess;
-  }
-
-  // Handle the read command.
-  void ReadCommand(const std::string& parameters) {
-    if (file_fd_ == -1) {
-      write_buffer_ += kError;
-      return;
-    }
-    int32_t size;
-    if (sscanf(parameters.c_str(), "%" SCNd32, &size) != 1) {
-      write_buffer_ += kError;
-      return;
-    }
-    if (size <= 0) {
-      write_buffer_ += kError;
-      return;
-    }
-    EnsureBufferCapacity(size);
-    int32_t result = read(file_fd_, buffer_.get(), size);
-    if (result < 0) {
-      perror("Unable to read");
-      close(file_fd_);
-      file_fd_ = -1;
-      write_buffer_ += kError;
-      return;
-    }
-    write_buffer_ += kSuccess;
-    int32_t size_to_send = htonl(result);
-    static_assert(sizeof(size_to_send) == 4, "Must send size with 4 byte.");
-    write_buffer_ += std::string(reinterpret_cast<char*>(&size_to_send), 4);
-    write_buffer_ += std::string(buffer_.get(), result);
-  }
-
-  // Ensure that |buffer_| has the capacity needed to read from the local file.
-  void EnsureBufferCapacity(size_t capacity) {
-    if (buffer_size_ >= capacity) {
-      return;
-    }
-    if (buffer_size_ == 0) {
-      buffer_.reset(static_cast<char*>(malloc(capacity)));
-      buffer_size_ = capacity;
-      return;
-    }
-    buffer_.reset(static_cast<char*>(realloc(buffer_.release(), capacity)));
-    buffer_size_ = capacity;
-  }
-
-  // File descriptor of the socket connected to the client.
-  int fd_;
-  // File descriptor of the current read file.
-  int file_fd_;
-  size_t buffer_size_;
-  std::unique_ptr<char, decltype(free)*> buffer_;
-  std::string write_buffer_;
-  std::string read_buffer_;
-};
-
-}  // namespace
-
-int main(int argc, char** argv) {
-  // The port to bind to.
-  int port = 0;
-  if (argc > 1) {
-    port = atoi(argv[1]);
-  }
-  // Setup the server socket.
-  int server_socket, connected_socket;
-  struct sockaddr_in server_address, client_address;
-  server_socket = socket(AF_INET, SOCK_STREAM, 0);
-  if (server_socket < 0) {
-    error("Unable to open socket");
-  }
-  bzero(&server_address, sizeof(server_address));
-  server_address.sin_family = AF_INET;
-  server_address.sin_addr.s_addr = INADDR_ANY;
-  server_address.sin_port = port;
-  if (bind(server_socket, reinterpret_cast<struct sockaddr*>(&server_address),
-           sizeof(server_address)) < 0) {
-    error("Unable to bind socket");
-  }
-  socklen_t socket_size = sizeof(server_address);
-  if (getsockname(server_socket,
-                  reinterpret_cast<struct sockaddr*>(&server_address),
-                  &socket_size) < 0) {
-    perror("Unable to retrieve socket information");
-  }
-  // Print the port on the bound port on the standard output.
-  printf("%d\n", ntohs(server_address.sin_port));
-
-  // Start listening for client.
-  listen(server_socket, 5);
-
-  // Wait for the first client to connect.
-  socket_size = sizeof(client_address);
-  connected_socket =
-      accept(server_socket, reinterpret_cast<struct sockaddr*>(&client_address),
-             &socket_size);
-  if (connected_socket < 0) {
-    error("Unable to accept the intiial client");
-  }
-
-  // Keep track of active connections.
-  std::vector<std::unique_ptr<Connection>> connections;
-  connections.push_back(
-      std::unique_ptr<Connection>(new Connection(connected_socket)));
-
-  // Stop when all clients have disconnected.
-  while (connections.size()) {
-    // Prepate data to wait for any I/O to be ready.
-    fd_set rset;
-    fd_set wset;
-    FD_ZERO(&rset);
-    FD_ZERO(&wset);
-    // Always wait for a new connection.
-    FD_SET(server_socket, &rset);
-    int max_fd = server_socket + 1;
-    for (auto& c : connections) {
-      // Always wait for a client sending data.
-      FD_SET(c->fd(), &rset);
-      // Wait for a client to be ready to receive data only if some data needs
-      // to be sent.
-      if (c->NeedsWriting()) {
-        FD_SET(c->fd(), &wset);
-      }
-      max_fd = std::max(max_fd, c->fd() + 1);
-    }
-    // Wait for any I/O to be ready.
-    select(max_fd, &rset, &wset, nullptr, nullptr);
-
-    // Check if a client a connected.
-    if (FD_ISSET(server_socket, &rset)) {
-      int fd = accept(server_socket,
-                      reinterpret_cast<struct sockaddr*>(&client_address),
-                      &socket_size);
-      if (fd >= 0) {
-        connections.push_back(std::unique_ptr<Connection>(new Connection(fd)));
-      }
-    }
-
-    // Check each connection.
-    for (auto& c : connections) {
-      if (FD_ISSET(c->fd(), &rset)) {
-        if (!c->Read()) {
-          // If a fatal error happen, delete the connection.
-          c.reset();
-        }
-      }
-      if (c && FD_ISSET(c->fd(), &wset)) {
-        if (!c->Write()) {
-          // If a fatal error happen, delete the connection.
-          c.reset();
-        }
-      }
-    }
-
-    // Remove any deleted connection from the list of active connections.
-    connections.erase(
-        std::remove_if(connections.begin(), connections.end(),
-                       [](const std::unique_ptr<Connection>& c) { return !c; }),
-        connections.end());
-  }
-  return 0;
-}
diff --git a/mojo/tools/roll/android_build.patch b/mojo/tools/roll/android_build.patch
deleted file mode 100644
index bd73b9e..0000000
--- a/mojo/tools/roll/android_build.patch
+++ /dev/null
@@ -1,33 +0,0 @@
---- a/build/android/pylib/constants/__init__.py
-+++ b/build/android/pylib/constants/__init__.py
-@@ -184,7 +184,7 @@ class ANDROID_SDK_VERSION_CODES(object):
-   LOLLIPOP_MR1 = 22
- 
- ANDROID_SDK_VERSION = ANDROID_SDK_VERSION_CODES.LOLLIPOP_MR1
--ANDROID_SDK_BUILD_TOOLS_VERSION = '22.0.0'
-+ANDROID_SDK_BUILD_TOOLS_VERSION = '22.0.1'
- ANDROID_SDK_ROOT = os.path.join(DIR_SOURCE_ROOT,
-                                 'third_party/android_tools/sdk')
- ANDROID_SDK_TOOLS = os.path.join(ANDROID_SDK_ROOT,
---- a/build/common.gypi
-+++ b/build/common.gypi
-@@ -1682,7 +1682,7 @@
-             'android_host_arch%': '<!(uname -m)',
-             # Android API-level of the SDK used for compilation.
-             'android_sdk_version%': '22',
--            'android_sdk_build_tools_version%': '22.0.0',
-+            'android_sdk_build_tools_version%': '22.0.1',
-             'host_os%': "<!(uname -s | sed -e 's/Linux/linux/;s/Darwin/mac/')",
-           },
-           # Copy conditionally-set variables out one scope.
---- a/build/config/android/config.gni
-+++ b/build/config/android/config.gni
-@@ -17,7 +17,7 @@ if (is_android) {
-   if (!defined(default_android_sdk_root)) {
-     default_android_sdk_root = "//third_party/android_tools/sdk"
-     default_android_sdk_version = "22"
--    default_android_sdk_build_tools_version = "22.0.0"
-+    default_android_sdk_build_tools_version = "22.0.1"
-   }
- 
-   if (!defined(google_play_services_library)) {
diff --git a/mojo/tools/roll/build_v8.patch b/mojo/tools/roll/build_v8.patch
deleted file mode 100644
index 7f0083b..0000000
--- a/mojo/tools/roll/build_v8.patch
+++ /dev/null
@@ -1,11 +0,0 @@
-diff --git a/build/module_args/v8.gni b/build/module_args/v8.gni
-index 8b5204c..aa2848c 100644
---- a/build/module_args/v8.gni
-+++ b/build/module_args/v8.gni
-@@ -9,5 +9,5 @@ if (is_android) {
- # TODO(sky): nuke this. Temporary while sorting out http://crbug.com/465456.
- enable_correct_v8_arch = false
- 
--v8_use_external_startup_data = !(is_chromeos || is_win)
-+v8_use_external_startup_data = false
- v8_extra_library_files = []
diff --git a/mojo/tools/roll/compare_deps.py b/mojo/tools/roll/compare_deps.py
deleted file mode 100755
index db4e20c..0000000
--- a/mojo/tools/roll/compare_deps.py
+++ /dev/null
@@ -1,36 +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 re
-import sys
-import utils
-
-if len(sys.argv) != 2:
-  print "usage: compare_deps.py <chromium DEPS file>"
-  sys.exit(1)
-
-chromium_deps_path = sys.argv[1]
-mojo_deps_path = os.path.join(utils.mojo_root_dir, "DEPS")
-
-chromium_deps = ""
-
-with open(chromium_deps_path) as chromium_deps_file:
-  chromium_deps = chromium_deps_file.read()
-
-found_mismatch = False
-
-with open(mojo_deps_path) as mojo_deps_file:
-  for line in mojo_deps_file:
-    m = re.search("[0-9a-f]{32}", line)
-    if m:
-      git_hash = m.group(0)
-      if not git_hash in chromium_deps:
-        print "%s in mojo DEPS but not in chromium DEPS" % git_hash
-        print "line %s" % line.strip()
-        found_mismatch = True
-
-if found_mismatch:
-  sys.exit(1)
diff --git a/mojo/tools/roll/patch.py b/mojo/tools/roll/patch.py
deleted file mode 100755
index 4147b24..0000000
--- a/mojo/tools/roll/patch.py
+++ /dev/null
@@ -1,49 +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 subprocess
-import utils
-
-def patch_and_filter():
-  """Applies the *.patch files in the current dir and some hardcoded filters."""
-  os.chdir(utils.mojo_root_dir)
-
-  utils.filter_file("build/landmines.py",
-      lambda line: not "gyp_environment" in line)
-  utils.commit("filter gyp_environment out of build/landmines.py")
-
-  utils.filter_file("gpu/BUILD.gn", lambda line: not "//gpu/ipc" in line)
-  utils.commit("filter //gpu/ipc out of gpu/BUILD.gn")
-
-  utils.filter_file("cc/BUILD.gn", lambda line: not "//media" in line)
-  utils.commit("filter //media out of cc/BUILD.gn")
-
-  patch()
-
-
-def patch(relative_patches_dir=os.curdir):
-  """Applies the *.patch files in |relative_patches_dir|.
-
-  Args:
-    relative_patches_dir: A directory path relative to the current directory.
-        Defaults to the directory of this file.
-
-  Raises:
-    subprocess.CalledProcessError if the patch couldn't be applied.
-  """
-  patches_dir = os.path.join(os.path.dirname(os.path.realpath(__file__)),
-                             relative_patches_dir)
-  assert os.path.isdir(patches_dir)
-
-  os.chdir(utils.mojo_root_dir)
-  for p in utils.find(["*.patch"], patches_dir):
-    print "applying patch %s" % os.path.basename(p)
-    try:
-      utils.system(["git", "apply", p])
-      utils.commit("applied patch %s" % os.path.basename(p))
-    except subprocess.CalledProcessError:
-      print "ERROR: patch %s failed to apply" % os.path.basename(p)
-      raise
diff --git a/mojo/tools/roll/sanitizers_build.patch b/mojo/tools/roll/sanitizers_build.patch
deleted file mode 100644
index 9f9e8b8..0000000
--- a/mojo/tools/roll/sanitizers_build.patch
+++ /dev/null
@@ -1,35 +0,0 @@
-diff --git a/build/config/sanitizers/BUILD.gn b/build/config/sanitizers/BUILD.gn
-index 8996951..023315f 100644
---- a/build/config/sanitizers/BUILD.gn
-+++ b/build/config/sanitizers/BUILD.gn
-@@ -8,9 +8,12 @@ import("//build/config/sanitizers/sanitizers.gni")
- # shared_libraries. Unconditionally depend upon this target as it is empty if
- # |is_asan|, |is_lsan|, |is_tsan|, |is_msan| and |use_custom_libcxx| are false.
- group("deps") {
--  deps = [
--    "//third_party/instrumented_libraries:deps",
--  ]
-+  # TODO(vtl): Chromium has the following (but we don't have
-+  # instrumented_libraries).
-+  # deps = [
-+  #   "//third_party/instrumented_libraries:deps",
-+  # ]
-+  deps = []
-   if (is_asan || is_lsan || is_tsan || is_msan) {
-     public_configs = [ ":sanitizer_options_link_helper" ]
-     deps += [ ":options_sources" ]
-diff --git a/build/config/sanitizers/sanitizers.gni b/build/config/sanitizers/sanitizers.gni
-index a7b9658..0edc144 100644
---- a/build/config/sanitizers/sanitizers.gni
-+++ b/build/config/sanitizers/sanitizers.gni
-@@ -6,7 +6,9 @@ declare_args() {
-   # Use libc++ (buildtools/third_party/libc++ and
-   # buildtools/third_party/libc++abi) instead of stdlibc++ as standard library.
-   # This is intended to be used for instrumented builds.
--  use_custom_libcxx = (is_asan && is_linux) || is_tsan || is_msan
-+  # TODO(vtl): We don't use this, since building fails, for some reason.
-+  use_custom_libcxx = false
-+  # use_custom_libcxx = (is_asan && is_linux) || is_tsan || is_msan
- 
-   # Track where uninitialized memory originates from. From fastest to slowest:
-   # 0 - no tracking, 1 - track only the initial allocation site, 2 - track the
diff --git a/mojo/tools/roll/update_from_chromium.py b/mojo/tools/roll/update_from_chromium.py
deleted file mode 100755
index d9ae68d..0000000
--- a/mojo/tools/roll/update_from_chromium.py
+++ /dev/null
@@ -1,121 +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 json
-import os
-import subprocess
-import sys
-import urllib2
-from utils import commit
-from utils import mojo_root_dir
-from utils import system
-
-import patch
-
-# //base and its dependencies
-base_deps = [
-    "base",
-    "testing",
-    "third_party/ashmem",
-    "third_party/libevent",
-    "third_party/libxml", # via //base/test
-    "third_party/modp_b64",
-    "third_party/tcmalloc",
-]
-
-# //build and its dependencies
-build_deps = [
-    "build",
-    "third_party/android_testrunner",
-    "third_party/binutils",
-    "third_party/pymock",
-    "tools/android",
-    "tools/clang",
-    "tools/generate_library_loader",
-    "tools/gritsettings",
-    "tools/relocation_packer",
-    "tools/valgrind",
-]
-
-# //sandbox/linux and its dependencies
-sandbox_deps = [
-    "sandbox/linux",
-]
-
-# things used from //mojo/public
-mojo_sdk_deps = [
-    "third_party/cython",
-]
-
-# These directories are snapshotted from chromium without modifications.
-dirs_to_snapshot = base_deps + build_deps + sandbox_deps + mojo_sdk_deps
-
-files_to_copy = [ "sandbox/sandbox_export.h" ]
-
-# The contents of these files before the roll will be preserved after the roll,
-# even though they live in directories rolled in from Chromium.
-files_not_to_roll = [
-    "build/config/ui.gni",
-    "build/ls.py",
-    "build/module_args/mojo.gni",
-]
-
-dirs = dirs_to_snapshot
-
-def chromium_rev_number(src_commit):
-  base_url = "https://cr-rev.appspot.com/_ah/api/crrev/v1/commit/"
-  commit_info = json.load(urllib2.urlopen(base_url + src_commit))
-  return commit_info["numberings"][0]["number"]
-
-def rev(source_dir):
-  for d in dirs:
-    print "removing directory %s" % d
-    try:
-      system(["git", "rm", "-r", d], cwd=mojo_root_dir)
-    except subprocess.CalledProcessError:
-      print "Could not remove %s" % d
-    print "cloning directory %s" % d
-    files = system(["git", "ls-files", d], cwd=source_dir)
-    for f in files.splitlines():
-      dest_path = os.path.join(mojo_root_dir, f)
-      system(["mkdir", "-p", os.path.dirname(dest_path)], cwd=source_dir)
-      system(["cp", os.path.join(source_dir, f), dest_path], cwd=source_dir)
-    system(["git", "add", d], cwd=mojo_root_dir)
-
-  for f in files_to_copy:
-    system(["cp", os.path.join(source_dir, f), os.path.join(mojo_root_dir, f)])
-
-  system(["git", "add", "."], cwd=mojo_root_dir)
-  src_commit = system(["git", "rev-parse", "HEAD"], cwd=source_dir).strip()
-  src_rev = chromium_rev_number(src_commit)
-  commit("Update from https://crrev.com/" + src_rev, cwd=mojo_root_dir)
-
-def main():
-  parser = argparse.ArgumentParser(description="Update the mojo repo's " +
-      "snapshot of things imported from chromium.")
-  parser.add_argument("chromium_dir", help="chromium source dir")
-  args = parser.parse_args()
-  pre_roll_commit = system(
-      ["git", "rev-parse", "HEAD"], cwd=mojo_root_dir).strip()
-
-  rev(args.chromium_dir)
-
-  try:
-    patch.patch_and_filter()
-  except subprocess.CalledProcessError:
-    print "ERROR: Roll failed due to a patch not applying"
-    print "Fix the patch to apply, commit the result, and re-run this script"
-    return 1
-
-  print "Restoring files whose contents don't track Chromium"
-  for f in files_not_to_roll:
-    system(["git", "checkout", pre_roll_commit, "--", f], cwd=mojo_root_dir)
-  if files_not_to_roll:
-    commit("Restored pre-roll versions of files that don't get rolled")
-  return 0
-
-if __name__ == "__main__":
-  sys.exit(main())
diff --git a/mojo/tools/roll/utils.py b/mojo/tools/roll/utils.py
deleted file mode 100755
index dcdfc35..0000000
--- a/mojo/tools/roll/utils.py
+++ /dev/null
@@ -1,32 +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 fnmatch
-import os
-import subprocess
-
-mojo_root_dir = os.path.join(os.path.dirname(os.path.realpath(__file__)),
-                             os.pardir, os.pardir, os.pardir)
-
-def commit(message, cwd=None):
-  subprocess.call(['git', 'commit', '-a', '-m', message], cwd=cwd)
-
-def system(command, cwd=None):
-  return subprocess.check_output(command, cwd=cwd)
-
-def find(patterns, start='.'):
-  for path, dirs, files in os.walk(start):
-    for basename in files + dirs:
-      if any([fnmatch.fnmatch(basename, pattern) for pattern in patterns]):
-        filename = os.path.join(path, basename)
-        yield filename
-
-def filter_file(path, predicate):
-  with open(path, 'r+') as f:
-    lines = f.readlines()
-    new_lines = [line for line in lines if predicate(line)]
-    f.seek(0)
-    f.truncate()
-    f.write(''.join(new_lines))
diff --git a/mojo/tools/roll_services.py b/mojo/tools/roll_services.py
deleted file mode 100755
index 5f9a94d..0000000
--- a/mojo/tools/roll_services.py
+++ /dev/null
@@ -1,75 +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.
-
-"""Roll services version in the cdn."""
-
-import argparse
-import os
-import subprocess
-import sys
-import tempfile
-
-from mopy.config import Config
-from mopy.paths import Paths
-
-def target(config):
-  target_name = config.target_os + "-" + config.target_cpu
-  if config.is_official_build:
-    target_name += "-official"
-  return target_name
-
-
-def get_gsutil():
-  paths = Paths()
-  sys.path.insert(0, os.path.join(paths.src_root, "tools"))
-  # pylint: disable=F0401
-  import find_depot_tools
-
-  depot_tools_path = find_depot_tools.add_depot_tools_to_path()
-  return os.path.join(depot_tools_path, "third_party", "gsutil", "gsutil")
-
-
-def upload(gsutil_exe, source, dest):
-  subprocess.check_call([gsutil_exe, "cp", source, dest])
-
-
-def write_file_to_gs(gsutil_exe, file_contents, dest):
-  with tempfile.NamedTemporaryFile() as temp_version_file:
-    temp_version_file.write(file_contents)
-    temp_version_file.flush()
-    upload(gsutil_exe, temp_version_file.name, dest)
-
-
-def roll_version(gsutil_exe, config, version):
-  service_dir = 'gs://mojo/services/%s/%s' % (target(config), version)
-  services = subprocess.check_output(
-      [gsutil_exe, 'ls', service_dir]).strip().split('\n')
-  for service in services:
-    service_binary_name = service.split('/')[-1]
-    service_location_file = ("gs://mojo/services/" + target(config) + "/" +
-        service_binary_name + "_location")
-    service_location_in_gs = service[len('gs://'):]
-    write_file_to_gs(gsutil_exe, service_location_in_gs, service_location_file)
-
-
-def main():
-  parser = argparse.ArgumentParser(description="Change the version of the mojo "
-      "services on the cdn.")
-  parser.add_argument("-v", "--verbose", help="Verbose mode",
-      action="store_true")
-  parser.add_argument("version",
-                      help="New version of the mojo services.")
-  args = parser.parse_args()
-
-  gsutil_exe = get_gsutil()
-
-  for target_os in [Config.OS_LINUX, Config.OS_ANDROID]:
-    config = Config(target_os=target_os)
-    roll_version(gsutil_exe, config, args.version)
-
-  return 0
-
-if __name__ == "__main__":
-  sys.exit(main())
diff --git a/mojo/tools/run_command_through_symbolizer.py b/mojo/tools/run_command_through_symbolizer.py
deleted file mode 100755
index 1110eee..0000000
--- a/mojo/tools/run_command_through_symbolizer.py
+++ /dev/null
@@ -1,26 +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.
-
-# Simple script that executes the command supplied as arguments and pipes
-# stderr/out through asan_symbolize.py.
-
-import os
-import subprocess
-import sys
-
-def main():
-  p1 = subprocess.Popen(sys.argv[1:], stdout=subprocess.PIPE,
-                        stderr=sys.stdout)
-  p2 = subprocess.Popen([os.path.join('tools', 'valgrind', 'asan',
-                                      'asan_symbolize.py')],
-                        stdin=p1.stdout)
-  p1.stdout.close()  # Allow p1 to receive a SIGPIPE if p2 exits.
-  p1.wait()
-  p2.wait()
-  return p1.returncode
-
-
-if __name__ == "__main__":
-  sys.exit(main())
diff --git a/mojo/tools/run_mojo_python_bindings_tests.py b/mojo/tools/run_mojo_python_bindings_tests.py
deleted file mode 100755
index d64f49c..0000000
--- a/mojo/tools/run_mojo_python_bindings_tests.py
+++ /dev/null
@@ -1,35 +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
-
-from mopy.mojo_python_tests_runner import MojoPythonTestRunner
-
-
-class PythonBindingsTestRunner(MojoPythonTestRunner):
-  def add_custom_commandline_options(self, parser):
-    parser.add_argument('--build-dir', action='store',
-                        help='path to the build output directory')
-
-  def apply_customization(self, args):
-    if args.build_dir:
-      python_build_dir = os.path.join(args.build_dir, 'python')
-      if python_build_dir not in sys.path:
-        sys.path.append(python_build_dir)
-      python_gen_dir = os.path.join(
-          args.build_dir,
-          'gen', 'mojo', 'public', 'interfaces', 'bindings', 'tests')
-      if python_gen_dir not in sys.path:
-        sys.path.append(python_gen_dir)
-
-
-def main():
-  runner = PythonBindingsTestRunner(os.path.join('mojo', 'python', 'tests'))
-  sys.exit(runner.run())
-
-
-if __name__ == '__main__':
-  sys.exit(main())
diff --git a/mojo/tools/run_mojo_python_tests.py b/mojo/tools/run_mojo_python_tests.py
deleted file mode 100755
index d18baf4..0000000
--- a/mojo/tools/run_mojo_python_tests.py
+++ /dev/null
@@ -1,30 +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
-
-from mopy.mojo_python_tests_runner import MojoPythonTestRunner
-
-
-def main():
-  test_dir_list = [
-      # Tests of pylib bindings.
-      os.path.join('mojo', 'public', 'tools', 'bindings', 'pylib'),
-      # Tests of "mopy" python tools code.
-      os.path.join('mojo', 'tools', 'mopy'),
-      # Tests of python code in devtools.
-      os.path.join('mojo', 'devtools', 'common', 'devtoolslib')
-  ]
-
-  for test_dir in test_dir_list:
-    runner = MojoPythonTestRunner(test_dir)
-    exit_code = runner.run()
-    if exit_code:
-      return exit_code
-
-
-if __name__ == '__main__':
-  sys.exit(main())
diff --git a/mojo/tools/test_runner.py b/mojo/tools/test_runner.py
deleted file mode 100755
index fe564a9..0000000
--- a/mojo/tools/test_runner.py
+++ /dev/null
@@ -1,152 +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.
-
-"""A "smart" test runner for gtest unit tests (that caches successes)."""
-
-import argparse
-import logging
-import os
-import subprocess
-import sys
-
-from mopy import gtest
-from mopy.config import Config
-from mopy.gn import ConfigForGNArgs, ParseGNConfig
-from mopy.log import InitLogging
-from mopy.paths import Paths
-from mopy.transitive_hash import file_hash, transitive_hash
-
-
-_logger = logging.getLogger()
-_paths = Paths()
-
-
-def main():
-  parser = argparse.ArgumentParser(
-      description="A 'smart' test runner for gtest unit tests (that caches "
-                  "successes).")
-
-  parser.add_argument("--verbose", help="be verbose (multiple times for more)",
-                      default=0, dest="verbose_count", action="count")
-  parser.add_argument("--successes-cache",
-                      help="the file caching test results (empty to not cache)",
-                      default="mojob_test_successes")
-  parser.add_argument("test_list_file",
-                      help="the file containing the tests to run", type=file)
-  parser.add_argument("root_dir", help="the build directory")
-  args = parser.parse_args()
-
-  InitLogging(args.verbose_count)
-  config = ConfigForGNArgs(ParseGNConfig(args.root_dir))
-
-  _logger.debug("Test list file: %s", args.test_list_file)
-  execution_globals = {"config": config}
-  exec args.test_list_file in execution_globals
-  test_list = execution_globals["tests"]
-  _logger.debug("Test list: %s" % test_list)
-
-  print "Running tests in directory: %s" % args.root_dir
-  os.chdir(args.root_dir)
-
-  if args.successes_cache:
-    print "Successes cache file: %s" % args.successes_cache
-  else:
-    print "No successes cache file (will run all tests unconditionally)"
-
-  if args.successes_cache:
-    # This file simply contains a list of transitive hashes of tests that
-    # succeeded.
-    try:
-      _logger.debug("Trying to read successes cache file: %s",
-                     args.successes_cache)
-      with open(args.successes_cache, 'rb') as f:
-        successes = set([x.strip() for x in f.readlines()])
-      _logger.debug("Successes: %s", successes)
-    except IOError:
-      # Just assume that it didn't exist, or whatever.
-      print ("Failed to read successes cache file %s (will create)" %
-             args.successes_cache)
-      successes = set()
-
-  gtest.set_color()
-
-  exit_code = 0
-  successes_cache_file = (open(args.successes_cache, "ab")
-      if args.successes_cache else None)
-  for test_dict in test_list:
-    test = test_dict["test"]
-    test_name = test_dict.get("name", test)
-    # TODO(vtl): Add type.
-    cacheable = test_dict.get("cacheable", True)
-    if not cacheable:
-      _logger.debug("%s is marked as non-cacheable" % test_name)
-
-    gtest_file = test
-    if config.target_os == Config.OS_ANDROID:
-      gtest_file = test + "_apk/" + test + "-debug.apk"
-
-    if successes_cache_file and cacheable:
-      _logger.debug("Getting transitive hash for %s ... " % test_name)
-      try:
-        if config.target_os == Config.OS_ANDROID:
-          gtest_hash = file_hash(gtest_file)
-        else:
-          gtest_hash = transitive_hash(gtest_file)
-      except subprocess.CalledProcessError:
-        print "Failed to get transitive hash for %s" % test_name
-        exit_code = 1
-        continue
-      _logger.debug("  Transitive hash: %s" % gtest_hash)
-
-      if gtest_hash in successes:
-        print "Skipping %s (previously succeeded)" % test_name
-        continue
-
-    _logger.info("Will start: %s" % test_name)
-    print "Running %s...." % test_name,
-    sys.stdout.flush()
-    try:
-      if config.target_os == Config.OS_ANDROID:
-        command = [
-            "python",
-            os.path.join(_paths.src_root, "build", "android", "test_runner.py"),
-            "gtest",
-            "--output-directory",
-            args.root_dir,
-            "-s",
-            test,
-        ]
-      else:
-        command = ["./" + test]
-      _logger.debug("Command: %s" % command)
-      subprocess.check_output(command, stderr=subprocess.STDOUT)
-      print "Succeeded"
-      # Record success.
-      if args.successes_cache and cacheable:
-        successes.add(gtest_hash)
-        successes_cache_file.write(gtest_hash + "\n")
-        successes_cache_file.flush()
-    except subprocess.CalledProcessError as e:
-      print "Failed with exit code %d and output:" % e.returncode
-      print 72 * "-"
-      print e.output
-      print 72 * "-"
-      exit_code = 1
-      continue
-    except OSError as e:
-      print "  Failed to start test"
-      exit_code = 1
-      continue
-    _logger.info("Completed: %s" % test_name)
-  if exit_code == 0:
-    print "All tests succeeded"
-  if successes_cache_file:
-    successes_cache_file.close()
-
-  return exit_code
-
-
-if __name__ == "__main__":
-  sys.exit(main())
diff --git a/mojo/tools/testing/mojom_fetcher/dependency_tests.py b/mojo/tools/testing/mojom_fetcher/dependency_tests.py
deleted file mode 100644
index 68f0ed8..0000000
--- a/mojo/tools/testing/mojom_fetcher/dependency_tests.py
+++ /dev/null
@@ -1,110 +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 unittest
-
-from fetcher.dependency import Dependency
-
-class FakeRepository(object):
-  def get_repo_root_directory(self):
-    return "/base/repo"
-
-  def get_external_directory(self):
-    return "/base/repo/third_party/external"
-
-class TestDependency(unittest.TestCase):
-  def test_importer_imported(self):
-    dep = Dependency(FakeRepository(),
-                     "/base/repo/services/foo/../bar/bar.mojom",
-                     "mojo/public/./../public/baz.mojom")
-
-    self.assertEqual("/base/repo/services/bar/bar.mojom", dep.get_importer())
-    self.assertEqual("mojo/public/baz.mojom", dep.get_imported())
-
-  def test_is_sdk_dep(self):
-    # Not in SDK
-    dep = Dependency(FakeRepository(),
-                     "/base/repo/services/bar/bar.mojom",
-                     "mojo/public/../foo/baz.mojom")
-    self.assertFalse(dep.is_sdk_dep())
-
-    # In SDK
-    dep = Dependency(FakeRepository(),
-                     "/base/repo/services/bar/bar.mojom",
-                     "mojo/public/baz.mojom")
-    self.assertTrue(dep.is_sdk_dep())
-
-  def test_maybe_is_a_url(self):
-    # Not a URL
-    dep = Dependency(FakeRepository(),
-                     "/base/repo/services/bar/bar.mojom",
-                     "mojo/foo/baz.mojom")
-    self.assertFalse(dep.maybe_is_a_url())
-
-    # URL import from non-external mojom
-    dep = Dependency(FakeRepository(),
-                     "/base/repo/services/bar/bar.mojom",
-                     "foo.bar.com/foo/baz.mojom")
-    self.assertTrue(dep.maybe_is_a_url())
-
-    # URL import from an external mojom
-    dep = Dependency(FakeRepository(),
-                     "/base/repo/third_party/external/" +
-                     "services.bar.com/bar/bar.mojom",
-                     "foo.bar.com/foo/baz.mojom")
-    self.assertTrue(dep.maybe_is_a_url())
-
-    # relative import from an external mojom
-    dep = Dependency(
-        FakeRepository(),
-        "/base/repo/third_party/external/services.bar.com/bar/bar.mojom",
-        "foo/baz.mojom")
-    self.assertTrue(dep.maybe_is_a_url())
-
-    # external mojom importing SDK dep
-    dep = Dependency(
-        FakeRepository(),
-        "/base/repo/third_party/external/services.bar.com/bar/bar.mojom",
-        "mojo/public/foo/baz.mojom")
-    self.assertFalse(dep.maybe_is_a_url())
-
-  def test_generate_candidate_urls_relative(self):
-    dep = Dependency(
-        FakeRepository(),
-        "/base/repo/third_party/external/" +
-            "services.bar.com/bar/interfaces/bar.mojom",
-        "foo/baz.mojom")
-    self.assertTrue(dep.maybe_is_a_url())
-    candidate_urls = dep.generate_candidate_urls()
-    self.assertEqual(["services.bar.com/bar/interfaces/foo/baz.mojom",
-                       "services.bar.com/bar/foo/baz.mojom",
-                       "services.bar.com/foo/baz.mojom"], candidate_urls)
-
-  def test_generate_candidate_urls_absolute(self):
-    dep = Dependency(FakeRepository(),
-                     "/base/repo/services/bar/interfaces/bar.mojom",
-                     "services.foo.com/foo/baz.mojom")
-    self.assertTrue(dep.maybe_is_a_url())
-    candidate_urls = dep.generate_candidate_urls()
-    self.assertEqual(["services.foo.com/foo/baz.mojom"], candidate_urls)
-
-  def test_get_search_path_for_dependency(self):
-    # Absolute
-    dep = Dependency(FakeRepository(),
-                     "/base/repo/services/bar/interfaces/bar.mojom",
-                     "services.foo.com/foo/baz.mojom")
-    self.assertEqual(set(["/base/repo/services/bar/interfaces",
-                          "/base/repo", "/base/repo/third_party/external"]),
-                     dep.get_search_path_for_dependency())
-
-    # Relative
-    dep = Dependency(
-        FakeRepository(),
-        "/base/repo/third_party/external/services.foo.com/bar/bar.mojom",
-        "baz/baz.mojom")
-    self.assertEqual(set([
-        "/base/repo", "/base/repo/third_party/external",
-        "/base/repo/third_party/external/services.foo.com/bar",
-        "/base/repo/third_party/external/services.foo.com"]),
-                     dep.get_search_path_for_dependency())
diff --git a/mojo/tools/testing/mojom_fetcher/fakes.py b/mojo/tools/testing/mojom_fetcher/fakes.py
deleted file mode 100644
index 699d306..0000000
--- a/mojo/tools/testing/mojom_fetcher/fakes.py
+++ /dev/null
@@ -1,113 +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 io
-import os.path
-
-from fetcher.dependency import Dependency
-from fetcher.mojom_file import MojomFile
-from fetcher.repository import Repository
-
-class FakeRepository(Repository):
-  data1 = """module test;
-import "bar/baz.mojom";
-interface Foo {};"""
-  data2 = """module test;
-import "services.domokit.org/foo/fiz.mojom";
-interface Baz {};"""
-  data3 = """module test;
-import "services.fiz.org/foo/bar.mojom";
-interface Fiz {};"""
-  data4 = """module test;
-interface SomeInterface {};"""
-
-  def __init__(self, *args, **kwargs):
-    self.files_opened = []
-    self.directories_walked = []
-    self.all_files_available = False
-
-    Repository.__init__(self, *args, **kwargs)
-
-  def get_walk_base(self, directory):
-    data_base = [
-        (directory, ["foo", "third_party"], []),
-        (os.path.join(directory, "foo"), ["bar"], ["foo.mojom"]),
-        (os.path.join(directory, "foo/bar"), [], ["baz.mojom"]),
-        (os.path.join(directory, "third_party"), ["external"], []),
-        (os.path.join(directory, "third_party/external"),
-         ["services.domokit.org"], []),
-        (os.path.join(directory,
-                      "third_party/external/services.domokit.org"),
-         ["foo"], []),
-        (os.path.join(directory,
-                      "third_party/external/services.domokit.org/foo"),
-         [], ["fiz.mojom"])]
-    if self.all_files_available:
-      data_base.extend([
-          (os.path.join(directory,
-                      "third_party/external/services.fiz.org"),
-           ["foo"], []),
-          (os.path.join(directory,
-                        "third_party/external/services.fiz.org/foo"),
-           [], ["bar.mojom"])])
-    return data_base
-
-  def get_walk_external(self, directory):
-    data_external = [
-        (directory, ["services.domokit.org"], []),
-        (os.path.join(directory, "services.domokit.org"),
-         ["foo"], []),
-        (os.path.join(directory, "services.domokit.org/foo"),
-         [], ["fiz.mojom"])]
-    if self.all_files_available:
-      data_external.extend([
-          (os.path.join(directory, "services.fiz.org"),
-           ["foo"], []),
-          (os.path.join(directory, "services.fiz.org/foo"),
-           [], ["bar.mojom"])])
-    return data_external
-
-
-  def _open(self, f):
-    self.files_opened.append(f)
-
-    if "foo.mojom" in f:
-      val = io.BytesIO(self.data1)
-    elif "baz.mojom" in f:
-      val = io.BytesIO(self.data2)
-    elif "fiz.mojom" in f:
-      val = io.BytesIO(self.data3)
-    else:
-      val = io.BytesIO(self.data4)
-    return val
-
-  def _os_walk(self, directory):
-    self.directories_walked.append(directory)
-    if directory == self._root_dir:
-      return iter(self.get_walk_base(directory))
-    else:
-      return iter(self.get_walk_external(directory))
-
-
-class FakeDependency(Dependency):
-  IN_FILESYSTEM = [
-      "/base/repo/third_party/external/example.com/dir/example.mojom",
-      "/base/repo/third_party/external/example.com/dir/dir.mojom",
-      "/base/repo/third_party/external/domokit.org/bar/baz/buzz.mojom",
-      "/base/repo/third_party/external/domokit.org/bar/foo/bar.mojom",
-      ]
-
-  def _os_path_exists(self, path):
-    if path in self.IN_FILESYSTEM:
-      return True
-    elif os.path.join("/base/repo", path) in self.IN_FILESYSTEM:
-      return True
-    else:
-      return False
-
-
-class FakeMojomFile(MojomFile):
-  def add_dependency(self, dependency):
-    """Declare a new dependency of this mojom."""
-    self.deps.append(FakeDependency(self._repository, self.name, dependency))
diff --git a/mojo/tools/testing/mojom_fetcher/mojom_directory_tests.py b/mojo/tools/testing/mojom_fetcher/mojom_directory_tests.py
deleted file mode 100644
index 0b2f5dd..0000000
--- a/mojo/tools/testing/mojom_fetcher/mojom_directory_tests.py
+++ /dev/null
@@ -1,50 +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 os.path
-import unittest
-
-from fakes import FakeMojomFile
-from fetcher.dependency import Dependency
-from fetcher.mojom_directory import MojomDirectory
-from fetcher.mojom_file import MojomFile
-from fetcher.repository import Repository
-
-
-class TestMojomDirectory(unittest.TestCase):
-  def test_build_gn_path(self):
-    directory = MojomDirectory(
-        "/base/repo/third_party/external/domokit.org/bar/baz")
-    self.assertEquals(
-        "/base/repo/third_party/external/domokit.org/bar/baz/BUILD.gn",
-        directory.get_build_gn_path())
-
-  def test_jinja_parameters(self):
-    mojom = FakeMojomFile(
-        Repository("/base/repo", "third_party/external"),
-        "/base/repo/third_party/external/domokit.org/bar/baz/foo.mojom")
-    mojom.add_dependency("example.com/dir/example.mojom")
-    mojom.add_dependency("example.com/dir/dir.mojom")
-    mojom.add_dependency("buzz.mojom")
-    mojom.add_dependency("foo/bar.mojom")
-    mojom.add_dependency(
-        "mojo/public/interfaces/application/shell.mojom")
-    directory = MojomDirectory(
-        "/base/repo/third_party/external/domokit.org/bar/baz")
-    directory.add_mojom(mojom)
-    params = directory.get_jinja_parameters([])
-    self.assertEquals(
-        {"group_name": "baz",
-         "mojoms": [{
-             "target_name": "foo",
-             "filename": "foo.mojom",
-             "import_dirs": [".."],
-             "mojo_sdk_deps": ["mojo/public/interfaces/application"],
-             "deps": [
-                 '//third_party/external/example.com/dir:example',
-                 '//third_party/external/example.com/dir:dir_mojom',
-                 ':buzz',
-                 '../foo:bar']
-             }]}, params)
-
diff --git a/mojo/tools/testing/mojom_fetcher/mojom_fetcher_tests.py b/mojo/tools/testing/mojom_fetcher/mojom_fetcher_tests.py
deleted file mode 100755
index 8781ffe..0000000
--- a/mojo/tools/testing/mojom_fetcher/mojom_fetcher_tests.py
+++ /dev/null
@@ -1,109 +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.
-
-import io
-import os
-import sys
-import unittest
-
-sys.path.insert(0, os.path.join(os.path.dirname(os.path.abspath(__file__)),
-                                "..", "..", "..", "public", "tools",
-                                "mojom_fetcher"))
-sys.path.insert(0, os.path.join(os.path.dirname(os.path.abspath(__file__)),
-                                "..", "..", "..", "public", "tools",
-                                "mojom_fetcher", "pylib"))
-sys.path.insert(0, os.path.join(os.path.dirname(os.path.abspath(__file__)),
-                                "..", "..", "..", "public", "tools",
-                                "bindings", "pylib"))
-
-from mojom_fetcher import UrlRewriter, UrlRewriterException, MojomFetcher
-
-# Fake repository for testing
-from fakes import FakeRepository
-
-
-class TestUrlRewriter(unittest.TestCase):
-  def test_no_transitive(self):
-    rules = {"foo.com": "bar.com/foo", "bar.com": "baz.com"}
-    try:
-      UrlRewriter(rules)
-      self.fail()
-    except UrlRewriterException:
-      # This is expected
-      pass
-
-  def test_rewrite(self):
-    rules = {"foo.com": "bar.com/foo", "baz.com": "bar.com/baz"}
-    rewriter = UrlRewriter(rules)
-    self.assertEquals("bar.com/foo/foo_file",
-                      rewriter.rewrite("foo.com/foo_file"))
-    self.assertEquals("bar.com/baz/foo_file",
-                      rewriter.rewrite("baz.com/foo_file"))
-    self.assertEquals("example.com/file",
-                      rewriter.rewrite("example.com/file"))
-
-
-class FakeRequest(object):
-  def __init__(self, content, ok):
-    self.content = content
-    self.ok = ok
-
-
-class FakeMojomFetcher(MojomFetcher):
-  data = """module test;
-interface Fiz {};"""
-
-  def __init__(self, repository, rewriter):
-    self.count = 1
-    self.opened_files = {}
-    self.downloaded_urls = []
-    MojomFetcher.__init__(self, repository, rewriter)
-
-  def _requests_get(self, url):
-    self.downloaded_urls.append(url)
-    return FakeRequest(self.data, True)
-
-  def _os_makedirs(self, _):
-    return
-
-  def _open(self, f, _):
-    fake_file = io.BytesIO()
-    self.opened_files[f] = fake_file
-    if "services.fiz.org/foo/bar.mojom" in f:
-      self._repository.all_files_available = True
-    return fake_file
-
-
-class TestMojomFetcher(unittest.TestCase):
-  def setUp(self):
-    self.rules = {"foo.com": "bar.com/foo", "baz.com": "bar.com/baz"}
-    self.rewriter = UrlRewriter(self.rules)
-    self.repository = FakeRepository("/path/to/repo", "third_party/external")
-    self.fetcher = FakeMojomFetcher(self.repository, self.rewriter)
-
-  def test_get(self):
-    self.fetcher.get("foo.com/bar.mojom")
-    self.assertEquals(["https://bar.com/foo/bar.mojom",
-                       "https://services.fiz.org/foo/bar.mojom"],
-                      self.fetcher.downloaded_urls)
-
-  def test_update(self):
-    self.fetcher.update()
-    self.assertEquals(["https://services.domokit.org/foo/fiz.mojom",
-                       "https://services.fiz.org/foo/bar.mojom"],
-                      self.fetcher.downloaded_urls)
-
-  def test_discover(self):
-    self.fetcher.update()
-    self.assertEquals(["https://services.domokit.org/foo/fiz.mojom",
-                       "https://services.fiz.org/foo/bar.mojom"],
-                      self.fetcher.downloaded_urls)
-
-if __name__ == '__main__':
-  loader = unittest.defaultTestLoader
-  runner = unittest.TextTestRunner()
-  directory = os.path.dirname(os.path.abspath(__file__))
-  suite = loader.discover(directory, '*_tests.py')
-  runner.run(suite)
diff --git a/mojo/tools/testing/mojom_fetcher/mojom_file_tests.py b/mojo/tools/testing/mojom_fetcher/mojom_file_tests.py
deleted file mode 100644
index cb5558d..0000000
--- a/mojo/tools/testing/mojom_fetcher/mojom_file_tests.py
+++ /dev/null
@@ -1,44 +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 os.path
-import unittest
-
-from fetcher.mojom_file import MojomFile
-from fetcher.dependency import Dependency
-from fetcher.repository import Repository
-from fakes import FakeDependency, FakeMojomFile
-
-
-class TestMojomFile(unittest.TestCase):
-  def test_add_dependency(self):
-    mojom = MojomFile(Repository("/base/repo", "third_party/external"),
-                      "mojom_name")
-    mojom.add_dependency("dependency_name")
-    self.assertEqual(1, len(mojom.deps))
-    self.assertEqual("mojom_name", mojom.deps[0].get_importer())
-    self.assertEqual("dependency_name", mojom.deps[0].get_imported())
-
-  def test_jinja_parameters(self):
-    mojom = FakeMojomFile(
-        Repository("/base/repo", "third_party/external"),
-        "/base/repo/third_party/external/domokit.org/bar/baz/foo.mojom")
-    mojom.add_dependency("example.com/dir/example.mojom")
-    mojom.add_dependency("example.com/dir/dir.mojom")
-    mojom.add_dependency("buzz.mojom")
-    mojom.add_dependency("foo/bar.mojom")
-    mojom.add_dependency(
-        "mojo/public/interfaces/application/shell.mojom")
-    params = mojom.get_jinja_parameters([])
-    self.assertEquals({
-        "target_name": "foo",
-        "filename": "foo.mojom",
-        "import_dirs": [".."],
-        "mojo_sdk_deps": ["mojo/public/interfaces/application"],
-        "deps": [
-            '//third_party/external/example.com/dir:example',
-            '//third_party/external/example.com/dir:dir_mojom',
-            ':buzz',
-            '../foo:bar']
-        }, params)
diff --git a/mojo/tools/testing/mojom_fetcher/mojom_gn_tests.py b/mojo/tools/testing/mojom_fetcher/mojom_gn_tests.py
deleted file mode 100644
index 11e61b3..0000000
--- a/mojo/tools/testing/mojom_fetcher/mojom_gn_tests.py
+++ /dev/null
@@ -1,88 +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 io
-import os.path
-import unittest
-
-from fakes import FakeMojomFile
-from fetcher.mojom_directory import MojomDirectory
-from fetcher.repository import Repository
-from mojom_gn import BuildGNGenerator
-
-class FakeRepository(Repository):
-  def get_all_external_mojom_directories(self):
-    mojom = FakeMojomFile(
-        self, os.path.join(self.get_external_directory(),
-                           "domokit.org/bar/baz/foo.mojom"))
-    mojom.add_dependency("example.com/dir/example.mojom")
-    mojom.add_dependency("example.com/dir/dir.mojom")
-    mojom.add_dependency("buzz.mojom")
-    mojom.add_dependency("foo/bar.mojom")
-    mojom.add_dependency(
-        "mojo/public/interfaces/application/shell.mojom")
-    directory = MojomDirectory(
-        os.path.join(self.get_external_directory(),
-                     "domokit.org/bar/baz"))
-    directory.add_mojom(mojom)
-    return [directory]
-
-
-class FakeBuildGNGenerator(BuildGNGenerator):
-  def __init__(self, *args, **kwargs):
-    self.opened_files = {}
-    BuildGNGenerator.__init__(self, *args, **kwargs)
-
-  def _open(self, filepath, mode):
-    if mode != "w":
-      raise Exception("Invalid mode " + str(mode))
-    self.opened_files[filepath] = io.StringIO()
-    return self.opened_files[filepath]
-
-
-class TestBuildGNGenerator(unittest.TestCase):
-  BAZ_BUILD_GN = u"""import("//build/module_args/mojo.gni")
-import("$mojo_sdk_root/mojo/public/tools/bindings/mojom.gni")
-
-mojom("baz") {
-  deps = [
-    ":foo",
-  ]
-}
-
-mojom("foo") {
-  sources = [
-    "foo.mojom",
-  ]
-  import_dirs = [
-    get_path_info("..", "abspath"),
-  ]
-  mojo_sdk_deps = [
-    "mojo/public/interfaces/application",
-  ]
-  deps = [
-    "//third_party/external/example.com/dir:example",
-    "//third_party/external/example.com/dir:dir_mojom",
-    ":buzz",
-    "../foo:bar",
-  ]
-}"""
-  def test_generate(self):
-    self.maxDiff = None
-    repository = FakeRepository("/base/repo", "third_party/external")
-    gn_generator = FakeBuildGNGenerator(repository, os.path.abspath(
-        os.path.join(os.path.dirname(__file__),
-                     "../../../public/tools/mojom_fetcher")))
-    gn_generator.generate()
-    output_stream = gn_generator.opened_files[
-        "/base/repo/third_party/external/domokit.org/bar/baz/BUILD.gn"]
-    self.assertEquals(prepare_string(self.BAZ_BUILD_GN),
-                      prepare_string(output_stream.getvalue()))
-
-def prepare_string(value):
-  lines = value.split("\n")
-  lines = map(lambda l: l.strip().replace(" ", ""), lines)
-  lines = filter(lambda l: not l.startswith("#"), lines)
-  return ''.join(lines)
-
diff --git a/mojo/tools/testing/mojom_fetcher/repository_tests.py b/mojo/tools/testing/mojom_fetcher/repository_tests.py
deleted file mode 100644
index 46724d1..0000000
--- a/mojo/tools/testing/mojom_fetcher/repository_tests.py
+++ /dev/null
@@ -1,43 +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 io
-import os.path
-import unittest
-
-from fetcher.dependency import Dependency
-
-# Fake repository for testing
-from fakes import FakeRepository
-
-
-class TestRepository(unittest.TestCase):
-  def test_init(self):
-    repository = FakeRepository("/path/to/repo", "third_party/external")
-    self.assertEqual("/path/to/repo", repository.get_repo_root_directory())
-    self.assertEqual("/path/to/repo/third_party/external",
-                     repository.get_external_directory())
-
-  def test_get_missing_dependencies(self):
-    repository = FakeRepository("/path/to/repo", "third_party/external")
-    missing_deps = repository.get_missing_dependencies()
-    self.assertEquals(["/path/to/repo"], repository.directories_walked)
-    # Order is not important
-    self.assertIn("/path/to/repo/foo/foo.mojom", repository.files_opened)
-    self.assertIn("/path/to/repo/foo/bar/baz.mojom", repository.files_opened)
-    self.assertIn(
-        "/path/to/repo/third_party/external/services.domokit.org/foo/fiz.mojom",
-        repository.files_opened)
-    self.assertEquals(3, len(repository.files_opened))
-
-    self.assertEquals([Dependency(repository,
-        "/path/to/repo/third_party/external/services.domokit.org/foo/fiz.mojom",
-        "services.fiz.org/foo/bar.mojom")], missing_deps)
-
-  def test_get_external_urls(self):
-    repository = FakeRepository("/path/to/repo", "third_party/external")
-    urls = repository.get_external_urls()
-    self.assertEquals(["/path/to/repo/third_party/external"],
-                      repository.directories_walked)
-    self.assertEquals(["services.domokit.org/foo/fiz.mojom"], urls)
diff --git a/mojo/tools/upload_binaries.py b/mojo/tools/upload_binaries.py
deleted file mode 100755
index d1c25cc..0000000
--- a/mojo/tools/upload_binaries.py
+++ /dev/null
@@ -1,234 +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.
-
-"""Tool to roll Chromium into Mojo. See:
-https://github.com/domokit/mojo/wiki/Rolling-code-between-chromium-and-mojo#chromium---mojo-updates
-"""
-
-import argparse
-import glob
-import itertools
-import os
-import subprocess
-import sys
-import tempfile
-import time
-import zipfile
-
-import mopy.gn as gn
-from mopy.config import Config
-from mopy.paths import Paths
-from mopy.version import Version
-
-sys.path.append(os.path.join(os.path.dirname(__file__), os.pardir, os.pardir,
-                             "third_party", "pyelftools"))
-import elftools.elf.elffile as elffile
-
-sys.path.append(os.path.join(os.path.dirname(__file__), os.pardir,
-                             'devtools', 'common'))
-import android_gdb.signatures as signatures
-
-
-BLACKLISTED_APPS = [
-  # The network service apps are not produced out of the Mojo repo, but may
-  # be present in the build dir.
-  "network_service.mojo",
-  "network_service_apptests.mojo",
-]
-
-ARCHITECTURE_INDEPENDENT_FILES = [
-  # These are files other than *.mojo files which are part of our binary
-  # artifact scheme. These files must be architecture independent.
-  "obj/mojo/dart/apptest/apptest.dartzip",
-]
-
-
-def target(config):
-  target_name = config.target_os + "-" + config.target_cpu
-  if config.is_official_build:
-    target_name += "-official"
-  return target_name
-
-def find_apps_to_upload(build_dir):
-  apps = []
-  for path in glob.glob(build_dir + "/*"):
-    if not os.path.isfile(path):
-      continue
-    _, ext = os.path.splitext(path)
-    if ext != '.mojo':
-      continue
-    if os.path.basename(path) in BLACKLISTED_APPS:
-      continue
-    apps.append(path)
-  return apps
-
-
-def find_architecture_independent_files(build_dir):
-  existing_files = []
-  for path in ARCHITECTURE_INDEPENDENT_FILES:
-    joined_path = os.path.join(build_dir, path)
-    if os.path.isfile(joined_path):
-      existing_files.append(joined_path)
-  return existing_files
-
-
-def check_call(command_line, dry_run, **kwargs):
-  if dry_run:
-    print command_line
-  else:
-    subprocess.check_call(command_line, **kwargs)
-
-
-def upload(config, source, dest, dry_run, gzip=False):
-  paths = Paths(config)
-  sys.path.insert(0, os.path.join(paths.src_root, "tools"))
-  # pylint: disable=F0401
-  import find_depot_tools
-
-  depot_tools_path = find_depot_tools.add_depot_tools_to_path()
-  gsutil_exe = os.path.join(depot_tools_path, "third_party", "gsutil", "gsutil")
-
-  command_line = [gsutil_exe, "cp"]
-  if gzip and "." in source:
-    extension = source.split(".")[-1]
-    command_line.extend(["-z", extension])
-  command_line.extend([source, dest])
-
-  check_call(command_line, dry_run)
-
-
-def upload_symbols(config, build_dir, breakpad_upload_urls, dry_run):
-  dump_syms_exe = os.path.join(Paths().src_root,
-                               "mojo", "tools", "linux64", "dump_syms")
-  symupload_exe = os.path.join(Paths().src_root,
-                               "mojo", "tools", "linux64", "symupload")
-  dest_dir = "gs://mojo/symbols/"
-  symbols_dir = os.path.join(build_dir, "symbols")
-  with open(os.devnull, "w") as devnull:
-    for name in os.listdir(symbols_dir):
-      path = os.path.join(symbols_dir, name)
-      with open(path) as f:
-        signature = signatures.get_signature(f, elffile)
-        if signature is not None:
-          dest = dest_dir + signature
-          upload(config, path, dest, dry_run)
-      if breakpad_upload_urls:
-        with tempfile.NamedTemporaryFile() as temp:
-          check_call([dump_syms_exe, path], dry_run,
-                     stdout=temp, stderr=devnull)
-          temp.flush()
-          for upload_url in breakpad_upload_urls:
-            check_call([symupload_exe, temp.name, upload_url], dry_run)
-
-def upload_shell(config, dry_run, verbose):
-  paths = Paths(config)
-  zipfile_name = target(config)
-  version = Version().version
-
-  # Upload the binary.
-  # TODO(blundell): Change this to be in the same structure as the LATEST files,
-  # e.g., gs://mojo/shell/linux-x64/<version>/shell.zip.
-  dest = "gs://mojo/shell/" + version + "/" + zipfile_name + ".zip"
-  with tempfile.NamedTemporaryFile() as zip_file:
-    with zipfile.ZipFile(zip_file, 'w') as z:
-      shell_path = paths.target_mojo_shell_path
-      with open(shell_path) as shell_binary:
-        shell_filename = os.path.basename(shell_path)
-        zipinfo = zipfile.ZipInfo(shell_filename)
-        zipinfo.external_attr = 0777 << 16L
-        compress_type = zipfile.ZIP_DEFLATED
-        if config.target_os == Config.OS_ANDROID:
-          # The APK is already compressed.
-          compress_type = zipfile.ZIP_STORED
-        zipinfo.compress_type = compress_type
-        zipinfo.date_time = time.gmtime(os.path.getmtime(shell_path))
-        if verbose:
-          print "zipping %s" % shell_path
-        z.writestr(zipinfo, shell_binary.read())
-    upload(config, zip_file.name, dest, dry_run, gzip=False)
-
-  # Update the LATEST file to contain the version of the new binary.
-  latest_file = "gs://mojo/shell/%s/LATEST" % target(config)
-  write_file_to_gs(version, latest_file, config, dry_run)
-
-
-def upload_app(app_binary_path, config, dry_run):
-  app_binary_name = os.path.basename(app_binary_path)
-  version = Version().version
-  gsutil_app_location = ("gs://mojo/services/%s/%s/%s" %
-                         (target(config), version, app_binary_name))
-
-  # Upload the new binary.
-  upload(config, app_binary_path, gsutil_app_location, dry_run)
-
-
-def upload_file(file_path, config, dry_run):
-  file_binary_name = os.path.basename(file_path)
-  version = Version().version
-  gsutil_file_location = "gs://mojo/file/%s/%s" % (version, file_binary_name)
-
-  # Upload the new binary.
-  upload(config, file_path, gsutil_file_location, dry_run)
-
-
-def write_file_to_gs(file_contents, dest, config, dry_run):
-  with tempfile.NamedTemporaryFile() as temp_version_file:
-    temp_version_file.write(file_contents)
-    temp_version_file.flush()
-    upload(config, temp_version_file.name, dest, dry_run)
-
-
-def main():
-  parser = argparse.ArgumentParser(description="Upload binaries for apps and "
-      "the Mojo shell to google storage (by default on Linux, but this can be "
-      "changed via options).")
-  parser.add_argument("-n", "--dry_run", help="Dry run, do not actually "+
-      "upload", action="store_true")
-  parser.add_argument("-v", "--verbose", help="Verbose mode",
-      action="store_true")
-  parser.add_argument("--android",
-                      action="store_true",
-                      help="Upload the shell and apps for Android")
-  parser.add_argument("--official",
-                      action="store_true",
-                      help="Upload the official build of the Android shell")
-  parser.add_argument("--symbols-upload-url",
-                      action="append", default=[],
-                      help="URL of the server to upload breakpad symbols to")
-  args = parser.parse_args()
-
-  is_official_build = args.official
-  target_os = Config.OS_LINUX
-  if args.android:
-    target_os = Config.OS_ANDROID
-  elif is_official_build:
-    print "Uploading official builds is only supported for android."
-    return 1
-
-  config = Config(target_os=target_os, is_debug=False,
-                  is_official_build=is_official_build)
-
-  upload_shell(config, args.dry_run, args.verbose)
-
-  if is_official_build:
-    print "Skipping uploading apps (official apk build)."
-    return 0
-
-  build_directory = gn.BuildDirectoryForConfig(config, Paths(config).src_root)
-  apps_to_upload = find_apps_to_upload(build_directory)
-  for app in apps_to_upload:
-    upload_app(app, config, args.dry_run)
-
-  files_to_upload = find_architecture_independent_files(build_directory)
-  for file_to_upload in files_to_upload:
-    upload_file(file_to_upload, config, args.dry_run)
-
-  upload_symbols(config, build_directory,
-                 args.symbols_upload_url, args.dry_run)
-
-  return 0
-
-if __name__ == "__main__":
-  sys.exit(main())
diff --git a/services/asset_bundle/BUILD.gn b/services/asset_bundle/BUILD.gn
index 8d98859..7c38a37 100644
--- a/services/asset_bundle/BUILD.gn
+++ b/services/asset_bundle/BUILD.gn
@@ -16,7 +16,7 @@
 
   deps = [
     "//base",
-    "//mojo/common",
+    "//mojo/data_pipe_utils",
     "//mojo/public/cpp/bindings:callback",
     "//mojo/public/cpp/system",
     "//mojo/services/asset_bundle/public/interfaces",
@@ -32,7 +32,6 @@
   deps = [
     "//base",
     "//mojo/application",
-    "//mojo/common",
     "//mojo/public/cpp/application",
     "//mojo/public/cpp/bindings:callback",
     "//mojo/public/cpp/system",
@@ -54,7 +53,7 @@
     "//base",
     "//mojo/application",
     "//mojo/application:test_support",
-    "//mojo/common",
+    "//mojo/data_pipe_utils",
     "//mojo/public/cpp/bindings",
     "//mojo/services/asset_bundle/public/interfaces",
     "//third_party/zlib:zip",
diff --git a/services/asset_bundle/asset_bundle_apptest.cc b/services/asset_bundle/asset_bundle_apptest.cc
index 4fd9849..c449796 100644
--- a/services/asset_bundle/asset_bundle_apptest.cc
+++ b/services/asset_bundle/asset_bundle_apptest.cc
@@ -7,8 +7,7 @@
 #include "base/files/file_util.h"
 #include "base/files/scoped_temp_dir.h"
 #include "base/run_loop.h"
-#include "mojo/common/common_type_converters.h"
-#include "mojo/common/data_pipe_utils.h"
+#include "mojo/data_pipe_utils/data_pipe_utils.h"
 #include "mojo/public/cpp/application/application_impl.h"
 #include "mojo/public/cpp/application/application_test_base.h"
 #include "mojo/services/asset_bundle/public/interfaces/asset_bundle.mojom.h"
diff --git a/services/asset_bundle/asset_bundle_impl.cc b/services/asset_bundle/asset_bundle_impl.cc
index 0c3bd34..8776641 100644
--- a/services/asset_bundle/asset_bundle_impl.cc
+++ b/services/asset_bundle/asset_bundle_impl.cc
@@ -8,7 +8,7 @@
 #include "base/files/file_path.h"
 #include "base/files/file_util.h"
 #include "base/logging.h"
-#include "mojo/common/data_pipe_utils.h"
+#include "mojo/data_pipe_utils/data_pipe_utils.h"
 
 namespace mojo {
 namespace asset_bundle {
diff --git a/services/asset_bundle/asset_unpacker_job.h b/services/asset_bundle/asset_unpacker_job.h
index 66c2b33..ed7cddc 100644
--- a/services/asset_bundle/asset_unpacker_job.h
+++ b/services/asset_bundle/asset_unpacker_job.h
@@ -9,7 +9,7 @@
 #include "base/macros.h"
 #include "base/memory/weak_ptr.h"
 #include "base/task_runner.h"
-#include "mojo/common/data_pipe_utils.h"
+#include "mojo/data_pipe_utils/data_pipe_utils.h"
 #include "mojo/public/cpp/bindings/interface_request.h"
 #include "mojo/services/asset_bundle/public/interfaces/asset_bundle.mojom.h"
 
diff --git a/services/sky/BUILD.gn b/services/sky/BUILD.gn
index 90ee461..4b15f98 100644
--- a/services/sky/BUILD.gn
+++ b/services/sky/BUILD.gn
@@ -30,7 +30,6 @@
 
   deps = [
     "//mojo/application",
-    "//mojo/common",
     "//mojo/common:tracing_impl",
     "//mojo/converters/geometry",
     "//mojo/converters/input_events",
diff --git a/sky/engine/bindings/BUILD.gn b/sky/engine/bindings/BUILD.gn
index 03a4299..509a207 100644
--- a/sky/engine/bindings/BUILD.gn
+++ b/sky/engine/bindings/BUILD.gn
@@ -376,7 +376,6 @@
     "//dart/runtime:libdart",
     "//dart/runtime/vm:libdart_platform",
     "//mojo/application",
-    "//mojo/common",
     "//mojo/public/c/system",
     "//mojo/public/cpp/bindings",
     "//mojo/public/cpp/system",
diff --git a/sky/engine/core/BUILD.gn b/sky/engine/core/BUILD.gn
index e655074..45103f2 100644
--- a/sky/engine/core/BUILD.gn
+++ b/sky/engine/core/BUILD.gn
@@ -14,7 +14,7 @@
   public_deps = [
     "//base",
     "//mojo/application",
-    "//mojo/common",
+    "//mojo/data_pipe_utils",
     "//mojo/public/c/system",
     "//mojo/public/cpp/bindings",
     "//mojo/public/cpp/system",
diff --git a/sky/engine/core/loader/CanvasImageDecoder.h b/sky/engine/core/loader/CanvasImageDecoder.h
index 8d545db..020a548 100644
--- a/sky/engine/core/loader/CanvasImageDecoder.h
+++ b/sky/engine/core/loader/CanvasImageDecoder.h
@@ -7,7 +7,7 @@
 #define SKY_ENGINE_CORE_LOADER_CANVASIMAGELOADER_H_
 
 #include "base/memory/weak_ptr.h"
-#include "mojo/common/data_pipe_drainer.h"
+#include "mojo/data_pipe_utils/data_pipe_drainer.h"
 #include "sky/engine/core/loader/ImageDecoderCallback.h"
 #include "sky/engine/platform/SharedBuffer.h"
 #include "sky/engine/tonic/dart_wrappable.h"
diff --git a/sky/engine/core/script/dart_controller.cc b/sky/engine/core/script/dart_controller.cc
index 8f9bb0a..eca1102 100644
--- a/sky/engine/core/script/dart_controller.cc
+++ b/sky/engine/core/script/dart_controller.cc
@@ -9,7 +9,7 @@
 #include "base/single_thread_task_runner.h"
 #include "base/trace_event/trace_event.h"
 #include "dart/runtime/include/dart_tools_api.h"
-#include "mojo/common/data_pipe_utils.h"
+#include "mojo/data_pipe_utils/data_pipe_utils.h"
 #include "mojo/public/cpp/system/data_pipe.h"
 #include "sky/engine/bindings/builtin.h"
 #include "sky/engine/bindings/builtin_natives.h"
diff --git a/sky/engine/platform/BUILD.gn b/sky/engine/platform/BUILD.gn
index db9d9cb..281a3f5 100644
--- a/sky/engine/platform/BUILD.gn
+++ b/sky/engine/platform/BUILD.gn
@@ -542,7 +542,6 @@
     ":make_platform_generated",
     "//base:base",
     "//mojo/application",
-    "//mojo/common",
     "//mojo/environment:chromium",
     "//mojo/public/c/system",
     "//mojo/public/cpp/bindings",
diff --git a/sky/engine/tonic/BUILD.gn b/sky/engine/tonic/BUILD.gn
index 4f37841..cbcc08c 100644
--- a/sky/engine/tonic/BUILD.gn
+++ b/sky/engine/tonic/BUILD.gn
@@ -57,7 +57,7 @@
 
   deps = [
     "//base",
-    "//mojo/common",
+    "//mojo/data_pipe_utils",
     "//mojo/public/cpp/system",
     "//sky/engine/wtf",
   ]
diff --git a/sky/engine/tonic/dart_library_loader.cc b/sky/engine/tonic/dart_library_loader.cc
index 93c4587..0b65fd6 100644
--- a/sky/engine/tonic/dart_library_loader.cc
+++ b/sky/engine/tonic/dart_library_loader.cc
@@ -6,7 +6,7 @@
 
 #include "base/callback.h"
 #include "base/trace_event/trace_event.h"
-#include "mojo/common/data_pipe_drainer.h"
+#include "mojo/data_pipe_utils/data_pipe_drainer.h"
 #include "sky/engine/tonic/dart_api_scope.h"
 #include "sky/engine/tonic/dart_converter.h"
 #include "sky/engine/tonic/dart_dependency_catcher.h"
diff --git a/sky/engine/tonic/dart_snapshot_loader.h b/sky/engine/tonic/dart_snapshot_loader.h
index 53edb04..a1f7356 100644
--- a/sky/engine/tonic/dart_snapshot_loader.h
+++ b/sky/engine/tonic/dart_snapshot_loader.h
@@ -11,7 +11,7 @@
 #include "base/macros.h"
 #include "base/memory/weak_ptr.h"
 #include "dart/runtime/include/dart_api.h"
-#include "mojo/common/data_pipe_drainer.h"
+#include "mojo/data_pipe_utils/data_pipe_drainer.h"
 
 namespace blink {
 class DartState;
diff --git a/sky/engine/web/BUILD.gn b/sky/engine/web/BUILD.gn
index 5d21211..57185be 100644
--- a/sky/engine/web/BUILD.gn
+++ b/sky/engine/web/BUILD.gn
@@ -2,10 +2,9 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
-component("web") {
-  output_name = "sky_web"
-
+source_set("web") {
   deps = [
+    "//mojo/message_pump",
     "//sky/engine/core",
     "//sky/engine/platform",
   ]
diff --git a/sky/engine/web/Sky.cpp b/sky/engine/web/Sky.cpp
index c06612b..4abd634 100644
--- a/sky/engine/web/Sky.cpp
+++ b/sky/engine/web/Sky.cpp
@@ -33,7 +33,7 @@
 #include "base/message_loop/message_loop.h"
 #include "base/rand_util.h"
 #include "gen/sky/platform/RuntimeEnabledFeatures.h"
-#include "mojo/common/message_pump_mojo.h"
+#include "mojo/message_pump/message_pump_mojo.h"
 #include "sky/engine/core/dom/Microtask.h"
 #include "sky/engine/core/frame/Settings.h"
 #include "sky/engine/core/Init.h"
diff --git a/sky/services/keyboard/BUILD.gn b/sky/services/keyboard/BUILD.gn
index c7320c1..7b6fd1a 100644
--- a/sky/services/keyboard/BUILD.gn
+++ b/sky/services/keyboard/BUILD.gn
@@ -10,7 +10,6 @@
     ]
     deps = [
       "//base:base",
-      "//mojo/common",
       "//mojo/public/cpp/application",
       "//mojo/services/keyboard/public/interfaces",
     ]
diff --git a/sky/services/media/BUILD.gn b/sky/services/media/BUILD.gn
index f149bc2..af7ad39 100644
--- a/sky/services/media/BUILD.gn
+++ b/sky/services/media/BUILD.gn
@@ -50,7 +50,7 @@
     deps = [
       ":interfaces",
       "//base:base",
-      "//mojo/common",
+      "//mojo/data_pipe_utils",
       "//mojo/public/cpp/application",
     ]
   }
diff --git a/sky/services/media/ios/media_player_impl.mm b/sky/services/media/ios/media_player_impl.mm
index 718dfa4..0250a93 100644
--- a/sky/services/media/ios/media_player_impl.mm
+++ b/sky/services/media/ios/media_player_impl.mm
@@ -4,7 +4,7 @@
 
 #include "base/bind.h"
 #include "base/message_loop/message_loop.h"
-#include "mojo/common/data_pipe_utils.h"
+#include "mojo/data_pipe_utils/data_pipe_utils.h"
 #include "sky/services/media/ios/media_player_impl.h"
 
 #import <Foundation/Foundation.h>
diff --git a/sky/services/ns_net/BUILD.gn b/sky/services/ns_net/BUILD.gn
index ab7a5eb..6905604 100644
--- a/sky/services/ns_net/BUILD.gn
+++ b/sky/services/ns_net/BUILD.gn
@@ -12,7 +12,6 @@
 
   deps = [
     "//base:base",
-    "//mojo/common",
     "//mojo/public/cpp/application",
     "//mojo/services/network/public/interfaces",
   ]
diff --git a/sky/shell/BUILD.gn b/sky/shell/BUILD.gn
index 5939a85..196b28d 100644
--- a/sky/shell/BUILD.gn
+++ b/sky/shell/BUILD.gn
@@ -7,8 +7,9 @@
   "//base:i18n",
   "//build/config/sanitizers:deps",
   "//dart/runtime:libdart",
-  "//mojo/common",
+  "//mojo/data_pipe_utils",
   "//mojo/edk/system",
+  "//mojo/message_pump",
   "//mojo/public/cpp/application",
   "//mojo/public/interfaces/application",
   "//mojo/services/asset_bundle/public/interfaces",
@@ -244,6 +245,7 @@
 
     deps = common_deps + [
              ":common",
+             "//mojo/common",
              "//sky/services/testing:interfaces",
            ]
   }
diff --git a/sky/shell/dart/BUILD.gn b/sky/shell/dart/BUILD.gn
index b4a1cf5..06d83f1 100644
--- a/sky/shell/dart/BUILD.gn
+++ b/sky/shell/dart/BUILD.gn
@@ -14,7 +14,7 @@
     "//base",
     "//build/config/sanitizers:deps",
     "//dart/runtime:libdart",
-    "//mojo/common",
+    "//mojo/data_pipe_utils",
     "//mojo/public/cpp/application",
     "//mojo/services/network/public/interfaces",
     "//sky/engine/tonic",
diff --git a/sky/shell/dart/dart_library_provider_files.cc b/sky/shell/dart/dart_library_provider_files.cc
index 948e083..1b5e78c 100644
--- a/sky/shell/dart/dart_library_provider_files.cc
+++ b/sky/shell/dart/dart_library_provider_files.cc
@@ -8,7 +8,7 @@
 #include "base/files/file_util.h"
 #include "base/strings/string_util.h"
 #include "base/threading/worker_pool.h"
-#include "mojo/common/data_pipe_utils.h"
+#include "mojo/data_pipe_utils/data_pipe_utils.h"
 #include "sky/engine/tonic/dart_converter.h"
 
 namespace sky {
diff --git a/sky/shell/shell.cc b/sky/shell/shell.cc
index 07658ad..78e4960 100644
--- a/sky/shell/shell.cc
+++ b/sky/shell/shell.cc
@@ -10,7 +10,7 @@
 #include "base/memory/discardable_memory.h"
 #include "base/memory/discardable_memory_allocator.h"
 #include "base/single_thread_task_runner.h"
-#include "mojo/common/message_pump_mojo.h"
+#include "mojo/message_pump/message_pump_mojo.h"
 #include "mojo/edk/embedder/embedder.h"
 #include "mojo/edk/embedder/simple_platform_support.h"
 #include "sky/shell/ui/engine.h"
diff --git a/sky/shell/tracing_controller.h b/sky/shell/tracing_controller.h
index 0c6a8bc..4514cc8 100644
--- a/sky/shell/tracing_controller.h
+++ b/sky/shell/tracing_controller.h
@@ -8,7 +8,7 @@
 #include "base/files/file.h"
 #include "base/macros.h"
 #include "base/memory/ref_counted_memory.h"
-#include "mojo/common/data_pipe_drainer.h"
+#include "mojo/data_pipe_utils/data_pipe_drainer.h"
 #include "mojo/public/cpp/system/data_pipe.h"
 #include "sky/shell/shell_view.h"
 
diff --git a/sky/shell/ui/engine.cc b/sky/shell/ui/engine.cc
index 058efdc..8c31cae 100644
--- a/sky/shell/ui/engine.cc
+++ b/sky/shell/ui/engine.cc
@@ -9,7 +9,7 @@
 #include "base/files/file_path.h"
 #include "base/threading/worker_pool.h"
 #include "base/trace_event/trace_event.h"
-#include "mojo/common/data_pipe_utils.h"
+#include "mojo/data_pipe_utils/data_pipe_utils.h"
 #include "mojo/public/cpp/application/connect.h"
 #include "services/asset_bundle/asset_unpacker_job.h"
 #include "sky/engine/public/platform/WebInputEvent.h"
diff --git a/sky/tools/roll/patches/mojo/mojo_converters_input_events.patch b/sky/tools/roll/patches/mojo/mojo_converters_input_events.patch
new file mode 100644
index 0000000..8434aca
--- /dev/null
+++ b/sky/tools/roll/patches/mojo/mojo_converters_input_events.patch
@@ -0,0 +1,20 @@
+diff --git b/mojo/converters/input_events/input_events_type_converters.cc a/mojo/converters/input_events/input_events_type_converters.cc
+index a4f6e73..a7d6a97 100644
+--- b/mojo/converters/input_events/input_events_type_converters.cc
++++ a/mojo/converters/input_events/input_events_type_converters.cc
+@@ -11,7 +11,6 @@
+ #include <X11/Xlib.h>
+ #endif
+ 
+-#include "base/time/time.h"
+ #include "mojo/converters/geometry/geometry_type_converters.h"
+ #include "mojo/converters/input_events/mojo_extended_key_event_data.h"
+ #include "mojo/services/input_events/public/interfaces/input_events.mojom.h"
+@@ -278,7 +277,6 @@ scoped_ptr<ui::Event> TypeConverter<scoped_ptr<ui::Event>, EventPtr>::Convert(
+         // TODO: last flags isn't right. Need to send changed_flags.
+         scoped_ptr<ui::MouseEvent> event(new ui::MouseEvent(
+             MojoMouseEventTypeToUIEvent(input), location, screen_location,
+-            base::TimeDelta::FromMilliseconds(input->time_stamp),
+             ui::EventFlags(input->flags), ui::EventFlags(input->flags)));
+         if (event->IsMouseWheelEvent()) {
+           // This conversion assumes we're using the mojo meaning of these
diff --git a/sky/tools/roll/patches/mojo/services_keyboard.patch b/sky/tools/roll/patches/mojo/services_keyboard.patch
new file mode 100644
index 0000000..d1180aa
--- /dev/null
+++ b/sky/tools/roll/patches/mojo/services_keyboard.patch
@@ -0,0 +1,30 @@
+diff --git a/services/keyboard/src/org/chromium/mojo/keyboard/InputConnectionAdaptor.java b/services/keyboard/src/org/chromium/mojo/keyboard/InputConnectionAdaptor.java
+index 42bdd57..a3cdc61 100644
+--- a/services/keyboard/src/org/chromium/mojo/keyboard/InputConnectionAdaptor.java
++++ b/services/keyboard/src/org/chromium/mojo/keyboard/InputConnectionAdaptor.java
+@@ -4,7 +4,10 @@
+ 
+ package org.chromium.mojo.keyboard;
+ 
++import java.lang.StringBuilder;
++
+ import android.view.View;
++import android.view.KeyEvent;
+ import android.view.inputmethod.BaseInputConnection;
+ import android.view.inputmethod.CompletionInfo;
+ import android.view.inputmethod.CorrectionInfo;
+@@ -71,4 +74,14 @@ public class InputConnectionAdaptor extends BaseInputConnection {
+         mClient.setSelection(start, end);
+         return super.setSelection(start, end);
+     }
++
++    // Number keys come through as key events instead of commitText!?
++    @Override
++    public boolean sendKeyEvent(KeyEvent event) {
++        if (event.getAction() == KeyEvent.ACTION_UP) {
++            // 1 appears to always be the value for newCursorPosition?
++            mClient.commitText(String.valueOf(event.getNumber()), 1);
++        }
++        return super.sendKeyEvent(event);
++    }
+ }
diff --git a/sky/tools/roll/roll.py b/sky/tools/roll/roll.py
index a066a7f..c66fb7b 100755
--- a/sky/tools/roll/roll.py
+++ b/sky/tools/roll/roll.py
@@ -72,7 +72,21 @@
 
 dirs_from_mojo = [
     'gpu',
-    'mojo',
+    'mojo/android',
+    'mojo/application',
+    'mojo/common',
+    'mojo/converters',
+    'mojo/dart',
+    'mojo/data_pipe_utils',
+    'mojo/edk',
+    'mojo/environment',
+    'mojo/gles2',
+    'mojo/gpu',
+    'mojo/icu',
+    'mojo/java',
+    'mojo/message_pump',
+    'mojo/services',
+    'mojo/skia',
     'services/asset_bundle',
     'services/keyboard',
     'services/sensors',