Update mojo sdk to rev e01f9a49449381a5eb430c1fd88bf2cae73ec35a

Includes updates to ipc/mojo/ipc_channel_mojo.cc for mojo::embedder API
changes and updates to use mojo::Binding<> in ui/keyboard and
device/battery.

Review URL: https://codereview.chromium.org/728133002

Cr-Commit-Position: refs/heads/master@{#304731}


CrOS-Libchrome-Original-Commit: a9125266d3fc89ff0bfd4c3a05bf2f31ffaeff1f
diff --git a/ipc/mojo/ipc_channel_mojo.cc b/ipc/mojo/ipc_channel_mojo.cc
index 4051bb5..36e5bae 100644
--- a/ipc/mojo/ipc_channel_mojo.cc
+++ b/ipc/mojo/ipc_channel_mojo.cc
@@ -168,7 +168,7 @@
 
 void ChannelMojo::ChannelInfoDeleter::operator()(
     mojo::embedder::ChannelInfo* ptr) const {
-  mojo::embedder::DestroyChannelOnIOThread(ptr);
+  mojo::embedder::DestroyChannel(ptr);
 }
 
 //------------------------------------------------------------------------------
diff --git a/mojo/edk/embedder/channel_info_forward.h b/mojo/edk/embedder/channel_info_forward.h
index 494d5ef..8d23836 100644
--- a/mojo/edk/embedder/channel_info_forward.h
+++ b/mojo/edk/embedder/channel_info_forward.h
@@ -9,23 +9,14 @@
 #define MOJO_EDK_EMBEDDER_CHANNEL_INFO_FORWARD_H_
 
 namespace mojo {
-
-// Forward declare |system::ChannelInfo|, so that we can typedef it to
-// |embedder::ChannelInfo|. Users of the embedder API shouldn't use this
-// directly; instead they should use |embedder::ChannelInfo|.
-namespace system {
-struct ChannelInfo;
-}
-
 namespace embedder {
 
 // This is an opaque type. The embedder API uses (returns and takes as
 // arguments) pointers to this type. (We don't simply use |void*|, so that
 // custom deleters and such can be used without additional wrappers.
-typedef system::ChannelInfo ChannelInfo;
+struct ChannelInfo;
 
 }  // namespace embedder
-
 }  // namespace mojo
 
 #endif  // MOJO_EDK_EMBEDDER_CHANNEL_INFO_FORWARD_H_
diff --git a/mojo/edk/embedder/channel_init.cc b/mojo/edk/embedder/channel_init.cc
index 9ea984b..0e7a7b6 100644
--- a/mojo/edk/embedder/channel_init.cc
+++ b/mojo/edk/embedder/channel_init.cc
@@ -25,12 +25,11 @@
   DCHECK(!io_thread_task_runner_.get());  // Should only init once.
   io_thread_task_runner_ = io_thread_task_runner;
   ScopedMessagePipeHandle message_pipe =
-      CreateChannel(ScopedPlatformHandle(PlatformHandle(file)),
-                    io_thread_task_runner,
-                    base::Bind(&ChannelInit::OnCreatedChannel,
-                               weak_factory_.GetWeakPtr(),
-                               io_thread_task_runner),
-                    base::MessageLoop::current()->message_loop_proxy()).Pass();
+      CreateChannel(
+          ScopedPlatformHandle(PlatformHandle(file)), io_thread_task_runner,
+          base::Bind(&ChannelInit::OnCreatedChannel, weak_factory_.GetWeakPtr(),
+                     io_thread_task_runner),
+          base::MessageLoop::current()->message_loop_proxy()).Pass();
   return message_pipe.Pass();
 }
 
diff --git a/mojo/edk/embedder/channel_init.h b/mojo/edk/embedder/channel_init.h
index ce191b4..59b6694 100644
--- a/mojo/edk/embedder/channel_init.h
+++ b/mojo/edk/embedder/channel_init.h
@@ -10,7 +10,7 @@
 #include "base/memory/weak_ptr.h"
 #include "mojo/edk/embedder/channel_info_forward.h"
 #include "mojo/edk/system/system_impl_export.h"
-#include "mojo/public/cpp/system/core.h"
+#include "mojo/public/cpp/system/message_pipe.h"
 
 namespace base {
 class MessageLoopProxy;
diff --git a/mojo/edk/embedder/configuration.h b/mojo/edk/embedder/configuration.h
new file mode 100644
index 0000000..0f99e1f
--- /dev/null
+++ b/mojo/edk/embedder/configuration.h
@@ -0,0 +1,68 @@
+// 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_EDK_EMBEDDER_CONFIGURATION_H_
+#define MOJO_EDK_EMBEDDER_CONFIGURATION_H_
+
+#include <stddef.h>
+
+namespace mojo {
+namespace embedder {
+
+// A set of constants that the Mojo system internally uses. These values should
+// be consistent across all processes on the same system.
+//
+// In general, there should be no need to change these values from their
+// defaults. However, if you do change them, you must do so before
+// initialization.
+struct Configuration {
+  // Maximum number of open (Mojo) handles. The default is 1,000,000.
+  //
+  // TODO(vtl): This doesn't count "live" handles, some of which may live in
+  // messages.
+  size_t max_handle_table_size;
+
+  // Maximum number of active memory mappings. The default is 1,000,000.
+  size_t max_mapping_table_sze;
+
+  // Upper limit of |MojoWaitMany()|'s |num_handles|. The default is 1,000,000.
+  // Must be same as or smaller than |max_handle_table_size|.
+  size_t max_wait_many_num_handles;
+
+  // Maximum data size of messages sent over message pipes, in bytes. The
+  // default is 4MB.
+  size_t max_message_num_bytes;
+
+  // Maximum number of handles that can be attached to messages sent over
+  // message pipes. The default is 10,000.
+  size_t max_message_num_handles;
+
+  // Maximum capacity of a data pipe, in bytes. The default is 256MB. This value
+  // must fit into a |uint32_t|. WARNING: If you bump it closer to 2^32, you
+  // must audit all the code to check that we don't overflow (2^31 would
+  // definitely be risky; up to 2^30 is probably okay).
+  size_t max_data_pipe_capacity_bytes;
+
+  // Default data pipe capacity, if not specified explicitly in the creation
+  // options. The default is 1MB.
+  size_t default_data_pipe_capacity_bytes;
+
+  // Alignment for the "start" of the data buffer used by data pipes. (The
+  // alignment of elements will depend on this and the element size.)  The
+  // default is 16 bytes.
+  size_t data_pipe_buffer_alignment_bytes;
+
+  // Maximum size of a single shared memory segment, in bytes. The default is
+  // 1GB.
+  //
+  // TODO(vtl): Set this hard limit appropriately (e.g., higher on 64-bit).
+  // (This will also entail some auditing to make sure I'm not messing up my
+  // checks anywhere.)
+  size_t max_shared_memory_num_bytes;
+};
+
+}  // namespace embedder
+}  // namespace mojo
+
+#endif  // MOJO_EDK_EMBEDDER_CONFIGURATION_H_
diff --git a/mojo/edk/embedder/embedder.cc b/mojo/edk/embedder/embedder.cc
index ca2169a..9c73eb0 100644
--- a/mojo/edk/embedder/embedder.cc
+++ b/mojo/edk/embedder/embedder.cc
@@ -9,12 +9,13 @@
 #include "base/logging.h"
 #include "base/memory/scoped_ptr.h"
 #include "base/message_loop/message_loop_proxy.h"
+#include "mojo/edk/embedder/embedder_internal.h"
 #include "mojo/edk/embedder/platform_support.h"
 #include "mojo/edk/system/channel.h"
 #include "mojo/edk/system/channel_endpoint.h"
-#include "mojo/edk/system/channel_info.h"
+#include "mojo/edk/system/channel_manager.h"
+#include "mojo/edk/system/configuration.h"
 #include "mojo/edk/system/core.h"
-#include "mojo/edk/system/entrypoints.h"
 #include "mojo/edk/system/message_pipe_dispatcher.h"
 #include "mojo/edk/system/platform_handle_dispatcher.h"
 #include "mojo/edk/system/raw_channel.h"
@@ -24,39 +25,41 @@
 
 namespace {
 
-// Helper for |CreateChannel...()|. (Note: May return null for some failures.)
-scoped_refptr<system::Channel> MakeChannel(
-    system::Core* core,
+// Helper for |CreateChannel...()|. Returns 0 on failure. Called on the channel
+// creation thread.
+system::ChannelId MakeChannel(
     ScopedPlatformHandle platform_handle,
     scoped_refptr<system::ChannelEndpoint> channel_endpoint) {
   DCHECK(platform_handle.is_valid());
 
   // Create and initialize a |system::Channel|.
+  DCHECK(internal::g_core);
   scoped_refptr<system::Channel> channel =
-      new system::Channel(core->platform_support());
+      new system::Channel(internal::g_core->platform_support());
   if (!channel->Init(system::RawChannel::Create(platform_handle.Pass()))) {
     // This is very unusual (e.g., maybe |platform_handle| was invalid or we
     // reached some system resource limit).
     LOG(ERROR) << "Channel::Init() failed";
     // Return null, since |Shutdown()| shouldn't be called in this case.
-    return scoped_refptr<system::Channel>();
+    return 0;
   }
-  // Once |Init()| has succeeded, we have to return |channel| (since
-  // |Shutdown()| will have to be called on it).
 
   channel->AttachAndRunEndpoint(channel_endpoint, true);
-  return channel;
+
+  DCHECK(internal::g_channel_manager);
+  return internal::g_channel_manager->AddChannel(
+      channel, base::MessageLoopProxy::current());
 }
 
+// Helper for |CreateChannel()|. Called on the channel creation thread.
 void CreateChannelHelper(
-    system::Core* core,
     ScopedPlatformHandle platform_handle,
     scoped_ptr<ChannelInfo> channel_info,
     scoped_refptr<system::ChannelEndpoint> channel_endpoint,
     DidCreateChannelCallback callback,
     scoped_refptr<base::TaskRunner> callback_thread_task_runner) {
-  channel_info->channel =
-      MakeChannel(core, platform_handle.Pass(), channel_endpoint);
+  channel_info->channel_id =
+      MakeChannel(platform_handle.Pass(), channel_endpoint);
 
   // Hand the channel back to the embedder.
   if (callback_thread_task_runner.get()) {
@@ -69,8 +72,23 @@
 
 }  // namespace
 
+namespace internal {
+
+// Declared in embedder_internal.h.
+system::Core* g_core = nullptr;
+system::ChannelManager* g_channel_manager = nullptr;
+
+}  // namespace internal
+
 void Init(scoped_ptr<PlatformSupport> platform_support) {
-  system::entrypoints::SetCore(new system::Core(platform_support.Pass()));
+  DCHECK(!internal::g_core);
+  internal::g_core = new system::Core(platform_support.Pass());
+  DCHECK(!internal::g_channel_manager);
+  internal::g_channel_manager = new system::ChannelManager();
+}
+
+Configuration* GetConfiguration() {
+  return system::GetMutableConfiguration();
 }
 
 // TODO(vtl): Write tests for this.
@@ -84,14 +102,12 @@
   scoped_refptr<system::MessagePipeDispatcher> dispatcher =
       system::MessagePipeDispatcher::CreateRemoteMessagePipe(&channel_endpoint);
 
-  system::Core* core = system::entrypoints::GetCore();
-  DCHECK(core);
+  DCHECK(internal::g_core);
   ScopedMessagePipeHandle rv(
-      MessagePipeHandle(core->AddDispatcher(dispatcher)));
+      MessagePipeHandle(internal::g_core->AddDispatcher(dispatcher)));
 
-  *channel_info = new ChannelInfo(
-      MakeChannel(core, platform_handle.Pass(), channel_endpoint),
-      base::MessageLoopProxy::current());
+  *channel_info =
+      new ChannelInfo(MakeChannel(platform_handle.Pass(), channel_endpoint));
 
   return rv.Pass();
 }
@@ -109,24 +125,19 @@
   scoped_refptr<system::MessagePipeDispatcher> dispatcher =
       system::MessagePipeDispatcher::CreateRemoteMessagePipe(&channel_endpoint);
 
-  system::Core* core = system::entrypoints::GetCore();
-  DCHECK(core);
+  DCHECK(internal::g_core);
   ScopedMessagePipeHandle rv(
-      MessagePipeHandle(core->AddDispatcher(dispatcher)));
+      MessagePipeHandle(internal::g_core->AddDispatcher(dispatcher)));
 
+  // We'll have to set |channel_info->channel_id| on the I/O thread.
   scoped_ptr<ChannelInfo> channel_info(new ChannelInfo());
-  // We'll have to set |channel_info->channel| on the I/O thread.
-  channel_info->channel_thread_task_runner = io_thread_task_runner;
 
   if (rv.is_valid()) {
-    io_thread_task_runner->PostTask(FROM_HERE,
-                                    base::Bind(&CreateChannelHelper,
-                                               base::Unretained(core),
-                                               base::Passed(&platform_handle),
-                                               base::Passed(&channel_info),
-                                               channel_endpoint,
-                                               callback,
-                                               callback_thread_task_runner));
+    io_thread_task_runner->PostTask(
+        FROM_HERE,
+        base::Bind(&CreateChannelHelper, base::Passed(&platform_handle),
+                   base::Passed(&channel_info), channel_endpoint, callback,
+                   callback_thread_task_runner));
   } else {
     (callback_thread_task_runner.get() ? callback_thread_task_runner
                                        : io_thread_task_runner)
@@ -136,35 +147,25 @@
   return rv.Pass();
 }
 
-void DestroyChannelOnIOThread(ChannelInfo* channel_info) {
-  DCHECK(channel_info);
-  if (!channel_info->channel.get()) {
-    // Presumably, |Init()| on the channel failed.
-    return;
-  }
-
-  channel_info->channel->Shutdown();
-  delete channel_info;
-}
-
 // TODO(vtl): Write tests for this.
 void DestroyChannel(ChannelInfo* channel_info) {
   DCHECK(channel_info);
-  DCHECK(channel_info->channel_thread_task_runner.get());
-
-  if (!channel_info->channel.get()) {
+  if (!channel_info->channel_id) {
     // Presumably, |Init()| on the channel failed.
     return;
   }
 
-  channel_info->channel->WillShutdownSoon();
-  channel_info->channel_thread_task_runner->PostTask(
-      FROM_HERE, base::Bind(&DestroyChannelOnIOThread, channel_info));
+  DCHECK(internal::g_channel_manager);
+  // This will destroy the channel synchronously if called from the channel
+  // thread.
+  internal::g_channel_manager->ShutdownChannel(channel_info->channel_id);
+  delete channel_info;
 }
 
 void WillDestroyChannelSoon(ChannelInfo* channel_info) {
   DCHECK(channel_info);
-  channel_info->channel->WillShutdownSoon();
+  DCHECK(internal::g_channel_manager);
+  internal::g_channel_manager->WillShutdownChannel(channel_info->channel_id);
 }
 
 MojoResult CreatePlatformHandleWrapper(
@@ -175,9 +176,8 @@
   scoped_refptr<system::Dispatcher> dispatcher(
       new system::PlatformHandleDispatcher(platform_handle.Pass()));
 
-  system::Core* core = system::entrypoints::GetCore();
-  DCHECK(core);
-  MojoHandle h = core->AddDispatcher(dispatcher);
+  DCHECK(internal::g_core);
+  MojoHandle h = internal::g_core->AddDispatcher(dispatcher);
   if (h == MOJO_HANDLE_INVALID) {
     LOG(ERROR) << "Handle table full";
     dispatcher->Close();
@@ -192,10 +192,9 @@
                                      ScopedPlatformHandle* platform_handle) {
   DCHECK(platform_handle);
 
-  system::Core* core = system::entrypoints::GetCore();
-  DCHECK(core);
+  DCHECK(internal::g_core);
   scoped_refptr<system::Dispatcher> dispatcher(
-      core->GetDispatcher(platform_handle_wrapper_handle));
+      internal::g_core->GetDispatcher(platform_handle_wrapper_handle));
   if (!dispatcher.get())
     return MOJO_RESULT_INVALID_ARGUMENT;
 
diff --git a/mojo/edk/embedder/embedder.h b/mojo/edk/embedder/embedder.h
index 85bc583..02b4ac3 100644
--- a/mojo/edk/embedder/embedder.h
+++ b/mojo/edk/embedder/embedder.h
@@ -12,23 +12,32 @@
 #include "mojo/edk/embedder/channel_info_forward.h"
 #include "mojo/edk/embedder/scoped_platform_handle.h"
 #include "mojo/edk/system/system_impl_export.h"
-#include "mojo/public/cpp/system/core.h"
+#include "mojo/public/cpp/system/message_pipe.h"
 
 namespace mojo {
 namespace embedder {
 
+struct Configuration;
 class PlatformSupport;
 
-// Must be called first to initialize the (global, singleton) system.
+// Must be called first, or just after setting configuration parameters,
+// to initialize the (global, singleton) system.
 MOJO_SYSTEM_IMPL_EXPORT void Init(scoped_ptr<PlatformSupport> platform_support);
 
+// Returns the global configuration. In general there should be no need to
+// change the configuration, but if you do so this must be done before calling
+// |Init()|.
+MOJO_SYSTEM_IMPL_EXPORT Configuration* GetConfiguration();
+
 // A "channel" is a connection on top of an OS "pipe", on top of which Mojo
 // message pipes (etc.) can be multiplexed. It must "live" on some I/O thread.
 //
-// There are two "channel" creation/destruction APIs: the synchronous
-// |CreateChannelOnIOThread()|/|DestroyChannelOnIOThread()|, which must be
-// called from the I/O thread, and the asynchronous
-// |CreateChannel()|/|DestroyChannel()|, which may be called from any thread.
+// There are two channel creation APIs: |CreateChannelOnIOThread()| creates a
+// channel synchronously and must be called from the I/O thread, while
+// |CreateChannel()| is asynchronous and may be called from any thread.
+// |DestroyChannel()| is used to destroy the channel in either case and may be
+// called from any thread, but completes synchronously when called from the I/O
+// thread.
 //
 // Both creation functions have a |platform_handle| argument, which should be an
 // OS-dependent handle to one side of a suitable bidirectional OS "pipe" (e.g.,
@@ -60,44 +69,37 @@
 
 // Creates a channel; must only be called from the I/O thread. |platform_handle|
 // should be a handle to a connected OS "pipe". Eventually (even on failure),
-// the "out" value |*channel_info| should be passed to
-// |DestroyChannelOnIOThread()| (or |DestoryChannel()|) to tear down the
-// channel. Returns a handle to the bootstrap message pipe.
+// the "out" value |*channel_info| should be passed to |DestoryChannel()| to
+// tear down the channel. Returns a handle to the bootstrap message pipe.
 MOJO_SYSTEM_IMPL_EXPORT ScopedMessagePipeHandle
-    CreateChannelOnIOThread(ScopedPlatformHandle platform_handle,
-                            ChannelInfo** channel_info);
+CreateChannelOnIOThread(ScopedPlatformHandle platform_handle,
+                        ChannelInfo** channel_info);
 
 typedef base::Callback<void(ChannelInfo*)> DidCreateChannelCallback;
 // Creates a channel asynchronously; may be called from any thread.
 // |platform_handle| should be a handle to a connected OS "pipe".
 // |io_thread_task_runner| should be the |TaskRunner| for the I/O thread.
 // |callback| should be the callback to call with the |ChannelInfo*|, which
-// should eventually be passed to |DestroyChannel()| (or
-// |DestroyChannelOnIOThread()|) to tear down the channel; the callback will be
-// called using |callback_thread_task_runner| if that is non-null, or otherwise
-// it will be called using |io_thread_task_runner|. Returns a handle to the
-// bootstrap message pipe.
+// should eventually be passed to |DestroyChannel()| to tear down the channel;
+// the callback will be called using |callback_thread_task_runner| if that is
+// non-null, or otherwise it will be called using |io_thread_task_runner|.
+// Returns a handle to the bootstrap message pipe.
 MOJO_SYSTEM_IMPL_EXPORT ScopedMessagePipeHandle
-    CreateChannel(ScopedPlatformHandle platform_handle,
-                  scoped_refptr<base::TaskRunner> io_thread_task_runner,
-                  DidCreateChannelCallback callback,
-                  scoped_refptr<base::TaskRunner> callback_thread_task_runner);
+CreateChannel(ScopedPlatformHandle platform_handle,
+              scoped_refptr<base::TaskRunner> io_thread_task_runner,
+              DidCreateChannelCallback callback,
+              scoped_refptr<base::TaskRunner> callback_thread_task_runner);
 
-// Destroys a channel that was created using either |CreateChannelOnIOThread()|
-// or |CreateChannel()|; must only be called from the I/O thread. |channel_info|
-// should be the "out" value from |CreateChannelOnIOThread()| or the value
-// provided to the callback to |CreateChannel()|.
-MOJO_SYSTEM_IMPL_EXPORT void DestroyChannelOnIOThread(
-    ChannelInfo* channel_info);
-
-// Destroys a channel (asynchronously) that was created using |CreateChannel()|;
-// may be called from any thread. |channel_info| should be the value provided to
-// the callback to |CreateChannel()|.
+// Destroys a channel that was created using |CreateChannel()| (or
+// |CreateChannelOnIOThread()|); may be called from any thread. |channel_info|
+// should be the value provided to the callback to |CreateChannel()| (or
+// returned by |CreateChannelOnIOThread()|). If called from the I/O thread, this
+// will complete synchronously (in particular, it will post no tasks).
 MOJO_SYSTEM_IMPL_EXPORT void DestroyChannel(ChannelInfo* channel_info);
 
 // Inform the channel that it will soon be destroyed (doing so is optional).
 // This may be called from any thread, but the caller must ensure that this is
-// called before |DestroyChannel()| or |DestroyChannelOnIOThread()|.
+// called before |DestroyChannel()|.
 MOJO_SYSTEM_IMPL_EXPORT void WillDestroyChannelSoon(ChannelInfo* channel_info);
 
 // Creates a |MojoHandle| that wraps the given |PlatformHandle| (taking
@@ -106,14 +108,14 @@
 // failure, which is different from what you'd expect from a Mojo API, but it
 // makes for a more convenient embedder API.
 MOJO_SYSTEM_IMPL_EXPORT MojoResult
-    CreatePlatformHandleWrapper(ScopedPlatformHandle platform_handle,
-                                MojoHandle* platform_handle_wrapper_handle);
+CreatePlatformHandleWrapper(ScopedPlatformHandle platform_handle,
+                            MojoHandle* platform_handle_wrapper_handle);
 // Retrieves the |PlatformHandle| that was wrapped into a |MojoHandle| (using
 // |CreatePlatformHandleWrapper()| above). Note that the |MojoHandle| must still
 // be closed separately.
 MOJO_SYSTEM_IMPL_EXPORT MojoResult
-    PassWrappedPlatformHandle(MojoHandle platform_handle_wrapper_handle,
-                              ScopedPlatformHandle* platform_handle);
+PassWrappedPlatformHandle(MojoHandle platform_handle_wrapper_handle,
+                          ScopedPlatformHandle* platform_handle);
 
 }  // namespace embedder
 }  // namespace mojo
diff --git a/mojo/edk/embedder/embedder_internal.h b/mojo/edk/embedder/embedder_internal.h
new file mode 100644
index 0000000..ab8388a
--- /dev/null
+++ b/mojo/edk/embedder/embedder_internal.h
@@ -0,0 +1,53 @@
+// 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 header contains internal details for the *implementation* of the
+// embedder API. It should not be included by any public header (nor by users of
+// the embedder API).
+
+#ifndef MOJO_EDK_EMBEDDER_EMBEDDER_INTERNAL_H_
+#define MOJO_EDK_EMBEDDER_EMBEDDER_INTERNAL_H_
+
+#include <stdint.h>
+
+namespace mojo {
+
+namespace system {
+
+class ChannelManager;
+class Core;
+
+// Repeat a typedef in mojo/edk/system/channel_manager.h, to avoid including it.
+typedef uintptr_t ChannelId;
+
+}  // namespace system
+
+namespace embedder {
+
+// This is a type that's opaque to users of the embedder API (which only
+// gives/takes |ChannelInfo*|s). We make it a struct to make it
+// template-friendly.
+struct ChannelInfo {
+  explicit ChannelInfo(system::ChannelId channel_id = 0)
+      : channel_id(channel_id) {}
+
+  system::ChannelId channel_id;
+};
+
+namespace internal {
+
+// Instance of |Core| used by the system functions (|Mojo...()|).
+extern system::Core* g_core;
+
+// Instance of |ChannelManager| used by the channel management functions
+// (|mojo::embedder::CreateChannel()|, etc.).
+extern system::ChannelManager* g_channel_manager;
+
+}  // namespace internal
+
+}  // namepace embedder
+
+}  // namespace mojo
+
+#endif  // MOJO_EDK_EMBEDDER_EMBEDDER_INTERNAL_H_
diff --git a/mojo/edk/embedder/embedder_unittest.cc b/mojo/edk/embedder/embedder_unittest.cc
index 5c4d0d8..16a5ce2 100644
--- a/mojo/edk/embedder/embedder_unittest.cc
+++ b/mojo/edk/embedder/embedder_unittest.cc
@@ -39,8 +39,7 @@
         did_create_channel_event_(true, false),
         channel_info_(nullptr) {
     bootstrap_message_pipe_ =
-        CreateChannel(platform_handle.Pass(),
-                      io_thread_task_runner_,
+        CreateChannel(platform_handle.Pass(), io_thread_task_runner_,
                       base::Bind(&ScopedTestChannel::DidCreateChannel,
                                  base::Unretained(this)),
                       nullptr)
@@ -51,12 +50,7 @@
 
   // Destructor: Shuts down the channel. (As noted above, for this to happen,
   // the I/O thread must be alive and pumping messages.)
-  ~ScopedTestChannel() {
-    system::test::PostTaskAndWait(
-        io_thread_task_runner_,
-        FROM_HERE,
-        base::Bind(&ScopedTestChannel::DestroyChannel, base::Unretained(this)));
-  }
+  ~ScopedTestChannel() { DestroyChannel(channel_info_); }
 
   // Waits for channel creation to be completed.
   void WaitForChannelCreationCompletion() { did_create_channel_event_.Wait(); }
@@ -75,12 +69,6 @@
     did_create_channel_event_.Signal();
   }
 
-  void DestroyChannel() {
-    CHECK(channel_info_);
-    DestroyChannelOnIOThread(channel_info_);
-    channel_info_ = nullptr;
-  }
-
   scoped_refptr<base::TaskRunner> io_thread_task_runner_;
 
   // Valid from creation until whenever it gets closed (by the "owner" of this
@@ -130,27 +118,18 @@
     // We can write to a message pipe handle immediately.
     const char kHello[] = "hello";
     EXPECT_EQ(MOJO_RESULT_OK,
-              MojoWriteMessage(server_mp,
-                               kHello,
-                               static_cast<uint32_t>(sizeof(kHello)),
-                               nullptr,
-                               0,
-                               MOJO_WRITE_MESSAGE_FLAG_NONE));
+              MojoWriteMessage(server_mp, kHello,
+                               static_cast<uint32_t>(sizeof(kHello)), nullptr,
+                               0, MOJO_WRITE_MESSAGE_FLAG_NONE));
 
     // Now wait for the other side to become readable.
-    EXPECT_EQ(
-        MOJO_RESULT_OK,
-        MojoWait(
-            client_mp, MOJO_HANDLE_SIGNAL_READABLE, MOJO_DEADLINE_INDEFINITE));
+    EXPECT_EQ(MOJO_RESULT_OK, MojoWait(client_mp, MOJO_HANDLE_SIGNAL_READABLE,
+                                       MOJO_DEADLINE_INDEFINITE));
 
     char buffer[1000] = {};
     uint32_t num_bytes = static_cast<uint32_t>(sizeof(buffer));
     EXPECT_EQ(MOJO_RESULT_OK,
-              MojoReadMessage(client_mp,
-                              buffer,
-                              &num_bytes,
-                              nullptr,
-                              nullptr,
+              MojoReadMessage(client_mp, buffer, &num_bytes, nullptr, nullptr,
                               MOJO_READ_MESSAGE_FLAG_NONE));
     EXPECT_EQ(sizeof(kHello), num_bytes);
     EXPECT_STREQ(kHello, buffer);
@@ -189,40 +168,28 @@
 
     // Write a message to |h0| (attaching nothing).
     const char kHello[] = "hello";
-    EXPECT_EQ(MOJO_RESULT_OK,
-              MojoWriteMessage(h0,
-                               kHello,
-                               static_cast<uint32_t>(sizeof(kHello)),
-                               nullptr,
-                               0,
-                               MOJO_WRITE_MESSAGE_FLAG_NONE));
+    EXPECT_EQ(
+        MOJO_RESULT_OK,
+        MojoWriteMessage(h0, kHello, static_cast<uint32_t>(sizeof(kHello)),
+                         nullptr, 0, MOJO_WRITE_MESSAGE_FLAG_NONE));
 
     // Write one message to |server_mp|, attaching |h1|.
     const char kWorld[] = "world!!!";
     EXPECT_EQ(MOJO_RESULT_OK,
-              MojoWriteMessage(server_mp,
-                               kWorld,
-                               static_cast<uint32_t>(sizeof(kWorld)),
-                               &h1,
-                               1,
+              MojoWriteMessage(server_mp, kWorld,
+                               static_cast<uint32_t>(sizeof(kWorld)), &h1, 1,
                                MOJO_WRITE_MESSAGE_FLAG_NONE));
     h1 = MOJO_HANDLE_INVALID;
 
     // Write another message to |h0|.
     const char kFoo[] = "foo";
     EXPECT_EQ(MOJO_RESULT_OK,
-              MojoWriteMessage(h0,
-                               kFoo,
-                               static_cast<uint32_t>(sizeof(kFoo)),
-                               nullptr,
-                               0,
-                               MOJO_WRITE_MESSAGE_FLAG_NONE));
+              MojoWriteMessage(h0, kFoo, static_cast<uint32_t>(sizeof(kFoo)),
+                               nullptr, 0, MOJO_WRITE_MESSAGE_FLAG_NONE));
 
     // Wait for |client_mp| to become readable.
-    EXPECT_EQ(
-        MOJO_RESULT_OK,
-        MojoWait(
-            client_mp, MOJO_HANDLE_SIGNAL_READABLE, MOJO_DEADLINE_INDEFINITE));
+    EXPECT_EQ(MOJO_RESULT_OK, MojoWait(client_mp, MOJO_HANDLE_SIGNAL_READABLE,
+                                       MOJO_DEADLINE_INDEFINITE));
 
     // Read a message from |client_mp|.
     char buffer[1000] = {};
@@ -230,12 +197,8 @@
     MojoHandle handles[10] = {};
     uint32_t num_handles = arraysize(handles);
     EXPECT_EQ(MOJO_RESULT_OK,
-              MojoReadMessage(client_mp,
-                              buffer,
-                              &num_bytes,
-                              handles,
-                              &num_handles,
-                              MOJO_READ_MESSAGE_FLAG_NONE));
+              MojoReadMessage(client_mp, buffer, &num_bytes, handles,
+                              &num_handles, MOJO_READ_MESSAGE_FLAG_NONE));
     EXPECT_EQ(sizeof(kWorld), num_bytes);
     EXPECT_STREQ(kWorld, buffer);
     EXPECT_EQ(1u, num_handles);
@@ -243,9 +206,8 @@
     h1 = handles[0];
 
     // Wait for |h1| to become readable.
-    EXPECT_EQ(
-        MOJO_RESULT_OK,
-        MojoWait(h1, MOJO_HANDLE_SIGNAL_READABLE, MOJO_DEADLINE_INDEFINITE));
+    EXPECT_EQ(MOJO_RESULT_OK, MojoWait(h1, MOJO_HANDLE_SIGNAL_READABLE,
+                                       MOJO_DEADLINE_INDEFINITE));
 
     // Read a message from |h1|.
     memset(buffer, 0, sizeof(buffer));
@@ -253,58 +215,41 @@
     memset(handles, 0, sizeof(handles));
     num_handles = arraysize(handles);
     EXPECT_EQ(MOJO_RESULT_OK,
-              MojoReadMessage(h1,
-                              buffer,
-                              &num_bytes,
-                              handles,
-                              &num_handles,
+              MojoReadMessage(h1, buffer, &num_bytes, handles, &num_handles,
                               MOJO_READ_MESSAGE_FLAG_NONE));
     EXPECT_EQ(sizeof(kHello), num_bytes);
     EXPECT_STREQ(kHello, buffer);
     EXPECT_EQ(0u, num_handles);
 
     // Wait for |h1| to become readable (again).
-    EXPECT_EQ(
-        MOJO_RESULT_OK,
-        MojoWait(h1, MOJO_HANDLE_SIGNAL_READABLE, MOJO_DEADLINE_INDEFINITE));
+    EXPECT_EQ(MOJO_RESULT_OK, MojoWait(h1, MOJO_HANDLE_SIGNAL_READABLE,
+                                       MOJO_DEADLINE_INDEFINITE));
 
     // Read the second message from |h1|.
     memset(buffer, 0, sizeof(buffer));
     num_bytes = static_cast<uint32_t>(sizeof(buffer));
     EXPECT_EQ(MOJO_RESULT_OK,
-              MojoReadMessage(h1,
-                              buffer,
-                              &num_bytes,
-                              nullptr,
-                              nullptr,
+              MojoReadMessage(h1, buffer, &num_bytes, nullptr, nullptr,
                               MOJO_READ_MESSAGE_FLAG_NONE));
     EXPECT_EQ(sizeof(kFoo), num_bytes);
     EXPECT_STREQ(kFoo, buffer);
 
     // Write a message to |h1|.
     const char kBarBaz[] = "barbaz";
-    EXPECT_EQ(MOJO_RESULT_OK,
-              MojoWriteMessage(h1,
-                               kBarBaz,
-                               static_cast<uint32_t>(sizeof(kBarBaz)),
-                               nullptr,
-                               0,
-                               MOJO_WRITE_MESSAGE_FLAG_NONE));
-
-    // Wait for |h0| to become readable.
     EXPECT_EQ(
         MOJO_RESULT_OK,
-        MojoWait(h0, MOJO_HANDLE_SIGNAL_READABLE, MOJO_DEADLINE_INDEFINITE));
+        MojoWriteMessage(h1, kBarBaz, static_cast<uint32_t>(sizeof(kBarBaz)),
+                         nullptr, 0, MOJO_WRITE_MESSAGE_FLAG_NONE));
+
+    // Wait for |h0| to become readable.
+    EXPECT_EQ(MOJO_RESULT_OK, MojoWait(h0, MOJO_HANDLE_SIGNAL_READABLE,
+                                       MOJO_DEADLINE_INDEFINITE));
 
     // Read a message from |h0|.
     memset(buffer, 0, sizeof(buffer));
     num_bytes = static_cast<uint32_t>(sizeof(buffer));
     EXPECT_EQ(MOJO_RESULT_OK,
-              MojoReadMessage(h0,
-                              buffer,
-                              &num_bytes,
-                              nullptr,
-                              nullptr,
+              MojoReadMessage(h0, buffer, &num_bytes, nullptr, nullptr,
                               MOJO_READ_MESSAGE_FLAG_NONE));
     EXPECT_EQ(sizeof(kBarBaz), num_bytes);
     EXPECT_STREQ(kBarBaz, buffer);
@@ -354,29 +299,20 @@
     // 1. Write a message to |server_mp| (attaching nothing).
     const char kHello[] = "hello";
     EXPECT_EQ(MOJO_RESULT_OK,
-              MojoWriteMessage(server_mp,
-                               kHello,
-                               static_cast<uint32_t>(sizeof(kHello)),
-                               nullptr,
-                               0,
-                               MOJO_WRITE_MESSAGE_FLAG_NONE));
+              MojoWriteMessage(server_mp, kHello,
+                               static_cast<uint32_t>(sizeof(kHello)), nullptr,
+                               0, MOJO_WRITE_MESSAGE_FLAG_NONE));
 
     // TODO(vtl): If the scope were ended immediately here (maybe after closing
     // |server_mp|), we die with a fatal error in |Channel::HandleLocalError()|.
 
     // 2. Read a message from |server_mp|.
-    EXPECT_EQ(
-        MOJO_RESULT_OK,
-        MojoWait(
-            server_mp, MOJO_HANDLE_SIGNAL_READABLE, MOJO_DEADLINE_INDEFINITE));
+    EXPECT_EQ(MOJO_RESULT_OK, MojoWait(server_mp, MOJO_HANDLE_SIGNAL_READABLE,
+                                       MOJO_DEADLINE_INDEFINITE));
     char buffer[1000] = {};
     uint32_t num_bytes = static_cast<uint32_t>(sizeof(buffer));
     EXPECT_EQ(MOJO_RESULT_OK,
-              MojoReadMessage(server_mp,
-                              buffer,
-                              &num_bytes,
-                              nullptr,
-                              nullptr,
+              MojoReadMessage(server_mp, buffer, &num_bytes, nullptr, nullptr,
                               MOJO_READ_MESSAGE_FLAG_NONE));
     const char kWorld[] = "world!";
     EXPECT_EQ(sizeof(kWorld), num_bytes);
@@ -389,41 +325,29 @@
     // 3. Write something to |mp0|.
     const char kFoo[] = "FOO";
     EXPECT_EQ(MOJO_RESULT_OK,
-              MojoWriteMessage(mp0,
-                               kFoo,
-                               static_cast<uint32_t>(sizeof(kFoo)),
-                               nullptr,
-                               0,
-                               MOJO_WRITE_MESSAGE_FLAG_NONE));
+              MojoWriteMessage(mp0, kFoo, static_cast<uint32_t>(sizeof(kFoo)),
+                               nullptr, 0, MOJO_WRITE_MESSAGE_FLAG_NONE));
 
     // 4. Write a message to |server_mp|, attaching |mp1|.
     const char kBar[] = "Bar";
-    EXPECT_EQ(MOJO_RESULT_OK,
-              MojoWriteMessage(server_mp,
-                               kBar,
-                               static_cast<uint32_t>(sizeof(kBar)),
-                               &mp1,
-                               1,
-                               MOJO_WRITE_MESSAGE_FLAG_NONE));
+    EXPECT_EQ(
+        MOJO_RESULT_OK,
+        MojoWriteMessage(server_mp, kBar, static_cast<uint32_t>(sizeof(kBar)),
+                         &mp1, 1, MOJO_WRITE_MESSAGE_FLAG_NONE));
     mp1 = MOJO_HANDLE_INVALID;
 
     // 5. Close |server_mp|.
     EXPECT_EQ(MOJO_RESULT_OK, MojoClose(server_mp));
 
     // 9. Read a message from |mp0|, which should have |mp2| attached.
-    EXPECT_EQ(
-        MOJO_RESULT_OK,
-        MojoWait(mp0, MOJO_HANDLE_SIGNAL_READABLE, MOJO_DEADLINE_INDEFINITE));
+    EXPECT_EQ(MOJO_RESULT_OK, MojoWait(mp0, MOJO_HANDLE_SIGNAL_READABLE,
+                                       MOJO_DEADLINE_INDEFINITE));
     memset(buffer, 0, sizeof(buffer));
     num_bytes = static_cast<uint32_t>(sizeof(buffer));
     MojoHandle mp2 = MOJO_HANDLE_INVALID;
     uint32_t num_handles = 1;
     EXPECT_EQ(MOJO_RESULT_OK,
-              MojoReadMessage(mp0,
-                              buffer,
-                              &num_bytes,
-                              &mp2,
-                              &num_handles,
+              MojoReadMessage(mp0, buffer, &num_bytes, &mp2, &num_handles,
                               MOJO_READ_MESSAGE_FLAG_NONE));
     const char kQuux[] = "quux";
     EXPECT_EQ(sizeof(kQuux), num_bytes);
@@ -432,17 +356,12 @@
     EXPECT_NE(mp2, MOJO_HANDLE_INVALID);
 
     // 7. Read a message from |mp2|.
-    EXPECT_EQ(
-        MOJO_RESULT_OK,
-        MojoWait(mp2, MOJO_HANDLE_SIGNAL_READABLE, MOJO_DEADLINE_INDEFINITE));
+    EXPECT_EQ(MOJO_RESULT_OK, MojoWait(mp2, MOJO_HANDLE_SIGNAL_READABLE,
+                                       MOJO_DEADLINE_INDEFINITE));
     memset(buffer, 0, sizeof(buffer));
     num_bytes = static_cast<uint32_t>(sizeof(buffer));
     EXPECT_EQ(MOJO_RESULT_OK,
-              MojoReadMessage(mp2,
-                              buffer,
-                              &num_bytes,
-                              nullptr,
-                              nullptr,
+              MojoReadMessage(mp2, buffer, &num_bytes, nullptr, nullptr,
                               MOJO_READ_MESSAGE_FLAG_NONE));
     const char kBaz[] = "baz";
     EXPECT_EQ(sizeof(kBaz), num_bytes);
@@ -482,18 +401,12 @@
     CHECK(client_channel.channel_info() != nullptr);
 
     // 1. Read the first message from |client_mp|.
-    EXPECT_EQ(
-        MOJO_RESULT_OK,
-        MojoWait(
-            client_mp, MOJO_HANDLE_SIGNAL_READABLE, MOJO_DEADLINE_INDEFINITE));
+    EXPECT_EQ(MOJO_RESULT_OK, MojoWait(client_mp, MOJO_HANDLE_SIGNAL_READABLE,
+                                       MOJO_DEADLINE_INDEFINITE));
     char buffer[1000] = {};
     uint32_t num_bytes = static_cast<uint32_t>(sizeof(buffer));
     EXPECT_EQ(MOJO_RESULT_OK,
-              MojoReadMessage(client_mp,
-                              buffer,
-                              &num_bytes,
-                              nullptr,
-                              nullptr,
+              MojoReadMessage(client_mp, buffer, &num_bytes, nullptr, nullptr,
                               MOJO_READ_MESSAGE_FLAG_NONE));
     const char kHello[] = "hello";
     EXPECT_EQ(sizeof(kHello), num_bytes);
@@ -502,18 +415,13 @@
     // 2. Write a message to |client_mp| (attaching nothing).
     const char kWorld[] = "world!";
     EXPECT_EQ(MOJO_RESULT_OK,
-              MojoWriteMessage(client_mp,
-                               kWorld,
-                               static_cast<uint32_t>(sizeof(kWorld)),
-                               nullptr,
-                               0,
-                               MOJO_WRITE_MESSAGE_FLAG_NONE));
+              MojoWriteMessage(client_mp, kWorld,
+                               static_cast<uint32_t>(sizeof(kWorld)), nullptr,
+                               0, MOJO_WRITE_MESSAGE_FLAG_NONE));
 
     // 4. Read a message from |client_mp|, which should have |mp1| attached.
-    EXPECT_EQ(
-        MOJO_RESULT_OK,
-        MojoWait(
-            client_mp, MOJO_HANDLE_SIGNAL_READABLE, MOJO_DEADLINE_INDEFINITE));
+    EXPECT_EQ(MOJO_RESULT_OK, MojoWait(client_mp, MOJO_HANDLE_SIGNAL_READABLE,
+                                       MOJO_DEADLINE_INDEFINITE));
     // TODO(vtl): If the scope were to end here (and |client_mp| closed), we'd
     // die (again due to |Channel::HandleLocalError()|).
     memset(buffer, 0, sizeof(buffer));
@@ -521,11 +429,7 @@
     MojoHandle mp1 = MOJO_HANDLE_INVALID;
     uint32_t num_handles = 1;
     EXPECT_EQ(MOJO_RESULT_OK,
-              MojoReadMessage(client_mp,
-                              buffer,
-                              &num_bytes,
-                              &mp1,
-                              &num_handles,
+              MojoReadMessage(client_mp, buffer, &num_bytes, &mp1, &num_handles,
                               MOJO_READ_MESSAGE_FLAG_NONE));
     const char kBar[] = "Bar";
     EXPECT_EQ(sizeof(kBar), num_bytes);
@@ -546,12 +450,8 @@
     // 7. Write a message to |mp3|.
     const char kBaz[] = "baz";
     EXPECT_EQ(MOJO_RESULT_OK,
-              MojoWriteMessage(mp3,
-                               kBaz,
-                               static_cast<uint32_t>(sizeof(kBaz)),
-                               nullptr,
-                               0,
-                               MOJO_WRITE_MESSAGE_FLAG_NONE));
+              MojoWriteMessage(mp3, kBaz, static_cast<uint32_t>(sizeof(kBaz)),
+                               nullptr, 0, MOJO_WRITE_MESSAGE_FLAG_NONE));
 
     // 8. Close |mp3|.
     EXPECT_EQ(MOJO_RESULT_OK, MojoClose(mp3));
@@ -559,26 +459,17 @@
     // 9. Write a message to |mp1|, attaching |mp2|.
     const char kQuux[] = "quux";
     EXPECT_EQ(MOJO_RESULT_OK,
-              MojoWriteMessage(mp1,
-                               kQuux,
-                               static_cast<uint32_t>(sizeof(kQuux)),
-                               &mp2,
-                               1,
-                               MOJO_WRITE_MESSAGE_FLAG_NONE));
+              MojoWriteMessage(mp1, kQuux, static_cast<uint32_t>(sizeof(kQuux)),
+                               &mp2, 1, MOJO_WRITE_MESSAGE_FLAG_NONE));
     mp2 = MOJO_HANDLE_INVALID;
 
     // 3. Read a message from |mp1|.
-    EXPECT_EQ(
-        MOJO_RESULT_OK,
-        MojoWait(mp1, MOJO_HANDLE_SIGNAL_READABLE, MOJO_DEADLINE_INDEFINITE));
+    EXPECT_EQ(MOJO_RESULT_OK, MojoWait(mp1, MOJO_HANDLE_SIGNAL_READABLE,
+                                       MOJO_DEADLINE_INDEFINITE));
     memset(buffer, 0, sizeof(buffer));
     num_bytes = static_cast<uint32_t>(sizeof(buffer));
     EXPECT_EQ(MOJO_RESULT_OK,
-              MojoReadMessage(mp1,
-                              buffer,
-                              &num_bytes,
-                              nullptr,
-                              nullptr,
+              MojoReadMessage(mp1, buffer, &num_bytes, nullptr, nullptr,
                               MOJO_READ_MESSAGE_FLAG_NONE));
     const char kFoo[] = "FOO";
     EXPECT_EQ(sizeof(kFoo), num_bytes);
diff --git a/mojo/edk/system/entrypoints.cc b/mojo/edk/embedder/entrypoints.cc
similarity index 70%
rename from mojo/edk/system/entrypoints.cc
rename to mojo/edk/embedder/entrypoints.cc
index 7ec5bb4..7b2e53f 100644
--- a/mojo/edk/system/entrypoints.cc
+++ b/mojo/edk/embedder/entrypoints.cc
@@ -2,35 +2,16 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "mojo/edk/system/entrypoints.h"
-
-#include "base/logging.h"
+#include "mojo/edk/embedder/embedder_internal.h"
 #include "mojo/edk/system/core.h"
 #include "mojo/public/c/system/buffer.h"
 #include "mojo/public/c/system/data_pipe.h"
 #include "mojo/public/c/system/functions.h"
 #include "mojo/public/c/system/message_pipe.h"
 
-static mojo::system::Core* g_core = nullptr;
-
+using mojo::embedder::internal::g_core;
 using mojo::system::MakeUserPointer;
 
-namespace mojo {
-namespace system {
-namespace entrypoints {
-
-void SetCore(Core* core) {
-  g_core = core;
-}
-
-Core* GetCore() {
-  return g_core;
-}
-
-}  // namespace entrypoints
-}  // namepace system
-}  // namespace mojo
-
 // Definitions of the system functions.
 extern "C" {
 MojoTimeTicks MojoGetTimeTicksNow() {
@@ -44,8 +25,8 @@
 MojoResult MojoWait(MojoHandle handle,
                     MojoHandleSignals signals,
                     MojoDeadline deadline) {
-  return g_core->Wait(
-      handle, signals, deadline, mojo::system::NullUserPointer());
+  return g_core->Wait(handle, signals, deadline,
+                      mojo::system::NullUserPointer());
 }
 
 MojoResult MojoWaitMany(const MojoHandle* handles,
@@ -53,12 +34,9 @@
                         uint32_t num_handles,
                         MojoDeadline deadline) {
   uint32_t result_index = static_cast<uint32_t>(-1);
-  MojoResult result = g_core->WaitMany(MakeUserPointer(handles),
-                                       MakeUserPointer(signals),
-                                       num_handles,
-                                       deadline,
-                                       MakeUserPointer(&result_index),
-                                       mojo::system::NullUserPointer());
+  MojoResult result = g_core->WaitMany(
+      MakeUserPointer(handles), MakeUserPointer(signals), num_handles, deadline,
+      MakeUserPointer(&result_index), mojo::system::NullUserPointer());
   return (result == MOJO_RESULT_OK) ? static_cast<MojoResult>(result_index)
                                     : result;
 }
@@ -77,11 +55,8 @@
                             const MojoHandle* handles,
                             uint32_t num_handles,
                             MojoWriteMessageFlags flags) {
-  return g_core->WriteMessage(message_pipe_handle,
-                              MakeUserPointer(bytes),
-                              num_bytes,
-                              MakeUserPointer(handles),
-                              num_handles,
+  return g_core->WriteMessage(message_pipe_handle, MakeUserPointer(bytes),
+                              num_bytes, MakeUserPointer(handles), num_handles,
                               flags);
 }
 
@@ -91,12 +66,9 @@
                            MojoHandle* handles,
                            uint32_t* num_handles,
                            MojoReadMessageFlags flags) {
-  return g_core->ReadMessage(message_pipe_handle,
-                             MakeUserPointer(bytes),
-                             MakeUserPointer(num_bytes),
-                             MakeUserPointer(handles),
-                             MakeUserPointer(num_handles),
-                             flags);
+  return g_core->ReadMessage(
+      message_pipe_handle, MakeUserPointer(bytes), MakeUserPointer(num_bytes),
+      MakeUserPointer(handles), MakeUserPointer(num_handles), flags);
 }
 
 MojoResult MojoCreateDataPipe(const MojoCreateDataPipeOptions* options,
@@ -111,10 +83,8 @@
                          const void* elements,
                          uint32_t* num_elements,
                          MojoWriteDataFlags flags) {
-  return g_core->WriteData(data_pipe_producer_handle,
-                           MakeUserPointer(elements),
-                           MakeUserPointer(num_elements),
-                           flags);
+  return g_core->WriteData(data_pipe_producer_handle, MakeUserPointer(elements),
+                           MakeUserPointer(num_elements), flags);
 }
 
 MojoResult MojoBeginWriteData(MojoHandle data_pipe_producer_handle,
@@ -123,8 +93,7 @@
                               MojoWriteDataFlags flags) {
   return g_core->BeginWriteData(data_pipe_producer_handle,
                                 MakeUserPointer(buffer),
-                                MakeUserPointer(buffer_num_elements),
-                                flags);
+                                MakeUserPointer(buffer_num_elements), flags);
 }
 
 MojoResult MojoEndWriteData(MojoHandle data_pipe_producer_handle,
@@ -136,10 +105,8 @@
                         void* elements,
                         uint32_t* num_elements,
                         MojoReadDataFlags flags) {
-  return g_core->ReadData(data_pipe_consumer_handle,
-                          MakeUserPointer(elements),
-                          MakeUserPointer(num_elements),
-                          flags);
+  return g_core->ReadData(data_pipe_consumer_handle, MakeUserPointer(elements),
+                          MakeUserPointer(num_elements), flags);
 }
 
 MojoResult MojoBeginReadData(MojoHandle data_pipe_consumer_handle,
@@ -148,8 +115,7 @@
                              MojoReadDataFlags flags) {
   return g_core->BeginReadData(data_pipe_consumer_handle,
                                MakeUserPointer(buffer),
-                               MakeUserPointer(buffer_num_elements),
-                               flags);
+                               MakeUserPointer(buffer_num_elements), flags);
 }
 
 MojoResult MojoEndReadData(MojoHandle data_pipe_consumer_handle,
@@ -161,8 +127,7 @@
     const struct MojoCreateSharedBufferOptions* options,
     uint64_t num_bytes,
     MojoHandle* shared_buffer_handle) {
-  return g_core->CreateSharedBuffer(MakeUserPointer(options),
-                                    num_bytes,
+  return g_core->CreateSharedBuffer(MakeUserPointer(options), num_bytes,
                                     MakeUserPointer(shared_buffer_handle));
 }
 
@@ -170,8 +135,7 @@
     MojoHandle buffer_handle,
     const struct MojoDuplicateBufferHandleOptions* options,
     MojoHandle* new_buffer_handle) {
-  return g_core->DuplicateBufferHandle(buffer_handle,
-                                       MakeUserPointer(options),
+  return g_core->DuplicateBufferHandle(buffer_handle, MakeUserPointer(options),
                                        MakeUserPointer(new_buffer_handle));
 }
 
@@ -180,8 +144,8 @@
                          uint64_t num_bytes,
                          void** buffer,
                          MojoMapBufferFlags flags) {
-  return g_core->MapBuffer(
-      buffer_handle, offset, num_bytes, MakeUserPointer(buffer), flags);
+  return g_core->MapBuffer(buffer_handle, offset, num_bytes,
+                           MakeUserPointer(buffer), flags);
 }
 
 MojoResult MojoUnmapBuffer(void* buffer) {
diff --git a/mojo/edk/embedder/platform_channel_pair_posix.cc b/mojo/edk/embedder/platform_channel_pair_posix.cc
index f9886b5..2242cce 100644
--- a/mojo/edk/embedder/platform_channel_pair_posix.cc
+++ b/mojo/edk/embedder/platform_channel_pair_posix.cc
@@ -46,14 +46,10 @@
   // fail with |EPIPE| instead). On Linux, we have to use |send...()| with
   // |MSG_NOSIGNAL| -- which is not supported on Mac -- instead.
   int no_sigpipe = 1;
-  PCHECK(
-      setsockopt(
-          fds[0], SOL_SOCKET, SO_NOSIGPIPE, &no_sigpipe, sizeof(no_sigpipe)) ==
-      0);
-  PCHECK(
-      setsockopt(
-          fds[1], SOL_SOCKET, SO_NOSIGPIPE, &no_sigpipe, sizeof(no_sigpipe)) ==
-      0);
+  PCHECK(setsockopt(fds[0], SOL_SOCKET, SO_NOSIGPIPE, &no_sigpipe,
+                    sizeof(no_sigpipe)) == 0);
+  PCHECK(setsockopt(fds[1], SOL_SOCKET, SO_NOSIGPIPE, &no_sigpipe,
+                    sizeof(no_sigpipe)) == 0);
 #endif  // defined(OS_MACOSX)
 
   server_handle_.reset(PlatformHandle(fds[0]));
diff --git a/mojo/edk/embedder/platform_channel_pair_posix_unittest.cc b/mojo/edk/embedder/platform_channel_pair_posix_unittest.cc
index 926bbc5..c3b1ef1 100644
--- a/mojo/edk/embedder/platform_channel_pair_posix_unittest.cc
+++ b/mojo/edk/embedder/platform_channel_pair_posix_unittest.cc
@@ -112,15 +112,15 @@
     std::string send_string(1 << i, 'A' + i);
 
     EXPECT_EQ(static_cast<ssize_t>(send_string.size()),
-              PlatformChannelWrite(
-                  server_handle.get(), send_string.data(), send_string.size()));
+              PlatformChannelWrite(server_handle.get(), send_string.data(),
+                                   send_string.size()));
 
     WaitReadable(client_handle.get());
 
     char buf[10000] = {};
     std::deque<PlatformHandle> received_handles;
-    ssize_t result = PlatformChannelRecvmsg(
-        client_handle.get(), buf, sizeof(buf), &received_handles);
+    ssize_t result = PlatformChannelRecvmsg(client_handle.get(), buf,
+                                            sizeof(buf), &received_handles);
     EXPECT_EQ(static_cast<ssize_t>(send_string.size()), result);
     EXPECT_EQ(send_string, std::string(buf, static_cast<size_t>(result)));
     EXPECT_TRUE(received_handles.empty());
@@ -155,9 +155,7 @@
     struct iovec iov = {const_cast<char*>(kHello), sizeof(kHello)};
     // We assume that the |sendmsg()| actually sends all the data.
     EXPECT_EQ(static_cast<ssize_t>(sizeof(kHello)),
-              PlatformChannelSendmsgWithHandles(server_handle.get(),
-                                                &iov,
-                                                1,
+              PlatformChannelSendmsgWithHandles(server_handle.get(), &iov, 1,
                                                 &platform_handles[0],
                                                 platform_handles.size()));
 
@@ -167,8 +165,8 @@
     std::deque<PlatformHandle> received_handles;
     // We assume that the |recvmsg()| actually reads all the data.
     EXPECT_EQ(static_cast<ssize_t>(sizeof(kHello)),
-              PlatformChannelRecvmsg(
-                  client_handle.get(), buf, sizeof(buf), &received_handles));
+              PlatformChannelRecvmsg(client_handle.get(), buf, sizeof(buf),
+                                     &received_handles));
     EXPECT_STREQ(kHello, buf);
     EXPECT_EQ(i, received_handles.size());
 
@@ -214,9 +212,7 @@
     struct iovec iov = {const_cast<char*>(kHello), sizeof(kHello)};
     // We assume that the |sendmsg()| actually sends all the data.
     EXPECT_EQ(static_cast<ssize_t>(sizeof(kHello)),
-              PlatformChannelSendmsgWithHandles(server_handle.get(),
-                                                &iov,
-                                                1,
+              PlatformChannelSendmsgWithHandles(server_handle.get(), &iov, 1,
                                                 &platform_handles[0],
                                                 platform_handles.size()));
   }
@@ -230,8 +226,8 @@
   char buf[100] = {};
   // We assume that the |recvmsg()| actually reads all the data.
   EXPECT_EQ(static_cast<ssize_t>(sizeof(kHello)),
-            PlatformChannelRecvmsg(
-                client_handle.get(), buf, sizeof(buf), &received_handles));
+            PlatformChannelRecvmsg(client_handle.get(), buf, sizeof(buf),
+                                   &received_handles));
   EXPECT_STREQ(kHello, buf);
   ASSERT_EQ(2u, received_handles.size());
   EXPECT_FALSE(received_handles[0].is_valid());
diff --git a/mojo/edk/embedder/platform_channel_utils_posix.h b/mojo/edk/embedder/platform_channel_utils_posix.h
index 87176fb..34efcad 100644
--- a/mojo/edk/embedder/platform_channel_utils_posix.h
+++ b/mojo/edk/embedder/platform_channel_utils_posix.h
@@ -30,9 +30,9 @@
 // never raise |SIGPIPE|. (Note: On Mac, the suppression of |SIGPIPE| is set up
 // by |PlatformChannelPair|.)
 MOJO_SYSTEM_IMPL_EXPORT ssize_t
-    PlatformChannelWrite(PlatformHandle h, const void* bytes, size_t num_bytes);
+PlatformChannelWrite(PlatformHandle h, const void* bytes, size_t num_bytes);
 MOJO_SYSTEM_IMPL_EXPORT ssize_t
-    PlatformChannelWritev(PlatformHandle h, struct iovec* iov, size_t num_iov);
+PlatformChannelWritev(PlatformHandle h, struct iovec* iov, size_t num_iov);
 
 // Writes data, and the given set of |PlatformHandle|s (i.e., file descriptors)
 // over the Unix domain socket given by |h| (e.g., created using
@@ -43,11 +43,11 @@
 // specified by |iov|). (The handles are not closed, regardless of success or
 // failure.)
 MOJO_SYSTEM_IMPL_EXPORT ssize_t
-    PlatformChannelSendmsgWithHandles(PlatformHandle h,
-                                      struct iovec* iov,
-                                      size_t num_iov,
-                                      PlatformHandle* platform_handles,
-                                      size_t num_platform_handles);
+PlatformChannelSendmsgWithHandles(PlatformHandle h,
+                                  struct iovec* iov,
+                                  size_t num_iov,
+                                  PlatformHandle* platform_handles,
+                                  size_t num_platform_handles);
 
 // TODO(vtl): Remove this once I've switched things over to
 // |PlatformChannelSendmsgWithHandles()|.
@@ -65,10 +65,10 @@
 // (in the control message) to |PlatformHandle|s (and append them to
 // |platform_handles|). (This also handles |EINTR|.)
 MOJO_SYSTEM_IMPL_EXPORT ssize_t
-    PlatformChannelRecvmsg(PlatformHandle h,
-                           void* buf,
-                           size_t num_bytes,
-                           std::deque<PlatformHandle>* platform_handles);
+PlatformChannelRecvmsg(PlatformHandle h,
+                       void* buf,
+                       size_t num_bytes,
+                       std::deque<PlatformHandle>* platform_handles);
 
 }  // namespace embedder
 }  // namespace mojo
diff --git a/mojo/edk/embedder/platform_handle_utils.h b/mojo/edk/embedder/platform_handle_utils.h
index f594e21..b3d7a79 100644
--- a/mojo/edk/embedder/platform_handle_utils.h
+++ b/mojo/edk/embedder/platform_handle_utils.h
@@ -18,15 +18,14 @@
     PlatformHandleContainer* platform_handles) {
   for (typename PlatformHandleContainer::iterator it =
            platform_handles->begin();
-       it != platform_handles->end();
-       ++it)
+       it != platform_handles->end(); ++it)
     it->CloseIfNecessary();
 }
 
 // Duplicates the given |PlatformHandle| (which must be valid). (Returns an
 // invalid |ScopedPlatformHandle| on failure.)
 MOJO_SYSTEM_IMPL_EXPORT ScopedPlatformHandle
-    DuplicatePlatformHandle(PlatformHandle platform_handle);
+DuplicatePlatformHandle(PlatformHandle platform_handle);
 
 }  // namespace embedder
 }  // namespace mojo
diff --git a/mojo/edk/embedder/simple_platform_shared_buffer_posix.cc b/mojo/edk/embedder/simple_platform_shared_buffer_posix.cc
index ebb55ee..8dfcf44 100644
--- a/mojo/edk/embedder/simple_platform_shared_buffer_posix.cc
+++ b/mojo/edk/embedder/simple_platform_shared_buffer_posix.cc
@@ -127,12 +127,9 @@
   DCHECK_LE(static_cast<uint64_t>(real_offset),
             static_cast<uint64_t>(std::numeric_limits<off_t>::max()));
 
-  void* real_base = mmap(nullptr,
-                         real_length,
-                         PROT_READ | PROT_WRITE,
-                         MAP_SHARED,
-                         handle_.get().fd,
-                         static_cast<off_t>(real_offset));
+  void* real_base =
+      mmap(nullptr, real_length, PROT_READ | PROT_WRITE, MAP_SHARED,
+           handle_.get().fd, static_cast<off_t>(real_offset));
   // |mmap()| should return |MAP_FAILED| (a.k.a. -1) on error. But it shouldn't
   // return null either.
   if (real_base == MAP_FAILED || !real_base) {
diff --git a/mojo/edk/embedder/test_embedder.cc b/mojo/edk/embedder/test_embedder.cc
index 95d3be6..defab41 100644
--- a/mojo/edk/embedder/test_embedder.cc
+++ b/mojo/edk/embedder/test_embedder.cc
@@ -8,9 +8,10 @@
 #include "base/macros.h"
 #include "base/memory/scoped_ptr.h"
 #include "mojo/edk/embedder/embedder.h"
+#include "mojo/edk/embedder/embedder_internal.h"
 #include "mojo/edk/embedder/simple_platform_support.h"
+#include "mojo/edk/system/channel_manager.h"
 #include "mojo/edk/system/core.h"
-#include "mojo/edk/system/entrypoints.h"
 #include "mojo/edk/system/handle_table.h"
 
 namespace mojo {
@@ -18,18 +19,17 @@
 namespace system {
 namespace internal {
 
-bool ShutdownCheckNoLeaks(Core* core_impl) {
+bool ShutdownCheckNoLeaks(Core* core) {
   // No point in taking the lock.
   const HandleTable::HandleToEntryMap& handle_to_entry_map =
-      core_impl->handle_table_.handle_to_entry_map_;
+      core->handle_table_.handle_to_entry_map_;
 
   if (handle_to_entry_map.empty())
     return true;
 
   for (HandleTable::HandleToEntryMap::const_iterator it =
            handle_to_entry_map.begin();
-       it != handle_to_entry_map.end();
-       ++it) {
+       it != handle_to_entry_map.end(); ++it) {
     LOG(ERROR) << "Mojo embedder shutdown: Leaking handle " << (*it).first;
   }
   return false;
@@ -46,12 +46,14 @@
 }
 
 bool Shutdown() {
-  system::Core* core = system::entrypoints::GetCore();
-  CHECK(core);
-  system::entrypoints::SetCore(nullptr);
+  CHECK(internal::g_channel_manager);
+  delete internal::g_channel_manager;
+  internal::g_channel_manager = nullptr;
 
-  bool rv = system::internal::ShutdownCheckNoLeaks(core);
-  delete core;
+  CHECK(internal::g_core);
+  bool rv = system::internal::ShutdownCheckNoLeaks(internal::g_core);
+  delete internal::g_core;
+  internal::g_core = nullptr;
   return rv;
 }
 
diff --git a/mojo/edk/embedder/test_embedder.h b/mojo/edk/embedder/test_embedder.h
index b6203b4..76917ee 100644
--- a/mojo/edk/embedder/test_embedder.h
+++ b/mojo/edk/embedder/test_embedder.h
@@ -20,6 +20,9 @@
 // do more work to ensure that tests don't leak, etc.) Returns true if there
 // were no problems, false if there were leaks -- i.e., handles still open -- or
 // any other problems.
+//
+// Note: It is up to the caller to ensure that there are not outstanding
+// callbacks from |CreateChannel()| before calling this.
 MOJO_SYSTEM_IMPL_EXPORT bool Shutdown();
 
 }  // namespace test
diff --git a/mojo/edk/js/core.cc b/mojo/edk/js/core.cc
index 91a746c..232f0e3 100644
--- a/mojo/edk/js/core.cc
+++ b/mojo/edk/js/core.cc
@@ -247,69 +247,73 @@
       &g_wrapper_info);
 
   if (templ.IsEmpty()) {
-     templ = gin::ObjectTemplateBuilder(isolate)
-        // TODO(mpcomplete): Should these just be methods on the JS Handle
-        // object?
-        .SetMethod("close", CloseHandle)
-        .SetMethod("wait", WaitHandle)
-        .SetMethod("waitMany", WaitMany)
-        .SetMethod("createMessagePipe", CreateMessagePipe)
-        .SetMethod("writeMessage", WriteMessage)
-        .SetMethod("readMessage", ReadMessage)
-        .SetMethod("createDataPipe", CreateDataPipe)
-        .SetMethod("writeData", WriteData)
-        .SetMethod("readData", ReadData)
-        .SetMethod("drainData", DoDrainData)
+    templ =
+        gin::ObjectTemplateBuilder(isolate)
+            // TODO(mpcomplete): Should these just be methods on the JS Handle
+            // object?
+            .SetMethod("close", CloseHandle)
+            .SetMethod("wait", WaitHandle)
+            .SetMethod("waitMany", WaitMany)
+            .SetMethod("createMessagePipe", CreateMessagePipe)
+            .SetMethod("writeMessage", WriteMessage)
+            .SetMethod("readMessage", ReadMessage)
+            .SetMethod("createDataPipe", CreateDataPipe)
+            .SetMethod("writeData", WriteData)
+            .SetMethod("readData", ReadData)
+            .SetMethod("drainData", DoDrainData)
 
-        .SetValue("RESULT_OK", MOJO_RESULT_OK)
-        .SetValue("RESULT_CANCELLED", MOJO_RESULT_CANCELLED)
-        .SetValue("RESULT_UNKNOWN", MOJO_RESULT_UNKNOWN)
-        .SetValue("RESULT_INVALID_ARGUMENT", MOJO_RESULT_INVALID_ARGUMENT)
-        .SetValue("RESULT_DEADLINE_EXCEEDED", MOJO_RESULT_DEADLINE_EXCEEDED)
-        .SetValue("RESULT_NOT_FOUND", MOJO_RESULT_NOT_FOUND)
-        .SetValue("RESULT_ALREADY_EXISTS", MOJO_RESULT_ALREADY_EXISTS)
-        .SetValue("RESULT_PERMISSION_DENIED", MOJO_RESULT_PERMISSION_DENIED)
-        .SetValue("RESULT_RESOURCE_EXHAUSTED", MOJO_RESULT_RESOURCE_EXHAUSTED)
-        .SetValue("RESULT_FAILED_PRECONDITION", MOJO_RESULT_FAILED_PRECONDITION)
-        .SetValue("RESULT_ABORTED", MOJO_RESULT_ABORTED)
-        .SetValue("RESULT_OUT_OF_RANGE", MOJO_RESULT_OUT_OF_RANGE)
-        .SetValue("RESULT_UNIMPLEMENTED", MOJO_RESULT_UNIMPLEMENTED)
-        .SetValue("RESULT_INTERNAL", MOJO_RESULT_INTERNAL)
-        .SetValue("RESULT_UNAVAILABLE", MOJO_RESULT_UNAVAILABLE)
-        .SetValue("RESULT_DATA_LOSS", MOJO_RESULT_DATA_LOSS)
-        .SetValue("RESULT_BUSY", MOJO_RESULT_BUSY)
-        .SetValue("RESULT_SHOULD_WAIT", MOJO_RESULT_SHOULD_WAIT)
+            .SetValue("RESULT_OK", MOJO_RESULT_OK)
+            .SetValue("RESULT_CANCELLED", MOJO_RESULT_CANCELLED)
+            .SetValue("RESULT_UNKNOWN", MOJO_RESULT_UNKNOWN)
+            .SetValue("RESULT_INVALID_ARGUMENT", MOJO_RESULT_INVALID_ARGUMENT)
+            .SetValue("RESULT_DEADLINE_EXCEEDED", MOJO_RESULT_DEADLINE_EXCEEDED)
+            .SetValue("RESULT_NOT_FOUND", MOJO_RESULT_NOT_FOUND)
+            .SetValue("RESULT_ALREADY_EXISTS", MOJO_RESULT_ALREADY_EXISTS)
+            .SetValue("RESULT_PERMISSION_DENIED", MOJO_RESULT_PERMISSION_DENIED)
+            .SetValue("RESULT_RESOURCE_EXHAUSTED",
+                      MOJO_RESULT_RESOURCE_EXHAUSTED)
+            .SetValue("RESULT_FAILED_PRECONDITION",
+                      MOJO_RESULT_FAILED_PRECONDITION)
+            .SetValue("RESULT_ABORTED", MOJO_RESULT_ABORTED)
+            .SetValue("RESULT_OUT_OF_RANGE", MOJO_RESULT_OUT_OF_RANGE)
+            .SetValue("RESULT_UNIMPLEMENTED", MOJO_RESULT_UNIMPLEMENTED)
+            .SetValue("RESULT_INTERNAL", MOJO_RESULT_INTERNAL)
+            .SetValue("RESULT_UNAVAILABLE", MOJO_RESULT_UNAVAILABLE)
+            .SetValue("RESULT_DATA_LOSS", MOJO_RESULT_DATA_LOSS)
+            .SetValue("RESULT_BUSY", MOJO_RESULT_BUSY)
+            .SetValue("RESULT_SHOULD_WAIT", MOJO_RESULT_SHOULD_WAIT)
 
-        .SetValue("DEADLINE_INDEFINITE", MOJO_DEADLINE_INDEFINITE)
+            .SetValue("DEADLINE_INDEFINITE", MOJO_DEADLINE_INDEFINITE)
 
-        .SetValue("HANDLE_SIGNAL_NONE", MOJO_HANDLE_SIGNAL_NONE)
-        .SetValue("HANDLE_SIGNAL_READABLE", MOJO_HANDLE_SIGNAL_READABLE)
-        .SetValue("HANDLE_SIGNAL_WRITABLE", MOJO_HANDLE_SIGNAL_WRITABLE)
+            .SetValue("HANDLE_SIGNAL_NONE", MOJO_HANDLE_SIGNAL_NONE)
+            .SetValue("HANDLE_SIGNAL_READABLE", MOJO_HANDLE_SIGNAL_READABLE)
+            .SetValue("HANDLE_SIGNAL_WRITABLE", MOJO_HANDLE_SIGNAL_WRITABLE)
 
-        .SetValue("CREATE_MESSAGE_PIPE_OPTIONS_FLAG_NONE",
-                  MOJO_CREATE_MESSAGE_PIPE_OPTIONS_FLAG_NONE)
+            .SetValue("CREATE_MESSAGE_PIPE_OPTIONS_FLAG_NONE",
+                      MOJO_CREATE_MESSAGE_PIPE_OPTIONS_FLAG_NONE)
 
-        .SetValue("WRITE_MESSAGE_FLAG_NONE", MOJO_WRITE_MESSAGE_FLAG_NONE)
+            .SetValue("WRITE_MESSAGE_FLAG_NONE", MOJO_WRITE_MESSAGE_FLAG_NONE)
 
-        .SetValue("READ_MESSAGE_FLAG_NONE", MOJO_READ_MESSAGE_FLAG_NONE)
-        .SetValue("READ_MESSAGE_FLAG_MAY_DISCARD",
-                  MOJO_READ_MESSAGE_FLAG_MAY_DISCARD)
+            .SetValue("READ_MESSAGE_FLAG_NONE", MOJO_READ_MESSAGE_FLAG_NONE)
+            .SetValue("READ_MESSAGE_FLAG_MAY_DISCARD",
+                      MOJO_READ_MESSAGE_FLAG_MAY_DISCARD)
 
-        .SetValue("CREATE_DATA_PIPE_OPTIONS_FLAG_NONE",
-                  MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_NONE)
-        .SetValue("CREATE_DATA_PIPE_OPTIONS_FLAG_MAY_DISCARD",
-                  MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_MAY_DISCARD)
+            .SetValue("CREATE_DATA_PIPE_OPTIONS_FLAG_NONE",
+                      MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_NONE)
+            .SetValue("CREATE_DATA_PIPE_OPTIONS_FLAG_MAY_DISCARD",
+                      MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_MAY_DISCARD)
 
-        .SetValue("WRITE_DATA_FLAG_NONE", MOJO_WRITE_DATA_FLAG_NONE)
-        .SetValue("WRITE_DATA_FLAG_ALL_OR_NONE",
-                  MOJO_WRITE_DATA_FLAG_ALL_OR_NONE)
+            .SetValue("WRITE_DATA_FLAG_NONE", MOJO_WRITE_DATA_FLAG_NONE)
+            .SetValue("WRITE_DATA_FLAG_ALL_OR_NONE",
+                      MOJO_WRITE_DATA_FLAG_ALL_OR_NONE)
 
-        .SetValue("READ_DATA_FLAG_NONE", MOJO_READ_DATA_FLAG_NONE)
-        .SetValue("READ_DATA_FLAG_ALL_OR_NONE",
-                  MOJO_READ_DATA_FLAG_ALL_OR_NONE)
-        .SetValue("READ_DATA_FLAG_DISCARD", MOJO_READ_DATA_FLAG_DISCARD)
-        .SetValue("READ_DATA_FLAG_QUERY", MOJO_READ_DATA_FLAG_QUERY)
-        .Build();
+            .SetValue("READ_DATA_FLAG_NONE", MOJO_READ_DATA_FLAG_NONE)
+            .SetValue("READ_DATA_FLAG_ALL_OR_NONE",
+                      MOJO_READ_DATA_FLAG_ALL_OR_NONE)
+            .SetValue("READ_DATA_FLAG_DISCARD", MOJO_READ_DATA_FLAG_DISCARD)
+            .SetValue("READ_DATA_FLAG_QUERY", MOJO_READ_DATA_FLAG_QUERY)
+            .SetValue("READ_DATA_FLAG_PEEK", MOJO_READ_DATA_FLAG_PEEK)
+            .Build();
 
     data->SetObjectTemplate(&g_wrapper_info, templ);
   }
diff --git a/mojo/edk/js/core.h b/mojo/edk/js/core.h
index bde327c..445fb00 100644
--- a/mojo/edk/js/core.h
+++ b/mojo/edk/js/core.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_BINDINGS_JS_CORE_H_
-#define MOJO_BINDINGS_JS_CORE_H_
+#ifndef MOJO_EDK_JS_CORE_H_
+#define MOJO_EDK_JS_CORE_H_
 
 #include "v8/include/v8.h"
 
@@ -19,4 +19,4 @@
 }  // namespace js
 }  // namespace mojo
 
-#endif  // MOJO_BINDINGS_JS_CORE_H_
+#endif  // MOJO_EDK_JS_CORE_H_
diff --git a/mojo/edk/js/drain_data.h b/mojo/edk/js/drain_data.h
index 27d8f52..48f1de2 100644
--- a/mojo/edk/js/drain_data.h
+++ b/mojo/edk/js/drain_data.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_BINDINGS_JS_DRAIN_DATA_H_
-#define MOJO_BINDINGS_JS_DRAIN_DATA_H_
+#ifndef MOJO_EDK_JS_DRAIN_DATA_H_
+#define MOJO_EDK_JS_DRAIN_DATA_H_
 
 #include "base/memory/scoped_vector.h"
 #include "gin/runner.h"
@@ -61,4 +61,4 @@
 }  // namespace js
 }  // namespace mojo
 
-#endif  // MOJO_BINDINGS_JS_DRAIN_DATA_H_
+#endif  // MOJO_EDK_JS_DRAIN_DATA_H_
diff --git a/mojo/edk/js/handle.cc b/mojo/edk/js/handle.cc
index ae3415f..de8f338 100644
--- a/mojo/edk/js/handle.cc
+++ b/mojo/edk/js/handle.cc
@@ -4,7 +4,6 @@
 
 #include "mojo/edk/js/handle.h"
 
-#include <sstream>
 #include "mojo/edk/js/handle_close_observer.h"
 
 namespace mojo {
@@ -20,23 +19,6 @@
   NotifyCloseObservers();
 }
 
-std::string HandleWrapper::ToString() {
-  std::ostringstream oss;
-  oss << "[mojo::Handle ";
-  if (handle_.is_valid())
-    oss << handle_.get().value();
-  else
-    oss << "null";
-  oss << "]";
-  return oss.str();
-}
-
-gin::ObjectTemplateBuilder HandleWrapper::GetObjectTemplateBuilder(
-    v8::Isolate* isolate) {
-  return Wrappable<HandleWrapper>::GetObjectTemplateBuilder(isolate)
-      .SetMethod("toString", &HandleWrapper::ToString);
-}
-
 void HandleWrapper::Close() {
   NotifyCloseObservers();
   handle_.reset();
diff --git a/mojo/edk/js/handle.h b/mojo/edk/js/handle.h
index e363b7c..200b322 100644
--- a/mojo/edk/js/handle.h
+++ b/mojo/edk/js/handle.h
@@ -2,13 +2,12 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef MOJO_BINDINGS_JS_HANDLE_H_
-#define MOJO_BINDINGS_JS_HANDLE_H_
+#ifndef MOJO_EDK_JS_HANDLE_H_
+#define MOJO_EDK_JS_HANDLE_H_
 
 #include "base/observer_list.h"
 #include "gin/converter.h"
 #include "gin/handle.h"
-#include "gin/object_template_builder.h"
 #include "gin/wrappable.h"
 #include "mojo/public/cpp/system/core.h"
 
@@ -27,11 +26,6 @@
     return gin::CreateHandle(isolate, new HandleWrapper(handle));
   }
 
-  std::string ToString();
-
-  gin::ObjectTemplateBuilder GetObjectTemplateBuilder(v8::Isolate* isolate)
-      override;
-
   mojo::Handle get() const { return handle_.get(); }
   mojo::Handle release() { return handle_.release(); }
   void Close();
@@ -101,4 +95,4 @@
 
 }  // namespace gin
 
-#endif  // MOJO_BINDINGS_JS_HANDLE_H_
+#endif  // MOJO_EDK_JS_HANDLE_H_
diff --git a/mojo/edk/js/handle_close_observer.h b/mojo/edk/js/handle_close_observer.h
index 8f19466..3e537fd 100644
--- a/mojo/edk/js/handle_close_observer.h
+++ b/mojo/edk/js/handle_close_observer.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_BINDINGS_JS_HANDLE_CLOSE_OBSERVER_H_
-#define MOJO_BINDINGS_JS_HANDLE_CLOSE_OBSERVER_H_
+#ifndef MOJO_EDK_JS_HANDLE_CLOSE_OBSERVER_H_
+#define MOJO_EDK_JS_HANDLE_CLOSE_OBSERVER_H_
 
 namespace mojo {
 namespace js {
@@ -19,4 +19,4 @@
 }  // namespace js
 }  // namespace mojo
 
-#endif  // MOJO_BINDINGS_JS_HANDLE_CLOSE_OBSERVER_H_
+#endif  // MOJO_EDK_JS_HANDLE_CLOSE_OBSERVER_H_
diff --git a/mojo/edk/js/mojo_runner_delegate.cc b/mojo/edk/js/mojo_runner_delegate.cc
new file mode 100644
index 0000000..152b12c
--- /dev/null
+++ b/mojo/edk/js/mojo_runner_delegate.cc
@@ -0,0 +1,78 @@
+// 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/edk/js/mojo_runner_delegate.h"
+
+#include "base/bind.h"
+#include "base/path_service.h"
+#include "gin/converter.h"
+#include "gin/modules/console.h"
+#include "gin/modules/module_registry.h"
+#include "gin/modules/timer.h"
+#include "gin/try_catch.h"
+#include "mojo/edk/js/core.h"
+#include "mojo/edk/js/handle.h"
+#include "mojo/edk/js/support.h"
+#include "mojo/edk/js/threading.h"
+
+namespace mojo {
+namespace js {
+
+namespace {
+
+// TODO(abarth): Rather than loading these modules from the file system, we
+// should load them from the network via Mojo IPC.
+std::vector<base::FilePath> GetModuleSearchPaths() {
+  std::vector<base::FilePath> search_paths(2);
+  PathService::Get(base::DIR_SOURCE_ROOT, &search_paths[0]);
+  PathService::Get(base::DIR_EXE, &search_paths[1]);
+  search_paths[1] = search_paths[1].AppendASCII("gen");
+  return search_paths;
+}
+
+void StartCallback(base::WeakPtr<gin::Runner> runner,
+                   MojoHandle pipe,
+                   v8::Handle<v8::Value> module) {
+  v8::Isolate* isolate = runner->GetContextHolder()->isolate();
+  v8::Handle<v8::Function> start;
+  CHECK(gin::ConvertFromV8(isolate, module, &start));
+
+  v8::Handle<v8::Value> args[] = {
+      gin::ConvertToV8(isolate, Handle(pipe)) };
+  runner->Call(start, runner->global(), 1, args);
+}
+
+}  // namespace
+
+MojoRunnerDelegate::MojoRunnerDelegate()
+    : ModuleRunnerDelegate(GetModuleSearchPaths()) {
+  AddBuiltinModule(gin::Console::kModuleName, gin::Console::GetModule);
+  AddBuiltinModule(gin::TimerModule::kName, gin::TimerModule::GetModule);
+  AddBuiltinModule(js::Core::kModuleName, js::Core::GetModule);
+  AddBuiltinModule(js::Support::kModuleName, js::Support::GetModule);
+  AddBuiltinModule(js::Threading::kModuleName, js::Threading::GetModule);
+}
+
+MojoRunnerDelegate::~MojoRunnerDelegate() {
+}
+
+void MojoRunnerDelegate::Start(gin::Runner* runner,
+                               MojoHandle pipe,
+                               const std::string& module) {
+  gin::Runner::Scope scope(runner);
+  gin::ModuleRegistry* registry =
+      gin::ModuleRegistry::From(runner->GetContextHolder()->context());
+  registry->LoadModule(runner->GetContextHolder()->isolate(), module,
+                       base::Bind(StartCallback, runner->GetWeakPtr(), pipe));
+  AttemptToLoadMoreModules(runner);
+}
+
+void MojoRunnerDelegate::UnhandledException(gin::ShellRunner* runner,
+                                            gin::TryCatch& try_catch) {
+  gin::ModuleRunnerDelegate::UnhandledException(runner, try_catch);
+  LOG(ERROR) << try_catch.GetStackTrace();
+}
+
+}  // namespace js
+}  // namespace mojo
diff --git a/mojo/edk/js/mojo_runner_delegate.h b/mojo/edk/js/mojo_runner_delegate.h
new file mode 100644
index 0000000..423eefb
--- /dev/null
+++ b/mojo/edk/js/mojo_runner_delegate.h
@@ -0,0 +1,33 @@
+// 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_EDK_JS_MOJO_RUNNER_DELEGATE_H_
+#define MOJO_EDK_JS_MOJO_RUNNER_DELEGATE_H_
+
+#include "base/macros.h"
+#include "gin/modules/module_runner_delegate.h"
+#include "mojo/public/c/system/core.h"
+
+namespace mojo {
+namespace js {
+
+class MojoRunnerDelegate : public gin::ModuleRunnerDelegate {
+ public:
+  MojoRunnerDelegate();
+  ~MojoRunnerDelegate() override;
+
+  void Start(gin::Runner* runner, MojoHandle pipe, const std::string& module);
+
+ private:
+  // From ModuleRunnerDelegate:
+  void UnhandledException(gin::ShellRunner* runner,
+                          gin::TryCatch& try_catch) override;
+
+  DISALLOW_COPY_AND_ASSIGN(MojoRunnerDelegate);
+};
+
+}  // namespace js
+}  // namespace mojo
+
+#endif  // MOJO_EDK_JS_MOJO_RUNNER_DELEGATE_H_
diff --git a/mojo/edk/js/support.h b/mojo/edk/js/support.h
index 0f6eb07..b49dd23 100644
--- a/mojo/edk/js/support.h
+++ b/mojo/edk/js/support.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_BINDINGS_JS_SUPPORT_H_
-#define MOJO_BINDINGS_JS_SUPPORT_H_
+#ifndef MOJO_EDK_JS_SUPPORT_H_
+#define MOJO_EDK_JS_SUPPORT_H_
 
 #include "v8/include/v8.h"
 
@@ -19,4 +19,4 @@
 }  // namespace js
 }  // namespace mojo
 
-#endif  // MOJO_BINDINGS_JS_SUPPORT_H_
+#endif  // MOJO_EDK_JS_SUPPORT_H_
diff --git a/mojo/edk/js/test/hexdump.js b/mojo/edk/js/test/hexdump.js
new file mode 100644
index 0000000..b36c47f
--- /dev/null
+++ b/mojo/edk/js/test/hexdump.js
@@ -0,0 +1,34 @@
+// 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.
+
+define(function() {
+  function hexify(value, length) {
+    var hex = value.toString(16);
+    while (hex.length < length)
+      hex = "0" + hex;
+    return hex;
+  }
+
+  function dumpArray(bytes) {
+    var dumped = "";
+    for (var i = 0; i < bytes.length; ++i) {
+      dumped += hexify(bytes[i], 2);
+
+      if (i % 16 == 15) {
+        dumped += "\n";
+        continue;
+      }
+
+      if (i % 2 == 1)
+        dumped += " ";
+      if (i % 8 == 7)
+        dumped += " ";
+    }
+    return dumped;
+  }
+
+  var exports = {};
+  exports.dumpArray = dumpArray;
+  return exports;
+});
diff --git a/mojo/edk/js/tests/run_js_tests.cc b/mojo/edk/js/test/run_js_integration_tests.cc
similarity index 64%
copy from mojo/edk/js/tests/run_js_tests.cc
copy to mojo/edk/js/test/run_js_integration_tests.cc
index 4246f8e..1a6f1d6 100644
--- a/mojo/edk/js/tests/run_js_tests.cc
+++ b/mojo/edk/js/test/run_js_integration_tests.cc
@@ -11,7 +11,7 @@
 #include "gin/test/gtest.h"
 #include "mojo/edk/js/core.h"
 #include "mojo/edk/js/support.h"
-#include "mojo/public/cpp/environment/environment.h"
+#include "mojo/edk/js/threading.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace mojo {
@@ -23,40 +23,33 @@
   TestRunnerDelegate() {
     AddBuiltinModule(gin::Console::kModuleName, gin::Console::GetModule);
     AddBuiltinModule(Core::kModuleName, Core::GetModule);
-    AddBuiltinModule(Support::kModuleName, Support::GetModule);
+    AddBuiltinModule(gin::TimerModule::kName, gin::TimerModule::GetModule);
+    AddBuiltinModule(Threading::kModuleName, Threading::GetModule);
   }
-
  private:
   DISALLOW_COPY_AND_ASSIGN(TestRunnerDelegate);
 };
 
-void RunTest(std::string test, bool run_until_idle) {
-  Environment env;
+void RunTest(std::string test, bool addSupportModule) {
   base::FilePath path;
   PathService::Get(base::DIR_SOURCE_ROOT, &path);
   path = path.AppendASCII("mojo")
-             .AppendASCII("public")
+             .AppendASCII("edk")
              .AppendASCII("js")
+             .AppendASCII("tests")
              .AppendASCII(test);
   TestRunnerDelegate delegate;
-  gin::RunTestFromFile(path, &delegate, run_until_idle);
+  if (addSupportModule)
+    delegate.AddBuiltinModule(Support::kModuleName, Support::GetModule);
+  gin::RunTestFromFile(path, &delegate, true);
 }
 
-// TODO(abarth): Should we autogenerate these stubs from GYP?
-TEST(JSTest, core) {
-  RunTest("core_unittests.js", true);
+TEST(JSTest, connection) {
+  RunTest("connection_tests.js", false);
 }
 
-TEST(JSTest, codec) {
-  RunTest("codec_unittests.js", true);
-}
-
-TEST(JSTest, struct) {
-  RunTest("struct_unittests.js", true);
-}
-
-TEST(JSTest, validation) {
-  RunTest("validation_unittests.js", true);
+TEST(JSTest, sample_service) {
+  RunTest("sample_service_tests.js", true);
 }
 
 }  // namespace
diff --git a/mojo/edk/js/tests/run_js_tests.cc b/mojo/edk/js/test/run_js_tests.cc
similarity index 96%
rename from mojo/edk/js/tests/run_js_tests.cc
rename to mojo/edk/js/test/run_js_tests.cc
index 4246f8e..b574902 100644
--- a/mojo/edk/js/tests/run_js_tests.cc
+++ b/mojo/edk/js/test/run_js_tests.cc
@@ -6,7 +6,6 @@
 #include "base/path_service.h"
 #include "gin/modules/console.h"
 #include "gin/modules/module_registry.h"
-#include "gin/modules/timer.h"
 #include "gin/test/file_runner.h"
 #include "gin/test/gtest.h"
 #include "mojo/edk/js/core.h"
@@ -31,7 +30,6 @@
 };
 
 void RunTest(std::string test, bool run_until_idle) {
-  Environment env;
   base::FilePath path;
   PathService::Get(base::DIR_SOURCE_ROOT, &path);
   path = path.AppendASCII("mojo")
diff --git a/mojo/edk/js/tests/connection_tests.js b/mojo/edk/js/tests/connection_tests.js
new file mode 100644
index 0000000..6649dfe
--- /dev/null
+++ b/mojo/edk/js/tests/connection_tests.js
@@ -0,0 +1,261 @@
+// 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.
+
+// Mock out the support module to avoid depending on the message loop.
+define("mojo/public/js/support", ["timer"], function(timer) {
+  var waitingCallbacks = [];
+
+  function WaitCookie(id) {
+    this.id = id;
+  }
+
+  function asyncWait(handle, flags, callback) {
+    var id = waitingCallbacks.length;
+    waitingCallbacks.push(callback);
+    return new WaitCookie(id);
+  }
+
+  function cancelWait(cookie) {
+    waitingCallbacks[cookie.id] = null;
+  }
+
+  function numberOfWaitingCallbacks() {
+    var count = 0;
+    for (var i = 0; i < waitingCallbacks.length; ++i) {
+      if (waitingCallbacks[i])
+        ++count;
+    }
+    return count;
+  }
+
+  function pumpOnce(result) {
+    var callbacks = waitingCallbacks;
+    waitingCallbacks = [];
+    for (var i = 0; i < callbacks.length; ++i) {
+      if (callbacks[i])
+        callbacks[i](result);
+    }
+  }
+
+  // Queue up a pumpOnce call to execute after the stack unwinds. Use
+  // this to trigger a pump after all Promises are executed.
+  function queuePump(result) {
+    timer.createOneShot(0, pumpOnce.bind(undefined, result));
+  }
+
+  var exports = {};
+  exports.asyncWait = asyncWait;
+  exports.cancelWait = cancelWait;
+  exports.numberOfWaitingCallbacks = numberOfWaitingCallbacks;
+  exports.pumpOnce = pumpOnce;
+  exports.queuePump = queuePump;
+  return exports;
+});
+
+define([
+    "gin/test/expect",
+    "mojo/public/js/support",
+    "mojo/public/js/core",
+    "mojo/public/js/connection",
+    "mojo/public/interfaces/bindings/tests/sample_interfaces.mojom",
+    "mojo/public/interfaces/bindings/tests/sample_service.mojom",
+    "mojo/public/js/threading",
+    "gc",
+], function(expect,
+            mockSupport,
+            core,
+            connection,
+            sample_interfaces,
+            sample_service,
+            threading,
+            gc) {
+  testClientServer();
+  testWriteToClosedPipe();
+  testRequestResponse().then(function() {
+    this.result = "PASS";
+    gc.collectGarbage();  // should not crash
+    threading.quit();
+  }.bind(this)).catch(function(e) {
+    this.result = "FAIL: " + (e.stack || e);
+    threading.quit();
+  }.bind(this));
+
+  function testClientServer() {
+    var receivedFrobinate = false;
+    var receivedDidFrobinate = false;
+
+    // ServiceImpl ------------------------------------------------------------
+
+    function ServiceImpl(peer) {
+      this.peer = peer;
+    }
+
+    ServiceImpl.prototype = Object.create(
+        sample_service.Service.stubClass.prototype);
+
+    ServiceImpl.prototype.frobinate = function(foo, baz, port) {
+      receivedFrobinate = true;
+
+      expect(foo.name).toBe("Example name");
+      expect(baz).toBeTruthy();
+      expect(core.close(port)).toBe(core.RESULT_OK);
+
+      this.peer.didFrobinate(42);
+    };
+
+    // ServiceClientImpl ------------------------------------------------------
+
+    function ServiceClientImpl(peer) {
+      this.peer = peer;
+    }
+
+    ServiceClientImpl.prototype =
+        Object.create(sample_service.ServiceClient.stubClass.prototype);
+
+    ServiceClientImpl.prototype.didFrobinate = function(result) {
+      receivedDidFrobinate = true;
+
+      expect(result).toBe(42);
+    };
+
+    var pipe = core.createMessagePipe();
+    var anotherPipe = core.createMessagePipe();
+    var sourcePipe = core.createMessagePipe();
+
+    var connection0 = new connection.Connection(
+        pipe.handle0, ServiceImpl, sample_service.ServiceClient.proxyClass);
+
+    var connection1 = new connection.Connection(
+        pipe.handle1, ServiceClientImpl, sample_service.Service.proxyClass);
+
+    var foo = new sample_service.Foo();
+    foo.bar = new sample_service.Bar();
+    foo.name = "Example name";
+    foo.source = sourcePipe.handle0;
+    connection1.remote.frobinate(foo, true, anotherPipe.handle0);
+
+    mockSupport.pumpOnce(core.RESULT_OK);
+
+    expect(receivedFrobinate).toBeTruthy();
+    expect(receivedDidFrobinate).toBeTruthy();
+
+    connection0.close();
+    connection1.close();
+
+    expect(mockSupport.numberOfWaitingCallbacks()).toBe(0);
+
+    // sourcePipe.handle0 was closed automatically when sent over IPC.
+    expect(core.close(sourcePipe.handle0)).toBe(core.RESULT_INVALID_ARGUMENT);
+    // sourcePipe.handle1 hasn't been closed yet.
+    expect(core.close(sourcePipe.handle1)).toBe(core.RESULT_OK);
+
+    // anotherPipe.handle0 was closed automatically when sent over IPC.
+    expect(core.close(anotherPipe.handle0)).toBe(core.RESULT_INVALID_ARGUMENT);
+    // anotherPipe.handle1 hasn't been closed yet.
+    expect(core.close(anotherPipe.handle1)).toBe(core.RESULT_OK);
+
+    // The Connection object is responsible for closing these handles.
+    expect(core.close(pipe.handle0)).toBe(core.RESULT_INVALID_ARGUMENT);
+    expect(core.close(pipe.handle1)).toBe(core.RESULT_INVALID_ARGUMENT);
+  }
+
+  function testWriteToClosedPipe() {
+    var pipe = core.createMessagePipe();
+
+    var connection1 = new connection.Connection(
+        pipe.handle1, function() {}, sample_service.Service.proxyClass);
+
+    // Close the other end of the pipe.
+    core.close(pipe.handle0);
+
+    // Not observed yet because we haven't pumped events yet.
+    expect(connection1.encounteredError()).toBeFalsy();
+
+    var foo = new sample_service.Foo();
+    foo.bar = new sample_service.Bar();
+    // TODO(darin): crbug.com/357043: pass null in place of |foo| here.
+    connection1.remote.frobinate(foo, true, null);
+
+    // Write failures are not reported.
+    expect(connection1.encounteredError()).toBeFalsy();
+
+    // Pump events, and then we should start observing the closed pipe.
+    mockSupport.pumpOnce(core.RESULT_OK);
+
+    expect(connection1.encounteredError()).toBeTruthy();
+
+    connection1.close();
+  }
+
+  function testRequestResponse() {
+
+    // ProviderImpl ------------------------------------------------------------
+
+    function ProviderImpl(peer) {
+      this.peer = peer;
+    }
+
+    ProviderImpl.prototype =
+        Object.create(sample_interfaces.Provider.stubClass.prototype);
+
+    ProviderImpl.prototype.echoString = function(a) {
+      mockSupport.queuePump(core.RESULT_OK);
+      return Promise.resolve({a: a});
+    };
+
+    ProviderImpl.prototype.echoStrings = function(a, b) {
+      mockSupport.queuePump(core.RESULT_OK);
+      return Promise.resolve({a: a, b: b});
+    };
+
+    // ProviderClientImpl ------------------------------------------------------
+
+    function ProviderClientImpl(peer) {
+      this.peer = peer;
+    }
+
+    ProviderClientImpl.prototype =
+        Object.create(sample_interfaces.ProviderClient.stubClass.prototype);
+
+    var pipe = core.createMessagePipe();
+
+    var connection0 = new connection.Connection(
+        pipe.handle0,
+        ProviderImpl,
+        sample_interfaces.ProviderClient.proxyClass);
+
+    var connection1 = new connection.Connection(
+        pipe.handle1,
+        ProviderClientImpl,
+        sample_interfaces.Provider.proxyClass);
+
+    var origReadMessage = core.readMessage;
+    // echoString
+    mockSupport.queuePump(core.RESULT_OK);
+    return connection1.remote.echoString("hello").then(function(response) {
+      expect(response.a).toBe("hello");
+    }).then(function() {
+      // echoStrings
+      mockSupport.queuePump(core.RESULT_OK);
+      return connection1.remote.echoStrings("hello", "world");
+    }).then(function(response) {
+      expect(response.a).toBe("hello");
+      expect(response.b).toBe("world");
+    }).then(function() {
+      // Mock a read failure, expect it to fail.
+      core.readMessage = function() {
+        return { result: core.RESULT_UNKNOWN };
+      };
+      mockSupport.queuePump(core.RESULT_OK);
+      return connection1.remote.echoString("goodbye");
+    }).then(function() {
+      throw Error("Expected echoString to fail.");
+    }, function(error) {
+      expect(error.message).toBe("Connection error: " + core.RESULT_UNKNOWN);
+
+      // Clean up.
+      core.readMessage = origReadMessage;
+    });
+  }
+});
diff --git a/mojo/edk/js/tests/js_to_cpp.mojom b/mojo/edk/js/tests/js_to_cpp.mojom
new file mode 100644
index 0000000..69f67b6
--- /dev/null
+++ b/mojo/edk/js/tests/js_to_cpp.mojom
@@ -0,0 +1,53 @@
+module js_to_cpp;
+
+// This struct encompasses all of the basic types, so that they
+// may be sent from C++ to JS and back for validation.
+struct EchoArgs {
+  int64 si64;
+  int32 si32;
+  int16 si16;
+  int8  si8;
+  uint64 ui64;
+  uint32 ui32;
+  uint16 ui16;
+  uint8  ui8;
+  float float_val;
+  float float_inf;
+  float float_nan;
+  double double_val;
+  double double_inf;
+  double double_nan;
+  string? name;
+  array<string>? string_array;
+  handle<message_pipe>? message_handle;
+  handle<data_pipe_consumer>? data_handle;
+};
+
+struct EchoArgsList {
+  EchoArgsList? next;
+  EchoArgs? item;
+};
+
+// Note: For messages which control test flow, pick numbers that are unlikely
+// to be hit as a result of our deliberate corruption of response messages.
+interface CppSide {
+  // Sent for all tests to notify that the JS side is now ready.
+  StartTest@88888888();
+
+  // Indicates end for echo, bit-flip, and back-pointer tests.
+  TestFinished@99999999();
+
+  // Responses from specific tests.
+  PingResponse();
+  EchoResponse(EchoArgsList list);
+  BitFlipResponse(EchoArgsList arg);
+  BackPointerResponse(EchoArgsList arg);
+};
+
+[Client=CppSide]
+interface JsSide {
+  Ping();
+  Echo(int32 numIterations, EchoArgs arg);
+  BitFlip(EchoArgs arg);
+  BackPointer(EchoArgs arg);
+};
diff --git a/mojo/edk/js/tests/js_to_cpp_tests.cc b/mojo/edk/js/tests/js_to_cpp_tests.cc
new file mode 100644
index 0000000..1da70c2
--- /dev/null
+++ b/mojo/edk/js/tests/js_to_cpp_tests.cc
@@ -0,0 +1,418 @@
+// 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/at_exit.h"
+#include "base/files/file_path.h"
+#include "base/files/file_util.h"
+#include "base/macros.h"
+#include "base/message_loop/message_loop.h"
+#include "base/run_loop.h"
+#include "base/strings/utf_string_conversions.h"
+#include "gin/array_buffer.h"
+#include "gin/public/isolate_holder.h"
+#include "mojo/edk/js/mojo_runner_delegate.h"
+#include "mojo/edk/js/tests/js_to_cpp.mojom.h"
+#include "mojo/edk/test/test_utils.h"
+#include "mojo/public/cpp/system/core.h"
+#include "mojo/public/cpp/system/macros.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace mojo {
+namespace js {
+
+// Global value updated by some checks to prevent compilers from optimizing
+// reads out of existence.
+uint32 g_waste_accumulator = 0;
+
+namespace {
+
+// Negative numbers with different values in each byte, the last of
+// which can survive promotion to double and back.
+const int8  kExpectedInt8Value = -65;
+const int16 kExpectedInt16Value = -16961;
+const int32 kExpectedInt32Value = -1145258561;
+const int64 kExpectedInt64Value = -77263311946305LL;
+
+// Positive numbers with different values in each byte, the last of
+// which can survive promotion to double and back.
+const uint8  kExpectedUInt8Value = 65;
+const uint16 kExpectedUInt16Value = 16961;
+const uint32 kExpectedUInt32Value = 1145258561;
+const uint64 kExpectedUInt64Value = 77263311946305LL;
+
+// Double/float values, including special case constants.
+const double kExpectedDoubleVal = 3.14159265358979323846;
+const double kExpectedDoubleInf = std::numeric_limits<double>::infinity();
+const double kExpectedDoubleNan = std::numeric_limits<double>::quiet_NaN();
+const float kExpectedFloatVal = static_cast<float>(kExpectedDoubleVal);
+const float kExpectedFloatInf = std::numeric_limits<float>::infinity();
+const float kExpectedFloatNan = std::numeric_limits<float>::quiet_NaN();
+
+// NaN has the property that it is not equal to itself.
+#define EXPECT_NAN(x) EXPECT_NE(x, x)
+
+void CheckDataPipe(MojoHandle data_pipe_handle) {
+  unsigned char buffer[100];
+  uint32_t buffer_size = static_cast<uint32_t>(sizeof(buffer));
+  MojoResult result = MojoReadData(
+      data_pipe_handle, buffer, &buffer_size, MOJO_READ_DATA_FLAG_NONE);
+  EXPECT_EQ(MOJO_RESULT_OK, result);
+  EXPECT_EQ(64u, buffer_size);
+  for (int i = 0; i < 64; ++i) {
+    EXPECT_EQ(i, buffer[i]);
+  }
+}
+
+void CheckMessagePipe(MojoHandle message_pipe_handle) {
+  unsigned char buffer[100];
+  uint32_t buffer_size = static_cast<uint32_t>(sizeof(buffer));
+  MojoResult result = MojoReadMessage(
+      message_pipe_handle, buffer, &buffer_size, 0, 0, 0);
+  EXPECT_EQ(MOJO_RESULT_OK, result);
+  EXPECT_EQ(64u, buffer_size);
+  for (int i = 0; i < 64; ++i) {
+    EXPECT_EQ(255 - i, buffer[i]);
+  }
+}
+
+js_to_cpp::EchoArgsPtr BuildSampleEchoArgs() {
+  js_to_cpp::EchoArgsPtr args(js_to_cpp::EchoArgs::New());
+  args->si64 = kExpectedInt64Value;
+  args->si32 = kExpectedInt32Value;
+  args->si16 = kExpectedInt16Value;
+  args->si8 = kExpectedInt8Value;
+  args->ui64 = kExpectedUInt64Value;
+  args->ui32 = kExpectedUInt32Value;
+  args->ui16 = kExpectedUInt16Value;
+  args->ui8 = kExpectedUInt8Value;
+  args->float_val = kExpectedFloatVal;
+  args->float_inf = kExpectedFloatInf;
+  args->float_nan = kExpectedFloatNan;
+  args->double_val = kExpectedDoubleVal;
+  args->double_inf = kExpectedDoubleInf;
+  args->double_nan = kExpectedDoubleNan;
+  args->name = "coming";
+  Array<String> string_array(3);
+  string_array[0] = "one";
+  string_array[1] = "two";
+  string_array[2] = "three";
+  args->string_array = string_array.Pass();
+  return args.Pass();
+}
+
+void CheckSampleEchoArgs(const js_to_cpp::EchoArgs& arg) {
+  EXPECT_EQ(kExpectedInt64Value, arg.si64);
+  EXPECT_EQ(kExpectedInt32Value, arg.si32);
+  EXPECT_EQ(kExpectedInt16Value, arg.si16);
+  EXPECT_EQ(kExpectedInt8Value, arg.si8);
+  EXPECT_EQ(kExpectedUInt64Value, arg.ui64);
+  EXPECT_EQ(kExpectedUInt32Value, arg.ui32);
+  EXPECT_EQ(kExpectedUInt16Value, arg.ui16);
+  EXPECT_EQ(kExpectedUInt8Value, arg.ui8);
+  EXPECT_EQ(kExpectedFloatVal, arg.float_val);
+  EXPECT_EQ(kExpectedFloatInf, arg.float_inf);
+  EXPECT_NAN(arg.float_nan);
+  EXPECT_EQ(kExpectedDoubleVal, arg.double_val);
+  EXPECT_EQ(kExpectedDoubleInf, arg.double_inf);
+  EXPECT_NAN(arg.double_nan);
+  EXPECT_EQ(std::string("coming"), arg.name.get());
+  EXPECT_EQ(std::string("one"), arg.string_array[0].get());
+  EXPECT_EQ(std::string("two"), arg.string_array[1].get());
+  EXPECT_EQ(std::string("three"), arg.string_array[2].get());
+  CheckDataPipe(arg.data_handle.get().value());
+  CheckMessagePipe(arg.message_handle.get().value());
+}
+
+void CheckSampleEchoArgsList(const js_to_cpp::EchoArgsListPtr& list) {
+  if (list.is_null())
+    return;
+  CheckSampleEchoArgs(*list->item);
+  CheckSampleEchoArgsList(list->next);
+}
+
+// More forgiving checks are needed in the face of potentially corrupt
+// messages. The values don't matter so long as all accesses are within
+// bounds.
+void CheckCorruptedString(const String& arg) {
+  if (arg.is_null())
+    return;
+  for (size_t i = 0; i < arg.size(); ++i)
+    g_waste_accumulator += arg[i];
+}
+
+void CheckCorruptedStringArray(const Array<String>& string_array) {
+  if (string_array.is_null())
+    return;
+  for (size_t i = 0; i < string_array.size(); ++i)
+    CheckCorruptedString(string_array[i]);
+}
+
+void CheckCorruptedDataPipe(MojoHandle data_pipe_handle) {
+  unsigned char buffer[100];
+  uint32_t buffer_size = static_cast<uint32_t>(sizeof(buffer));
+  MojoResult result = MojoReadData(
+      data_pipe_handle, buffer, &buffer_size, MOJO_READ_DATA_FLAG_NONE);
+  if (result != MOJO_RESULT_OK)
+    return;
+  for (uint32_t i = 0; i < buffer_size; ++i)
+    g_waste_accumulator += buffer[i];
+}
+
+void CheckCorruptedMessagePipe(MojoHandle message_pipe_handle) {
+  unsigned char buffer[100];
+  uint32_t buffer_size = static_cast<uint32_t>(sizeof(buffer));
+  MojoResult result = MojoReadMessage(
+      message_pipe_handle, buffer, &buffer_size, 0, 0, 0);
+  if (result != MOJO_RESULT_OK)
+    return;
+  for (uint32_t i = 0; i < buffer_size; ++i)
+    g_waste_accumulator += buffer[i];
+}
+
+void CheckCorruptedEchoArgs(const js_to_cpp::EchoArgsPtr& arg) {
+  if (arg.is_null())
+    return;
+  CheckCorruptedString(arg->name);
+  CheckCorruptedStringArray(arg->string_array);
+  if (arg->data_handle.is_valid())
+    CheckCorruptedDataPipe(arg->data_handle.get().value());
+  if (arg->message_handle.is_valid())
+    CheckCorruptedMessagePipe(arg->message_handle.get().value());
+}
+
+void CheckCorruptedEchoArgsList(const js_to_cpp::EchoArgsListPtr& list) {
+  if (list.is_null())
+    return;
+  CheckCorruptedEchoArgs(list->item);
+  CheckCorruptedEchoArgsList(list->next);
+}
+
+// Base Provider implementation class. It's expected that tests subclass and
+// override the appropriate Provider functions. When test is done quit the
+// run_loop().
+class CppSideConnection : public js_to_cpp::CppSide {
+ public:
+  CppSideConnection() :
+      run_loop_(NULL),
+      js_side_(NULL),
+      mishandled_messages_(0) {
+  }
+  ~CppSideConnection() override {}
+
+  void set_run_loop(base::RunLoop* run_loop) { run_loop_ = run_loop; }
+  base::RunLoop* run_loop() { return run_loop_; }
+
+  void set_js_side(js_to_cpp::JsSide* js_side) { js_side_ = js_side; }
+  js_to_cpp::JsSide* js_side() { return js_side_; }
+
+  // js_to_cpp::CppSide:
+  void StartTest() override { NOTREACHED(); }
+
+  void TestFinished() override { NOTREACHED(); }
+
+  void PingResponse() override { mishandled_messages_ += 1; }
+
+  void EchoResponse(js_to_cpp::EchoArgsListPtr list) override {
+    mishandled_messages_ += 1;
+  }
+
+  void BitFlipResponse(js_to_cpp::EchoArgsListPtr list) override {
+    mishandled_messages_ += 1;
+  }
+
+  void BackPointerResponse(js_to_cpp::EchoArgsListPtr list) override {
+    mishandled_messages_ += 1;
+  }
+
+ protected:
+  base::RunLoop* run_loop_;
+  js_to_cpp::JsSide* js_side_;
+  int mishandled_messages_;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(CppSideConnection);
+};
+
+// Trivial test to verify a message sent from JS is received.
+class PingCppSideConnection : public CppSideConnection {
+ public:
+  PingCppSideConnection() : got_message_(false) {}
+  ~PingCppSideConnection() override {}
+
+  // js_to_cpp::CppSide:
+  void StartTest() override { js_side_->Ping(); }
+
+  void PingResponse() override {
+    got_message_ = true;
+    run_loop()->Quit();
+  }
+
+  bool DidSucceed() {
+    return got_message_ && !mishandled_messages_;
+  }
+
+ private:
+  bool got_message_;
+  DISALLOW_COPY_AND_ASSIGN(PingCppSideConnection);
+};
+
+// Test that parameters are passed with correct values.
+class EchoCppSideConnection : public CppSideConnection {
+ public:
+  EchoCppSideConnection() :
+      message_count_(0),
+      termination_seen_(false) {
+  }
+  ~EchoCppSideConnection() override {}
+
+  // js_to_cpp::CppSide:
+  void StartTest() override {
+    js_side_->Echo(kExpectedMessageCount, BuildSampleEchoArgs());
+  }
+
+  void EchoResponse(js_to_cpp::EchoArgsListPtr list) override {
+    const js_to_cpp::EchoArgsPtr& special_arg = list->item;
+    message_count_ += 1;
+    EXPECT_EQ(-1, special_arg->si64);
+    EXPECT_EQ(-1, special_arg->si32);
+    EXPECT_EQ(-1, special_arg->si16);
+    EXPECT_EQ(-1, special_arg->si8);
+    EXPECT_EQ(std::string("going"), special_arg->name.To<std::string>());
+    CheckSampleEchoArgsList(list->next);
+  }
+
+  void TestFinished() override {
+    termination_seen_ = true;
+    run_loop()->Quit();
+  }
+
+  bool DidSucceed() {
+    return termination_seen_ &&
+        !mishandled_messages_ &&
+        message_count_ == kExpectedMessageCount;
+  }
+
+ private:
+  static const int kExpectedMessageCount = 10;
+  int message_count_;
+  bool termination_seen_;
+  DISALLOW_COPY_AND_ASSIGN(EchoCppSideConnection);
+};
+
+// Test that corrupted messages don't wreak havoc.
+class BitFlipCppSideConnection : public CppSideConnection {
+ public:
+  BitFlipCppSideConnection() : termination_seen_(false) {}
+  ~BitFlipCppSideConnection() override {}
+
+  // js_to_cpp::CppSide:
+  void StartTest() override { js_side_->BitFlip(BuildSampleEchoArgs()); }
+
+  void BitFlipResponse(js_to_cpp::EchoArgsListPtr list) override {
+    CheckCorruptedEchoArgsList(list);
+  }
+
+  void TestFinished() override {
+    termination_seen_ = true;
+    run_loop()->Quit();
+  }
+
+  bool DidSucceed() {
+    return termination_seen_;
+  }
+
+ private:
+  bool termination_seen_;
+  DISALLOW_COPY_AND_ASSIGN(BitFlipCppSideConnection);
+};
+
+// Test that severely random messages don't wreak havoc.
+class BackPointerCppSideConnection : public CppSideConnection {
+ public:
+  BackPointerCppSideConnection() : termination_seen_(false) {}
+  ~BackPointerCppSideConnection() override {}
+
+  // js_to_cpp::CppSide:
+  void StartTest() override { js_side_->BackPointer(BuildSampleEchoArgs()); }
+
+  void BackPointerResponse(js_to_cpp::EchoArgsListPtr list) override {
+    CheckCorruptedEchoArgsList(list);
+  }
+
+  void TestFinished() override {
+    termination_seen_ = true;
+    run_loop()->Quit();
+  }
+
+  bool DidSucceed() {
+    return termination_seen_;
+  }
+
+ private:
+  bool termination_seen_;
+  DISALLOW_COPY_AND_ASSIGN(BackPointerCppSideConnection);
+};
+
+}  // namespace
+
+class JsToCppTest : public testing::Test {
+ public:
+  JsToCppTest() {}
+
+  void RunTest(const std::string& test, CppSideConnection* cpp_side) {
+    cpp_side->set_run_loop(&run_loop_);
+
+    MessagePipe pipe;
+    js_to_cpp::JsSidePtr js_side =
+        MakeProxy<js_to_cpp::JsSide>(pipe.handle0.Pass());
+    js_side.set_client(cpp_side);
+
+    js_side.internal_state()->router_for_testing()->EnableTestingMode();
+
+    cpp_side->set_js_side(js_side.get());
+
+    gin::IsolateHolder::Initialize(gin::IsolateHolder::kStrictMode,
+                                   gin::ArrayBufferAllocator::SharedInstance());
+    gin::IsolateHolder instance;
+    MojoRunnerDelegate delegate;
+    gin::ShellRunner runner(&delegate, instance.isolate());
+    delegate.Start(&runner, pipe.handle1.release().value(), test);
+
+    run_loop_.Run();
+  }
+
+ private:
+  base::ShadowingAtExitManager at_exit_;
+  base::MessageLoop loop;
+  base::RunLoop run_loop_;
+
+  DISALLOW_COPY_AND_ASSIGN(JsToCppTest);
+};
+
+TEST_F(JsToCppTest, Ping) {
+  PingCppSideConnection cpp_side_connection;
+  RunTest("mojo/edk/js/tests/js_to_cpp_tests", &cpp_side_connection);
+  EXPECT_TRUE(cpp_side_connection.DidSucceed());
+}
+
+TEST_F(JsToCppTest, Echo) {
+  EchoCppSideConnection cpp_side_connection;
+  RunTest("mojo/edk/js/tests/js_to_cpp_tests", &cpp_side_connection);
+  EXPECT_TRUE(cpp_side_connection.DidSucceed());
+}
+
+TEST_F(JsToCppTest, BitFlip) {
+  BitFlipCppSideConnection cpp_side_connection;
+  RunTest("mojo/edk/js/tests/js_to_cpp_tests", &cpp_side_connection);
+  EXPECT_TRUE(cpp_side_connection.DidSucceed());
+}
+
+TEST_F(JsToCppTest, BackPointer) {
+  BackPointerCppSideConnection cpp_side_connection;
+  RunTest("mojo/edk/js/tests/js_to_cpp_tests", &cpp_side_connection);
+  EXPECT_TRUE(cpp_side_connection.DidSucceed());
+}
+
+}  // namespace js
+}  // namespace mojo
diff --git a/mojo/edk/js/tests/js_to_cpp_tests.js b/mojo/edk/js/tests/js_to_cpp_tests.js
new file mode 100644
index 0000000..c32f0af
--- /dev/null
+++ b/mojo/edk/js/tests/js_to_cpp_tests.js
@@ -0,0 +1,221 @@
+// 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.
+
+define('mojo/edk/js/tests/js_to_cpp_tests', [
+  'console',
+  'mojo/edk/js/tests/js_to_cpp.mojom',
+  'mojo/public/js/connection',
+  'mojo/public/js/connector',
+  'mojo/public/js/core',
+], function (console, jsToCpp, connection, connector, core) {
+  var retainedConnection;
+  var sampleData;
+  var sampleMessage;
+  var BAD_VALUE = 13;
+  var DATA_PIPE_PARAMS = {
+    flags: core.CREATE_DATA_PIPE_OPTIONS_FLAG_NONE,
+    elementNumBytes: 1,
+    capacityNumBytes: 64
+  };
+
+  function JsSideConnection(cppSide) {
+    this.cppSide_ = cppSide;
+    cppSide.startTest();
+  }
+
+  JsSideConnection.prototype =
+      Object.create(jsToCpp.JsSide.stubClass.prototype);
+
+  JsSideConnection.prototype.ping = function (arg) {
+    this.cppSide_.pingResponse();
+  };
+
+  JsSideConnection.prototype.echo = function (numIterations, arg) {
+    var dataPipe1;
+    var dataPipe2;
+    var i;
+    var messagePipe1;
+    var messagePipe2;
+    var specialArg;
+
+    // Ensure expected negative values are negative.
+    if (arg.si64 > 0)
+      arg.si64 = BAD_VALUE;
+
+    if (arg.si32 > 0)
+      arg.si32 = BAD_VALUE;
+
+    if (arg.si16 > 0)
+      arg.si16 = BAD_VALUE;
+
+    if (arg.si8 > 0)
+      arg.si8 = BAD_VALUE;
+
+    for (i = 0; i < numIterations; ++i) {
+      dataPipe1 = core.createDataPipe(DATA_PIPE_PARAMS);
+      dataPipe2 = core.createDataPipe(DATA_PIPE_PARAMS);
+      messagePipe1 = core.createMessagePipe();
+      messagePipe2 = core.createMessagePipe();
+
+      arg.data_handle = dataPipe1.consumerHandle;
+      arg.message_handle = messagePipe1.handle1;
+
+      specialArg = new jsToCpp.EchoArgs();
+      specialArg.si64 = -1;
+      specialArg.si32 = -1;
+      specialArg.si16 = -1;
+      specialArg.si8 = -1;
+      specialArg.name = 'going';
+      specialArg.data_handle = dataPipe2.consumerHandle;
+      specialArg.message_handle = messagePipe2.handle1;
+
+      writeDataPipe(dataPipe1, sampleData);
+      writeDataPipe(dataPipe2, sampleData);
+      writeMessagePipe(messagePipe1, sampleMessage);
+      writeMessagePipe(messagePipe2, sampleMessage);
+
+      this.cppSide_.echoResponse(createEchoArgsList(specialArg, arg));
+
+      core.close(dataPipe1.producerHandle);
+      core.close(dataPipe2.producerHandle);
+      core.close(messagePipe1.handle0);
+      core.close(messagePipe2.handle0);
+    }
+    this.cppSide_.testFinished();
+  };
+
+  JsSideConnection.prototype.bitFlip = function (arg) {
+    var iteration = 0;
+    var dataPipe;
+    var messagePipe;
+    var proto = connector.Connector.prototype;
+    var stopSignalled = false;
+
+    proto.realAccept = proto.accept;
+    proto.accept = function (message) {
+      var offset = iteration / 8;
+      var mask;
+      var value;
+      if (offset < message.buffer.arrayBuffer.byteLength) {
+        mask = 1 << (iteration % 8);
+        value = message.buffer.getUint8(offset) ^ mask;
+        message.buffer.setUint8(offset, value);
+        return this.realAccept(message);
+      }
+      stopSignalled = true;
+      return false;
+    };
+
+    while (!stopSignalled) {
+      dataPipe = core.createDataPipe(DATA_PIPE_PARAMS);
+      messagePipe = core.createMessagePipe();
+      writeDataPipe(dataPipe, sampleData);
+      writeMessagePipe(messagePipe, sampleMessage);
+      arg.data_handle = dataPipe.consumerHandle;
+      arg.message_handle = messagePipe.handle1;
+
+      this.cppSide_.bitFlipResponse(createEchoArgsList(arg));
+
+      core.close(dataPipe.producerHandle);
+      core.close(messagePipe.handle0);
+      iteration += 1;
+    }
+
+    proto.accept = proto.realAccept;
+    proto.realAccept = null;
+    this.cppSide_.testFinished();
+  };
+
+  JsSideConnection.prototype.backPointer = function (arg) {
+    var iteration = 0;
+    var dataPipe;
+    var messagePipe;
+    var proto = connector.Connector.prototype;
+    var stopSignalled = false;
+
+    proto.realAccept = proto.accept;
+    proto.accept = function (message) {
+      var delta = 8 * (1 + iteration % 32);
+      var offset = 8 * ((iteration / 32) | 0);
+      if (offset < message.buffer.arrayBuffer.byteLength - 4) {
+        message.buffer.dataView.setUint32(offset, 0x100000000 - delta, true);
+        message.buffer.dataView.setUint32(offset + 4, 0xffffffff, true);
+        return this.realAccept(message);
+      }
+      stopSignalled = true;
+      return false;
+    };
+
+    while (!stopSignalled) {
+      dataPipe = core.createDataPipe(DATA_PIPE_PARAMS);
+      messagePipe = core.createMessagePipe();
+      writeDataPipe(dataPipe, sampleData);
+      writeMessagePipe(messagePipe, sampleMessage);
+      arg.data_handle = dataPipe.consumerHandle;
+      arg.message_handle = messagePipe.handle1;
+
+      this.cppSide_.backPointerResponse(createEchoArgsList(arg));
+
+      core.close(dataPipe.producerHandle);
+      core.close(messagePipe.handle0);
+      iteration += 1;
+    }
+
+    proto.accept = proto.realAccept;
+    proto.realAccept = null;
+    this.cppSide_.testFinished();
+  };
+
+  function writeDataPipe(pipe, data) {
+    var writeResult = core.writeData(
+      pipe.producerHandle, data, core.WRITE_DATA_FLAG_ALL_OR_NONE);
+
+    if (writeResult.result != core.RESULT_OK) {
+      console.log('ERROR: Data pipe write result was ' + writeResult.result);
+      return false;
+    }
+    if (writeResult.numBytes != data.length) {
+      console.log('ERROR: Data pipe write length was ' + writeResult.numBytes);
+      return false;
+    }
+    return true;
+  }
+
+  function writeMessagePipe(pipe, arrayBuffer) {
+    var result = core.writeMessage(pipe.handle0, arrayBuffer, [], 0);
+    if (result != core.RESULT_OK) {
+      console.log('ERROR: Message pipe write result was ' + result);
+      return false;
+    }
+    return true;
+  }
+
+  function createEchoArgsListElement(item, next) {
+    var list = new jsToCpp.EchoArgsList();
+    list.item = item;
+    list.next = next;
+    return list;
+  }
+
+  function createEchoArgsList() {
+    var genuineArray = Array.prototype.slice.call(arguments);
+    return genuineArray.reduceRight(function (previous, current) {
+      return createEchoArgsListElement(current, previous);
+    }, null);
+  }
+
+  return function(handle) {
+    var i;
+    sampleData = new Uint8Array(DATA_PIPE_PARAMS.capacityNumBytes);
+    for (i = 0; i < sampleData.length; ++i) {
+      sampleData[i] = i;
+    }
+    sampleMessage = new Uint8Array(DATA_PIPE_PARAMS.capacityNumBytes);
+    for (i = 0; i < sampleMessage.length; ++i) {
+      sampleMessage[i] = 255 - i;
+    }
+    retainedConnection = new connection.Connection(handle, JsSideConnection,
+                                                   jsToCpp.CppSide.proxyClass);
+  };
+});
diff --git a/mojo/edk/js/tests/sample_service_tests.js b/mojo/edk/js/tests/sample_service_tests.js
new file mode 100644
index 0000000..ca4f8e6
--- /dev/null
+++ b/mojo/edk/js/tests/sample_service_tests.js
@@ -0,0 +1,168 @@
+// 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.
+
+define([
+    "console",
+    "mojo/edk/js/test/hexdump",
+    "gin/test/expect",
+    "mojo/public/interfaces/bindings/tests/sample_service.mojom",
+    "mojo/public/interfaces/bindings/tests/sample_import.mojom",
+    "mojo/public/interfaces/bindings/tests/sample_import2.mojom",
+  ], function(console, hexdump, expect, sample, imported, imported2) {
+
+  var global = this;
+
+  // Set this variable to true to print the binary message in hex.
+  var dumpMessageAsHex = false;
+
+  function makeFoo() {
+    var bar = new sample.Bar();
+    bar.alpha = 20;
+    bar.beta = 40;
+    bar.gamma = 60;
+    bar.type = sample.Bar.Type.VERTICAL;
+
+    var extra_bars = new Array(3);
+    for (var i = 0; i < extra_bars.length; ++i) {
+      var base = i * 100;
+      var type = i % 2 ?
+          sample.Bar.Type.VERTICAL : sample.Bar.Type.HORIZONTAL;
+      extra_bars[i] = new sample.Bar();
+      extra_bars[i].alpha = base;
+      extra_bars[i].beta = base + 20;
+      extra_bars[i].gamma = base + 40;
+      extra_bars[i].type = type;
+    }
+
+    var data = new Array(10);
+    for (var i = 0; i < data.length; ++i) {
+      data[i] = data.length - i;
+    }
+
+    var source = 0xFFFF;  // Invent a dummy handle.
+
+    var foo = new sample.Foo();
+    foo.name = "foopy";
+    foo.x = 1;
+    foo.y = 2;
+    foo.a = false;
+    foo.b = true;
+    foo.c = false;
+    foo.bar = bar;
+    foo.extra_bars = extra_bars;
+    foo.data = data;
+    foo.source = source;
+    return foo;
+  }
+
+  // Check that the given |Foo| is identical to the one made by |MakeFoo()|.
+  function checkFoo(foo) {
+    expect(foo.name).toBe("foopy");
+    expect(foo.x).toBe(1);
+    expect(foo.y).toBe(2);
+    expect(foo.a).toBeFalsy();
+    expect(foo.b).toBeTruthy();
+    expect(foo.c).toBeFalsy();
+    expect(foo.bar.alpha).toBe(20);
+    expect(foo.bar.beta).toBe(40);
+    expect(foo.bar.gamma).toBe(60);
+    expect(foo.bar.type).toBe(sample.Bar.Type.VERTICAL);
+
+    expect(foo.extra_bars.length).toBe(3);
+    for (var i = 0; i < foo.extra_bars.length; ++i) {
+      var base = i * 100;
+      var type = i % 2 ?
+          sample.Bar.Type.VERTICAL : sample.Bar.Type.HORIZONTAL;
+      expect(foo.extra_bars[i].alpha).toBe(base);
+      expect(foo.extra_bars[i].beta).toBe(base + 20);
+      expect(foo.extra_bars[i].gamma).toBe(base + 40);
+      expect(foo.extra_bars[i].type).toBe(type);
+    }
+
+    expect(foo.data.length).toBe(10);
+    for (var i = 0; i < foo.data.length; ++i)
+      expect(foo.data[i]).toBe(foo.data.length - i);
+
+    expect(foo.source).toBe(0xFFFF);
+  }
+
+  // Check that values are set to the defaults if we don't override them.
+  function checkDefaultValues() {
+    var bar = new sample.Bar();
+    expect(bar.alpha).toBe(255);
+    expect(bar.type).toBe(sample.Bar.Type.VERTICAL);
+
+    var foo = new sample.Foo();
+    expect(foo.name).toBe("Fooby");
+    expect(foo.a).toBeTruthy();
+    expect(foo.data).toBeNull();
+
+    var defaults = new sample.DefaultsTest();
+    expect(defaults.a0).toBe(-12);
+    expect(defaults.a1).toBe(sample.kTwelve);
+    expect(defaults.a2).toBe(1234);
+    expect(defaults.a3).toBe(34567);
+    expect(defaults.a4).toBe(123456);
+    expect(defaults.a5).toBe(3456789012);
+    expect(defaults.a6).toBe(-111111111111);
+    // JS doesn't have a 64 bit integer type so this is just checking that the
+    // expected and actual values have the same closest double value.
+    expect(defaults.a7).toBe(9999999999999999999);
+    expect(defaults.a8).toBe(0x12345);
+    expect(defaults.a9).toBe(-0x12345);
+    expect(defaults.a10).toBe(1234);
+    expect(defaults.a11).toBe(true);
+    expect(defaults.a12).toBe(false);
+    expect(defaults.a13).toBe(123.25);
+    expect(defaults.a14).toBe(1234567890.123);
+    expect(defaults.a15).toBe(1E10);
+    expect(defaults.a16).toBe(-1.2E+20);
+    expect(defaults.a17).toBe(1.23E-20);
+    expect(defaults.a20).toBe(sample.Bar.Type.BOTH);
+    expect(defaults.a21).toBeNull();
+    expect(defaults.a22).toBeTruthy();
+    expect(defaults.a22.shape).toBe(imported.Shape.RECTANGLE);
+    expect(defaults.a22.color).toBe(imported2.Color.BLACK);
+    expect(defaults.a21).toBeNull();
+    expect(defaults.a23).toBe(0xFFFFFFFFFFFFFFFF);
+    expect(defaults.a24).toBe(0x123456789);
+    expect(defaults.a25).toBe(-0x123456789);
+  }
+
+  function ServiceImpl() {
+  }
+
+  ServiceImpl.prototype = Object.create(sample.Service.stubClass.prototype);
+
+  ServiceImpl.prototype.frobinate = function(foo, baz, port) {
+    checkFoo(foo);
+    expect(baz).toBe(sample.Service.BazOptions.EXTRA);
+    expect(port).toBe(10);
+    global.result = "PASS";
+  };
+
+  function SimpleMessageReceiver() {
+  }
+
+  SimpleMessageReceiver.prototype.accept = function(message) {
+    if (dumpMessageAsHex) {
+      var uint8Array = new Uint8Array(message.buffer.arrayBuffer);
+      console.log(hexdump.dumpArray(uint8Array));
+    }
+    // Imagine some IPC happened here.
+    var serviceImpl = new ServiceImpl();
+    serviceImpl.accept(message);
+  };
+
+  var receiver = new SimpleMessageReceiver();
+  var serviceProxy = new sample.Service.proxyClass(receiver);
+
+  checkDefaultValues();
+
+  var foo = makeFoo();
+  checkFoo(foo);
+
+  var port = 10;
+  serviceProxy.frobinate(foo, sample.Service.BazOptions.EXTRA, port);
+});
diff --git a/mojo/edk/js/threading.cc b/mojo/edk/js/threading.cc
new file mode 100644
index 0000000..b571e3e
--- /dev/null
+++ b/mojo/edk/js/threading.cc
@@ -0,0 +1,47 @@
+// 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/edk/js/threading.h"
+
+#include "base/message_loop/message_loop.h"
+#include "gin/object_template_builder.h"
+#include "gin/per_isolate_data.h"
+#include "mojo/edk/js/handle.h"
+
+namespace mojo {
+namespace js {
+
+namespace {
+
+void Quit() {
+  base::MessageLoop::current()->QuitNow();
+}
+
+gin::WrapperInfo g_wrapper_info = { gin::kEmbedderNativeGin };
+
+}  // namespace
+
+const char Threading::kModuleName[] = "mojo/public/js/threading";
+
+v8::Local<v8::Value> Threading::GetModule(v8::Isolate* isolate) {
+  gin::PerIsolateData* data = gin::PerIsolateData::From(isolate);
+  v8::Local<v8::ObjectTemplate> templ = data->GetObjectTemplate(
+      &g_wrapper_info);
+
+  if (templ.IsEmpty()) {
+    templ = gin::ObjectTemplateBuilder(isolate)
+        .SetMethod("quit", Quit)
+        .Build();
+
+    data->SetObjectTemplate(&g_wrapper_info, templ);
+  }
+
+  return templ->NewInstance();
+}
+
+Threading::Threading() {
+}
+
+}  // namespace js
+}  // namespace mojo
diff --git a/mojo/edk/js/threading.h b/mojo/edk/js/threading.h
new file mode 100644
index 0000000..7cf0d53
--- /dev/null
+++ b/mojo/edk/js/threading.h
@@ -0,0 +1,25 @@
+// 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_EDK_JS_THREADING_H_
+#define MOJO_EDK_JS_THREADING_H_
+
+#include "gin/public/wrapper_info.h"
+#include "v8/include/v8.h"
+
+namespace mojo {
+namespace js {
+
+class Threading {
+ public:
+  static const char kModuleName[];
+  static v8::Local<v8::Value> GetModule(v8::Isolate* isolate);
+ private:
+  Threading();
+};
+
+}  // namespace js
+}  // namespace mojo
+
+#endif  // MOJO_EDK_JS_THREADING_H_
diff --git a/mojo/edk/js/waiting_callback.h b/mojo/edk/js/waiting_callback.h
index fdffde5..6b2ccc7 100644
--- a/mojo/edk/js/waiting_callback.h
+++ b/mojo/edk/js/waiting_callback.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_BINDINGS_JS_WAITING_CALLBACK_H_
-#define MOJO_BINDINGS_JS_WAITING_CALLBACK_H_
+#ifndef MOJO_EDK_JS_WAITING_CALLBACK_H_
+#define MOJO_EDK_JS_WAITING_CALLBACK_H_
 
 #include "gin/handle.h"
 #include "gin/runner.h"
@@ -60,4 +60,4 @@
 }  // namespace js
 }  // namespace mojo
 
-#endif  // MOJO_BINDINGS_JS_WAITING_CALLBACK_H_
+#endif  // MOJO_EDK_JS_WAITING_CALLBACK_H_
diff --git a/mojo/edk/mojo_edk.gyp b/mojo/edk/mojo_edk.gyp
index e826893..05bde04 100644
--- a/mojo/edk/mojo_edk.gyp
+++ b/mojo/edk/mojo_edk.gyp
@@ -2,196 +2,12 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
-# Essential components (and their tests) that are needed to build
-# Chrome should be here.  Other components that are useful only in
-# Mojo land like mojo_shell should be in mojo.gyp.
 {
   'includes': [
     '../mojo_variables.gypi',
   ],
   'targets': [
     {
-      'target_name': 'mojo_edk',
-      'type': 'none',
-      'dependencies': [
-        # NOTE: If adding a new dependency here, please consider whether it
-        # should also be added to the list of Mojo-related dependencies of
-        # build/all.gyp:All on iOS, as All cannot depend on the mojo_base
-        # target on iOS due to the presence of the js targets, which cause v8
-        # to be built.
-        'mojo_message_pipe_perftests',
-        'mojo_public_application_unittests',
-        'mojo_public_bindings_unittests',
-        'mojo_public_environment_unittests',
-        'mojo_public_system_perftests',
-        'mojo_public_system_unittests',
-        'mojo_public_utility_unittests',
-        'mojo_system_impl',
-        'mojo_system_unittests',
-        'mojo_js_unittests',
-      ],
-    },
-    {
-      'target_name': 'mojo_none',
-      'type': 'none',
-    },
-    {
-      # GN version: //mojo/edk/test:run_all_unittests
-      'target_name': 'mojo_run_all_unittests',
-      'type': 'static_library',
-      'dependencies': [
-        '../../base/base.gyp:base',
-        '../../base/base.gyp:test_support_base',
-        '../../testing/gtest.gyp:gtest',
-        'mojo_system_impl',
-        'mojo_test_support_impl',
-        '../public/mojo_public.gyp:mojo_test_support',
-      ],
-      'sources': [
-        'test/run_all_unittests.cc',
-      ],
-    },
-    {
-      # GN version: //mojo/edk/test:run_all_perftests
-      'target_name': 'mojo_run_all_perftests',
-      'type': 'static_library',
-      'dependencies': [
-        '../../base/base.gyp:test_support_base',
-        'mojo_system_impl',
-        'mojo_test_support_impl',
-        '../public/mojo_public.gyp:mojo_test_support',
-      ],
-      'sources': [
-        'test/run_all_perftests.cc',
-      ],
-    },
-    # TODO(vtl): Reorganize the mojo_public_*_unittests.
-    {
-      # GN version: //mojo/public/cpp/bindings/tests:mojo_public_bindings_unittests
-      'target_name': 'mojo_public_bindings_unittests',
-      'type': 'executable',
-      'dependencies': [
-        '../../testing/gtest.gyp:gtest',
-        'mojo_run_all_unittests',
-        '../public/mojo_public.gyp:mojo_cpp_bindings',
-        '../public/mojo_public.gyp:mojo_environment_standalone',
-        '../public/mojo_public.gyp:mojo_public_bindings_test_utils',
-        '../public/mojo_public.gyp:mojo_public_test_interfaces',
-        '../public/mojo_public.gyp:mojo_public_test_utils',
-        '../public/mojo_public.gyp:mojo_utility',
-      ],
-      'sources': [
-        '../public/cpp/bindings/tests/array_unittest.cc',
-        '../public/cpp/bindings/tests/bounds_checker_unittest.cc',
-        '../public/cpp/bindings/tests/buffer_unittest.cc',
-        '../public/cpp/bindings/tests/connector_unittest.cc',
-        '../public/cpp/bindings/tests/container_test_util.cc',
-        '../public/cpp/bindings/tests/equals_unittest.cc',
-        '../public/cpp/bindings/tests/handle_passing_unittest.cc',
-        '../public/cpp/bindings/tests/interface_ptr_unittest.cc',
-        '../public/cpp/bindings/tests/map_unittest.cc',
-        '../public/cpp/bindings/tests/request_response_unittest.cc',
-        '../public/cpp/bindings/tests/router_unittest.cc',
-        '../public/cpp/bindings/tests/sample_service_unittest.cc',
-        '../public/cpp/bindings/tests/serialization_warning_unittest.cc',
-        '../public/cpp/bindings/tests/string_unittest.cc',
-        '../public/cpp/bindings/tests/struct_unittest.cc',
-        '../public/cpp/bindings/tests/type_conversion_unittest.cc',
-        '../public/cpp/bindings/tests/validation_unittest.cc',
-      ],
-    },
-    {
-      # GN version: //mojo/public/cpp/environment/tests:mojo_public_environment_unittests
-      'target_name': 'mojo_public_environment_unittests',
-      'type': 'executable',
-      'dependencies': [
-        '../../testing/gtest.gyp:gtest',
-        'mojo_run_all_unittests',
-        '../public/mojo_public.gyp:mojo_environment_standalone',
-        '../public/mojo_public.gyp:mojo_public_test_utils',
-        '../public/mojo_public.gyp:mojo_utility',
-      ],
-      'include_dirs': [ '../..' ],
-      'sources': [
-        '../public/cpp/environment/tests/async_wait_unittest.cc',
-        '../public/cpp/environment/tests/async_waiter_unittest.cc',
-        '../public/cpp/environment/tests/logger_unittest.cc',
-        '../public/cpp/environment/tests/logging_unittest.cc',
-      ],
-    },
-    {
-      # GN version: //mojo/public/cpp/application/tests:mojo_public_application_unittests
-      'target_name': 'mojo_public_application_unittests',
-      'type': 'executable',
-      'dependencies': [
-        '../../base/base.gyp:base',
-        '../../testing/gtest.gyp:gtest',
-        'mojo_run_all_unittests',
-        '../public/mojo_public.gyp:mojo_application_standalone',
-        '../public/mojo_public.gyp:mojo_utility',
-        '../public/mojo_public.gyp:mojo_environment_standalone',
-      ],
-      'sources': [
-        '../public/cpp/application/tests/service_registry_unittest.cc',
-      ],
-    },
-    {
-      # GN version: //mojo/public/cpp/application/tests:mojo_public_system_unittests
-      'target_name': 'mojo_public_system_unittests',
-      'type': 'executable',
-      'dependencies': [
-        '../../testing/gtest.gyp:gtest',
-        'mojo_run_all_unittests',
-        '../public/mojo_public.gyp:mojo_public_test_utils',
-      ],
-      'include_dirs': [ '../..' ],
-      'sources': [
-        '<@(mojo_public_system_unittest_sources)',
-      ],
-    },
-    {
-      # GN version: //mojo/public/cpp/application/tests:mojo_public_utility_unittests
-      'target_name': 'mojo_public_utility_unittests',
-      'type': 'executable',
-      'dependencies': [
-        '../../testing/gtest.gyp:gtest',
-        'mojo_run_all_unittests',
-        '../public/mojo_public.gyp:mojo_public_test_utils',
-        '../public/mojo_public.gyp:mojo_utility',
-      ],
-      'include_dirs': [ '../..' ],
-      'sources': [
-        '../public/cpp/utility/tests/mutex_unittest.cc',
-        '../public/cpp/utility/tests/run_loop_unittest.cc',
-        '../public/cpp/utility/tests/thread_unittest.cc',
-      ],
-      'conditions': [
-        # See crbug.com/342893:
-        ['OS=="win"', {
-          'sources!': [
-            '../public/cpp/utility/tests/mutex_unittest.cc',
-            '../public/cpp/utility/tests/thread_unittest.cc',
-          ],
-        }],
-      ],
-    },
-    {
-      # GN version: //mojo/public/c/system/tests:perftests
-      'target_name': 'mojo_public_system_perftests',
-      'type': 'executable',
-      'dependencies': [
-        '../../base/base.gyp:base',
-        '../../testing/gtest.gyp:gtest',
-        'mojo_run_all_perftests',
-        '../public/mojo_public.gyp:mojo_public_test_utils',
-        '../public/mojo_public.gyp:mojo_utility',
-      ],
-      'sources': [
-        '../public/c/system/tests/core_perftest.cc',
-      ],
-    },
-
-    {
       # GN version: //mojo/edk/system
       'target_name': 'mojo_system_impl',
       'type': '<(component)',
@@ -205,11 +21,14 @@
         'MOJO_USE_SYSTEM_IMPL',
       ],
       'sources': [
+        'embedder/configuration.h',
         'embedder/channel_info_forward.h',
         'embedder/channel_init.cc',
         'embedder/channel_init.h',
         'embedder/embedder.cc',
         'embedder/embedder.h',
+        'embedder/embedder_internal.h',
+        'embedder/entrypoints.cc',
         'embedder/platform_channel_pair.cc',
         'embedder/platform_channel_pair.h',
         'embedder/platform_channel_pair_posix.cc',
@@ -239,7 +58,10 @@
         'system/channel_endpoint_id.h',
         'system/channel_info.cc',
         'system/channel_info.h',
-        'system/constants.h',
+        'system/channel_manager.cc',
+        'system/channel_manager.h',
+        'system/configuration.cc',
+        'system/configuration.h',
         'system/core.cc',
         'system/core.h',
         'system/data_pipe.cc',
@@ -250,7 +72,6 @@
         'system/data_pipe_producer_dispatcher.h',
         'system/dispatcher.cc',
         'system/dispatcher.h',
-        'system/entrypoints.cc',
         'system/handle_signals_state.h',
         'system/handle_table.cc',
         'system/handle_table.h',
@@ -304,77 +125,6 @@
       }
     },
     {
-      # GN version: //mojo/edk/system:mojo_system_unittests
-      'target_name': 'mojo_system_unittests',
-      'type': 'executable',
-      'dependencies': [
-        '../../base/base.gyp:base',
-        '../../testing/gtest.gyp:gtest',
-        'mojo_common_test_support',
-        'mojo_system_impl',
-      ],
-      'sources': [
-        'embedder/embedder_unittest.cc',
-        'embedder/platform_channel_pair_posix_unittest.cc',
-        'embedder/simple_platform_shared_buffer_unittest.cc',
-        'system/channel_endpoint_id_unittest.cc',
-        'system/channel_unittest.cc',
-        'system/core_unittest.cc',
-        'system/core_test_base.cc',
-        'system/core_test_base.h',
-        'system/data_pipe_unittest.cc',
-        'system/dispatcher_unittest.cc',
-        'system/local_data_pipe_unittest.cc',
-        'system/memory_unittest.cc',
-        'system/message_pipe_dispatcher_unittest.cc',
-        'system/message_pipe_test_utils.h',
-        'system/message_pipe_test_utils.cc',
-        'system/message_pipe_unittest.cc',
-        'system/multiprocess_message_pipe_unittest.cc',
-        'system/options_validation_unittest.cc',
-        'system/platform_handle_dispatcher_unittest.cc',
-        'system/raw_channel_unittest.cc',
-        'system/remote_message_pipe_unittest.cc',
-        'system/run_all_unittests.cc',
-        'system/shared_buffer_dispatcher_unittest.cc',
-        'system/simple_dispatcher_unittest.cc',
-        'system/test_utils.cc',
-        'system/test_utils.h',
-        'system/waiter_list_unittest.cc',
-        'system/waiter_test_utils.cc',
-        'system/waiter_test_utils.h',
-        'system/waiter_unittest.cc',
-      ],
-      'conditions': [
-        ['OS=="ios"', {
-          'sources!': [
-            'embedder/embedder_unittest.cc',
-            'system/multiprocess_message_pipe_unittest.cc',
-          ],
-        }],
-      ],
-    },
-    {
-      # GN version: //mojo/edk/system:mojo_message_pipe_perftests
-      'target_name': 'mojo_message_pipe_perftests',
-      'type': 'executable',
-      'dependencies': [
-        '../../base/base.gyp:base',
-        '../../base/base.gyp:test_support_base',
-        '../../base/base.gyp:test_support_perf',
-        '../../testing/gtest.gyp:gtest',
-        'mojo_common_test_support',
-        'mojo_system_impl',
-      ],
-      'sources': [
-        'system/message_pipe_perftest.cc',
-        'system/message_pipe_test_utils.h',
-        'system/message_pipe_test_utils.cc',
-        'system/test_utils.cc',
-        'system/test_utils.h',
-      ],
-    },
-    {
       # GN version: //mojo/edk/js
       'target_name': 'mojo_js_lib',
       'type': 'static_library',
@@ -396,32 +146,18 @@
         'js/handle.cc',
         'js/handle.h',
         'js/handle_close_observer.h',
+        'js/mojo_runner_delegate.cc',
+        'js/mojo_runner_delegate.h',
         'js/support.cc',
         'js/support.h',
+        'js/threading.cc',
+        'js/threading.h',
         'js/waiting_callback.cc',
         'js/waiting_callback.h',
       ],
     },
     {
-      # GN version: //mojo/edk/js:js_unittests
-      'target_name': 'mojo_js_unittests',
-      'type': 'executable',
-      'dependencies': [
-        '../../gin/gin.gyp:gin_test',
-        'mojo_common_test_support',
-        'mojo_run_all_unittests',
-        'mojo_js_lib',
-        '../public/mojo_public.gyp:mojo_environment_standalone',
-        '../public/mojo_public.gyp:mojo_public_test_interfaces',
-        '../public/mojo_public.gyp:mojo_utility',
-      ],
-      'sources': [
-        'js/handle_unittest.cc',
-        'js/tests/run_js_tests.cc',
-      ],
-    },
-    {
-      # GN version: //mojo/common/test:test_support_impl
+      # GN version: //mojo/edk/test:test_support_impl
       'target_name': 'mojo_test_support_impl',
       'type': 'static_library',
       'dependencies': [
@@ -457,5 +193,35 @@
         }],
       ],
     },
+    {
+      # GN version: //mojo/edk/test:run_all_unittests
+      'target_name': 'mojo_run_all_unittests',
+      'type': 'static_library',
+      'dependencies': [
+        '../../base/base.gyp:base',
+        '../../base/base.gyp:test_support_base',
+        '../../testing/gtest.gyp:gtest',
+        'mojo_system_impl',
+        'mojo_test_support_impl',
+        '../public/mojo_public.gyp:mojo_test_support',
+      ],
+      'sources': [
+        'test/run_all_unittests.cc',
+      ],
+    },
+    {
+      # GN version: //mojo/edk/test:run_all_perftests
+      'target_name': 'mojo_run_all_perftests',
+      'type': 'static_library',
+      'dependencies': [
+        '../../base/base.gyp:test_support_base',
+        'mojo_edk.gyp:mojo_system_impl',
+        'mojo_test_support_impl',
+        '../public/mojo_public.gyp:mojo_test_support',
+      ],
+      'sources': [
+        'test/run_all_perftests.cc',
+      ],
+    },
   ],
 }
diff --git a/mojo/edk/mojo_edk_tests.gyp b/mojo/edk/mojo_edk_tests.gyp
new file mode 100644
index 0000000..943cad3
--- /dev/null
+++ b/mojo/edk/mojo_edk_tests.gyp
@@ -0,0 +1,278 @@
+# 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': [
+    '../mojo_variables.gypi',
+  ],
+  'targets': [
+    {
+      'target_name': 'mojo_edk_tests',
+      'type': 'none',
+      'dependencies': [
+        # NOTE: If adding a new dependency here, please consider whether it
+        # should also be added to the list of Mojo-related dependencies of
+        # build/all.gyp:All on iOS, as All cannot depend on the mojo_base
+        # target on iOS due to the presence of the js targets, which cause v8
+        # to be built.
+        'mojo_message_pipe_perftests',
+        'mojo_public_application_unittests',
+        'mojo_public_bindings_unittests',
+        'mojo_public_environment_unittests',
+        'mojo_public_system_perftests',
+        'mojo_public_system_unittests',
+        'mojo_public_utility_unittests',
+        'mojo_system_unittests',
+        'mojo_js_unittests',
+        'mojo_js_integration_tests',
+      ],
+    },
+    # TODO(vtl): Reorganize the mojo_public_*_unittests.
+    {
+      # GN version: //mojo/public/cpp/bindings/tests:mojo_public_bindings_unittests
+      'target_name': 'mojo_public_bindings_unittests',
+      'type': 'executable',
+      'dependencies': [
+        '../../testing/gtest.gyp:gtest',
+        'mojo_edk.gyp:mojo_run_all_unittests',
+        '../public/mojo_public.gyp:mojo_cpp_bindings',
+        '../public/mojo_public.gyp:mojo_environment_standalone',
+        '../public/mojo_public.gyp:mojo_public_bindings_test_utils',
+        '../public/mojo_public.gyp:mojo_public_test_interfaces',
+        '../public/mojo_public.gyp:mojo_public_test_utils',
+        '../public/mojo_public.gyp:mojo_utility',
+      ],
+      'sources': [
+        '../public/cpp/bindings/tests/array_unittest.cc',
+        '../public/cpp/bindings/tests/bounds_checker_unittest.cc',
+        '../public/cpp/bindings/tests/buffer_unittest.cc',
+        '../public/cpp/bindings/tests/connector_unittest.cc',
+        '../public/cpp/bindings/tests/container_test_util.cc',
+        '../public/cpp/bindings/tests/equals_unittest.cc',
+        '../public/cpp/bindings/tests/handle_passing_unittest.cc',
+        '../public/cpp/bindings/tests/interface_ptr_unittest.cc',
+        '../public/cpp/bindings/tests/map_unittest.cc',
+        '../public/cpp/bindings/tests/request_response_unittest.cc',
+        '../public/cpp/bindings/tests/router_unittest.cc',
+        '../public/cpp/bindings/tests/sample_service_unittest.cc',
+        '../public/cpp/bindings/tests/serialization_warning_unittest.cc',
+        '../public/cpp/bindings/tests/string_unittest.cc',
+        '../public/cpp/bindings/tests/struct_unittest.cc',
+        '../public/cpp/bindings/tests/type_conversion_unittest.cc',
+        '../public/cpp/bindings/tests/validation_unittest.cc',
+      ],
+    },
+    {
+      # GN version: //mojo/public/cpp/environment/tests:mojo_public_environment_unittests
+      'target_name': 'mojo_public_environment_unittests',
+      'type': 'executable',
+      'dependencies': [
+        '../../testing/gtest.gyp:gtest',
+        'mojo_edk.gyp:mojo_run_all_unittests',
+        '../public/mojo_public.gyp:mojo_environment_standalone',
+        '../public/mojo_public.gyp:mojo_public_test_utils',
+        '../public/mojo_public.gyp:mojo_utility',
+      ],
+      'include_dirs': [ '../..' ],
+      'sources': [
+        '../public/cpp/environment/tests/async_wait_unittest.cc',
+        '../public/cpp/environment/tests/async_waiter_unittest.cc',
+        '../public/cpp/environment/tests/logger_unittest.cc',
+        '../public/cpp/environment/tests/logging_unittest.cc',
+      ],
+    },
+    {
+      # GN version: //mojo/public/cpp/application/tests:mojo_public_application_unittests
+      'target_name': 'mojo_public_application_unittests',
+      'type': 'executable',
+      'dependencies': [
+        '../../base/base.gyp:base',
+        '../../testing/gtest.gyp:gtest',
+        'mojo_edk.gyp:mojo_run_all_unittests',
+        '../public/mojo_public.gyp:mojo_application_standalone',
+        '../public/mojo_public.gyp:mojo_utility',
+        '../public/mojo_public.gyp:mojo_environment_standalone',
+      ],
+      'sources': [
+        '../public/cpp/application/tests/service_registry_unittest.cc',
+      ],
+    },
+    {
+      # GN version: //mojo/public/cpp/system/tests:mojo_public_system_unittests
+      # and         //mojo/public/c/system/tests
+      'target_name': 'mojo_public_system_unittests',
+      'type': 'executable',
+      'dependencies': [
+        '../../testing/gtest.gyp:gtest',
+        'mojo_edk.gyp:mojo_run_all_unittests',
+        '../public/mojo_public.gyp:mojo_public_test_utils',
+      ],
+      'include_dirs': [ '../..' ],
+      'sources': [
+        '<@(mojo_public_system_unittest_sources)',
+      ],
+    },
+    {
+      # GN version: //mojo/public/cpp/application/tests:mojo_public_utility_unittests
+      'target_name': 'mojo_public_utility_unittests',
+      'type': 'executable',
+      'dependencies': [
+        '../../testing/gtest.gyp:gtest',
+        'mojo_edk.gyp:mojo_run_all_unittests',
+        '../public/mojo_public.gyp:mojo_public_test_utils',
+        '../public/mojo_public.gyp:mojo_utility',
+      ],
+      'include_dirs': [ '../..' ],
+      'sources': [
+        '../public/cpp/utility/tests/mutex_unittest.cc',
+        '../public/cpp/utility/tests/run_loop_unittest.cc',
+        '../public/cpp/utility/tests/thread_unittest.cc',
+      ],
+      'conditions': [
+        # See crbug.com/342893:
+        ['OS=="win"', {
+          'sources!': [
+            '../public/cpp/utility/tests/mutex_unittest.cc',
+            '../public/cpp/utility/tests/thread_unittest.cc',
+          ],
+        }],
+      ],
+    },
+    {
+      # GN version: //mojo/public/c/system/tests:perftests
+      'target_name': 'mojo_public_system_perftests',
+      'type': 'executable',
+      'dependencies': [
+        '../../base/base.gyp:base',
+        '../../testing/gtest.gyp:gtest',
+        'mojo_edk.gyp:mojo_run_all_perftests',
+        '../public/mojo_public.gyp:mojo_public_test_utils',
+        '../public/mojo_public.gyp:mojo_utility',
+      ],
+      'sources': [
+        '../public/c/system/tests/core_perftest.cc',
+      ],
+    },
+    {
+      # GN version: //mojo/edk/system:mojo_system_unittests
+      'target_name': 'mojo_system_unittests',
+      'type': 'executable',
+      'dependencies': [
+        '../../base/base.gyp:base',
+        '../../testing/gtest.gyp:gtest',
+        'mojo_edk.gyp:mojo_common_test_support',
+        'mojo_edk.gyp:mojo_system_impl',
+      ],
+      'sources': [
+        'embedder/embedder_unittest.cc',
+        'embedder/platform_channel_pair_posix_unittest.cc',
+        'embedder/simple_platform_shared_buffer_unittest.cc',
+        'system/channel_endpoint_id_unittest.cc',
+        'system/channel_unittest.cc',
+        'system/core_unittest.cc',
+        'system/core_test_base.cc',
+        'system/core_test_base.h',
+        'system/data_pipe_unittest.cc',
+        'system/dispatcher_unittest.cc',
+        'system/local_data_pipe_unittest.cc',
+        'system/memory_unittest.cc',
+        'system/message_pipe_dispatcher_unittest.cc',
+        'system/message_pipe_test_utils.h',
+        'system/message_pipe_test_utils.cc',
+        'system/message_pipe_unittest.cc',
+        'system/multiprocess_message_pipe_unittest.cc',
+        'system/options_validation_unittest.cc',
+        'system/platform_handle_dispatcher_unittest.cc',
+        'system/raw_channel_unittest.cc',
+        'system/remote_message_pipe_unittest.cc',
+        'system/run_all_unittests.cc',
+        'system/shared_buffer_dispatcher_unittest.cc',
+        'system/simple_dispatcher_unittest.cc',
+        'system/test_utils.cc',
+        'system/test_utils.h',
+        'system/waiter_list_unittest.cc',
+        'system/waiter_test_utils.cc',
+        'system/waiter_test_utils.h',
+        'system/waiter_unittest.cc',
+        'test/multiprocess_test_helper_unittest.cc',
+      ],
+      'conditions': [
+        ['OS=="ios"', {
+          'sources!': [
+            'embedder/embedder_unittest.cc',
+            'system/multiprocess_message_pipe_unittest.cc',
+            'test/multiprocess_test_helper_unittest.cc',
+          ],
+        }],
+      ],
+    },
+    {
+      # GN version: //mojo/edk/system:mojo_message_pipe_perftests
+      'target_name': 'mojo_message_pipe_perftests',
+      'type': 'executable',
+      'dependencies': [
+        '../../base/base.gyp:base',
+        '../../base/base.gyp:test_support_base',
+        '../../base/base.gyp:test_support_perf',
+        '../../testing/gtest.gyp:gtest',
+        'mojo_edk.gyp:mojo_common_test_support',
+        'mojo_edk.gyp:mojo_system_impl',
+      ],
+      'sources': [
+        'system/message_pipe_perftest.cc',
+        'system/message_pipe_test_utils.h',
+        'system/message_pipe_test_utils.cc',
+        'system/test_utils.cc',
+        'system/test_utils.h',
+      ],
+    },
+    {
+      # GN version: //mojo/edk/js/test:js_unittests
+      'target_name': 'mojo_js_unittests',
+      'type': 'executable',
+      'dependencies': [
+        '../../gin/gin.gyp:gin_test',
+        'mojo_edk.gyp:mojo_common_test_support',
+        'mojo_edk.gyp:mojo_run_all_unittests',
+        'mojo_edk.gyp:mojo_js_lib',
+        '../public/mojo_public.gyp:mojo_environment_standalone',
+        '../public/mojo_public.gyp:mojo_public_test_interfaces',
+        '../public/mojo_public.gyp:mojo_utility',
+      ],
+      'sources': [
+        'js/handle_unittest.cc',
+        'js/test/run_js_tests.cc',
+      ],
+    },
+    {
+      # GN version: //mojo/edk/js/test:js_integration_tests
+      'target_name': 'mojo_js_integration_tests',
+      'type': 'executable',
+      'dependencies': [
+        '../../base/base.gyp:base',
+        '../../gin/gin.gyp:gin_test',
+        '../public/mojo_public.gyp:mojo_environment_standalone',
+        '../public/mojo_public.gyp:mojo_public_test_interfaces',
+        '../public/mojo_public.gyp:mojo_utility',
+        'mojo_edk.gyp:mojo_js_lib',
+        'mojo_edk.gyp:mojo_run_all_unittests',
+        'mojo_js_to_cpp_bindings',
+      ],
+      'sources': [
+        'js/test/run_js_integration_tests.cc',
+        'js/tests/js_to_cpp_tests',
+      ],
+    },
+    {
+      'target_name': 'mojo_js_to_cpp_bindings',
+      'type': 'none',
+      'variables': {
+        'mojom_files': [
+          'js/tests/js_to_cpp.mojom',
+        ],
+      },
+      'includes': [ '../public/tools/bindings/mojom_bindings_generator_explicit.gypi' ],
+    },
+  ],
+}
diff --git a/mojo/edk/system/channel.cc b/mojo/edk/system/channel.cc
index b63aaeb..2f2a2ab 100644
--- a/mojo/edk/system/channel.cc
+++ b/mojo/edk/system/channel.cc
@@ -20,7 +20,8 @@
 Channel::Channel(embedder::PlatformSupport* platform_support)
     : platform_support_(platform_support),
       is_running_(false),
-      is_shutting_down_(false) {
+      is_shutting_down_(false),
+      channel_manager_(nullptr) {
 }
 
 bool Channel::Init(scoped_ptr<RawChannel> raw_channel) {
@@ -41,6 +42,15 @@
   return true;
 }
 
+void Channel::SetChannelManager(ChannelManager* channel_manager) {
+  DCHECK(channel_manager);
+
+  base::AutoLock locker(lock_);
+  DCHECK(!is_shutting_down_);
+  DCHECK(!channel_manager_);
+  channel_manager_ = channel_manager;
+}
+
 void Channel::Shutdown() {
   DCHECK(creation_thread_checker_.CalledOnValidThread());
 
@@ -62,8 +72,7 @@
   size_t num_live = 0;
   size_t num_zombies = 0;
   for (IdToEndpointMap::iterator it = to_destroy.begin();
-       it != to_destroy.end();
-       ++it) {
+       it != to_destroy.end(); ++it) {
     if (it->second.get()) {
       num_live++;
       it->second->OnDisconnect();
@@ -80,6 +89,7 @@
 void Channel::WillShutdownSoon() {
   base::AutoLock locker(lock_);
   is_shutting_down_ = true;
+  channel_manager_ = nullptr;
 }
 
 // Note: |endpoint| being a |scoped_refptr| makes this function safe, since it
@@ -120,8 +130,7 @@
 
   if (!is_bootstrap) {
     if (!SendControlMessage(
-            MessageInTransit::kSubtypeChannelAttachAndRunEndpoint,
-            local_id,
+            MessageInTransit::kSubtypeChannelAttachAndRunEndpoint, local_id,
             remote_id)) {
       HandleLocalError(base::StringPrintf(
           "Failed to send message to run remote message pipe endpoint (local "
@@ -185,8 +194,7 @@
   }
 
   if (!SendControlMessage(
-          MessageInTransit::kSubtypeChannelRemoveMessagePipeEndpoint,
-          local_id,
+          MessageInTransit::kSubtypeChannelRemoveMessagePipeEndpoint, local_id,
           remote_id)) {
     HandleLocalError(base::StringPrintf(
         "Failed to send message to remove remote message pipe endpoint (local "
@@ -207,7 +215,7 @@
 
   auto it = incoming_message_pipes_.find(local_id);
   if (it == incoming_message_pipes_.end())
-    return scoped_refptr<MessagePipe>();
+    return nullptr;
 
   scoped_refptr<MessagePipe> rv;
   rv.swap(it->second);
@@ -459,8 +467,7 @@
 
   if (!SendControlMessage(
           MessageInTransit::kSubtypeChannelRemoveMessagePipeEndpointAck,
-          local_id,
-          remote_id)) {
+          local_id, remote_id)) {
     HandleLocalError(base::StringPrintf(
         "Failed to send message to remove remote message pipe endpoint ack "
         "(local ID %u, remote ID %u)",
diff --git a/mojo/edk/system/channel.h b/mojo/edk/system/channel.h
index 6697965..715d1f2 100644
--- a/mojo/edk/system/channel.h
+++ b/mojo/edk/system/channel.h
@@ -32,6 +32,7 @@
 namespace system {
 
 class ChannelEndpoint;
+class ChannelManager;
 
 // This class is mostly thread-safe. It must be created on an I/O thread.
 // |Init()| must be called on that same thread before it becomes thread-safe (in
@@ -61,6 +62,11 @@
   // failure, no other methods should be called (including |Shutdown()|).
   bool Init(scoped_ptr<RawChannel> raw_channel);
 
+  // Sets the channel manager associated with this channel. This should be set
+  // at most once and only called before |WillShutdownSoon()| (and
+  // |Shutdown()|).
+  void SetChannelManager(ChannelManager* channel_manager);
+
   // This must be called on the creation thread before destruction (which can
   // happen on any thread).
   void Shutdown();
@@ -69,6 +75,8 @@
   // thread, unlike |Shutdown()|). Warnings will be issued if, e.g., messages
   // are written after this is called; other warnings may be suppressed. (This
   // may be called multiple times, or not at all.)
+  //
+  // If set, the channel manager associated with this channel will be reset.
   void WillShutdownSoon();
 
   // Attaches the given endpoint to this channel and runs it. |is_bootstrap|
@@ -175,6 +183,9 @@
   // Set when |WillShutdownSoon()| is called.
   bool is_shutting_down_;
 
+  // Has a reference to us.
+  ChannelManager* channel_manager_;
+
   typedef base::hash_map<ChannelEndpointId, scoped_refptr<ChannelEndpoint>>
       IdToEndpointMap;
   // Map from local IDs to endpoints. If the endpoint is null, this means that
diff --git a/mojo/edk/system/channel_endpoint.cc b/mojo/edk/system/channel_endpoint.cc
index 8b64643..dd7cd5b 100644
--- a/mojo/edk/system/channel_endpoint.cc
+++ b/mojo/edk/system/channel_endpoint.cc
@@ -109,8 +109,7 @@
       DCHECK(message_view.transport_data_buffer());
       message->SetDispatchers(TransportData::DeserializeDispatchers(
           message_view.transport_data_buffer(),
-          message_view.transport_data_buffer_size(),
-          platform_handles.Pass(),
+          message_view.transport_data_buffer_size(), platform_handles.Pass(),
           channel_));
     }
 
diff --git a/mojo/edk/system/channel_endpoint.h b/mojo/edk/system/channel_endpoint.h
index 377599d..3c415ea 100644
--- a/mojo/edk/system/channel_endpoint.h
+++ b/mojo/edk/system/channel_endpoint.h
@@ -26,13 +26,13 @@
 //     refcounted, and not copyable. Make |Channel| a friend. Make things work.
 //   - (Done.) Give |ChannelEndpoint| a lock. The lock order (in order of
 //     allowable acquisition) is: |MessagePipe|, |ChannelEndpoint|, |Channel|.
-//   - Stop having |Channel| as a friend.
-//   - Move logic from |ProxyMessagePipeEndpoint| into |ChannelEndpoint|. Right
-//     now, we have to go through lots of contortions to manipulate state owned
-//     by |ProxyMessagePipeEndpoint| (in particular, |Channel::Endpoint| doesn't
-//     know about the remote ID; the local ID is duplicated in two places).
-//     Hollow out |ProxyMessagePipeEndpoint|, and have it just own a reference
-//     to |ChannelEndpoint| (hence the refcounting).
+//   - (Done) Stop having |Channel| as a friend.
+//   - (Done) Move logic from |ProxyMessagePipeEndpoint| into |ChannelEndpoint|.
+//     Right now, we have to go through lots of contortions to manipulate state
+//     owned by |ProxyMessagePipeEndpoint| (in particular, |Channel::Endpoint|
+//     doesn't know about the remote ID; the local ID is duplicated in two
+//     places). Hollow out |ProxyMessagePipeEndpoint|, and have it just own a
+//     reference to |ChannelEndpoint| (hence the refcounting).
 //   - In essence, |ChannelEndpoint| becomes the thing that knows about
 //     channel-specific aspects of an endpoint (notably local and remote IDs,
 //     and knowledge about handshaking), and mediates between the |Channel| and
diff --git a/mojo/edk/system/channel_info.cc b/mojo/edk/system/channel_info.cc
index efc5f04..6d23215 100644
--- a/mojo/edk/system/channel_info.cc
+++ b/mojo/edk/system/channel_info.cc
@@ -4,6 +4,8 @@
 
 #include "mojo/edk/system/channel_info.h"
 
+#include <algorithm>
+
 namespace mojo {
 namespace system {
 
@@ -19,5 +21,11 @@
 ChannelInfo::~ChannelInfo() {
 }
 
+void ChannelInfo::Swap(ChannelInfo* other) {
+  // Note: Swapping avoids refcount churn.
+  std::swap(channel, other->channel);
+  std::swap(channel_thread_task_runner, other->channel_thread_task_runner);
+}
+
 }  // namespace system
 }  // namespace mojo
diff --git a/mojo/edk/system/channel_info.h b/mojo/edk/system/channel_info.h
index bd84e16..5167cca 100644
--- a/mojo/edk/system/channel_info.h
+++ b/mojo/edk/system/channel_info.h
@@ -19,6 +19,8 @@
               scoped_refptr<base::TaskRunner> channel_thread_task_runner);
   ~ChannelInfo();
 
+  void Swap(ChannelInfo* other);
+
   scoped_refptr<Channel> channel;
   // The task runner for |channel|'s creation thread (a.k.a. its I/O thread), on
   // which it must, e.g., be shut down.
diff --git a/mojo/edk/system/channel_manager.cc b/mojo/edk/system/channel_manager.cc
new file mode 100644
index 0000000..4e58f89
--- /dev/null
+++ b/mojo/edk/system/channel_manager.cc
@@ -0,0 +1,78 @@
+// 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/edk/system/channel_manager.h"
+
+#include "base/bind.h"
+#include "base/location.h"
+#include "base/message_loop/message_loop_proxy.h"
+
+namespace mojo {
+namespace system {
+
+namespace {
+
+void ShutdownChannelHelper(const ChannelInfo& channel_info) {
+  if (base::MessageLoopProxy::current() ==
+      channel_info.channel_thread_task_runner) {
+    channel_info.channel->Shutdown();
+  } else {
+    channel_info.channel->WillShutdownSoon();
+    channel_info.channel_thread_task_runner->PostTask(
+        FROM_HERE, base::Bind(&Channel::Shutdown, channel_info.channel));
+  }
+}
+
+}  // namespace
+
+ChannelManager::ChannelManager() {
+}
+
+ChannelManager::~ChannelManager() {
+  // No need to take the lock.
+  for (const auto& map_elem : channel_infos_)
+    ShutdownChannelHelper(map_elem.second);
+}
+
+ChannelId ChannelManager::AddChannel(
+    scoped_refptr<Channel> channel,
+    scoped_refptr<base::TaskRunner> channel_thread_task_runner) {
+  ChannelId channel_id = GetChannelId(channel.get());
+
+  {
+    base::AutoLock locker(lock_);
+    DCHECK(channel_infos_.find(channel_id) == channel_infos_.end());
+    channel_infos_[channel_id] =
+        ChannelInfo(channel, channel_thread_task_runner);
+  }
+  channel->SetChannelManager(this);
+
+  return channel_id;
+}
+
+void ChannelManager::WillShutdownChannel(ChannelId channel_id) {
+  GetChannelInfo(channel_id).channel->WillShutdownSoon();
+}
+
+void ChannelManager::ShutdownChannel(ChannelId channel_id) {
+  ChannelInfo channel_info;
+  {
+    base::AutoLock locker(lock_);
+    auto it = channel_infos_.find(channel_id);
+    DCHECK(it != channel_infos_.end());
+    channel_info.Swap(&it->second);
+    channel_infos_.erase(it);
+  }
+  ShutdownChannelHelper(channel_info);
+}
+
+ChannelInfo ChannelManager::GetChannelInfo(ChannelId channel_id) {
+  base::AutoLock locker(lock_);
+  auto it = channel_infos_.find(channel_id);
+  DCHECK(it != channel_infos_.end());
+  return it->second;
+}
+
+}  // namespace system
+}  // namespace mojo
diff --git a/mojo/edk/system/channel_manager.h b/mojo/edk/system/channel_manager.h
new file mode 100644
index 0000000..60a3048
--- /dev/null
+++ b/mojo/edk/system/channel_manager.h
@@ -0,0 +1,83 @@
+// 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_EDK_SYSTEM_CHANNEL_MANAGER_H_
+#define MOJO_EDK_SYSTEM_CHANNEL_MANAGER_H_
+
+#include <stdint.h>
+
+#include "base/containers/hash_tables.h"
+#include "base/macros.h"
+#include "base/memory/ref_counted.h"
+#include "base/synchronization/lock.h"
+#include "base/task_runner.h"
+#include "mojo/edk/system/channel.h"
+#include "mojo/edk/system/channel_info.h"
+
+namespace mojo {
+namespace system {
+
+// IDs for |Channel|s managed by a |ChannelManager|. (IDs should be thought of
+// as specific to a given |ChannelManager|.) 0 is never a valid ID.
+//
+// Note: We currently just use the pointer of the |Channel| casted to a
+// |uintptr_t|, but we reserve the right to change this.
+typedef uintptr_t ChannelId;
+
+// This class manages and "owns" |Channel|s (which typically connect to other
+// processes) for a given process. This class is thread-safe.
+class MOJO_SYSTEM_IMPL_EXPORT ChannelManager {
+ public:
+  ChannelManager();
+  ~ChannelManager();
+
+  // Gets the ID for a given channel.
+  //
+  // Note: This is currently a static method and thus may be called under
+  // |lock_|. If this is ever made non-static (i.e., made specific to a given
+  // |ChannelManager|), those call sites may have to changed.
+  static ChannelId GetChannelId(const Channel* channel) {
+    return reinterpret_cast<ChannelId>(channel);
+  }
+
+  // Adds |channel| to the set of |Channel|s managed by this |ChannelManager|;
+  // |channel_thread_task_runner| should be the task runner for |channel|'s
+  // creation (a.k.a. I/O) thread. |channel| should either already be
+  // initialized. It should not be managed by any |ChannelManager| yet. Returns
+  // the ID for the added channel.
+  ChannelId AddChannel(
+      scoped_refptr<Channel> channel,
+      scoped_refptr<base::TaskRunner> channel_thread_task_runner);
+
+  // Informs the channel manager (and thus channel) that it will be shutdown
+  // soon (by calling |ShutdownChannel()|). Calling this is optional (and may in
+  // fact be called multiple times) but it will suppress certain warnings (e.g.,
+  // for the channel being broken) and enable others (if messages are written to
+  // the channel).
+  void WillShutdownChannel(ChannelId channel_id);
+
+  // Shuts down the channel specified by the given ID. It is up to the caller to
+  // guarantee that this is only called once per channel (that was added using
+  // |AddChannel()|). If called from the chanel's creation thread (i.e.,
+  // |base::MessageLoopProxy::current()| is the channel thread's |TaskRunner|),
+  // this will complete synchronously.
+  void ShutdownChannel(ChannelId channel_id);
+
+ private:
+  // Gets the |ChannelInfo| for the channel specified by the given ID. (This
+  // should *not* be called under lock.)
+  ChannelInfo GetChannelInfo(ChannelId channel_id);
+
+  // Note: |Channel| methods should not be called under |lock_|.
+  base::Lock lock_;  // Protects the members below.
+
+  base::hash_map<ChannelId, ChannelInfo> channel_infos_;
+
+  DISALLOW_COPY_AND_ASSIGN(ChannelManager);
+};
+
+}  // namespace system
+}  // namespace mojo
+
+#endif  // MOJO_EDK_SYSTEM_CHANNEL_MANAGER_H_
diff --git a/mojo/edk/system/channel_unittest.cc b/mojo/edk/system/channel_unittest.cc
index f6cf896..68b1315 100644
--- a/mojo/edk/system/channel_unittest.cc
+++ b/mojo/edk/system/channel_unittest.cc
@@ -104,9 +104,8 @@
   EXPECT_EQ(TRISTATE_TRUE, init_result());
 
   io_thread()->PostTaskAndWait(
-      FROM_HERE,
-      base::Bind(&ChannelTest::ShutdownChannelOnIOThread,
-                 base::Unretained(this)));
+      FROM_HERE, base::Bind(&ChannelTest::ShutdownChannelOnIOThread,
+                            base::Unretained(this)));
 
   // Okay to destroy |Channel| on not-the-I/O-thread.
   EXPECT_TRUE(channel()->HasOneRef());
@@ -203,9 +202,8 @@
   channel()->AttachAndRunEndpoint(channel_endpoint, true);
 
   io_thread()->PostTaskAndWait(
-      FROM_HERE,
-      base::Bind(&ChannelTest::ShutdownChannelOnIOThread,
-                 base::Unretained(this)));
+      FROM_HERE, base::Bind(&ChannelTest::ShutdownChannelOnIOThread,
+                            base::Unretained(this)));
 
   EXPECT_TRUE(channel()->HasOneRef());
 }
@@ -273,9 +271,8 @@
   channel()->AttachAndRunEndpoint(channel_endpoint, true);
 
   io_thread()->PostTaskAndWait(
-      FROM_HERE,
-      base::Bind(&ChannelTest::ShutdownChannelOnIOThread,
-                 base::Unretained(this)));
+      FROM_HERE, base::Bind(&ChannelTest::ShutdownChannelOnIOThread,
+                            base::Unretained(this)));
 
   Waiter waiter;
   waiter.Init();
diff --git a/mojo/edk/system/configuration.cc b/mojo/edk/system/configuration.cc
new file mode 100644
index 0000000..4756c99
--- /dev/null
+++ b/mojo/edk/system/configuration.cc
@@ -0,0 +1,26 @@
+// 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/edk/system/configuration.h"
+
+namespace mojo {
+namespace system {
+namespace internal {
+
+// These default values should be synced with the documentation in
+// mojo/edk/embedder/configuration.h.
+embedder::Configuration g_configuration = {
+    1000000,              // max_handle_table_size
+    1000000,              // max_mapping_table_sze
+    1000000,              // max_wait_many_num_handles
+    4 * 1024 * 1024,      // max_message_num_bytes
+    10000,                // max_message_num_handles
+    256 * 1024 * 1024,    // max_data_pipe_capacity_bytes
+    1024 * 1024,          // default_data_pipe_capacity_bytes
+    16,                   // data_pipe_buffer_alignment_bytes
+    1024 * 1024 * 1024};  // max_shared_memory_num_bytes
+
+}  // namespace internal
+}  // namespace system
+}  // namespace mojo
diff --git a/mojo/edk/system/configuration.h b/mojo/edk/system/configuration.h
new file mode 100644
index 0000000..007277a
--- /dev/null
+++ b/mojo/edk/system/configuration.h
@@ -0,0 +1,31 @@
+// 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_EDK_SYSTEM_CONFIGURATION_H_
+#define MOJO_EDK_SYSTEM_CONFIGURATION_H_
+
+#include "mojo/edk/embedder/configuration.h"
+#include "mojo/edk/system/system_impl_export.h"
+
+namespace mojo {
+namespace system {
+
+namespace internal {
+MOJO_SYSTEM_IMPL_EXPORT extern embedder::Configuration g_configuration;
+}  // namespace internal
+
+MOJO_SYSTEM_IMPL_EXPORT inline const embedder::Configuration&
+GetConfiguration() {
+  return internal::g_configuration;
+}
+
+MOJO_SYSTEM_IMPL_EXPORT inline embedder::Configuration*
+GetMutableConfiguration() {
+  return &internal::g_configuration;
+}
+
+}  // namespace system
+}  // namespace mojo
+
+#endif  // MOJO_EDK_SYSTEM_CONFIGURATION_H_
diff --git a/mojo/edk/system/constants.h b/mojo/edk/system/constants.h
deleted file mode 100644
index 23f35d8..0000000
--- a/mojo/edk/system/constants.h
+++ /dev/null
@@ -1,48 +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_EDK_SYSTEM_CONSTANTS_H_
-#define MOJO_EDK_SYSTEM_CONSTANTS_H_
-
-#include <stddef.h>
-
-namespace mojo {
-namespace system {
-
-// Maximum number of open (Mojo) handles.
-// TODO(vtl): This doesn't count "live" handles, some of which may live in
-// messages.
-const size_t kMaxHandleTableSize = 1000000;
-
-// Maximum number of active memory mappings.
-const size_t kMaxMappingTableSize = 1000000;
-
-const size_t kMaxWaitManyNumHandles = kMaxHandleTableSize;
-
-const size_t kMaxMessageNumBytes = 4 * 1024 * 1024;
-
-const size_t kMaxMessageNumHandles = 10000;
-
-// Maximum capacity of a data pipe, in bytes. This value must fit into a
-// |uint32_t|.
-// WARNING: If you bump it closer to 2^32, you must audit all the code to check
-// that we don't overflow (2^31 would definitely be risky; up to 2^30 is
-// probably okay).
-const size_t kMaxDataPipeCapacityBytes = 256 * 1024 * 1024;  // 256 MB.
-
-const size_t kDefaultDataPipeCapacityBytes = 1024 * 1024;  // 1 MB.
-
-// Alignment for the "start" of the data buffer used by data pipes. (The
-// alignment of elements will depend on this and the element size.)
-const size_t kDataPipeBufferAlignmentBytes = 16;
-
-// TODO(vtl): Set this hard limit appropriately (e.g., higher on 64-bit). (This
-// will also entail some auditing to make sure I'm not messing up my checks
-// anywhere.)
-const size_t kMaxSharedMemoryNumBytes = 1024 * 1024 * 1024;  // 1 GB.
-
-}  // namespace system
-}  // namespace mojo
-
-#endif  // MOJO_EDK_SYSTEM_CONSTANTS_H_
diff --git a/mojo/edk/system/core.cc b/mojo/edk/system/core.cc
index c67a626..27d33b2 100644
--- a/mojo/edk/system/core.cc
+++ b/mojo/edk/system/core.cc
@@ -10,7 +10,7 @@
 #include "base/time/time.h"
 #include "mojo/edk/embedder/platform_shared_buffer.h"
 #include "mojo/edk/embedder/platform_support.h"
-#include "mojo/edk/system/constants.h"
+#include "mojo/edk/system/configuration.h"
 #include "mojo/edk/system/data_pipe.h"
 #include "mojo/edk/system/data_pipe_consumer_dispatcher.h"
 #include "mojo/edk/system/data_pipe_producer_dispatcher.h"
@@ -126,11 +126,7 @@
                       UserPointer<MojoHandleSignalsState> signals_state) {
   uint32_t unused = static_cast<uint32_t>(-1);
   HandleSignalsState hss;
-  MojoResult rv = WaitManyInternal(&handle,
-                                   &signals,
-                                   1,
-                                   deadline,
-                                   &unused,
+  MojoResult rv = WaitManyInternal(&handle, &signals, 1, deadline, &unused,
                                    signals_state.IsNull() ? nullptr : &hss);
   if (rv != MOJO_RESULT_INVALID_ARGUMENT && !signals_state.IsNull())
     signals_state.Put(hss);
@@ -145,7 +141,7 @@
                           UserPointer<MojoHandleSignalsState> signals_states) {
   if (num_handles < 1)
     return MOJO_RESULT_INVALID_ARGUMENT;
-  if (num_handles > kMaxWaitManyNumHandles)
+  if (num_handles > GetConfiguration().max_wait_many_num_handles)
     return MOJO_RESULT_RESOURCE_EXHAUSTED;
 
   UserPointer<const MojoHandle>::Reader handles_reader(handles, num_handles);
@@ -155,23 +151,17 @@
   MojoResult rv;
   if (signals_states.IsNull()) {
     rv = WaitManyInternal(handles_reader.GetPointer(),
-                          signals_reader.GetPointer(),
-                          num_handles,
-                          deadline,
-                          &index,
-                          nullptr);
+                          signals_reader.GetPointer(), num_handles, deadline,
+                          &index, nullptr);
   } else {
     UserPointer<MojoHandleSignalsState>::Writer signals_states_writer(
         signals_states, num_handles);
     // Note: The |reinterpret_cast| is safe, since |HandleSignalsState| is a
     // subclass of |MojoHandleSignalsState| that doesn't add any data members.
     rv = WaitManyInternal(handles_reader.GetPointer(),
-                          signals_reader.GetPointer(),
-                          num_handles,
-                          deadline,
-                          &index,
-                          reinterpret_cast<HandleSignalsState*>(
-                              signals_states_writer.GetPointer()));
+                          signals_reader.GetPointer(), num_handles, deadline,
+                          &index, reinterpret_cast<HandleSignalsState*>(
+                                      signals_states_writer.GetPointer()));
     if (rv != MOJO_RESULT_INVALID_ARGUMENT)
       signals_states_writer.Commit();
   }
@@ -246,7 +236,7 @@
   // validity, even for dispatchers that don't support |WriteMessage()| and will
   // simply return failure unconditionally. It also breaks the usual
   // left-to-right verification order of arguments.)
-  if (num_handles > kMaxMessageNumHandles)
+  if (num_handles > GetConfiguration().max_message_num_handles)
     return MOJO_RESULT_RESOURCE_EXHAUSTED;
 
   UserPointer<const MojoHandle>::Reader handles_reader(handles, num_handles);
@@ -263,11 +253,9 @@
   // handles from the handle table.
   {
     base::AutoLock locker(handle_table_lock_);
-    MojoResult result =
-        handle_table_.MarkBusyAndStartTransport(message_pipe_handle,
-                                                handles_reader.GetPointer(),
-                                                num_handles,
-                                                &transports);
+    MojoResult result = handle_table_.MarkBusyAndStartTransport(
+        message_pipe_handle, handles_reader.GetPointer(), num_handles,
+        &transports);
     if (result != MOJO_RESULT_OK)
       return result;
   }
@@ -308,12 +296,12 @@
   MojoResult rv;
   if (num_handles_value == 0) {
     // Easy case: won't receive any handles.
-    rv = dispatcher->ReadMessage(
-        bytes, num_bytes, nullptr, &num_handles_value, flags);
+    rv = dispatcher->ReadMessage(bytes, num_bytes, nullptr, &num_handles_value,
+                                 flags);
   } else {
     DispatcherVector dispatchers;
-    rv = dispatcher->ReadMessage(
-        bytes, num_bytes, &dispatchers, &num_handles_value, flags);
+    rv = dispatcher->ReadMessage(bytes, num_bytes, &dispatchers,
+                                 &num_handles_value, flags);
     if (!dispatchers.empty()) {
       DCHECK_EQ(rv, MOJO_RESULT_OK);
       DCHECK(!num_handles.IsNull());
@@ -466,8 +454,8 @@
     return result;
 
   scoped_refptr<SharedBufferDispatcher> dispatcher;
-  result = SharedBufferDispatcher::Create(
-      platform_support(), validated_options, num_bytes, &dispatcher);
+  result = SharedBufferDispatcher::Create(platform_support(), validated_options,
+                                          num_bytes, &dispatcher);
   if (result != MOJO_RESULT_OK) {
     DCHECK(!dispatcher.get());
     return result;
diff --git a/mojo/edk/system/core_test_base.cc b/mojo/edk/system/core_test_base.cc
index d1a1a24..ea06c29 100644
--- a/mojo/edk/system/core_test_base.cc
+++ b/mojo/edk/system/core_test_base.cc
@@ -10,7 +10,7 @@
 #include "base/logging.h"
 #include "base/memory/ref_counted.h"
 #include "mojo/edk/embedder/simple_platform_support.h"
-#include "mojo/edk/system/constants.h"
+#include "mojo/edk/system/configuration.h"
 #include "mojo/edk/system/core.h"
 #include "mojo/edk/system/dispatcher.h"
 #include "mojo/edk/system/memory.h"
@@ -50,7 +50,7 @@
     info_->IncrementWriteMessageCallCount();
     lock().AssertAcquired();
 
-    if (num_bytes > kMaxMessageNumBytes)
+    if (num_bytes > GetConfiguration().max_message_num_bytes)
       return MOJO_RESULT_RESOURCE_EXHAUSTED;
 
     if (transports)
diff --git a/mojo/edk/system/core_unittest.cc b/mojo/edk/system/core_unittest.cc
index e6607df..96780f7 100644
--- a/mojo/edk/system/core_unittest.cc
+++ b/mojo/edk/system/core_unittest.cc
@@ -42,45 +42,34 @@
 
   EXPECT_EQ(0u, info.GetWriteMessageCallCount());
   EXPECT_EQ(MOJO_RESULT_OK,
-            core()->WriteMessage(h,
-                                 NullUserPointer(),
-                                 0,
-                                 NullUserPointer(),
-                                 0,
+            core()->WriteMessage(h, NullUserPointer(), 0, NullUserPointer(), 0,
                                  MOJO_WRITE_MESSAGE_FLAG_NONE));
   EXPECT_EQ(1u, info.GetWriteMessageCallCount());
 
   EXPECT_EQ(0u, info.GetReadMessageCallCount());
   uint32_t num_bytes = 0;
-  EXPECT_EQ(MOJO_RESULT_OK,
-            core()->ReadMessage(h,
-                                NullUserPointer(),
-                                MakeUserPointer(&num_bytes),
-                                NullUserPointer(),
-                                NullUserPointer(),
-                                MOJO_READ_MESSAGE_FLAG_NONE));
+  EXPECT_EQ(
+      MOJO_RESULT_OK,
+      core()->ReadMessage(h, NullUserPointer(), MakeUserPointer(&num_bytes),
+                          NullUserPointer(), NullUserPointer(),
+                          MOJO_READ_MESSAGE_FLAG_NONE));
   EXPECT_EQ(1u, info.GetReadMessageCallCount());
   EXPECT_EQ(MOJO_RESULT_OK,
-            core()->ReadMessage(h,
-                                NullUserPointer(),
-                                NullUserPointer(),
-                                NullUserPointer(),
-                                NullUserPointer(),
+            core()->ReadMessage(h, NullUserPointer(), NullUserPointer(),
+                                NullUserPointer(), NullUserPointer(),
                                 MOJO_READ_MESSAGE_FLAG_NONE));
   EXPECT_EQ(2u, info.GetReadMessageCallCount());
 
   EXPECT_EQ(0u, info.GetWriteDataCallCount());
-  EXPECT_EQ(
-      MOJO_RESULT_UNIMPLEMENTED,
-      core()->WriteData(
-          h, NullUserPointer(), NullUserPointer(), MOJO_WRITE_DATA_FLAG_NONE));
+  EXPECT_EQ(MOJO_RESULT_UNIMPLEMENTED,
+            core()->WriteData(h, NullUserPointer(), NullUserPointer(),
+                              MOJO_WRITE_DATA_FLAG_NONE));
   EXPECT_EQ(1u, info.GetWriteDataCallCount());
 
   EXPECT_EQ(0u, info.GetBeginWriteDataCallCount());
-  EXPECT_EQ(
-      MOJO_RESULT_UNIMPLEMENTED,
-      core()->BeginWriteData(
-          h, NullUserPointer(), NullUserPointer(), MOJO_WRITE_DATA_FLAG_NONE));
+  EXPECT_EQ(MOJO_RESULT_UNIMPLEMENTED,
+            core()->BeginWriteData(h, NullUserPointer(), NullUserPointer(),
+                                   MOJO_WRITE_DATA_FLAG_NONE));
   EXPECT_EQ(1u, info.GetBeginWriteDataCallCount());
 
   EXPECT_EQ(0u, info.GetEndWriteDataCallCount());
@@ -88,17 +77,15 @@
   EXPECT_EQ(1u, info.GetEndWriteDataCallCount());
 
   EXPECT_EQ(0u, info.GetReadDataCallCount());
-  EXPECT_EQ(
-      MOJO_RESULT_UNIMPLEMENTED,
-      core()->ReadData(
-          h, NullUserPointer(), NullUserPointer(), MOJO_READ_DATA_FLAG_NONE));
+  EXPECT_EQ(MOJO_RESULT_UNIMPLEMENTED,
+            core()->ReadData(h, NullUserPointer(), NullUserPointer(),
+                             MOJO_READ_DATA_FLAG_NONE));
   EXPECT_EQ(1u, info.GetReadDataCallCount());
 
   EXPECT_EQ(0u, info.GetBeginReadDataCallCount());
-  EXPECT_EQ(
-      MOJO_RESULT_UNIMPLEMENTED,
-      core()->BeginReadData(
-          h, NullUserPointer(), NullUserPointer(), MOJO_READ_DATA_FLAG_NONE));
+  EXPECT_EQ(MOJO_RESULT_UNIMPLEMENTED,
+            core()->BeginReadData(h, NullUserPointer(), NullUserPointer(),
+                                  MOJO_READ_DATA_FLAG_NONE));
   EXPECT_EQ(1u, info.GetBeginReadDataCallCount());
 
   EXPECT_EQ(0u, info.GetEndReadDataCallCount());
@@ -107,9 +94,7 @@
 
   EXPECT_EQ(0u, info.GetAddWaiterCallCount());
   EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION,
-            core()->Wait(h,
-                         ~MOJO_HANDLE_SIGNAL_NONE,
-                         MOJO_DEADLINE_INDEFINITE,
+            core()->Wait(h, ~MOJO_HANDLE_SIGNAL_NONE, MOJO_DEADLINE_INDEFINITE,
                          NullUserPointer()));
   EXPECT_EQ(1u, info.GetAddWaiterCallCount());
   EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION,
@@ -117,9 +102,7 @@
   EXPECT_EQ(2u, info.GetAddWaiterCallCount());
   MojoHandleSignalsState hss = kFullMojoHandleSignalsState;
   EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION,
-            core()->Wait(h,
-                         ~MOJO_HANDLE_SIGNAL_NONE,
-                         MOJO_DEADLINE_INDEFINITE,
+            core()->Wait(h, ~MOJO_HANDLE_SIGNAL_NONE, MOJO_DEADLINE_INDEFINITE,
                          MakeUserPointer(&hss)));
   EXPECT_EQ(3u, info.GetAddWaiterCallCount());
   EXPECT_EQ(0u, hss.satisfied_signals);
@@ -130,51 +113,43 @@
   EXPECT_EQ(4u, info.GetAddWaiterCallCount());
   hss = kFullMojoHandleSignalsState;
   EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION,
-            core()->Wait(
-                h, ~MOJO_HANDLE_SIGNAL_NONE, 10 * 1000, MakeUserPointer(&hss)));
+            core()->Wait(h, ~MOJO_HANDLE_SIGNAL_NONE, 10 * 1000,
+                         MakeUserPointer(&hss)));
   EXPECT_EQ(5u, info.GetAddWaiterCallCount());
   EXPECT_EQ(0u, hss.satisfied_signals);
   EXPECT_EQ(0u, hss.satisfiable_signals);
 
   MojoHandleSignals handle_signals = ~MOJO_HANDLE_SIGNAL_NONE;
-  EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION,
-            core()->WaitMany(MakeUserPointer(&h),
-                             MakeUserPointer(&handle_signals),
-                             1,
-                             MOJO_DEADLINE_INDEFINITE,
-                             NullUserPointer(),
-                             NullUserPointer()));
+  EXPECT_EQ(
+      MOJO_RESULT_FAILED_PRECONDITION,
+      core()->WaitMany(MakeUserPointer(&h), MakeUserPointer(&handle_signals), 1,
+                       MOJO_DEADLINE_INDEFINITE, NullUserPointer(),
+                       NullUserPointer()));
   EXPECT_EQ(6u, info.GetAddWaiterCallCount());
   uint32_t result_index = static_cast<uint32_t>(-1);
-  EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION,
-            core()->WaitMany(MakeUserPointer(&h),
-                             MakeUserPointer(&handle_signals),
-                             1,
-                             MOJO_DEADLINE_INDEFINITE,
-                             MakeUserPointer(&result_index),
-                             NullUserPointer()));
+  EXPECT_EQ(
+      MOJO_RESULT_FAILED_PRECONDITION,
+      core()->WaitMany(MakeUserPointer(&h), MakeUserPointer(&handle_signals), 1,
+                       MOJO_DEADLINE_INDEFINITE, MakeUserPointer(&result_index),
+                       NullUserPointer()));
   EXPECT_EQ(7u, info.GetAddWaiterCallCount());
   EXPECT_EQ(0u, result_index);
   hss = kFullMojoHandleSignalsState;
-  EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION,
-            core()->WaitMany(MakeUserPointer(&h),
-                             MakeUserPointer(&handle_signals),
-                             1,
-                             MOJO_DEADLINE_INDEFINITE,
-                             NullUserPointer(),
-                             MakeUserPointer(&hss)));
+  EXPECT_EQ(
+      MOJO_RESULT_FAILED_PRECONDITION,
+      core()->WaitMany(MakeUserPointer(&h), MakeUserPointer(&handle_signals), 1,
+                       MOJO_DEADLINE_INDEFINITE, NullUserPointer(),
+                       MakeUserPointer(&hss)));
   EXPECT_EQ(8u, info.GetAddWaiterCallCount());
   EXPECT_EQ(0u, hss.satisfied_signals);
   EXPECT_EQ(0u, hss.satisfiable_signals);
   result_index = static_cast<uint32_t>(-1);
   hss = kFullMojoHandleSignalsState;
-  EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION,
-            core()->WaitMany(MakeUserPointer(&h),
-                             MakeUserPointer(&handle_signals),
-                             1,
-                             MOJO_DEADLINE_INDEFINITE,
-                             MakeUserPointer(&result_index),
-                             MakeUserPointer(&hss)));
+  EXPECT_EQ(
+      MOJO_RESULT_FAILED_PRECONDITION,
+      core()->WaitMany(MakeUserPointer(&h), MakeUserPointer(&handle_signals), 1,
+                       MOJO_DEADLINE_INDEFINITE, MakeUserPointer(&result_index),
+                       MakeUserPointer(&hss)));
   EXPECT_EQ(9u, info.GetAddWaiterCallCount());
   EXPECT_EQ(0u, result_index);
   EXPECT_EQ(0u, hss.satisfied_signals);
@@ -211,22 +186,16 @@
   // |Wait()|:
   {
     EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
-              core()->Wait(MOJO_HANDLE_INVALID,
-                           ~MOJO_HANDLE_SIGNAL_NONE,
-                           MOJO_DEADLINE_INDEFINITE,
-                           NullUserPointer()));
+              core()->Wait(MOJO_HANDLE_INVALID, ~MOJO_HANDLE_SIGNAL_NONE,
+                           MOJO_DEADLINE_INDEFINITE, NullUserPointer()));
     EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
-              core()->Wait(10,
-                           ~MOJO_HANDLE_SIGNAL_NONE,
-                           MOJO_DEADLINE_INDEFINITE,
-                           NullUserPointer()));
+              core()->Wait(10, ~MOJO_HANDLE_SIGNAL_NONE,
+                           MOJO_DEADLINE_INDEFINITE, NullUserPointer()));
 
     MojoHandleSignalsState hss = kFullMojoHandleSignalsState;
     EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
-              core()->Wait(MOJO_HANDLE_INVALID,
-                           ~MOJO_HANDLE_SIGNAL_NONE,
-                           MOJO_DEADLINE_INDEFINITE,
-                           MakeUserPointer(&hss)));
+              core()->Wait(MOJO_HANDLE_INVALID, ~MOJO_HANDLE_SIGNAL_NONE,
+                           MOJO_DEADLINE_INDEFINITE, MakeUserPointer(&hss)));
     // On invalid argument, it shouldn't modify the handle signals state.
     EXPECT_EQ(kFullMojoHandleSignalsState.satisfied_signals,
               hss.satisfied_signals);
@@ -234,10 +203,8 @@
               hss.satisfiable_signals);
     hss = kFullMojoHandleSignalsState;
     EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
-              core()->Wait(10,
-                           ~MOJO_HANDLE_SIGNAL_NONE,
-                           MOJO_DEADLINE_INDEFINITE,
-                           MakeUserPointer(&hss)));
+              core()->Wait(10, ~MOJO_HANDLE_SIGNAL_NONE,
+                           MOJO_DEADLINE_INDEFINITE, MakeUserPointer(&hss)));
     // On invalid argument, it shouldn't modify the handle signals state.
     EXPECT_EQ(kFullMojoHandleSignalsState.satisfied_signals,
               hss.satisfied_signals);
@@ -250,19 +217,14 @@
     MojoHandle handles[2] = {MOJO_HANDLE_INVALID, MOJO_HANDLE_INVALID};
     MojoHandleSignals signals[2] = {~MOJO_HANDLE_SIGNAL_NONE,
                                     ~MOJO_HANDLE_SIGNAL_NONE};
+    EXPECT_EQ(
+        MOJO_RESULT_INVALID_ARGUMENT,
+        core()->WaitMany(MakeUserPointer(handles), MakeUserPointer(signals), 0,
+                         MOJO_DEADLINE_INDEFINITE, NullUserPointer(),
+                         NullUserPointer()));
     EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
-              core()->WaitMany(MakeUserPointer(handles),
-                               MakeUserPointer(signals),
-                               0,
-                               MOJO_DEADLINE_INDEFINITE,
-                               NullUserPointer(),
-                               NullUserPointer()));
-    EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
-              core()->WaitMany(NullUserPointer(),
-                               MakeUserPointer(signals),
-                               0,
-                               MOJO_DEADLINE_INDEFINITE,
-                               NullUserPointer(),
+              core()->WaitMany(NullUserPointer(), MakeUserPointer(signals), 0,
+                               MOJO_DEADLINE_INDEFINITE, NullUserPointer(),
                                NullUserPointer()));
     // If |num_handles| is invalid, it should leave |result_index| and
     // |signals_states| alone.
@@ -270,9 +232,7 @@
     uint32_t result_index = 123;
     MojoHandleSignalsState hss = kFullMojoHandleSignalsState;
     EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
-              core()->WaitMany(NullUserPointer(),
-                               MakeUserPointer(signals),
-                               0,
+              core()->WaitMany(NullUserPointer(), MakeUserPointer(signals), 0,
                                MOJO_DEADLINE_INDEFINITE,
                                MakeUserPointer(&result_index),
                                MakeUserPointer(&hss)));
@@ -283,30 +243,23 @@
               hss.satisfiable_signals);
 
     EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
-              core()->WaitMany(MakeUserPointer(handles),
-                               NullUserPointer(),
-                               0,
-                               MOJO_DEADLINE_INDEFINITE,
-                               NullUserPointer(),
+              core()->WaitMany(MakeUserPointer(handles), NullUserPointer(), 0,
+                               MOJO_DEADLINE_INDEFINITE, NullUserPointer(),
                                NullUserPointer()));
-    EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
-              core()->WaitMany(MakeUserPointer(handles),
-                               MakeUserPointer(signals),
-                               1,
-                               MOJO_DEADLINE_INDEFINITE,
-                               NullUserPointer(),
-                               NullUserPointer()));
+    EXPECT_EQ(
+        MOJO_RESULT_INVALID_ARGUMENT,
+        core()->WaitMany(MakeUserPointer(handles), MakeUserPointer(signals), 1,
+                         MOJO_DEADLINE_INDEFINITE, NullUserPointer(),
+                         NullUserPointer()));
     // But if a handle is bad, then it should set |result_index| but still leave
     // |signals_states| alone.
     result_index = static_cast<uint32_t>(-1);
     hss = kFullMojoHandleSignalsState;
     EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
-              core()->WaitMany(MakeUserPointer(handles),
-                               MakeUserPointer(signals),
-                               1,
-                               MOJO_DEADLINE_INDEFINITE,
-                               MakeUserPointer(&result_index),
-                               MakeUserPointer(&hss)));
+              core()->WaitMany(
+                  MakeUserPointer(handles), MakeUserPointer(signals), 1,
+                  MOJO_DEADLINE_INDEFINITE, MakeUserPointer(&result_index),
+                  MakeUserPointer(&hss)));
     EXPECT_EQ(0u, result_index);
     EXPECT_EQ(kFullMojoHandleSignalsState.satisfied_signals,
               hss.satisfied_signals);
@@ -319,12 +272,10 @@
     result_index = static_cast<uint32_t>(-1);
     hss = kFullMojoHandleSignalsState;
     EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION,
-              core()->WaitMany(MakeUserPointer(handles),
-                               MakeUserPointer(signals),
-                               1,
-                               MOJO_DEADLINE_INDEFINITE,
-                               MakeUserPointer(&result_index),
-                               MakeUserPointer(&hss)));
+              core()->WaitMany(
+                  MakeUserPointer(handles), MakeUserPointer(signals), 1,
+                  MOJO_DEADLINE_INDEFINITE, MakeUserPointer(&result_index),
+                  MakeUserPointer(&hss)));
     EXPECT_EQ(0u, result_index);
     EXPECT_EQ(0u, hss.satisfied_signals);
     EXPECT_EQ(0u, hss.satisfiable_signals);
@@ -333,33 +284,27 @@
     result_index = static_cast<uint32_t>(-1);
     hss = kFullMojoHandleSignalsState;
     EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
-              core()->WaitMany(MakeUserPointer(handles),
-                               MakeUserPointer(signals),
-                               2,
-                               MOJO_DEADLINE_INDEFINITE,
-                               MakeUserPointer(&result_index),
-                               MakeUserPointer(&hss)));
+              core()->WaitMany(
+                  MakeUserPointer(handles), MakeUserPointer(signals), 2,
+                  MOJO_DEADLINE_INDEFINITE, MakeUserPointer(&result_index),
+                  MakeUserPointer(&hss)));
     EXPECT_EQ(1u, result_index);
     EXPECT_EQ(kFullMojoHandleSignalsState.satisfied_signals,
               hss.satisfied_signals);
     EXPECT_EQ(kFullMojoHandleSignalsState.satisfiable_signals,
               hss.satisfiable_signals);
     handles[1] = handles[0] + 1;  // Invalid handle.
-    EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
-              core()->WaitMany(MakeUserPointer(handles),
-                               MakeUserPointer(signals),
-                               2,
-                               MOJO_DEADLINE_INDEFINITE,
-                               NullUserPointer(),
-                               NullUserPointer()));
+    EXPECT_EQ(
+        MOJO_RESULT_INVALID_ARGUMENT,
+        core()->WaitMany(MakeUserPointer(handles), MakeUserPointer(signals), 2,
+                         MOJO_DEADLINE_INDEFINITE, NullUserPointer(),
+                         NullUserPointer()));
     handles[1] = CreateMockHandle(&info[1]);
-    EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION,
-              core()->WaitMany(MakeUserPointer(handles),
-                               MakeUserPointer(signals),
-                               2,
-                               MOJO_DEADLINE_INDEFINITE,
-                               NullUserPointer(),
-                               NullUserPointer()));
+    EXPECT_EQ(
+        MOJO_RESULT_FAILED_PRECONDITION,
+        core()->WaitMany(MakeUserPointer(handles), MakeUserPointer(signals), 2,
+                         MOJO_DEADLINE_INDEFINITE, NullUserPointer(),
+                         NullUserPointer()));
 
     // TODO(vtl): Test one where we get "failed precondition" only for the
     // second handle (and the first one is valid to wait on).
@@ -376,11 +321,8 @@
   // |num_handles|.
   {
     EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
-              core()->WriteMessage(MOJO_HANDLE_INVALID,
-                                   NullUserPointer(),
-                                   0,
-                                   NullUserPointer(),
-                                   0,
+              core()->WriteMessage(MOJO_HANDLE_INVALID, NullUserPointer(), 0,
+                                   NullUserPointer(), 0,
                                    MOJO_WRITE_MESSAGE_FLAG_NONE));
 
     MockHandleInfo info;
@@ -392,55 +334,41 @@
     // Note: This may return either |MOJO_RESULT_INVALID_ARGUMENT| or
     // |MOJO_RESULT_RESOURCE_EXHAUSTED|, depending on whether it's plausible or
     // not.
-    EXPECT_NE(MOJO_RESULT_OK,
-              core()->WriteMessage(h,
-                                   NullUserPointer(),
-                                   0,
-                                   MakeUserPointer(handles),
-                                   std::numeric_limits<uint32_t>::max(),
-                                   MOJO_WRITE_MESSAGE_FLAG_NONE));
+    EXPECT_NE(
+        MOJO_RESULT_OK,
+        core()->WriteMessage(h, NullUserPointer(), 0, MakeUserPointer(handles),
+                             std::numeric_limits<uint32_t>::max(),
+                             MOJO_WRITE_MESSAGE_FLAG_NONE));
     EXPECT_EQ(0u, info.GetWriteMessageCallCount());
 
     // Huge handle count (plausibly big).
     EXPECT_EQ(MOJO_RESULT_RESOURCE_EXHAUSTED,
               core()->WriteMessage(
-                  h,
-                  NullUserPointer(),
-                  0,
-                  MakeUserPointer(handles),
+                  h, NullUserPointer(), 0, MakeUserPointer(handles),
                   std::numeric_limits<uint32_t>::max() / sizeof(handles[0]),
                   MOJO_WRITE_MESSAGE_FLAG_NONE));
     EXPECT_EQ(0u, info.GetWriteMessageCallCount());
 
     // Invalid handle in |handles|.
-    EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
-              core()->WriteMessage(h,
-                                   NullUserPointer(),
-                                   0,
-                                   MakeUserPointer(handles),
-                                   1,
-                                   MOJO_WRITE_MESSAGE_FLAG_NONE));
+    EXPECT_EQ(
+        MOJO_RESULT_INVALID_ARGUMENT,
+        core()->WriteMessage(h, NullUserPointer(), 0, MakeUserPointer(handles),
+                             1, MOJO_WRITE_MESSAGE_FLAG_NONE));
     EXPECT_EQ(0u, info.GetWriteMessageCallCount());
 
     // Two invalid handles in |handles|.
-    EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
-              core()->WriteMessage(h,
-                                   NullUserPointer(),
-                                   0,
-                                   MakeUserPointer(handles),
-                                   2,
-                                   MOJO_WRITE_MESSAGE_FLAG_NONE));
+    EXPECT_EQ(
+        MOJO_RESULT_INVALID_ARGUMENT,
+        core()->WriteMessage(h, NullUserPointer(), 0, MakeUserPointer(handles),
+                             2, MOJO_WRITE_MESSAGE_FLAG_NONE));
     EXPECT_EQ(0u, info.GetWriteMessageCallCount());
 
     // Can't send a handle over itself.
     handles[0] = h;
-    EXPECT_EQ(MOJO_RESULT_BUSY,
-              core()->WriteMessage(h,
-                                   NullUserPointer(),
-                                   0,
-                                   MakeUserPointer(handles),
-                                   1,
-                                   MOJO_WRITE_MESSAGE_FLAG_NONE));
+    EXPECT_EQ(
+        MOJO_RESULT_BUSY,
+        core()->WriteMessage(h, NullUserPointer(), 0, MakeUserPointer(handles),
+                             1, MOJO_WRITE_MESSAGE_FLAG_NONE));
     EXPECT_EQ(0u, info.GetWriteMessageCallCount());
 
     MockHandleInfo info2;
@@ -448,45 +376,33 @@
 
     // This is "okay", but |MockDispatcher| doesn't implement it.
     handles[0] = h2;
-    EXPECT_EQ(MOJO_RESULT_UNIMPLEMENTED,
-              core()->WriteMessage(h,
-                                   NullUserPointer(),
-                                   0,
-                                   MakeUserPointer(handles),
-                                   1,
-                                   MOJO_WRITE_MESSAGE_FLAG_NONE));
+    EXPECT_EQ(
+        MOJO_RESULT_UNIMPLEMENTED,
+        core()->WriteMessage(h, NullUserPointer(), 0, MakeUserPointer(handles),
+                             1, MOJO_WRITE_MESSAGE_FLAG_NONE));
     EXPECT_EQ(1u, info.GetWriteMessageCallCount());
 
     // One of the |handles| is still invalid.
-    EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
-              core()->WriteMessage(h,
-                                   NullUserPointer(),
-                                   0,
-                                   MakeUserPointer(handles),
-                                   2,
-                                   MOJO_WRITE_MESSAGE_FLAG_NONE));
+    EXPECT_EQ(
+        MOJO_RESULT_INVALID_ARGUMENT,
+        core()->WriteMessage(h, NullUserPointer(), 0, MakeUserPointer(handles),
+                             2, MOJO_WRITE_MESSAGE_FLAG_NONE));
     EXPECT_EQ(1u, info.GetWriteMessageCallCount());
 
     // One of the |handles| is the same as |handle|.
     handles[1] = h;
-    EXPECT_EQ(MOJO_RESULT_BUSY,
-              core()->WriteMessage(h,
-                                   NullUserPointer(),
-                                   0,
-                                   MakeUserPointer(handles),
-                                   2,
-                                   MOJO_WRITE_MESSAGE_FLAG_NONE));
+    EXPECT_EQ(
+        MOJO_RESULT_BUSY,
+        core()->WriteMessage(h, NullUserPointer(), 0, MakeUserPointer(handles),
+                             2, MOJO_WRITE_MESSAGE_FLAG_NONE));
     EXPECT_EQ(1u, info.GetWriteMessageCallCount());
 
     // Can't send a handle twice in the same message.
     handles[1] = h2;
-    EXPECT_EQ(MOJO_RESULT_BUSY,
-              core()->WriteMessage(h,
-                                   NullUserPointer(),
-                                   0,
-                                   MakeUserPointer(handles),
-                                   2,
-                                   MOJO_WRITE_MESSAGE_FLAG_NONE));
+    EXPECT_EQ(
+        MOJO_RESULT_BUSY,
+        core()->WriteMessage(h, NullUserPointer(), 0, MakeUserPointer(handles),
+                             2, MOJO_WRITE_MESSAGE_FLAG_NONE));
     EXPECT_EQ(1u, info.GetWriteMessageCallCount());
 
     // Note: Since we never successfully sent anything with it, |h2| should
@@ -500,13 +416,11 @@
   // Only check arguments checked by |Core|, namely |handle|, |handles|, and
   // |num_handles|.
   {
-    EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
-              core()->ReadMessage(MOJO_HANDLE_INVALID,
-                                  NullUserPointer(),
-                                  NullUserPointer(),
-                                  NullUserPointer(),
-                                  NullUserPointer(),
-                                  MOJO_READ_MESSAGE_FLAG_NONE));
+    EXPECT_EQ(
+        MOJO_RESULT_INVALID_ARGUMENT,
+        core()->ReadMessage(MOJO_HANDLE_INVALID, NullUserPointer(),
+                            NullUserPointer(), NullUserPointer(),
+                            NullUserPointer(), MOJO_READ_MESSAGE_FLAG_NONE));
 
     MockHandleInfo info;
     MojoHandle h = CreateMockHandle(&info);
@@ -514,12 +428,9 @@
     // Okay.
     uint32_t handle_count = 0;
     EXPECT_EQ(MOJO_RESULT_OK,
-              core()->ReadMessage(h,
-                                  NullUserPointer(),
-                                  NullUserPointer(),
-                                  NullUserPointer(),
-                                  MakeUserPointer(&handle_count),
-                                  MOJO_READ_MESSAGE_FLAG_NONE));
+              core()->ReadMessage(
+                  h, NullUserPointer(), NullUserPointer(), NullUserPointer(),
+                  MakeUserPointer(&handle_count), MOJO_READ_MESSAGE_FLAG_NONE));
     // Checked by |Core|, shouldn't go through to the dispatcher.
     EXPECT_EQ(1u, info.GetReadMessageCallCount());
 
@@ -540,20 +451,16 @@
   {
     MojoHandle handle = MOJO_HANDLE_INVALID;
     MojoHandleSignals signals = ~MOJO_HANDLE_SIGNAL_NONE;
-    EXPECT_DEATH_IF_SUPPORTED(core()->WaitMany(NullUserPointer(),
-                                               MakeUserPointer(&signals),
-                                               1,
-                                               MOJO_DEADLINE_INDEFINITE,
-                                               NullUserPointer(),
-                                               NullUserPointer()),
-                              kMemoryCheckFailedRegex);
-    EXPECT_DEATH_IF_SUPPORTED(core()->WaitMany(MakeUserPointer(&handle),
-                                               NullUserPointer(),
-                                               1,
-                                               MOJO_DEADLINE_INDEFINITE,
-                                               NullUserPointer(),
-                                               NullUserPointer()),
-                              kMemoryCheckFailedRegex);
+    EXPECT_DEATH_IF_SUPPORTED(
+        core()->WaitMany(NullUserPointer(), MakeUserPointer(&signals), 1,
+                         MOJO_DEADLINE_INDEFINITE, NullUserPointer(),
+                         NullUserPointer()),
+        kMemoryCheckFailedRegex);
+    EXPECT_DEATH_IF_SUPPORTED(
+        core()->WaitMany(MakeUserPointer(&handle), NullUserPointer(), 1,
+                         MOJO_DEADLINE_INDEFINITE, NullUserPointer(),
+                         NullUserPointer()),
+        kMemoryCheckFailedRegex);
     // TODO(vtl): |result_index| and |signals_states| are optional. Test them
     // with non-null invalid pointers?
   }
@@ -562,16 +469,16 @@
   {
     MojoHandle h;
     EXPECT_DEATH_IF_SUPPORTED(
-        core()->CreateMessagePipe(
-            NullUserPointer(), NullUserPointer(), NullUserPointer()),
+        core()->CreateMessagePipe(NullUserPointer(), NullUserPointer(),
+                                  NullUserPointer()),
         kMemoryCheckFailedRegex);
     EXPECT_DEATH_IF_SUPPORTED(
-        core()->CreateMessagePipe(
-            NullUserPointer(), MakeUserPointer(&h), NullUserPointer()),
+        core()->CreateMessagePipe(NullUserPointer(), MakeUserPointer(&h),
+                                  NullUserPointer()),
         kMemoryCheckFailedRegex);
     EXPECT_DEATH_IF_SUPPORTED(
-        core()->CreateMessagePipe(
-            NullUserPointer(), NullUserPointer(), MakeUserPointer(&h)),
+        core()->CreateMessagePipe(NullUserPointer(), NullUserPointer(),
+                                  MakeUserPointer(&h)),
         kMemoryCheckFailedRegex);
   }
 
@@ -584,11 +491,7 @@
 
     // Null |handles| with nonzero |num_handles|.
     EXPECT_DEATH_IF_SUPPORTED(
-        core()->WriteMessage(h,
-                             NullUserPointer(),
-                             0,
-                             NullUserPointer(),
-                             1,
+        core()->WriteMessage(h, NullUserPointer(), 0, NullUserPointer(), 1,
                              MOJO_WRITE_MESSAGE_FLAG_NONE),
         kMemoryCheckFailedRegex);
 
@@ -604,11 +507,8 @@
 
     uint32_t handle_count = 1;
     EXPECT_DEATH_IF_SUPPORTED(
-        core()->ReadMessage(h,
-                            NullUserPointer(),
-                            NullUserPointer(),
-                            NullUserPointer(),
-                            MakeUserPointer(&handle_count),
+        core()->ReadMessage(h, NullUserPointer(), NullUserPointer(),
+                            NullUserPointer(), MakeUserPointer(&handle_count),
                             MOJO_READ_MESSAGE_FLAG_NONE),
         kMemoryCheckFailedRegex);
 
@@ -625,10 +525,9 @@
   MojoHandleSignalsState hss[2];
   uint32_t result_index;
 
-  EXPECT_EQ(
-      MOJO_RESULT_OK,
-      core()->CreateMessagePipe(
-          NullUserPointer(), MakeUserPointer(&h[0]), MakeUserPointer(&h[1])));
+  EXPECT_EQ(MOJO_RESULT_OK,
+            core()->CreateMessagePipe(NullUserPointer(), MakeUserPointer(&h[0]),
+                                      MakeUserPointer(&h[1])));
   // Should get two distinct, valid handles.
   EXPECT_NE(h[0], MOJO_HANDLE_INVALID);
   EXPECT_NE(h[1], MOJO_HANDLE_INVALID);
@@ -640,13 +539,10 @@
   result_index = static_cast<uint32_t>(-1);
   hss[0] = kEmptyMojoHandleSignalsState;
   hss[1] = kEmptyMojoHandleSignalsState;
-  EXPECT_EQ(MOJO_RESULT_DEADLINE_EXCEEDED,
-            core()->WaitMany(MakeUserPointer(h),
-                             MakeUserPointer(signals),
-                             2,
-                             0,
-                             MakeUserPointer(&result_index),
-                             MakeUserPointer(hss)));
+  EXPECT_EQ(
+      MOJO_RESULT_DEADLINE_EXCEEDED,
+      core()->WaitMany(MakeUserPointer(h), MakeUserPointer(signals), 2, 0,
+                       MakeUserPointer(&result_index), MakeUserPointer(hss)));
   EXPECT_EQ(static_cast<uint32_t>(-1), result_index);
   EXPECT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE, hss[0].satisfied_signals);
   EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE,
@@ -658,33 +554,25 @@
   // Try to read anyway.
   char buffer[1] = {'a'};
   uint32_t buffer_size = 1;
-  EXPECT_EQ(MOJO_RESULT_SHOULD_WAIT,
-            core()->ReadMessage(h[0],
-                                UserPointer<void>(buffer),
-                                MakeUserPointer(&buffer_size),
-                                NullUserPointer(),
-                                NullUserPointer(),
-                                MOJO_READ_MESSAGE_FLAG_NONE));
+  EXPECT_EQ(
+      MOJO_RESULT_SHOULD_WAIT,
+      core()->ReadMessage(h[0], UserPointer<void>(buffer),
+                          MakeUserPointer(&buffer_size), NullUserPointer(),
+                          NullUserPointer(), MOJO_READ_MESSAGE_FLAG_NONE));
   // Check that it left its inputs alone.
   EXPECT_EQ('a', buffer[0]);
   EXPECT_EQ(1u, buffer_size);
 
   // Both should be writable.
   hss[0] = kEmptyMojoHandleSignalsState;
-  EXPECT_EQ(MOJO_RESULT_OK,
-            core()->Wait(h[0],
-                         MOJO_HANDLE_SIGNAL_WRITABLE,
-                         1000000000,
-                         MakeUserPointer(&hss[0])));
+  EXPECT_EQ(MOJO_RESULT_OK, core()->Wait(h[0], MOJO_HANDLE_SIGNAL_WRITABLE,
+                                         1000000000, MakeUserPointer(&hss[0])));
   EXPECT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE, hss[0].satisfied_signals);
   EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE,
             hss[0].satisfiable_signals);
   hss[0] = kEmptyMojoHandleSignalsState;
-  EXPECT_EQ(MOJO_RESULT_OK,
-            core()->Wait(h[1],
-                         MOJO_HANDLE_SIGNAL_WRITABLE,
-                         1000000000,
-                         MakeUserPointer(&hss[0])));
+  EXPECT_EQ(MOJO_RESULT_OK, core()->Wait(h[1], MOJO_HANDLE_SIGNAL_WRITABLE,
+                                         1000000000, MakeUserPointer(&hss[0])));
   EXPECT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE, hss[0].satisfied_signals);
   EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE,
             hss[0].satisfiable_signals);
@@ -695,13 +583,11 @@
   result_index = static_cast<uint32_t>(-1);
   hss[0] = kEmptyMojoHandleSignalsState;
   hss[1] = kEmptyMojoHandleSignalsState;
-  EXPECT_EQ(MOJO_RESULT_OK,
-            core()->WaitMany(MakeUserPointer(h),
-                             MakeUserPointer(signals),
-                             2,
-                             MOJO_DEADLINE_INDEFINITE,
-                             MakeUserPointer(&result_index),
-                             MakeUserPointer(hss)));
+  EXPECT_EQ(
+      MOJO_RESULT_OK,
+      core()->WaitMany(MakeUserPointer(h), MakeUserPointer(signals), 2,
+                       MOJO_DEADLINE_INDEFINITE, MakeUserPointer(&result_index),
+                       MakeUserPointer(hss)));
   EXPECT_EQ(1u, result_index);
   EXPECT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE, hss[0].satisfied_signals);
   EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE,
@@ -712,13 +598,10 @@
 
   // Write to |h[1]|.
   buffer[0] = 'b';
-  EXPECT_EQ(MOJO_RESULT_OK,
-            core()->WriteMessage(h[1],
-                                 UserPointer<const void>(buffer),
-                                 1,
-                                 NullUserPointer(),
-                                 0,
-                                 MOJO_WRITE_MESSAGE_FLAG_NONE));
+  EXPECT_EQ(
+      MOJO_RESULT_OK,
+      core()->WriteMessage(h[1], UserPointer<const void>(buffer), 1,
+                           NullUserPointer(), 0, MOJO_WRITE_MESSAGE_FLAG_NONE));
 
   // Check that |h[0]| is now readable.
   signals[0] = MOJO_HANDLE_SIGNAL_READABLE;
@@ -726,13 +609,11 @@
   result_index = static_cast<uint32_t>(-1);
   hss[0] = kEmptyMojoHandleSignalsState;
   hss[1] = kEmptyMojoHandleSignalsState;
-  EXPECT_EQ(MOJO_RESULT_OK,
-            core()->WaitMany(MakeUserPointer(h),
-                             MakeUserPointer(signals),
-                             2,
-                             MOJO_DEADLINE_INDEFINITE,
-                             MakeUserPointer(&result_index),
-                             MakeUserPointer(hss)));
+  EXPECT_EQ(
+      MOJO_RESULT_OK,
+      core()->WaitMany(MakeUserPointer(h), MakeUserPointer(signals), 2,
+                       MOJO_DEADLINE_INDEFINITE, MakeUserPointer(&result_index),
+                       MakeUserPointer(hss)));
   EXPECT_EQ(0u, result_index);
   EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE,
             hss[0].satisfied_signals);
@@ -745,46 +626,38 @@
   // Read from |h[0]|.
   // First, get only the size.
   buffer_size = 0;
-  EXPECT_EQ(MOJO_RESULT_RESOURCE_EXHAUSTED,
-            core()->ReadMessage(h[0],
-                                NullUserPointer(),
-                                MakeUserPointer(&buffer_size),
-                                NullUserPointer(),
-                                NullUserPointer(),
-                                MOJO_READ_MESSAGE_FLAG_NONE));
+  EXPECT_EQ(
+      MOJO_RESULT_RESOURCE_EXHAUSTED,
+      core()->ReadMessage(h[0], NullUserPointer(),
+                          MakeUserPointer(&buffer_size), NullUserPointer(),
+                          NullUserPointer(), MOJO_READ_MESSAGE_FLAG_NONE));
   EXPECT_EQ(1u, buffer_size);
   // Then actually read it.
   buffer[0] = 'c';
   buffer_size = 1;
-  EXPECT_EQ(MOJO_RESULT_OK,
-            core()->ReadMessage(h[0],
-                                UserPointer<void>(buffer),
-                                MakeUserPointer(&buffer_size),
-                                NullUserPointer(),
-                                NullUserPointer(),
-                                MOJO_READ_MESSAGE_FLAG_NONE));
+  EXPECT_EQ(
+      MOJO_RESULT_OK,
+      core()->ReadMessage(h[0], UserPointer<void>(buffer),
+                          MakeUserPointer(&buffer_size), NullUserPointer(),
+                          NullUserPointer(), MOJO_READ_MESSAGE_FLAG_NONE));
   EXPECT_EQ('b', buffer[0]);
   EXPECT_EQ(1u, buffer_size);
 
   // |h[0]| should no longer be readable.
   hss[0] = kEmptyMojoHandleSignalsState;
-  EXPECT_EQ(
-      MOJO_RESULT_DEADLINE_EXCEEDED,
-      core()->Wait(
-          h[0], MOJO_HANDLE_SIGNAL_READABLE, 0, MakeUserPointer(&hss[0])));
+  EXPECT_EQ(MOJO_RESULT_DEADLINE_EXCEEDED,
+            core()->Wait(h[0], MOJO_HANDLE_SIGNAL_READABLE, 0,
+                         MakeUserPointer(&hss[0])));
   EXPECT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE, hss[0].satisfied_signals);
   EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE,
             hss[0].satisfiable_signals);
 
   // Write to |h[0]|.
   buffer[0] = 'd';
-  EXPECT_EQ(MOJO_RESULT_OK,
-            core()->WriteMessage(h[0],
-                                 UserPointer<const void>(buffer),
-                                 1,
-                                 NullUserPointer(),
-                                 0,
-                                 MOJO_WRITE_MESSAGE_FLAG_NONE));
+  EXPECT_EQ(
+      MOJO_RESULT_OK,
+      core()->WriteMessage(h[0], UserPointer<const void>(buffer), 1,
+                           NullUserPointer(), 0, MOJO_WRITE_MESSAGE_FLAG_NONE));
 
   // Close |h[0]|.
   EXPECT_EQ(MOJO_RESULT_OK, core()->Close(h[0]));
@@ -792,51 +665,38 @@
   // Check that |h[1]| is no longer writable (and will never be).
   hss[0] = kEmptyMojoHandleSignalsState;
   EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION,
-            core()->Wait(h[1],
-                         MOJO_HANDLE_SIGNAL_WRITABLE,
-                         1000000000,
+            core()->Wait(h[1], MOJO_HANDLE_SIGNAL_WRITABLE, 1000000000,
                          MakeUserPointer(&hss[0])));
   EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE, hss[0].satisfied_signals);
   EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE, hss[0].satisfiable_signals);
 
   // Check that |h[1]| is still readable (for the moment).
   hss[0] = kEmptyMojoHandleSignalsState;
-  EXPECT_EQ(MOJO_RESULT_OK,
-            core()->Wait(h[1],
-                         MOJO_HANDLE_SIGNAL_READABLE,
-                         1000000000,
-                         MakeUserPointer(&hss[0])));
+  EXPECT_EQ(MOJO_RESULT_OK, core()->Wait(h[1], MOJO_HANDLE_SIGNAL_READABLE,
+                                         1000000000, MakeUserPointer(&hss[0])));
   EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE, hss[0].satisfied_signals);
   EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE, hss[0].satisfiable_signals);
 
   // Discard a message from |h[1]|.
   EXPECT_EQ(MOJO_RESULT_RESOURCE_EXHAUSTED,
-            core()->ReadMessage(h[1],
-                                NullUserPointer(),
-                                NullUserPointer(),
-                                NullUserPointer(),
-                                NullUserPointer(),
+            core()->ReadMessage(h[1], NullUserPointer(), NullUserPointer(),
+                                NullUserPointer(), NullUserPointer(),
                                 MOJO_READ_MESSAGE_FLAG_MAY_DISCARD));
 
   // |h[1]| is no longer readable (and will never be).
   hss[0] = kFullMojoHandleSignalsState;
   EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION,
-            core()->Wait(h[1],
-                         MOJO_HANDLE_SIGNAL_READABLE,
-                         1000000000,
+            core()->Wait(h[1], MOJO_HANDLE_SIGNAL_READABLE, 1000000000,
                          MakeUserPointer(&hss[0])));
   EXPECT_EQ(0u, hss[0].satisfied_signals);
   EXPECT_EQ(0u, hss[0].satisfiable_signals);
 
   // Try writing to |h[1]|.
   buffer[0] = 'e';
-  EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION,
-            core()->WriteMessage(h[1],
-                                 UserPointer<const void>(buffer),
-                                 1,
-                                 NullUserPointer(),
-                                 0,
-                                 MOJO_WRITE_MESSAGE_FLAG_NONE));
+  EXPECT_EQ(
+      MOJO_RESULT_FAILED_PRECONDITION,
+      core()->WriteMessage(h[1], UserPointer<const void>(buffer), 1,
+                           NullUserPointer(), 0, MOJO_WRITE_MESSAGE_FLAG_NONE));
 
   EXPECT_EQ(MOJO_RESULT_OK, core()->Close(h[1]));
 }
@@ -863,17 +723,12 @@
 
   // Make sure that |h_passing[]| work properly.
   EXPECT_EQ(MOJO_RESULT_OK,
-            core()->WriteMessage(h_passing[0],
-                                 UserPointer<const void>(kHello),
-                                 kHelloSize,
-                                 NullUserPointer(),
-                                 0,
+            core()->WriteMessage(h_passing[0], UserPointer<const void>(kHello),
+                                 kHelloSize, NullUserPointer(), 0,
                                  MOJO_WRITE_MESSAGE_FLAG_NONE));
   hss = kEmptyMojoHandleSignalsState;
   EXPECT_EQ(MOJO_RESULT_OK,
-            core()->Wait(h_passing[1],
-                         MOJO_HANDLE_SIGNAL_READABLE,
-                         1000000000,
+            core()->Wait(h_passing[1], MOJO_HANDLE_SIGNAL_READABLE, 1000000000,
                          MakeUserPointer(&hss)));
   EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE,
             hss.satisfied_signals);
@@ -882,12 +737,10 @@
   num_bytes = kBufferSize;
   num_handles = arraysize(handles);
   EXPECT_EQ(MOJO_RESULT_OK,
-            core()->ReadMessage(h_passing[1],
-                                UserPointer<void>(buffer),
-                                MakeUserPointer(&num_bytes),
-                                MakeUserPointer(handles),
-                                MakeUserPointer(&num_handles),
-                                MOJO_READ_MESSAGE_FLAG_NONE));
+            core()->ReadMessage(
+                h_passing[1], UserPointer<void>(buffer),
+                MakeUserPointer(&num_bytes), MakeUserPointer(handles),
+                MakeUserPointer(&num_handles), MOJO_READ_MESSAGE_FLAG_NONE));
   EXPECT_EQ(kHelloSize, num_bytes);
   EXPECT_STREQ(kHello, buffer);
   EXPECT_EQ(0u, num_handles);
@@ -895,18 +748,12 @@
   // Make sure that you can't pass either of the message pipe's handles over
   // itself.
   EXPECT_EQ(MOJO_RESULT_BUSY,
-            core()->WriteMessage(h_passing[0],
-                                 UserPointer<const void>(kHello),
-                                 kHelloSize,
-                                 MakeUserPointer(&h_passing[0]),
-                                 1,
+            core()->WriteMessage(h_passing[0], UserPointer<const void>(kHello),
+                                 kHelloSize, MakeUserPointer(&h_passing[0]), 1,
                                  MOJO_WRITE_MESSAGE_FLAG_NONE));
   EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
-            core()->WriteMessage(h_passing[0],
-                                 UserPointer<const void>(kHello),
-                                 kHelloSize,
-                                 MakeUserPointer(&h_passing[1]),
-                                 1,
+            core()->WriteMessage(h_passing[0], UserPointer<const void>(kHello),
+                                 kHelloSize, MakeUserPointer(&h_passing[1]), 1,
                                  MOJO_WRITE_MESSAGE_FLAG_NONE));
 
   MojoHandle h_passed[2];
@@ -917,17 +764,12 @@
 
   // Make sure that |h_passed[]| work properly.
   EXPECT_EQ(MOJO_RESULT_OK,
-            core()->WriteMessage(h_passed[0],
-                                 UserPointer<const void>(kHello),
-                                 kHelloSize,
-                                 NullUserPointer(),
-                                 0,
+            core()->WriteMessage(h_passed[0], UserPointer<const void>(kHello),
+                                 kHelloSize, NullUserPointer(), 0,
                                  MOJO_WRITE_MESSAGE_FLAG_NONE));
   hss = kEmptyMojoHandleSignalsState;
   EXPECT_EQ(MOJO_RESULT_OK,
-            core()->Wait(h_passed[1],
-                         MOJO_HANDLE_SIGNAL_READABLE,
-                         1000000000,
+            core()->Wait(h_passed[1], MOJO_HANDLE_SIGNAL_READABLE, 1000000000,
                          MakeUserPointer(&hss)));
   EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE,
             hss.satisfied_signals);
@@ -936,29 +778,22 @@
   num_bytes = kBufferSize;
   num_handles = arraysize(handles);
   EXPECT_EQ(MOJO_RESULT_OK,
-            core()->ReadMessage(h_passed[1],
-                                UserPointer<void>(buffer),
-                                MakeUserPointer(&num_bytes),
-                                MakeUserPointer(handles),
-                                MakeUserPointer(&num_handles),
-                                MOJO_READ_MESSAGE_FLAG_NONE));
+            core()->ReadMessage(
+                h_passed[1], UserPointer<void>(buffer),
+                MakeUserPointer(&num_bytes), MakeUserPointer(handles),
+                MakeUserPointer(&num_handles), MOJO_READ_MESSAGE_FLAG_NONE));
   EXPECT_EQ(kHelloSize, num_bytes);
   EXPECT_STREQ(kHello, buffer);
   EXPECT_EQ(0u, num_handles);
 
   // Send |h_passed[1]| from |h_passing[0]| to |h_passing[1]|.
   EXPECT_EQ(MOJO_RESULT_OK,
-            core()->WriteMessage(h_passing[0],
-                                 UserPointer<const void>(kWorld),
-                                 kWorldSize,
-                                 MakeUserPointer(&h_passed[1]),
-                                 1,
+            core()->WriteMessage(h_passing[0], UserPointer<const void>(kWorld),
+                                 kWorldSize, MakeUserPointer(&h_passed[1]), 1,
                                  MOJO_WRITE_MESSAGE_FLAG_NONE));
   hss = kEmptyMojoHandleSignalsState;
   EXPECT_EQ(MOJO_RESULT_OK,
-            core()->Wait(h_passing[1],
-                         MOJO_HANDLE_SIGNAL_READABLE,
-                         1000000000,
+            core()->Wait(h_passing[1], MOJO_HANDLE_SIGNAL_READABLE, 1000000000,
                          MakeUserPointer(&hss)));
   EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE,
             hss.satisfied_signals);
@@ -967,12 +802,10 @@
   num_bytes = kBufferSize;
   num_handles = arraysize(handles);
   EXPECT_EQ(MOJO_RESULT_OK,
-            core()->ReadMessage(h_passing[1],
-                                UserPointer<void>(buffer),
-                                MakeUserPointer(&num_bytes),
-                                MakeUserPointer(handles),
-                                MakeUserPointer(&num_handles),
-                                MOJO_READ_MESSAGE_FLAG_NONE));
+            core()->ReadMessage(
+                h_passing[1], UserPointer<void>(buffer),
+                MakeUserPointer(&num_bytes), MakeUserPointer(handles),
+                MakeUserPointer(&num_handles), MOJO_READ_MESSAGE_FLAG_NONE));
   EXPECT_EQ(kWorldSize, num_bytes);
   EXPECT_STREQ(kWorld, buffer);
   EXPECT_EQ(1u, num_handles);
@@ -991,17 +824,12 @@
 
   // Write to |h_passed[0]|. Should receive on |h_received|.
   EXPECT_EQ(MOJO_RESULT_OK,
-            core()->WriteMessage(h_passed[0],
-                                 UserPointer<const void>(kHello),
-                                 kHelloSize,
-                                 NullUserPointer(),
-                                 0,
+            core()->WriteMessage(h_passed[0], UserPointer<const void>(kHello),
+                                 kHelloSize, NullUserPointer(), 0,
                                  MOJO_WRITE_MESSAGE_FLAG_NONE));
   hss = kEmptyMojoHandleSignalsState;
   EXPECT_EQ(MOJO_RESULT_OK,
-            core()->Wait(h_received,
-                         MOJO_HANDLE_SIGNAL_READABLE,
-                         1000000000,
+            core()->Wait(h_received, MOJO_HANDLE_SIGNAL_READABLE, 1000000000,
                          MakeUserPointer(&hss)));
   EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE,
             hss.satisfied_signals);
@@ -1010,12 +838,10 @@
   num_bytes = kBufferSize;
   num_handles = arraysize(handles);
   EXPECT_EQ(MOJO_RESULT_OK,
-            core()->ReadMessage(h_received,
-                                UserPointer<void>(buffer),
-                                MakeUserPointer(&num_bytes),
-                                MakeUserPointer(handles),
-                                MakeUserPointer(&num_handles),
-                                MOJO_READ_MESSAGE_FLAG_NONE));
+            core()->ReadMessage(
+                h_received, UserPointer<void>(buffer),
+                MakeUserPointer(&num_bytes), MakeUserPointer(handles),
+                MakeUserPointer(&num_handles), MOJO_READ_MESSAGE_FLAG_NONE));
   EXPECT_EQ(kHelloSize, num_bytes);
   EXPECT_STREQ(kHello, buffer);
   EXPECT_EQ(0u, num_handles);
@@ -1031,8 +857,8 @@
   MojoHandleSignalsState hss;
 
   EXPECT_EQ(MOJO_RESULT_OK,
-            core()->CreateDataPipe(
-                NullUserPointer(), MakeUserPointer(&ph), MakeUserPointer(&ch)));
+            core()->CreateDataPipe(NullUserPointer(), MakeUserPointer(&ph),
+                                   MakeUserPointer(&ch)));
   // Should get two distinct, valid handles.
   EXPECT_NE(ph, MOJO_HANDLE_INVALID);
   EXPECT_NE(ch, MOJO_HANDLE_INVALID);
@@ -1046,9 +872,8 @@
   EXPECT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE, hss.satisfied_signals);
   EXPECT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE, hss.satisfiable_signals);
   hss = kEmptyMojoHandleSignalsState;
-  EXPECT_EQ(
-      MOJO_RESULT_OK,
-      core()->Wait(ph, MOJO_HANDLE_SIGNAL_WRITABLE, 0, MakeUserPointer(&hss)));
+  EXPECT_EQ(MOJO_RESULT_OK, core()->Wait(ph, MOJO_HANDLE_SIGNAL_WRITABLE, 0,
+                                         MakeUserPointer(&hss)));
   EXPECT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE, hss.satisfied_signals);
   EXPECT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE, hss.satisfiable_signals);
 
@@ -1070,17 +895,15 @@
   char elements[2] = {'A', 'B'};
   uint32_t num_bytes = 2u;
   EXPECT_EQ(MOJO_RESULT_OK,
-            core()->WriteData(ph,
-                              UserPointer<const void>(elements),
+            core()->WriteData(ph, UserPointer<const void>(elements),
                               MakeUserPointer(&num_bytes),
                               MOJO_WRITE_DATA_FLAG_NONE));
   EXPECT_EQ(2u, num_bytes);
 
   // Consumer should now be readable.
   hss = kEmptyMojoHandleSignalsState;
-  EXPECT_EQ(
-      MOJO_RESULT_OK,
-      core()->Wait(ch, MOJO_HANDLE_SIGNAL_READABLE, 0, MakeUserPointer(&hss)));
+  EXPECT_EQ(MOJO_RESULT_OK, core()->Wait(ch, MOJO_HANDLE_SIGNAL_READABLE, 0,
+                                         MakeUserPointer(&hss)));
   EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE, hss.satisfied_signals);
   EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE, hss.satisfiable_signals);
 
@@ -1090,9 +913,7 @@
   num_bytes = 1u;
   EXPECT_EQ(MOJO_RESULT_OK,
             core()->ReadData(
-                ch,
-                UserPointer<void>(elements),
-                MakeUserPointer(&num_bytes),
+                ch, UserPointer<void>(elements), MakeUserPointer(&num_bytes),
                 MOJO_READ_DATA_FLAG_NONE | MOJO_READ_DATA_FLAG_PEEK));
   EXPECT_EQ('A', elements[0]);
   EXPECT_EQ(-1, elements[1]);
@@ -1101,11 +922,9 @@
   elements[0] = -1;
   elements[1] = -1;
   num_bytes = 1u;
-  EXPECT_EQ(MOJO_RESULT_OK,
-            core()->ReadData(ch,
-                             UserPointer<void>(elements),
-                             MakeUserPointer(&num_bytes),
-                             MOJO_READ_DATA_FLAG_NONE));
+  EXPECT_EQ(MOJO_RESULT_OK, core()->ReadData(ch, UserPointer<void>(elements),
+                                             MakeUserPointer(&num_bytes),
+                                             MOJO_READ_DATA_FLAG_NONE));
   EXPECT_EQ('A', elements[0]);
   EXPECT_EQ(-1, elements[1]);
 
@@ -1113,8 +932,7 @@
   void* write_ptr = nullptr;
   num_bytes = 0u;
   ASSERT_EQ(MOJO_RESULT_OK,
-            core()->BeginWriteData(ph,
-                                   MakeUserPointer(&write_ptr),
+            core()->BeginWriteData(ph, MakeUserPointer(&write_ptr),
                                    MakeUserPointer(&num_bytes),
                                    MOJO_WRITE_DATA_FLAG_NONE));
   // We count on the default options providing a decent buffer size.
@@ -1124,8 +942,7 @@
   elements[0] = 'X';
   num_bytes = 1u;
   EXPECT_EQ(MOJO_RESULT_BUSY,
-            core()->WriteData(ph,
-                              UserPointer<const void>(elements),
+            core()->WriteData(ph, UserPointer<const void>(elements),
                               MakeUserPointer(&num_bytes),
                               MOJO_WRITE_DATA_FLAG_NONE));
 
@@ -1138,63 +955,51 @@
   // Query how much data we have.
   num_bytes = 0;
   EXPECT_EQ(MOJO_RESULT_OK,
-            core()->ReadData(ch,
-                             NullUserPointer(),
-                             MakeUserPointer(&num_bytes),
+            core()->ReadData(ch, NullUserPointer(), MakeUserPointer(&num_bytes),
                              MOJO_READ_DATA_FLAG_QUERY));
   EXPECT_EQ(4u, num_bytes);
 
   // Try to query with peek. Should fail.
   num_bytes = 0;
-  EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
-            core()->ReadData(
-                ch,
-                NullUserPointer(),
-                MakeUserPointer(&num_bytes),
-                MOJO_READ_DATA_FLAG_QUERY | MOJO_READ_DATA_FLAG_PEEK));
+  EXPECT_EQ(
+      MOJO_RESULT_INVALID_ARGUMENT,
+      core()->ReadData(ch, NullUserPointer(), MakeUserPointer(&num_bytes),
+                       MOJO_READ_DATA_FLAG_QUERY | MOJO_READ_DATA_FLAG_PEEK));
   EXPECT_EQ(0u, num_bytes);
 
   // Try to discard ten characters, in all-or-none mode. Should fail.
   num_bytes = 10;
   EXPECT_EQ(MOJO_RESULT_OUT_OF_RANGE,
             core()->ReadData(
-                ch,
-                NullUserPointer(),
-                MakeUserPointer(&num_bytes),
+                ch, NullUserPointer(), MakeUserPointer(&num_bytes),
                 MOJO_READ_DATA_FLAG_DISCARD | MOJO_READ_DATA_FLAG_ALL_OR_NONE));
 
   // Try to discard two characters, in peek mode. Should fail.
   num_bytes = 2;
-  EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
-            core()->ReadData(
-                ch,
-                NullUserPointer(),
-                MakeUserPointer(&num_bytes),
-                MOJO_READ_DATA_FLAG_DISCARD | MOJO_READ_DATA_FLAG_PEEK));
+  EXPECT_EQ(
+      MOJO_RESULT_INVALID_ARGUMENT,
+      core()->ReadData(ch, NullUserPointer(), MakeUserPointer(&num_bytes),
+                       MOJO_READ_DATA_FLAG_DISCARD | MOJO_READ_DATA_FLAG_PEEK));
 
   // Discard two characters.
   num_bytes = 2;
   EXPECT_EQ(MOJO_RESULT_OK,
             core()->ReadData(
-                ch,
-                NullUserPointer(),
-                MakeUserPointer(&num_bytes),
+                ch, NullUserPointer(), MakeUserPointer(&num_bytes),
                 MOJO_READ_DATA_FLAG_DISCARD | MOJO_READ_DATA_FLAG_ALL_OR_NONE));
 
   // Try a two-phase read of the remaining two bytes with peek. Should fail.
   const void* read_ptr = nullptr;
   num_bytes = 2;
   ASSERT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
-            core()->BeginReadData(ch,
-                                  MakeUserPointer(&read_ptr),
+            core()->BeginReadData(ch, MakeUserPointer(&read_ptr),
                                   MakeUserPointer(&num_bytes),
                                   MOJO_READ_DATA_FLAG_PEEK));
 
   // Read the remaining two characters, in two-phase mode (all-or-none).
   num_bytes = 2;
   ASSERT_EQ(MOJO_RESULT_OK,
-            core()->BeginReadData(ch,
-                                  MakeUserPointer(&read_ptr),
+            core()->BeginReadData(ch, MakeUserPointer(&read_ptr),
                                   MakeUserPointer(&num_bytes),
                                   MOJO_READ_DATA_FLAG_ALL_OR_NONE));
   // Note: Count on still being able to do the contiguous read here.
@@ -1203,9 +1008,7 @@
   // Discarding right now should fail.
   num_bytes = 1;
   EXPECT_EQ(MOJO_RESULT_BUSY,
-            core()->ReadData(ch,
-                             NullUserPointer(),
-                             MakeUserPointer(&num_bytes),
+            core()->ReadData(ch, NullUserPointer(), MakeUserPointer(&num_bytes),
                              MOJO_READ_DATA_FLAG_DISCARD));
 
   // Actually check our data and end the two-phase read.
@@ -1258,22 +1061,17 @@
 
   MojoHandle ph, ch;
   EXPECT_EQ(MOJO_RESULT_OK,
-            core()->CreateDataPipe(
-                NullUserPointer(), MakeUserPointer(&ph), MakeUserPointer(&ch)));
+            core()->CreateDataPipe(NullUserPointer(), MakeUserPointer(&ph),
+                                   MakeUserPointer(&ch)));
 
   // Send |ch| from |h_passing[0]| to |h_passing[1]|.
   EXPECT_EQ(MOJO_RESULT_OK,
-            core()->WriteMessage(h_passing[0],
-                                 UserPointer<const void>(kHello),
-                                 kHelloSize,
-                                 MakeUserPointer(&ch),
-                                 1,
+            core()->WriteMessage(h_passing[0], UserPointer<const void>(kHello),
+                                 kHelloSize, MakeUserPointer(&ch), 1,
                                  MOJO_WRITE_MESSAGE_FLAG_NONE));
   hss = kEmptyMojoHandleSignalsState;
   EXPECT_EQ(MOJO_RESULT_OK,
-            core()->Wait(h_passing[1],
-                         MOJO_HANDLE_SIGNAL_READABLE,
-                         1000000000,
+            core()->Wait(h_passing[1], MOJO_HANDLE_SIGNAL_READABLE, 1000000000,
                          MakeUserPointer(&hss)));
   EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE,
             hss.satisfied_signals);
@@ -1282,12 +1080,10 @@
   num_bytes = kBufferSize;
   num_handles = arraysize(handles);
   EXPECT_EQ(MOJO_RESULT_OK,
-            core()->ReadMessage(h_passing[1],
-                                UserPointer<void>(buffer),
-                                MakeUserPointer(&num_bytes),
-                                MakeUserPointer(handles),
-                                MakeUserPointer(&num_handles),
-                                MOJO_READ_MESSAGE_FLAG_NONE));
+            core()->ReadMessage(
+                h_passing[1], UserPointer<void>(buffer),
+                MakeUserPointer(&num_bytes), MakeUserPointer(handles),
+                MakeUserPointer(&num_handles), MOJO_READ_MESSAGE_FLAG_NONE));
   EXPECT_EQ(kHelloSize, num_bytes);
   EXPECT_STREQ(kHello, buffer);
   EXPECT_EQ(1u, num_handles);
@@ -1307,22 +1103,18 @@
   // Write to |ph|. Should receive on |ch_received|.
   num_bytes = kWorldSize;
   EXPECT_EQ(MOJO_RESULT_OK,
-            core()->WriteData(ph,
-                              UserPointer<const void>(kWorld),
+            core()->WriteData(ph, UserPointer<const void>(kWorld),
                               MakeUserPointer(&num_bytes),
                               MOJO_WRITE_DATA_FLAG_ALL_OR_NONE));
   hss = kEmptyMojoHandleSignalsState;
   EXPECT_EQ(MOJO_RESULT_OK,
-            core()->Wait(ch_received,
-                         MOJO_HANDLE_SIGNAL_READABLE,
-                         1000000000,
+            core()->Wait(ch_received, MOJO_HANDLE_SIGNAL_READABLE, 1000000000,
                          MakeUserPointer(&hss)));
   EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE, hss.satisfied_signals);
   EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE, hss.satisfiable_signals);
   num_bytes = kBufferSize;
   EXPECT_EQ(MOJO_RESULT_OK,
-            core()->ReadData(ch_received,
-                             UserPointer<void>(buffer),
+            core()->ReadData(ch_received, UserPointer<void>(buffer),
                              MakeUserPointer(&num_bytes),
                              MOJO_READ_MESSAGE_FLAG_NONE));
   EXPECT_EQ(kWorldSize, num_bytes);
@@ -1330,17 +1122,12 @@
 
   // Now pass |ph| in the same direction.
   EXPECT_EQ(MOJO_RESULT_OK,
-            core()->WriteMessage(h_passing[0],
-                                 UserPointer<const void>(kWorld),
-                                 kWorldSize,
-                                 MakeUserPointer(&ph),
-                                 1,
+            core()->WriteMessage(h_passing[0], UserPointer<const void>(kWorld),
+                                 kWorldSize, MakeUserPointer(&ph), 1,
                                  MOJO_WRITE_MESSAGE_FLAG_NONE));
   hss = kEmptyMojoHandleSignalsState;
   EXPECT_EQ(MOJO_RESULT_OK,
-            core()->Wait(h_passing[1],
-                         MOJO_HANDLE_SIGNAL_READABLE,
-                         1000000000,
+            core()->Wait(h_passing[1], MOJO_HANDLE_SIGNAL_READABLE, 1000000000,
                          MakeUserPointer(&hss)));
   EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE,
             hss.satisfied_signals);
@@ -1349,12 +1136,10 @@
   num_bytes = kBufferSize;
   num_handles = arraysize(handles);
   EXPECT_EQ(MOJO_RESULT_OK,
-            core()->ReadMessage(h_passing[1],
-                                UserPointer<void>(buffer),
-                                MakeUserPointer(&num_bytes),
-                                MakeUserPointer(handles),
-                                MakeUserPointer(&num_handles),
-                                MOJO_READ_MESSAGE_FLAG_NONE));
+            core()->ReadMessage(
+                h_passing[1], UserPointer<void>(buffer),
+                MakeUserPointer(&num_bytes), MakeUserPointer(handles),
+                MakeUserPointer(&num_handles), MOJO_READ_MESSAGE_FLAG_NONE));
   EXPECT_EQ(kWorldSize, num_bytes);
   EXPECT_STREQ(kWorld, buffer);
   EXPECT_EQ(1u, num_handles);
@@ -1374,22 +1159,18 @@
   // Write to |ph_received|. Should receive on |ch_received|.
   num_bytes = kHelloSize;
   EXPECT_EQ(MOJO_RESULT_OK,
-            core()->WriteData(ph_received,
-                              UserPointer<const void>(kHello),
+            core()->WriteData(ph_received, UserPointer<const void>(kHello),
                               MakeUserPointer(&num_bytes),
                               MOJO_WRITE_DATA_FLAG_ALL_OR_NONE));
   hss = kEmptyMojoHandleSignalsState;
   EXPECT_EQ(MOJO_RESULT_OK,
-            core()->Wait(ch_received,
-                         MOJO_HANDLE_SIGNAL_READABLE,
-                         1000000000,
+            core()->Wait(ch_received, MOJO_HANDLE_SIGNAL_READABLE, 1000000000,
                          MakeUserPointer(&hss)));
   EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE, hss.satisfied_signals);
   EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE, hss.satisfiable_signals);
   num_bytes = kBufferSize;
   EXPECT_EQ(MOJO_RESULT_OK,
-            core()->ReadData(ch_received,
-                             UserPointer<void>(buffer),
+            core()->ReadData(ch_received, UserPointer<void>(buffer),
                              MakeUserPointer(&num_bytes),
                              MOJO_READ_MESSAGE_FLAG_NONE));
   EXPECT_EQ(kHelloSize, num_bytes);
@@ -1404,42 +1185,31 @@
   void* write_ptr = nullptr;
   num_bytes = 0;
   ASSERT_EQ(MOJO_RESULT_OK,
-            core()->BeginWriteData(ph,
-                                   MakeUserPointer(&write_ptr),
+            core()->BeginWriteData(ph, MakeUserPointer(&write_ptr),
                                    MakeUserPointer(&num_bytes),
                                    MOJO_WRITE_DATA_FLAG_NONE));
   ASSERT_GE(num_bytes, 1u);
   EXPECT_EQ(MOJO_RESULT_BUSY,
-            core()->WriteMessage(h_passing[0],
-                                 UserPointer<const void>(kHello),
-                                 kHelloSize,
-                                 MakeUserPointer(&ph),
-                                 1,
+            core()->WriteMessage(h_passing[0], UserPointer<const void>(kHello),
+                                 kHelloSize, MakeUserPointer(&ph), 1,
                                  MOJO_WRITE_MESSAGE_FLAG_NONE));
 
   // But |ch| can, even if |ph| is in a two-phase write.
   EXPECT_EQ(MOJO_RESULT_OK,
-            core()->WriteMessage(h_passing[0],
-                                 UserPointer<const void>(kHello),
-                                 kHelloSize,
-                                 MakeUserPointer(&ch),
-                                 1,
+            core()->WriteMessage(h_passing[0], UserPointer<const void>(kHello),
+                                 kHelloSize, MakeUserPointer(&ch), 1,
                                  MOJO_WRITE_MESSAGE_FLAG_NONE));
   ch = MOJO_HANDLE_INVALID;
   EXPECT_EQ(MOJO_RESULT_OK,
-            core()->Wait(h_passing[1],
-                         MOJO_HANDLE_SIGNAL_READABLE,
-                         1000000000,
+            core()->Wait(h_passing[1], MOJO_HANDLE_SIGNAL_READABLE, 1000000000,
                          NullUserPointer()));
   num_bytes = kBufferSize;
   num_handles = arraysize(handles);
   EXPECT_EQ(MOJO_RESULT_OK,
-            core()->ReadMessage(h_passing[1],
-                                UserPointer<void>(buffer),
-                                MakeUserPointer(&num_bytes),
-                                MakeUserPointer(handles),
-                                MakeUserPointer(&num_handles),
-                                MOJO_READ_MESSAGE_FLAG_NONE));
+            core()->ReadMessage(
+                h_passing[1], UserPointer<void>(buffer),
+                MakeUserPointer(&num_bytes), MakeUserPointer(handles),
+                MakeUserPointer(&num_handles), MOJO_READ_MESSAGE_FLAG_NONE));
   EXPECT_EQ(kHelloSize, num_bytes);
   EXPECT_STREQ(kHello, buffer);
   EXPECT_EQ(1u, num_handles);
@@ -1452,10 +1222,8 @@
 
   // Wait for |ch| to be readable.
   hss = kEmptyMojoHandleSignalsState;
-  EXPECT_EQ(
-      MOJO_RESULT_OK,
-      core()->Wait(
-          ch, MOJO_HANDLE_SIGNAL_READABLE, 1000000000, MakeUserPointer(&hss)));
+  EXPECT_EQ(MOJO_RESULT_OK, core()->Wait(ch, MOJO_HANDLE_SIGNAL_READABLE,
+                                         1000000000, MakeUserPointer(&hss)));
   EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE, hss.satisfied_signals);
   EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE, hss.satisfiable_signals);
 
@@ -1463,32 +1231,23 @@
   const void* read_ptr = nullptr;
   num_bytes = 1;
   ASSERT_EQ(MOJO_RESULT_OK,
-            core()->BeginReadData(ch,
-                                  MakeUserPointer(&read_ptr),
+            core()->BeginReadData(ch, MakeUserPointer(&read_ptr),
                                   MakeUserPointer(&num_bytes),
                                   MOJO_READ_DATA_FLAG_ALL_OR_NONE));
   EXPECT_EQ(MOJO_RESULT_BUSY,
-            core()->WriteMessage(h_passing[0],
-                                 UserPointer<const void>(kHello),
-                                 kHelloSize,
-                                 MakeUserPointer(&ch),
-                                 1,
+            core()->WriteMessage(h_passing[0], UserPointer<const void>(kHello),
+                                 kHelloSize, MakeUserPointer(&ch), 1,
                                  MOJO_WRITE_MESSAGE_FLAG_NONE));
 
   // But |ph| can, even if |ch| is in a two-phase read.
   EXPECT_EQ(MOJO_RESULT_OK,
-            core()->WriteMessage(h_passing[0],
-                                 UserPointer<const void>(kWorld),
-                                 kWorldSize,
-                                 MakeUserPointer(&ph),
-                                 1,
+            core()->WriteMessage(h_passing[0], UserPointer<const void>(kWorld),
+                                 kWorldSize, MakeUserPointer(&ph), 1,
                                  MOJO_WRITE_MESSAGE_FLAG_NONE));
   ph = MOJO_HANDLE_INVALID;
   hss = kEmptyMojoHandleSignalsState;
   EXPECT_EQ(MOJO_RESULT_OK,
-            core()->Wait(h_passing[1],
-                         MOJO_HANDLE_SIGNAL_READABLE,
-                         1000000000,
+            core()->Wait(h_passing[1], MOJO_HANDLE_SIGNAL_READABLE, 1000000000,
                          MakeUserPointer(&hss)));
   EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE,
             hss.satisfied_signals);
@@ -1497,12 +1256,10 @@
   num_bytes = kBufferSize;
   num_handles = arraysize(handles);
   EXPECT_EQ(MOJO_RESULT_OK,
-            core()->ReadMessage(h_passing[1],
-                                UserPointer<void>(buffer),
-                                MakeUserPointer(&num_bytes),
-                                MakeUserPointer(handles),
-                                MakeUserPointer(&num_handles),
-                                MOJO_READ_MESSAGE_FLAG_NONE));
+            core()->ReadMessage(
+                h_passing[1], UserPointer<void>(buffer),
+                MakeUserPointer(&num_bytes), MakeUserPointer(handles),
+                MakeUserPointer(&num_handles), MOJO_READ_MESSAGE_FLAG_NONE));
   EXPECT_EQ(kWorldSize, num_bytes);
   EXPECT_STREQ(kWorld, buffer);
   EXPECT_EQ(1u, num_handles);
diff --git a/mojo/edk/system/data_pipe.cc b/mojo/edk/system/data_pipe.cc
index e9525bc..cbacb89 100644
--- a/mojo/edk/system/data_pipe.cc
+++ b/mojo/edk/system/data_pipe.cc
@@ -10,7 +10,7 @@
 #include <limits>
 
 #include "base/logging.h"
-#include "mojo/edk/system/constants.h"
+#include "mojo/edk/system/configuration.h"
 #include "mojo/edk/system/memory.h"
 #include "mojo/edk/system/options_validation.h"
 #include "mojo/edk/system/waiter_list.h"
@@ -19,11 +19,15 @@
 namespace system {
 
 // static
-const MojoCreateDataPipeOptions DataPipe::kDefaultCreateOptions = {
-    static_cast<uint32_t>(sizeof(MojoCreateDataPipeOptions)),
-    MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_NONE,
-    1u,
-    static_cast<uint32_t>(kDefaultDataPipeCapacityBytes)};
+MojoCreateDataPipeOptions DataPipe::GetDefaultCreateOptions() {
+  MojoCreateDataPipeOptions result = {
+      static_cast<uint32_t>(sizeof(MojoCreateDataPipeOptions)),
+      MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_NONE,
+      1u,
+      static_cast<uint32_t>(
+          GetConfiguration().default_data_pipe_capacity_bytes)};
+  return result;
+}
 
 // static
 MojoResult DataPipe::ValidateCreateOptions(
@@ -32,7 +36,7 @@
   const MojoCreateDataPipeOptionsFlags kKnownFlags =
       MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_MAY_DISCARD;
 
-  *out_options = kDefaultCreateOptions;
+  *out_options = GetDefaultCreateOptions();
   if (in_options.IsNull())
     return MOJO_RESULT_OK;
 
@@ -48,28 +52,31 @@
 
   // Checks for fields beyond |flags|:
 
-  if (!OPTIONS_STRUCT_HAS_MEMBER(
-          MojoCreateDataPipeOptions, element_num_bytes, reader))
+  if (!OPTIONS_STRUCT_HAS_MEMBER(MojoCreateDataPipeOptions, element_num_bytes,
+                                 reader))
     return MOJO_RESULT_OK;
   if (reader.options().element_num_bytes == 0)
     return MOJO_RESULT_INVALID_ARGUMENT;
   out_options->element_num_bytes = reader.options().element_num_bytes;
 
-  if (!OPTIONS_STRUCT_HAS_MEMBER(
-          MojoCreateDataPipeOptions, capacity_num_bytes, reader) ||
+  if (!OPTIONS_STRUCT_HAS_MEMBER(MojoCreateDataPipeOptions, capacity_num_bytes,
+                                 reader) ||
       reader.options().capacity_num_bytes == 0) {
     // Round the default capacity down to a multiple of the element size (but at
     // least one element).
+    size_t default_data_pipe_capacity_bytes =
+        GetConfiguration().default_data_pipe_capacity_bytes;
     out_options->capacity_num_bytes =
-        std::max(static_cast<uint32_t>(kDefaultDataPipeCapacityBytes -
-                                       (kDefaultDataPipeCapacityBytes %
+        std::max(static_cast<uint32_t>(default_data_pipe_capacity_bytes -
+                                       (default_data_pipe_capacity_bytes %
                                         out_options->element_num_bytes)),
                  out_options->element_num_bytes);
     return MOJO_RESULT_OK;
   }
   if (reader.options().capacity_num_bytes % out_options->element_num_bytes != 0)
     return MOJO_RESULT_INVALID_ARGUMENT;
-  if (reader.options().capacity_num_bytes > kMaxDataPipeCapacityBytes)
+  if (reader.options().capacity_num_bytes >
+      GetConfiguration().max_data_pipe_capacity_bytes)
     return MOJO_RESULT_RESOURCE_EXHAUSTED;
   out_options->capacity_num_bytes = reader.options().capacity_num_bytes;
 
@@ -148,8 +155,8 @@
       return MOJO_RESULT_INVALID_ARGUMENT;
   }
 
-  MojoResult rv = ProducerBeginWriteDataImplNoLock(
-      buffer, buffer_num_bytes, min_num_bytes_to_write);
+  MojoResult rv = ProducerBeginWriteDataImplNoLock(buffer, buffer_num_bytes,
+                                                   min_num_bytes_to_write);
   if (rv != MOJO_RESULT_OK)
     return rv;
   // Note: No need to awake producer waiters, even though we're going from
@@ -345,8 +352,8 @@
       return MOJO_RESULT_INVALID_ARGUMENT;
   }
 
-  MojoResult rv = ConsumerBeginReadDataImplNoLock(
-      buffer, buffer_num_bytes, min_num_bytes_to_read);
+  MojoResult rv = ConsumerBeginReadDataImplNoLock(buffer, buffer_num_bytes,
+                                                  min_num_bytes_to_read);
   if (rv != MOJO_RESULT_OK)
     return rv;
   DCHECK(consumer_in_two_phase_read_no_lock());
diff --git a/mojo/edk/system/data_pipe.h b/mojo/edk/system/data_pipe.h
index d4afdda..767d405 100644
--- a/mojo/edk/system/data_pipe.h
+++ b/mojo/edk/system/data_pipe.h
@@ -35,7 +35,7 @@
   // The default options for |MojoCreateDataPipe()|. (Real uses should obtain
   // this via |ValidateCreateOptions()| with a null |in_options|; this is
   // exposed directly for testing convenience.)
-  static const MojoCreateDataPipeOptions kDefaultCreateOptions;
+  static MojoCreateDataPipeOptions GetDefaultCreateOptions();
 
   // Validates and/or sets default options for |MojoCreateDataPipeOptions|. If
   // non-null, |in_options| must point to a struct of at least
@@ -117,12 +117,11 @@
 
   virtual void ConsumerCloseImplNoLock() = 0;
   // |*num_bytes| will be a nonzero multiple of |element_num_bytes_|.
-  virtual MojoResult ConsumerReadDataImplNoLock(
-      UserPointer<void> elements,
-      UserPointer<uint32_t> num_bytes,
-      uint32_t max_num_bytes_to_read,
-      uint32_t min_num_bytes_to_read,
-      bool peek) = 0;
+  virtual MojoResult ConsumerReadDataImplNoLock(UserPointer<void> elements,
+                                                UserPointer<uint32_t> num_bytes,
+                                                uint32_t max_num_bytes_to_read,
+                                                uint32_t min_num_bytes_to_read,
+                                                bool peek) = 0;
   virtual MojoResult ConsumerDiscardDataImplNoLock(
       UserPointer<uint32_t> num_bytes,
       uint32_t max_num_bytes_to_discard,
diff --git a/mojo/edk/system/data_pipe_consumer_dispatcher.cc b/mojo/edk/system/data_pipe_consumer_dispatcher.cc
index fa103c3..3c14f35 100644
--- a/mojo/edk/system/data_pipe_consumer_dispatcher.cc
+++ b/mojo/edk/system/data_pipe_consumer_dispatcher.cc
@@ -77,9 +77,7 @@
   }
 
   return data_pipe_->ConsumerReadData(
-      elements,
-      num_bytes,
-      !!(flags & MOJO_READ_DATA_FLAG_ALL_OR_NONE),
+      elements, num_bytes, !!(flags & MOJO_READ_DATA_FLAG_ALL_OR_NONE),
       !!(flags & MOJO_READ_DATA_FLAG_PEEK));
 }
 
@@ -91,8 +89,7 @@
 
   // These flags may not be used in two-phase mode.
   if ((flags & MOJO_READ_DATA_FLAG_DISCARD) ||
-      (flags & MOJO_READ_DATA_FLAG_QUERY) ||
-      (flags & MOJO_READ_DATA_FLAG_PEEK))
+      (flags & MOJO_READ_DATA_FLAG_QUERY) || (flags & MOJO_READ_DATA_FLAG_PEEK))
     return MOJO_RESULT_INVALID_ARGUMENT;
 
   return data_pipe_->ConsumerBeginReadData(
diff --git a/mojo/edk/system/data_pipe_unittest.cc b/mojo/edk/system/data_pipe_unittest.cc
index 8d2e4eb..ad02222 100644
--- a/mojo/edk/system/data_pipe_unittest.cc
+++ b/mojo/edk/system/data_pipe_unittest.cc
@@ -9,7 +9,7 @@
 
 #include <limits>
 
-#include "mojo/edk/system/constants.h"
+#include "mojo/edk/system/configuration.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace mojo {
@@ -28,9 +28,8 @@
   // Nothing to check for flags.
   EXPECT_GT(validated_options.element_num_bytes, 0u);
   EXPECT_GT(validated_options.capacity_num_bytes, 0u);
-  EXPECT_EQ(0u,
-            validated_options.capacity_num_bytes %
-                validated_options.element_num_bytes);
+  EXPECT_EQ(0u, validated_options.capacity_num_bytes %
+                    validated_options.element_num_bytes);
 
   MojoCreateDataPipeOptions revalidated_options = {};
   EXPECT_EQ(MOJO_RESULT_OK,
@@ -48,10 +47,10 @@
 // checks done by |RevalidateCreateOptions()|.)
 void CheckDefaultCapacity(const MojoCreateDataPipeOptions& validated_options) {
   EXPECT_LE(validated_options.capacity_num_bytes,
-            kDefaultDataPipeCapacityBytes);
+            GetConfiguration().default_data_pipe_capacity_bytes);
   EXPECT_GT(validated_options.capacity_num_bytes +
                 validated_options.element_num_bytes,
-            kDefaultDataPipeCapacityBytes);
+            GetConfiguration().default_data_pipe_capacity_bytes);
 }
 
 // Tests valid inputs to |ValidateCreateOptions()|.
@@ -59,9 +58,8 @@
   // Default options.
   {
     MojoCreateDataPipeOptions validated_options = {};
-    EXPECT_EQ(
-        MOJO_RESULT_OK,
-        DataPipe::ValidateCreateOptions(NullUserPointer(), &validated_options));
+    EXPECT_EQ(MOJO_RESULT_OK, DataPipe::ValidateCreateOptions(
+                                  NullUserPointer(), &validated_options));
     RevalidateCreateOptions(validated_options);
     CheckDefaultCapacity(validated_options);
   }
diff --git a/mojo/edk/system/dispatcher.cc b/mojo/edk/system/dispatcher.cc
index 5607125..bed5f9e 100644
--- a/mojo/edk/system/dispatcher.cc
+++ b/mojo/edk/system/dispatcher.cc
@@ -5,7 +5,7 @@
 #include "mojo/edk/system/dispatcher.h"
 
 #include "base/logging.h"
-#include "mojo/edk/system/constants.h"
+#include "mojo/edk/system/configuration.h"
 #include "mojo/edk/system/message_pipe_dispatcher.h"
 #include "mojo/edk/system/platform_handle_dispatcher.h"
 #include "mojo/edk/system/shared_buffer_dispatcher.h"
@@ -58,8 +58,8 @@
     size_t* actual_size,
     embedder::PlatformHandleVector* platform_handles) {
   DCHECK(dispatcher);
-  return dispatcher->EndSerializeAndClose(
-      channel, destination, actual_size, platform_handles);
+  return dispatcher->EndSerializeAndClose(channel, destination, actual_size,
+                                          platform_handles);
 }
 
 // static
@@ -72,7 +72,7 @@
   switch (static_cast<int32_t>(type)) {
     case kTypeUnknown:
       DVLOG(2) << "Deserializing invalid handle";
-      return scoped_refptr<Dispatcher>();
+      return nullptr;
     case kTypeMessagePipe:
       return scoped_refptr<Dispatcher>(
           MessagePipeDispatcher::Deserialize(channel, source, size));
@@ -81,7 +81,7 @@
       // TODO(vtl): Implement.
       LOG(WARNING) << "Deserialization of dispatcher type " << type
                    << " not supported";
-      return scoped_refptr<Dispatcher>();
+      return nullptr;
     case kTypeSharedBuffer:
       return scoped_refptr<Dispatcher>(SharedBufferDispatcher::Deserialize(
           channel, source, size, platform_handles));
@@ -90,7 +90,7 @@
           channel, source, size, platform_handles));
   }
   LOG(WARNING) << "Unknown dispatcher type " << type;
-  return scoped_refptr<Dispatcher>();
+  return nullptr;
 }
 
 MojoResult Dispatcher::Close() {
@@ -107,8 +107,9 @@
     uint32_t num_bytes,
     std::vector<DispatcherTransport>* transports,
     MojoWriteMessageFlags flags) {
-  DCHECK(!transports || (transports->size() > 0 &&
-                         transports->size() < kMaxMessageNumHandles));
+  DCHECK(!transports ||
+         (transports->size() > 0 &&
+          transports->size() < GetConfiguration().max_message_num_handles));
 
   base::AutoLock locker(lock_);
   if (is_closed_)
@@ -129,8 +130,8 @@
   if (is_closed_)
     return MOJO_RESULT_INVALID_ARGUMENT;
 
-  return ReadMessageImplNoLock(
-      bytes, num_bytes, dispatchers, num_dispatchers, flags);
+  return ReadMessageImplNoLock(bytes, num_bytes, dispatchers, num_dispatchers,
+                               flags);
 }
 
 MojoResult Dispatcher::WriteData(UserPointer<const void> elements,
@@ -473,8 +474,8 @@
   base::AutoLock locker(lock_);
 #endif
 
-  return EndSerializeAndCloseImplNoLock(
-      channel, destination, actual_size, platform_handles);
+  return EndSerializeAndCloseImplNoLock(channel, destination, actual_size,
+                                        platform_handles);
 }
 
 // DispatcherTransport ---------------------------------------------------------
diff --git a/mojo/edk/system/dispatcher.h b/mojo/edk/system/dispatcher.h
index 8d3edd4..b17bfae 100644
--- a/mojo/edk/system/dispatcher.h
+++ b/mojo/edk/system/dispatcher.h
@@ -14,7 +14,6 @@
 #include "base/memory/ref_counted.h"
 #include "base/memory/scoped_ptr.h"
 #include "base/synchronization/lock.h"
-#include "mojo/edk/embedder/platform_handle.h"
 #include "mojo/edk/embedder/platform_handle_vector.h"
 #include "mojo/edk/system/handle_signals_state.h"
 #include "mojo/edk/system/memory.h"
@@ -48,7 +47,7 @@
 
 // Test helper. We need to declare it here so we can friend it.
 MOJO_SYSTEM_IMPL_EXPORT DispatcherTransport
-    DispatcherTryStartTransport(Dispatcher* dispatcher);
+DispatcherTryStartTransport(Dispatcher* dispatcher);
 
 }  // namespace test
 
diff --git a/mojo/edk/system/dispatcher_unittest.cc b/mojo/edk/system/dispatcher_unittest.cc
index b5a05d4..0b15436 100644
--- a/mojo/edk/system/dispatcher_unittest.cc
+++ b/mojo/edk/system/dispatcher_unittest.cc
@@ -44,31 +44,24 @@
   EXPECT_EQ(Dispatcher::kTypeUnknown, d->GetType());
 
   EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
-            d->WriteMessage(
-                NullUserPointer(), 0, nullptr, MOJO_WRITE_MESSAGE_FLAG_NONE));
+            d->WriteMessage(NullUserPointer(), 0, nullptr,
+                            MOJO_WRITE_MESSAGE_FLAG_NONE));
   EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
-            d->ReadMessage(NullUserPointer(),
-                           NullUserPointer(),
-                           nullptr,
-                           nullptr,
-                           MOJO_WRITE_MESSAGE_FLAG_NONE));
-  EXPECT_EQ(
-      MOJO_RESULT_INVALID_ARGUMENT,
-      d->WriteData(
-          NullUserPointer(), NullUserPointer(), MOJO_WRITE_DATA_FLAG_NONE));
-  EXPECT_EQ(
-      MOJO_RESULT_INVALID_ARGUMENT,
-      d->BeginWriteData(
-          NullUserPointer(), NullUserPointer(), MOJO_WRITE_DATA_FLAG_NONE));
+            d->ReadMessage(NullUserPointer(), NullUserPointer(), nullptr,
+                           nullptr, MOJO_WRITE_MESSAGE_FLAG_NONE));
+  EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
+            d->WriteData(NullUserPointer(), NullUserPointer(),
+                         MOJO_WRITE_DATA_FLAG_NONE));
+  EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
+            d->BeginWriteData(NullUserPointer(), NullUserPointer(),
+                              MOJO_WRITE_DATA_FLAG_NONE));
   EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, d->EndWriteData(0));
-  EXPECT_EQ(
-      MOJO_RESULT_INVALID_ARGUMENT,
-      d->ReadData(
-          NullUserPointer(), NullUserPointer(), MOJO_READ_DATA_FLAG_NONE));
-  EXPECT_EQ(
-      MOJO_RESULT_INVALID_ARGUMENT,
-      d->BeginReadData(
-          NullUserPointer(), NullUserPointer(), MOJO_READ_DATA_FLAG_NONE));
+  EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
+            d->ReadData(NullUserPointer(), NullUserPointer(),
+                        MOJO_READ_DATA_FLAG_NONE));
+  EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
+            d->BeginReadData(NullUserPointer(), NullUserPointer(),
+                             MOJO_READ_DATA_FLAG_NONE));
   EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, d->EndReadData(0));
   Waiter w;
   w.Init();
@@ -90,31 +83,24 @@
   EXPECT_EQ(MOJO_RESULT_OK, d->Close());
 
   EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
-            d->WriteMessage(
-                NullUserPointer(), 0, nullptr, MOJO_WRITE_MESSAGE_FLAG_NONE));
+            d->WriteMessage(NullUserPointer(), 0, nullptr,
+                            MOJO_WRITE_MESSAGE_FLAG_NONE));
   EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
-            d->ReadMessage(NullUserPointer(),
-                           NullUserPointer(),
-                           nullptr,
-                           nullptr,
-                           MOJO_WRITE_MESSAGE_FLAG_NONE));
-  EXPECT_EQ(
-      MOJO_RESULT_INVALID_ARGUMENT,
-      d->WriteData(
-          NullUserPointer(), NullUserPointer(), MOJO_WRITE_DATA_FLAG_NONE));
-  EXPECT_EQ(
-      MOJO_RESULT_INVALID_ARGUMENT,
-      d->BeginWriteData(
-          NullUserPointer(), NullUserPointer(), MOJO_WRITE_DATA_FLAG_NONE));
+            d->ReadMessage(NullUserPointer(), NullUserPointer(), nullptr,
+                           nullptr, MOJO_WRITE_MESSAGE_FLAG_NONE));
+  EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
+            d->WriteData(NullUserPointer(), NullUserPointer(),
+                         MOJO_WRITE_DATA_FLAG_NONE));
+  EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
+            d->BeginWriteData(NullUserPointer(), NullUserPointer(),
+                              MOJO_WRITE_DATA_FLAG_NONE));
   EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, d->EndWriteData(0));
-  EXPECT_EQ(
-      MOJO_RESULT_INVALID_ARGUMENT,
-      d->ReadData(
-          NullUserPointer(), NullUserPointer(), MOJO_READ_DATA_FLAG_NONE));
-  EXPECT_EQ(
-      MOJO_RESULT_INVALID_ARGUMENT,
-      d->BeginReadData(
-          NullUserPointer(), NullUserPointer(), MOJO_READ_DATA_FLAG_NONE));
+  EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
+            d->ReadData(NullUserPointer(), NullUserPointer(),
+                        MOJO_READ_DATA_FLAG_NONE));
+  EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
+            d->BeginReadData(NullUserPointer(), NullUserPointer(),
+                             MOJO_READ_DATA_FLAG_NONE));
   EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, d->EndReadData(0));
   hss = HandleSignalsState();
   EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
@@ -172,45 +158,40 @@
         break;
       }
       case WRITE_MESSAGE:
-        EXPECT_EQ(
-            MOJO_RESULT_INVALID_ARGUMENT,
-            dispatcher_->WriteMessage(
-                NullUserPointer(), 0, nullptr, MOJO_WRITE_MESSAGE_FLAG_NONE));
+        EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
+                  dispatcher_->WriteMessage(NullUserPointer(), 0, nullptr,
+                                            MOJO_WRITE_MESSAGE_FLAG_NONE));
         break;
       case READ_MESSAGE:
         EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
-                  dispatcher_->ReadMessage(NullUserPointer(),
-                                           NullUserPointer(),
-                                           nullptr,
-                                           nullptr,
+                  dispatcher_->ReadMessage(NullUserPointer(), NullUserPointer(),
+                                           nullptr, nullptr,
                                            MOJO_WRITE_MESSAGE_FLAG_NONE));
         break;
       case WRITE_DATA:
         EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
-                  dispatcher_->WriteData(NullUserPointer(),
-                                         NullUserPointer(),
+                  dispatcher_->WriteData(NullUserPointer(), NullUserPointer(),
                                          MOJO_WRITE_DATA_FLAG_NONE));
         break;
       case BEGIN_WRITE_DATA:
-        EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
-                  dispatcher_->BeginWriteData(NullUserPointer(),
-                                              NullUserPointer(),
-                                              MOJO_WRITE_DATA_FLAG_NONE));
+        EXPECT_EQ(
+            MOJO_RESULT_INVALID_ARGUMENT,
+            dispatcher_->BeginWriteData(NullUserPointer(), NullUserPointer(),
+                                        MOJO_WRITE_DATA_FLAG_NONE));
         break;
       case END_WRITE_DATA:
         EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, dispatcher_->EndWriteData(0));
         break;
       case READ_DATA:
         EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
-                  dispatcher_->ReadData(NullUserPointer(),
-                                        NullUserPointer(),
+                  dispatcher_->ReadData(NullUserPointer(), NullUserPointer(),
                                         MOJO_READ_DATA_FLAG_NONE));
         break;
       case BEGIN_READ_DATA:
-        EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
-                  dispatcher_->BeginReadData(NullUserPointer(),
-                                             NullUserPointer(),
-                                             MOJO_READ_DATA_FLAG_NONE));
+        EXPECT_EQ(
+            MOJO_RESULT_INVALID_ARGUMENT,
+            dispatcher_->BeginReadData(NullUserPointer(), NullUserPointer(),
+                                       MOJO_READ_DATA_FLAG_NONE));
         break;
       case END_READ_DATA:
         EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, dispatcher_->EndReadData(0));
diff --git a/mojo/edk/system/entrypoints.h b/mojo/edk/system/entrypoints.h
deleted file mode 100644
index 46c41b4..0000000
--- a/mojo/edk/system/entrypoints.h
+++ /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.
-
-#ifndef MOJO_EDK_SYSTEM_ENTRYPOINTS_H_
-#define MOJO_EDK_SYSTEM_ENTRYPOINTS_H_
-
-namespace mojo {
-namespace system {
-
-class Core;
-
-namespace entrypoints {
-
-// Sets the instance of Core to be used by system functions.
-void SetCore(Core* core);
-// Gets the instance of Core to be used by system functions.
-Core* GetCore();
-
-}  // namespace entrypoints
-}  // namepace system
-}  // namespace mojo
-
-#endif  // MOJO_EDK_SYSTEM_ENTRYPOINTS_H_
diff --git a/mojo/edk/system/handle_table.cc b/mojo/edk/system/handle_table.cc
index 9c01230..05d5260 100644
--- a/mojo/edk/system/handle_table.cc
+++ b/mojo/edk/system/handle_table.cc
@@ -4,9 +4,10 @@
 
 #include "mojo/edk/system/handle_table.h"
 
+#include <limits>
 #include "base/logging.h"
 #include "base/macros.h"
-#include "mojo/edk/system/constants.h"
+#include "mojo/edk/system/configuration.h"
 #include "mojo/edk/system/dispatcher.h"
 
 namespace mojo {
@@ -59,7 +60,7 @@
 
 MojoHandle HandleTable::AddDispatcher(
     const scoped_refptr<Dispatcher>& dispatcher) {
-  if (handle_to_entry_map_.size() >= kMaxHandleTableSize)
+  if (handle_to_entry_map_.size() >= GetConfiguration().max_handle_table_size)
     return MOJO_HANDLE_INVALID;
   return AddDispatcherNoSizeCheck(dispatcher);
 }
@@ -67,7 +68,8 @@
 std::pair<MojoHandle, MojoHandle> HandleTable::AddDispatcherPair(
     const scoped_refptr<Dispatcher>& dispatcher0,
     const scoped_refptr<Dispatcher>& dispatcher1) {
-  if (handle_to_entry_map_.size() + 1 >= kMaxHandleTableSize)
+  if (handle_to_entry_map_.size() + 1 >=
+      GetConfiguration().max_handle_table_size)
     return std::make_pair(MOJO_HANDLE_INVALID, MOJO_HANDLE_INVALID);
   return std::make_pair(AddDispatcherNoSizeCheck(dispatcher0),
                         AddDispatcherNoSizeCheck(dispatcher1));
@@ -75,17 +77,17 @@
 
 bool HandleTable::AddDispatcherVector(const DispatcherVector& dispatchers,
                                       MojoHandle* handles) {
-  DCHECK_LE(dispatchers.size(), kMaxMessageNumHandles);
-  DCHECK(handles);
-  // TODO(vtl): |std::numeric_limits<size_t>::max()| isn't a compile-time
-  // expression in C++03.
-  static_assert(
-      static_cast<uint64_t>(kMaxHandleTableSize) + kMaxMessageNumHandles <
-          (sizeof(size_t) == 8 ? kuint64max
-                               : static_cast<uint64_t>(kuint32max)),
-      "Addition may overflow");
+  size_t max_message_num_handles = GetConfiguration().max_message_num_handles;
+  size_t max_handle_table_size = GetConfiguration().max_handle_table_size;
 
-  if (handle_to_entry_map_.size() + dispatchers.size() > kMaxHandleTableSize)
+  DCHECK_LE(dispatchers.size(), max_message_num_handles);
+  DCHECK(handles);
+  DCHECK_LT(
+      static_cast<uint64_t>(max_handle_table_size) + max_message_num_handles,
+      std::numeric_limits<size_t>::max())
+      << "Addition may overflow";
+
+  if (handle_to_entry_map_.size() + dispatchers.size() > max_handle_table_size)
     return false;
 
   for (size_t i = 0; i < dispatchers.size(); i++) {
@@ -106,7 +108,7 @@
     std::vector<DispatcherTransport>* transports) {
   DCHECK_NE(disallowed_handle, MOJO_HANDLE_INVALID);
   DCHECK(handles);
-  DCHECK_LE(num_handles, kMaxMessageNumHandles);
+  DCHECK_LE(num_handles, GetConfiguration().max_message_num_handles);
   DCHECK(transports);
   DCHECK_EQ(transports->size(), num_handles);
 
@@ -187,7 +189,8 @@
 MojoHandle HandleTable::AddDispatcherNoSizeCheck(
     const scoped_refptr<Dispatcher>& dispatcher) {
   DCHECK(dispatcher.get());
-  DCHECK_LT(handle_to_entry_map_.size(), kMaxHandleTableSize);
+  DCHECK_LT(handle_to_entry_map_.size(),
+            GetConfiguration().max_handle_table_size);
   DCHECK_NE(next_handle_, MOJO_HANDLE_INVALID);
 
   // TODO(vtl): Maybe we want to do something different/smarter. (Or maybe try
@@ -212,7 +215,7 @@
 void HandleTable::RemoveBusyHandles(const MojoHandle* handles,
                                     uint32_t num_handles) {
   DCHECK(handles);
-  DCHECK_LE(num_handles, kMaxMessageNumHandles);
+  DCHECK_LE(num_handles, GetConfiguration().max_message_num_handles);
 
   for (uint32_t i = 0; i < num_handles; i++) {
     HandleToEntryMap::iterator it = handle_to_entry_map_.find(handles[i]);
@@ -226,7 +229,7 @@
 void HandleTable::RestoreBusyHandles(const MojoHandle* handles,
                                      uint32_t num_handles) {
   DCHECK(handles);
-  DCHECK_LE(num_handles, kMaxMessageNumHandles);
+  DCHECK_LE(num_handles, GetConfiguration().max_message_num_handles);
 
   for (uint32_t i = 0; i < num_handles; i++) {
     HandleToEntryMap::iterator it = handle_to_entry_map_.find(handles[i]);
diff --git a/mojo/edk/system/local_data_pipe.cc b/mojo/edk/system/local_data_pipe.cc
index fdfaf28..177b238 100644
--- a/mojo/edk/system/local_data_pipe.cc
+++ b/mojo/edk/system/local_data_pipe.cc
@@ -15,7 +15,7 @@
 #include <algorithm>
 
 #include "base/logging.h"
-#include "mojo/edk/system/constants.h"
+#include "mojo/edk/system/configuration.h"
 
 namespace mojo {
 namespace system {
@@ -301,7 +301,8 @@
   if (buffer_)
     return;
   buffer_.reset(static_cast<char*>(
-      base::AlignedAlloc(capacity_num_bytes(), kDataPipeBufferAlignmentBytes)));
+      base::AlignedAlloc(capacity_num_bytes(),
+                         GetConfiguration().data_pipe_buffer_alignment_bytes)));
 }
 
 void LocalDataPipe::DestroyBufferNoLock() {
diff --git a/mojo/edk/system/local_data_pipe.h b/mojo/edk/system/local_data_pipe.h
index c98cb7e..abe3a46 100644
--- a/mojo/edk/system/local_data_pipe.h
+++ b/mojo/edk/system/local_data_pipe.h
@@ -44,12 +44,11 @@
       uint32_t num_bytes_written) override;
   HandleSignalsState ProducerGetHandleSignalsStateImplNoLock() const override;
   void ConsumerCloseImplNoLock() override;
-  MojoResult ConsumerReadDataImplNoLock(
-      UserPointer<void> elements,
-      UserPointer<uint32_t> num_bytes,
-      uint32_t max_num_bytes_to_read,
-      uint32_t min_num_bytes_to_read,
-      bool peek) override;
+  MojoResult ConsumerReadDataImplNoLock(UserPointer<void> elements,
+                                        UserPointer<uint32_t> num_bytes,
+                                        uint32_t max_num_bytes_to_read,
+                                        uint32_t min_num_bytes_to_read,
+                                        bool peek) override;
   MojoResult ConsumerDiscardDataImplNoLock(
       UserPointer<uint32_t> num_bytes,
       uint32_t max_num_bytes_to_discard,
diff --git a/mojo/edk/system/local_data_pipe_unittest.cc b/mojo/edk/system/local_data_pipe_unittest.cc
index e8bc716..9ba6b21 100644
--- a/mojo/edk/system/local_data_pipe_unittest.cc
+++ b/mojo/edk/system/local_data_pipe_unittest.cc
@@ -25,9 +25,8 @@
   {
     // Get default options.
     MojoCreateDataPipeOptions default_options = {0};
-    EXPECT_EQ(
-        MOJO_RESULT_OK,
-        DataPipe::ValidateCreateOptions(NullUserPointer(), &default_options));
+    EXPECT_EQ(MOJO_RESULT_OK, DataPipe::ValidateCreateOptions(
+                                  NullUserPointer(), &default_options));
     scoped_refptr<LocalDataPipe> dp(new LocalDataPipe(default_options));
     dp->ProducerClose();
     dp->ConsumerClose();
@@ -105,9 +104,8 @@
       1000 * sizeof(int32_t)                    // |capacity_num_bytes|.
   };
   MojoCreateDataPipeOptions validated_options = {0};
-  EXPECT_EQ(MOJO_RESULT_OK,
-            DataPipe::ValidateCreateOptions(MakeUserPointer(&options),
-                                            &validated_options));
+  EXPECT_EQ(MOJO_RESULT_OK, DataPipe::ValidateCreateOptions(
+                                MakeUserPointer(&options), &validated_options));
 
   scoped_refptr<LocalDataPipe> dp(new LocalDataPipe(validated_options));
 
@@ -116,12 +114,9 @@
 
   // Try reading; nothing there yet.
   num_bytes = static_cast<uint32_t>(arraysize(elements) * sizeof(elements[0]));
-  EXPECT_EQ(
-      MOJO_RESULT_SHOULD_WAIT,
-      dp->ConsumerReadData(UserPointer<void>(elements),
-                           MakeUserPointer(&num_bytes),
-                           false,
-                           false));
+  EXPECT_EQ(MOJO_RESULT_SHOULD_WAIT,
+            dp->ConsumerReadData(UserPointer<void>(elements),
+                                 MakeUserPointer(&num_bytes), false, false));
 
   // Query; nothing there yet.
   num_bytes = 0;
@@ -135,12 +130,9 @@
 
   // Read with invalid |num_bytes|.
   num_bytes = sizeof(elements[0]) + 1;
-  EXPECT_EQ(
-      MOJO_RESULT_INVALID_ARGUMENT,
-      dp->ConsumerReadData(UserPointer<void>(elements),
-                           MakeUserPointer(&num_bytes),
-                           false,
-                           false));
+  EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
+            dp->ConsumerReadData(UserPointer<void>(elements),
+                                 MakeUserPointer(&num_bytes), false, false));
 
   // Write two elements.
   elements[0] = 123;
@@ -148,8 +140,7 @@
   num_bytes = static_cast<uint32_t>(2u * sizeof(elements[0]));
   EXPECT_EQ(MOJO_RESULT_OK,
             dp->ProducerWriteData(UserPointer<const void>(elements),
-                                  MakeUserPointer(&num_bytes),
-                                  false));
+                                  MakeUserPointer(&num_bytes), false));
   // It should have written everything (even without "all or none").
   EXPECT_EQ(2u * sizeof(elements[0]), num_bytes);
 
@@ -162,12 +153,9 @@
   elements[0] = -1;
   elements[1] = -1;
   num_bytes = static_cast<uint32_t>(1u * sizeof(elements[0]));
-  EXPECT_EQ(
-      MOJO_RESULT_OK,
-      dp->ConsumerReadData(UserPointer<void>(elements),
-                           MakeUserPointer(&num_bytes),
-                           false,
-                           false));
+  EXPECT_EQ(MOJO_RESULT_OK,
+            dp->ConsumerReadData(UserPointer<void>(elements),
+                                 MakeUserPointer(&num_bytes), false, false));
   EXPECT_EQ(1u * sizeof(elements[0]), num_bytes);
   EXPECT_EQ(123, elements[0]);
   EXPECT_EQ(-1, elements[1]);
@@ -181,12 +169,9 @@
   elements[0] = -1;
   elements[1] = -1;
   num_bytes = static_cast<uint32_t>(1u * sizeof(elements[0]));
-  EXPECT_EQ(
-      MOJO_RESULT_OK,
-      dp->ConsumerReadData(UserPointer<void>(elements),
-                           MakeUserPointer(&num_bytes),
-                           false,
-                           true));
+  EXPECT_EQ(MOJO_RESULT_OK,
+            dp->ConsumerReadData(UserPointer<void>(elements),
+                                 MakeUserPointer(&num_bytes), false, true));
   EXPECT_EQ(1u * sizeof(elements[0]), num_bytes);
   EXPECT_EQ(456, elements[0]);
   EXPECT_EQ(-1, elements[1]);
@@ -200,12 +185,9 @@
   elements[0] = -1;
   elements[1] = -1;
   num_bytes = static_cast<uint32_t>(2u * sizeof(elements[0]));
-  EXPECT_EQ(
-      MOJO_RESULT_OUT_OF_RANGE,
-      dp->ConsumerReadData(UserPointer<void>(elements),
-                           MakeUserPointer(&num_bytes),
-                           true,
-                           false));
+  EXPECT_EQ(MOJO_RESULT_OUT_OF_RANGE,
+            dp->ConsumerReadData(UserPointer<void>(elements),
+                                 MakeUserPointer(&num_bytes), true, false));
   EXPECT_EQ(-1, elements[0]);
   EXPECT_EQ(-1, elements[1]);
 
@@ -213,12 +195,9 @@
   elements[0] = -1;
   elements[1] = -1;
   num_bytes = static_cast<uint32_t>(2u * sizeof(elements[0]));
-  EXPECT_EQ(
-      MOJO_RESULT_OK,
-      dp->ConsumerReadData(UserPointer<void>(elements),
-                           MakeUserPointer(&num_bytes),
-                           false,
-                           false));
+  EXPECT_EQ(MOJO_RESULT_OK,
+            dp->ConsumerReadData(UserPointer<void>(elements),
+                                 MakeUserPointer(&num_bytes), false, false));
   EXPECT_EQ(456, elements[0]);
   EXPECT_EQ(-1, elements[1]);
 
@@ -245,9 +224,8 @@
       2 * sizeof(int32_t)                       // |capacity_num_bytes|.
   };
   MojoCreateDataPipeOptions validated_options = {0};
-  EXPECT_EQ(MOJO_RESULT_OK,
-            DataPipe::ValidateCreateOptions(MakeUserPointer(&options),
-                                            &validated_options));
+  EXPECT_EQ(MOJO_RESULT_OK, DataPipe::ValidateCreateOptions(
+                                MakeUserPointer(&options), &validated_options));
 
   scoped_refptr<LocalDataPipe> dp(new LocalDataPipe(validated_options));
   Waiter waiter;
@@ -275,8 +253,7 @@
   uint32_t num_bytes = static_cast<uint32_t>(2u * sizeof(elements[0]));
   EXPECT_EQ(MOJO_RESULT_OK,
             dp->ProducerWriteData(UserPointer<const void>(elements),
-                                  MakeUserPointer(&num_bytes),
-                                  true));
+                                  MakeUserPointer(&num_bytes), true));
   EXPECT_EQ(static_cast<uint32_t>(2u * sizeof(elements[0])), num_bytes);
 
   // Adding a waiter should now succeed.
@@ -295,12 +272,9 @@
   elements[0] = -1;
   elements[1] = -1;
   num_bytes = static_cast<uint32_t>(1u * sizeof(elements[0]));
-  EXPECT_EQ(
-      MOJO_RESULT_OK,
-      dp->ConsumerReadData(UserPointer<void>(elements),
-                           MakeUserPointer(&num_bytes),
-                           true,
-                           true));
+  EXPECT_EQ(MOJO_RESULT_OK,
+            dp->ConsumerReadData(UserPointer<void>(elements),
+                                 MakeUserPointer(&num_bytes), true, true));
   EXPECT_EQ(static_cast<uint32_t>(1u * sizeof(elements[0])), num_bytes);
   EXPECT_EQ(123, elements[0]);
   EXPECT_EQ(-1, elements[1]);
@@ -327,12 +301,9 @@
   elements[0] = -1;
   elements[1] = -1;
   num_bytes = static_cast<uint32_t>(1u * sizeof(elements[0]));
-  EXPECT_EQ(
-      MOJO_RESULT_OK,
-      dp->ConsumerReadData(UserPointer<void>(elements),
-                           MakeUserPointer(&num_bytes),
-                           true,
-                           false));
+  EXPECT_EQ(MOJO_RESULT_OK,
+            dp->ConsumerReadData(UserPointer<void>(elements),
+                                 MakeUserPointer(&num_bytes), true, false));
   EXPECT_EQ(static_cast<uint32_t>(1u * sizeof(elements[0])), num_bytes);
   EXPECT_EQ(123, elements[0]);
   EXPECT_EQ(-1, elements[1]);
@@ -349,15 +320,14 @@
   void* buffer = nullptr;
   num_bytes = static_cast<uint32_t>(3u * sizeof(elements[0]));
   EXPECT_EQ(MOJO_RESULT_OK,
-            dp->ProducerBeginWriteData(
-                MakeUserPointer(&buffer), MakeUserPointer(&num_bytes), false));
+            dp->ProducerBeginWriteData(MakeUserPointer(&buffer),
+                                       MakeUserPointer(&num_bytes), false));
   EXPECT_TRUE(buffer);
   EXPECT_EQ(static_cast<uint32_t>(1u * sizeof(elements[0])), num_bytes);
 
   static_cast<int32_t*>(buffer)[0] = 789;
-  EXPECT_EQ(MOJO_RESULT_OK,
-            dp->ProducerEndWriteData(
-                static_cast<uint32_t>(1u * sizeof(elements[0]))));
+  EXPECT_EQ(MOJO_RESULT_OK, dp->ProducerEndWriteData(static_cast<uint32_t>(
+                                1u * sizeof(elements[0]))));
 
   // Add a waiter.
   waiter.Init();
@@ -368,10 +338,9 @@
   // Read one element, using a two-phase read.
   const void* read_buffer = nullptr;
   num_bytes = 0u;
-  EXPECT_EQ(
-      MOJO_RESULT_OK,
-      dp->ConsumerBeginReadData(
-          MakeUserPointer(&read_buffer), MakeUserPointer(&num_bytes), false));
+  EXPECT_EQ(MOJO_RESULT_OK,
+            dp->ConsumerBeginReadData(MakeUserPointer(&read_buffer),
+                                      MakeUserPointer(&num_bytes), false));
   EXPECT_TRUE(read_buffer);
   // Since we only read one element (after having written three in all), the
   // two-phase read should only allow us to read one. This checks an
@@ -395,8 +364,7 @@
   num_bytes = static_cast<uint32_t>(1u * sizeof(elements[0]));
   EXPECT_EQ(MOJO_RESULT_OK,
             dp->ProducerWriteData(UserPointer<const void>(elements),
-                                  MakeUserPointer(&num_bytes),
-                                  false));
+                                  MakeUserPointer(&num_bytes), false));
   EXPECT_EQ(static_cast<uint32_t>(1u * sizeof(elements[0])), num_bytes);
 
   // Add a waiter.
@@ -427,9 +395,8 @@
       1000 * sizeof(int32_t)                    // |capacity_num_bytes|.
   };
   MojoCreateDataPipeOptions validated_options = {0};
-  EXPECT_EQ(MOJO_RESULT_OK,
-            DataPipe::ValidateCreateOptions(MakeUserPointer(&options),
-                                            &validated_options));
+  EXPECT_EQ(MOJO_RESULT_OK, DataPipe::ValidateCreateOptions(
+                                MakeUserPointer(&options), &validated_options));
 
   {
     scoped_refptr<LocalDataPipe> dp(new LocalDataPipe(validated_options));
@@ -449,8 +416,8 @@
     // Not yet readable.
     waiter.Init();
     ASSERT_EQ(MOJO_RESULT_OK,
-              dp->ConsumerAddWaiter(
-                  &waiter, MOJO_HANDLE_SIGNAL_READABLE, 34, nullptr));
+              dp->ConsumerAddWaiter(&waiter, MOJO_HANDLE_SIGNAL_READABLE, 34,
+                                    nullptr));
     EXPECT_EQ(MOJO_RESULT_DEADLINE_EXCEEDED, waiter.Wait(0, nullptr));
     hss = HandleSignalsState();
     dp->ConsumerRemoveWaiter(&waiter, &hss);
@@ -462,8 +429,7 @@
     uint32_t num_bytes = static_cast<uint32_t>(2u * sizeof(elements[0]));
     EXPECT_EQ(MOJO_RESULT_OK,
               dp->ProducerWriteData(UserPointer<const void>(elements),
-                                    MakeUserPointer(&num_bytes),
-                                    true));
+                                    MakeUserPointer(&num_bytes), true));
 
     // Should already be readable.
     waiter.Init();
@@ -493,12 +459,9 @@
     elements[0] = -1;
     elements[1] = -1;
     num_bytes = static_cast<uint32_t>(1u * sizeof(elements[0]));
-    EXPECT_EQ(
-        MOJO_RESULT_OK,
-        dp->ConsumerReadData(UserPointer<void>(elements),
-                             MakeUserPointer(&num_bytes),
-                             true,
-                             true));
+    EXPECT_EQ(MOJO_RESULT_OK,
+              dp->ConsumerReadData(UserPointer<void>(elements),
+                                   MakeUserPointer(&num_bytes), true, true));
     EXPECT_EQ(static_cast<uint32_t>(1u * sizeof(elements[0])), num_bytes);
     EXPECT_EQ(456, elements[0]);
     EXPECT_EQ(-1, elements[1]);
@@ -516,12 +479,9 @@
     elements[0] = -1;
     elements[1] = -1;
     num_bytes = static_cast<uint32_t>(1u * sizeof(elements[0]));
-    EXPECT_EQ(
-        MOJO_RESULT_OK,
-        dp->ConsumerReadData(UserPointer<void>(elements),
-                             MakeUserPointer(&num_bytes),
-                             true,
-                             false));
+    EXPECT_EQ(MOJO_RESULT_OK,
+              dp->ConsumerReadData(UserPointer<void>(elements),
+                                   MakeUserPointer(&num_bytes), true, false));
     EXPECT_EQ(static_cast<uint32_t>(1u * sizeof(elements[0])), num_bytes);
     EXPECT_EQ(456, elements[0]);
     EXPECT_EQ(-1, elements[1]);
@@ -529,8 +489,8 @@
     // Adding a waiter should now succeed.
     waiter.Init();
     ASSERT_EQ(MOJO_RESULT_OK,
-              dp->ConsumerAddWaiter(
-                  &waiter, MOJO_HANDLE_SIGNAL_READABLE, 90, nullptr));
+              dp->ConsumerAddWaiter(&waiter, MOJO_HANDLE_SIGNAL_READABLE, 90,
+                                    nullptr));
 
     // Write one element.
     elements[0] = 789;
@@ -538,8 +498,7 @@
     num_bytes = static_cast<uint32_t>(1u * sizeof(elements[0]));
     EXPECT_EQ(MOJO_RESULT_OK,
               dp->ProducerWriteData(UserPointer<const void>(elements),
-                                    MakeUserPointer(&num_bytes),
-                                    true));
+                                    MakeUserPointer(&num_bytes), true));
 
     // Waiting should now succeed.
     EXPECT_EQ(MOJO_RESULT_OK, waiter.Wait(1000, &context));
@@ -565,12 +524,9 @@
     elements[0] = -1;
     elements[1] = -1;
     num_bytes = static_cast<uint32_t>(1u * sizeof(elements[0]));
-    EXPECT_EQ(
-        MOJO_RESULT_OK,
-        dp->ConsumerReadData(UserPointer<void>(elements),
-                             MakeUserPointer(&num_bytes),
-                             true,
-                             false));
+    EXPECT_EQ(MOJO_RESULT_OK,
+              dp->ConsumerReadData(UserPointer<void>(elements),
+                                   MakeUserPointer(&num_bytes), true, false));
     EXPECT_EQ(static_cast<uint32_t>(1u * sizeof(elements[0])), num_bytes);
     EXPECT_EQ(789, elements[0]);
     EXPECT_EQ(-1, elements[1]);
@@ -601,16 +557,15 @@
     // Request room for three (but we'll only write two).
     uint32_t num_bytes = static_cast<uint32_t>(3u * sizeof(elements[0]));
     EXPECT_EQ(MOJO_RESULT_OK,
-              dp->ProducerBeginWriteData(
-                  MakeUserPointer(&buffer), MakeUserPointer(&num_bytes), true));
+              dp->ProducerBeginWriteData(MakeUserPointer(&buffer),
+                                         MakeUserPointer(&num_bytes), true));
     EXPECT_TRUE(buffer);
     EXPECT_GE(num_bytes, static_cast<uint32_t>(3u * sizeof(elements[0])));
     elements = static_cast<int32_t*>(buffer);
     elements[0] = 123;
     elements[1] = 456;
-    EXPECT_EQ(MOJO_RESULT_OK,
-              dp->ProducerEndWriteData(
-                  static_cast<uint32_t>(2u * sizeof(elements[0]))));
+    EXPECT_EQ(MOJO_RESULT_OK, dp->ProducerEndWriteData(static_cast<uint32_t>(
+                                  2u * sizeof(elements[0]))));
 
     // Should already be readable.
     waiter.Init();
@@ -625,17 +580,15 @@
     // Request two in all-or-none mode, but only read one.
     const void* read_buffer = nullptr;
     num_bytes = static_cast<uint32_t>(2u * sizeof(elements[0]));
-    EXPECT_EQ(
-        MOJO_RESULT_OK,
-        dp->ConsumerBeginReadData(
-            MakeUserPointer(&read_buffer), MakeUserPointer(&num_bytes), true));
+    EXPECT_EQ(MOJO_RESULT_OK,
+              dp->ConsumerBeginReadData(MakeUserPointer(&read_buffer),
+                                        MakeUserPointer(&num_bytes), true));
     EXPECT_TRUE(read_buffer);
     EXPECT_EQ(static_cast<uint32_t>(2u * sizeof(elements[0])), num_bytes);
     const int32_t* read_elements = static_cast<const int32_t*>(read_buffer);
     EXPECT_EQ(123, read_elements[0]);
-    EXPECT_EQ(MOJO_RESULT_OK,
-              dp->ConsumerEndReadData(
-                  static_cast<uint32_t>(1u * sizeof(elements[0]))));
+    EXPECT_EQ(MOJO_RESULT_OK, dp->ConsumerEndReadData(static_cast<uint32_t>(
+                                  1u * sizeof(elements[0]))));
 
     // Should still be readable.
     waiter.Init();
@@ -650,23 +603,21 @@
     // Request three, but not in all-or-none mode.
     read_buffer = nullptr;
     num_bytes = static_cast<uint32_t>(3u * sizeof(elements[0]));
-    EXPECT_EQ(
-        MOJO_RESULT_OK,
-        dp->ConsumerBeginReadData(
-            MakeUserPointer(&read_buffer), MakeUserPointer(&num_bytes), false));
+    EXPECT_EQ(MOJO_RESULT_OK,
+              dp->ConsumerBeginReadData(MakeUserPointer(&read_buffer),
+                                        MakeUserPointer(&num_bytes), false));
     EXPECT_TRUE(read_buffer);
     EXPECT_EQ(static_cast<uint32_t>(1u * sizeof(elements[0])), num_bytes);
     read_elements = static_cast<const int32_t*>(read_buffer);
     EXPECT_EQ(456, read_elements[0]);
-    EXPECT_EQ(MOJO_RESULT_OK,
-              dp->ConsumerEndReadData(
-                  static_cast<uint32_t>(1u * sizeof(elements[0]))));
+    EXPECT_EQ(MOJO_RESULT_OK, dp->ConsumerEndReadData(static_cast<uint32_t>(
+                                  1u * sizeof(elements[0]))));
 
     // Adding a waiter should now succeed.
     waiter.Init();
     ASSERT_EQ(MOJO_RESULT_OK,
-              dp->ConsumerAddWaiter(
-                  &waiter, MOJO_HANDLE_SIGNAL_READABLE, 56, nullptr));
+              dp->ConsumerAddWaiter(&waiter, MOJO_HANDLE_SIGNAL_READABLE, 56,
+                                    nullptr));
 
     // Close the producer.
     dp->ProducerClose();
@@ -692,9 +643,8 @@
       1000 * sizeof(int32_t)                    // |capacity_num_bytes|.
   };
   MojoCreateDataPipeOptions validated_options = {0};
-  EXPECT_EQ(MOJO_RESULT_OK,
-            DataPipe::ValidateCreateOptions(MakeUserPointer(&options),
-                                            &validated_options));
+  EXPECT_EQ(MOJO_RESULT_OK, DataPipe::ValidateCreateOptions(
+                                MakeUserPointer(&options), &validated_options));
 
   scoped_refptr<LocalDataPipe> dp(new LocalDataPipe(validated_options));
   Waiter waiter;
@@ -711,10 +661,9 @@
 
   uint32_t num_bytes = static_cast<uint32_t>(1u * sizeof(int32_t));
   void* write_ptr = nullptr;
-  EXPECT_EQ(
-      MOJO_RESULT_OK,
-      dp->ProducerBeginWriteData(
-          MakeUserPointer(&write_ptr), MakeUserPointer(&num_bytes), false));
+  EXPECT_EQ(MOJO_RESULT_OK,
+            dp->ProducerBeginWriteData(MakeUserPointer(&write_ptr),
+                                       MakeUserPointer(&num_bytes), false));
   EXPECT_TRUE(write_ptr);
   EXPECT_GE(num_bytes, static_cast<uint32_t>(1u * sizeof(int32_t)));
 
@@ -741,9 +690,8 @@
   EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE, hss.satisfiable_signals);
 
   static_cast<int32_t*>(write_ptr)[0] = 123;
-  EXPECT_EQ(
-      MOJO_RESULT_OK,
-      dp->ProducerEndWriteData(static_cast<uint32_t>(1u * sizeof(int32_t))));
+  EXPECT_EQ(MOJO_RESULT_OK, dp->ProducerEndWriteData(
+                                static_cast<uint32_t>(1u * sizeof(int32_t))));
 
   // It should be writable again.
   waiter.Init();
@@ -767,10 +715,9 @@
   // middle of it.
   num_bytes = static_cast<uint32_t>(1u * sizeof(int32_t));
   write_ptr = nullptr;
-  EXPECT_EQ(
-      MOJO_RESULT_OK,
-      dp->ProducerBeginWriteData(
-          MakeUserPointer(&write_ptr), MakeUserPointer(&num_bytes), false));
+  EXPECT_EQ(MOJO_RESULT_OK,
+            dp->ProducerBeginWriteData(MakeUserPointer(&write_ptr),
+                                       MakeUserPointer(&num_bytes), false));
   EXPECT_TRUE(write_ptr);
   EXPECT_GE(num_bytes, static_cast<uint32_t>(1u * sizeof(int32_t)));
 
@@ -789,10 +736,9 @@
   // Start a two-phase read.
   num_bytes = static_cast<uint32_t>(1u * sizeof(int32_t));
   const void* read_ptr = nullptr;
-  EXPECT_EQ(
-      MOJO_RESULT_OK,
-      dp->ConsumerBeginReadData(
-          MakeUserPointer(&read_ptr), MakeUserPointer(&num_bytes), false));
+  EXPECT_EQ(MOJO_RESULT_OK,
+            dp->ConsumerBeginReadData(MakeUserPointer(&read_ptr),
+                                      MakeUserPointer(&num_bytes), false));
   EXPECT_TRUE(read_ptr);
   EXPECT_EQ(static_cast<uint32_t>(1u * sizeof(int32_t)), num_bytes);
 
@@ -841,9 +787,8 @@
       1 * sizeof(int32_t)                              // |capacity_num_bytes|.
   };
   MojoCreateDataPipeOptions validated_options = {0};
-  EXPECT_EQ(MOJO_RESULT_OK,
-            DataPipe::ValidateCreateOptions(MakeUserPointer(&options),
-                                            &validated_options));
+  EXPECT_EQ(MOJO_RESULT_OK, DataPipe::ValidateCreateOptions(
+                                MakeUserPointer(&options), &validated_options));
 
   scoped_refptr<LocalDataPipe> dp(new LocalDataPipe(validated_options));
   Waiter waiter;
@@ -873,8 +818,7 @@
   int32_t element = 123;
   EXPECT_EQ(MOJO_RESULT_OK,
             dp->ProducerWriteData(UserPointer<const void>(&element),
-                                  MakeUserPointer(&num_bytes),
-                                  false));
+                                  MakeUserPointer(&num_bytes), false));
   EXPECT_EQ(static_cast<uint32_t>(sizeof(int32_t)), num_bytes);
 
   // Still writable (even though it's full).
@@ -900,8 +844,7 @@
   element = 456;
   EXPECT_EQ(MOJO_RESULT_OK,
             dp->ProducerWriteData(UserPointer<const void>(&element),
-                                  MakeUserPointer(&num_bytes),
-                                  false));
+                                  MakeUserPointer(&num_bytes), false));
   EXPECT_EQ(static_cast<uint32_t>(sizeof(int32_t)), num_bytes);
 
   // Still writable.
@@ -925,12 +868,9 @@
   // Read that element.
   num_bytes = static_cast<uint32_t>(sizeof(int32_t));
   element = 0;
-  EXPECT_EQ(
-      MOJO_RESULT_OK,
-      dp->ConsumerReadData(UserPointer<void>(&element),
-                           MakeUserPointer(&num_bytes),
-                           false,
-                           false));
+  EXPECT_EQ(MOJO_RESULT_OK,
+            dp->ConsumerReadData(UserPointer<void>(&element),
+                                 MakeUserPointer(&num_bytes), false, false));
   EXPECT_EQ(static_cast<uint32_t>(sizeof(int32_t)), num_bytes);
   EXPECT_EQ(456, element);
 
@@ -971,9 +911,8 @@
       10 * sizeof(int32_t)                             // |capacity_num_bytes|.
   };
   MojoCreateDataPipeOptions validated_options = {0};
-  EXPECT_EQ(MOJO_RESULT_OK,
-            DataPipe::ValidateCreateOptions(MakeUserPointer(&options),
-                                            &validated_options));
+  EXPECT_EQ(MOJO_RESULT_OK, DataPipe::ValidateCreateOptions(
+                                MakeUserPointer(&options), &validated_options));
 
   scoped_refptr<LocalDataPipe> dp(new LocalDataPipe(validated_options));
 
@@ -984,10 +923,9 @@
   Seq(0, arraysize(buffer), buffer);
   // Try writing more than capacity. (This test relies on the implementation
   // enforcing the capacity strictly.)
-  EXPECT_EQ(
-      MOJO_RESULT_OK,
-      dp->ProducerWriteData(
-          UserPointer<const void>(buffer), MakeUserPointer(&num_bytes), false));
+  EXPECT_EQ(MOJO_RESULT_OK,
+            dp->ProducerWriteData(UserPointer<const void>(buffer),
+                                  MakeUserPointer(&num_bytes), false));
   EXPECT_EQ(10u * sizeof(int32_t), num_bytes);
 
   // Read half of what we wrote.
@@ -995,9 +933,7 @@
   memset(buffer, 0xab, sizeof(buffer));
   EXPECT_EQ(MOJO_RESULT_OK,
             dp->ConsumerReadData(UserPointer<void>(buffer),
-                                 MakeUserPointer(&num_bytes),
-                                 false,
-                                 false));
+                                 MakeUserPointer(&num_bytes), false, false));
   EXPECT_EQ(5u * sizeof(int32_t), num_bytes);
   int32_t expected_buffer[100];
   memset(expected_buffer, 0xab, sizeof(expected_buffer));
@@ -1009,10 +945,9 @@
   // Write a bit more than the space that's available.
   num_bytes = 8u * sizeof(int32_t);
   Seq(100, arraysize(buffer), buffer);
-  EXPECT_EQ(
-      MOJO_RESULT_OK,
-      dp->ProducerWriteData(
-          UserPointer<const void>(buffer), MakeUserPointer(&num_bytes), false));
+  EXPECT_EQ(MOJO_RESULT_OK,
+            dp->ProducerWriteData(UserPointer<const void>(buffer),
+                                  MakeUserPointer(&num_bytes), false));
   EXPECT_EQ(8u * sizeof(int32_t), num_bytes);
   // Internally, a circular buffer would now look like:
   //   100, 101, 102, 103, 104, 105, 106, 107, 8, 9
@@ -1022,9 +957,7 @@
   memset(buffer, 0xab, sizeof(buffer));
   EXPECT_EQ(MOJO_RESULT_OK,
             dp->ConsumerReadData(UserPointer<void>(buffer),
-                                 MakeUserPointer(&num_bytes),
-                                 false,
-                                 false));
+                                 MakeUserPointer(&num_bytes), false, false));
   EXPECT_EQ(5u * sizeof(int32_t), num_bytes);
   memset(expected_buffer, 0xab, sizeof(expected_buffer));
   expected_buffer[0] = 8;
@@ -1039,10 +972,9 @@
   // Write one integer.
   num_bytes = 1u * sizeof(int32_t);
   Seq(200, arraysize(buffer), buffer);
-  EXPECT_EQ(
-      MOJO_RESULT_OK,
-      dp->ProducerWriteData(
-          UserPointer<const void>(buffer), MakeUserPointer(&num_bytes), false));
+  EXPECT_EQ(MOJO_RESULT_OK,
+            dp->ProducerWriteData(UserPointer<const void>(buffer),
+                                  MakeUserPointer(&num_bytes), false));
   EXPECT_EQ(1u * sizeof(int32_t), num_bytes);
   // Internally, a circular buffer would now look like:
   //   -, -, -, 103, 104, 105, 106, 107, 200, -
@@ -1050,10 +982,9 @@
   // Write five more.
   num_bytes = 5u * sizeof(int32_t);
   Seq(300, arraysize(buffer), buffer);
-  EXPECT_EQ(
-      MOJO_RESULT_OK,
-      dp->ProducerWriteData(
-          UserPointer<const void>(buffer), MakeUserPointer(&num_bytes), false));
+  EXPECT_EQ(MOJO_RESULT_OK,
+            dp->ProducerWriteData(UserPointer<const void>(buffer),
+                                  MakeUserPointer(&num_bytes), false));
   EXPECT_EQ(5u * sizeof(int32_t), num_bytes);
   // Internally, a circular buffer would now look like:
   //   301, 302, 303, 304, 104, 105, 106, 107, 200, 300
@@ -1063,9 +994,7 @@
   memset(buffer, 0xab, sizeof(buffer));
   EXPECT_EQ(MOJO_RESULT_OK,
             dp->ConsumerReadData(UserPointer<void>(buffer),
-                                 MakeUserPointer(&num_bytes),
-                                 false,
-                                 false));
+                                 MakeUserPointer(&num_bytes), false, false));
   EXPECT_EQ(10u * sizeof(int32_t), num_bytes);
   memset(expected_buffer, 0xab, sizeof(expected_buffer));
   expected_buffer[0] = 104;
@@ -1087,10 +1016,9 @@
 
   num_bytes = 0u;
   void* write_ptr = nullptr;
-  EXPECT_EQ(
-      MOJO_RESULT_OK,
-      dp->ProducerBeginWriteData(
-          MakeUserPointer(&write_ptr), MakeUserPointer(&num_bytes), false));
+  EXPECT_EQ(MOJO_RESULT_OK,
+            dp->ProducerBeginWriteData(MakeUserPointer(&write_ptr),
+                                       MakeUserPointer(&num_bytes), false));
   EXPECT_TRUE(write_ptr);
   EXPECT_EQ(6u * sizeof(int32_t), num_bytes);
   Seq(400, 6, static_cast<int32_t*>(write_ptr));
@@ -1102,10 +1030,9 @@
   // mode.
   num_bytes = 6u * sizeof(int32_t);
   write_ptr = nullptr;
-  EXPECT_EQ(
-      MOJO_RESULT_OK,
-      dp->ProducerBeginWriteData(
-          MakeUserPointer(&write_ptr), MakeUserPointer(&num_bytes), false));
+  EXPECT_EQ(MOJO_RESULT_OK,
+            dp->ProducerBeginWriteData(MakeUserPointer(&write_ptr),
+                                       MakeUserPointer(&num_bytes), false));
   EXPECT_EQ(4u * sizeof(int32_t), num_bytes);
   static_cast<int32_t*>(write_ptr)[0] = 500;
   EXPECT_EQ(MOJO_RESULT_OK, dp->ProducerEndWriteData(1u * sizeof(int32_t)));
@@ -1115,19 +1042,17 @@
   // Requesting a 10-element buffer in all-or-none mode fails at this point.
   num_bytes = 10u * sizeof(int32_t);
   write_ptr = nullptr;
-  EXPECT_EQ(
-      MOJO_RESULT_OUT_OF_RANGE,
-      dp->ProducerBeginWriteData(
-          MakeUserPointer(&write_ptr), MakeUserPointer(&num_bytes), true));
+  EXPECT_EQ(MOJO_RESULT_OUT_OF_RANGE,
+            dp->ProducerBeginWriteData(MakeUserPointer(&write_ptr),
+                                       MakeUserPointer(&num_bytes), true));
 
   // But requesting, say, a 5-element (up to 9, really) buffer should be okay.
   // It will discard two elements.
   num_bytes = 5u * sizeof(int32_t);
   write_ptr = nullptr;
-  EXPECT_EQ(
-      MOJO_RESULT_OK,
-      dp->ProducerBeginWriteData(
-          MakeUserPointer(&write_ptr), MakeUserPointer(&num_bytes), true));
+  EXPECT_EQ(MOJO_RESULT_OK,
+            dp->ProducerBeginWriteData(MakeUserPointer(&write_ptr),
+                                       MakeUserPointer(&num_bytes), true));
   EXPECT_EQ(5u * sizeof(int32_t), num_bytes);
   // Only write 4 elements though.
   Seq(600, 4, static_cast<int32_t*>(write_ptr));
@@ -1139,10 +1064,9 @@
   // the internal buffer.
   num_bytes = 5u * sizeof(int32_t);
   write_ptr = nullptr;
-  EXPECT_EQ(
-      MOJO_RESULT_OK,
-      dp->ProducerBeginWriteData(
-          MakeUserPointer(&write_ptr), MakeUserPointer(&num_bytes), true));
+  EXPECT_EQ(MOJO_RESULT_OK,
+            dp->ProducerBeginWriteData(MakeUserPointer(&write_ptr),
+                                       MakeUserPointer(&num_bytes), true));
   EXPECT_EQ(5u * sizeof(int32_t), num_bytes);
   // Only write 3 elements though.
   Seq(700, 3, static_cast<int32_t*>(write_ptr));
@@ -1155,9 +1079,7 @@
   memset(buffer, 0xab, sizeof(buffer));
   EXPECT_EQ(MOJO_RESULT_OK,
             dp->ConsumerReadData(UserPointer<void>(buffer),
-                                 MakeUserPointer(&num_bytes),
-                                 false,
-                                 false));
+                                 MakeUserPointer(&num_bytes), false, false));
   EXPECT_EQ(8u * sizeof(int32_t), num_bytes);
   memset(expected_buffer, 0xab, sizeof(expected_buffer));
   expected_buffer[0] = 500;
@@ -1182,9 +1104,8 @@
       10 * sizeof(int32_t)                      // |capacity_num_bytes|.
   };
   MojoCreateDataPipeOptions validated_options = {0};
-  EXPECT_EQ(MOJO_RESULT_OK,
-            DataPipe::ValidateCreateOptions(MakeUserPointer(&options),
-                                            &validated_options));
+  EXPECT_EQ(MOJO_RESULT_OK, DataPipe::ValidateCreateOptions(
+                                MakeUserPointer(&options), &validated_options));
 
   scoped_refptr<LocalDataPipe> dp(new LocalDataPipe(validated_options));
 
@@ -1192,10 +1113,9 @@
   uint32_t num_bytes = 20u * sizeof(int32_t);
   int32_t buffer[100];
   Seq(0, arraysize(buffer), buffer);
-  EXPECT_EQ(
-      MOJO_RESULT_OUT_OF_RANGE,
-      dp->ProducerWriteData(
-          UserPointer<const void>(buffer), MakeUserPointer(&num_bytes), true));
+  EXPECT_EQ(MOJO_RESULT_OUT_OF_RANGE,
+            dp->ProducerWriteData(UserPointer<const void>(buffer),
+                                  MakeUserPointer(&num_bytes), true));
 
   // Should still be empty.
   num_bytes = ~0u;
@@ -1205,10 +1125,9 @@
   // Write some data.
   num_bytes = 5u * sizeof(int32_t);
   Seq(100, arraysize(buffer), buffer);
-  EXPECT_EQ(
-      MOJO_RESULT_OK,
-      dp->ProducerWriteData(
-          UserPointer<const void>(buffer), MakeUserPointer(&num_bytes), true));
+  EXPECT_EQ(MOJO_RESULT_OK,
+            dp->ProducerWriteData(UserPointer<const void>(buffer),
+                                  MakeUserPointer(&num_bytes), true));
   EXPECT_EQ(5u * sizeof(int32_t), num_bytes);
 
   // Half full.
@@ -1219,19 +1138,16 @@
   // Too much.
   num_bytes = 6u * sizeof(int32_t);
   Seq(200, arraysize(buffer), buffer);
-  EXPECT_EQ(
-      MOJO_RESULT_OUT_OF_RANGE,
-      dp->ProducerWriteData(
-          UserPointer<const void>(buffer), MakeUserPointer(&num_bytes), true));
+  EXPECT_EQ(MOJO_RESULT_OUT_OF_RANGE,
+            dp->ProducerWriteData(UserPointer<const void>(buffer),
+                                  MakeUserPointer(&num_bytes), true));
 
   // Try reading too much.
   num_bytes = 11u * sizeof(int32_t);
   memset(buffer, 0xab, sizeof(buffer));
   EXPECT_EQ(MOJO_RESULT_OUT_OF_RANGE,
             dp->ConsumerReadData(UserPointer<void>(buffer),
-                                 MakeUserPointer(&num_bytes),
-                                 true,
-                                 false));
+                                 MakeUserPointer(&num_bytes), true, false));
   int32_t expected_buffer[100];
   memset(expected_buffer, 0xab, sizeof(expected_buffer));
   EXPECT_EQ(0, memcmp(buffer, expected_buffer, sizeof(buffer)));
@@ -1244,19 +1160,17 @@
   // Just a little.
   num_bytes = 2u * sizeof(int32_t);
   Seq(300, arraysize(buffer), buffer);
-  EXPECT_EQ(
-      MOJO_RESULT_OK,
-      dp->ProducerWriteData(
-          UserPointer<const void>(buffer), MakeUserPointer(&num_bytes), true));
+  EXPECT_EQ(MOJO_RESULT_OK,
+            dp->ProducerWriteData(UserPointer<const void>(buffer),
+                                  MakeUserPointer(&num_bytes), true));
   EXPECT_EQ(2u * sizeof(int32_t), num_bytes);
 
   // Just right.
   num_bytes = 3u * sizeof(int32_t);
   Seq(400, arraysize(buffer), buffer);
-  EXPECT_EQ(
-      MOJO_RESULT_OK,
-      dp->ProducerWriteData(
-          UserPointer<const void>(buffer), MakeUserPointer(&num_bytes), true));
+  EXPECT_EQ(MOJO_RESULT_OK,
+            dp->ProducerWriteData(UserPointer<const void>(buffer),
+                                  MakeUserPointer(&num_bytes), true));
   EXPECT_EQ(3u * sizeof(int32_t), num_bytes);
 
   // Exactly full.
@@ -1269,9 +1183,7 @@
   memset(buffer, 0xab, sizeof(buffer));
   EXPECT_EQ(MOJO_RESULT_OK,
             dp->ConsumerReadData(UserPointer<void>(buffer),
-                                 MakeUserPointer(&num_bytes),
-                                 true,
-                                 false));
+                                 MakeUserPointer(&num_bytes), true, false));
   EXPECT_EQ(5u * sizeof(int32_t), num_bytes);
   memset(expected_buffer, 0xab, sizeof(expected_buffer));
   Seq(100, 5, expected_buffer);
@@ -1282,9 +1194,7 @@
   memset(buffer, 0xab, sizeof(buffer));
   EXPECT_EQ(MOJO_RESULT_OUT_OF_RANGE,
             dp->ConsumerReadData(UserPointer<void>(buffer),
-                                 MakeUserPointer(&num_bytes),
-                                 true,
-                                 false));
+                                 MakeUserPointer(&num_bytes), true, false));
   memset(expected_buffer, 0xab, sizeof(expected_buffer));
   EXPECT_EQ(0, memcmp(buffer, expected_buffer, sizeof(buffer)));
 
@@ -1312,9 +1222,7 @@
   memset(buffer, 0xab, sizeof(buffer));
   EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION,
             dp->ConsumerReadData(UserPointer<void>(buffer),
-                                 MakeUserPointer(&num_bytes),
-                                 true,
-                                 false));
+                                 MakeUserPointer(&num_bytes), true, false));
   memset(expected_buffer, 0xab, sizeof(expected_buffer));
   EXPECT_EQ(0, memcmp(buffer, expected_buffer, sizeof(buffer)));
 
@@ -1328,9 +1236,7 @@
   memset(buffer, 0xab, sizeof(buffer));
   EXPECT_EQ(MOJO_RESULT_OK,
             dp->ConsumerReadData(UserPointer<void>(buffer),
-                                 MakeUserPointer(&num_bytes),
-                                 true,
-                                 false));
+                                 MakeUserPointer(&num_bytes), true, false));
   EXPECT_EQ(2u * sizeof(int32_t), num_bytes);
   memset(expected_buffer, 0xab, sizeof(expected_buffer));
   Seq(400, 2, expected_buffer);
@@ -1358,9 +1264,8 @@
       10 * sizeof(int32_t)                             // |capacity_num_bytes|.
   };
   MojoCreateDataPipeOptions validated_options = {0};
-  EXPECT_EQ(MOJO_RESULT_OK,
-            DataPipe::ValidateCreateOptions(MakeUserPointer(&options),
-                                            &validated_options));
+  EXPECT_EQ(MOJO_RESULT_OK, DataPipe::ValidateCreateOptions(
+                                MakeUserPointer(&options), &validated_options));
 
   scoped_refptr<LocalDataPipe> dp(new LocalDataPipe(validated_options));
 
@@ -1368,27 +1273,24 @@
   uint32_t num_bytes = 20u * sizeof(int32_t);
   int32_t buffer[100];
   Seq(0, arraysize(buffer), buffer);
-  EXPECT_EQ(
-      MOJO_RESULT_OUT_OF_RANGE,
-      dp->ProducerWriteData(
-          UserPointer<const void>(buffer), MakeUserPointer(&num_bytes), true));
+  EXPECT_EQ(MOJO_RESULT_OUT_OF_RANGE,
+            dp->ProducerWriteData(UserPointer<const void>(buffer),
+                                  MakeUserPointer(&num_bytes), true));
 
   // Write some stuff.
   num_bytes = 5u * sizeof(int32_t);
   Seq(100, arraysize(buffer), buffer);
-  EXPECT_EQ(
-      MOJO_RESULT_OK,
-      dp->ProducerWriteData(
-          UserPointer<const void>(buffer), MakeUserPointer(&num_bytes), true));
+  EXPECT_EQ(MOJO_RESULT_OK,
+            dp->ProducerWriteData(UserPointer<const void>(buffer),
+                                  MakeUserPointer(&num_bytes), true));
   EXPECT_EQ(5u * sizeof(int32_t), num_bytes);
 
   // Write lots of stuff (discarding all but "104").
   num_bytes = 9u * sizeof(int32_t);
   Seq(200, arraysize(buffer), buffer);
-  EXPECT_EQ(
-      MOJO_RESULT_OK,
-      dp->ProducerWriteData(
-          UserPointer<const void>(buffer), MakeUserPointer(&num_bytes), true));
+  EXPECT_EQ(MOJO_RESULT_OK,
+            dp->ProducerWriteData(UserPointer<const void>(buffer),
+                                  MakeUserPointer(&num_bytes), true));
   EXPECT_EQ(9u * sizeof(int32_t), num_bytes);
 
   // Read one.
@@ -1396,9 +1298,7 @@
   memset(buffer, 0xab, sizeof(buffer));
   EXPECT_EQ(MOJO_RESULT_OK,
             dp->ConsumerReadData(UserPointer<void>(buffer),
-                                 MakeUserPointer(&num_bytes),
-                                 true,
-                                 false));
+                                 MakeUserPointer(&num_bytes), true, false));
   EXPECT_EQ(1u * sizeof(int32_t), num_bytes);
   int32_t expected_buffer[100];
   memset(expected_buffer, 0xab, sizeof(expected_buffer));
@@ -1410,9 +1310,7 @@
   memset(buffer, 0xab, sizeof(buffer));
   EXPECT_EQ(MOJO_RESULT_OUT_OF_RANGE,
             dp->ConsumerReadData(UserPointer<void>(buffer),
-                                 MakeUserPointer(&num_bytes),
-                                 true,
-                                 false));
+                                 MakeUserPointer(&num_bytes), true, false));
   memset(expected_buffer, 0xab, sizeof(expected_buffer));
   EXPECT_EQ(0, memcmp(buffer, expected_buffer, sizeof(buffer)));
 
@@ -1434,10 +1332,9 @@
   // Write as much as possible.
   num_bytes = 10u * sizeof(int32_t);
   Seq(300, arraysize(buffer), buffer);
-  EXPECT_EQ(
-      MOJO_RESULT_OK,
-      dp->ProducerWriteData(
-          UserPointer<const void>(buffer), MakeUserPointer(&num_bytes), true));
+  EXPECT_EQ(MOJO_RESULT_OK,
+            dp->ProducerWriteData(UserPointer<const void>(buffer),
+                                  MakeUserPointer(&num_bytes), true));
   EXPECT_EQ(10u * sizeof(int32_t), num_bytes);
 
   // Read everything.
@@ -1445,9 +1342,7 @@
   memset(buffer, 0xab, sizeof(buffer));
   EXPECT_EQ(MOJO_RESULT_OK,
             dp->ConsumerReadData(UserPointer<void>(buffer),
-                                 MakeUserPointer(&num_bytes),
-                                 true,
-                                 false));
+                                 MakeUserPointer(&num_bytes), true, false));
   memset(expected_buffer, 0xab, sizeof(expected_buffer));
   EXPECT_EQ(10u * sizeof(int32_t), num_bytes);
   Seq(300, 10, expected_buffer);
@@ -1468,44 +1363,40 @@
       10 * sizeof(int32_t)                      // |capacity_num_bytes|.
   };
   MojoCreateDataPipeOptions validated_options = {0};
-  EXPECT_EQ(MOJO_RESULT_OK,
-            DataPipe::ValidateCreateOptions(MakeUserPointer(&options),
-                                            &validated_options));
+  EXPECT_EQ(MOJO_RESULT_OK, DataPipe::ValidateCreateOptions(
+                                MakeUserPointer(&options), &validated_options));
 
   scoped_refptr<LocalDataPipe> dp(new LocalDataPipe(validated_options));
 
   // Try writing way too much (two-phase).
   uint32_t num_bytes = 20u * sizeof(int32_t);
   void* write_ptr = nullptr;
-  EXPECT_EQ(
-      MOJO_RESULT_OUT_OF_RANGE,
-      dp->ProducerBeginWriteData(
-          MakeUserPointer(&write_ptr), MakeUserPointer(&num_bytes), true));
+  EXPECT_EQ(MOJO_RESULT_OUT_OF_RANGE,
+            dp->ProducerBeginWriteData(MakeUserPointer(&write_ptr),
+                                       MakeUserPointer(&num_bytes), true));
 
   // Try writing an amount which isn't a multiple of the element size
   // (two-phase).
   static_assert(sizeof(int32_t) > 1u, "Wow! int32_t's have size 1");
   num_bytes = 1u;
   write_ptr = nullptr;
-  EXPECT_EQ(
-      MOJO_RESULT_INVALID_ARGUMENT,
-      dp->ProducerBeginWriteData(
-          MakeUserPointer(&write_ptr), MakeUserPointer(&num_bytes), true));
+  EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
+            dp->ProducerBeginWriteData(MakeUserPointer(&write_ptr),
+                                       MakeUserPointer(&num_bytes), true));
 
   // Try reading way too much (two-phase).
   num_bytes = 20u * sizeof(int32_t);
   const void* read_ptr = nullptr;
   EXPECT_EQ(MOJO_RESULT_OUT_OF_RANGE,
-            dp->ConsumerBeginReadData(
-                MakeUserPointer(&read_ptr), MakeUserPointer(&num_bytes), true));
+            dp->ConsumerBeginReadData(MakeUserPointer(&read_ptr),
+                                      MakeUserPointer(&num_bytes), true));
 
   // Write half (two-phase).
   num_bytes = 5u * sizeof(int32_t);
   write_ptr = nullptr;
-  EXPECT_EQ(
-      MOJO_RESULT_OK,
-      dp->ProducerBeginWriteData(
-          MakeUserPointer(&write_ptr), MakeUserPointer(&num_bytes), true));
+  EXPECT_EQ(MOJO_RESULT_OK,
+            dp->ProducerBeginWriteData(MakeUserPointer(&write_ptr),
+                                       MakeUserPointer(&num_bytes), true));
   // May provide more space than requested.
   EXPECT_GE(num_bytes, 5u * sizeof(int32_t));
   EXPECT_TRUE(write_ptr);
@@ -1517,15 +1408,15 @@
   num_bytes = 1u;
   read_ptr = nullptr;
   EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
-            dp->ConsumerBeginReadData(
-                MakeUserPointer(&read_ptr), MakeUserPointer(&num_bytes), true));
+            dp->ConsumerBeginReadData(MakeUserPointer(&read_ptr),
+                                      MakeUserPointer(&num_bytes), true));
 
   // Read one (two-phase).
   num_bytes = 1u * sizeof(int32_t);
   read_ptr = nullptr;
   EXPECT_EQ(MOJO_RESULT_OK,
-            dp->ConsumerBeginReadData(
-                MakeUserPointer(&read_ptr), MakeUserPointer(&num_bytes), true));
+            dp->ConsumerBeginReadData(MakeUserPointer(&read_ptr),
+                                      MakeUserPointer(&num_bytes), true));
   EXPECT_GE(num_bytes, 1u * sizeof(int32_t));
   EXPECT_EQ(0, static_cast<const int32_t*>(read_ptr)[0]);
   EXPECT_EQ(MOJO_RESULT_OK, dp->ConsumerEndReadData(1u * sizeof(int32_t)));
@@ -1539,19 +1430,17 @@
   // two-phase write of six now.
   num_bytes = 6u * sizeof(int32_t);
   write_ptr = nullptr;
-  EXPECT_EQ(
-      MOJO_RESULT_OUT_OF_RANGE,
-      dp->ProducerBeginWriteData(
-          MakeUserPointer(&write_ptr), MakeUserPointer(&num_bytes), true));
+  EXPECT_EQ(MOJO_RESULT_OUT_OF_RANGE,
+            dp->ProducerBeginWriteData(MakeUserPointer(&write_ptr),
+                                       MakeUserPointer(&num_bytes), true));
 
   // Write six elements (simple), filling the buffer.
   num_bytes = 6u * sizeof(int32_t);
   int32_t buffer[100];
   Seq(100, 6, buffer);
-  EXPECT_EQ(
-      MOJO_RESULT_OK,
-      dp->ProducerWriteData(
-          UserPointer<const void>(buffer), MakeUserPointer(&num_bytes), true));
+  EXPECT_EQ(MOJO_RESULT_OK,
+            dp->ProducerWriteData(UserPointer<const void>(buffer),
+                                  MakeUserPointer(&num_bytes), true));
   EXPECT_EQ(6u * sizeof(int32_t), num_bytes);
 
   // We have ten.
@@ -1563,8 +1452,8 @@
   num_bytes = 10u * sizeof(int32_t);
   read_ptr = nullptr;
   EXPECT_EQ(MOJO_RESULT_OUT_OF_RANGE,
-            dp->ConsumerBeginReadData(
-                MakeUserPointer(&read_ptr), MakeUserPointer(&num_bytes), true));
+            dp->ConsumerBeginReadData(MakeUserPointer(&read_ptr),
+                                      MakeUserPointer(&num_bytes), true));
 
   // Close the producer.
   dp->ProducerClose();
@@ -1573,8 +1462,8 @@
   num_bytes = 9u * sizeof(int32_t);
   read_ptr = nullptr;
   EXPECT_EQ(MOJO_RESULT_OK,
-            dp->ConsumerBeginReadData(
-                MakeUserPointer(&read_ptr), MakeUserPointer(&num_bytes), true));
+            dp->ConsumerBeginReadData(MakeUserPointer(&read_ptr),
+                                      MakeUserPointer(&num_bytes), true));
   EXPECT_GE(num_bytes, 9u * sizeof(int32_t));
   EXPECT_EQ(1, static_cast<const int32_t*>(read_ptr)[0]);
   EXPECT_EQ(2, static_cast<const int32_t*>(read_ptr)[1]);
@@ -1591,8 +1480,8 @@
   num_bytes = 2u * sizeof(int32_t);
   read_ptr = nullptr;
   EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION,
-            dp->ConsumerBeginReadData(
-                MakeUserPointer(&read_ptr), MakeUserPointer(&num_bytes), true));
+            dp->ConsumerBeginReadData(MakeUserPointer(&read_ptr),
+                                      MakeUserPointer(&num_bytes), true));
 
   dp->ConsumerClose();
 }
@@ -1613,9 +1502,8 @@
       100u                                      // |capacity_num_bytes|.
   };
   MojoCreateDataPipeOptions validated_options = {0};
-  EXPECT_EQ(MOJO_RESULT_OK,
-            DataPipe::ValidateCreateOptions(MakeUserPointer(&options),
-                                            &validated_options));
+  EXPECT_EQ(MOJO_RESULT_OK, DataPipe::ValidateCreateOptions(
+                                MakeUserPointer(&options), &validated_options));
   // This test won't be valid if |ValidateCreateOptions()| decides to give the
   // pipe more space.
   ASSERT_EQ(100u, validated_options.capacity_num_bytes);
@@ -1626,19 +1514,15 @@
   uint32_t num_bytes = 20u;
   EXPECT_EQ(MOJO_RESULT_OK,
             dp->ProducerWriteData(UserPointer<const void>(&test_data[0]),
-                                  MakeUserPointer(&num_bytes),
-                                  false));
+                                  MakeUserPointer(&num_bytes), false));
   EXPECT_EQ(20u, num_bytes);
 
   // Read 10 bytes.
   unsigned char read_buffer[1000] = {0};
   num_bytes = 10u;
-  EXPECT_EQ(
-      MOJO_RESULT_OK,
-      dp->ConsumerReadData(UserPointer<void>(read_buffer),
-                           MakeUserPointer(&num_bytes),
-                           false,
-                           false));
+  EXPECT_EQ(MOJO_RESULT_OK,
+            dp->ConsumerReadData(UserPointer<void>(read_buffer),
+                                 MakeUserPointer(&num_bytes), false, false));
   EXPECT_EQ(10u, num_bytes);
   EXPECT_EQ(0, memcmp(read_buffer, &test_data[0], 10u));
 
@@ -1649,8 +1533,7 @@
   num_bytes = 0u;
   EXPECT_EQ(MOJO_RESULT_OK,
             dp->ProducerBeginWriteData(MakeUserPointer(&write_buffer_ptr),
-                                       MakeUserPointer(&num_bytes),
-                                       false));
+                                       MakeUserPointer(&num_bytes), false));
   EXPECT_TRUE(write_buffer_ptr);
   EXPECT_EQ(80u, num_bytes);
   EXPECT_EQ(MOJO_RESULT_OK, dp->ProducerEndWriteData(0u));
@@ -1660,8 +1543,7 @@
   num_bytes = 200u;
   EXPECT_EQ(MOJO_RESULT_OK,
             dp->ProducerWriteData(UserPointer<const void>(&test_data[20]),
-                                  MakeUserPointer(&num_bytes),
-                                  false));
+                                  MakeUserPointer(&num_bytes), false));
   EXPECT_EQ(90u, num_bytes);
 
   // Check that a two-phase read can now only read (at most) 90 bytes. (This
@@ -1671,8 +1553,7 @@
   num_bytes = 0u;
   EXPECT_EQ(MOJO_RESULT_OK,
             dp->ConsumerBeginReadData(MakeUserPointer(&read_buffer_ptr),
-                                      MakeUserPointer(&num_bytes),
-                                      false));
+                                      MakeUserPointer(&num_bytes), false));
   EXPECT_TRUE(read_buffer_ptr);
   EXPECT_EQ(90u, num_bytes);
   EXPECT_EQ(MOJO_RESULT_OK, dp->ConsumerEndReadData(0u));
@@ -1682,12 +1563,9 @@
   num_bytes =
       static_cast<uint32_t>(arraysize(read_buffer) * sizeof(read_buffer[0]));
   memset(read_buffer, 0, num_bytes);
-  EXPECT_EQ(
-      MOJO_RESULT_OK,
-      dp->ConsumerReadData(UserPointer<void>(read_buffer),
-                           MakeUserPointer(&num_bytes),
-                           false,
-                           false));
+  EXPECT_EQ(MOJO_RESULT_OK,
+            dp->ConsumerReadData(UserPointer<void>(read_buffer),
+                                 MakeUserPointer(&num_bytes), false, false));
   EXPECT_EQ(100u, num_bytes);
   EXPECT_EQ(0, memcmp(read_buffer, &test_data[10], 100u));
 
@@ -1708,9 +1586,8 @@
       1000u                                     // |capacity_num_bytes|.
   };
   MojoCreateDataPipeOptions validated_options = {0};
-  EXPECT_EQ(MOJO_RESULT_OK,
-            DataPipe::ValidateCreateOptions(MakeUserPointer(&options),
-                                            &validated_options));
+  EXPECT_EQ(MOJO_RESULT_OK, DataPipe::ValidateCreateOptions(
+                                MakeUserPointer(&options), &validated_options));
 
   // Close producer first, then consumer.
   {
@@ -1720,16 +1597,14 @@
     uint32_t num_bytes = kTestDataSize;
     EXPECT_EQ(MOJO_RESULT_OK,
               dp->ProducerWriteData(UserPointer<const void>(kTestData),
-                                    MakeUserPointer(&num_bytes),
-                                    false));
+                                    MakeUserPointer(&num_bytes), false));
     EXPECT_EQ(kTestDataSize, num_bytes);
 
     // Write it again, so we'll have something left over.
     num_bytes = kTestDataSize;
     EXPECT_EQ(MOJO_RESULT_OK,
               dp->ProducerWriteData(UserPointer<const void>(kTestData),
-                                    MakeUserPointer(&num_bytes),
-                                    false));
+                                    MakeUserPointer(&num_bytes), false));
     EXPECT_EQ(kTestDataSize, num_bytes);
 
     // Start two-phase write.
@@ -1737,8 +1612,7 @@
     num_bytes = 0u;
     EXPECT_EQ(MOJO_RESULT_OK,
               dp->ProducerBeginWriteData(MakeUserPointer(&write_buffer_ptr),
-                                         MakeUserPointer(&num_bytes),
-                                         false));
+                                         MakeUserPointer(&num_bytes), false));
     EXPECT_TRUE(write_buffer_ptr);
     EXPECT_GT(num_bytes, 0u);
 
@@ -1747,8 +1621,7 @@
     num_bytes = 0u;
     EXPECT_EQ(MOJO_RESULT_OK,
               dp->ConsumerBeginReadData(MakeUserPointer(&read_buffer_ptr),
-                                        MakeUserPointer(&num_bytes),
-                                        false));
+                                        MakeUserPointer(&num_bytes), false));
     EXPECT_TRUE(read_buffer_ptr);
     EXPECT_EQ(2u * kTestDataSize, num_bytes);
 
@@ -1764,8 +1637,7 @@
     num_bytes = 0u;
     EXPECT_EQ(MOJO_RESULT_OK,
               dp->ConsumerBeginReadData(MakeUserPointer(&read_buffer_ptr),
-                                        MakeUserPointer(&num_bytes),
-                                        false));
+                                        MakeUserPointer(&num_bytes), false));
     EXPECT_TRUE(read_buffer_ptr);
     EXPECT_EQ(kTestDataSize, num_bytes);
 
@@ -1781,8 +1653,7 @@
     uint32_t num_bytes = kTestDataSize;
     EXPECT_EQ(MOJO_RESULT_OK,
               dp->ProducerWriteData(UserPointer<const void>(kTestData),
-                                    MakeUserPointer(&num_bytes),
-                                    false));
+                                    MakeUserPointer(&num_bytes), false));
     EXPECT_EQ(kTestDataSize, num_bytes);
 
     // Start two-phase write.
@@ -1790,8 +1661,7 @@
     num_bytes = 0u;
     EXPECT_EQ(MOJO_RESULT_OK,
               dp->ProducerBeginWriteData(MakeUserPointer(&write_buffer_ptr),
-                                         MakeUserPointer(&num_bytes),
-                                         false));
+                                         MakeUserPointer(&num_bytes), false));
     EXPECT_TRUE(write_buffer_ptr);
     ASSERT_GT(num_bytes, kTestDataSize);
 
@@ -1800,8 +1670,7 @@
     num_bytes = 0u;
     EXPECT_EQ(MOJO_RESULT_OK,
               dp->ConsumerBeginReadData(MakeUserPointer(&read_buffer_ptr),
-                                        MakeUserPointer(&num_bytes),
-                                        false));
+                                        MakeUserPointer(&num_bytes), false));
     EXPECT_TRUE(read_buffer_ptr);
     EXPECT_EQ(kTestDataSize, num_bytes);
 
@@ -1819,16 +1688,14 @@
     num_bytes = kTestDataSize;
     EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION,
               dp->ProducerWriteData(UserPointer<const void>(kTestData),
-                                    MakeUserPointer(&num_bytes),
-                                    false));
+                                    MakeUserPointer(&num_bytes), false));
 
     // As will trying to start another two-phase write.
     write_buffer_ptr = nullptr;
     num_bytes = 0u;
     EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION,
               dp->ProducerBeginWriteData(MakeUserPointer(&write_buffer_ptr),
-                                         MakeUserPointer(&num_bytes),
-                                         false));
+                                         MakeUserPointer(&num_bytes), false));
 
     dp->ProducerClose();
   }
@@ -1843,8 +1710,7 @@
     uint32_t num_bytes = 0u;
     EXPECT_EQ(MOJO_RESULT_OK,
               dp->ProducerBeginWriteData(MakeUserPointer(&write_buffer_ptr),
-                                         MakeUserPointer(&num_bytes),
-                                         false));
+                                         MakeUserPointer(&num_bytes), false));
     EXPECT_TRUE(write_buffer_ptr);
     ASSERT_GT(num_bytes, kTestDataSize);
 
@@ -1860,8 +1726,7 @@
     uint32_t num_bytes = kTestDataSize;
     EXPECT_EQ(MOJO_RESULT_OK,
               dp->ProducerWriteData(UserPointer<const void>(kTestData),
-                                    MakeUserPointer(&num_bytes),
-                                    false));
+                                    MakeUserPointer(&num_bytes), false));
     EXPECT_EQ(kTestDataSize, num_bytes);
 
     // Close the producer.
@@ -1870,43 +1735,33 @@
     // Peek that data.
     char buffer[1000];
     num_bytes = static_cast<uint32_t>(sizeof(buffer));
-    EXPECT_EQ(
-        MOJO_RESULT_OK,
-        dp->ConsumerReadData(UserPointer<void>(buffer),
-                             MakeUserPointer(&num_bytes),
-                             false,
-                             true));
+    EXPECT_EQ(MOJO_RESULT_OK,
+              dp->ConsumerReadData(UserPointer<void>(buffer),
+                                   MakeUserPointer(&num_bytes), false, true));
     EXPECT_EQ(kTestDataSize, num_bytes);
     EXPECT_EQ(0, memcmp(buffer, kTestData, kTestDataSize));
 
     // Read that data.
     memset(buffer, 0, 1000);
     num_bytes = static_cast<uint32_t>(sizeof(buffer));
-    EXPECT_EQ(
-        MOJO_RESULT_OK,
-        dp->ConsumerReadData(UserPointer<void>(buffer),
-                             MakeUserPointer(&num_bytes),
-                             false,
-                             false));
+    EXPECT_EQ(MOJO_RESULT_OK,
+              dp->ConsumerReadData(UserPointer<void>(buffer),
+                                   MakeUserPointer(&num_bytes), false, false));
     EXPECT_EQ(kTestDataSize, num_bytes);
     EXPECT_EQ(0, memcmp(buffer, kTestData, kTestDataSize));
 
     // A second read should fail.
     num_bytes = static_cast<uint32_t>(sizeof(buffer));
-    EXPECT_EQ(
-        MOJO_RESULT_FAILED_PRECONDITION,
-        dp->ConsumerReadData(UserPointer<void>(buffer),
-                             MakeUserPointer(&num_bytes),
-                             false,
-                             false));
+    EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION,
+              dp->ConsumerReadData(UserPointer<void>(buffer),
+                                   MakeUserPointer(&num_bytes), false, false));
 
     // A two-phase read should also fail.
     const void* read_buffer_ptr = nullptr;
     num_bytes = 0u;
     EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION,
               dp->ConsumerBeginReadData(MakeUserPointer(&read_buffer_ptr),
-                                        MakeUserPointer(&num_bytes),
-                                        false));
+                                        MakeUserPointer(&num_bytes), false));
 
     // Ditto for discard.
     num_bytes = 10u;
@@ -1925,9 +1780,8 @@
       10 * sizeof(int32_t)                      // |capacity_num_bytes|.
   };
   MojoCreateDataPipeOptions validated_options = {0};
-  EXPECT_EQ(MOJO_RESULT_OK,
-            DataPipe::ValidateCreateOptions(MakeUserPointer(&options),
-                                            &validated_options));
+  EXPECT_EQ(MOJO_RESULT_OK, DataPipe::ValidateCreateOptions(
+                                MakeUserPointer(&options), &validated_options));
 
   scoped_refptr<LocalDataPipe> dp(new LocalDataPipe(validated_options));
 
@@ -1948,10 +1802,9 @@
   // Try ending a two-phase write with an invalid amount (too much).
   num_bytes = 0u;
   void* write_ptr = nullptr;
-  EXPECT_EQ(
-      MOJO_RESULT_OK,
-      dp->ProducerBeginWriteData(
-          MakeUserPointer(&write_ptr), MakeUserPointer(&num_bytes), false));
+  EXPECT_EQ(MOJO_RESULT_OK,
+            dp->ProducerBeginWriteData(MakeUserPointer(&write_ptr),
+                                       MakeUserPointer(&num_bytes), false));
   EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
             dp->ProducerEndWriteData(num_bytes +
                                      static_cast<uint32_t>(sizeof(int32_t))));
@@ -1968,10 +1821,9 @@
   // element size).
   num_bytes = 0u;
   write_ptr = nullptr;
-  EXPECT_EQ(
-      MOJO_RESULT_OK,
-      dp->ProducerBeginWriteData(
-          MakeUserPointer(&write_ptr), MakeUserPointer(&num_bytes), false));
+  EXPECT_EQ(MOJO_RESULT_OK,
+            dp->ProducerBeginWriteData(MakeUserPointer(&write_ptr),
+                                       MakeUserPointer(&num_bytes), false));
   EXPECT_GE(num_bytes, 1u);
   EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, dp->ProducerEndWriteData(1u));
 
@@ -1988,8 +1840,7 @@
   num_bytes = 1u * sizeof(int32_t);
   EXPECT_EQ(MOJO_RESULT_OK,
             dp->ProducerWriteData(UserPointer<const void>(&element),
-                                  MakeUserPointer(&num_bytes),
-                                  false));
+                                  MakeUserPointer(&num_bytes), false));
 
   // One element available.
   num_bytes = 0u;
@@ -2008,10 +1859,9 @@
   // Try ending a two-phase read with an invalid amount (too much).
   num_bytes = 0u;
   const void* read_ptr = nullptr;
-  EXPECT_EQ(
-      MOJO_RESULT_OK,
-      dp->ConsumerBeginReadData(
-          MakeUserPointer(&read_ptr), MakeUserPointer(&num_bytes), false));
+  EXPECT_EQ(MOJO_RESULT_OK,
+            dp->ConsumerBeginReadData(MakeUserPointer(&read_ptr),
+                                      MakeUserPointer(&num_bytes), false));
   EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
             dp->ConsumerEndReadData(num_bytes +
                                     static_cast<uint32_t>(sizeof(int32_t))));
@@ -2025,10 +1875,9 @@
   // element size).
   num_bytes = 0u;
   read_ptr = nullptr;
-  EXPECT_EQ(
-      MOJO_RESULT_OK,
-      dp->ConsumerBeginReadData(
-          MakeUserPointer(&read_ptr), MakeUserPointer(&num_bytes), false));
+  EXPECT_EQ(MOJO_RESULT_OK,
+            dp->ConsumerBeginReadData(MakeUserPointer(&read_ptr),
+                                      MakeUserPointer(&num_bytes), false));
   EXPECT_EQ(1u * sizeof(int32_t), num_bytes);
   EXPECT_EQ(123, static_cast<const int32_t*>(read_ptr)[0]);
   EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, dp->ConsumerEndReadData(1u));
@@ -2057,9 +1906,8 @@
       2                                                // |capacity_num_bytes|.
   };
   MojoCreateDataPipeOptions validated_options = {0};
-  EXPECT_EQ(MOJO_RESULT_OK,
-            DataPipe::ValidateCreateOptions(MakeUserPointer(&options),
-                                            &validated_options));
+  EXPECT_EQ(MOJO_RESULT_OK, DataPipe::ValidateCreateOptions(
+                                MakeUserPointer(&options), &validated_options));
 
   scoped_refptr<LocalDataPipe> dp(new LocalDataPipe(validated_options));
 
@@ -2068,17 +1916,15 @@
   uint32_t num_bytes = 2u;
   EXPECT_EQ(MOJO_RESULT_OK,
             dp->ProducerWriteData(UserPointer<const void>(elements),
-                                  MakeUserPointer(&num_bytes),
-                                  false));
+                                  MakeUserPointer(&num_bytes), false));
   EXPECT_EQ(2u, num_bytes);
 
   // Begin reading.
   const void* read_ptr = nullptr;
   num_bytes = 2u;
-  EXPECT_EQ(
-      MOJO_RESULT_OK,
-      dp->ConsumerBeginReadData(
-          MakeUserPointer(&read_ptr), MakeUserPointer(&num_bytes), false));
+  EXPECT_EQ(MOJO_RESULT_OK,
+            dp->ConsumerBeginReadData(MakeUserPointer(&read_ptr),
+                                      MakeUserPointer(&num_bytes), false));
   EXPECT_EQ(2u, num_bytes);
   EXPECT_EQ('a', static_cast<const char*>(read_ptr)[0]);
   EXPECT_EQ('b', static_cast<const char*>(read_ptr)[1]);
@@ -2094,8 +1940,7 @@
   // this through reveals the significant consequence.
   EXPECT_EQ(MOJO_RESULT_OK,
             dp->ProducerWriteData(UserPointer<const void>(elements),
-                                  MakeUserPointer(&num_bytes),
-                                  false));
+                                  MakeUserPointer(&num_bytes), false));
 
   // Check that our read buffer hasn't changed underneath us.
   EXPECT_EQ('a', static_cast<const char*>(read_ptr)[0]);
@@ -2107,16 +1952,14 @@
   // Now writing should succeed.
   EXPECT_EQ(MOJO_RESULT_OK,
             dp->ProducerWriteData(UserPointer<const void>(elements),
-                                  MakeUserPointer(&num_bytes),
-                                  false));
+                                  MakeUserPointer(&num_bytes), false));
 
   // And if we read, we should get the new values.
   read_ptr = nullptr;
   num_bytes = 2u;
-  EXPECT_EQ(
-      MOJO_RESULT_OK,
-      dp->ConsumerBeginReadData(
-          MakeUserPointer(&read_ptr), MakeUserPointer(&num_bytes), false));
+  EXPECT_EQ(MOJO_RESULT_OK,
+            dp->ConsumerBeginReadData(MakeUserPointer(&read_ptr),
+                                      MakeUserPointer(&num_bytes), false));
   EXPECT_EQ(2u, num_bytes);
   EXPECT_EQ('x', static_cast<const char*>(read_ptr)[0]);
   EXPECT_EQ('y', static_cast<const char*>(read_ptr)[1]);
diff --git a/mojo/edk/system/mapping_table.cc b/mojo/edk/system/mapping_table.cc
index 0a28a1d..693e8d7 100644
--- a/mojo/edk/system/mapping_table.cc
+++ b/mojo/edk/system/mapping_table.cc
@@ -6,7 +6,7 @@
 
 #include "base/logging.h"
 #include "mojo/edk/embedder/platform_shared_buffer.h"
-#include "mojo/edk/system/constants.h"
+#include "mojo/edk/system/configuration.h"
 
 namespace mojo {
 namespace system {
@@ -23,7 +23,8 @@
     scoped_ptr<embedder::PlatformSharedBufferMapping> mapping) {
   DCHECK(mapping);
 
-  if (address_to_mapping_map_.size() >= kMaxMappingTableSize)
+  if (address_to_mapping_map_.size() >=
+      GetConfiguration().max_mapping_table_sze)
     return MOJO_RESULT_RESOURCE_EXHAUSTED;
 
   uintptr_t address = reinterpret_cast<uintptr_t>(mapping->GetBase());
diff --git a/mojo/edk/system/memory.cc b/mojo/edk/system/memory.cc
index 1d7f792..0e3d9a9 100644
--- a/mojo/edk/system/memory.cc
+++ b/mojo/edk/system/memory.cc
@@ -40,20 +40,20 @@
 
 template <size_t size, size_t alignment>
 void MOJO_SYSTEM_IMPL_EXPORT
-    CheckUserPointerWithCount(const void* pointer, size_t count) {
+CheckUserPointerWithCount(const void* pointer, size_t count) {
   CHECK_LE(count, std::numeric_limits<size_t>::max() / size);
   CHECK(count == 0 || (pointer && IsAligned<alignment>(pointer)));
 }
 
 // Explicitly instantiate the sizes we need. Add instantiations as needed.
 template void MOJO_SYSTEM_IMPL_EXPORT
-    CheckUserPointerWithCount<1, 1>(const void*, size_t);
+CheckUserPointerWithCount<1, 1>(const void*, size_t);
 template void MOJO_SYSTEM_IMPL_EXPORT
-    CheckUserPointerWithCount<4, 4>(const void*, size_t);
+CheckUserPointerWithCount<4, 4>(const void*, size_t);
 template void MOJO_SYSTEM_IMPL_EXPORT
-    CheckUserPointerWithCount<8, 4>(const void*, size_t);
+CheckUserPointerWithCount<8, 4>(const void*, size_t);
 template void MOJO_SYSTEM_IMPL_EXPORT
-    CheckUserPointerWithCount<8, 8>(const void*, size_t);
+CheckUserPointerWithCount<8, 8>(const void*, size_t);
 
 template <size_t alignment>
 void CheckUserPointerWithSize(const void* pointer, size_t size) {
@@ -65,9 +65,9 @@
 
 // Explicitly instantiate the sizes we need. Add instantiations as needed.
 template void MOJO_SYSTEM_IMPL_EXPORT
-    CheckUserPointerWithSize<1>(const void*, size_t);
+CheckUserPointerWithSize<1>(const void*, size_t);
 template void MOJO_SYSTEM_IMPL_EXPORT
-    CheckUserPointerWithSize<4>(const void*, size_t);
+CheckUserPointerWithSize<4>(const void*, size_t);
 // Whereas the other |Check...()| functions are usually used with integral typs
 // or arrays of integral types, this one is used with Options structs for which
 // alignment has been explicitly been specified (using |MOJO_ALIGNAS()|), which
@@ -75,13 +75,13 @@
 #if defined(COMPILER_MSVC) && defined(ARCH_CPU_32_BITS)
 template <>
 void MOJO_SYSTEM_IMPL_EXPORT
-    CheckUserPointerWithSize<8>(const void* pointer, size_t size) {
+CheckUserPointerWithSize<8>(const void* pointer, size_t size) {
   CHECK(size == 0 ||
         (!!pointer && reinterpret_cast<uintptr_t>(pointer) % 8 == 0));
 }
 #else
 template void MOJO_SYSTEM_IMPL_EXPORT
-    CheckUserPointerWithSize<8>(const void*, size_t);
+CheckUserPointerWithSize<8>(const void*, size_t);
 #endif
 
 }  // namespace internal
diff --git a/mojo/edk/system/memory.h b/mojo/edk/system/memory.h
index 7b5b724..96cf219 100644
--- a/mojo/edk/system/memory.h
+++ b/mojo/edk/system/memory.h
@@ -53,13 +53,13 @@
 // a buffer of |count| elements of the given size and alignment (both in bytes).
 template <size_t size, size_t alignment>
 void MOJO_SYSTEM_IMPL_EXPORT
-    CheckUserPointerWithCount(const void* pointer, size_t count);
+CheckUserPointerWithCount(const void* pointer, size_t count);
 
 // Checks (insofar as appropriate/possible) that |pointer| is a valid pointer to
 // a buffer of the given size and alignment (both in bytes).
 template <size_t alignment>
 void MOJO_SYSTEM_IMPL_EXPORT
-    CheckUserPointerWithSize(const void* pointer, size_t size);
+CheckUserPointerWithSize(const void* pointer, size_t size);
 
 }  // namespace internal
 
diff --git a/mojo/edk/system/message_in_transit.cc b/mojo/edk/system/message_in_transit.cc
index 95a7d23..0f2ff5e 100644
--- a/mojo/edk/system/message_in_transit.cc
+++ b/mojo/edk/system/message_in_transit.cc
@@ -8,7 +8,7 @@
 
 #include "base/compiler_specific.h"
 #include "base/logging.h"
-#include "mojo/edk/system/constants.h"
+#include "mojo/edk/system/configuration.h"
 #include "mojo/edk/system/transport_data.h"
 
 namespace mojo {
@@ -38,23 +38,13 @@
   // The size of |Header| must be a multiple of the alignment.
   static_assert(sizeof(Header) % kMessageAlignment == 0,
                 "sizeof(MessageInTransit::Header) invalid");
-  // Avoid dangerous situations, but making sure that the size of the "header" +
-  // the size of the data fits into a 31-bit number.
-  static_assert(static_cast<uint64_t>(sizeof(Header)) + kMaxMessageNumBytes <=
-                    0x7fffffffULL,
-                "kMaxMessageNumBytes too big");
-
-  // We assume (to avoid extra rounding code) that the maximum message (data)
-  // size is a multiple of the alignment.
-  static_assert(kMaxMessageNumBytes % kMessageAlignment == 0,
-                "kMessageAlignment not a multiple of alignment");
 };
 
 MessageInTransit::View::View(size_t message_size, const void* buffer)
     : buffer_(buffer) {
   size_t next_message_size = 0;
-  DCHECK(MessageInTransit::GetNextMessageSize(
-      buffer_, message_size, &next_message_size));
+  DCHECK(MessageInTransit::GetNextMessageSize(buffer_, message_size,
+                                              &next_message_size));
   DCHECK_EQ(message_size, next_message_size);
   // This should be equivalent.
   DCHECK_EQ(message_size, total_size());
@@ -62,18 +52,29 @@
 
 bool MessageInTransit::View::IsValid(size_t serialized_platform_handle_size,
                                      const char** error_message) const {
+  size_t max_message_num_bytes = GetConfiguration().max_message_num_bytes;
+  // Avoid dangerous situations, but making sure that the size of the "header" +
+  // the size of the data fits into a 31-bit number.
+  DCHECK_LE(static_cast<uint64_t>(sizeof(Header)) + max_message_num_bytes,
+            0x7fffffffULL)
+      << "GetConfiguration().max_message_num_bytes too big";
+
+  // We assume (to avoid extra rounding code) that the maximum message (data)
+  // size is a multiple of the alignment.
+  DCHECK_EQ(max_message_num_bytes % kMessageAlignment, 0U)
+      << "GetConfiguration().max_message_num_bytes not a multiple of alignment";
+
   // Note: This also implies a check on the |main_buffer_size()|, which is just
   // |RoundUpMessageAlignment(sizeof(Header) + num_bytes())|.
-  if (num_bytes() > kMaxMessageNumBytes) {
+  if (num_bytes() > max_message_num_bytes) {
     *error_message = "Message data payload too large";
     return false;
   }
 
   if (transport_data_buffer_size() > 0) {
-    const char* e =
-        TransportData::ValidateBuffer(serialized_platform_handle_size,
-                                      transport_data_buffer(),
-                                      transport_data_buffer_size());
+    const char* e = TransportData::ValidateBuffer(
+        serialized_platform_handle_size, transport_data_buffer(),
+        transport_data_buffer_size());
     if (e) {
       *error_message = e;
       return false;
@@ -93,8 +94,7 @@
   ConstructorHelper(type, subtype, num_bytes);
   if (bytes) {
     memcpy(MessageInTransit::bytes(), bytes, num_bytes);
-    memset(static_cast<char*>(MessageInTransit::bytes()) + num_bytes,
-           0,
+    memset(static_cast<char*>(MessageInTransit::bytes()) + num_bytes, 0,
            main_buffer_size_ - sizeof(Header) - num_bytes);
   } else {
     memset(MessageInTransit::bytes(), 0, main_buffer_size_ - sizeof(Header));
@@ -195,7 +195,7 @@
 void MessageInTransit::ConstructorHelper(Type type,
                                          Subtype subtype,
                                          uint32_t num_bytes) {
-  DCHECK_LE(num_bytes, kMaxMessageNumBytes);
+  DCHECK_LE(num_bytes, GetConfiguration().max_message_num_bytes);
 
   // |total_size| is updated below, from the other values.
   header()->type = type;
diff --git a/mojo/edk/system/message_pipe.cc b/mojo/edk/system/message_pipe.cc
index e215730..731fd90 100644
--- a/mojo/edk/system/message_pipe.cc
+++ b/mojo/edk/system/message_pipe.cc
@@ -5,7 +5,9 @@
 #include "mojo/edk/system/message_pipe.h"
 
 #include "base/logging.h"
+#include "mojo/edk/system/channel.h"
 #include "mojo/edk/system/channel_endpoint.h"
+#include "mojo/edk/system/channel_endpoint_id.h"
 #include "mojo/edk/system/local_message_pipe_endpoint.h"
 #include "mojo/edk/system/message_in_transit.h"
 #include "mojo/edk/system/message_pipe_dispatcher.h"
@@ -15,6 +17,19 @@
 namespace mojo {
 namespace system {
 
+namespace {
+
+// TODO(vtl): Move this into |Channel| (and possible further).
+struct SerializedMessagePipe {
+  // This is the endpoint ID on the receiving side, and should be a "remote ID".
+  // (The receiving side should already have had an endpoint attached and been
+  // run via the |Channel|s. This endpoint will have both IDs assigned, so this
+  // ID is only needed to associate that endpoint with a particular dispatcher.)
+  ChannelEndpointId receiver_endpoint_id;
+};
+
+}  // namespace
+
 // static
 MessagePipe* MessagePipe::CreateLocalLocal() {
   MessagePipe* message_pipe = new MessagePipe();
@@ -53,6 +68,34 @@
   return port ^ 1;
 }
 
+// static
+bool MessagePipe::Deserialize(Channel* channel,
+                              const void* source,
+                              size_t size,
+                              scoped_refptr<MessagePipe>* message_pipe,
+                              unsigned* port) {
+  DCHECK(!message_pipe->get());  // Not technically wrong, but unlikely.
+
+  if (size != sizeof(SerializedMessagePipe)) {
+    LOG(ERROR) << "Invalid serialized message pipe";
+    return false;
+  }
+
+  const SerializedMessagePipe* s =
+      static_cast<const SerializedMessagePipe*>(source);
+  *message_pipe = channel->PassIncomingMessagePipe(s->receiver_endpoint_id);
+  if (!message_pipe->get()) {
+    LOG(ERROR) << "Failed to deserialize message pipe (ID = "
+               << s->receiver_endpoint_id << ")";
+    return false;
+  }
+
+  DVLOG(2) << "Deserializing message pipe dispatcher (new local ID = "
+           << s->receiver_endpoint_id << ")";
+  *port = 0;
+  return true;
+}
+
 MessagePipeEndpoint::Type MessagePipe::GetType(unsigned port) {
   DCHECK(port == 0 || port == 1);
   base::AutoLock locker(lock_);
@@ -100,9 +143,7 @@
       GetPeerPort(port),
       make_scoped_ptr(new MessageInTransit(
           MessageInTransit::kTypeMessagePipeEndpoint,
-          MessageInTransit::kSubtypeMessagePipeEndpointData,
-          num_bytes,
-          bytes)),
+          MessageInTransit::kSubtypeMessagePipeEndpointData, num_bytes, bytes)),
       transports);
 }
 
@@ -117,8 +158,8 @@
   base::AutoLock locker(lock_);
   DCHECK(endpoints_[port]);
 
-  return endpoints_[port]->ReadMessage(
-      bytes, num_bytes, dispatchers, num_dispatchers, flags);
+  return endpoints_[port]->ReadMessage(bytes, num_bytes, dispatchers,
+                                       num_dispatchers, flags);
 }
 
 HandleSignalsState MessagePipe::GetHandleSignalsState(unsigned port) const {
@@ -154,6 +195,32 @@
   endpoints_[port]->RemoveWaiter(waiter, signals_state);
 }
 
+void MessagePipe::StartSerialize(unsigned /*port*/,
+                                 Channel* /*channel*/,
+                                 size_t* max_size,
+                                 size_t* max_platform_handles) {
+  *max_size = sizeof(SerializedMessagePipe);
+  *max_platform_handles = 0;
+}
+
+bool MessagePipe::EndSerialize(
+    unsigned port,
+    Channel* channel,
+    void* destination,
+    size_t* actual_size,
+    embedder::PlatformHandleVector* /*platform_handles*/) {
+  SerializedMessagePipe* s = static_cast<SerializedMessagePipe*>(destination);
+
+  // Convert the local endpoint to a proxy endpoint (moving the message queue)
+  // and attach it to the channel.
+  s->receiver_endpoint_id =
+      channel->AttachAndRunEndpoint(ConvertLocalToProxy(port), false);
+  DVLOG(2) << "Serializing message pipe (remote ID = "
+           << s->receiver_endpoint_id << ")";
+  *actual_size = sizeof(SerializedMessagePipe);
+  return true;
+}
+
 scoped_refptr<ChannelEndpoint> MessagePipe::ConvertLocalToProxy(unsigned port) {
   DCHECK(port == 0 || port == 1);
 
@@ -165,10 +232,8 @@
   // send the already-queued messages.
   if (!endpoints_[GetPeerPort(port)]) {
     scoped_refptr<ChannelEndpoint> channel_endpoint(new ChannelEndpoint(
-        nullptr,
-        0,
-        static_cast<LocalMessagePipeEndpoint*>(endpoints_[port].get())
-            ->message_queue()));
+        nullptr, 0, static_cast<LocalMessagePipeEndpoint*>(
+                        endpoints_[port].get())->message_queue()));
     endpoints_[port]->Close();
     endpoints_[port].reset();
     return channel_endpoint;
@@ -177,18 +242,15 @@
   // TODO(vtl): Allowing this case is a temporary hack. It'll set up a
   // |MessagePipe| with two proxy endpoints, which will then act as a proxy
   // (rather than trying to connect the two ends directly).
-  DLOG_IF(WARNING,
-          endpoints_[GetPeerPort(port)]->GetType() !=
-              MessagePipeEndpoint::kTypeLocal)
+  DLOG_IF(WARNING, endpoints_[GetPeerPort(port)]->GetType() !=
+                       MessagePipeEndpoint::kTypeLocal)
       << "Direct message pipe passing across multiple channels not yet "
          "implemented; will proxy";
 
   scoped_ptr<MessagePipeEndpoint> old_endpoint(endpoints_[port].Pass());
   scoped_refptr<ChannelEndpoint> channel_endpoint(new ChannelEndpoint(
-      this,
-      port,
-      static_cast<LocalMessagePipeEndpoint*>(old_endpoint.get())
-          ->message_queue()));
+      this, port, static_cast<LocalMessagePipeEndpoint*>(old_endpoint.get())
+                      ->message_queue()));
   endpoints_[port].reset(new ProxyMessagePipeEndpoint(channel_endpoint.get()));
   old_endpoint->Close();
 
@@ -280,7 +342,7 @@
           (*transports)[i].CreateEquivalentDispatcherAndClose());
     } else {
       LOG(WARNING) << "Enqueueing null dispatcher";
-      dispatchers->push_back(scoped_refptr<Dispatcher>());
+      dispatchers->push_back(nullptr);
     }
   }
   message->SetDispatchers(dispatchers.Pass());
diff --git a/mojo/edk/system/message_pipe.h b/mojo/edk/system/message_pipe.h
index a52743d..b39e517 100644
--- a/mojo/edk/system/message_pipe.h
+++ b/mojo/edk/system/message_pipe.h
@@ -5,6 +5,7 @@
 #ifndef MOJO_EDK_SYSTEM_MESSAGE_PIPE_H_
 #define MOJO_EDK_SYSTEM_MESSAGE_PIPE_H_
 
+#include <stddef.h>
 #include <stdint.h>
 
 #include <vector>
@@ -13,6 +14,7 @@
 #include "base/memory/ref_counted.h"
 #include "base/memory/scoped_ptr.h"
 #include "base/synchronization/lock.h"
+#include "mojo/edk/embedder/platform_handle_vector.h"
 #include "mojo/edk/system/dispatcher.h"
 #include "mojo/edk/system/handle_signals_state.h"
 #include "mojo/edk/system/memory.h"
@@ -25,6 +27,7 @@
 namespace mojo {
 namespace system {
 
+class Channel;
 class ChannelEndpoint;
 class Waiter;
 
@@ -55,6 +58,15 @@
   // Gets the other port number (i.e., 0 -> 1, 1 -> 0).
   static unsigned GetPeerPort(unsigned port);
 
+  // Used by |MessagePipeDispatcher::Deserialize()|. Returns true on success (in
+  // which case, |*message_pipe|/|*port| are set appropriately) and false on
+  // failure (in which case |*message_pipe| may or may not be set to null).
+  static bool Deserialize(Channel* channel,
+                          const void* source,
+                          size_t size,
+                          scoped_refptr<MessagePipe>* message_pipe,
+                          unsigned* port);
+
   // Gets the type of the endpoint (used for assertions, etc.).
   MessagePipeEndpoint::Type GetType(unsigned port);
 
@@ -84,9 +96,18 @@
   void RemoveWaiter(unsigned port,
                     Waiter* waiter,
                     HandleSignalsState* signals_state);
+  void StartSerialize(unsigned port,
+                      Channel* channel,
+                      size_t* max_size,
+                      size_t* max_platform_handles);
+  bool EndSerialize(unsigned port,
+                    Channel* channel,
+                    void* destination,
+                    size_t* actual_size,
+                    embedder::PlatformHandleVector* platform_handles);
 
-  // This is called by the dispatcher to convert a local endpoint to a proxy
-  // endpoint.
+  // Used by |EndSerialize()|. TODO(vtl): Remove this (merge it into
+  // |EndSerialize()|).
   scoped_refptr<ChannelEndpoint> ConvertLocalToProxy(unsigned port);
 
   // This is used by |Channel| to enqueue messages (typically to a
diff --git a/mojo/edk/system/message_pipe_dispatcher.cc b/mojo/edk/system/message_pipe_dispatcher.cc
index 7db16e8..df861df 100644
--- a/mojo/edk/system/message_pipe_dispatcher.cc
+++ b/mojo/edk/system/message_pipe_dispatcher.cc
@@ -5,10 +5,7 @@
 #include "mojo/edk/system/message_pipe_dispatcher.h"
 
 #include "base/logging.h"
-#include "mojo/edk/system/channel.h"
-#include "mojo/edk/system/channel_endpoint.h"
-#include "mojo/edk/system/channel_endpoint_id.h"
-#include "mojo/edk/system/constants.h"
+#include "mojo/edk/system/configuration.h"
 #include "mojo/edk/system/local_message_pipe_endpoint.h"
 #include "mojo/edk/system/memory.h"
 #include "mojo/edk/system/message_pipe.h"
@@ -18,20 +15,8 @@
 namespace mojo {
 namespace system {
 
-namespace {
-
 const unsigned kInvalidPort = static_cast<unsigned>(-1);
 
-struct SerializedMessagePipeDispatcher {
-  // This is the endpoint ID on the receiving side, and should be a "remote ID".
-  // (The receiving side should have already have an endpoint attached and run
-  // via the |Channel|s. This endpoint will have both IDs assigned, so this ID
-  // is only needed to associated that endpoint with a particular dispatcher.)
-  ChannelEndpointId receiver_endpoint_id;
-};
-
-}  // namespace
-
 // MessagePipeDispatcher -------------------------------------------------------
 
 // static
@@ -103,26 +88,16 @@
     Channel* channel,
     const void* source,
     size_t size) {
-  if (size != sizeof(SerializedMessagePipeDispatcher)) {
-    LOG(ERROR) << "Invalid serialized message pipe dispatcher";
-    return scoped_refptr<MessagePipeDispatcher>();
-  }
+  unsigned port = kInvalidPort;
+  scoped_refptr<MessagePipe> message_pipe;
+  if (!MessagePipe::Deserialize(channel, source, size, &message_pipe, &port))
+    return nullptr;
+  DCHECK(message_pipe.get());
+  DCHECK(port == 0 || port == 1);
 
-  const SerializedMessagePipeDispatcher* s =
-      static_cast<const SerializedMessagePipeDispatcher*>(source);
-  scoped_refptr<MessagePipe> message_pipe =
-      channel->PassIncomingMessagePipe(s->receiver_endpoint_id);
-  if (!message_pipe.get()) {
-    LOG(ERROR) << "Failed to deserialize message pipe dispatcher (ID = "
-               << s->receiver_endpoint_id << ")";
-    return scoped_refptr<MessagePipeDispatcher>();
-  }
-
-  DVLOG(2) << "Deserializing message pipe dispatcher (new local ID = "
-           << s->receiver_endpoint_id << ")";
   scoped_refptr<MessagePipeDispatcher> dispatcher(
       new MessagePipeDispatcher(MessagePipeDispatcher::kDefaultCreateOptions));
-  dispatcher->Init(message_pipe, 0);
+  dispatcher->Init(message_pipe, port);
   return dispatcher;
 }
 
@@ -173,16 +148,17 @@
     uint32_t num_bytes,
     std::vector<DispatcherTransport>* transports,
     MojoWriteMessageFlags flags) {
-  DCHECK(!transports || (transports->size() > 0 &&
-                         transports->size() <= kMaxMessageNumHandles));
+  DCHECK(!transports ||
+         (transports->size() > 0 &&
+          transports->size() <= GetConfiguration().max_message_num_handles));
 
   lock().AssertAcquired();
 
-  if (num_bytes > kMaxMessageNumBytes)
+  if (num_bytes > GetConfiguration().max_message_num_bytes)
     return MOJO_RESULT_RESOURCE_EXHAUSTED;
 
-  return message_pipe_->WriteMessage(
-      port_, bytes, num_bytes, transports, flags);
+  return message_pipe_->WriteMessage(port_, bytes, num_bytes, transports,
+                                     flags);
 }
 
 MojoResult MessagePipeDispatcher::ReadMessageImplNoLock(
@@ -192,8 +168,8 @@
     uint32_t* num_dispatchers,
     MojoReadMessageFlags flags) {
   lock().AssertAcquired();
-  return message_pipe_->ReadMessage(
-      port_, bytes, num_bytes, dispatchers, num_dispatchers, flags);
+  return message_pipe_->ReadMessage(port_, bytes, num_bytes, dispatchers,
+                                    num_dispatchers, flags);
 }
 
 HandleSignalsState MessagePipeDispatcher::GetHandleSignalsStateImplNoLock()
@@ -208,8 +184,8 @@
     uint32_t context,
     HandleSignalsState* signals_state) {
   lock().AssertAcquired();
-  return message_pipe_->AddWaiter(
-      port_, waiter, signals, context, signals_state);
+  return message_pipe_->AddWaiter(port_, waiter, signals, context,
+                                  signals_state);
 }
 
 void MessagePipeDispatcher::RemoveWaiterImplNoLock(
@@ -220,36 +196,26 @@
 }
 
 void MessagePipeDispatcher::StartSerializeImplNoLock(
-    Channel* /*channel*/,
+    Channel* channel,
     size_t* max_size,
     size_t* max_platform_handles) {
   DCHECK(HasOneRef());  // Only one ref => no need to take the lock.
-  *max_size = sizeof(SerializedMessagePipeDispatcher);
-  *max_platform_handles = 0;
+  return message_pipe_->StartSerialize(port_, channel, max_size,
+                                       max_platform_handles);
 }
 
 bool MessagePipeDispatcher::EndSerializeAndCloseImplNoLock(
     Channel* channel,
     void* destination,
     size_t* actual_size,
-    embedder::PlatformHandleVector* /*platform_handles*/) {
+    embedder::PlatformHandleVector* platform_handles) {
   DCHECK(HasOneRef());  // Only one ref => no need to take the lock.
 
-  SerializedMessagePipeDispatcher* s =
-      static_cast<SerializedMessagePipeDispatcher*>(destination);
-
-  // Convert the local endpoint to a proxy endpoint (moving the message queue)
-  // and attach it to the channel.
-  s->receiver_endpoint_id = channel->AttachAndRunEndpoint(
-      message_pipe_->ConvertLocalToProxy(port_), false);
-  DVLOG(2) << "Serializing message pipe dispatcher (remote ID = "
-           << s->receiver_endpoint_id << ")";
-
+  bool rv = message_pipe_->EndSerialize(port_, channel, destination,
+                                        actual_size, platform_handles);
   message_pipe_ = nullptr;
   port_ = kInvalidPort;
-
-  *actual_size = sizeof(SerializedMessagePipeDispatcher);
-  return true;
+  return rv;
 }
 
 // MessagePipeDispatcherTransport ----------------------------------------------
diff --git a/mojo/edk/system/message_pipe_dispatcher_unittest.cc b/mojo/edk/system/message_pipe_dispatcher_unittest.cc
index ae651fa..8076a99 100644
--- a/mojo/edk/system/message_pipe_dispatcher_unittest.cc
+++ b/mojo/edk/system/message_pipe_dispatcher_unittest.cc
@@ -68,10 +68,8 @@
               d0->AddWaiter(&w, MOJO_HANDLE_SIGNAL_READABLE, 1, nullptr));
     buffer[0] = 123456789;
     EXPECT_EQ(MOJO_RESULT_OK,
-              d1->WriteMessage(UserPointer<const void>(buffer),
-                               kBufferSize,
-                               nullptr,
-                               MOJO_WRITE_MESSAGE_FLAG_NONE));
+              d1->WriteMessage(UserPointer<const void>(buffer), kBufferSize,
+                               nullptr, MOJO_WRITE_MESSAGE_FLAG_NONE));
     stopwatch.Start();
     EXPECT_EQ(MOJO_RESULT_OK, w.Wait(MOJO_DEADLINE_INDEFINITE, &context));
     EXPECT_EQ(1u, context);
@@ -99,9 +97,7 @@
     buffer_size = kBufferSize;
     EXPECT_EQ(MOJO_RESULT_OK,
               d0->ReadMessage(UserPointer<void>(buffer),
-                              MakeUserPointer(&buffer_size),
-                              0,
-                              nullptr,
+                              MakeUserPointer(&buffer_size), 0, nullptr,
                               MOJO_READ_MESSAGE_FLAG_NONE));
     EXPECT_EQ(kBufferSize, buffer_size);
     EXPECT_EQ(123456789, buffer[0]);
@@ -157,8 +153,7 @@
   // Huge buffer size.
   EXPECT_EQ(MOJO_RESULT_RESOURCE_EXHAUSTED,
             d0->WriteMessage(UserPointer<const void>(buffer),
-                             std::numeric_limits<uint32_t>::max(),
-                             nullptr,
+                             std::numeric_limits<uint32_t>::max(), nullptr,
                              MOJO_WRITE_MESSAGE_FLAG_NONE));
 
   EXPECT_EQ(MOJO_RESULT_OK, d0->Close());
@@ -186,26 +181,21 @@
 
   // |WriteMessage|:
   // Null buffer with nonzero buffer size.
-  EXPECT_DEATH_IF_SUPPORTED(
-      d0->WriteMessage(
-          NullUserPointer(), 1, nullptr, MOJO_WRITE_MESSAGE_FLAG_NONE),
-      kMemoryCheckFailedRegex);
+  EXPECT_DEATH_IF_SUPPORTED(d0->WriteMessage(NullUserPointer(), 1, nullptr,
+                                             MOJO_WRITE_MESSAGE_FLAG_NONE),
+                            kMemoryCheckFailedRegex);
 
   // |ReadMessage|:
   // Null buffer with nonzero buffer size.
   // First write something so that we actually have something to read.
   EXPECT_EQ(MOJO_RESULT_OK,
-            d1->WriteMessage(UserPointer<const void>("x"),
-                             1,
-                             nullptr,
+            d1->WriteMessage(UserPointer<const void>("x"), 1, nullptr,
                              MOJO_WRITE_MESSAGE_FLAG_NONE));
   uint32_t buffer_size = 1;
-  EXPECT_DEATH_IF_SUPPORTED(d0->ReadMessage(NullUserPointer(),
-                                            MakeUserPointer(&buffer_size),
-                                            0,
-                                            nullptr,
-                                            MOJO_READ_MESSAGE_FLAG_NONE),
-                            kMemoryCheckFailedRegex);
+  EXPECT_DEATH_IF_SUPPORTED(
+      d0->ReadMessage(NullUserPointer(), MakeUserPointer(&buffer_size), 0,
+                      nullptr, MOJO_READ_MESSAGE_FLAG_NONE),
+      kMemoryCheckFailedRegex);
 
   EXPECT_EQ(MOJO_RESULT_OK, d0->Close());
   EXPECT_EQ(MOJO_RESULT_OK, d1->Close());
@@ -234,16 +224,12 @@
     // Write (twice) to |d1|.
     buffer[0] = 123456789;
     EXPECT_EQ(MOJO_RESULT_OK,
-              d1->WriteMessage(UserPointer<const void>(buffer),
-                               kBufferSize,
-                               nullptr,
-                               MOJO_WRITE_MESSAGE_FLAG_NONE));
+              d1->WriteMessage(UserPointer<const void>(buffer), kBufferSize,
+                               nullptr, MOJO_WRITE_MESSAGE_FLAG_NONE));
     buffer[0] = 234567890;
     EXPECT_EQ(MOJO_RESULT_OK,
-              d1->WriteMessage(UserPointer<const void>(buffer),
-                               kBufferSize,
-                               nullptr,
-                               MOJO_WRITE_MESSAGE_FLAG_NONE));
+              d1->WriteMessage(UserPointer<const void>(buffer), kBufferSize,
+                               nullptr, MOJO_WRITE_MESSAGE_FLAG_NONE));
 
     // Try waiting for readable on |d0|; should fail (already satisfied).
     w.Init();
@@ -260,9 +246,7 @@
     buffer_size = kBufferSize;
     EXPECT_EQ(MOJO_RESULT_SHOULD_WAIT,
               d1->ReadMessage(UserPointer<void>(buffer),
-                              MakeUserPointer(&buffer_size),
-                              0,
-                              nullptr,
+                              MakeUserPointer(&buffer_size), 0, nullptr,
                               MOJO_READ_MESSAGE_FLAG_NONE));
 
     // Close |d1|.
@@ -281,9 +265,7 @@
     buffer_size = kBufferSize;
     EXPECT_EQ(MOJO_RESULT_OK,
               d0->ReadMessage(UserPointer<void>(buffer),
-                              MakeUserPointer(&buffer_size),
-                              0,
-                              nullptr,
+                              MakeUserPointer(&buffer_size), 0, nullptr,
                               MOJO_READ_MESSAGE_FLAG_NONE));
     EXPECT_EQ(kBufferSize, buffer_size);
     EXPECT_EQ(123456789, buffer[0]);
@@ -301,9 +283,7 @@
     buffer_size = kBufferSize;
     EXPECT_EQ(MOJO_RESULT_OK,
               d0->ReadMessage(UserPointer<void>(buffer),
-                              MakeUserPointer(&buffer_size),
-                              0,
-                              nullptr,
+                              MakeUserPointer(&buffer_size), 0, nullptr,
                               MOJO_READ_MESSAGE_FLAG_NONE));
     EXPECT_EQ(kBufferSize, buffer_size);
     EXPECT_EQ(234567890, buffer[0]);
@@ -330,18 +310,14 @@
     buffer_size = kBufferSize;
     EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION,
               d0->ReadMessage(UserPointer<void>(buffer),
-                              MakeUserPointer(&buffer_size),
-                              0,
-                              nullptr,
+                              MakeUserPointer(&buffer_size), 0, nullptr,
                               MOJO_READ_MESSAGE_FLAG_NONE));
 
     // Try writing to |d0|; should fail (other end closed).
     buffer[0] = 345678901;
     EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION,
-              d0->WriteMessage(UserPointer<const void>(buffer),
-                               kBufferSize,
-                               nullptr,
-                               MOJO_WRITE_MESSAGE_FLAG_NONE));
+              d0->WriteMessage(UserPointer<const void>(buffer), kBufferSize,
+                               nullptr, MOJO_WRITE_MESSAGE_FLAG_NONE));
 
     EXPECT_EQ(MOJO_RESULT_OK, d0->Close());
   }
@@ -378,24 +354,17 @@
 
     // Wait for readable on |d1|, which will become readable after some time.
     {
-      test::WaiterThread thread(d1,
-                                MOJO_HANDLE_SIGNAL_READABLE,
-                                MOJO_DEADLINE_INDEFINITE,
-                                1,
-                                &did_wait,
-                                &result,
-                                &context,
-                                &hss);
+      test::WaiterThread thread(d1, MOJO_HANDLE_SIGNAL_READABLE,
+                                MOJO_DEADLINE_INDEFINITE, 1, &did_wait, &result,
+                                &context, &hss);
       stopwatch.Start();
       thread.Start();
       base::PlatformThread::Sleep(2 * test::EpsilonTimeout());
       // Wake it up by writing to |d0|.
       buffer[0] = 123456789;
       EXPECT_EQ(MOJO_RESULT_OK,
-                d0->WriteMessage(UserPointer<const void>(buffer),
-                                 kBufferSize,
-                                 nullptr,
-                                 MOJO_WRITE_MESSAGE_FLAG_NONE));
+                d0->WriteMessage(UserPointer<const void>(buffer), kBufferSize,
+                                 nullptr, MOJO_WRITE_MESSAGE_FLAG_NONE));
     }  // Joins the thread.
     elapsed = stopwatch.Elapsed();
     EXPECT_GT(elapsed, (2 - 1) * test::EpsilonTimeout());
@@ -410,14 +379,9 @@
 
     // Now |d1| is already readable. Try waiting for it again.
     {
-      test::WaiterThread thread(d1,
-                                MOJO_HANDLE_SIGNAL_READABLE,
-                                MOJO_DEADLINE_INDEFINITE,
-                                2,
-                                &did_wait,
-                                &result,
-                                &context,
-                                &hss);
+      test::WaiterThread thread(d1, MOJO_HANDLE_SIGNAL_READABLE,
+                                MOJO_DEADLINE_INDEFINITE, 2, &did_wait, &result,
+                                &context, &hss);
       stopwatch.Start();
       thread.Start();
     }  // Joins the thread.
@@ -434,9 +398,7 @@
     buffer_size = kBufferSize;
     EXPECT_EQ(MOJO_RESULT_OK,
               d1->ReadMessage(UserPointer<void>(buffer),
-                              MakeUserPointer(&buffer_size),
-                              0,
-                              nullptr,
+                              MakeUserPointer(&buffer_size), 0, nullptr,
                               MOJO_READ_MESSAGE_FLAG_NONE));
     EXPECT_EQ(kBufferSize, buffer_size);
     EXPECT_EQ(123456789, buffer[0]);
@@ -444,14 +406,9 @@
     // Wait for readable on |d1| and close |d0| after some time, which should
     // cancel that wait.
     {
-      test::WaiterThread thread(d1,
-                                MOJO_HANDLE_SIGNAL_READABLE,
-                                MOJO_DEADLINE_INDEFINITE,
-                                3,
-                                &did_wait,
-                                &result,
-                                &context,
-                                &hss);
+      test::WaiterThread thread(d1, MOJO_HANDLE_SIGNAL_READABLE,
+                                MOJO_DEADLINE_INDEFINITE, 3, &did_wait, &result,
+                                &context, &hss);
       stopwatch.Start();
       thread.Start();
       base::PlatformThread::Sleep(2 * test::EpsilonTimeout());
@@ -483,14 +440,9 @@
     // Wait for readable on |d1| and close |d1| after some time, which should
     // cancel that wait.
     {
-      test::WaiterThread thread(d1,
-                                MOJO_HANDLE_SIGNAL_READABLE,
-                                MOJO_DEADLINE_INDEFINITE,
-                                4,
-                                &did_wait,
-                                &result,
-                                &context,
-                                &hss);
+      test::WaiterThread thread(d1, MOJO_HANDLE_SIGNAL_READABLE,
+                                MOJO_DEADLINE_INDEFINITE, 4, &did_wait, &result,
+                                &context, &hss);
       stopwatch.Start();
       thread.Start();
       base::PlatformThread::Sleep(2 * test::EpsilonTimeout());
@@ -546,18 +498,15 @@
           base::RandInt(1, static_cast<int>(kMaxMessageSize)));
       EXPECT_EQ(MOJO_RESULT_OK,
                 write_dispatcher_->WriteMessage(UserPointer<const void>(buffer),
-                                                bytes_to_write,
-                                                nullptr,
+                                                bytes_to_write, nullptr,
                                                 MOJO_WRITE_MESSAGE_FLAG_NONE));
       *bytes_written_ += bytes_to_write;
     }
 
     // Write one last "quit" message.
-    EXPECT_EQ(MOJO_RESULT_OK,
-              write_dispatcher_->WriteMessage(UserPointer<const void>("quit"),
-                                              4,
-                                              nullptr,
-                                              MOJO_WRITE_MESSAGE_FLAG_NONE));
+    EXPECT_EQ(MOJO_RESULT_OK, write_dispatcher_->WriteMessage(
+                                  UserPointer<const void>("quit"), 4, nullptr,
+                                  MOJO_WRITE_MESSAGE_FLAG_NONE));
   }
 
   const scoped_refptr<Dispatcher> write_dispatcher_;
@@ -612,11 +561,9 @@
       // Clear the buffer so that we can check the result.
       memset(buffer, 0, sizeof(buffer));
       uint32_t buffer_size = static_cast<uint32_t>(sizeof(buffer));
-      result = read_dispatcher_->ReadMessage(UserPointer<void>(buffer),
-                                             MakeUserPointer(&buffer_size),
-                                             0,
-                                             nullptr,
-                                             MOJO_READ_MESSAGE_FLAG_NONE);
+      result = read_dispatcher_->ReadMessage(
+          UserPointer<void>(buffer), MakeUserPointer(&buffer_size), 0, nullptr,
+          MOJO_READ_MESSAGE_FLAG_NONE);
       EXPECT_TRUE(result == MOJO_RESULT_OK || result == MOJO_RESULT_SHOULD_WAIT)
           << "result: " << result;
       // We're racing with others to read, so maybe we failed.
diff --git a/mojo/edk/system/message_pipe_perftest.cc b/mojo/edk/system/message_pipe_perftest.cc
index 9861e0b..9f1ac5d 100644
--- a/mojo/edk/system/message_pipe_perftest.cc
+++ b/mojo/edk/system/message_pipe_perftest.cc
@@ -47,31 +47,23 @@
 
  protected:
   void WriteWaitThenRead(scoped_refptr<MessagePipe> mp) {
-    CHECK_EQ(mp->WriteMessage(0,
-                              UserPointer<const void>(payload_.data()),
-                              static_cast<uint32_t>(payload_.size()),
-                              nullptr,
+    CHECK_EQ(mp->WriteMessage(0, UserPointer<const void>(payload_.data()),
+                              static_cast<uint32_t>(payload_.size()), nullptr,
                               MOJO_WRITE_MESSAGE_FLAG_NONE),
              MOJO_RESULT_OK);
     HandleSignalsState hss;
     CHECK_EQ(test::WaitIfNecessary(mp, MOJO_HANDLE_SIGNAL_READABLE, &hss),
              MOJO_RESULT_OK);
     uint32_t read_buffer_size = static_cast<uint32_t>(read_buffer_.size());
-    CHECK_EQ(mp->ReadMessage(0,
-                             UserPointer<void>(&read_buffer_[0]),
-                             MakeUserPointer(&read_buffer_size),
-                             nullptr,
-                             nullptr,
-                             MOJO_READ_MESSAGE_FLAG_NONE),
+    CHECK_EQ(mp->ReadMessage(0, UserPointer<void>(&read_buffer_[0]),
+                             MakeUserPointer(&read_buffer_size), nullptr,
+                             nullptr, MOJO_READ_MESSAGE_FLAG_NONE),
              MOJO_RESULT_OK);
     CHECK_EQ(read_buffer_size, static_cast<uint32_t>(payload_.size()));
   }
 
   void SendQuitMessage(scoped_refptr<MessagePipe> mp) {
-    CHECK_EQ(mp->WriteMessage(0,
-                              UserPointer<const void>(""),
-                              0,
-                              nullptr,
+    CHECK_EQ(mp->WriteMessage(0, UserPointer<const void>(""), 0, nullptr,
                               MOJO_WRITE_MESSAGE_FLAG_NONE),
              MOJO_RESULT_OK);
   }
@@ -81,8 +73,7 @@
     WriteWaitThenRead(mp);
 
     std::string test_name =
-        base::StringPrintf("IPC_Perf_%dx_%u",
-                           message_count_,
+        base::StringPrintf("IPC_Perf_%dx_%u", message_count_,
                            static_cast<unsigned>(message_size_));
     base::PerfTimeLogger logger(test_name.c_str());
 
@@ -127,11 +118,8 @@
     }
 
     uint32_t read_size = static_cast<uint32_t>(buffer.size());
-    CHECK_EQ(mp->ReadMessage(0,
-                             UserPointer<void>(&buffer[0]),
-                             MakeUserPointer(&read_size),
-                             nullptr,
-                             nullptr,
+    CHECK_EQ(mp->ReadMessage(0, UserPointer<void>(&buffer[0]),
+                             MakeUserPointer(&read_size), nullptr, nullptr,
                              MOJO_READ_MESSAGE_FLAG_NONE),
              MOJO_RESULT_OK);
 
@@ -139,10 +127,8 @@
     if (0 == read_size)
       break;
 
-    CHECK_EQ(mp->WriteMessage(0,
-                              UserPointer<const void>(&buffer[0]),
-                              static_cast<uint32_t>(read_size),
-                              nullptr,
+    CHECK_EQ(mp->WriteMessage(0, UserPointer<const void>(&buffer[0]),
+                              static_cast<uint32_t>(read_size), nullptr,
                               MOJO_WRITE_MESSAGE_FLAG_NONE),
              MOJO_RESULT_OK);
   }
diff --git a/mojo/edk/system/message_pipe_test_utils.cc b/mojo/edk/system/message_pipe_test_utils.cc
index 8f217ca..e5df26d 100644
--- a/mojo/edk/system/message_pipe_test_utils.cc
+++ b/mojo/edk/system/message_pipe_test_utils.cc
@@ -46,10 +46,8 @@
   test_io_thread_.Start();
   test_io_thread_.PostTaskAndWait(
       FROM_HERE,
-      base::Bind(&ChannelThread::InitChannelOnIOThread,
-                 base::Unretained(this),
-                 base::Passed(&platform_handle),
-                 channel_endpoint));
+      base::Bind(&ChannelThread::InitChannelOnIOThread, base::Unretained(this),
+                 base::Passed(&platform_handle), channel_endpoint));
 }
 
 void ChannelThread::Stop() {
@@ -61,9 +59,8 @@
       base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(20));
 
     test_io_thread_.PostTaskAndWait(
-        FROM_HERE,
-        base::Bind(&ChannelThread::ShutdownChannelOnIOThread,
-                   base::Unretained(this)));
+        FROM_HERE, base::Bind(&ChannelThread::ShutdownChannelOnIOThread,
+                              base::Unretained(this)));
   }
   test_io_thread_.Stop();
 }
diff --git a/mojo/edk/system/message_pipe_unittest.cc b/mojo/edk/system/message_pipe_unittest.cc
index dbffb4c..030084b 100644
--- a/mojo/edk/system/message_pipe_unittest.cc
+++ b/mojo/edk/system/message_pipe_unittest.cc
@@ -39,11 +39,8 @@
   buffer[1] = 456;
   buffer_size = kBufferSize;
   EXPECT_EQ(MOJO_RESULT_SHOULD_WAIT,
-            mp->ReadMessage(0,
-                            UserPointer<void>(buffer),
-                            MakeUserPointer(&buffer_size),
-                            0,
-                            nullptr,
+            mp->ReadMessage(0, UserPointer<void>(buffer),
+                            MakeUserPointer(&buffer_size), 0, nullptr,
                             MOJO_READ_MESSAGE_FLAG_NONE));
   EXPECT_EQ(kBufferSize, buffer_size);
   EXPECT_EQ(123, buffer[0]);
@@ -54,21 +51,16 @@
   buffer[1] = 456;
   buffer_size = kBufferSize;
   EXPECT_EQ(MOJO_RESULT_SHOULD_WAIT,
-            mp->ReadMessage(1,
-                            UserPointer<void>(buffer),
-                            MakeUserPointer(&buffer_size),
-                            0,
-                            nullptr,
+            mp->ReadMessage(1, UserPointer<void>(buffer),
+                            MakeUserPointer(&buffer_size), 0, nullptr,
                             MOJO_READ_MESSAGE_FLAG_NONE));
 
   // Write from port 1 (to port 0).
   buffer[0] = 789012345;
   buffer[1] = 0;
   EXPECT_EQ(MOJO_RESULT_OK,
-            mp->WriteMessage(1,
-                             UserPointer<const void>(buffer),
-                             static_cast<uint32_t>(sizeof(buffer[0])),
-                             nullptr,
+            mp->WriteMessage(1, UserPointer<const void>(buffer),
+                             static_cast<uint32_t>(sizeof(buffer[0])), nullptr,
                              MOJO_WRITE_MESSAGE_FLAG_NONE));
 
   // Read from port 0.
@@ -76,11 +68,8 @@
   buffer[1] = 456;
   buffer_size = kBufferSize;
   EXPECT_EQ(MOJO_RESULT_OK,
-            mp->ReadMessage(0,
-                            UserPointer<void>(buffer),
-                            MakeUserPointer(&buffer_size),
-                            0,
-                            nullptr,
+            mp->ReadMessage(0, UserPointer<void>(buffer),
+                            MakeUserPointer(&buffer_size), 0, nullptr,
                             MOJO_READ_MESSAGE_FLAG_NONE));
   EXPECT_EQ(static_cast<uint32_t>(sizeof(buffer[0])), buffer_size);
   EXPECT_EQ(789012345, buffer[0]);
@@ -89,41 +78,30 @@
   // Read again from port 0 -- it should be empty.
   buffer_size = kBufferSize;
   EXPECT_EQ(MOJO_RESULT_SHOULD_WAIT,
-            mp->ReadMessage(0,
-                            UserPointer<void>(buffer),
-                            MakeUserPointer(&buffer_size),
-                            0,
-                            nullptr,
+            mp->ReadMessage(0, UserPointer<void>(buffer),
+                            MakeUserPointer(&buffer_size), 0, nullptr,
                             MOJO_READ_MESSAGE_FLAG_NONE));
 
   // Write two messages from port 0 (to port 1).
   buffer[0] = 123456789;
   buffer[1] = 0;
   EXPECT_EQ(MOJO_RESULT_OK,
-            mp->WriteMessage(0,
-                             UserPointer<const void>(buffer),
-                             static_cast<uint32_t>(sizeof(buffer[0])),
-                             nullptr,
+            mp->WriteMessage(0, UserPointer<const void>(buffer),
+                             static_cast<uint32_t>(sizeof(buffer[0])), nullptr,
                              MOJO_WRITE_MESSAGE_FLAG_NONE));
   buffer[0] = 234567890;
   buffer[1] = 0;
   EXPECT_EQ(MOJO_RESULT_OK,
-            mp->WriteMessage(0,
-                             UserPointer<const void>(buffer),
-                             static_cast<uint32_t>(sizeof(buffer[0])),
-                             nullptr,
+            mp->WriteMessage(0, UserPointer<const void>(buffer),
+                             static_cast<uint32_t>(sizeof(buffer[0])), nullptr,
                              MOJO_WRITE_MESSAGE_FLAG_NONE));
 
   // Read from port 1 with buffer size 0 (should get the size of next message).
   // Also test that giving a null buffer is okay when the buffer size is 0.
   buffer_size = 0;
   EXPECT_EQ(MOJO_RESULT_RESOURCE_EXHAUSTED,
-            mp->ReadMessage(1,
-                            NullUserPointer(),
-                            MakeUserPointer(&buffer_size),
-                            0,
-                            nullptr,
-                            MOJO_READ_MESSAGE_FLAG_NONE));
+            mp->ReadMessage(1, NullUserPointer(), MakeUserPointer(&buffer_size),
+                            0, nullptr, MOJO_READ_MESSAGE_FLAG_NONE));
   EXPECT_EQ(static_cast<uint32_t>(sizeof(buffer[0])), buffer_size);
 
   // Read from port 1 with buffer size 1 (too small; should get the size of next
@@ -132,11 +110,8 @@
   buffer[1] = 456;
   buffer_size = 1;
   EXPECT_EQ(MOJO_RESULT_RESOURCE_EXHAUSTED,
-            mp->ReadMessage(1,
-                            UserPointer<void>(buffer),
-                            MakeUserPointer(&buffer_size),
-                            0,
-                            nullptr,
+            mp->ReadMessage(1, UserPointer<void>(buffer),
+                            MakeUserPointer(&buffer_size), 0, nullptr,
                             MOJO_READ_MESSAGE_FLAG_NONE));
   EXPECT_EQ(static_cast<uint32_t>(sizeof(buffer[0])), buffer_size);
   EXPECT_EQ(123, buffer[0]);
@@ -147,11 +122,8 @@
   buffer[1] = 456;
   buffer_size = kBufferSize;
   EXPECT_EQ(MOJO_RESULT_OK,
-            mp->ReadMessage(1,
-                            UserPointer<void>(buffer),
-                            MakeUserPointer(&buffer_size),
-                            0,
-                            nullptr,
+            mp->ReadMessage(1, UserPointer<void>(buffer),
+                            MakeUserPointer(&buffer_size), 0, nullptr,
                             MOJO_READ_MESSAGE_FLAG_NONE));
   EXPECT_EQ(static_cast<uint32_t>(sizeof(buffer[0])), buffer_size);
   EXPECT_EQ(123456789, buffer[0]);
@@ -162,11 +134,8 @@
   buffer[1] = 456;
   buffer_size = kBufferSize;
   EXPECT_EQ(MOJO_RESULT_OK,
-            mp->ReadMessage(1,
-                            UserPointer<void>(buffer),
-                            MakeUserPointer(&buffer_size),
-                            0,
-                            nullptr,
+            mp->ReadMessage(1, UserPointer<void>(buffer),
+                            MakeUserPointer(&buffer_size), 0, nullptr,
                             MOJO_READ_MESSAGE_FLAG_NONE));
   EXPECT_EQ(static_cast<uint32_t>(sizeof(buffer[0])), buffer_size);
   EXPECT_EQ(234567890, buffer[0]);
@@ -175,21 +144,16 @@
   // Read again from port 1 -- it should be empty.
   buffer_size = kBufferSize;
   EXPECT_EQ(MOJO_RESULT_SHOULD_WAIT,
-            mp->ReadMessage(1,
-                            UserPointer<void>(buffer),
-                            MakeUserPointer(&buffer_size),
-                            0,
-                            nullptr,
+            mp->ReadMessage(1, UserPointer<void>(buffer),
+                            MakeUserPointer(&buffer_size), 0, nullptr,
                             MOJO_READ_MESSAGE_FLAG_NONE));
 
   // Write from port 0 (to port 1).
   buffer[0] = 345678901;
   buffer[1] = 0;
   EXPECT_EQ(MOJO_RESULT_OK,
-            mp->WriteMessage(0,
-                             UserPointer<const void>(buffer),
-                             static_cast<uint32_t>(sizeof(buffer[0])),
-                             nullptr,
+            mp->WriteMessage(0, UserPointer<const void>(buffer),
+                             static_cast<uint32_t>(sizeof(buffer[0])), nullptr,
                              MOJO_WRITE_MESSAGE_FLAG_NONE));
 
   // Close port 0.
@@ -199,10 +163,8 @@
   buffer[0] = 456789012;
   buffer[1] = 0;
   EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION,
-            mp->WriteMessage(1,
-                             UserPointer<const void>(buffer),
-                             static_cast<uint32_t>(sizeof(buffer[0])),
-                             nullptr,
+            mp->WriteMessage(1, UserPointer<const void>(buffer),
+                             static_cast<uint32_t>(sizeof(buffer[0])), nullptr,
                              MOJO_WRITE_MESSAGE_FLAG_NONE));
 
   // Read from port 1; should still get message (even though port 0 was closed).
@@ -210,11 +172,8 @@
   buffer[1] = 456;
   buffer_size = kBufferSize;
   EXPECT_EQ(MOJO_RESULT_OK,
-            mp->ReadMessage(1,
-                            UserPointer<void>(buffer),
-                            MakeUserPointer(&buffer_size),
-                            0,
-                            nullptr,
+            mp->ReadMessage(1, UserPointer<void>(buffer),
+                            MakeUserPointer(&buffer_size), 0, nullptr,
                             MOJO_READ_MESSAGE_FLAG_NONE));
   EXPECT_EQ(static_cast<uint32_t>(sizeof(buffer[0])), buffer_size);
   EXPECT_EQ(345678901, buffer[0]);
@@ -223,11 +182,8 @@
   // Read again from port 1 -- it should be empty (and port 0 is closed).
   buffer_size = kBufferSize;
   EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION,
-            mp->ReadMessage(1,
-                            UserPointer<void>(buffer),
-                            MakeUserPointer(&buffer_size),
-                            0,
-                            nullptr,
+            mp->ReadMessage(1, UserPointer<void>(buffer),
+                            MakeUserPointer(&buffer_size), 0, nullptr,
                             MOJO_READ_MESSAGE_FLAG_NONE));
 
   mp->Close(1);
@@ -244,22 +200,15 @@
   for (int32_t i = 0; i < 5; i++) {
     buffer[0] = i;
     EXPECT_EQ(MOJO_RESULT_OK,
-              mp->WriteMessage(1,
-                               UserPointer<const void>(buffer),
-                               kBufferSize,
-                               nullptr,
-                               MOJO_WRITE_MESSAGE_FLAG_NONE));
+              mp->WriteMessage(1, UserPointer<const void>(buffer), kBufferSize,
+                               nullptr, MOJO_WRITE_MESSAGE_FLAG_NONE));
   }
 
   // Port 0 shouldn't be empty.
   buffer_size = 0;
   EXPECT_EQ(MOJO_RESULT_RESOURCE_EXHAUSTED,
-            mp->ReadMessage(0,
-                            NullUserPointer(),
-                            MakeUserPointer(&buffer_size),
-                            0,
-                            nullptr,
-                            MOJO_READ_MESSAGE_FLAG_NONE));
+            mp->ReadMessage(0, NullUserPointer(), MakeUserPointer(&buffer_size),
+                            0, nullptr, MOJO_READ_MESSAGE_FLAG_NONE));
   EXPECT_EQ(kBufferSize, buffer_size);
 
   // Close port 0 first, which should have outstanding (incoming) messages.
@@ -278,41 +227,30 @@
   buffer[0] = 789012345;
   buffer[1] = 0;
   EXPECT_EQ(MOJO_RESULT_OK,
-            mp->WriteMessage(1,
-                             UserPointer<const void>(buffer),
-                             static_cast<uint32_t>(sizeof(buffer[0])),
-                             nullptr,
+            mp->WriteMessage(1, UserPointer<const void>(buffer),
+                             static_cast<uint32_t>(sizeof(buffer[0])), nullptr,
                              MOJO_WRITE_MESSAGE_FLAG_NONE));
 
   // Read/discard from port 0 (no buffer); get size.
   buffer_size = 0;
   EXPECT_EQ(MOJO_RESULT_RESOURCE_EXHAUSTED,
-            mp->ReadMessage(0,
-                            NullUserPointer(),
-                            MakeUserPointer(&buffer_size),
-                            0,
-                            nullptr,
-                            MOJO_READ_MESSAGE_FLAG_MAY_DISCARD));
+            mp->ReadMessage(0, NullUserPointer(), MakeUserPointer(&buffer_size),
+                            0, nullptr, MOJO_READ_MESSAGE_FLAG_MAY_DISCARD));
   EXPECT_EQ(static_cast<uint32_t>(sizeof(buffer[0])), buffer_size);
 
   // Read again from port 0 -- it should be empty.
   buffer_size = kBufferSize;
   EXPECT_EQ(MOJO_RESULT_SHOULD_WAIT,
-            mp->ReadMessage(0,
-                            UserPointer<void>(buffer),
-                            MakeUserPointer(&buffer_size),
-                            0,
-                            nullptr,
+            mp->ReadMessage(0, UserPointer<void>(buffer),
+                            MakeUserPointer(&buffer_size), 0, nullptr,
                             MOJO_READ_MESSAGE_FLAG_MAY_DISCARD));
 
   // Write from port 1 (to port 0).
   buffer[0] = 890123456;
   buffer[1] = 0;
   EXPECT_EQ(MOJO_RESULT_OK,
-            mp->WriteMessage(1,
-                             UserPointer<const void>(buffer),
-                             static_cast<uint32_t>(sizeof(buffer[0])),
-                             nullptr,
+            mp->WriteMessage(1, UserPointer<const void>(buffer),
+                             static_cast<uint32_t>(sizeof(buffer[0])), nullptr,
                              MOJO_WRITE_MESSAGE_FLAG_NONE));
 
   // Read from port 0 (buffer big enough).
@@ -320,11 +258,8 @@
   buffer[1] = 456;
   buffer_size = kBufferSize;
   EXPECT_EQ(MOJO_RESULT_OK,
-            mp->ReadMessage(0,
-                            UserPointer<void>(buffer),
-                            MakeUserPointer(&buffer_size),
-                            0,
-                            nullptr,
+            mp->ReadMessage(0, UserPointer<void>(buffer),
+                            MakeUserPointer(&buffer_size), 0, nullptr,
                             MOJO_READ_MESSAGE_FLAG_MAY_DISCARD));
   EXPECT_EQ(static_cast<uint32_t>(sizeof(buffer[0])), buffer_size);
   EXPECT_EQ(890123456, buffer[0]);
@@ -333,72 +268,52 @@
   // Read again from port 0 -- it should be empty.
   buffer_size = kBufferSize;
   EXPECT_EQ(MOJO_RESULT_SHOULD_WAIT,
-            mp->ReadMessage(0,
-                            UserPointer<void>(buffer),
-                            MakeUserPointer(&buffer_size),
-                            0,
-                            nullptr,
+            mp->ReadMessage(0, UserPointer<void>(buffer),
+                            MakeUserPointer(&buffer_size), 0, nullptr,
                             MOJO_READ_MESSAGE_FLAG_MAY_DISCARD));
 
   // Write from port 1 (to port 0).
   buffer[0] = 901234567;
   buffer[1] = 0;
   EXPECT_EQ(MOJO_RESULT_OK,
-            mp->WriteMessage(1,
-                             UserPointer<const void>(buffer),
-                             static_cast<uint32_t>(sizeof(buffer[0])),
-                             nullptr,
+            mp->WriteMessage(1, UserPointer<const void>(buffer),
+                             static_cast<uint32_t>(sizeof(buffer[0])), nullptr,
                              MOJO_WRITE_MESSAGE_FLAG_NONE));
 
   // Read/discard from port 0 (buffer too small); get size.
   buffer_size = 1;
   EXPECT_EQ(MOJO_RESULT_RESOURCE_EXHAUSTED,
-            mp->ReadMessage(0,
-                            UserPointer<void>(buffer),
-                            MakeUserPointer(&buffer_size),
-                            0,
-                            nullptr,
+            mp->ReadMessage(0, UserPointer<void>(buffer),
+                            MakeUserPointer(&buffer_size), 0, nullptr,
                             MOJO_READ_MESSAGE_FLAG_MAY_DISCARD));
   EXPECT_EQ(static_cast<uint32_t>(sizeof(buffer[0])), buffer_size);
 
   // Read again from port 0 -- it should be empty.
   buffer_size = kBufferSize;
   EXPECT_EQ(MOJO_RESULT_SHOULD_WAIT,
-            mp->ReadMessage(0,
-                            UserPointer<void>(buffer),
-                            MakeUserPointer(&buffer_size),
-                            0,
-                            nullptr,
+            mp->ReadMessage(0, UserPointer<void>(buffer),
+                            MakeUserPointer(&buffer_size), 0, nullptr,
                             MOJO_READ_MESSAGE_FLAG_MAY_DISCARD));
 
   // Write from port 1 (to port 0).
   buffer[0] = 123456789;
   buffer[1] = 0;
   EXPECT_EQ(MOJO_RESULT_OK,
-            mp->WriteMessage(1,
-                             UserPointer<const void>(buffer),
-                             static_cast<uint32_t>(sizeof(buffer[0])),
-                             nullptr,
+            mp->WriteMessage(1, UserPointer<const void>(buffer),
+                             static_cast<uint32_t>(sizeof(buffer[0])), nullptr,
                              MOJO_WRITE_MESSAGE_FLAG_NONE));
 
   // Discard from port 0.
   buffer_size = 1;
   EXPECT_EQ(MOJO_RESULT_RESOURCE_EXHAUSTED,
-            mp->ReadMessage(0,
-                            NullUserPointer(),
-                            NullUserPointer(),
-                            0,
-                            nullptr,
+            mp->ReadMessage(0, NullUserPointer(), NullUserPointer(), 0, nullptr,
                             MOJO_READ_MESSAGE_FLAG_MAY_DISCARD));
 
   // Read again from port 0 -- it should be empty.
   buffer_size = kBufferSize;
   EXPECT_EQ(MOJO_RESULT_SHOULD_WAIT,
-            mp->ReadMessage(0,
-                            UserPointer<void>(buffer),
-                            MakeUserPointer(&buffer_size),
-                            0,
-                            nullptr,
+            mp->ReadMessage(0, UserPointer<void>(buffer),
+                            MakeUserPointer(&buffer_size), 0, nullptr,
                             MOJO_READ_MESSAGE_FLAG_MAY_DISCARD));
 
   mp->Close(0);
@@ -424,13 +339,10 @@
             hss.satisfiable_signals);
   waiter.Init();
   hss = HandleSignalsState();
-  EXPECT_EQ(
-      MOJO_RESULT_ALREADY_EXISTS,
-      mp->AddWaiter(0,
-                    &waiter,
-                    MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE,
-                    0,
-                    &hss));
+  EXPECT_EQ(MOJO_RESULT_ALREADY_EXISTS,
+            mp->AddWaiter(0, &waiter, MOJO_HANDLE_SIGNAL_READABLE |
+                                          MOJO_HANDLE_SIGNAL_WRITABLE,
+                          0, &hss));
   EXPECT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE, hss.satisfied_signals);
   EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE,
             hss.satisfiable_signals);
@@ -449,11 +361,8 @@
   // Write from port 0 (to port 1), to make port 1 readable.
   buffer[0] = 123456789;
   EXPECT_EQ(MOJO_RESULT_OK,
-            mp->WriteMessage(0,
-                             UserPointer<const void>(buffer),
-                             kBufferSize,
-                             nullptr,
-                             MOJO_WRITE_MESSAGE_FLAG_NONE));
+            mp->WriteMessage(0, UserPointer<const void>(buffer), kBufferSize,
+                             nullptr, MOJO_WRITE_MESSAGE_FLAG_NONE));
 
   // Port 1 should already be readable now.
   waiter.Init();
@@ -466,13 +375,10 @@
             hss.satisfiable_signals);
   waiter.Init();
   hss = HandleSignalsState();
-  EXPECT_EQ(
-      MOJO_RESULT_ALREADY_EXISTS,
-      mp->AddWaiter(1,
-                    &waiter,
-                    MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE,
-                    0,
-                    &hss));
+  EXPECT_EQ(MOJO_RESULT_ALREADY_EXISTS,
+            mp->AddWaiter(1, &waiter, MOJO_HANDLE_SIGNAL_READABLE |
+                                          MOJO_HANDLE_SIGNAL_WRITABLE,
+                          0, &hss));
   EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE,
             hss.satisfied_signals);
   EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE,
@@ -510,11 +416,8 @@
   buffer[0] = 0;
   buffer_size = kBufferSize;
   EXPECT_EQ(MOJO_RESULT_OK,
-            mp->ReadMessage(1,
-                            UserPointer<void>(buffer),
-                            MakeUserPointer(&buffer_size),
-                            0,
-                            nullptr,
+            mp->ReadMessage(1, UserPointer<void>(buffer),
+                            MakeUserPointer(&buffer_size), 0, nullptr,
                             MOJO_READ_MESSAGE_FLAG_NONE));
   EXPECT_EQ(123456789, buffer[0]);
 
@@ -543,18 +446,15 @@
 
     thread.waiter()->Init();
     ASSERT_EQ(MOJO_RESULT_OK,
-              mp->AddWaiter(
-                  1, thread.waiter(), MOJO_HANDLE_SIGNAL_READABLE, 1, nullptr));
+              mp->AddWaiter(1, thread.waiter(), MOJO_HANDLE_SIGNAL_READABLE, 1,
+                            nullptr));
     thread.Start();
 
     buffer[0] = 123456789;
     // Write from port 0 (to port 1), which should wake up the waiter.
     EXPECT_EQ(MOJO_RESULT_OK,
-              mp->WriteMessage(0,
-                               UserPointer<const void>(buffer),
-                               kBufferSize,
-                               nullptr,
-                               MOJO_WRITE_MESSAGE_FLAG_NONE));
+              mp->WriteMessage(0, UserPointer<const void>(buffer), kBufferSize,
+                               nullptr, MOJO_WRITE_MESSAGE_FLAG_NONE));
 
     HandleSignalsState hss;
     mp->RemoveWaiter(1, thread.waiter(), &hss);
@@ -577,8 +477,8 @@
 
     thread.waiter()->Init();
     ASSERT_EQ(MOJO_RESULT_OK,
-              mp->AddWaiter(
-                  1, thread.waiter(), MOJO_HANDLE_SIGNAL_READABLE, 2, nullptr));
+              mp->AddWaiter(1, thread.waiter(), MOJO_HANDLE_SIGNAL_READABLE, 2,
+                            nullptr));
     thread.Start();
 
     // Close port 1 first -- this should result in the waiter being cancelled.
@@ -600,8 +500,8 @@
 
     thread.waiter()->Init();
     ASSERT_EQ(MOJO_RESULT_OK,
-              mp->AddWaiter(
-                  1, thread.waiter(), MOJO_HANDLE_SIGNAL_READABLE, 3, nullptr));
+              mp->AddWaiter(1, thread.waiter(), MOJO_HANDLE_SIGNAL_READABLE, 3,
+                            nullptr));
     thread.Start();
 
     // Close port 0 first -- this should wake the waiter up, since port 1 will
diff --git a/mojo/edk/system/multiprocess_message_pipe_unittest.cc b/mojo/edk/system/multiprocess_message_pipe_unittest.cc
index 2f22d67..ab2e75c 100644
--- a/mojo/edk/system/multiprocess_message_pipe_unittest.cc
+++ b/mojo/edk/system/multiprocess_message_pipe_unittest.cc
@@ -72,12 +72,9 @@
 
     std::string read_buffer(1000, '\0');
     uint32_t read_buffer_size = static_cast<uint32_t>(read_buffer.size());
-    CHECK_EQ(mp->ReadMessage(0,
-                             UserPointer<void>(&read_buffer[0]),
-                             MakeUserPointer(&read_buffer_size),
-                             nullptr,
-                             nullptr,
-                             MOJO_READ_MESSAGE_FLAG_NONE),
+    CHECK_EQ(mp->ReadMessage(0, UserPointer<void>(&read_buffer[0]),
+                             MakeUserPointer(&read_buffer_size), nullptr,
+                             nullptr, MOJO_READ_MESSAGE_FLAG_NONE),
              MOJO_RESULT_OK);
     read_buffer.resize(read_buffer_size);
     VLOG(2) << "Child got: " << read_buffer;
@@ -88,11 +85,9 @@
     }
 
     std::string write_buffer = read_buffer + read_buffer;
-    CHECK_EQ(mp->WriteMessage(0,
-                              UserPointer<const void>(write_buffer.data()),
+    CHECK_EQ(mp->WriteMessage(0, UserPointer<const void>(write_buffer.data()),
                               static_cast<uint32_t>(write_buffer.size()),
-                              nullptr,
-                              MOJO_WRITE_MESSAGE_FLAG_NONE),
+                              nullptr, MOJO_WRITE_MESSAGE_FLAG_NONE),
              MOJO_RESULT_OK);
   }
 
@@ -110,10 +105,8 @@
 
   std::string hello("hello");
   EXPECT_EQ(MOJO_RESULT_OK,
-            mp->WriteMessage(0,
-                             UserPointer<const void>(hello.data()),
-                             static_cast<uint32_t>(hello.size()),
-                             nullptr,
+            mp->WriteMessage(0, UserPointer<const void>(hello.data()),
+                             static_cast<uint32_t>(hello.size()), nullptr,
                              MOJO_WRITE_MESSAGE_FLAG_NONE));
 
   HandleSignalsState hss;
@@ -127,11 +120,8 @@
 
   std::string read_buffer(1000, '\0');
   uint32_t read_buffer_size = static_cast<uint32_t>(read_buffer.size());
-  CHECK_EQ(mp->ReadMessage(0,
-                           UserPointer<void>(&read_buffer[0]),
-                           MakeUserPointer(&read_buffer_size),
-                           nullptr,
-                           nullptr,
+  CHECK_EQ(mp->ReadMessage(0, UserPointer<void>(&read_buffer[0]),
+                           MakeUserPointer(&read_buffer_size), nullptr, nullptr,
                            MOJO_READ_MESSAGE_FLAG_NONE),
            MOJO_RESULT_OK);
   read_buffer.resize(read_buffer_size);
@@ -157,20 +147,16 @@
   for (size_t i = 0; i < kNumMessages; i++) {
     std::string write_buffer(i, 'A' + (i % 26));
     EXPECT_EQ(MOJO_RESULT_OK,
-              mp->WriteMessage(0,
-                               UserPointer<const void>(write_buffer.data()),
+              mp->WriteMessage(0, UserPointer<const void>(write_buffer.data()),
                                static_cast<uint32_t>(write_buffer.size()),
-                               nullptr,
-                               MOJO_WRITE_MESSAGE_FLAG_NONE));
+                               nullptr, MOJO_WRITE_MESSAGE_FLAG_NONE));
   }
 
   const std::string quitquitquit("quitquitquit");
   EXPECT_EQ(MOJO_RESULT_OK,
-            mp->WriteMessage(0,
-                             UserPointer<const void>(quitquitquit.data()),
+            mp->WriteMessage(0, UserPointer<const void>(quitquitquit.data()),
                              static_cast<uint32_t>(quitquitquit.size()),
-                             nullptr,
-                             MOJO_WRITE_MESSAGE_FLAG_NONE));
+                             nullptr, MOJO_WRITE_MESSAGE_FLAG_NONE));
 
   for (size_t i = 0; i < kNumMessages; i++) {
     HandleSignalsState hss;
@@ -184,12 +170,9 @@
 
     std::string read_buffer(kNumMessages * 2, '\0');
     uint32_t read_buffer_size = static_cast<uint32_t>(read_buffer.size());
-    CHECK_EQ(mp->ReadMessage(0,
-                             UserPointer<void>(&read_buffer[0]),
-                             MakeUserPointer(&read_buffer_size),
-                             nullptr,
-                             nullptr,
-                             MOJO_READ_MESSAGE_FLAG_NONE),
+    CHECK_EQ(mp->ReadMessage(0, UserPointer<void>(&read_buffer[0]),
+                             MakeUserPointer(&read_buffer_size), nullptr,
+                             nullptr, MOJO_READ_MESSAGE_FLAG_NONE),
              MOJO_RESULT_OK);
     read_buffer.resize(read_buffer_size);
 
@@ -236,12 +219,9 @@
   uint32_t num_bytes = static_cast<uint32_t>(read_buffer.size());
   DispatcherVector dispatchers;
   uint32_t num_dispatchers = 10;  // Maximum number to receive.
-  CHECK_EQ(mp->ReadMessage(0,
-                           UserPointer<void>(&read_buffer[0]),
-                           MakeUserPointer(&num_bytes),
-                           &dispatchers,
-                           &num_dispatchers,
-                           MOJO_READ_MESSAGE_FLAG_NONE),
+  CHECK_EQ(mp->ReadMessage(0, UserPointer<void>(&read_buffer[0]),
+                           MakeUserPointer(&num_bytes), &dispatchers,
+                           &num_dispatchers, MOJO_READ_MESSAGE_FLAG_NONE),
            MOJO_RESULT_OK);
   read_buffer.resize(num_bytes);
   CHECK_EQ(read_buffer, std::string("go 1"));
@@ -269,10 +249,8 @@
 
   // And send a message to signal that we've written stuff.
   const std::string go2("go 2");
-  CHECK_EQ(mp->WriteMessage(0,
-                            UserPointer<const void>(&go2[0]),
-                            static_cast<uint32_t>(go2.size()),
-                            nullptr,
+  CHECK_EQ(mp->WriteMessage(0, UserPointer<const void>(&go2[0]),
+                            static_cast<uint32_t>(go2.size()), nullptr,
                             MOJO_WRITE_MESSAGE_FLAG_NONE),
            MOJO_RESULT_OK);
 
@@ -287,11 +265,8 @@
 
   read_buffer = std::string(100, '\0');
   num_bytes = static_cast<uint32_t>(read_buffer.size());
-  CHECK_EQ(mp->ReadMessage(0,
-                           UserPointer<void>(&read_buffer[0]),
-                           MakeUserPointer(&num_bytes),
-                           nullptr,
-                           nullptr,
+  CHECK_EQ(mp->ReadMessage(0, UserPointer<void>(&read_buffer[0]),
+                           MakeUserPointer(&num_bytes), nullptr, nullptr,
                            MOJO_READ_MESSAGE_FLAG_NONE),
            MOJO_RESULT_OK);
   read_buffer.resize(num_bytes);
@@ -322,12 +297,10 @@
 
   // Make a shared buffer.
   scoped_refptr<SharedBufferDispatcher> dispatcher;
-  EXPECT_EQ(MOJO_RESULT_OK,
-            SharedBufferDispatcher::Create(
-                platform_support(),
-                SharedBufferDispatcher::kDefaultCreateOptions,
-                100,
-                &dispatcher));
+  EXPECT_EQ(MOJO_RESULT_OK, SharedBufferDispatcher::Create(
+                                platform_support(),
+                                SharedBufferDispatcher::kDefaultCreateOptions,
+                                100, &dispatcher));
   ASSERT_TRUE(dispatcher.get());
 
   // Make a mapping.
@@ -347,10 +320,8 @@
   std::vector<DispatcherTransport> transports;
   transports.push_back(transport);
   EXPECT_EQ(MOJO_RESULT_OK,
-            mp->WriteMessage(0,
-                             UserPointer<const void>(&go1[0]),
-                             static_cast<uint32_t>(go1.size()),
-                             &transports,
+            mp->WriteMessage(0, UserPointer<const void>(&go1[0]),
+                             static_cast<uint32_t>(go1.size()), &transports,
                              MOJO_WRITE_MESSAGE_FLAG_NONE));
   transport.End();
 
@@ -367,11 +338,8 @@
   std::string read_buffer(100, '\0');
   uint32_t num_bytes = static_cast<uint32_t>(read_buffer.size());
   EXPECT_EQ(MOJO_RESULT_OK,
-            mp->ReadMessage(0,
-                            UserPointer<void>(&read_buffer[0]),
-                            MakeUserPointer(&num_bytes),
-                            nullptr,
-                            nullptr,
+            mp->ReadMessage(0, UserPointer<void>(&read_buffer[0]),
+                            MakeUserPointer(&num_bytes), nullptr, nullptr,
                             MOJO_READ_MESSAGE_FLAG_NONE));
   read_buffer.resize(num_bytes);
   EXPECT_EQ(std::string("go 2"), read_buffer);
@@ -388,10 +356,8 @@
   // And send a message to signal that we've written stuff.
   const std::string go3("go 3");
   EXPECT_EQ(MOJO_RESULT_OK,
-            mp->WriteMessage(0,
-                             UserPointer<const void>(&go3[0]),
-                             static_cast<uint32_t>(go3.size()),
-                             nullptr,
+            mp->WriteMessage(0, UserPointer<const void>(&go3[0]),
+                             static_cast<uint32_t>(go3.size()), nullptr,
                              MOJO_WRITE_MESSAGE_FLAG_NONE));
 
   // Wait for |mp| to become readable, which should fail.
@@ -428,12 +394,9 @@
   uint32_t num_bytes = static_cast<uint32_t>(read_buffer.size());
   DispatcherVector dispatchers;
   uint32_t num_dispatchers = 10;  // Maximum number to receive.
-  CHECK_EQ(mp->ReadMessage(0,
-                           UserPointer<void>(&read_buffer[0]),
-                           MakeUserPointer(&num_bytes),
-                           &dispatchers,
-                           &num_dispatchers,
-                           MOJO_READ_MESSAGE_FLAG_NONE),
+  CHECK_EQ(mp->ReadMessage(0, UserPointer<void>(&read_buffer[0]),
+                           MakeUserPointer(&num_bytes), &dispatchers,
+                           &num_dispatchers, MOJO_READ_MESSAGE_FLAG_NONE),
            MOJO_RESULT_OK);
   mp->Close(0);
 
@@ -496,10 +459,8 @@
   std::vector<DispatcherTransport> transports;
   transports.push_back(transport);
   EXPECT_EQ(MOJO_RESULT_OK,
-            mp->WriteMessage(0,
-                             UserPointer<const void>(&hello[0]),
-                             static_cast<uint32_t>(hello.size()),
-                             &transports,
+            mp->WriteMessage(0, UserPointer<const void>(&hello[0]),
+                             static_cast<uint32_t>(hello.size()), &transports,
                              MOJO_WRITE_MESSAGE_FLAG_NONE));
   transport.End();
 
diff --git a/mojo/edk/system/options_validation.h b/mojo/edk/system/options_validation.h
index 4772508..9724e38 100644
--- a/mojo/edk/system/options_validation.h
+++ b/mojo/edk/system/options_validation.h
@@ -18,7 +18,6 @@
 
 #include "base/logging.h"
 #include "base/macros.h"
-#include "mojo/edk/system/constants.h"
 #include "mojo/edk/system/memory.h"
 #include "mojo/edk/system/system_impl_export.h"
 #include "mojo/public/c/system/types.h"
diff --git a/mojo/edk/system/platform_handle_dispatcher.cc b/mojo/edk/system/platform_handle_dispatcher.cc
index a6072cf..f064c67 100644
--- a/mojo/edk/system/platform_handle_dispatcher.cc
+++ b/mojo/edk/system/platform_handle_dispatcher.cc
@@ -43,7 +43,7 @@
     embedder::PlatformHandleVector* platform_handles) {
   if (size != sizeof(SerializedPlatformHandleDispatcher)) {
     LOG(ERROR) << "Invalid serialized platform handle dispatcher (bad size)";
-    return scoped_refptr<PlatformHandleDispatcher>();
+    return nullptr;
   }
 
   const SerializedPlatformHandleDispatcher* serialization =
@@ -58,7 +58,7 @@
         platform_handle_index >= platform_handles->size()) {
       LOG(ERROR)
           << "Invalid serialized platform handle dispatcher (missing handles)";
-      return scoped_refptr<PlatformHandleDispatcher>();
+      return nullptr;
     }
 
     // We take ownership of the handle, so we have to invalidate the one in
diff --git a/mojo/edk/system/raw_channel.cc b/mojo/edk/system/raw_channel.cc
index 0bfe104..4331166 100644
--- a/mojo/edk/system/raw_channel.cc
+++ b/mojo/edk/system/raw_channel.cc
@@ -133,9 +133,8 @@
   // attached.
 
   // Write from both buffers.
-  DCHECK_EQ(
-      bytes_to_write,
-      message->main_buffer_size() - data_offset_ + transport_data_buffer_size);
+  DCHECK_EQ(bytes_to_write, message->main_buffer_size() - data_offset_ +
+                                transport_data_buffer_size);
   Buffer buffer1 = {
       static_cast<const char*>(message->main_buffer()) + data_offset_,
       message->main_buffer_size() - data_offset_};
@@ -195,11 +194,9 @@
   if (io_result != IO_PENDING) {
     // This will notify the delegate about the read failure. Although we're on
     // the I/O thread, don't call it in the nested context.
-    message_loop_for_io_->PostTask(FROM_HERE,
-                                   base::Bind(&RawChannel::OnReadCompleted,
-                                              weak_ptr_factory_.GetWeakPtr(),
-                                              io_result,
-                                              0));
+    message_loop_for_io_->PostTask(
+        FROM_HERE, base::Bind(&RawChannel::OnReadCompleted,
+                              weak_ptr_factory_.GetWeakPtr(), io_result, 0));
   }
 
   // ScheduleRead() failure is treated as a read failure (by notifying the
@@ -246,15 +243,15 @@
   if (io_result == IO_PENDING)
     return true;
 
-  bool result = OnWriteCompletedNoLock(
-      io_result, platform_handles_written, bytes_written);
+  bool result = OnWriteCompletedNoLock(io_result, platform_handles_written,
+                                       bytes_written);
   if (!result) {
     // Even if we're on the I/O thread, don't call |OnError()| in the nested
     // context.
-    message_loop_for_io_->PostTask(FROM_HERE,
-                                   base::Bind(&RawChannel::CallOnError,
-                                              weak_ptr_factory_.GetWeakPtr(),
-                                              Delegate::ERROR_WRITE));
+    message_loop_for_io_->PostTask(
+        FROM_HERE,
+        base::Bind(&RawChannel::CallOnError, weak_ptr_factory_.GetWeakPtr(),
+                   Delegate::ERROR_WRITE));
   }
 
   return result;
@@ -312,8 +309,7 @@
     // TODO(vtl): Validate that |message_size| is sane.
     while (remaining_bytes > 0 && MessageInTransit::GetNextMessageSize(
                                       &read_buffer_->buffer_[read_buffer_start],
-                                      remaining_bytes,
-                                      &message_size) &&
+                                      remaining_bytes, &message_size) &&
            remaining_bytes >= message_size) {
       MessageInTransit::View message_view(
           message_size, &read_buffer_->buffer_[read_buffer_start]);
@@ -341,8 +337,7 @@
           size_t num_platform_handles;
           const void* platform_handle_table;
           TransportData::GetPlatformHandleTable(
-              message_view.transport_data_buffer(),
-              &num_platform_handles,
+              message_view.transport_data_buffer(), &num_platform_handles,
               &platform_handle_table);
 
           if (num_platform_handles > 0) {
@@ -383,8 +378,7 @@
       read_buffer_->num_valid_bytes_ = remaining_bytes;
       if (read_buffer_->num_valid_bytes_ > 0) {
         memmove(&read_buffer_->buffer_[0],
-                &read_buffer_->buffer_[read_buffer_start],
-                remaining_bytes);
+                &read_buffer_->buffer_[read_buffer_start], remaining_bytes);
       }
       read_buffer_start = 0;
     }
@@ -433,8 +427,8 @@
       return;
     }
 
-    did_fail = !OnWriteCompletedNoLock(
-                   io_result, platform_handles_written, bytes_written);
+    did_fail = !OnWriteCompletedNoLock(io_result, platform_handles_written,
+                                       bytes_written);
   }
 
   if (did_fail)
diff --git a/mojo/edk/system/raw_channel.h b/mojo/edk/system/raw_channel.h
index 1a077ef..62e13ff 100644
--- a/mojo/edk/system/raw_channel.h
+++ b/mojo/edk/system/raw_channel.h
@@ -14,7 +14,6 @@
 #include "base/synchronization/lock.h"
 #include "mojo/edk/embedder/platform_handle_vector.h"
 #include "mojo/edk/embedder/scoped_platform_handle.h"
-#include "mojo/edk/system/constants.h"
 #include "mojo/edk/system/message_in_transit.h"
 #include "mojo/edk/system/system_impl_export.h"
 
diff --git a/mojo/edk/system/raw_channel_posix.cc b/mojo/edk/system/raw_channel_posix.cc
index 45d93e8..71ec02f 100644
--- a/mojo/edk/system/raw_channel_posix.cc
+++ b/mojo/edk/system/raw_channel_posix.cc
@@ -135,8 +135,7 @@
            i += embedder::kPlatformChannelMaxNumHandles) {
         scoped_ptr<MessageInTransit> fd_message(new MessageInTransit(
             MessageInTransit::kTypeRawChannel,
-            MessageInTransit::kSubtypeRawChannelPosixExtraPlatformHandles,
-            0,
+            MessageInTransit::kSubtypeRawChannelPosixExtraPlatformHandles, 0,
             nullptr));
         embedder::ScopedPlatformHandleVectorPtr fds(
             new embedder::PlatformHandleVector(
@@ -253,8 +252,8 @@
     DCHECK(!buffers.empty());
 
     if (buffers.size() == 1) {
-      write_result = embedder::PlatformChannelWrite(
-          fd_.get(), buffers[0].addr, buffers[0].size);
+      write_result = embedder::PlatformChannelWrite(fd_.get(), buffers[0].addr,
+                                                    buffers[0].size);
     } else {
       const size_t kMaxBufferCount = 10;
       iovec iov[kMaxBufferCount];
@@ -302,11 +301,8 @@
   }
 
   if (message_loop_for_io()->WatchFileDescriptor(
-          fd_.get().fd,
-          false,
-          base::MessageLoopForIO::WATCH_WRITE,
-          write_watcher_.get(),
-          this)) {
+          fd_.get().fd, false, base::MessageLoopForIO::WATCH_WRITE,
+          write_watcher_.get(), this)) {
     pending_write_ = true;
     return IO_PENDING;
   }
@@ -323,11 +319,8 @@
   write_watcher_.reset(new base::MessageLoopForIO::FileDescriptorWatcher());
 
   if (!message_loop_for_io()->WatchFileDescriptor(
-          fd_.get().fd,
-          true,
-          base::MessageLoopForIO::WATCH_READ,
-          read_watcher_.get(),
-          this)) {
+          fd_.get().fd, true, base::MessageLoopForIO::WATCH_READ,
+          read_watcher_.get(), this)) {
     // TODO(vtl): I'm not sure |WatchFileDescriptor()| actually fails cleanly
     // (in the sense of returning the message loop's state to what it was before
     // it was called).
@@ -421,7 +414,7 @@
     // then received the message data plus the first set of handles for the next
     // message in the subsequent |recvmsg()|.)
     if (read_platform_handles_.size() >
-        (TransportData::kMaxPlatformHandles +
+        (TransportData::GetMaxPlatformHandles() +
          embedder::kPlatformChannelMaxNumHandles)) {
       LOG(ERROR) << "Received too many platform handles";
       embedder::CloseAllPlatformHandles(&read_platform_handles_);
@@ -455,11 +448,8 @@
   DCHECK(write_watcher_);
 
   if (!message_loop_for_io()->WatchFileDescriptor(
-          fd_.get().fd,
-          false,
-          base::MessageLoopForIO::WATCH_WRITE,
-          write_watcher_.get(),
-          this)) {
+          fd_.get().fd, false, base::MessageLoopForIO::WATCH_WRITE,
+          write_watcher_.get(), this)) {
     {
       base::AutoLock locker(write_lock());
 
diff --git a/mojo/edk/system/raw_channel_unittest.cc b/mojo/edk/system/raw_channel_unittest.cc
index 9ee937d..7717f49 100644
--- a/mojo/edk/system/raw_channel_unittest.cc
+++ b/mojo/edk/system/raw_channel_unittest.cc
@@ -41,8 +41,7 @@
   return make_scoped_ptr(
       new MessageInTransit(MessageInTransit::kTypeMessagePipeEndpoint,
                            MessageInTransit::kSubtypeMessagePipeEndpointData,
-                           num_bytes,
-                           bytes.empty() ? nullptr : &bytes[0]));
+                           num_bytes, bytes.empty() ? nullptr : &bytes[0]));
 }
 
 bool CheckMessageData(const void* bytes, uint32_t num_bytes) {
@@ -63,8 +62,8 @@
   scoped_ptr<MessageInTransit> message(MakeTestMessage(num_bytes));
 
   size_t write_size = 0;
-  mojo::test::BlockingWrite(
-      handle, message->main_buffer(), message->main_buffer_size(), &write_size);
+  mojo::test::BlockingWrite(handle, message->main_buffer(),
+                            message->main_buffer_size(), &write_size);
   return write_size == message->main_buffer_size();
 }
 
@@ -135,8 +134,8 @@
 
     for (size_t i = 0; i < kMessageReaderMaxPollIterations;) {
       size_t read_size = 0;
-      CHECK(mojo::test::NonBlockingRead(
-          handle_, buffer, sizeof(buffer), &read_size));
+      CHECK(mojo::test::NonBlockingRead(handle_, buffer, sizeof(buffer),
+                                        &read_size));
 
       // Append newly-read data to |bytes_|.
       bytes_.insert(bytes_.end(), buffer, buffer + read_size);
@@ -144,8 +143,7 @@
       // If we have the header....
       size_t message_size;
       if (MessageInTransit::GetNextMessageSize(
-              bytes_.empty() ? nullptr : &bytes_[0],
-              bytes_.size(),
+              bytes_.empty() ? nullptr : &bytes_[0], bytes_.size(),
               &message_size)) {
         // If we've read the whole message....
         if (bytes_.size() >= message_size) {
@@ -378,16 +376,14 @@
   WriteOnlyRawChannelDelegate writer_delegate;
   scoped_ptr<RawChannel> writer_rc(RawChannel::Create(handles[0].Pass()));
   io_thread()->PostTaskAndWait(FROM_HERE,
-                               base::Bind(&InitOnIOThread,
-                                          writer_rc.get(),
+                               base::Bind(&InitOnIOThread, writer_rc.get(),
                                           base::Unretained(&writer_delegate)));
 
   ReadCountdownRawChannelDelegate reader_delegate(kNumWriterThreads *
                                                   kNumWriteMessagesPerThread);
   scoped_ptr<RawChannel> reader_rc(RawChannel::Create(handles[1].Pass()));
   io_thread()->PostTaskAndWait(FROM_HERE,
-                               base::Bind(&InitOnIOThread,
-                                          reader_rc.get(),
+                               base::Bind(&InitOnIOThread, reader_rc.get(),
                                           base::Unretained(&reader_delegate)));
 
   {
diff --git a/mojo/edk/system/remote_message_pipe_unittest.cc b/mojo/edk/system/remote_message_pipe_unittest.cc
index d3a95df..e3a320e 100644
--- a/mojo/edk/system/remote_message_pipe_unittest.cc
+++ b/mojo/edk/system/remote_message_pipe_unittest.cc
@@ -48,16 +48,14 @@
 
   void SetUp() override {
     io_thread_.PostTaskAndWait(
-        FROM_HERE,
-        base::Bind(&RemoteMessagePipeTest::SetUpOnIOThread,
-                   base::Unretained(this)));
+        FROM_HERE, base::Bind(&RemoteMessagePipeTest::SetUpOnIOThread,
+                              base::Unretained(this)));
   }
 
   void TearDown() override {
     io_thread_.PostTaskAndWait(
-        FROM_HERE,
-        base::Bind(&RemoteMessagePipeTest::TearDownOnIOThread,
-                   base::Unretained(this)));
+        FROM_HERE, base::Bind(&RemoteMessagePipeTest::TearDownOnIOThread,
+                              base::Unretained(this)));
   }
 
  protected:
@@ -69,9 +67,7 @@
     io_thread_.PostTaskAndWait(
         FROM_HERE,
         base::Bind(&RemoteMessagePipeTest::BootstrapChannelEndpointsOnIOThread,
-                   base::Unretained(this),
-                   ep0,
-                   ep1));
+                   base::Unretained(this), ep0, ep1));
   }
 
   // This bootstraps |ep| on |channels_[channel_index]|. It assumes/requires
@@ -82,9 +78,7 @@
     io_thread_.PostTask(
         FROM_HERE,
         base::Bind(&RemoteMessagePipeTest::BootstrapChannelEndpointOnIOThread,
-                   base::Unretained(this),
-                   channel_index,
-                   ep));
+                   base::Unretained(this), channel_index, ep));
   }
 
   void RestoreInitialState() {
@@ -198,12 +192,10 @@
       mp1->AddWaiter(1, &waiter, MOJO_HANDLE_SIGNAL_READABLE, 123, nullptr));
 
   // Write to MP 0, port 0.
-  EXPECT_EQ(MOJO_RESULT_OK,
-            mp0->WriteMessage(0,
-                              UserPointer<const void>(kHello),
-                              sizeof(kHello),
-                              nullptr,
-                              MOJO_WRITE_MESSAGE_FLAG_NONE));
+  EXPECT_EQ(
+      MOJO_RESULT_OK,
+      mp0->WriteMessage(0, UserPointer<const void>(kHello), sizeof(kHello),
+                        nullptr, MOJO_WRITE_MESSAGE_FLAG_NONE));
 
   // Wait.
   EXPECT_EQ(MOJO_RESULT_OK, waiter.Wait(MOJO_DEADLINE_INDEFINITE, &context));
@@ -217,11 +209,8 @@
 
   // Read from MP 1, port 1.
   EXPECT_EQ(MOJO_RESULT_OK,
-            mp1->ReadMessage(1,
-                             UserPointer<void>(buffer),
-                             MakeUserPointer(&buffer_size),
-                             nullptr,
-                             nullptr,
+            mp1->ReadMessage(1, UserPointer<void>(buffer),
+                             MakeUserPointer(&buffer_size), nullptr, nullptr,
                              MOJO_READ_MESSAGE_FLAG_NONE));
   EXPECT_EQ(sizeof(kHello), static_cast<size_t>(buffer_size));
   EXPECT_STREQ(kHello, buffer);
@@ -233,12 +222,10 @@
       MOJO_RESULT_OK,
       mp0->AddWaiter(0, &waiter, MOJO_HANDLE_SIGNAL_READABLE, 456, nullptr));
 
-  EXPECT_EQ(MOJO_RESULT_OK,
-            mp1->WriteMessage(1,
-                              UserPointer<const void>(kWorld),
-                              sizeof(kWorld),
-                              nullptr,
-                              MOJO_WRITE_MESSAGE_FLAG_NONE));
+  EXPECT_EQ(
+      MOJO_RESULT_OK,
+      mp1->WriteMessage(1, UserPointer<const void>(kWorld), sizeof(kWorld),
+                        nullptr, MOJO_WRITE_MESSAGE_FLAG_NONE));
 
   EXPECT_EQ(MOJO_RESULT_OK, waiter.Wait(MOJO_DEADLINE_INDEFINITE, &context));
   EXPECT_EQ(456u, context);
@@ -251,11 +238,8 @@
 
   buffer_size = static_cast<uint32_t>(sizeof(buffer));
   EXPECT_EQ(MOJO_RESULT_OK,
-            mp0->ReadMessage(0,
-                             UserPointer<void>(buffer),
-                             MakeUserPointer(&buffer_size),
-                             nullptr,
-                             nullptr,
+            mp0->ReadMessage(0, UserPointer<void>(buffer),
+                             MakeUserPointer(&buffer_size), nullptr, nullptr,
                              MOJO_READ_MESSAGE_FLAG_NONE));
   EXPECT_EQ(sizeof(kWorld), static_cast<size_t>(buffer_size));
   EXPECT_STREQ(kWorld, buffer);
@@ -320,10 +304,8 @@
       mp1->AddWaiter(1, &waiter, MOJO_HANDLE_SIGNAL_READABLE, 123, nullptr));
 
   EXPECT_EQ(MOJO_RESULT_OK,
-            mp0->WriteMessage(0,
-                              UserPointer<const void>(&remote_id),
-                              sizeof(remote_id),
-                              nullptr,
+            mp0->WriteMessage(0, UserPointer<const void>(&remote_id),
+                              sizeof(remote_id), nullptr,
                               MOJO_WRITE_MESSAGE_FLAG_NONE));
 
   EXPECT_EQ(MOJO_RESULT_OK, waiter.Wait(MOJO_DEADLINE_INDEFINITE, &context));
@@ -338,11 +320,8 @@
   ChannelEndpointId received_id;
   buffer_size = static_cast<uint32_t>(sizeof(received_id));
   EXPECT_EQ(MOJO_RESULT_OK,
-            mp1->ReadMessage(1,
-                             UserPointer<void>(&received_id),
-                             MakeUserPointer(&buffer_size),
-                             nullptr,
-                             nullptr,
+            mp1->ReadMessage(1, UserPointer<void>(&received_id),
+                             MakeUserPointer(&buffer_size), nullptr, nullptr,
                              MOJO_READ_MESSAGE_FLAG_NONE));
   EXPECT_EQ(sizeof(received_id), static_cast<size_t>(buffer_size));
   EXPECT_EQ(remote_id, received_id);
@@ -359,12 +338,10 @@
       MOJO_RESULT_OK,
       mp3->AddWaiter(0, &waiter, MOJO_HANDLE_SIGNAL_READABLE, 789, nullptr));
 
-  EXPECT_EQ(MOJO_RESULT_OK,
-            mp2->WriteMessage(0,
-                              UserPointer<const void>(kHello),
-                              sizeof(kHello),
-                              nullptr,
-                              MOJO_WRITE_MESSAGE_FLAG_NONE));
+  EXPECT_EQ(
+      MOJO_RESULT_OK,
+      mp2->WriteMessage(0, UserPointer<const void>(kHello), sizeof(kHello),
+                        nullptr, MOJO_WRITE_MESSAGE_FLAG_NONE));
 
   EXPECT_EQ(MOJO_RESULT_OK, waiter.Wait(MOJO_DEADLINE_INDEFINITE, &context));
   EXPECT_EQ(789u, context);
@@ -378,37 +355,25 @@
   // Make sure there's nothing on MP 0, port 0 or MP 1, port 1 or MP 2, port 0.
   buffer_size = static_cast<uint32_t>(sizeof(buffer));
   EXPECT_EQ(MOJO_RESULT_SHOULD_WAIT,
-            mp0->ReadMessage(0,
-                             UserPointer<void>(buffer),
-                             MakeUserPointer(&buffer_size),
-                             nullptr,
-                             nullptr,
+            mp0->ReadMessage(0, UserPointer<void>(buffer),
+                             MakeUserPointer(&buffer_size), nullptr, nullptr,
                              MOJO_READ_MESSAGE_FLAG_NONE));
   buffer_size = static_cast<uint32_t>(sizeof(buffer));
   EXPECT_EQ(MOJO_RESULT_SHOULD_WAIT,
-            mp1->ReadMessage(1,
-                             UserPointer<void>(buffer),
-                             MakeUserPointer(&buffer_size),
-                             nullptr,
-                             nullptr,
+            mp1->ReadMessage(1, UserPointer<void>(buffer),
+                             MakeUserPointer(&buffer_size), nullptr, nullptr,
                              MOJO_READ_MESSAGE_FLAG_NONE));
   buffer_size = static_cast<uint32_t>(sizeof(buffer));
   EXPECT_EQ(MOJO_RESULT_SHOULD_WAIT,
-            mp2->ReadMessage(0,
-                             UserPointer<void>(buffer),
-                             MakeUserPointer(&buffer_size),
-                             nullptr,
-                             nullptr,
+            mp2->ReadMessage(0, UserPointer<void>(buffer),
+                             MakeUserPointer(&buffer_size), nullptr, nullptr,
                              MOJO_READ_MESSAGE_FLAG_NONE));
 
   // Read from MP 3, port 1.
   buffer_size = static_cast<uint32_t>(sizeof(buffer));
   EXPECT_EQ(MOJO_RESULT_OK,
-            mp3->ReadMessage(0,
-                             UserPointer<void>(buffer),
-                             MakeUserPointer(&buffer_size),
-                             nullptr,
-                             nullptr,
+            mp3->ReadMessage(0, UserPointer<void>(buffer),
+                             MakeUserPointer(&buffer_size), nullptr, nullptr,
                              MOJO_READ_MESSAGE_FLAG_NONE));
   EXPECT_EQ(sizeof(kHello), static_cast<size_t>(buffer_size));
   EXPECT_STREQ(kHello, buffer);
@@ -420,12 +385,10 @@
       MOJO_RESULT_OK,
       mp1->AddWaiter(1, &waiter, MOJO_HANDLE_SIGNAL_READABLE, 123, nullptr));
 
-  EXPECT_EQ(MOJO_RESULT_OK,
-            mp0->WriteMessage(0,
-                              UserPointer<const void>(kWorld),
-                              sizeof(kWorld),
-                              nullptr,
-                              MOJO_WRITE_MESSAGE_FLAG_NONE));
+  EXPECT_EQ(
+      MOJO_RESULT_OK,
+      mp0->WriteMessage(0, UserPointer<const void>(kWorld), sizeof(kWorld),
+                        nullptr, MOJO_WRITE_MESSAGE_FLAG_NONE));
 
   EXPECT_EQ(MOJO_RESULT_OK, waiter.Wait(MOJO_DEADLINE_INDEFINITE, &context));
   EXPECT_EQ(123u, context);
@@ -439,36 +402,24 @@
   // Make sure there's nothing on the other ports.
   buffer_size = static_cast<uint32_t>(sizeof(buffer));
   EXPECT_EQ(MOJO_RESULT_SHOULD_WAIT,
-            mp0->ReadMessage(0,
-                             UserPointer<void>(buffer),
-                             MakeUserPointer(&buffer_size),
-                             nullptr,
-                             nullptr,
+            mp0->ReadMessage(0, UserPointer<void>(buffer),
+                             MakeUserPointer(&buffer_size), nullptr, nullptr,
                              MOJO_READ_MESSAGE_FLAG_NONE));
   buffer_size = static_cast<uint32_t>(sizeof(buffer));
   EXPECT_EQ(MOJO_RESULT_SHOULD_WAIT,
-            mp2->ReadMessage(0,
-                             UserPointer<void>(buffer),
-                             MakeUserPointer(&buffer_size),
-                             nullptr,
-                             nullptr,
+            mp2->ReadMessage(0, UserPointer<void>(buffer),
+                             MakeUserPointer(&buffer_size), nullptr, nullptr,
                              MOJO_READ_MESSAGE_FLAG_NONE));
   buffer_size = static_cast<uint32_t>(sizeof(buffer));
   EXPECT_EQ(MOJO_RESULT_SHOULD_WAIT,
-            mp3->ReadMessage(0,
-                             UserPointer<void>(buffer),
-                             MakeUserPointer(&buffer_size),
-                             nullptr,
-                             nullptr,
+            mp3->ReadMessage(0, UserPointer<void>(buffer),
+                             MakeUserPointer(&buffer_size), nullptr, nullptr,
                              MOJO_READ_MESSAGE_FLAG_NONE));
 
   buffer_size = static_cast<uint32_t>(sizeof(buffer));
   EXPECT_EQ(MOJO_RESULT_OK,
-            mp1->ReadMessage(1,
-                             UserPointer<void>(buffer),
-                             MakeUserPointer(&buffer_size),
-                             nullptr,
-                             nullptr,
+            mp1->ReadMessage(1, UserPointer<void>(buffer),
+                             MakeUserPointer(&buffer_size), nullptr, nullptr,
                              MOJO_READ_MESSAGE_FLAG_NONE));
   EXPECT_EQ(sizeof(kWorld), static_cast<size_t>(buffer_size));
   EXPECT_STREQ(kWorld, buffer);
@@ -495,12 +446,10 @@
   scoped_refptr<MessagePipe> mp0(MessagePipe::CreateLocalProxy(&ep0));
 
   // Write to MP 0, port 0.
-  EXPECT_EQ(MOJO_RESULT_OK,
-            mp0->WriteMessage(0,
-                              UserPointer<const void>(kHello),
-                              sizeof(kHello),
-                              nullptr,
-                              MOJO_WRITE_MESSAGE_FLAG_NONE));
+  EXPECT_EQ(
+      MOJO_RESULT_OK,
+      mp0->WriteMessage(0, UserPointer<const void>(kHello), sizeof(kHello),
+                        nullptr, MOJO_WRITE_MESSAGE_FLAG_NONE));
 
   // Close MP 0, port 0 before it's even been attached to the channel and run.
   mp0->Close(0);
@@ -533,11 +482,8 @@
 
   // Read from MP 1, port 1.
   EXPECT_EQ(MOJO_RESULT_OK,
-            mp1->ReadMessage(1,
-                             UserPointer<void>(buffer),
-                             MakeUserPointer(&buffer_size),
-                             nullptr,
-                             nullptr,
+            mp1->ReadMessage(1, UserPointer<void>(buffer),
+                             MakeUserPointer(&buffer_size), nullptr, nullptr,
                              MOJO_READ_MESSAGE_FLAG_NONE));
   EXPECT_EQ(sizeof(kHello), static_cast<size_t>(buffer_size));
   EXPECT_STREQ(kHello, buffer);
@@ -562,12 +508,10 @@
   scoped_refptr<MessagePipe> mp0(MessagePipe::CreateLocalProxy(&ep0));
 
   // Write to MP 0, port 0.
-  EXPECT_EQ(MOJO_RESULT_OK,
-            mp0->WriteMessage(0,
-                              UserPointer<const void>(kHello),
-                              sizeof(kHello),
-                              nullptr,
-                              MOJO_WRITE_MESSAGE_FLAG_NONE));
+  EXPECT_EQ(
+      MOJO_RESULT_OK,
+      mp0->WriteMessage(0, UserPointer<const void>(kHello), sizeof(kHello),
+                        nullptr, MOJO_WRITE_MESSAGE_FLAG_NONE));
 
   BootstrapChannelEndpointNoWait(0, ep0);
 
@@ -600,11 +544,8 @@
 
   // Read from MP 1, port 1.
   EXPECT_EQ(MOJO_RESULT_OK,
-            mp1->ReadMessage(1,
-                             UserPointer<void>(buffer),
-                             MakeUserPointer(&buffer_size),
-                             nullptr,
-                             nullptr,
+            mp1->ReadMessage(1, UserPointer<void>(buffer),
+                             MakeUserPointer(&buffer_size), nullptr, nullptr,
                              MOJO_READ_MESSAGE_FLAG_NONE));
   EXPECT_EQ(sizeof(kHello), static_cast<size_t>(buffer_size));
   EXPECT_STREQ(kHello, buffer);
@@ -646,12 +587,10 @@
 
     std::vector<DispatcherTransport> transports;
     transports.push_back(transport);
-    EXPECT_EQ(MOJO_RESULT_OK,
-              mp0->WriteMessage(0,
-                                UserPointer<const void>(kHello),
-                                sizeof(kHello),
-                                &transports,
-                                MOJO_WRITE_MESSAGE_FLAG_NONE));
+    EXPECT_EQ(
+        MOJO_RESULT_OK,
+        mp0->WriteMessage(0, UserPointer<const void>(kHello), sizeof(kHello),
+                          &transports, MOJO_WRITE_MESSAGE_FLAG_NONE));
     transport.End();
 
     // |dispatcher| should have been closed. This is |DCHECK()|ed when the
@@ -675,13 +614,11 @@
   uint32_t read_buffer_size = static_cast<uint32_t>(sizeof(read_buffer));
   DispatcherVector read_dispatchers;
   uint32_t read_num_dispatchers = 10;  // Maximum to get.
-  EXPECT_EQ(MOJO_RESULT_OK,
-            mp1->ReadMessage(1,
-                             UserPointer<void>(read_buffer),
-                             MakeUserPointer(&read_buffer_size),
-                             &read_dispatchers,
-                             &read_num_dispatchers,
-                             MOJO_READ_MESSAGE_FLAG_NONE));
+  EXPECT_EQ(
+      MOJO_RESULT_OK,
+      mp1->ReadMessage(1, UserPointer<void>(read_buffer),
+                       MakeUserPointer(&read_buffer_size), &read_dispatchers,
+                       &read_num_dispatchers, MOJO_READ_MESSAGE_FLAG_NONE));
   EXPECT_EQ(sizeof(kHello), static_cast<size_t>(read_buffer_size));
   EXPECT_STREQ(kHello, read_buffer);
   EXPECT_EQ(1u, read_dispatchers.size());
@@ -695,16 +632,14 @@
   // Add the waiter now, before it becomes readable to avoid a race.
   waiter.Init();
   ASSERT_EQ(MOJO_RESULT_OK,
-            dispatcher->AddWaiter(
-                &waiter, MOJO_HANDLE_SIGNAL_READABLE, 456, nullptr));
+            dispatcher->AddWaiter(&waiter, MOJO_HANDLE_SIGNAL_READABLE, 456,
+                                  nullptr));
 
   // Write to "local_mp", port 1.
-  EXPECT_EQ(MOJO_RESULT_OK,
-            local_mp->WriteMessage(1,
-                                   UserPointer<const void>(kHello),
-                                   sizeof(kHello),
-                                   nullptr,
-                                   MOJO_WRITE_MESSAGE_FLAG_NONE));
+  EXPECT_EQ(
+      MOJO_RESULT_OK,
+      local_mp->WriteMessage(1, UserPointer<const void>(kHello), sizeof(kHello),
+                             nullptr, MOJO_WRITE_MESSAGE_FLAG_NONE));
 
   // TODO(vtl): FIXME -- We (racily) crash if I close |dispatcher| immediately
   // here. (We don't crash if I sleep and then close.)
@@ -724,25 +659,21 @@
   read_buffer_size = static_cast<uint32_t>(sizeof(read_buffer));
   EXPECT_EQ(MOJO_RESULT_OK,
             dispatcher->ReadMessage(UserPointer<void>(read_buffer),
-                                    MakeUserPointer(&read_buffer_size),
-                                    0,
-                                    nullptr,
-                                    MOJO_READ_MESSAGE_FLAG_NONE));
+                                    MakeUserPointer(&read_buffer_size), 0,
+                                    nullptr, MOJO_READ_MESSAGE_FLAG_NONE));
   EXPECT_EQ(sizeof(kHello), static_cast<size_t>(read_buffer_size));
   EXPECT_STREQ(kHello, read_buffer);
 
   // Prepare to wait on "local_mp", port 1.
   waiter.Init();
   ASSERT_EQ(MOJO_RESULT_OK,
-            local_mp->AddWaiter(
-                1, &waiter, MOJO_HANDLE_SIGNAL_READABLE, 789, nullptr));
+            local_mp->AddWaiter(1, &waiter, MOJO_HANDLE_SIGNAL_READABLE, 789,
+                                nullptr));
 
   // Write to the dispatcher.
-  EXPECT_EQ(MOJO_RESULT_OK,
-            dispatcher->WriteMessage(UserPointer<const void>(kHello),
-                                     sizeof(kHello),
-                                     nullptr,
-                                     MOJO_WRITE_MESSAGE_FLAG_NONE));
+  EXPECT_EQ(MOJO_RESULT_OK, dispatcher->WriteMessage(
+                                UserPointer<const void>(kHello), sizeof(kHello),
+                                nullptr, MOJO_WRITE_MESSAGE_FLAG_NONE));
 
   // Wait.
   EXPECT_EQ(MOJO_RESULT_OK, waiter.Wait(MOJO_DEADLINE_INDEFINITE, &context));
@@ -758,12 +689,9 @@
   memset(read_buffer, 0, sizeof(read_buffer));
   read_buffer_size = static_cast<uint32_t>(sizeof(read_buffer));
   EXPECT_EQ(MOJO_RESULT_OK,
-            local_mp->ReadMessage(1,
-                                  UserPointer<void>(read_buffer),
-                                  MakeUserPointer(&read_buffer_size),
-                                  nullptr,
-                                  nullptr,
-                                  MOJO_READ_MESSAGE_FLAG_NONE));
+            local_mp->ReadMessage(1, UserPointer<void>(read_buffer),
+                                  MakeUserPointer(&read_buffer_size), nullptr,
+                                  nullptr, MOJO_READ_MESSAGE_FLAG_NONE));
   EXPECT_EQ(sizeof(kHello), static_cast<size_t>(read_buffer_size));
   EXPECT_STREQ(kHello, read_buffer);
 
@@ -796,24 +724,20 @@
   EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE,
             hss.satisfiable_signals);
   // Write to the other end (|local_mp|, port 1), and then close it.
-  EXPECT_EQ(MOJO_RESULT_OK,
-            local_mp->WriteMessage(1,
-                                   UserPointer<const void>(kHello),
-                                   sizeof(kHello),
-                                   nullptr,
-                                   MOJO_WRITE_MESSAGE_FLAG_NONE));
+  EXPECT_EQ(
+      MOJO_RESULT_OK,
+      local_mp->WriteMessage(1, UserPointer<const void>(kHello), sizeof(kHello),
+                             nullptr, MOJO_WRITE_MESSAGE_FLAG_NONE));
   hss = local_mp->GetHandleSignalsState(0);
   EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE,
             hss.satisfied_signals);
   EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE,
             hss.satisfiable_signals);
   // Then the second message....
-  EXPECT_EQ(MOJO_RESULT_OK,
-            local_mp->WriteMessage(1,
-                                   UserPointer<const void>(kWorld),
-                                   sizeof(kWorld),
-                                   nullptr,
-                                   MOJO_WRITE_MESSAGE_FLAG_NONE));
+  EXPECT_EQ(
+      MOJO_RESULT_OK,
+      local_mp->WriteMessage(1, UserPointer<const void>(kWorld), sizeof(kWorld),
+                             nullptr, MOJO_WRITE_MESSAGE_FLAG_NONE));
   hss = local_mp->GetHandleSignalsState(0);
   EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE,
             hss.satisfied_signals);
@@ -843,12 +767,10 @@
 
     std::vector<DispatcherTransport> transports;
     transports.push_back(transport);
-    EXPECT_EQ(MOJO_RESULT_OK,
-              mp0->WriteMessage(0,
-                                UserPointer<const void>(kHello),
-                                sizeof(kHello),
-                                &transports,
-                                MOJO_WRITE_MESSAGE_FLAG_NONE));
+    EXPECT_EQ(
+        MOJO_RESULT_OK,
+        mp0->WriteMessage(0, UserPointer<const void>(kHello), sizeof(kHello),
+                          &transports, MOJO_WRITE_MESSAGE_FLAG_NONE));
     transport.End();
 
     // |dispatcher| should have been closed. This is |DCHECK()|ed when the
@@ -872,13 +794,11 @@
   uint32_t read_buffer_size = static_cast<uint32_t>(sizeof(read_buffer));
   DispatcherVector read_dispatchers;
   uint32_t read_num_dispatchers = 10;  // Maximum to get.
-  EXPECT_EQ(MOJO_RESULT_OK,
-            mp1->ReadMessage(1,
-                             UserPointer<void>(read_buffer),
-                             MakeUserPointer(&read_buffer_size),
-                             &read_dispatchers,
-                             &read_num_dispatchers,
-                             MOJO_READ_MESSAGE_FLAG_NONE));
+  EXPECT_EQ(
+      MOJO_RESULT_OK,
+      mp1->ReadMessage(1, UserPointer<void>(read_buffer),
+                       MakeUserPointer(&read_buffer_size), &read_dispatchers,
+                       &read_num_dispatchers, MOJO_READ_MESSAGE_FLAG_NONE));
   EXPECT_EQ(sizeof(kHello), static_cast<size_t>(read_buffer_size));
   EXPECT_STREQ(kHello, read_buffer);
   EXPECT_EQ(1u, read_dispatchers.size());
@@ -898,10 +818,8 @@
   read_buffer_size = static_cast<uint32_t>(sizeof(read_buffer));
   EXPECT_EQ(MOJO_RESULT_OK,
             dispatcher->ReadMessage(UserPointer<void>(read_buffer),
-                                    MakeUserPointer(&read_buffer_size),
-                                    0,
-                                    nullptr,
-                                    MOJO_READ_MESSAGE_FLAG_NONE));
+                                    MakeUserPointer(&read_buffer_size), 0,
+                                    nullptr, MOJO_READ_MESSAGE_FLAG_NONE));
   EXPECT_EQ(sizeof(kHello), static_cast<size_t>(read_buffer_size));
   EXPECT_STREQ(kHello, read_buffer);
   // It should still be readable.
@@ -913,10 +831,8 @@
   read_buffer_size = static_cast<uint32_t>(sizeof(read_buffer));
   EXPECT_EQ(MOJO_RESULT_OK,
             dispatcher->ReadMessage(UserPointer<void>(read_buffer),
-                                    MakeUserPointer(&read_buffer_size),
-                                    0,
-                                    nullptr,
-                                    MOJO_READ_MESSAGE_FLAG_NONE));
+                                    MakeUserPointer(&read_buffer_size), 0,
+                                    nullptr, MOJO_READ_MESSAGE_FLAG_NONE));
   EXPECT_EQ(sizeof(kWorld), static_cast<size_t>(read_buffer_size));
   EXPECT_STREQ(kWorld, read_buffer);
   // Now it should no longer be readable.
@@ -950,19 +866,16 @@
 
   // We'll try to pass this dispatcher.
   scoped_refptr<SharedBufferDispatcher> dispatcher;
-  EXPECT_EQ(MOJO_RESULT_OK,
-            SharedBufferDispatcher::Create(
-                platform_support(),
-                SharedBufferDispatcher::kDefaultCreateOptions,
-                100,
-                &dispatcher));
+  EXPECT_EQ(MOJO_RESULT_OK, SharedBufferDispatcher::Create(
+                                platform_support(),
+                                SharedBufferDispatcher::kDefaultCreateOptions,
+                                100, &dispatcher));
   ASSERT_TRUE(dispatcher.get());
 
   // Make a mapping.
   scoped_ptr<embedder::PlatformSharedBufferMapping> mapping0;
-  EXPECT_EQ(
-      MOJO_RESULT_OK,
-      dispatcher->MapBuffer(0, 100, MOJO_MAP_BUFFER_FLAG_NONE, &mapping0));
+  EXPECT_EQ(MOJO_RESULT_OK, dispatcher->MapBuffer(
+                                0, 100, MOJO_MAP_BUFFER_FLAG_NONE, &mapping0));
   ASSERT_TRUE(mapping0);
   ASSERT_TRUE(mapping0->GetBase());
   ASSERT_EQ(100u, mapping0->GetLength());
@@ -985,12 +898,10 @@
 
     std::vector<DispatcherTransport> transports;
     transports.push_back(transport);
-    EXPECT_EQ(MOJO_RESULT_OK,
-              mp0->WriteMessage(0,
-                                UserPointer<const void>(kHello),
-                                sizeof(kHello),
-                                &transports,
-                                MOJO_WRITE_MESSAGE_FLAG_NONE));
+    EXPECT_EQ(
+        MOJO_RESULT_OK,
+        mp0->WriteMessage(0, UserPointer<const void>(kHello), sizeof(kHello),
+                          &transports, MOJO_WRITE_MESSAGE_FLAG_NONE));
     transport.End();
 
     // |dispatcher| should have been closed. This is |DCHECK()|ed when the
@@ -1014,13 +925,11 @@
   uint32_t read_buffer_size = static_cast<uint32_t>(sizeof(read_buffer));
   DispatcherVector read_dispatchers;
   uint32_t read_num_dispatchers = 10;  // Maximum to get.
-  EXPECT_EQ(MOJO_RESULT_OK,
-            mp1->ReadMessage(1,
-                             UserPointer<void>(read_buffer),
-                             MakeUserPointer(&read_buffer_size),
-                             &read_dispatchers,
-                             &read_num_dispatchers,
-                             MOJO_READ_MESSAGE_FLAG_NONE));
+  EXPECT_EQ(
+      MOJO_RESULT_OK,
+      mp1->ReadMessage(1, UserPointer<void>(read_buffer),
+                       MakeUserPointer(&read_buffer_size), &read_dispatchers,
+                       &read_num_dispatchers, MOJO_READ_MESSAGE_FLAG_NONE));
   EXPECT_EQ(sizeof(kHello), static_cast<size_t>(read_buffer_size));
   EXPECT_STREQ(kHello, read_buffer);
   EXPECT_EQ(1u, read_dispatchers.size());
@@ -1033,9 +942,8 @@
 
   // Make another mapping.
   scoped_ptr<embedder::PlatformSharedBufferMapping> mapping1;
-  EXPECT_EQ(
-      MOJO_RESULT_OK,
-      dispatcher->MapBuffer(0, 100, MOJO_MAP_BUFFER_FLAG_NONE, &mapping1));
+  EXPECT_EQ(MOJO_RESULT_OK, dispatcher->MapBuffer(
+                                0, 100, MOJO_MAP_BUFFER_FLAG_NONE, &mapping1));
   ASSERT_TRUE(mapping1);
   ASSERT_TRUE(mapping1->GetBase());
   ASSERT_EQ(100u, mapping1->GetLength());
@@ -1110,12 +1018,10 @@
 
     std::vector<DispatcherTransport> transports;
     transports.push_back(transport);
-    EXPECT_EQ(MOJO_RESULT_OK,
-              mp0->WriteMessage(0,
-                                UserPointer<const void>(kWorld),
-                                sizeof(kWorld),
-                                &transports,
-                                MOJO_WRITE_MESSAGE_FLAG_NONE));
+    EXPECT_EQ(
+        MOJO_RESULT_OK,
+        mp0->WriteMessage(0, UserPointer<const void>(kWorld), sizeof(kWorld),
+                          &transports, MOJO_WRITE_MESSAGE_FLAG_NONE));
     transport.End();
 
     // |dispatcher| should have been closed. This is |DCHECK()|ed when the
@@ -1139,13 +1045,11 @@
   uint32_t read_buffer_size = static_cast<uint32_t>(sizeof(read_buffer));
   DispatcherVector read_dispatchers;
   uint32_t read_num_dispatchers = 10;  // Maximum to get.
-  EXPECT_EQ(MOJO_RESULT_OK,
-            mp1->ReadMessage(1,
-                             UserPointer<void>(read_buffer),
-                             MakeUserPointer(&read_buffer_size),
-                             &read_dispatchers,
-                             &read_num_dispatchers,
-                             MOJO_READ_MESSAGE_FLAG_NONE));
+  EXPECT_EQ(
+      MOJO_RESULT_OK,
+      mp1->ReadMessage(1, UserPointer<void>(read_buffer),
+                       MakeUserPointer(&read_buffer_size), &read_dispatchers,
+                       &read_num_dispatchers, MOJO_READ_MESSAGE_FLAG_NONE));
   EXPECT_EQ(sizeof(kWorld), static_cast<size_t>(read_buffer_size));
   EXPECT_STREQ(kWorld, read_buffer);
   EXPECT_EQ(1u, read_dispatchers.size());
@@ -1252,12 +1156,10 @@
 
     std::vector<DispatcherTransport> transports;
     transports.push_back(transport);
-    EXPECT_EQ(MOJO_RESULT_OK,
-              mp0->WriteMessage(0,
-                                UserPointer<const void>(kHello),
-                                sizeof(kHello),
-                                &transports,
-                                MOJO_WRITE_MESSAGE_FLAG_NONE));
+    EXPECT_EQ(
+        MOJO_RESULT_OK,
+        mp0->WriteMessage(0, UserPointer<const void>(kHello), sizeof(kHello),
+                          &transports, MOJO_WRITE_MESSAGE_FLAG_NONE));
     transport.End();
 
     // |dispatcher| should have been closed. This is |DCHECK()|ed when the
@@ -1281,13 +1183,11 @@
   uint32_t read_buffer_size = static_cast<uint32_t>(sizeof(read_buffer));
   DispatcherVector read_dispatchers;
   uint32_t read_num_dispatchers = 10;  // Maximum to get.
-  EXPECT_EQ(MOJO_RESULT_OK,
-            mp1->ReadMessage(1,
-                             UserPointer<void>(read_buffer),
-                             MakeUserPointer(&read_buffer_size),
-                             &read_dispatchers,
-                             &read_num_dispatchers,
-                             MOJO_READ_MESSAGE_FLAG_NONE));
+  EXPECT_EQ(
+      MOJO_RESULT_OK,
+      mp1->ReadMessage(1, UserPointer<void>(read_buffer),
+                       MakeUserPointer(&read_buffer_size), &read_dispatchers,
+                       &read_num_dispatchers, MOJO_READ_MESSAGE_FLAG_NONE));
   EXPECT_EQ(sizeof(kHello), static_cast<size_t>(read_buffer_size));
   EXPECT_STREQ(kHello, read_buffer);
   EXPECT_EQ(1u, read_dispatchers.size());
@@ -1316,12 +1216,10 @@
 
     std::vector<DispatcherTransport> transports;
     transports.push_back(transport);
-    EXPECT_EQ(MOJO_RESULT_OK,
-              mp1->WriteMessage(1,
-                                UserPointer<const void>(kWorld),
-                                sizeof(kWorld),
-                                &transports,
-                                MOJO_WRITE_MESSAGE_FLAG_NONE));
+    EXPECT_EQ(
+        MOJO_RESULT_OK,
+        mp1->WriteMessage(1, UserPointer<const void>(kWorld), sizeof(kWorld),
+                          &transports, MOJO_WRITE_MESSAGE_FLAG_NONE));
     transport.End();
 
     // |dispatcher| should have been closed. This is |DCHECK()|ed when the
@@ -1343,13 +1241,11 @@
   // Read from MP 0, port 0.
   read_buffer_size = static_cast<uint32_t>(sizeof(read_buffer));
   read_num_dispatchers = 10;  // Maximum to get.
-  EXPECT_EQ(MOJO_RESULT_OK,
-            mp0->ReadMessage(0,
-                             UserPointer<void>(read_buffer),
-                             MakeUserPointer(&read_buffer_size),
-                             &read_dispatchers,
-                             &read_num_dispatchers,
-                             MOJO_READ_MESSAGE_FLAG_NONE));
+  EXPECT_EQ(
+      MOJO_RESULT_OK,
+      mp0->ReadMessage(0, UserPointer<void>(read_buffer),
+                       MakeUserPointer(&read_buffer_size), &read_dispatchers,
+                       &read_num_dispatchers, MOJO_READ_MESSAGE_FLAG_NONE));
   EXPECT_EQ(sizeof(kWorld), static_cast<size_t>(read_buffer_size));
   EXPECT_STREQ(kWorld, read_buffer);
   EXPECT_EQ(1u, read_dispatchers.size());
@@ -1364,16 +1260,14 @@
   // Add the waiter now, before it becomes readable to avoid a race.
   waiter.Init();
   ASSERT_EQ(MOJO_RESULT_OK,
-            dispatcher->AddWaiter(
-                &waiter, MOJO_HANDLE_SIGNAL_READABLE, 789, nullptr));
+            dispatcher->AddWaiter(&waiter, MOJO_HANDLE_SIGNAL_READABLE, 789,
+                                  nullptr));
 
   // Write to "local_mp", port 1.
-  EXPECT_EQ(MOJO_RESULT_OK,
-            local_mp->WriteMessage(1,
-                                   UserPointer<const void>(kHello),
-                                   sizeof(kHello),
-                                   nullptr,
-                                   MOJO_WRITE_MESSAGE_FLAG_NONE));
+  EXPECT_EQ(
+      MOJO_RESULT_OK,
+      local_mp->WriteMessage(1, UserPointer<const void>(kHello), sizeof(kHello),
+                             nullptr, MOJO_WRITE_MESSAGE_FLAG_NONE));
 
   // Wait for the dispatcher to become readable.
   EXPECT_EQ(MOJO_RESULT_OK, waiter.Wait(MOJO_DEADLINE_INDEFINITE, &context));
@@ -1390,25 +1284,21 @@
   read_buffer_size = static_cast<uint32_t>(sizeof(read_buffer));
   EXPECT_EQ(MOJO_RESULT_OK,
             dispatcher->ReadMessage(UserPointer<void>(read_buffer),
-                                    MakeUserPointer(&read_buffer_size),
-                                    0,
-                                    nullptr,
-                                    MOJO_READ_MESSAGE_FLAG_NONE));
+                                    MakeUserPointer(&read_buffer_size), 0,
+                                    nullptr, MOJO_READ_MESSAGE_FLAG_NONE));
   EXPECT_EQ(sizeof(kHello), static_cast<size_t>(read_buffer_size));
   EXPECT_STREQ(kHello, read_buffer);
 
   // Prepare to wait on "local_mp", port 1.
   waiter.Init();
   ASSERT_EQ(MOJO_RESULT_OK,
-            local_mp->AddWaiter(
-                1, &waiter, MOJO_HANDLE_SIGNAL_READABLE, 789, nullptr));
+            local_mp->AddWaiter(1, &waiter, MOJO_HANDLE_SIGNAL_READABLE, 789,
+                                nullptr));
 
   // Write to the dispatcher.
-  EXPECT_EQ(MOJO_RESULT_OK,
-            dispatcher->WriteMessage(UserPointer<const void>(kHello),
-                                     sizeof(kHello),
-                                     nullptr,
-                                     MOJO_WRITE_MESSAGE_FLAG_NONE));
+  EXPECT_EQ(MOJO_RESULT_OK, dispatcher->WriteMessage(
+                                UserPointer<const void>(kHello), sizeof(kHello),
+                                nullptr, MOJO_WRITE_MESSAGE_FLAG_NONE));
 
   // Wait.
   EXPECT_EQ(MOJO_RESULT_OK, waiter.Wait(MOJO_DEADLINE_INDEFINITE, &context));
@@ -1424,12 +1314,9 @@
   memset(read_buffer, 0, sizeof(read_buffer));
   read_buffer_size = static_cast<uint32_t>(sizeof(read_buffer));
   EXPECT_EQ(MOJO_RESULT_OK,
-            local_mp->ReadMessage(1,
-                                  UserPointer<void>(read_buffer),
-                                  MakeUserPointer(&read_buffer_size),
-                                  nullptr,
-                                  nullptr,
-                                  MOJO_READ_MESSAGE_FLAG_NONE));
+            local_mp->ReadMessage(1, UserPointer<void>(read_buffer),
+                                  MakeUserPointer(&read_buffer_size), nullptr,
+                                  nullptr, MOJO_READ_MESSAGE_FLAG_NONE));
   EXPECT_EQ(sizeof(kHello), static_cast<size_t>(read_buffer_size));
   EXPECT_STREQ(kHello, read_buffer);
 
diff --git a/mojo/edk/system/run_all_unittests.cc b/mojo/edk/system/run_all_unittests.cc
index 2855e96..3ea1682 100644
--- a/mojo/edk/system/run_all_unittests.cc
+++ b/mojo/edk/system/run_all_unittests.cc
@@ -15,7 +15,6 @@
   base::TestSuite test_suite(argc, argv);
 
   return base::LaunchUnitTests(
-      argc,
-      argv,
+      argc, argv,
       base::Bind(&base::TestSuite::Run, base::Unretained(&test_suite)));
 }
diff --git a/mojo/edk/system/shared_buffer_dispatcher.cc b/mojo/edk/system/shared_buffer_dispatcher.cc
index 7e345d9..698ef4e 100644
--- a/mojo/edk/system/shared_buffer_dispatcher.cc
+++ b/mojo/edk/system/shared_buffer_dispatcher.cc
@@ -10,7 +10,7 @@
 #include "base/memory/scoped_ptr.h"
 #include "mojo/edk/embedder/platform_support.h"
 #include "mojo/edk/system/channel.h"
-#include "mojo/edk/system/constants.h"
+#include "mojo/edk/system/configuration.h"
 #include "mojo/edk/system/memory.h"
 #include "mojo/edk/system/options_validation.h"
 #include "mojo/public/c/system/macros.h"
@@ -69,7 +69,7 @@
     scoped_refptr<SharedBufferDispatcher>* result) {
   if (!num_bytes)
     return MOJO_RESULT_INVALID_ARGUMENT;
-  if (num_bytes > kMaxSharedMemoryNumBytes)
+  if (num_bytes > GetConfiguration().max_shared_memory_num_bytes)
     return MOJO_RESULT_RESOURCE_EXHAUSTED;
 
   scoped_refptr<embedder::PlatformSharedBuffer> shared_buffer(
@@ -95,7 +95,7 @@
 
   if (size != sizeof(SerializedSharedBufferDispatcher)) {
     LOG(ERROR) << "Invalid serialized shared buffer dispatcher (bad size)";
-    return scoped_refptr<SharedBufferDispatcher>();
+    return nullptr;
   }
 
   const SerializedSharedBufferDispatcher* serialization =
@@ -106,13 +106,13 @@
   if (!num_bytes) {
     LOG(ERROR)
         << "Invalid serialized shared buffer dispatcher (invalid num_bytes)";
-    return scoped_refptr<SharedBufferDispatcher>();
+    return nullptr;
   }
 
   if (!platform_handles || platform_handle_index >= platform_handles->size()) {
     LOG(ERROR)
         << "Invalid serialized shared buffer dispatcher (missing handles)";
-    return scoped_refptr<SharedBufferDispatcher>();
+    return nullptr;
   }
 
   // Starts off invalid, which is what we want.
@@ -129,7 +129,7 @@
   if (!shared_buffer.get()) {
     LOG(ERROR)
         << "Invalid serialized shared buffer dispatcher (invalid num_bytes?)";
-    return scoped_refptr<SharedBufferDispatcher>();
+    return nullptr;
   }
 
   return scoped_refptr<SharedBufferDispatcher>(
@@ -163,8 +163,8 @@
   if (!reader.is_valid())
     return MOJO_RESULT_INVALID_ARGUMENT;
 
-  if (!OPTIONS_STRUCT_HAS_MEMBER(
-          MojoDuplicateBufferHandleOptions, flags, reader))
+  if (!OPTIONS_STRUCT_HAS_MEMBER(MojoDuplicateBufferHandleOptions, flags,
+                                 reader))
     return MOJO_RESULT_OK;
   if ((reader.options().flags & ~kKnownFlags))
     return MOJO_RESULT_UNIMPLEMENTED;
diff --git a/mojo/edk/system/shared_buffer_dispatcher_unittest.cc b/mojo/edk/system/shared_buffer_dispatcher_unittest.cc
index a80f71d..5866089 100644
--- a/mojo/edk/system/shared_buffer_dispatcher_unittest.cc
+++ b/mojo/edk/system/shared_buffer_dispatcher_unittest.cc
@@ -58,9 +58,8 @@
   // Default options.
   {
     MojoCreateSharedBufferOptions validated_options = {};
-    EXPECT_EQ(MOJO_RESULT_OK,
-              SharedBufferDispatcher::ValidateCreateOptions(
-                  NullUserPointer(), &validated_options));
+    EXPECT_EQ(MOJO_RESULT_OK, SharedBufferDispatcher::ValidateCreateOptions(
+                                  NullUserPointer(), &validated_options));
     RevalidateCreateOptions(validated_options);
   }
 
@@ -115,20 +114,17 @@
 
 TEST_F(SharedBufferDispatcherTest, CreateAndMapBuffer) {
   scoped_refptr<SharedBufferDispatcher> dispatcher;
-  EXPECT_EQ(MOJO_RESULT_OK,
-            SharedBufferDispatcher::Create(
-                platform_support(),
-                SharedBufferDispatcher::kDefaultCreateOptions,
-                100,
-                &dispatcher));
+  EXPECT_EQ(MOJO_RESULT_OK, SharedBufferDispatcher::Create(
+                                platform_support(),
+                                SharedBufferDispatcher::kDefaultCreateOptions,
+                                100, &dispatcher));
   ASSERT_TRUE(dispatcher.get());
   EXPECT_EQ(Dispatcher::kTypeSharedBuffer, dispatcher->GetType());
 
   // Make a couple of mappings.
   scoped_ptr<embedder::PlatformSharedBufferMapping> mapping1;
-  EXPECT_EQ(
-      MOJO_RESULT_OK,
-      dispatcher->MapBuffer(0, 100, MOJO_MAP_BUFFER_FLAG_NONE, &mapping1));
+  EXPECT_EQ(MOJO_RESULT_OK, dispatcher->MapBuffer(
+                                0, 100, MOJO_MAP_BUFFER_FLAG_NONE, &mapping1));
   ASSERT_TRUE(mapping1);
   ASSERT_TRUE(mapping1->GetBase());
   EXPECT_EQ(100u, mapping1->GetLength());
@@ -136,9 +132,8 @@
   static_cast<char*>(mapping1->GetBase())[50] = 'x';
 
   scoped_ptr<embedder::PlatformSharedBufferMapping> mapping2;
-  EXPECT_EQ(
-      MOJO_RESULT_OK,
-      dispatcher->MapBuffer(50, 50, MOJO_MAP_BUFFER_FLAG_NONE, &mapping2));
+  EXPECT_EQ(MOJO_RESULT_OK, dispatcher->MapBuffer(
+                                50, 50, MOJO_MAP_BUFFER_FLAG_NONE, &mapping2));
   ASSERT_TRUE(mapping2);
   ASSERT_TRUE(mapping2->GetBase());
   EXPECT_EQ(50u, mapping2->GetLength());
@@ -154,35 +149,30 @@
 
 TEST_F(SharedBufferDispatcherTest, DuplicateBufferHandle) {
   scoped_refptr<SharedBufferDispatcher> dispatcher1;
-  EXPECT_EQ(MOJO_RESULT_OK,
-            SharedBufferDispatcher::Create(
-                platform_support(),
-                SharedBufferDispatcher::kDefaultCreateOptions,
-                100,
-                &dispatcher1));
+  EXPECT_EQ(MOJO_RESULT_OK, SharedBufferDispatcher::Create(
+                                platform_support(),
+                                SharedBufferDispatcher::kDefaultCreateOptions,
+                                100, &dispatcher1));
 
   // Map and write something.
   scoped_ptr<embedder::PlatformSharedBufferMapping> mapping;
-  EXPECT_EQ(
-      MOJO_RESULT_OK,
-      dispatcher1->MapBuffer(0, 100, MOJO_MAP_BUFFER_FLAG_NONE, &mapping));
+  EXPECT_EQ(MOJO_RESULT_OK, dispatcher1->MapBuffer(
+                                0, 100, MOJO_MAP_BUFFER_FLAG_NONE, &mapping));
   static_cast<char*>(mapping->GetBase())[0] = 'x';
   mapping.reset();
 
   // Duplicate |dispatcher1| and then close it.
   scoped_refptr<Dispatcher> dispatcher2;
-  EXPECT_EQ(
-      MOJO_RESULT_OK,
-      dispatcher1->DuplicateBufferHandle(NullUserPointer(), &dispatcher2));
+  EXPECT_EQ(MOJO_RESULT_OK, dispatcher1->DuplicateBufferHandle(
+                                NullUserPointer(), &dispatcher2));
   ASSERT_TRUE(dispatcher2.get());
   EXPECT_EQ(Dispatcher::kTypeSharedBuffer, dispatcher2->GetType());
 
   EXPECT_EQ(MOJO_RESULT_OK, dispatcher1->Close());
 
   // Map |dispatcher2| and read something.
-  EXPECT_EQ(
-      MOJO_RESULT_OK,
-      dispatcher2->MapBuffer(0, 100, MOJO_MAP_BUFFER_FLAG_NONE, &mapping));
+  EXPECT_EQ(MOJO_RESULT_OK, dispatcher2->MapBuffer(
+                                0, 100, MOJO_MAP_BUFFER_FLAG_NONE, &mapping));
   EXPECT_EQ('x', static_cast<char*>(mapping->GetBase())[0]);
 
   EXPECT_EQ(MOJO_RESULT_OK, dispatcher2->Close());
@@ -190,12 +180,10 @@
 
 TEST_F(SharedBufferDispatcherTest, DuplicateBufferHandleOptionsValid) {
   scoped_refptr<SharedBufferDispatcher> dispatcher1;
-  EXPECT_EQ(MOJO_RESULT_OK,
-            SharedBufferDispatcher::Create(
-                platform_support(),
-                SharedBufferDispatcher::kDefaultCreateOptions,
-                100,
-                &dispatcher1));
+  EXPECT_EQ(MOJO_RESULT_OK, SharedBufferDispatcher::Create(
+                                platform_support(),
+                                SharedBufferDispatcher::kDefaultCreateOptions,
+                                100, &dispatcher1));
 
   MojoDuplicateBufferHandleOptions options[] = {
       {sizeof(MojoDuplicateBufferHandleOptions),
@@ -203,9 +191,8 @@
       {sizeof(MojoDuplicateBufferHandleOptionsFlags), ~0u}};
   for (size_t i = 0; i < arraysize(options); i++) {
     scoped_refptr<Dispatcher> dispatcher2;
-    EXPECT_EQ(MOJO_RESULT_OK,
-              dispatcher1->DuplicateBufferHandle(MakeUserPointer(&options[i]),
-                                                 &dispatcher2));
+    EXPECT_EQ(MOJO_RESULT_OK, dispatcher1->DuplicateBufferHandle(
+                                  MakeUserPointer(&options[i]), &dispatcher2));
     ASSERT_TRUE(dispatcher2.get());
     EXPECT_EQ(Dispatcher::kTypeSharedBuffer, dispatcher2->GetType());
     EXPECT_EQ(MOJO_RESULT_OK, dispatcher2->Close());
@@ -216,12 +203,10 @@
 
 TEST_F(SharedBufferDispatcherTest, DuplicateBufferHandleOptionsInvalid) {
   scoped_refptr<SharedBufferDispatcher> dispatcher1;
-  EXPECT_EQ(MOJO_RESULT_OK,
-            SharedBufferDispatcher::Create(
-                platform_support(),
-                SharedBufferDispatcher::kDefaultCreateOptions,
-                100,
-                &dispatcher1));
+  EXPECT_EQ(MOJO_RESULT_OK, SharedBufferDispatcher::Create(
+                                platform_support(),
+                                SharedBufferDispatcher::kDefaultCreateOptions,
+                                100, &dispatcher1));
 
   // Invalid |struct_size|.
   {
@@ -251,32 +236,27 @@
 TEST_F(SharedBufferDispatcherTest, CreateInvalidNumBytes) {
   // Size too big.
   scoped_refptr<SharedBufferDispatcher> dispatcher;
-  EXPECT_EQ(MOJO_RESULT_RESOURCE_EXHAUSTED,
-            SharedBufferDispatcher::Create(
-                platform_support(),
-                SharedBufferDispatcher::kDefaultCreateOptions,
-                std::numeric_limits<uint64_t>::max(),
-                &dispatcher));
+  EXPECT_EQ(
+      MOJO_RESULT_RESOURCE_EXHAUSTED,
+      SharedBufferDispatcher::Create(
+          platform_support(), SharedBufferDispatcher::kDefaultCreateOptions,
+          std::numeric_limits<uint64_t>::max(), &dispatcher));
   EXPECT_FALSE(dispatcher.get());
 
   // Zero size.
   EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
             SharedBufferDispatcher::Create(
                 platform_support(),
-                SharedBufferDispatcher::kDefaultCreateOptions,
-                0,
-                &dispatcher));
+                SharedBufferDispatcher::kDefaultCreateOptions, 0, &dispatcher));
   EXPECT_FALSE(dispatcher.get());
 }
 
 TEST_F(SharedBufferDispatcherTest, MapBufferInvalidArguments) {
   scoped_refptr<SharedBufferDispatcher> dispatcher;
-  EXPECT_EQ(MOJO_RESULT_OK,
-            SharedBufferDispatcher::Create(
-                platform_support(),
-                SharedBufferDispatcher::kDefaultCreateOptions,
-                100,
-                &dispatcher));
+  EXPECT_EQ(MOJO_RESULT_OK, SharedBufferDispatcher::Create(
+                                platform_support(),
+                                SharedBufferDispatcher::kDefaultCreateOptions,
+                                100, &dispatcher));
 
   scoped_ptr<embedder::PlatformSharedBufferMapping> mapping;
   EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
diff --git a/mojo/edk/system/simple_dispatcher_unittest.cc b/mojo/edk/system/simple_dispatcher_unittest.cc
index 502e34b..f23ff68 100644
--- a/mojo/edk/system/simple_dispatcher_unittest.cc
+++ b/mojo/edk/system/simple_dispatcher_unittest.cc
@@ -343,14 +343,9 @@
     scoped_refptr<MockSimpleDispatcher> d(new MockSimpleDispatcher());
     {
       d->SetSatisfiedSignals(MOJO_HANDLE_SIGNAL_READABLE);
-      test::WaiterThread thread(d,
-                                MOJO_HANDLE_SIGNAL_READABLE,
-                                MOJO_DEADLINE_INDEFINITE,
-                                1,
-                                &did_wait,
-                                &result,
-                                &context,
-                                &hss);
+      test::WaiterThread thread(d, MOJO_HANDLE_SIGNAL_READABLE,
+                                MOJO_DEADLINE_INDEFINITE, 1, &did_wait, &result,
+                                &context, &hss);
       stopwatch.Start();
       thread.Start();
     }  // Joins the thread.
@@ -368,14 +363,9 @@
   {
     scoped_refptr<MockSimpleDispatcher> d(new MockSimpleDispatcher());
     {
-      test::WaiterThread thread(d,
-                                MOJO_HANDLE_SIGNAL_READABLE,
-                                MOJO_DEADLINE_INDEFINITE,
-                                2,
-                                &did_wait,
-                                &result,
-                                &context,
-                                &hss);
+      test::WaiterThread thread(d, MOJO_HANDLE_SIGNAL_READABLE,
+                                MOJO_DEADLINE_INDEFINITE, 2, &did_wait, &result,
+                                &context, &hss);
       stopwatch.Start();
       thread.Start();
       base::PlatformThread::Sleep(2 * test::EpsilonTimeout());
@@ -397,14 +387,9 @@
   {
     scoped_refptr<MockSimpleDispatcher> d(new MockSimpleDispatcher());
     {
-      test::WaiterThread thread(d,
-                                MOJO_HANDLE_SIGNAL_READABLE,
-                                MOJO_DEADLINE_INDEFINITE,
-                                3,
-                                &did_wait,
-                                &result,
-                                &context,
-                                &hss);
+      test::WaiterThread thread(d, MOJO_HANDLE_SIGNAL_READABLE,
+                                MOJO_DEADLINE_INDEFINITE, 3, &did_wait, &result,
+                                &context, &hss);
       stopwatch.Start();
       thread.Start();
       base::PlatformThread::Sleep(2 * test::EpsilonTimeout());
@@ -424,14 +409,9 @@
   // Wait for readable and dispatcher gets closed.
   {
     scoped_refptr<MockSimpleDispatcher> d(new MockSimpleDispatcher());
-    test::WaiterThread thread(d,
-                              MOJO_HANDLE_SIGNAL_READABLE,
-                              MOJO_DEADLINE_INDEFINITE,
-                              4,
-                              &did_wait,
-                              &result,
-                              &context,
-                              &hss);
+    test::WaiterThread thread(d, MOJO_HANDLE_SIGNAL_READABLE,
+                              MOJO_DEADLINE_INDEFINITE, 4, &did_wait, &result,
+                              &context, &hss);
     stopwatch.Start();
     thread.Start();
     base::PlatformThread::Sleep(2 * test::EpsilonTimeout());
@@ -450,14 +430,9 @@
   {
     scoped_refptr<MockSimpleDispatcher> d(new MockSimpleDispatcher());
     {
-      test::WaiterThread thread(d,
-                                MOJO_HANDLE_SIGNAL_READABLE,
-                                2 * test::EpsilonTimeout().InMicroseconds(),
-                                5,
-                                &did_wait,
-                                &result,
-                                &context,
-                                &hss);
+      test::WaiterThread thread(d, MOJO_HANDLE_SIGNAL_READABLE,
+                                2 * test::EpsilonTimeout().InMicroseconds(), 5,
+                                &did_wait, &result, &context, &hss);
       stopwatch.Start();
       thread.Start();
       base::PlatformThread::Sleep(1 * test::EpsilonTimeout());
@@ -496,14 +471,9 @@
     scoped_refptr<MockSimpleDispatcher> d(new MockSimpleDispatcher());
     ScopedVector<test::WaiterThread> threads;
     for (uint32_t i = 0; i < kNumWaiters; i++) {
-      threads.push_back(new test::WaiterThread(d,
-                                               MOJO_HANDLE_SIGNAL_READABLE,
-                                               MOJO_DEADLINE_INDEFINITE,
-                                               i,
-                                               &did_wait[i],
-                                               &result[i],
-                                               &context[i],
-                                               &hss[i]));
+      threads.push_back(new test::WaiterThread(
+          d, MOJO_HANDLE_SIGNAL_READABLE, MOJO_DEADLINE_INDEFINITE, i,
+          &did_wait[i], &result[i], &context[i], &hss[i]));
       threads.back()->Start();
     }
     base::PlatformThread::Sleep(2 * test::EpsilonTimeout());
@@ -524,25 +494,15 @@
     scoped_refptr<MockSimpleDispatcher> d(new MockSimpleDispatcher());
     ScopedVector<test::WaiterThread> threads;
     for (uint32_t i = 0; i < kNumWaiters / 2; i++) {
-      threads.push_back(new test::WaiterThread(d,
-                                               MOJO_HANDLE_SIGNAL_READABLE,
-                                               MOJO_DEADLINE_INDEFINITE,
-                                               i,
-                                               &did_wait[i],
-                                               &result[i],
-                                               &context[i],
-                                               &hss[i]));
+      threads.push_back(new test::WaiterThread(
+          d, MOJO_HANDLE_SIGNAL_READABLE, MOJO_DEADLINE_INDEFINITE, i,
+          &did_wait[i], &result[i], &context[i], &hss[i]));
       threads.back()->Start();
     }
     for (uint32_t i = kNumWaiters / 2; i < kNumWaiters; i++) {
-      threads.push_back(new test::WaiterThread(d,
-                                               MOJO_HANDLE_SIGNAL_WRITABLE,
-                                               MOJO_DEADLINE_INDEFINITE,
-                                               i,
-                                               &did_wait[i],
-                                               &result[i],
-                                               &context[i],
-                                               &hss[i]));
+      threads.push_back(new test::WaiterThread(
+          d, MOJO_HANDLE_SIGNAL_WRITABLE, MOJO_DEADLINE_INDEFINITE, i,
+          &did_wait[i], &result[i], &context[i], &hss[i]));
       threads.back()->Start();
     }
     base::PlatformThread::Sleep(2 * test::EpsilonTimeout());
@@ -571,25 +531,15 @@
     scoped_refptr<MockSimpleDispatcher> d(new MockSimpleDispatcher());
     ScopedVector<test::WaiterThread> threads;
     for (uint32_t i = 0; i < kNumWaiters / 2; i++) {
-      threads.push_back(new test::WaiterThread(d,
-                                               MOJO_HANDLE_SIGNAL_READABLE,
-                                               MOJO_DEADLINE_INDEFINITE,
-                                               i,
-                                               &did_wait[i],
-                                               &result[i],
-                                               &context[i],
-                                               &hss[i]));
+      threads.push_back(new test::WaiterThread(
+          d, MOJO_HANDLE_SIGNAL_READABLE, MOJO_DEADLINE_INDEFINITE, i,
+          &did_wait[i], &result[i], &context[i], &hss[i]));
       threads.back()->Start();
     }
     for (uint32_t i = kNumWaiters / 2; i < kNumWaiters; i++) {
-      threads.push_back(new test::WaiterThread(d,
-                                               MOJO_HANDLE_SIGNAL_WRITABLE,
-                                               MOJO_DEADLINE_INDEFINITE,
-                                               i,
-                                               &did_wait[i],
-                                               &result[i],
-                                               &context[i],
-                                               &hss[i]));
+      threads.push_back(new test::WaiterThread(
+          d, MOJO_HANDLE_SIGNAL_WRITABLE, MOJO_DEADLINE_INDEFINITE, i,
+          &did_wait[i], &result[i], &context[i], &hss[i]));
       threads.back()->Start();
     }
     base::PlatformThread::Sleep(1 * test::EpsilonTimeout());
@@ -619,27 +569,17 @@
     scoped_refptr<MockSimpleDispatcher> d(new MockSimpleDispatcher());
     ScopedVector<test::WaiterThread> threads;
     for (uint32_t i = 0; i < kNumWaiters / 2; i++) {
-      threads.push_back(
-          new test::WaiterThread(d,
-                                 MOJO_HANDLE_SIGNAL_READABLE,
-                                 3 * test::EpsilonTimeout().InMicroseconds(),
-                                 i,
-                                 &did_wait[i],
-                                 &result[i],
-                                 &context[i],
-                                 &hss[i]));
+      threads.push_back(new test::WaiterThread(
+          d, MOJO_HANDLE_SIGNAL_READABLE,
+          3 * test::EpsilonTimeout().InMicroseconds(), i, &did_wait[i],
+          &result[i], &context[i], &hss[i]));
       threads.back()->Start();
     }
     for (uint32_t i = kNumWaiters / 2; i < kNumWaiters; i++) {
-      threads.push_back(
-          new test::WaiterThread(d,
-                                 MOJO_HANDLE_SIGNAL_WRITABLE,
-                                 1 * test::EpsilonTimeout().InMicroseconds(),
-                                 i,
-                                 &did_wait[i],
-                                 &result[i],
-                                 &context[i],
-                                 &hss[i]));
+      threads.push_back(new test::WaiterThread(
+          d, MOJO_HANDLE_SIGNAL_WRITABLE,
+          1 * test::EpsilonTimeout().InMicroseconds(), i, &did_wait[i],
+          &result[i], &context[i], &hss[i]));
       threads.back()->Start();
     }
     base::PlatformThread::Sleep(2 * test::EpsilonTimeout());
diff --git a/mojo/edk/system/test_utils.h b/mojo/edk/system/test_utils.h
index 3ab1907..b8dee66 100644
--- a/mojo/edk/system/test_utils.h
+++ b/mojo/edk/system/test_utils.h
@@ -5,10 +5,7 @@
 #ifndef MOJO_EDK_SYSTEM_TEST_UTILS_H_
 #define MOJO_EDK_SYSTEM_TEST_UTILS_H_
 
-#include <stdint.h>
-
 #include "base/callback_forward.h"
-#include "base/compiler_specific.h"
 #include "base/macros.h"
 #include "base/memory/ref_counted.h"
 #include "base/task_runner.h"
diff --git a/mojo/edk/system/transport_data.cc b/mojo/edk/system/transport_data.cc
index 774b744..300b731 100644
--- a/mojo/edk/system/transport_data.cc
+++ b/mojo/edk/system/transport_data.cc
@@ -9,7 +9,7 @@
 #include "base/compiler_specific.h"
 #include "base/logging.h"
 #include "mojo/edk/system/channel.h"
-#include "mojo/edk/system/constants.h"
+#include "mojo/edk/system/configuration.h"
 #include "mojo/edk/system/message_in_transit.h"
 
 namespace mojo {
@@ -32,19 +32,20 @@
     TransportData::kMaxSerializedDispatcherPlatformHandles;
 
 // static
-const size_t TransportData::kMaxPlatformHandles =
-    kMaxMessageNumHandles * kMaxSerializedDispatcherPlatformHandles;
+size_t TransportData::GetMaxBufferSize() {
+  // In additional to the header, for each attached (Mojo) handle there'll be a
+  // handle table entry and serialized dispatcher data.
+  return sizeof(Header) +
+         GetConfiguration().max_message_num_handles *
+             (sizeof(HandleTableEntry) + kMaxSerializedDispatcherSize) +
+         GetMaxPlatformHandles() * kMaxSizePerPlatformHandle;
+}
 
-// In additional to the header, for each attached (Mojo) handle there'll be a
-// handle table entry and serialized dispatcher data.
-// Note: This definition must follow the one for |kMaxPlatformHandles|;
-// otherwise, we get a static initializer with gcc (but not clang).
 // static
-const size_t TransportData::kMaxBufferSize =
-    sizeof(Header) +
-    kMaxMessageNumHandles *
-        (sizeof(HandleTableEntry) + kMaxSerializedDispatcherSize) +
-    kMaxPlatformHandles * kMaxSizePerPlatformHandle;
+size_t TransportData::GetMaxPlatformHandles() {
+  return GetConfiguration().max_message_num_handles *
+         kMaxSerializedDispatcherPlatformHandles;
+}
 
 struct TransportData::PrivateStructForCompileAsserts {
   static_assert(sizeof(Header) % MessageInTransit::kMessageAlignment == 0,
@@ -90,11 +91,11 @@
 
       DCHECK_LE(max_size, kMaxSerializedDispatcherSize);
       estimated_size += MessageInTransit::RoundUpMessageAlignment(max_size);
-      DCHECK_LE(estimated_size, kMaxBufferSize);
+      DCHECK_LE(estimated_size, GetMaxBufferSize());
 
       DCHECK_LE(max_platform_handles, kMaxSerializedDispatcherPlatformHandles);
       estimated_num_platform_handles += max_platform_handles;
-      DCHECK_LE(estimated_num_platform_handles, kMaxPlatformHandles);
+      DCHECK_LE(estimated_num_platform_handles, GetMaxPlatformHandles());
 
 #if DCHECK_IS_ON
       all_max_sizes[i] = max_size;
@@ -109,7 +110,7 @@
     DCHECK_LE(size_per_platform_handle, kMaxSizePerPlatformHandle);
     estimated_size += estimated_num_platform_handles * size_per_platform_handle;
     estimated_size = MessageInTransit::RoundUpMessageAlignment(estimated_size);
-    DCHECK_LE(estimated_size, kMaxBufferSize);
+    DCHECK_LE(estimated_size, GetMaxBufferSize());
   }
 
   buffer_.reset(static_cast<char*>(
@@ -148,10 +149,7 @@
     void* destination = buffer_.get() + current_offset;
     size_t actual_size = 0;
     if (Dispatcher::TransportDataAccess::EndSerializeAndClose(
-            dispatcher,
-            channel,
-            destination,
-            &actual_size,
+            dispatcher, channel, destination, &actual_size,
             platform_handles_.get())) {
       handle_table[i].type = static_cast<int32_t>(dispatcher->GetType());
       handle_table[i].offset = static_cast<uint32_t>(current_offset);
@@ -216,7 +214,7 @@
 
   // Always make sure that the buffer size is sane; if it's not, someone's
   // messing with us.
-  if (buffer_size < sizeof(Header) || buffer_size > kMaxBufferSize ||
+  if (buffer_size < sizeof(Header) || buffer_size > GetMaxBufferSize() ||
       buffer_size % MessageInTransit::kMessageAlignment != 0)
     return "Invalid message secondary buffer size";
 
@@ -233,7 +231,7 @@
 #endif
 
   // Sanity-check |num_handles| (before multiplying it against anything).
-  if (num_handles > kMaxMessageNumHandles)
+  if (num_handles > GetConfiguration().max_message_num_handles)
     return "Message handle payload too large";
 
   if (buffer_size < sizeof(Header) + num_handles * sizeof(HandleTableEntry))
diff --git a/mojo/edk/system/transport_data.h b/mojo/edk/system/transport_data.h
index 395bc73..d54ad2a 100644
--- a/mojo/edk/system/transport_data.h
+++ b/mojo/edk/system/transport_data.h
@@ -84,10 +84,10 @@
   static const size_t kMaxSerializedDispatcherPlatformHandles = 2;
 
   // The maximum possible size of a valid transport data buffer.
-  static const size_t kMaxBufferSize;
+  static size_t GetMaxBufferSize();
 
   // The maximum total number of platform handles that may be attached.
-  static const size_t kMaxPlatformHandles;
+  static size_t GetMaxPlatformHandles();
 
   TransportData(scoped_ptr<DispatcherVector> dispatchers, Channel* channel);
 
diff --git a/mojo/edk/system/waiter_test_utils.cc b/mojo/edk/system/waiter_test_utils.cc
index 06a4033..39cb14e 100644
--- a/mojo/edk/system/waiter_test_utils.cc
+++ b/mojo/edk/system/waiter_test_utils.cc
@@ -55,8 +55,8 @@
 void WaiterThread::Run() {
   waiter_.Init();
 
-  *result_out_ = dispatcher_->AddWaiter(
-      &waiter_, handle_signals_, context_, signals_state_out_);
+  *result_out_ = dispatcher_->AddWaiter(&waiter_, handle_signals_, context_,
+                                        signals_state_out_);
   if (*result_out_ != MOJO_RESULT_OK)
     return;
 
diff --git a/mojo/edk/test/multiprocess_test_helper.cc b/mojo/edk/test/multiprocess_test_helper.cc
index 02367d6..30aa0be 100644
--- a/mojo/edk/test/multiprocess_test_helper.cc
+++ b/mojo/edk/test/multiprocess_test_helper.cc
@@ -60,8 +60,8 @@
   CHECK_NE(test_child_handle_, base::kNullProcessHandle);
 
   int rv = -1;
-  CHECK(base::WaitForExitCodeWithTimeout(
-      test_child_handle_, &rv, TestTimeouts::action_timeout()));
+  CHECK(base::WaitForExitCodeWithTimeout(test_child_handle_, &rv,
+                                         TestTimeouts::action_timeout()));
   base::CloseProcessHandle(test_child_handle_);
   test_child_handle_ = base::kNullProcessHandle;
   return rv;
diff --git a/mojo/edk/test/multiprocess_test_helper.h b/mojo/edk/test/multiprocess_test_helper.h
index 6b2713f..d131460 100644
--- a/mojo/edk/test/multiprocess_test_helper.h
+++ b/mojo/edk/test/multiprocess_test_helper.h
@@ -7,8 +7,7 @@
 
 #include <string>
 
-#include "base/basictypes.h"
-#include "base/compiler_specific.h"
+#include "base/macros.h"
 #include "base/process/process_handle.h"
 #include "base/test/multiprocess_test.h"
 #include "base/test/test_timeouts.h"
diff --git a/mojo/edk/test/run_all_unittests.cc b/mojo/edk/test/run_all_unittests.cc
index c66ea50..166a73e 100644
--- a/mojo/edk/test/run_all_unittests.cc
+++ b/mojo/edk/test/run_all_unittests.cc
@@ -21,7 +21,6 @@
   mojo::test::TestSupport::Init(new mojo::test::TestSupportImpl());
 
   return base::LaunchUnitTests(
-      argc,
-      argv,
+      argc, argv,
       base::Bind(&base::TestSuite::Run, base::Unretained(&test_suite)));
 }
diff --git a/mojo/edk/test/test_support_impl.cc b/mojo/edk/test/test_support_impl.cc
index 2a86331..fae3a8f 100644
--- a/mojo/edk/test/test_support_impl.cc
+++ b/mojo/edk/test/test_support_impl.cc
@@ -56,8 +56,7 @@
 char** TestSupportImpl::EnumerateSourceRootRelativeDirectory(
     const char* relative_path) {
   std::vector<std::string> names;
-  base::FileEnumerator e(ResolveSourceRootRelativePath(relative_path),
-                         false,
+  base::FileEnumerator e(ResolveSourceRootRelativePath(relative_path), false,
                          base::FileEnumerator::FILES);
   for (base::FilePath name = e.Next(); !name.empty(); name = e.Next())
     names.push_back(name.BaseName().AsUTF8Unsafe());
diff --git a/mojo/mojo.gyp b/mojo/mojo.gyp
index 2837ece..10d0ae8 100644
--- a/mojo/mojo.gyp
+++ b/mojo/mojo.gyp
@@ -12,7 +12,7 @@
       'target_name': 'mojo',
       'type': 'none',
       'dependencies': [
-        'edk/mojo_edk.gyp:mojo_edk',
+        'edk/mojo_edk_tests.gyp:mojo_edk_tests',
         'mojo_base.gyp:mojo_base',
         'mojo_geometry_converters.gyp:mojo_geometry_lib',
         'mojo_input_events_converters.gyp:mojo_input_events_lib',
diff --git a/mojo/mojo_base.gyp b/mojo/mojo_base.gyp
index 96305df..bab8c0e 100644
--- a/mojo/mojo_base.gyp
+++ b/mojo/mojo_base.gyp
@@ -71,9 +71,11 @@
       'type': 'executable',
       'dependencies': [
         '../base/base.gyp:base',
+        '../base/base.gyp:test_support_base',
         '../base/base.gyp:base_message_loop_tests',
         '../testing/gtest.gyp:gtest',
         '../url/url.gyp:url_lib',
+        'edk/mojo_edk.gyp:mojo_system_impl',
         'edk/mojo_edk.gyp:mojo_common_test_support',
         'edk/mojo_edk.gyp:mojo_run_all_unittests',
         'mojo_common_lib',
@@ -85,14 +87,6 @@
         'common/common_type_converters_unittest.cc',
         'common/handle_watcher_unittest.cc',
         'common/message_pump_mojo_unittest.cc',
-        'edk/test/multiprocess_test_helper_unittest.cc',
-      ],
-      'conditions': [
-        ['OS=="ios"', {
-          'sources!': [
-            'edk/test/multiprocess_test_helper_unittest.cc',
-          ],
-        }],
       ],
     },
     {
diff --git a/mojo/public/VERSION b/mojo/public/VERSION
index 1156739..3a8f9d8 100644
--- a/mojo/public/VERSION
+++ b/mojo/public/VERSION
@@ -1 +1 @@
-04a510fb37db10642e156957f9b2c11c2f6442ac
\ No newline at end of file
+e01f9a49449381a5eb430c1fd88bf2cae73ec35a
\ No newline at end of file
diff --git a/mojo/public/cpp/application/lib/application_test_main.cc b/mojo/public/cpp/application/lib/application_test_main.cc
index 9b76dad..6cdfb0d 100644
--- a/mojo/public/cpp/application/lib/application_test_main.cc
+++ b/mojo/public/cpp/application/lib/application_test_main.cc
@@ -6,16 +6,18 @@
 #include "mojo/public/cpp/application/application_delegate.h"
 #include "mojo/public/cpp/application/application_impl.h"
 #include "mojo/public/cpp/application/application_test_base.h"
+#include "mojo/public/cpp/environment/environment.h"
 #include "mojo/public/cpp/environment/logging.h"
 #include "mojo/public/cpp/system/message_pipe.h"
+#include "mojo/public/cpp/utility/run_loop.h"
 
 MojoResult MojoMain(MojoHandle shell_handle) {
   // An Environment instance is needed to construct run loops.
   mojo::Environment environment;
 
   {
-    // This RunLoop is used for init, and then destroyed before running tests.
-    mojo::Environment::InstantiateDefaultRunLoop();
+    // This loop is used for init, and then destroyed before running tests.
+    mojo::RunLoop run_loop;
 
     // Construct an ApplicationImpl just for the GTEST commandline arguments.
     // GTEST command line arguments are supported amid application arguments:
@@ -38,7 +40,6 @@
 
     testing::InitGoogleTest(&argc, const_cast<char**>(&(argv[0])));
     mojo::test::SetShellHandle(app.UnbindShell());
-    mojo::Environment::DestroyDefaultRunLoop();
   }
 
   int result = RUN_ALL_TESTS();
diff --git a/mojo/public/cpp/bindings/binding.h b/mojo/public/cpp/bindings/binding.h
new file mode 100644
index 0000000..2c4c9ce
--- /dev/null
+++ b/mojo/public/cpp/bindings/binding.h
@@ -0,0 +1,136 @@
+// 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_PUBLIC_CPP_BINDINGS_BINDING_H_
+#define MOJO_PUBLIC_CPP_BINDINGS_BINDING_H_
+
+#include "mojo/public/c/environment/async_waiter.h"
+#include "mojo/public/cpp/bindings/error_handler.h"
+#include "mojo/public/cpp/bindings/interface_ptr.h"
+#include "mojo/public/cpp/bindings/interface_request.h"
+#include "mojo/public/cpp/bindings/lib/filter_chain.h"
+#include "mojo/public/cpp/bindings/lib/message_header_validator.h"
+#include "mojo/public/cpp/bindings/lib/router.h"
+#include "mojo/public/cpp/environment/logging.h"
+#include "mojo/public/cpp/system/core.h"
+
+namespace mojo {
+
+// This binds an interface implementation a pipe. Deleting the binding closes
+// the pipe.
+//
+// Example:
+//
+//   #include "foo.mojom.h"
+//
+//   class FooImpl : public Foo {
+//    public:
+//     explicit FooImpl(ScopedMessagePipeHandle handle)
+//         : binding_(this, handle.Pass()) {}
+//
+//     // Foo implementation here.
+//
+//    private:
+//     Binding<Foo> binding_;
+//   };
+//
+template <typename Interface>
+class Binding : public ErrorHandler {
+ public:
+  using Client = typename Interface::Client;
+
+  explicit Binding(Interface* impl) : impl_(impl) { stub_.set_sink(impl_); }
+
+  Binding(Interface* impl,
+          ScopedMessagePipeHandle handle,
+          const MojoAsyncWaiter* waiter = Environment::GetDefaultAsyncWaiter())
+      : Binding(impl) {
+    Bind(handle.Pass(), waiter);
+  }
+
+  Binding(Interface* impl,
+          InterfacePtr<Interface>* ptr,
+          const MojoAsyncWaiter* waiter = Environment::GetDefaultAsyncWaiter())
+      : Binding(impl) {
+    Bind(ptr, waiter);
+  }
+
+  Binding(Interface* impl,
+          InterfaceRequest<Interface> request,
+          const MojoAsyncWaiter* waiter = Environment::GetDefaultAsyncWaiter())
+      : Binding(impl) {
+    Bind(request.PassMessagePipe(), waiter);
+  }
+
+  ~Binding() override {
+    delete proxy_;
+    if (internal_router_) {
+      internal_router_->set_error_handler(nullptr);
+      delete internal_router_;
+    }
+  }
+
+  void Bind(
+      ScopedMessagePipeHandle handle,
+      const MojoAsyncWaiter* waiter = Environment::GetDefaultAsyncWaiter()) {
+    internal::FilterChain filters;
+    filters.Append<internal::MessageHeaderValidator>();
+    filters.Append<typename Interface::RequestValidator_>();
+    filters.Append<typename Client::ResponseValidator_>();
+
+    internal_router_ =
+        new internal::Router(handle.Pass(), filters.Pass(), waiter);
+    internal_router_->set_incoming_receiver(&stub_);
+    internal_router_->set_error_handler(this);
+
+    proxy_ = new typename Client::Proxy_(internal_router_);
+  }
+
+  void Bind(
+      InterfacePtr<Interface>* ptr,
+      const MojoAsyncWaiter* waiter = Environment::GetDefaultAsyncWaiter()) {
+    MessagePipe pipe;
+    ptr->Bind(pipe.handle0.Pass(), waiter);
+    Bind(pipe.handle1.Pass(), waiter);
+  }
+
+  void Bind(
+      InterfaceRequest<Interface> request,
+      const MojoAsyncWaiter* waiter = Environment::GetDefaultAsyncWaiter()) {
+    Bind(request.PassMessagePipe(), waiter);
+  }
+
+  bool WaitForIncomingMethodCall() {
+    MOJO_DCHECK(internal_router_);
+    return internal_router_->WaitForIncomingMessage();
+  }
+
+  void set_error_handler(ErrorHandler* error_handler) {
+    error_handler_ = error_handler;
+  }
+
+  // ErrorHandler implementation
+  void OnConnectionError() override {
+    if (error_handler_)
+      error_handler_->OnConnectionError();
+  }
+
+  Interface* impl() { return impl_; }
+  Client* client() { return proxy_; }
+  // Exposed for testing, should not generally be used.
+  internal::Router* internal_router() { return internal_router_; }
+
+ private:
+  internal::Router* internal_router_ = nullptr;
+  typename Client::Proxy_* proxy_ = nullptr;
+  typename Interface::Stub_ stub_;
+  Interface* impl_;
+  ErrorHandler* error_handler_ = nullptr;
+
+  MOJO_DISALLOW_COPY_AND_ASSIGN(Binding);
+};
+
+}  // namespace mojo
+
+#endif  // MOJO_PUBLIC_CPP_BINDINGS_BINDING_H_
diff --git a/mojo/public/cpp/bindings/interface_impl.h b/mojo/public/cpp/bindings/interface_impl.h
index da1055d..0917103 100644
--- a/mojo/public/cpp/bindings/interface_impl.h
+++ b/mojo/public/cpp/bindings/interface_impl.h
@@ -5,40 +5,41 @@
 #ifndef MOJO_PUBLIC_CPP_BINDINGS_INTERFACE_IMPL_H_
 #define MOJO_PUBLIC_CPP_BINDINGS_INTERFACE_IMPL_H_
 
+#include "mojo/public/cpp/bindings/binding.h"
 #include "mojo/public/cpp/bindings/interface_request.h"
-#include "mojo/public/cpp/bindings/lib/interface_impl_internal.h"
 #include "mojo/public/cpp/environment/environment.h"
 #include "mojo/public/cpp/system/macros.h"
 
 namespace mojo {
 
+// DEPRECATED! Please use mojo::Binding instead of InterfaceImpl<> in new code.
+//
 // InterfaceImpl<..> is designed to be the base class of an interface
 // implementation. It may be bound to a pipe or a proxy, see BindToPipe and
 // BindToProxy.
 template <typename Interface>
-class InterfaceImpl : public internal::InterfaceImplBase<Interface> {
+class InterfaceImpl : public Interface, public ErrorHandler {
  public:
-  typedef typename Interface::Client Client;
-  typedef Interface ImplementedInterface;
+  using ImplementedInterface = Interface;
+  using Client = typename Interface::Client;
 
-  InterfaceImpl() : internal_state_(this) {}
+  InterfaceImpl() : binding_(this), error_handler_impl_(this) {
+    binding_.set_error_handler(&error_handler_impl_);
+  }
   virtual ~InterfaceImpl() {}
 
-  // Returns a proxy to the client interface. This is null upon construction,
-  // and becomes non-null after OnClientConnected. NOTE: It remains non-null
-  // until this instance is deleted.
-  Client* client() { return internal_state_.client(); }
-
-  // Blocks the current thread for the first incoming method call, i.e., either
-  // a call to a method or a client callback method. Returns |true| if a method
-  // has been called, |false| in case of error. It must only be called on a
-  // bound object.
-  bool WaitForIncomingMethodCall() {
-    return internal_state_.WaitForIncomingMethodCall();
+  void BindToHandle(
+      ScopedMessagePipeHandle handle,
+      const MojoAsyncWaiter* waiter = Environment::GetDefaultAsyncWaiter()) {
+    binding_.Bind(handle.Pass(), waiter);
   }
 
-  // Called when the client has connected to this instance.
-  virtual void OnConnectionEstablished() {}
+  bool WaitForIncomingMethodCall() {
+    return binding_.WaitForIncomingMethodCall();
+  }
+
+  Client* client() { return binding_.client(); }
+  internal::Router* internal_router() { return binding_.internal_router(); }
 
   // Called when the client is no longer connected to this instance. NOTE: The
   // client() method continues to return a non-null pointer after this method
@@ -46,13 +47,42 @@
   // will be silently ignored.
   virtual void OnConnectionError() {}
 
-  // DO NOT USE. Exposed only for internal use and for testing.
-  internal::InterfaceImplState<Interface>* internal_state() {
-    return &internal_state_;
+  void set_delete_on_error(bool delete_on_error) {
+    error_handler_impl_.set_delete_on_error(delete_on_error);
   }
 
  private:
-  internal::InterfaceImplState<Interface> internal_state_;
+  class ErrorHandlerImpl : public ErrorHandler {
+   public:
+    explicit ErrorHandlerImpl(InterfaceImpl* impl) : impl_(impl) {}
+    ~ErrorHandlerImpl() override {}
+
+    // ErrorHandler implementation:
+    void OnConnectionError() override {
+      // If the the instance is not bound to the pipe, the instance might choose
+      // to delete the binding in the OnConnectionError handler, which would in
+      // turn delete |this|.  Save the error behavior before invoking the error
+      // handler so we can correctly decide what to do.
+      bool delete_on_error = delete_on_error_;
+      impl_->OnConnectionError();
+      if (delete_on_error)
+        delete impl_;
+    }
+
+    void set_delete_on_error(bool delete_on_error) {
+      delete_on_error_ = delete_on_error;
+    }
+
+   private:
+    InterfaceImpl* impl_;
+    bool delete_on_error_ = false;
+
+    MOJO_DISALLOW_COPY_AND_ASSIGN(ErrorHandlerImpl);
+  };
+
+  Binding<Interface> binding_;
+  ErrorHandlerImpl error_handler_impl_;
+
   MOJO_DISALLOW_COPY_AND_ASSIGN(InterfaceImpl);
 };
 
@@ -67,14 +97,13 @@
 // called on the current thread, and if the current thread exits, then the end
 // point of the pipe will be closed and the error handler's OnConnectionError
 // method will be called.
-//
-// Before returning, the instance's OnConnectionEstablished method is called.
 template <typename Impl>
 Impl* BindToPipe(
     Impl* instance,
     ScopedMessagePipeHandle handle,
     const MojoAsyncWaiter* waiter = Environment::GetDefaultAsyncWaiter()) {
-  instance->internal_state()->Bind(handle.Pass(), true, waiter);
+  instance->set_delete_on_error(true);
+  instance->BindToHandle(handle.Pass(), waiter);
   return instance;
 }
 
@@ -84,7 +113,7 @@
     Impl* instance,
     ScopedMessagePipeHandle handle,
     const MojoAsyncWaiter* waiter = Environment::GetDefaultAsyncWaiter()) {
-  instance->internal_state()->Bind(handle.Pass(), false, waiter);
+  instance->BindToHandle(handle.Pass(), waiter);
   return instance;
 }
 
@@ -97,14 +126,13 @@
 // The instance is also bound to the current thread. Its methods will only be
 // called on the current thread, and if the current thread exits, then it will
 // also be deleted, and along with it, its end point of the pipe will be closed.
-//
-// Before returning, the instance's OnConnectionEstablished method is called.
 template <typename Impl, typename Interface>
 Impl* BindToProxy(
     Impl* instance,
     InterfacePtr<Interface>* ptr,
     const MojoAsyncWaiter* waiter = Environment::GetDefaultAsyncWaiter()) {
-  instance->internal_state()->BindProxy(ptr, true, waiter);
+  instance->set_delete_on_error(true);
+  WeakBindToProxy(instance, ptr, waiter);
   return instance;
 }
 
@@ -114,7 +142,9 @@
     Impl* instance,
     InterfacePtr<Interface>* ptr,
     const MojoAsyncWaiter* waiter = Environment::GetDefaultAsyncWaiter()) {
-  instance->internal_state()->BindProxy(ptr, false, waiter);
+  MessagePipe pipe;
+  ptr->Bind(pipe.handle0.Pass(), waiter);
+  instance->BindToHandle(pipe.handle1.Pass(), waiter);
   return instance;
 }
 
diff --git a/mojo/public/cpp/bindings/lib/interface_impl_internal.h b/mojo/public/cpp/bindings/lib/interface_impl_internal.h
deleted file mode 100644
index 492b182..0000000
--- a/mojo/public/cpp/bindings/lib/interface_impl_internal.h
+++ /dev/null
@@ -1,128 +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_PUBLIC_CPP_BINDINGS_LIB_INTERFACE_IMPL_INTERNAL_H_
-#define MOJO_PUBLIC_CPP_BINDINGS_LIB_INTERFACE_IMPL_INTERNAL_H_
-
-#include "mojo/public/cpp/bindings/error_handler.h"
-#include "mojo/public/cpp/bindings/interface_ptr.h"
-#include "mojo/public/cpp/bindings/lib/filter_chain.h"
-#include "mojo/public/cpp/bindings/lib/message_header_validator.h"
-#include "mojo/public/cpp/environment/environment.h"
-#include "mojo/public/cpp/environment/logging.h"
-#include "mojo/public/cpp/system/macros.h"
-
-namespace mojo {
-namespace internal {
-
-template <typename Interface>
-class InterfaceImplBase : public Interface {
- public:
-  virtual ~InterfaceImplBase() {}
-  virtual void OnConnectionEstablished() = 0;
-  virtual void OnConnectionError() = 0;
-};
-
-template <typename Interface>
-class InterfaceImplState : public ErrorHandler {
- public:
-  typedef typename Interface::Client Client;
-
-  explicit InterfaceImplState(InterfaceImplBase<Interface>* instance)
-      : router_(nullptr),
-        proxy_(nullptr),
-        instance_bound_to_pipe_(false)
-#ifndef NDEBUG
-        ,
-        deleting_instance_due_to_error_(false)
-#endif
-  {
-    MOJO_DCHECK(instance);
-    stub_.set_sink(instance);
-  }
-
-  virtual ~InterfaceImplState() {
-#ifndef NDEBUG
-    MOJO_DCHECK(!instance_bound_to_pipe_ || deleting_instance_due_to_error_);
-#endif
-    delete proxy_;
-    if (router_) {
-      router_->set_error_handler(nullptr);
-      delete router_;
-    }
-  }
-
-  void BindProxy(
-      InterfacePtr<Interface>* ptr,
-      bool instance_bound_to_pipe,
-      const MojoAsyncWaiter* waiter = Environment::GetDefaultAsyncWaiter()) {
-    MessagePipe pipe;
-    ptr->Bind(pipe.handle0.Pass(), waiter);
-    Bind(pipe.handle1.Pass(), instance_bound_to_pipe, waiter);
-  }
-
-  void Bind(ScopedMessagePipeHandle handle,
-            bool instance_bound_to_pipe,
-            const MojoAsyncWaiter* waiter) {
-    MOJO_CHECK(!router_);
-
-    FilterChain filters;
-    filters.Append<MessageHeaderValidator>();
-    filters.Append<typename Interface::RequestValidator_>();
-    filters.Append<typename Interface::Client::ResponseValidator_>();
-
-    router_ = new Router(handle.Pass(), filters.Pass(), waiter);
-    router_->set_incoming_receiver(&stub_);
-    router_->set_error_handler(this);
-
-    proxy_ = new typename Client::Proxy_(router_);
-
-    instance_bound_to_pipe_ = instance_bound_to_pipe;
-
-    instance()->OnConnectionEstablished();
-  }
-
-  bool WaitForIncomingMethodCall() {
-    MOJO_DCHECK(router_);
-    return router_->WaitForIncomingMessage();
-  }
-
-  Router* router() { return router_; }
-  Client* client() { return proxy_; }
-
- private:
-  InterfaceImplBase<Interface>* instance() {
-    return static_cast<InterfaceImplBase<Interface>*>(stub_.sink());
-  }
-
-  virtual void OnConnectionError() override {
-    // If the the instance is not bound to the pipe, the instance might choose
-    // to delete itself in the OnConnectionError handler, which would in turn
-    // delete this.  Save the error behavior before invoking the error handler
-    // so we can correctly decide what to do.
-    bool bound = instance_bound_to_pipe_;
-    instance()->OnConnectionError();
-    if (!bound)
-      return;
-#ifndef NDEBUG
-    deleting_instance_due_to_error_ = true;
-#endif
-    delete instance();
-  }
-
-  Router* router_;
-  typename Client::Proxy_* proxy_;
-  typename Interface::Stub_ stub_;
-  bool instance_bound_to_pipe_;
-#ifndef NDEBUG
-  bool deleting_instance_due_to_error_;
-#endif
-
-  MOJO_DISALLOW_COPY_AND_ASSIGN(InterfaceImplState);
-};
-
-}  // namespace internal
-}  // namespace mojo
-
-#endif  // MOJO_PUBLIC_CPP_BINDINGS_LIB_INTERFACE_IMPL_INTERNAL_H_
diff --git a/mojo/public/cpp/bindings/strong_binding.h b/mojo/public/cpp/bindings/strong_binding.h
new file mode 100644
index 0000000..106b282
--- /dev/null
+++ b/mojo/public/cpp/bindings/strong_binding.h
@@ -0,0 +1,96 @@
+// 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_PUBLIC_CPP_BINDINGS_STRONG_BINDING_H_
+#define MOJO_PUBLIC_CPP_BINDINGS_STRONG_BINDING_H_
+
+#include "mojo/public/c/environment/async_waiter.h"
+#include "mojo/public/cpp/bindings/binding.h"
+#include "mojo/public/cpp/bindings/error_handler.h"
+#include "mojo/public/cpp/bindings/interface_ptr.h"
+#include "mojo/public/cpp/bindings/interface_request.h"
+#include "mojo/public/cpp/bindings/lib/filter_chain.h"
+#include "mojo/public/cpp/bindings/lib/message_header_validator.h"
+#include "mojo/public/cpp/bindings/lib/router.h"
+#include "mojo/public/cpp/system/core.h"
+
+namespace mojo {
+
+// This connects an interface implementation strongly to a pipe. When a
+// connection error is detected the implementation is deleted. Deleting the
+// connector also closes the pipe.
+//
+// Example of an implementation that is always bound strongly to a pipe
+//
+//   class StronglyBound : public Foo {
+//    public:
+//     explicit StronglyBound(ScopedMessagePipeHandle handle)
+//         : binding_(this, handle.Pass()) {}
+//
+//     // Foo implementation here
+//
+//    private:
+//     StrongBinding<Foo> binding_;
+//   };
+//
+template <typename Interface>
+class StrongBinding : public ErrorHandler {
+ public:
+  explicit StrongBinding(Interface* impl) : binding_(impl) {
+    binding_.set_error_handler(this);
+  }
+
+  StrongBinding(
+      Interface* impl,
+      ScopedMessagePipeHandle handle,
+      const MojoAsyncWaiter* waiter = Environment::GetDefaultAsyncWaiter())
+      : StrongBinding(impl) {
+    binding_.Bind(handle.Pass(), waiter);
+  }
+
+  StrongBinding(
+      Interface* impl,
+      InterfacePtr<Interface>* ptr,
+      const MojoAsyncWaiter* waiter = Environment::GetDefaultAsyncWaiter())
+      : StrongBinding(impl) {
+    binding_.Bind(ptr, waiter);
+  }
+
+  StrongBinding(
+      Interface* impl,
+      InterfaceRequest<Interface> request,
+      const MojoAsyncWaiter* waiter = Environment::GetDefaultAsyncWaiter())
+      : StrongBinding(impl) {
+    binding_.Bind(request.Pass(), waiter);
+  }
+
+  ~StrongBinding() override {}
+
+  bool WaitForIncomingMethodCall() {
+    return binding_.WaitForIncomingMethodCall();
+  }
+
+  void set_error_handler(ErrorHandler* error_handler) {
+    error_handler_ = error_handler;
+  }
+
+  typename Interface::Client* client() { return binding_.client(); }
+  // Exposed for testing, should not generally be used.
+  internal::Router* internal_router() { return binding_.internal_router(); }
+
+  // ErrorHandler implementation
+  void OnConnectionError() override {
+    if (error_handler_)
+      error_handler_->OnConnectionError();
+    delete binding_.impl();
+  }
+
+ private:
+  ErrorHandler* error_handler_ = nullptr;
+  Binding<Interface> binding_;
+};
+
+}  // namespace mojo
+
+#endif  // MOJO_PUBLIC_CPP_BINDINGS_STRONG_BINDING_H_
diff --git a/mojo/public/cpp/bindings/tests/interface_ptr_unittest.cc b/mojo/public/cpp/bindings/tests/interface_ptr_unittest.cc
index 0cd5646..91ce84b 100644
--- a/mojo/public/cpp/bindings/tests/interface_ptr_unittest.cc
+++ b/mojo/public/cpp/bindings/tests/interface_ptr_unittest.cc
@@ -2,7 +2,9 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include "mojo/public/cpp/bindings/binding.h"
 #include "mojo/public/cpp/bindings/error_handler.h"
+#include "mojo/public/cpp/bindings/strong_binding.h"
 #include "mojo/public/cpp/environment/environment.h"
 #include "mojo/public/cpp/utility/run_loop.h"
 #include "mojo/public/interfaces/bindings/tests/math_calculator.mojom.h"
@@ -29,9 +31,7 @@
  public:
   ~MathCalculatorImpl() override {}
 
-  MathCalculatorImpl() : total_(0.0), got_connection_(false) {}
-
-  void OnConnectionEstablished() override { got_connection_ = true; }
+  MathCalculatorImpl() : total_(0.0) {}
 
   void Clear() override { client()->Output(total_); }
 
@@ -45,11 +45,8 @@
     client()->Output(total_);
   }
 
-  bool got_connection() const { return got_connection_; }
-
  private:
   double total_;
-  bool got_connection_;
 };
 
 class MathCalculatorUIImpl : public math::CalculatorUI {
@@ -123,12 +120,7 @@
  public:
   ~ReentrantServiceImpl() override {}
 
-  ReentrantServiceImpl()
-      : got_connection_(false), call_depth_(0), max_call_depth_(0) {}
-
-  void OnConnectionEstablished() override { got_connection_ = true; }
-
-  bool got_connection() const { return got_connection_; }
+  ReentrantServiceImpl() : call_depth_(0), max_call_depth_(0) {}
 
   int max_call_depth() { return max_call_depth_; }
 
@@ -145,7 +137,6 @@
   void GetPort(mojo::InterfaceRequest<sample::Port> port) override {}
 
  private:
-  bool got_connection_;
   int call_depth_;
   int max_call_depth_;
 };
@@ -163,8 +154,7 @@
 
 TEST_F(InterfacePtrTest, EndToEnd) {
   math::CalculatorPtr calc;
-  MathCalculatorImpl* impl = BindToProxy(new MathCalculatorImpl(), &calc);
-  EXPECT_TRUE(impl->got_connection());
+  BindToProxy(new MathCalculatorImpl(), &calc);
 
   // Suppose this is instantiated in a process that has pipe1_.
   MathCalculatorUIImpl calculator_ui(calc.Pass());
@@ -180,7 +170,6 @@
 TEST_F(InterfacePtrTest, EndToEnd_Synchronous) {
   math::CalculatorPtr calc;
   MathCalculatorImpl* impl = BindToProxy(new MathCalculatorImpl(), &calc);
-  EXPECT_TRUE(impl->got_connection());
 
   // Suppose this is instantiated in a process that has pipe1_.
   MathCalculatorUIImpl calculator_ui(calc.Pass());
@@ -252,7 +241,7 @@
   EXPECT_FALSE(calculator_ui.encountered_error());
 
   // Close the server.
-  server->internal_state()->router()->CloseMessagePipe();
+  server->internal_router()->CloseMessagePipe();
 
   // The state change isn't picked up locally yet.
   EXPECT_FALSE(calculator_ui.encountered_error());
@@ -281,7 +270,7 @@
   EXPECT_FALSE(calculator_ui.encountered_error());
 
   // Close the server.
-  server->internal_state()->router()->CloseMessagePipe();
+  server->internal_router()->CloseMessagePipe();
 
   // The state change isn't picked up locally yet.
   EXPECT_FALSE(calculator_ui.encountered_error());
@@ -337,7 +326,6 @@
 TEST_F(InterfacePtrTest, ReentrantWaitForIncomingMethodCall) {
   sample::ServicePtr proxy;
   ReentrantServiceImpl* impl = BindToProxy(new ReentrantServiceImpl(), &proxy);
-  EXPECT_TRUE(impl->got_connection());
 
   proxy->Frobinate(sample::FooPtr(),
                    sample::Service::BAZ_OPTIONS_REGULAR,
@@ -351,6 +339,148 @@
   EXPECT_EQ(2, impl->max_call_depth());
 }
 
+class StrongMathCalculatorImpl : public math::Calculator, public ErrorHandler {
+ public:
+  StrongMathCalculatorImpl(ScopedMessagePipeHandle handle,
+                           bool* error_received,
+                           bool* destroyed)
+      : error_received_(error_received),
+        destroyed_(destroyed),
+        binding_(this, handle.Pass()) {
+    binding_.set_error_handler(this);
+  }
+  ~StrongMathCalculatorImpl() override { *destroyed_ = true; }
+
+  // math::Calculator implementation.
+  void Clear() override { binding_.client()->Output(total_); }
+
+  void Add(double value) override {
+    total_ += value;
+    binding_.client()->Output(total_);
+  }
+
+  void Multiply(double value) override {
+    total_ *= value;
+    binding_.client()->Output(total_);
+  }
+
+  // ErrorHandler implementation.
+  void OnConnectionError() override { *error_received_ = true; }
+
+ private:
+  double total_ = 0.0;
+  bool* error_received_;
+  bool* destroyed_;
+
+  StrongBinding<math::Calculator> binding_;
+};
+
+TEST(StrongConnectorTest, Math) {
+  Environment env;
+  RunLoop loop;
+
+  bool error_received = false;
+  bool destroyed = false;
+  MessagePipe pipe;
+  new StrongMathCalculatorImpl(pipe.handle0.Pass(), &error_received,
+                               &destroyed);
+
+  math::CalculatorPtr calc;
+  calc.Bind(pipe.handle1.Pass());
+
+  {
+    // Suppose this is instantiated in a process that has the other end of the
+    // message pipe.
+    MathCalculatorUIImpl calculator_ui(calc.Pass());
+
+    calculator_ui.Add(2.0);
+    calculator_ui.Multiply(5.0);
+
+    loop.RunUntilIdle();
+
+    EXPECT_EQ(10.0, calculator_ui.GetOutput());
+    EXPECT_FALSE(error_received);
+    EXPECT_FALSE(destroyed);
+  }
+  // Destroying calculator_ui should close the pipe and generate an error on the
+  // other
+  // end which will destroy the instance since it is strongly bound.
+
+  loop.RunUntilIdle();
+  EXPECT_TRUE(error_received);
+  EXPECT_TRUE(destroyed);
+}
+
+class WeakMathCalculatorImpl : public math::Calculator, public ErrorHandler {
+ public:
+  WeakMathCalculatorImpl(ScopedMessagePipeHandle handle,
+                         bool* error_received,
+                         bool* destroyed)
+      : error_received_(error_received),
+        destroyed_(destroyed),
+        binding_(this, handle.Pass()) {
+    binding_.set_error_handler(this);
+  }
+  ~WeakMathCalculatorImpl() override { *destroyed_ = true; }
+
+  void Clear() override { binding_.client()->Output(total_); }
+
+  void Add(double value) override {
+    total_ += value;
+    binding_.client()->Output(total_);
+  }
+
+  void Multiply(double value) override {
+    total_ *= value;
+    binding_.client()->Output(total_);
+  }
+
+  // ErrorHandler implementation.
+  void OnConnectionError() override { *error_received_ = true; }
+
+ private:
+  double total_ = 0.0;
+  bool* error_received_;
+  bool* destroyed_;
+
+  Binding<math::Calculator> binding_;
+};
+
+TEST(WeakConnectorTest, Math) {
+  Environment env;
+  RunLoop loop;
+
+  bool error_received = false;
+  bool destroyed = false;
+  MessagePipe pipe;
+  WeakMathCalculatorImpl impl(pipe.handle0.Pass(), &error_received, &destroyed);
+
+  math::CalculatorPtr calc;
+  calc.Bind(pipe.handle1.Pass());
+
+  {
+    // Suppose this is instantiated in a process that has the other end of the
+    // message pipe.
+    MathCalculatorUIImpl calculator_ui(calc.Pass());
+
+    calculator_ui.Add(2.0);
+    calculator_ui.Multiply(5.0);
+
+    loop.RunUntilIdle();
+
+    EXPECT_EQ(10.0, calculator_ui.GetOutput());
+    EXPECT_FALSE(error_received);
+    EXPECT_FALSE(destroyed);
+    // Destroying calculator_ui should close the pipe and generate an error on
+    // the other
+    // end which will destroy the instance since it is strongly bound.
+  }
+
+  loop.RunUntilIdle();
+  EXPECT_TRUE(error_received);
+  EXPECT_FALSE(destroyed);
+}
+
 }  // namespace
 }  // namespace test
 }  // namespace mojo
diff --git a/mojo/public/cpp/bindings/tests/validation_unittest.cc b/mojo/public/cpp/bindings/tests/validation_unittest.cc
index c7edf19..6507f21 100644
--- a/mojo/public/cpp/bindings/tests/validation_unittest.cc
+++ b/mojo/public/cpp/bindings/tests/validation_unittest.cc
@@ -409,7 +409,7 @@
   // |interface1_impl| will delete itself when the pipe is closed.
   IntegrationTestInterface1Impl* interface1_impl =
       BindToPipe(new IntegrationTestInterface1Impl(), testee_endpoint().Pass());
-  interface1_impl->internal_state()->router()->EnableTestingMode();
+  interface1_impl->internal_router()->EnableTestingMode();
 
   RunValidationTests("integration_", test_message_receiver());
 }
diff --git a/mojo/public/dart/README b/mojo/public/dart/README
index aadb348..5ff7ee3 100644
--- a/mojo/public/dart/README
+++ b/mojo/public/dart/README
@@ -39,3 +39,17 @@
 4.) Run Dart tests.
 
   $ ./mojob.sh --release darttest
+
+
+These are instructions for adding a Dart VM source checkout to your client.
+
+1. Edit your .gclient file.
+
+  Replace "DEPS" with "DEPS.dart"
+
+2. Run:
+
+  $ gclient sync
+
+  You should now have a directory //src/dart
+
diff --git a/mojo/public/dart/core.dart b/mojo/public/dart/core.dart
new file mode 100644
index 0000000..6f26104
--- /dev/null
+++ b/mojo/public/dart/core.dart
@@ -0,0 +1,20 @@
+// 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.
+
+library core;
+
+import 'dart:async';
+import 'dart:core';
+import 'dart:isolate';
+import 'dart:typed_data';
+import 'dart-ext:src/mojo_dart_core';
+
+part 'src/buffer.dart';
+part 'src/data_pipe.dart';
+part 'src/handle.dart';
+part 'src/handle_watcher.dart';
+part 'src/message_pipe.dart';
+part 'src/types.dart';
+
+void mojoSystemThunksSet(int thunks) native "MojoSystemThunks_Set";
diff --git a/mojo/public/dart/mojo_init.dart b/mojo/public/dart/mojo_init.dart
new file mode 100644
index 0000000..2b93af6
--- /dev/null
+++ b/mojo/public/dart/mojo_init.dart
@@ -0,0 +1,19 @@
+// 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.
+
+library mojo_init;
+
+import 'dart:async';
+
+import 'core.dart' as core;
+import 'dart-ext:src/mojo_dart_init';
+
+void _init() native "MojoLibrary_Init";
+void _mojoSystemThunksMake(Function fn) native "MojoSystemThunks_Make";
+
+Future<Isolate> mojoInit() {
+  _init();
+  _mojoSystemThunksMake(core.mojoSystemThunksSet);
+  return core.MojoHandleWatcher.Start();
+}
diff --git a/mojo/public/dart/src/buffer.dart b/mojo/public/dart/src/buffer.dart
new file mode 100644
index 0000000..a00838e
--- /dev/null
+++ b/mojo/public/dart/src/buffer.dart
@@ -0,0 +1,107 @@
+// 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.
+
+part of core;
+
+class _MojoSharedBufferNatives {
+  static List Create(int num_bytes, int flags)
+      native "MojoSharedBuffer_Create";
+
+  static List Duplicate(int buffer_handle, int flags)
+      native "MojoSharedBuffer_Duplicate";
+
+  static List Map(int buffer_handle, int offset, int num_bytes, int flags)
+      native "MojoSharedBuffer_Map";
+
+  static int Unmap(ByteData buffer)
+      native "MojoSharedBuffer_Unmap";
+}
+
+
+class MojoSharedBuffer {
+  static const int CREATE_FLAG_NONE = 0;
+  static const int DUPLICATE_FLAG_NONE = 0;
+  static const int MAP_FLAG_NONE = 0;
+
+  RawMojoHandle handle;
+  MojoResult status;
+  ByteData mapping;
+
+  MojoSharedBuffer._() {
+    handle = null;
+    status = MojoResult.OK;
+    mapping = null;
+  }
+
+  factory MojoSharedBuffer(int num_bytes, [int flags = 0]) {
+    List result = _MojoSharedBufferNatives.Create(num_bytes, flags);
+    if (result == null) {
+      return null;
+    }
+    assert((result is List) && (result.length == 2));
+    var r = new MojoResult(result[0]);
+    if (!r.isOk) {
+      return null;
+    }
+
+    MojoSharedBuffer buf = new MojoSharedBuffer._();
+    buf.status = r;
+    buf.handle = new RawMojoHandle(result[1]);
+    buf.mapping = null;
+    return buf;
+  }
+
+  factory MojoSharedBuffer.duplicate(MojoSharedBuffer msb, [int flags = 0]) {
+    List result = _MojoSharedBufferNatives.Duplicate(msb.handle.h, flags);
+    if (result == null) {
+      return null;
+    }
+    assert((result is List) && (result.length == 2));
+    var r = new MojoResult(result[0]);
+    if(!r.isOk) {
+      return null;
+    }
+
+    MojoSharedBuffer dupe = new MojoSharedBuffer._();
+    dupe.status = r;
+    dupe.handle = new RawMojoHandle(result[1]);
+    dupe.mapping = msb.mapping;
+    return dupe;
+  }
+
+  MojoResult close() {
+    if (handle == null) {
+      status = MojoResult.INVALID_ARGUMENT;
+      return status;
+    }
+    MojoResult r = handle.close();
+    status = r;
+    mapping = null;
+    return status;
+  }
+
+  MojoResult map(int offset, int num_bytes, [int flags = 0]) {
+    if (handle == null) {
+      status = MojoResult.INVALID_ARGUMENT;
+      return status;
+    }
+    List result = _MojoSharedBufferNatives.Map(
+        handle.h, offset, num_bytes, flags);
+    if (result == null) {
+      status = MojoResult.INVALID_ARGUMENT;
+      return status;
+    }
+    assert((result is List) && (result.length == 2));
+    status = new MojoResult(result[0]);
+    mapping = result[1];
+    return status;
+  }
+
+  MojoResult unmap() {
+    int r = _MojoSharedBufferNatives.Unmap(mapping);
+    status = new MojoResult(r);
+    mapping = null;
+    return status;
+  }
+}
diff --git a/mojo/public/dart/src/data_pipe.dart b/mojo/public/dart/src/data_pipe.dart
new file mode 100644
index 0000000..665285d
--- /dev/null
+++ b/mojo/public/dart/src/data_pipe.dart
@@ -0,0 +1,191 @@
+// 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.
+
+part of core;
+
+
+class _MojoDataPipeNatives {
+  static List MojoCreateDataPipe(
+      int element_bytes, int capacity_bytes, int flags)
+      native "MojoDataPipe_Create";
+
+  static List MojoWriteData(int handle, ByteData data, int num_bytes, int flags)
+      native "MojoDataPipe_WriteData";
+
+  static List MojoBeginWriteData(int handle, int buffer_bytes, int flags)
+      native "MojoDataPipe_BeginWriteData";
+
+  static int MojoEndWriteData(int handle, int bytes_written)
+      native "MojoDataPipe_EndWriteData";
+
+  static List MojoReadData(int handle, ByteData data, int num_bytes, int flags)
+      native "MojoDataPipe_ReadData";
+
+  static List MojoBeginReadData(int handle, int buffer_bytes, int flags)
+      native "MojoDataPipe_BeginReadData";
+
+  static int MojoEndReadData(int handle, int bytes_read)
+      native "MojoDataPipe_EndReadData";
+}
+
+
+class MojoDataPipeProducer {
+  static const int FLAG_NONE = 0;
+  static const int FLAG_ALL_OR_NONE = 1 << 0;
+
+  RawMojoHandle handle;
+  MojoResult status;
+  final int element_bytes;
+
+  MojoDataPipeProducer(this.handle,
+                       this.status,
+                       this.element_bytes);
+
+  int write(ByteData data, [int num_bytes = -1, int flags = 0]) {
+    if (handle == null) {
+      status = MojoResult.INVALID_ARGUMENT;
+      return status;
+    }
+
+    int data_num_bytes = (num_bytes == -1) ? data.lengthInBytes : num_bytes;
+    List result = _MojoDataPipeNatives.MojoWriteData(
+        handle.h, data, data_num_bytes, flags);
+    if (result == null) {
+      status = MojoResult.INVALID_ARGUMENT;
+      return status;
+    }
+
+    assert((result is List) && (result.length == 2));
+    status = new MojoResult(result[0]);
+    return result[1];
+  }
+
+  ByteData beginWrite(int buffer_bytes, [int flags = 0]) {
+    if (handle == null) {
+      status = MojoResult.INVALID_ARGUMENT;
+      return null;
+    }
+
+    List result = _MojoDataPipeNatives.MojoBeginWriteData(
+        handle.h, buffer_bytes, flags);
+    if (result == null) {
+      status = MojoResult.INVALID_ARGUMENT;
+      return null;
+    }
+
+    assert((result is List) && (result.length == 2));
+    status = new MojoResult(result[0]);
+    return result[1];
+  }
+
+  MojoResult endWrite(int bytes_written) {
+    if (handle == null) {
+      status = MojoResult.INVALID_ARGUMENT;
+      return status;
+    }
+    int result = _MojoDataPipeNatives.MojoEndWriteData(handle.h, bytes_written);
+    status = new MojoResult(result);
+    return status;
+  }
+}
+
+
+class MojoDataPipeConsumer {
+  static const int FLAG_NONE = 0;
+  static const int FLAG_ALL_OR_NONE = 1 << 0;
+  static const int FLAG_MAY_DISCARD = 1 << 1;
+  static const int FLAG_QUERY = 1 << 2;
+
+  RawMojoHandle handle;
+  MojoResult status;
+  final int element_bytes;
+
+  MojoDataPipeConsumer(this.handle,
+                       this.status,
+                       this.element_bytes);
+
+  int read(ByteData data, [int num_bytes = -1, int flags = 0]) {
+    if (handle == null) {
+      status = MojoResult.INVALID_ARGUMENT;
+      return status;
+    }
+
+    int data_num_bytes = (num_bytes == -1) ? data.lengthInBytes : num_bytes;
+    List result = _MojoDataPipeNatives.MojoReadData(
+        handle.h, data, data_num_bytes, flags);
+    if (result == null) {
+      status = MojoResult.INVALID_ARGUMENT;
+      return status;
+    }
+    assert((result is List) && (result.length == 2));
+    status = new MojoResult(result[0]);
+    return result[1];
+  }
+
+  ByteData beginRead(int buffer_bytes, [int flags = 0]) {
+    if (handle == null) {
+      status = MojoResult.INVALID_ARGUMENT;
+      return null;
+    }
+
+    List result = _MojoDataPipeNatives.MojoBeginReadData(
+        handle.h, buffer_bytes, flags);
+    if (result == null) {
+      status = MojoResult.INVALID_ARGUMENT;
+      return null;
+    }
+
+    assert((result is List) && (result.length == 2));
+    status = new MojoResult(result[0]);
+    return result[1];
+  }
+
+  MojoResult endRead(int bytes_read) {
+    if (handle == null) {
+      status = MojoResult.INVALID_ARGUMENT;
+      return status;
+    }
+    int result = _MojoDataPipeNatives.MojoEndReadData(handle.h, bytes_read);
+    status = new MojoResult(result);
+    return status;
+  }
+}
+
+
+class MojoDataPipe {
+  static const int FLAG_NONE = 0;
+  static const int FLAG_MAY_DISCARD = 1 << 0;
+  static const int DEFAULT_ELEMENT_SIZE = 1;
+  static const int DEFAULT_CAPACITY = 0;
+
+  MojoDataPipeProducer producer;
+  MojoDataPipeConsumer consumer;
+  MojoResult status;
+
+  MojoDataPipe._internal() {
+    producer = null;
+    consumer = null;
+    status = MojoResult.OK;
+  }
+
+  factory MojoDataPipe([int element_bytes = DEFAULT_ELEMENT_SIZE,
+                        int capacity_bytes = DEFAULT_CAPACITY,
+                        int flags = FLAG_NONE]) {
+    List result = _MojoDataPipeNatives.MojoCreateDataPipe(
+        element_bytes, capacity_bytes, flags);
+    if (result == null) {
+      return null;
+    }
+    assert((result is List) && (result.length == 3));
+    RawMojoHandle producer_handle = new RawMojoHandle(result[1]);
+    RawMojoHandle consumer_handle = new RawMojoHandle(result[2]);
+    MojoDataPipe pipe = new MojoDataPipe._internal();
+    pipe.producer = new MojoDataPipeProducer(
+        producer_handle, new MojoResult(result[0]), element_bytes);
+    pipe.consumer = new MojoDataPipeConsumer(
+        consumer_handle, new MojoResult(result[0]), element_bytes);
+    pipe.status = new MojoResult(result[0]);
+    return pipe;
+  }
+}
diff --git a/mojo/public/dart/src/handle.dart b/mojo/public/dart/src/handle.dart
new file mode 100644
index 0000000..bf9d87b
--- /dev/null
+++ b/mojo/public/dart/src/handle.dart
@@ -0,0 +1,203 @@
+// 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.
+
+part of core;
+
+class _MojoHandleNatives {
+  static int close(int handle) native "MojoHandle_Close";
+  static int wait(int handle, int signals, int deadline)
+      native "MojoHandle_Wait";
+  static int waitMany(
+      List<int> handles, List<int> signals, int num_handles, int deadline)
+      native "MojoHandle_WaitMany";
+}
+
+
+class RawMojoHandle {
+  static const int INVALID = 0;
+  static const int DEADLINE_INDEFINITE = -1;
+
+  int h;
+
+  RawMojoHandle(this.h);
+
+  MojoResult close() {
+    int result = _MojoHandleNatives.close(h);
+    h = INVALID;
+    return new MojoResult(result);
+  }
+
+  MojoResult wait(int signals, int deadline) {
+    int result = _MojoHandleNatives.wait(h, signals, deadline);
+    return new MojoResult(result);
+  }
+
+  bool _ready(int signal) {
+    MojoResult res = wait(signal, 0);
+    switch (res) {
+      case MojoResult.OK:
+        return true;
+      case MojoResult.DEADLINE_EXCEEDED:
+      case MojoResult.CANCELLED:
+      case MojoResult.INVALID_ARGUMENT:
+      case MojoResult.FAILED_PRECONDITION:
+        return false;
+      default:
+        // Should be unreachable.
+        throw new Exception("Unreachable");
+    }
+  }
+
+  bool readyRead() => _ready(MojoHandleSignals.READABLE);
+  bool readyWrite() => _ready(MojoHandleSignals.WRITABLE);
+
+  static int waitMany(List<int> handles,
+                      List<int> signals,
+                      int deadline) {
+    if (handles.length != signals.length) {
+      return MojoResult.kInvalidArgument;
+    }
+    return _MojoHandleNatives.waitMany(
+        handles, signals, handles.length, deadline);
+  }
+
+  static bool isValid(RawMojoHandle h) => (h.h != INVALID);
+
+  String toString() => "$h";
+}
+
+
+class MojoHandle extends Stream<int> {
+  // The underlying Mojo handle.
+  RawMojoHandle _handle;
+
+  // Providing our own stream controller allows us to take custom actions when
+  // listeners pause/resume/etc. their StreamSubscription.
+  StreamController _controller;
+
+  // The send port that we give to the handle watcher to notify us of handle
+  // events.
+  SendPort _sendPort;
+
+  // The receive port on which we listen and receive events from the handle 
+  // watcher.
+  ReceivePort _receivePort;
+
+  // The signals on this handle that we're interested in.
+  int _signals;
+
+  // Whether the handle has been added to the handle watcher.
+  bool _eventHandlerAdded;
+
+  MojoHandle(this._handle) : 
+      _signals = MojoHandleSignals.READABLE,
+      _eventHandlerAdded = false,
+      _receivePort = new ReceivePort() {
+    _sendPort = _receivePort.sendPort;
+    _controller = new StreamController(sync: true,
+        onListen: _onSubscriptionStateChange,
+        onCancel: _onSubscriptionStateChange,
+        onPause: _onPauseStateChange,
+        onResume: _onPauseStateChange);
+    _controller.addStream(_receivePort);
+  }
+
+  void close() {
+    if (_eventHandlerAdded) {
+      MojoHandleWatcher.close(_handle);
+    } else {
+      // If we're not in the handle watcher, then close the handle manually.
+      _handle.close();
+    }
+    _receivePort.close();
+  }
+
+  // We wrap the callback provided by clients in listen() with some code to
+  // handle adding and removing the handle to/from the handle watcher. Because
+  // the handle watcher removes this handle whenever it receives an event,
+  // we have to re-add it when the callback is finished.
+  Function _onDataClosure(origOnData) {
+    return ((int event) {
+      // The handle watcher removes this handle from its set on an event.
+      _eventHandlerAdded = false;
+      origOnData(event);
+
+      // The callback could have closed the handle. If so, don't add it back to
+      // the MojoHandleWatcher.
+      if (RawMojoHandle.isValid(_handle)) {
+        assert(!_eventHandlerAdded);
+        var res = MojoHandleWatcher.add(_handle, _sendPort, _signals);
+        if (!res.isOk) {
+          throw new Exception("Failed to re-add handle: $_handle");
+        }
+        _eventHandlerAdded = true;
+      }
+    });
+  }
+
+  StreamSubscription<int> listen(
+      void onData(int event),
+      {Function onError, void onDone(), bool cancelOnError}) {
+
+    assert(!_eventHandlerAdded);
+    var res = MojoHandleWatcher.add(_handle, _sendPort, _signals);
+    if (!res.isOk) {
+      throw new Exception("MojoHandleWatcher add failed: $res");
+    }
+    _eventHandlerAdded = true;
+
+    return _controller.stream.listen(
+        _onDataClosure(onData),
+        onError: onError,
+        onDone: onDone,
+        cancelOnError: cancelOnError);
+  }
+
+  bool writeEnabled() => MojoHandleSignals.isWritable(_signals);
+
+  void toggleWriteEvents() {
+    _signals = MojoHandleSignals.toggleWrite(_signals);
+    if (_eventHandlerAdded) {
+      var res = MojoHandleWatcher.toggleWrite(_handle);
+      if (!res.isOk) {
+        throw new Exception("MojoHandleWatcher failed to toggle write: $res");
+      }
+    }
+  }
+
+  void enableWriteEvents() {
+    assert(!writeEnabled());
+    toggleWriteEvents();
+  }
+
+  void disableWriteEvents() {
+    assert(writeEnabled());
+    toggleWriteEvents();
+  }
+
+  void _onSubscriptionStateChange() {
+    if (!_controller.hasListener) {
+      close();
+    }
+  }
+
+  void _onPauseStateChange() {
+    if (_controller.isPaused) {
+      if (_eventHandlerAdded) {
+        MojoHandleWatcher.remove(_handle);
+        _eventHandlerAdded = false;
+      }
+    } else {
+      if (!_eventHandlerAdded) {
+        var res = MojoHandleWatcher.add(_handle, _sendPort, _signals);
+        if (!res.isOk) {
+          throw new Exception("MojoHandleWatcher add failed: $res");
+        }
+        _eventHandlerAdded = true;
+      }
+    }
+  }
+
+  String toString() => "$_handle";
+}
diff --git a/mojo/public/dart/src/handle_watcher.dart b/mojo/public/dart/src/handle_watcher.dart
new file mode 100644
index 0000000..47f3675
--- /dev/null
+++ b/mojo/public/dart/src/handle_watcher.dart
@@ -0,0 +1,296 @@
+// 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.
+
+part of core;
+
+class _MojoHandleWatcherNatives {
+  static int sendControlData(
+      int controlHandle, int mojoHandle, SendPort port, int data)
+      native "MojoHandleWatcher_SendControlData";
+  static List recvControlData(int controlHandle)
+      native "MojoHandleWatcher_RecvControlData";
+  static int setControlHandle(int controlHandle)
+      native "MojoHandleWatcher_SetControlHandle";
+  static int getControlHandle()
+      native "MojoHandleWatcher_GetControlHandle";
+}
+
+// The MojoHandleWatcher sends a stream of events to application isolates that
+// register Mojo handles with it. Application isolates make the following calls:
+//
+// Start() - Starts up the MojoHandleWatcher isolate. Should be called only once
+//           per VM process.
+//
+// Stop() - Causes the MojoHandleWatcher isolate to exit.
+//
+// add(handle, port, signals) - Instructs the MojoHandleWatcher isolate to add
+//     'handle' to the set of handles it watches, and to notify the calling
+//     isolate only for the events specified by 'signals' using the send port
+//     'port'
+//
+// remove(handle) - Instructs the MojoHandleWatcher isolate to remove 'handle'
+//     from the set of handles it watches. This allows the application isolate
+//     to, e.g., pause the stream of events.
+//
+// toggleWrite(handle) - Modifies the set of signals that an application isolate
+//     wishes to be notified about. Whether the application isolate should be
+//     be notified about a handle ready for writing is made the opposite.
+//
+// close(handle) - Notifies the HandleWatcherIsolate that a handle it is
+//     watching should be removed from its set and closed.
+class MojoHandleWatcher {
+  // Control commands.
+  static const int ADD = 0;
+  static const int REMOVE = 1;
+  static const int TOGGLE_WRITE = 2;
+  static const int CLOSE = 3;
+  static const int SHUTDOWN = 4;
+
+  static int _encodeCommand(int cmd, [int signals = 0]) =>
+      (cmd << 2) | (signals & MojoHandleSignals.READWRITE);
+  static int _decodeCommand(int cmd) => cmd >> 2;
+
+  // The Mojo handle over which control messages are sent.
+  int _controlHandle;
+
+  // Whether the handle watcher should shut down.
+  bool _shutdown;
+
+  // The list of handles being watched.
+  List<int> _handles;
+  int _handleCount;
+
+  // A port for each handle on which to send events back to the isolate that
+  // owns the handle.
+  List<SendPort> _ports;
+
+  // The signals that we care about for each handle.
+  List<int> _signals;
+
+  // A mapping from Mojo handles to their indices in _handles.
+  Map<int, int> _handleIndices;
+
+  // Since we are not storing wrapped handles, a dummy handle for when we need
+  // a RawMojoHandle.
+  RawMojoHandle _tempHandle;
+
+  MojoHandleWatcher(this._controlHandle) :
+      _shutdown = false,
+      _handles = new List<int>(),
+      _ports = new List<SendPort>(),
+      _signals = new List<int>(),
+      _handleIndices = new Map<int, int>(),
+      _handleCount = 1,
+      _tempHandle = new RawMojoHandle(RawMojoHandle.INVALID) {
+    // Setup control handle.
+    _handles.add(_controlHandle);
+    _ports.add(null);  // There is no port for the control handle.
+    _signals.add(MojoHandleSignals.READABLE);
+    _handleIndices[_controlHandle] = 0;
+  }
+
+  static void _handleWatcherIsolate(MojoHandleWatcher watcher) {
+    while (!watcher._shutdown) {
+      int res = RawMojoHandle.waitMany(watcher._handles,
+                                       watcher._signals,
+                                       RawMojoHandle.DEADLINE_INDEFINITE);
+      if (res == 0) {
+        watcher._handleControlMessage();
+      } else if (res > 0) {
+        int handle = watcher._handles[res];
+        // Route event.
+        watcher._routeEvent(res);
+        // Remove the handle from the list.
+        watcher._removeHandle(handle);
+      } else if (res == MojoResult.kFailedPrecondition) {
+        // None of the handles can ever be satisfied, including the control
+        // handle. This probably means we are going down. Clean up and
+        // shutdown.
+        watcher._pruneClosedHandles();
+        watcher._shutdown = true;
+      } else {
+        // Some handle was closed, but not by us.
+        // We have to go through the list and find it.
+        watcher._pruneClosedHandles();
+      }
+    }
+  }
+
+  void _routeEvent(int idx) {
+    int client_handle = _handles[idx];
+    int signals = _signals[idx];
+    SendPort port = _ports[idx];
+
+    _tempHandle.h = client_handle;
+    bool readyWrite =
+        MojoHandleSignals.isWritable(signals) && _tempHandle.readyWrite();
+    bool readyRead =
+        MojoHandleSignals.isReadable(signals) && _tempHandle.readyRead();
+    if (readyRead && readyWrite) {
+      port.send(MojoHandleSignals.READWRITE);
+    } else if (readyWrite) {
+      port.send(MojoHandleSignals.WRITABLE);
+    } else if (readyRead) {
+      port.send(MojoHandleSignals.READABLE);
+    }
+    _tempHandle.h = RawMojoHandle.INVALID;
+  }
+
+  void _handleControlMessage() {
+    List result = _MojoHandleWatcherNatives.recvControlData(_controlHandle);
+    // result[0] = mojo handle if any
+    // result[1] = SendPort if any
+    // result[2] = command << 2 | WRITABLE | READABLE
+
+    int signals = result[2] & MojoHandleSignals.READWRITE;
+    int command = _decodeCommand(result[2]);
+    switch (command) {
+      case ADD:
+        _addHandle(result[0], result[1], signals);
+        break;
+      case REMOVE:
+        _removeHandle(result[0]);
+        break;
+      case TOGGLE_WRITE:
+        _toggleWrite(result[0]);
+        break;
+      case CLOSE:
+        _close(result[0]);
+        break;
+      case SHUTDOWN:
+        _shutdown = true;
+        break;
+      default:
+        throw new Exception("Invalid Command: $command");
+        break;
+    }
+  }
+
+  void _addHandle(int mojoHandle, SendPort port, int signals) {
+    _handles.add(mojoHandle);
+    _ports.add(port);
+    _signals.add(signals & MojoHandleSignals.READWRITE);
+    _handleIndices[mojoHandle] = _handleCount;
+    _handleCount++;
+  }
+
+  void _removeHandle(int mojoHandle) {
+    int idx = _handleIndices[mojoHandle];
+    if (idx == null) {
+      throw new Exception("Remove on a non-existent handle: idx = $idx.");
+    }
+    if (idx == 0) {
+      throw new Exception("The control handle (idx = 0) cannot be removed.");
+    }
+    // We don't use List.removeAt so that we know how to fix-up _handleIndices.
+    if (idx == _handleCount - 1) {
+      int handle = _handles[idx];
+      _handleIndices[handle] = null;
+      _handles.removeLast();
+      _signals.removeLast();
+      _ports.removeLast();
+      _handleCount--;
+    } else {
+      int last = _handleCount - 1;
+      _handles[idx] = _handles[last];
+      _signals[idx] = _signals[last];
+      _ports[idx] = _ports[last];
+      _handles.removeLast();
+      _signals.removeLast();
+      _ports.removeLast();
+      _handleIndices[_handles[idx]] = idx;
+      _handleCount--;
+    }
+  }
+
+  void _close(int mojoHandle) {
+    int idx = _handleIndices[mojoHandle];
+    if (idx == null) {
+      throw new Exception("Close on a non-existent handle: idx = $idx.");
+    }
+    if (idx == 0) {
+      throw new Exception("The control handle (idx = 0) cannot be closed.");
+    }
+    _tempHandle.h = _handles[idx];
+    _tempHandle.close();
+    _tempHandle.h = RawMojoHandle.INVALID;
+    _removeHandle(mojoHandle);
+  }
+
+  void _toggleWrite(int mojoHandle) {
+    int idx = _handleIndices[mojoHandle];
+    if (idx == null) {
+      throw new Exception("Toggle write on a non-existent handle: idx = $idx.");
+    }
+    if (idx == 0) {
+      throw new Exception("The control handle (idx = 0) cannot be toggled.");
+    }
+    _signals[idx] = MojoHandleSignals.toggleWrite(_signals[idx]);
+  }
+
+  void _pruneClosedHandles() {
+    List<int> closed = new List();
+    for (var h in _handles) {
+      _tempHandle.h = h;
+      MojoResult res = _tempHandle.wait(MojoHandleSignals.READWRITE, 0);
+      if ((!res.isOk) && (!res.isDeadlineExceeded)) {
+        closed.add(h);
+      }
+      _tempHandle.h = RawMojoHandle.INVALID;
+    }
+    for (var h in closed) {
+      _close(h);
+    }
+  }
+
+  static MojoResult _sendControlData(RawMojoHandle mojoHandle,
+                                     SendPort port,
+                                     int data) {
+    int controlHandle = _MojoHandleWatcherNatives.getControlHandle();
+    if (controlHandle == RawMojoHandle.INVALID) {
+      throw new Exception("Found invalid control handle");
+    }
+    var result = _MojoHandleWatcherNatives.sendControlData(
+        controlHandle, mojoHandle.h, port, data);
+    return new MojoResult(result);
+  }
+
+  static Future<Isolate> Start() {
+    // 5. Return Future<bool> giving true on success.
+
+    // Make a control message pipe,
+    MojoMessagePipe pipe = new MojoMessagePipe();
+    int consumerHandle = pipe.endpoints[0].handle.h;
+    int producerHandle = pipe.endpoints[1].handle.h;
+
+    // Make a MojoHandleWatcher with one end.
+    MojoHandleWatcher watcher = new MojoHandleWatcher(consumerHandle);
+
+    // Call setControlHandle with the other end.
+    _MojoHandleWatcherNatives.setControlHandle(producerHandle);
+
+    // Spawn the handle watcher isolate with the MojoHandleWatcher,
+    return Isolate.spawn(_handleWatcherIsolate, watcher);
+  }
+
+  static void Stop() {
+    _sendControlData(RawMojoHandle.INVALID, null, _encodeCommand(SHUTDOWN));
+  }
+
+  static MojoResult close(RawMojoHandle mojoHandle) {
+    return _sendControlData(mojoHandle, null, _encodeCommand(CLOSE));
+  }
+
+  static MojoResult toggleWrite(RawMojoHandle mojoHandle) {
+    return _sendControlData(mojoHandle, null, _encodeCommand(TOGGLE_WRITE));
+  }
+
+  static MojoResult add(RawMojoHandle mojoHandle, SendPort port, int signals) {
+    return _sendControlData(mojoHandle, port, _encodeCommand(ADD, signals));
+  }
+
+  static MojoResult remove(RawMojoHandle mojoHandle) {
+    return _sendControlData(mojoHandle, null, _encodeCommand(REMOVE));
+  }
+}
diff --git a/mojo/public/dart/src/message_pipe.dart b/mojo/public/dart/src/message_pipe.dart
new file mode 100644
index 0000000..20fca27
--- /dev/null
+++ b/mojo/public/dart/src/message_pipe.dart
@@ -0,0 +1,155 @@
+// 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.
+
+part of core;
+
+
+class _MojoMessagePipeNatives {
+  static List MojoCreateMessagePipe(int flags)
+      native "MojoMessagePipe_Create";
+
+  static int MojoWriteMessage(
+      int handle, ByteData data, int numBytes, List<int> handles, int flags)
+      native "MojoMessagePipe_Write";
+
+  static List MojoReadMessage(
+      int handle, ByteData data, int numBytes, List<int> handles, int flags)
+      native "MojoMessagePipe_Read";
+}
+
+
+class MojoMessagePipeReadResult {
+  final MojoResult status;
+  final int bytesRead;
+  final int handlesRead;
+
+  MojoMessagePipeReadResult(this.status, this.bytesRead, this.handlesRead);
+  MojoMessagePipeReadResult.fromList(List<int> resultList)
+      : this(new MojoResult(resultList[0]), resultList[1], resultList[2]);
+}
+
+
+class MojoMessagePipeEndpoint {
+  static const int WRITE_FLAG_NONE = 0;
+  static const int READ_FLAG_NONE = 0;
+  static const int READ_FLAG_MAY_DISCARD = 0;
+
+  RawMojoHandle handle;
+  MojoResult status;
+
+  MojoMessagePipeEndpoint(this.handle);
+
+  MojoResult write(ByteData data,
+                   [int numBytes = -1,
+                    List<RawMojoHandle> handles = null,
+                    int flags = 0]) {
+    if (handle == null) {
+      status = MojoResult.INVALID_ARGUMENT;
+      return status;
+    }
+
+    // If numBytes has the default value, use the full length of the data.
+    int dataNumBytes = (numBytes == -1) ? data.lengthInBytes : numBytes;
+    if (dataNumBytes > data.lengthInBytes) {
+      status = MojoResult.INVALID_ARGUMENT;
+      return status;
+    }
+
+    // handles may be null, otherwise convert to ints.
+    List<int> mojoHandles =
+        (handles != null) ? handles.map((h) => h.h).toList() : null;
+
+    // Do the call.
+    int result = _MojoMessagePipeNatives.MojoWriteMessage(
+        handle.h, data, dataNumBytes, mojoHandles, flags);
+
+    status = new MojoResult(result);
+    return status;
+  }
+
+
+  MojoMessagePipeReadResult read(ByteData data,
+                                 [int numBytes = -1,
+                                  List<RawMojoHandle> handles = null,
+                                  int flags = 0]) {
+    if (handle == null) {
+      status = MojoResult.INVALID_ARGUMENT;
+      return null;
+    }
+
+    // If numBytes has the default value, use the full length of the data.
+    int dataNumBytes;
+    if (data == null) {
+      dataNumBytes = 0;
+    } else {
+      dataNumBytes = (numBytes == -1) ? data.lengthInBytes : numBytes;
+      if (dataNumBytes > data.lengthInBytes) {
+        status = MojoResult.INVALID_ARGUMENT;
+        return status;
+      }
+    }
+
+    // handles may be null, otherwise make an int list for the handles.
+    List<int> mojoHandles;
+    if (handles == null) {
+      mojoHandles = null;
+    } else {
+      mojoHandles = new List<int>(handles.length);
+    }
+
+    // Do the call.
+    List result = _MojoMessagePipeNatives.MojoReadMessage(
+        handle.h, data, dataNumBytes, mojoHandles, flags);
+
+    if (result == null) {
+      status = MojoResult.INVALID_ARGUMENT;
+      return null;
+    }
+
+    assert((result is List) && (result.length == 3));
+    var readResult = new MojoMessagePipeReadResult.fromList(result);
+
+    // Copy out the handles that were read.
+    if (handles != null) {
+      for (var i = 0; i < readResult.handlesRead; i++) {
+        handles[i].h = mojoHandles[i];
+      }
+    }
+
+    status = readResult.status;
+    return readResult;
+  }
+
+  MojoMessagePipeReadResult query() => read(null);
+}
+
+
+class MojoMessagePipe {
+  static const int FLAG_NONE = 0;
+
+  List<MojoMessagePipeEndpoint> endpoints;
+  MojoResult status;
+
+  MojoMessagePipe._() {
+    endpoints = null;
+    status = MojoResult.OK;
+  }
+
+  factory MojoMessagePipe([int flags = FLAG_NONE]) {
+    List result = _MojoMessagePipeNatives.MojoCreateMessagePipe(flags);
+    if (result == null) {
+      return null;
+    }
+    assert((result is List) && (result.length == 3));
+
+    RawMojoHandle end1 = new RawMojoHandle(result[1]);
+    RawMojoHandle end2 = new RawMojoHandle(result[2]);
+    MojoMessagePipe pipe = new MojoMessagePipe._();
+    pipe.endpoints = new List(2);
+    pipe.endpoints[0] = new MojoMessagePipeEndpoint(end1);
+    pipe.endpoints[1] = new MojoMessagePipeEndpoint(end2);
+    pipe.status = new MojoResult(result[0]);
+    return pipe;
+  }
+}
diff --git a/mojo/public/dart/src/mojo_dart_core.cc b/mojo/public/dart/src/mojo_dart_core.cc
new file mode 100644
index 0000000..12e5858
--- /dev/null
+++ b/mojo/public/dart/src/mojo_dart_core.cc
@@ -0,0 +1,742 @@
+// 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 <stdio.h>
+#include <string.h>
+
+#include "base/memory/scoped_ptr.h"
+#include "dart/runtime/include/dart_api.h"
+#include "mojo/public/c/system/core.h"
+#include "mojo/public/platform/native/system_thunks.h"
+
+
+static Dart_NativeFunction ResolveName(
+    Dart_Handle name, int argc, bool* auto_setup_scope);
+
+
+DART_EXPORT Dart_Handle mojo_dart_core_Init(Dart_Handle parent_library) {
+  if (Dart_IsError(parent_library)) {
+    return parent_library;
+  }
+
+  Dart_Handle result_code = Dart_SetNativeResolver(
+      parent_library, ResolveName, NULL);
+  if (Dart_IsError(result_code)) {
+    return result_code;
+  }
+
+  return Dart_Null();
+}
+
+
+static Dart_Handle HandleError(Dart_Handle handle) {
+  if (Dart_IsError(handle)) {
+    Dart_PropagateError(handle);
+  }
+  return handle;
+}
+
+
+static void SetNullReturn(Dart_NativeArguments arguments) {
+  Dart_SetReturnValue(arguments, Dart_Null());
+}
+
+
+static void SetInvalidArgumentReturn(Dart_NativeArguments arguments) {
+  Dart_SetIntegerReturnValue(
+      arguments, static_cast<int64_t>(MOJO_RESULT_INVALID_ARGUMENT));
+}
+
+
+#define CHECK_INTEGER_ARGUMENT(args, num, result, failure)                     \
+  {                                                                            \
+    Dart_Handle __status;                                                      \
+    __status = Dart_GetNativeIntegerArgument(args, num, result);               \
+    if (Dart_IsError(__status)) {                                              \
+      Set##failure##Return(arguments);                                         \
+      return;                                                                  \
+    }                                                                          \
+  }                                                                            \
+
+
+extern "C" {
+  extern size_t MojoSetSystemThunks(const MojoSystemThunks* system_thunks);
+}
+
+
+static void MojoSystemThunks_Set(Dart_NativeArguments arguments) {
+  int64_t thunks_addr = 0;
+  CHECK_INTEGER_ARGUMENT(arguments, 0, &thunks_addr, Null);
+
+  MojoSystemThunks* thunks = reinterpret_cast<MojoSystemThunks*>(thunks_addr);
+  MojoSetSystemThunks(thunks);
+
+  Dart_SetReturnValue(arguments, Dart_Null());
+}
+
+
+static void MojoHandle_Close(Dart_NativeArguments arguments) {
+  int64_t handle;
+  CHECK_INTEGER_ARGUMENT(arguments, 0, &handle, InvalidArgument);
+
+  MojoResult res = MojoClose(static_cast<MojoHandle>(handle));
+
+  Dart_SetIntegerReturnValue(arguments, static_cast<int64_t>(res));
+}
+
+
+static void MojoHandle_Wait(Dart_NativeArguments arguments) {
+  int64_t handle = 0;
+  int64_t signals = 0;
+  int64_t deadline = 0;
+  CHECK_INTEGER_ARGUMENT(arguments, 0, &handle, InvalidArgument);
+  CHECK_INTEGER_ARGUMENT(arguments, 1, &signals, InvalidArgument);
+  CHECK_INTEGER_ARGUMENT(arguments, 2, &deadline, InvalidArgument);
+
+  MojoResult r = MojoWait(static_cast<MojoHandle>(handle),
+                          static_cast<MojoHandleSignals>(signals),
+                          static_cast<MojoDeadline>(deadline));
+
+  Dart_SetIntegerReturnValue(arguments, static_cast<int64_t>(r));
+}
+
+
+static void MojoHandle_WaitMany(Dart_NativeArguments arguments) {
+  int64_t num_handles = 0;
+  int64_t deadline = 0;
+  Dart_Handle handles = Dart_GetNativeArgument(arguments, 0);
+  Dart_Handle signals = Dart_GetNativeArgument(arguments, 1);
+  CHECK_INTEGER_ARGUMENT(arguments, 2, &num_handles, InvalidArgument);
+  CHECK_INTEGER_ARGUMENT(arguments, 3, &deadline, InvalidArgument);
+
+  if (!Dart_IsList(handles) || !Dart_IsList(signals)) {
+    SetInvalidArgumentReturn(arguments);
+    return;
+  }
+
+  intptr_t handles_len = 0;
+  intptr_t signals_len = 0;
+  Dart_ListLength(handles, &handles_len);
+  Dart_ListLength(signals, &signals_len);
+  if ((handles_len != num_handles) || (signals_len != num_handles)) {
+    SetInvalidArgumentReturn(arguments);
+    return;
+  }
+
+  scoped_ptr<MojoHandle[]> mojo_handles(new MojoHandle[num_handles]);
+  scoped_ptr<MojoHandleSignals[]> mojo_signals(
+      new MojoHandleSignals[num_handles]);
+
+  for (int i = 0; i < num_handles; i++) {
+    Dart_Handle dart_handle = Dart_ListGetAt(handles, i);
+    Dart_Handle dart_signal = Dart_ListGetAt(signals, i);
+    if (!Dart_IsInteger(dart_handle) || !Dart_IsInteger(dart_signal)) {
+      SetInvalidArgumentReturn(arguments);
+      return;
+    }
+    int64_t mojo_handle = 0;
+    int64_t mojo_signal = 0;
+    Dart_IntegerToInt64(dart_handle, &mojo_handle);
+    Dart_IntegerToInt64(dart_signal, &mojo_signal);
+    mojo_handles[i] = static_cast<MojoHandle>(mojo_handle);
+    mojo_signals[i] = static_cast<MojoHandleSignals>(mojo_signal);
+  }
+
+  MojoResult res = MojoWaitMany(mojo_handles.get(), mojo_signals.get(),
+                                static_cast<uint32_t>(num_handles),
+                                static_cast<MojoDeadline>(deadline));
+  Dart_SetIntegerReturnValue(arguments, static_cast<int64_t>(res));
+}
+
+
+static void MojoSharedBuffer_Create(Dart_NativeArguments arguments) {
+  int64_t num_bytes = 0;
+  int64_t flags = 0;
+  CHECK_INTEGER_ARGUMENT(arguments, 0, &num_bytes, Null);
+  CHECK_INTEGER_ARGUMENT(arguments, 1, &flags, Null);
+
+  MojoCreateSharedBufferOptions options;
+  options.struct_size = sizeof(MojoCreateSharedBufferOptions);
+  options.flags = static_cast<MojoCreateSharedBufferOptionsFlags>(flags);
+
+  MojoHandle out = MOJO_HANDLE_INVALID;;
+  MojoResult res = MojoCreateSharedBuffer(
+      &options, static_cast<int32_t>(num_bytes), &out);
+
+  Dart_Handle list = Dart_NewList(2);
+  Dart_ListSetAt(list, 0, Dart_NewInteger(res));
+  Dart_ListSetAt(list, 1, Dart_NewInteger(out));
+  Dart_SetReturnValue(arguments, list);
+}
+
+
+static void MojoSharedBuffer_Duplicate(Dart_NativeArguments arguments) {
+  int64_t handle = 0;
+  int64_t flags = 0;
+  CHECK_INTEGER_ARGUMENT(arguments, 0, &handle, Null);
+  CHECK_INTEGER_ARGUMENT(arguments, 1, &flags, Null);
+
+  MojoDuplicateBufferHandleOptions options;
+  options.struct_size = sizeof(MojoDuplicateBufferHandleOptions);
+  options.flags = static_cast<MojoDuplicateBufferHandleOptionsFlags>(flags);
+
+  MojoHandle out = MOJO_HANDLE_INVALID;;
+  MojoResult res = MojoDuplicateBufferHandle(
+      static_cast<MojoHandle>(handle), &options, &out);
+
+  Dart_Handle list = Dart_NewList(2);
+  Dart_ListSetAt(list, 0, Dart_NewInteger(res));
+  Dart_ListSetAt(list, 1, Dart_NewInteger(out));
+  Dart_SetReturnValue(arguments, list);
+}
+
+
+static void MojoSharedBuffer_Map(Dart_NativeArguments arguments) {
+  int64_t handle = 0;
+  int64_t offset = 0;
+  int64_t num_bytes = 0;
+  int64_t flags = 0;
+  CHECK_INTEGER_ARGUMENT(arguments, 0, &handle, Null);
+  CHECK_INTEGER_ARGUMENT(arguments, 1, &offset, Null);
+  CHECK_INTEGER_ARGUMENT(arguments, 2, &num_bytes, Null);
+  CHECK_INTEGER_ARGUMENT(arguments, 3, &flags, Null);
+
+  void* out;
+  MojoResult res = MojoMapBuffer(static_cast<MojoHandle>(handle),
+                                 offset,
+                                 num_bytes,
+                                 &out,
+                                 static_cast<MojoMapBufferFlags>(flags));
+
+  Dart_Handle list = Dart_NewList(2);
+  Dart_Handle typed_data;
+  if (res == MOJO_RESULT_OK) {
+    typed_data = Dart_NewExternalTypedData(
+        Dart_TypedData_kByteData, out, num_bytes);
+  } else {
+    typed_data = Dart_Null();
+  }
+  Dart_ListSetAt(list, 0, Dart_NewInteger(res));
+  Dart_ListSetAt(list, 1, typed_data);
+  Dart_SetReturnValue(arguments, list);
+}
+
+
+static void MojoSharedBuffer_Unmap(Dart_NativeArguments arguments) {
+  Dart_Handle typed_data = Dart_GetNativeArgument(arguments, 0);
+  if (!Dart_IsTypedData(typed_data)) {
+    SetInvalidArgumentReturn(arguments);
+    return;
+  }
+
+  Dart_TypedData_Type typ;
+  void *data;
+  intptr_t len;
+  Dart_TypedDataAcquireData(typed_data, &typ, &data, &len);
+  MojoResult res = MojoUnmapBuffer(data);
+  Dart_TypedDataReleaseData(typed_data);
+
+  Dart_SetIntegerReturnValue(arguments, static_cast<int64_t>(res));
+}
+
+
+static void MojoDataPipe_Create(Dart_NativeArguments arguments) {
+  int64_t element_bytes = 0;
+  int64_t capacity_bytes = 0;
+  int64_t flags = 0;
+  CHECK_INTEGER_ARGUMENT(arguments, 0, &element_bytes, Null);
+  CHECK_INTEGER_ARGUMENT(arguments, 1, &capacity_bytes, Null);
+  CHECK_INTEGER_ARGUMENT(arguments, 2, &flags, Null);
+
+  MojoCreateDataPipeOptions options;
+  options.struct_size = sizeof(MojoCreateDataPipeOptions);
+  options.flags = static_cast<MojoCreateDataPipeOptionsFlags>(flags);
+  options.element_num_bytes = static_cast<uint32_t>(element_bytes);
+  options.capacity_num_bytes = static_cast<uint32_t>(capacity_bytes);
+
+  MojoHandle producer = MOJO_HANDLE_INVALID;
+  MojoHandle consumer = MOJO_HANDLE_INVALID;
+  MojoResult res = MojoCreateDataPipe(&options, &producer, &consumer);
+
+  Dart_Handle list = Dart_NewList(3);
+  Dart_ListSetAt(list, 0, Dart_NewInteger(res));
+  Dart_ListSetAt(list, 1, Dart_NewInteger(producer));
+  Dart_ListSetAt(list, 2, Dart_NewInteger(consumer));
+  Dart_SetReturnValue(arguments, list);
+}
+
+
+static void MojoDataPipe_WriteData(Dart_NativeArguments arguments) {
+  int64_t handle = 0;
+  CHECK_INTEGER_ARGUMENT(arguments, 0, &handle, Null);
+
+  Dart_Handle typed_data = Dart_GetNativeArgument(arguments, 1);
+  if (!Dart_IsTypedData(typed_data)) {
+    SetNullReturn(arguments);
+    return;
+  }
+
+  int64_t num_bytes = 0;
+  CHECK_INTEGER_ARGUMENT(arguments, 2, &num_bytes, Null);
+
+  int64_t flags = 0;
+  CHECK_INTEGER_ARGUMENT(arguments, 3, &flags, Null);
+
+  Dart_TypedData_Type type;
+  void* data;
+  intptr_t data_length;
+  Dart_TypedDataAcquireData(typed_data, &type, &data, &data_length);
+  uint32_t length = static_cast<uint32_t>(num_bytes);
+  MojoResult res = MojoWriteData(
+      static_cast<MojoHandle>(handle),
+      data,
+      &length,
+      static_cast<MojoWriteDataFlags>(flags));
+  Dart_TypedDataReleaseData(typed_data);
+
+  Dart_Handle list = Dart_NewList(2);
+  Dart_ListSetAt(list, 0, Dart_NewInteger(res));
+  Dart_ListSetAt(list, 1, Dart_NewInteger(length));
+  Dart_SetReturnValue(arguments, list);
+}
+
+
+static void MojoDataPipe_BeginWriteData(Dart_NativeArguments arguments) {
+  int64_t handle = 0;
+  int64_t buffer_bytes = 0;
+  int64_t flags = 0;
+  CHECK_INTEGER_ARGUMENT(arguments, 0, &handle, Null);
+  CHECK_INTEGER_ARGUMENT(arguments, 1, &buffer_bytes, Null);
+  CHECK_INTEGER_ARGUMENT(arguments, 2, &flags, Null);
+
+  void* buffer;
+  uint32_t size = static_cast<uint32_t>(buffer_bytes);
+  MojoResult res = MojoBeginWriteData(
+      static_cast<MojoHandle>(handle),
+      &buffer,
+      &size,
+      static_cast<MojoWriteDataFlags>(flags));
+
+  Dart_Handle list = Dart_NewList(2);
+  Dart_Handle typed_data;
+  if (res == MOJO_RESULT_OK) {
+    typed_data = Dart_NewExternalTypedData(
+        Dart_TypedData_kByteData, buffer, size);
+  } else {
+    typed_data = Dart_Null();
+  }
+  Dart_ListSetAt(list, 0, Dart_NewInteger(res));
+  Dart_ListSetAt(list, 1, typed_data);
+  Dart_SetReturnValue(arguments, list);
+}
+
+
+static void MojoDataPipe_EndWriteData(Dart_NativeArguments arguments) {
+  int64_t handle = 0;
+  int64_t num_bytes_written = 0;
+  CHECK_INTEGER_ARGUMENT(arguments, 0, &handle, InvalidArgument);
+  CHECK_INTEGER_ARGUMENT(arguments, 1, &num_bytes_written, InvalidArgument);
+
+  MojoResult res = MojoEndWriteData(
+      static_cast<MojoHandle>(handle),
+      static_cast<uint32_t>(num_bytes_written));
+
+  Dart_SetIntegerReturnValue(arguments, static_cast<int64_t>(res));
+}
+
+
+static void MojoDataPipe_ReadData(Dart_NativeArguments arguments) {
+  int64_t handle = 0;
+  CHECK_INTEGER_ARGUMENT(arguments, 0, &handle, Null);
+
+  Dart_Handle typed_data = Dart_GetNativeArgument(arguments, 1);
+  if (!Dart_IsTypedData(typed_data) && !Dart_IsNull(typed_data)) {
+    SetNullReturn(arguments);
+    return;
+  }
+
+  int64_t num_bytes = 0;
+  CHECK_INTEGER_ARGUMENT(arguments, 2, &num_bytes, Null);
+
+  int64_t flags = 0;
+  CHECK_INTEGER_ARGUMENT(arguments, 3, &flags, Null);
+
+  Dart_TypedData_Type typ;
+  void* data = NULL;
+  intptr_t bdlen = 0;
+  if (!Dart_IsNull(typed_data)) {
+    Dart_TypedDataAcquireData(typed_data, &typ, &data, &bdlen);
+  }
+  uint32_t len = static_cast<uint32_t>(num_bytes);
+  MojoResult res = MojoReadData(
+      static_cast<MojoHandle>(handle),
+      data,
+      &len,
+      static_cast<MojoReadDataFlags>(flags));
+  if (!Dart_IsNull(typed_data)) {
+    Dart_TypedDataReleaseData(typed_data);
+  }
+
+  Dart_Handle list = Dart_NewList(2);
+  Dart_ListSetAt(list, 0, Dart_NewInteger(res));
+  Dart_ListSetAt(list, 1, Dart_NewInteger(len));
+  Dart_SetReturnValue(arguments, list);
+}
+
+
+static void MojoDataPipe_BeginReadData(Dart_NativeArguments arguments) {
+  int64_t handle = 0;
+  int64_t buffer_bytes = 0;
+  int64_t flags = 0;
+  CHECK_INTEGER_ARGUMENT(arguments, 0, &handle, Null);
+  CHECK_INTEGER_ARGUMENT(arguments, 1, &buffer_bytes, Null);
+  CHECK_INTEGER_ARGUMENT(arguments, 2, &flags, Null);
+
+  void* buffer;
+  uint32_t size = static_cast<uint32_t>(buffer_bytes);
+  MojoResult res = MojoBeginReadData(
+      static_cast<MojoHandle>(handle),
+      const_cast<const void**>(&buffer),
+      &size,
+      static_cast<MojoWriteDataFlags>(flags));
+
+  Dart_Handle list = Dart_NewList(2);
+  Dart_Handle typed_data;
+  if (res == MOJO_RESULT_OK) {
+    typed_data = Dart_NewExternalTypedData(
+        Dart_TypedData_kByteData, buffer, size);
+  } else {
+    typed_data = Dart_Null();
+  }
+  Dart_ListSetAt(list, 0, Dart_NewInteger(res));
+  Dart_ListSetAt(list, 1, typed_data);
+  Dart_SetReturnValue(arguments, list);
+}
+
+
+static void MojoDataPipe_EndReadData(Dart_NativeArguments arguments) {
+  int64_t handle = 0;
+  int64_t num_bytes_read = 0;
+  CHECK_INTEGER_ARGUMENT(arguments, 0, &handle, InvalidArgument);
+  CHECK_INTEGER_ARGUMENT(arguments, 1, &num_bytes_read, InvalidArgument);
+
+  MojoResult res = MojoEndReadData(
+      static_cast<MojoHandle>(handle),
+      static_cast<uint32_t>(num_bytes_read));
+
+  Dart_SetIntegerReturnValue(arguments, static_cast<int64_t>(res));
+}
+
+
+static void MojoMessagePipe_Create(Dart_NativeArguments arguments) {
+  int64_t flags = 0;
+  CHECK_INTEGER_ARGUMENT(arguments, 0, &flags, Null);
+
+  MojoCreateMessagePipeOptions options;
+  options.struct_size = sizeof(MojoCreateMessagePipeOptions);
+  options.flags = static_cast<MojoCreateMessagePipeOptionsFlags>(flags);
+
+  MojoHandle end1 = MOJO_HANDLE_INVALID;
+  MojoHandle end2 = MOJO_HANDLE_INVALID;
+  MojoResult res = MojoCreateMessagePipe(&options, &end1, &end2);
+
+  Dart_Handle list = Dart_NewList(3);
+  Dart_ListSetAt(list, 0, Dart_NewInteger(res));
+  Dart_ListSetAt(list, 1, Dart_NewInteger(end1));
+  Dart_ListSetAt(list, 2, Dart_NewInteger(end2));
+  Dart_SetReturnValue(arguments, list);
+}
+
+
+static void MojoMessagePipe_Write(Dart_NativeArguments arguments) {
+  int64_t handle = 0;
+  CHECK_INTEGER_ARGUMENT(arguments, 0, &handle, InvalidArgument);
+
+  Dart_Handle typed_data = Dart_GetNativeArgument(arguments, 1);
+  if (!Dart_IsTypedData(typed_data) && !Dart_IsNull(typed_data)) {
+    SetInvalidArgumentReturn(arguments);
+    return;
+  }
+
+  int64_t num_bytes = 0;
+  CHECK_INTEGER_ARGUMENT(arguments, 2, &num_bytes, InvalidArgument);
+
+  Dart_Handle handles = Dart_GetNativeArgument(arguments, 3);
+  if (!Dart_IsList(handles) && !Dart_IsNull(handles)) {
+    SetInvalidArgumentReturn(arguments);
+    return;
+  }
+
+  int64_t flags = 0;
+  CHECK_INTEGER_ARGUMENT(arguments, 4, &flags, InvalidArgument);
+
+  // Grab the data if there is any.
+  Dart_TypedData_Type typ;
+  void* bytes = NULL;
+  intptr_t bdlen = 0;
+  if (!Dart_IsNull(typed_data)) {
+    Dart_TypedDataAcquireData(typed_data, &typ, &bytes, &bdlen);
+  }
+
+  // Grab the handles if there are any.
+  scoped_ptr<MojoHandle[]> mojo_handles;
+  intptr_t handles_len = 0;
+  if (!Dart_IsNull(handles)) {
+    Dart_ListLength(handles, &handles_len);
+    mojo_handles.reset(new MojoHandle[handles_len]);
+    for (int i = 0; i < handles_len; i++) {
+      Dart_Handle dart_handle = Dart_ListGetAt(handles, i);
+      if (!Dart_IsInteger(dart_handle)) {
+        SetInvalidArgumentReturn(arguments);
+        return;
+      }
+      int64_t mojo_handle = 0;
+      Dart_IntegerToInt64(dart_handle, &mojo_handle);
+      mojo_handles[i] = static_cast<MojoHandle>(mojo_handle);
+    }
+  }
+
+  MojoResult res = MojoWriteMessage(
+      static_cast<MojoHandle>(handle),
+      const_cast<const void*>(bytes),
+      static_cast<uint32_t>(num_bytes),
+      mojo_handles.get(),
+      static_cast<uint32_t>(handles_len),
+      static_cast<MojoWriteMessageFlags>(flags));
+
+  // Release the data.
+  if (!Dart_IsNull(typed_data)) {
+    Dart_TypedDataReleaseData(typed_data);
+  }
+
+  Dart_SetIntegerReturnValue(arguments, static_cast<int64_t>(res));
+}
+
+
+static void MojoMessagePipe_Read(Dart_NativeArguments arguments) {
+  int64_t handle = 0;
+  CHECK_INTEGER_ARGUMENT(arguments, 0, &handle, Null);
+
+  Dart_Handle typed_data = Dart_GetNativeArgument(arguments, 1);
+  if (!Dart_IsTypedData(typed_data) && !Dart_IsNull(typed_data)) {
+    SetNullReturn(arguments);
+    return;
+  }
+
+  int64_t num_bytes = 0;
+  CHECK_INTEGER_ARGUMENT(arguments, 2, &num_bytes, Null);
+
+  Dart_Handle handles = Dart_GetNativeArgument(arguments, 3);
+  if (!Dart_IsList(handles) && !Dart_IsNull(handles)) {
+    SetNullReturn(arguments);
+    return;
+  }
+
+  int64_t flags = 0;
+  CHECK_INTEGER_ARGUMENT(arguments, 4, &flags, Null);
+
+  // Grab the data if there is any.
+  Dart_TypedData_Type typ;
+  void* bytes = NULL;
+  intptr_t byte_data_len = 0;
+  if (!Dart_IsNull(typed_data)) {
+    Dart_TypedDataAcquireData(typed_data, &typ, &bytes, &byte_data_len);
+  }
+  uint32_t blen = static_cast<uint32_t>(num_bytes);
+
+  // Grab the handles if there are any.
+  scoped_ptr<MojoHandle[]> mojo_handles;
+  intptr_t handles_len = 0;
+  if (!Dart_IsNull(handles)) {
+    Dart_ListLength(handles, &handles_len);
+    mojo_handles.reset(new MojoHandle[handles_len]);
+  }
+  uint32_t hlen = static_cast<uint32_t>(handles_len);
+
+  MojoResult res = MojoReadMessage(
+      static_cast<MojoHandle>(handle),
+      bytes,
+      &blen,
+      mojo_handles.get(),
+      &hlen,
+      static_cast<MojoReadMessageFlags>(flags));
+
+  // Release the data.
+  if (!Dart_IsNull(typed_data)) {
+    Dart_TypedDataReleaseData(typed_data);
+  }
+
+  if (!Dart_IsNull(handles)) {
+    for (int i = 0; i < handles_len; i++) {
+      Dart_ListSetAt(handles, i, Dart_NewInteger(mojo_handles[i]));
+    }
+  }
+
+  Dart_Handle list = Dart_NewList(3);
+  Dart_ListSetAt(list, 0, Dart_NewInteger(res));
+  Dart_ListSetAt(list, 1, Dart_NewInteger(blen));
+  Dart_ListSetAt(list, 2, Dart_NewInteger(hlen));
+  Dart_SetReturnValue(arguments, list);
+}
+
+
+struct ControlData {
+  int64_t handle;
+  Dart_Port port;
+  int64_t data;
+};
+
+
+static void MojoHandleWatcher_SendControlData(Dart_NativeArguments arguments) {
+  int64_t control_handle = 0;
+  int64_t client_handle = 0;
+  CHECK_INTEGER_ARGUMENT(arguments, 0, &control_handle, InvalidArgument);
+  CHECK_INTEGER_ARGUMENT(arguments, 1, &client_handle, InvalidArgument);
+
+  Dart_Handle send_port_handle = Dart_GetNativeArgument(arguments, 2);
+  Dart_Port send_port_id = 0;
+  if (!Dart_IsNull(send_port_handle)) {
+    Dart_Handle result = Dart_SendPortGetId(send_port_handle, &send_port_id);
+    if (Dart_IsError(result)) {
+      SetInvalidArgumentReturn(arguments);
+      return;
+    }
+  }
+
+  int64_t data = 0;
+  CHECK_INTEGER_ARGUMENT(arguments, 3, &data, InvalidArgument);
+
+  ControlData cd;
+  cd.handle = client_handle;
+  cd.port = send_port_id;
+  cd.data = data;
+  const void* bytes = reinterpret_cast<const void*>(&cd);
+  MojoResult res = MojoWriteMessage(
+      control_handle, bytes,  sizeof(cd), NULL, 0, 0);
+
+  Dart_SetIntegerReturnValue(arguments, static_cast<int64_t>(res));
+}
+
+
+static void MojoHandleWatcher_RecvControlData(Dart_NativeArguments arguments) {
+  int64_t control_handle = 0;
+  CHECK_INTEGER_ARGUMENT(arguments, 0, &control_handle, Null);
+
+  ControlData cd;
+  void* bytes = reinterpret_cast<void*>(&cd);
+  uint32_t num_bytes = sizeof(cd);
+  uint32_t num_handles = 0;
+  MojoResult res = MojoReadMessage(
+      control_handle, bytes, &num_bytes, NULL, &num_handles, 0);
+  if (res != MOJO_RESULT_OK) {
+    SetNullReturn(arguments);
+    return;
+  }
+
+  Dart_Handle list = Dart_NewList(3);
+  Dart_ListSetAt(list, 0, Dart_NewInteger(cd.handle));
+  Dart_ListSetAt(list, 1, Dart_NewSendPort(cd.port));
+  Dart_ListSetAt(list, 2, Dart_NewInteger(cd.data));
+  Dart_SetReturnValue(arguments, list);
+}
+
+
+static int64_t mojo_control_handle = MOJO_HANDLE_INVALID;
+static void MojoHandleWatcher_SetControlHandle(Dart_NativeArguments arguments) {
+  int64_t control_handle;
+  CHECK_INTEGER_ARGUMENT(arguments, 0, &control_handle, InvalidArgument);
+
+  if (mojo_control_handle == MOJO_HANDLE_INVALID) {
+    mojo_control_handle = control_handle;
+  }
+
+  Dart_SetIntegerReturnValue(arguments, static_cast<int64_t>(MOJO_RESULT_OK));
+}
+
+
+static void MojoHandleWatcher_GetControlHandle(Dart_NativeArguments arguments) {
+  Dart_SetIntegerReturnValue(arguments, mojo_control_handle);
+}
+
+
+#define SCOPE_FUNCTIONS(V)                                                     \
+  V(MojoSharedBuffer_Create)                                                   \
+  V(MojoSharedBuffer_Duplicate)                                                \
+  V(MojoSharedBuffer_Map)                                                      \
+  V(MojoSharedBuffer_Unmap)                                                    \
+  V(MojoDataPipe_Create)                                                       \
+  V(MojoDataPipe_WriteData)                                                    \
+  V(MojoDataPipe_BeginWriteData)                                               \
+  V(MojoDataPipe_ReadData)                                                     \
+  V(MojoDataPipe_BeginReadData)                                                \
+  V(MojoDataPipe_EndReadData)                                                  \
+  V(MojoMessagePipe_Create)                                                    \
+  V(MojoMessagePipe_Write)                                                     \
+  V(MojoMessagePipe_Read)                                                      \
+  V(MojoHandle_WaitMany)                                                       \
+  V(MojoHandleWatcher_SendControlData)                                         \
+  V(MojoHandleWatcher_RecvControlData)                                         \
+
+#define NOSCOPE_FUNCTIONS(V)                                                   \
+  V(MojoSystemThunks_Set)                                                      \
+  V(MojoHandle_Close)                                                          \
+  V(MojoHandle_Wait)                                                           \
+  V(MojoDataPipe_EndWriteData)                                                 \
+  V(MojoHandleWatcher_SetControlHandle)                                        \
+  V(MojoHandleWatcher_GetControlHandle)                                        \
+
+#define FUNCTION_STRING_MAP(name) {#name, name},
+
+struct FunctionLookup {
+  const char* name;
+  Dart_NativeFunction function;
+};
+
+FunctionLookup function_list[] = {
+  SCOPE_FUNCTIONS(FUNCTION_STRING_MAP)
+  {NULL, NULL}
+};
+
+FunctionLookup no_scope_function_list[] = {
+  NOSCOPE_FUNCTIONS(FUNCTION_STRING_MAP)
+  {NULL, NULL}
+};
+
+#undef FUNCTION_STRING_MAP
+
+
+Dart_NativeFunction ResolveName(Dart_Handle name,
+                                int argc,
+                                bool* auto_setup_scope) {
+  if (!Dart_IsString(name)) {
+    return NULL;
+  }
+  Dart_NativeFunction result = NULL;
+  if (auto_setup_scope == NULL) {
+    return NULL;
+  }
+
+  Dart_EnterScope();
+  const char* cname;
+  HandleError(Dart_StringToCString(name, &cname));
+
+  for (int i=0; function_list[i].name != NULL; ++i) {
+    if (strcmp(function_list[i].name, cname) == 0) {
+      *auto_setup_scope = true;
+      Dart_ExitScope();
+      return function_list[i].function;
+    }
+  }
+
+  for (int i=0; no_scope_function_list[i].name != NULL; ++i) {
+    if (strcmp(no_scope_function_list[i].name, cname) == 0) {
+      *auto_setup_scope = false;
+      result = no_scope_function_list[i].function;
+      break;
+    }
+  }
+
+  Dart_ExitScope();
+  return result;
+}
diff --git a/mojo/public/dart/src/types.dart b/mojo/public/dart/src/types.dart
new file mode 100644
index 0000000..658e477
--- /dev/null
+++ b/mojo/public/dart/src/types.dart
@@ -0,0 +1,116 @@
+// 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.
+
+
+part of core;
+
+
+class MojoResult {
+  static const int kOk = 0;
+  static const int kCancelled = -1;
+  static const int kUnknown = -2;
+  static const int kInvalidArgument = -3;
+  static const int kDeadlineExceeded = -4;
+  static const int kNotFound = -5;
+  static const int kAlreadyExists = -6;
+  static const int kPermissionDenied = -7;
+  static const int kResourceExhausted = -8;
+  static const int kFailedPrecondition = -9;
+  static const int kAborted = -10;
+  static const int kOutOfRange = -11;
+  static const int kUnimplemented = -12;
+  static const int kInternal = -13;
+  static const int kUnavailable = -14;
+  static const int kDataLoss = -15;
+  static const int kBusy = -16;
+  static const int kShouldWait = -17;
+
+  static const OK = const MojoResult._(kOk);
+  static const CANCELLED = const MojoResult._(kCancelled);
+  static const UNKNOWN = const MojoResult._(kUnknown);
+  static const INVALID_ARGUMENT = const MojoResult._(kInvalidArgument);
+  static const DEADLINE_EXCEEDED = const MojoResult._(kDeadlineExceeded);
+  static const NOT_FOUND = const MojoResult._(kNotFound);
+  static const ALREADY_EXISTS = const MojoResult._(kAlreadyExists);
+  static const PERMISSION_DENIED = const MojoResult._(kPermissionDenied);
+  static const RESOURCE_EXHAUSTED = const MojoResult._(kResourceExhausted);
+  static const FAILED_PRECONDITION = const MojoResult._(kFailedPrecondition);
+  static const ABORTED = const MojoResult._(kAborted);
+  static const OUT_OF_RANGE = const MojoResult._(kOutOfRange);
+  static const UNIMPLEMENTED = const MojoResult._(kUnimplemented);
+  static const INTERNAL = const MojoResult._(kInternal);
+  static const UNAVAILABLE = const MojoResult._(kUnavailable);
+  static const DATA_LOSS = const MojoResult._(kDataLoss);
+  static const BUSY = const MojoResult._(kBusy);
+  static const SHOULD_WAIT = const MojoResult._(kShouldWait);
+
+  final int value;
+
+  const MojoResult._(this.value);
+
+  factory MojoResult(int value) {
+    switch (value) {
+      case kOk: return OK;
+      case kCancelled: return CANCELLED;
+      case kUnknown: return UNKNOWN;
+      case kInvalidArgument: return INVALID_ARGUMENT;
+      case kDeadlineExceeded: return DEADLINE_EXCEEDED;
+      case kNotFound: return NOT_FOUND;
+      case kAlreadyExists: return ALREADY_EXISTS;
+      case kPermissionDenied: return PERMISSION_DENIED;
+      case kResourceExhausted: return RESOURCE_EXHAUSTED;
+      case kFailedPrecondition: return FAILED_PRECONDITION;
+      case kAborted: return ABORTED;
+      case kOutOfRange: return OUT_OF_RANGE;
+      case kUnimplemented: return UNIMPLEMENTED;
+      case kInternal: return INTERNAL;
+      case kUnavailable: return UNAVAILABLE;
+      case kDataLoss: return DATA_LOSS;
+      case kBusy: return BUSY;
+      case kShouldWait: return SHOULD_WAIT;
+      default: return null;
+    }
+  }
+
+  bool get isOk => (this == OK);
+  bool get isCancelled => (this == CANCELLED);
+  bool get isUnknown => (this == UNKNOWN);
+  bool get isInvalidArgument => (this == INVALID_ARGUMENT);
+  bool get isDeadlineExceeded => (this == DEADLINE_EXCEEDED);
+  bool get isNotFound => (this == NOT_FOUND);
+  bool get isAlreadExists => (this == ALREADY_EXISTS);
+  bool get isPermissionDenied => (this == PERMISSION_DENIED);
+  bool get isResourceExhausted => (this == RESOURCE_EXHAUSTED);
+  bool get isFailedPrecondition => (this == FAILED_PRECONDITION);
+  bool get isAborted => (this == ABORTED);
+  bool get isOutOfRange => (this == OUT_OF_RANGE);
+  bool get isUnimplemented => (this == UNIMPLEMENTED);
+  bool get isInternal => (this == INTERNAL);
+  bool get isUnavailable => (this == UNAVAILABLE);
+  bool get isDataLoss => (this == DATA_LOSS);
+  bool get isBusy => (this == BUSY);
+  bool get isShouldWait => (this == SHOULD_WAIT);
+}
+
+
+class MojoHandleSignals {
+  static const int NONE = 0;
+  static const int READABLE = 1 << 0;
+  static const int WRITABLE = 1 << 1;
+  static const int READWRITE = READABLE | WRITABLE;
+
+  static bool isReadable(int mask) => (mask & READABLE) == READABLE;
+  static bool isWritable(int mask) => (mask & WRITABLE) == WRITABLE;
+  static bool isReadWrite(int mask) => (mask & READWRITE) == READWRITE;
+  static int toggleWrite(int mask) =>
+    isWritable(mask) ? (mask & ~WRITABLE) : (mask | WRITABLE);
+}
+
+
+class MojoHandleSignalsState {
+  const MojoHandleSignalsState(this.satisfied_signals,
+                               this.satisfiable_signals);
+  final int satisfied_signals;
+  final int satisfiable_signals;
+}
diff --git a/mojo/public/go/system/impl/mojo_types.go b/mojo/public/go/system/impl/mojo_types.go
index 9156a45..01d518e 100644
--- a/mojo/public/go/system/impl/mojo_types.go
+++ b/mojo/public/go/system/impl/mojo_types.go
@@ -66,6 +66,7 @@
 	MOJO_READ_DATA_FLAG_ALL_OR_NONE                     = 1 << 0
 	MOJO_READ_DATA_FLAG_DISCARD                         = 1 << 1
 	MOJO_READ_DATA_FLAG_QUERY                           = 1 << 2
+	MOJO_READ_DATA_FLAG_PEEK                            = 1 << 3
 	MOJO_WRITE_DATA_FLAG_NONE        MojoWriteDataFlags = 0
 	MOJO_WRITE_DATA_FLAG_ALL_OR_NONE MojoWriteDataFlags = 1 << 0
 
diff --git a/mojo/public/java/bindings/src/org/chromium/mojo/bindings/Decoder.java b/mojo/public/java/bindings/src/org/chromium/mojo/bindings/Decoder.java
index 80ed9d1..b95b6dd 100644
--- a/mojo/public/java/bindings/src/org/chromium/mojo/bindings/Decoder.java
+++ b/mojo/public/java/bindings/src/org/chromium/mojo/bindings/Decoder.java
@@ -108,7 +108,7 @@
 
     private Decoder(Message message, Validator validator, int baseOffset) {
         mMessage = message;
-        mMessage.getData().order(ByteOrder.nativeOrder());
+        mMessage.getData().order(ByteOrder.LITTLE_ENDIAN);
         mBaseOffset = baseOffset;
         mValidator = validator;
     }
@@ -615,8 +615,8 @@
         }
         if (expectedLength != BindingsHelper.UNSPECIFIED_ARRAY_LENGTH
                 && dataHeader.numFields != expectedLength) {
-            throw new DeserializationException("Incorrect array length. Expected: " +
-                    expectedLength + ", but got: " + dataHeader.numFields + ".");
+            throw new DeserializationException("Incorrect array length. Expected: "
+                    + expectedLength + ", but got: " + dataHeader.numFields + ".");
         }
         return dataHeader;
     }
@@ -631,8 +631,8 @@
         }
         if (expectedLength != BindingsHelper.UNSPECIFIED_ARRAY_LENGTH
                 && dataHeader.numFields != expectedLength) {
-            throw new DeserializationException("Incorrect array length. Expected: " +
-                    expectedLength + ", but got: " + dataHeader.numFields + ".");
+            throw new DeserializationException("Incorrect array length. Expected: "
+                    + expectedLength + ", but got: " + dataHeader.numFields + ".");
         }
         return dataHeader;
     }
diff --git a/mojo/public/java/bindings/src/org/chromium/mojo/bindings/Encoder.java b/mojo/public/java/bindings/src/org/chromium/mojo/bindings/Encoder.java
index ef04f6d..75cddc9 100644
--- a/mojo/public/java/bindings/src/org/chromium/mojo/bindings/Encoder.java
+++ b/mojo/public/java/bindings/src/org/chromium/mojo/bindings/Encoder.java
@@ -59,7 +59,7 @@
             this.core = core;
             byteBuffer = ByteBuffer.allocateDirect(
                     bufferSize > 0 ? bufferSize : INITIAL_BUFFER_SIZE);
-            byteBuffer.order(ByteOrder.nativeOrder());
+            byteBuffer.order(ByteOrder.LITTLE_ENDIAN);
             dataEnd = 0;
         }
 
@@ -226,8 +226,8 @@
             encodeNullPointer(offset, nullable);
             return;
         }
-        final int arrayNullability = nullable ?
-                BindingsHelper.ARRAY_NULLABLE : BindingsHelper.NOTHING_NULLABLE;
+        final int arrayNullability = nullable
+                ? BindingsHelper.ARRAY_NULLABLE : BindingsHelper.NOTHING_NULLABLE;
         encode(v.getBytes(Charset.forName("utf8")), offset, arrayNullability,
                 BindingsHelper.UNSPECIFIED_ARRAY_LENGTH);
     }
@@ -303,8 +303,8 @@
             encodeNullPointer(offset, BindingsHelper.isArrayNullable(arrayNullability));
             return;
         }
-        if (expectedLength != BindingsHelper.UNSPECIFIED_ARRAY_LENGTH &&
-                expectedLength != v.length) {
+        if (expectedLength != BindingsHelper.UNSPECIFIED_ARRAY_LENGTH
+                && expectedLength != v.length) {
             throw new SerializationException("Trying to encode a fixed array of incorrect length.");
         }
         byte[] bytes = new byte[(v.length + 7) / BindingsHelper.ALIGNMENT];
@@ -327,8 +327,8 @@
             encodeNullPointer(offset, BindingsHelper.isArrayNullable(arrayNullability));
             return;
         }
-        if (expectedLength != BindingsHelper.UNSPECIFIED_ARRAY_LENGTH &&
-                expectedLength != v.length) {
+        if (expectedLength != BindingsHelper.UNSPECIFIED_ARRAY_LENGTH
+                && expectedLength != v.length) {
             throw new SerializationException("Trying to encode a fixed array of incorrect length.");
         }
         encodeByteArray(v, v.length, offset);
@@ -473,8 +473,8 @@
 
     private Encoder encoderForArray(
             int elementSizeInByte, int length, int offset, int expectedLength) {
-        if (expectedLength != BindingsHelper.UNSPECIFIED_ARRAY_LENGTH &&
-                expectedLength != length) {
+        if (expectedLength != BindingsHelper.UNSPECIFIED_ARRAY_LENGTH
+                && expectedLength != length) {
             throw new SerializationException("Trying to encode a fixed array of incorrect length.");
         }
         return encoderForArrayByTotalSize(length * elementSizeInByte, length, offset);
diff --git a/mojo/public/java/bindings/src/org/chromium/mojo/bindings/ServiceMessage.java b/mojo/public/java/bindings/src/org/chromium/mojo/bindings/ServiceMessage.java
index ac62bf6..313dc6a 100644
--- a/mojo/public/java/bindings/src/org/chromium/mojo/bindings/ServiceMessage.java
+++ b/mojo/public/java/bindings/src/org/chromium/mojo/bindings/ServiceMessage.java
@@ -57,7 +57,7 @@
         if (mPayload == null) {
             ByteBuffer truncatedBuffer =
                     ((ByteBuffer) getData().position(getHeader().getSize())).slice();
-            truncatedBuffer.order(ByteOrder.nativeOrder());
+            truncatedBuffer.order(ByteOrder.LITTLE_ENDIAN);
             mPayload = new Message(truncatedBuffer, getHandles());
         }
         return mPayload;
diff --git a/mojo/public/java/system/src/org/chromium/mojo/system/DataPipe.java b/mojo/public/java/system/src/org/chromium/mojo/system/DataPipe.java
index 4cd74e1..a5b77ae 100644
--- a/mojo/public/java/system/src/org/chromium/mojo/system/DataPipe.java
+++ b/mojo/public/java/system/src/org/chromium/mojo/system/DataPipe.java
@@ -161,6 +161,7 @@
         private static final int FLAG_NONE = 0;
         private static final int FLAG_ALL_OR_NONE = 1 << 0;
         private static final int FLAG_QUERY = 1 << 2;
+        private static final int FLAG_PEEK = 1 << 3;
 
         /**
          * Immutable flag with not bit set.
@@ -189,7 +190,7 @@
 
         /**
          * Change the query bit of this flag. If set query the number of elements available to read.
-         * Mutually exclusive with |dicard| and |allOrNone| is ignored if this flag is set.
+         * Mutually exclusive with |discard| and |allOrNone| is ignored if this flag is set.
          *
          * @param query the new value of the query bit.
          * @return this.
@@ -199,6 +200,18 @@
         }
 
         /**
+         * Change the peek bit of this flag. If set, read the requested number of elements, and
+         * leave those elements in the pipe. A later read will return the same data.
+         * Mutually exclusive with |discard| and |query|.
+         *
+         * @param peek the new value of the peek bit.
+         * @return this.
+         */
+        public ReadFlags peek(boolean peek) {
+            return setFlag(FLAG_PEEK, peek);
+        }
+
+        /**
          * @return a flag with no bit set.
          */
         public static ReadFlags none() {
diff --git a/mojo/public/js/core.js b/mojo/public/js/core.js
index 8727833..9dcb20f 100644
--- a/mojo/public/js/core.js
+++ b/mojo/public/js/core.js
@@ -111,6 +111,7 @@
 var READ_DATA_FLAG_ALL_OR_NONE;
 var READ_DATA_FLAG_DISCARD;
 var READ_DATA_FLAG_QUERY;
+var READ_DATA_FLAG_PEEK;
 
 /**
  * Closes the given |handle|. See MojoClose for more info.
diff --git a/mojo/public/js/core_unittests.js b/mojo/public/js/core_unittests.js
index 34cd4c0..eaeaa4f 100644
--- a/mojo/public/js/core_unittests.js
+++ b/mojo/public/js/core_unittests.js
@@ -15,7 +15,6 @@
   runWithDataPipe(testReadAndWriteDataPipe);
   runWithDataPipeWithOptions(testNop);
   runWithDataPipeWithOptions(testReadAndWriteDataPipe);
-  testHandleToString();
   gc.collectGarbage();  // should not crash
   this.result = "PASS";
 
@@ -105,6 +104,16 @@
     expect(write.result).toBe(core.RESULT_OK);
     expect(write.numBytes).toBe(42);
 
+    var peeked = core.readData(
+         pipe.consumerHandle,
+         core.READ_DATA_FLAG_PEEK | core.READ_DATA_FLAG_ALL_OR_NONE);
+    expect(peeked.result).toBe(core.RESULT_OK);
+    expect(peeked.buffer.byteLength).toBe(42);
+
+    var peeked_memory = new Uint8Array(peeked.buffer);
+    for (var i = 0; i < peeked_memory.length; ++i)
+      expect(peeked_memory[i]).toBe((i * i) & 0xFF);
+
     var read = core.readData(
       pipe.consumerHandle, core.READ_DATA_FLAG_ALL_OR_NONE);
 
@@ -116,18 +125,4 @@
       expect(memory[i]).toBe((i * i) & 0xFF);
   }
 
-  function testHandleToString() {
-    var pipe = core.createDataPipe();
-    expect(pipe.consumerHandle.toString).toBeDefined();
-
-    var openHandleRE = /^\[mojo\:\:Handle \d+\]$/ // e.g. "[mojo::Handle 123]"
-    var openHandleString = pipe.consumerHandle.toString();
-    expect(openHandleString.match(openHandleRE)[0]).toEqual(openHandleString);
-
-    expect(core.close(pipe.producerHandle)).toBe(core.RESULT_OK);
-    expect(core.close(pipe.consumerHandle)).toBe(core.RESULT_OK);
-
-    expect(pipe.consumerHandle.toString()).toEqual("[mojo::Handle null]");
-  }
-
 });
diff --git a/mojo/public/js/threading.js b/mojo/public/js/threading.js
new file mode 100644
index 0000000..cfe5037
--- /dev/null
+++ b/mojo/public/js/threading.js
@@ -0,0 +1,21 @@
+// 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.
+
+// Module "mojo/public/js/threading"
+//
+// Note: This file is for documentation purposes only. The code here is not
+// actually executed. The real module is implemented natively in Mojo.
+//
+// This module provides a way for a Mojo application implemented in JS
+// to exit by quitting the current message loop. This module is not
+// intended to be used by Mojo JS application started by the JS
+// content handler.
+
+while (1);
+
+/**
+ * Quits the current message loop, esssentially:
+ * base::MessageLoop::current()->QuitNow();
+*/
+function quit() { [native code] }
diff --git a/mojo/public/mojo_application.gni b/mojo/public/mojo_application.gni
new file mode 100644
index 0000000..e7d4c8b
--- /dev/null
+++ b/mojo/public/mojo_application.gni
@@ -0,0 +1,127 @@
+# 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/mojo.gni")
+
+# Generate a binary mojo application.The parameters of this template are those
+# of a shared library.
+template("mojo_native_application") {
+  if (defined(invoker.output_name)) {
+    output = invoker.output_name + ".mojo"
+    library_target_name = invoker.output_name + "_library"
+  } else {
+    output = target_name + ".mojo"
+    library_target_name = target_name + "_library"
+  }
+
+  if (is_linux || is_android) {
+    library_name = "lib${library_target_name}.so"
+  } else if (is_win) {
+    library_name = "${library_target_name}.dll"
+  } else if (is_mac) {
+    library_name = "${library_target_name}.so"
+  } else {
+    assert(false, "Platform not supported.")
+  }
+
+  final_target_name = target_name
+
+  shared_library(library_target_name) {
+    if (defined(invoker.cflags)) {
+      cflags = invoker.cflags
+    }
+    if (defined(invoker.cflags_c)) {
+      cflags_c = invoker.cflags_c
+    }
+    if (defined(invoker.cflags_cc)) {
+      cflags_cc = invoker.cflags_cc
+    }
+    if (defined(invoker.cflags_objc)) {
+      cflags_objc = invoker.cflags_objc
+    }
+    if (defined(invoker.cflags_objcc)) {
+      cflags_objcc = invoker.cflags_objcc
+    }
+    if (defined(invoker.defines)) {
+      defines = invoker.defines
+    }
+    if (defined(invoker.include_dirs)) {
+      include_dirs = invoker.include_dirs
+    }
+    if (defined(invoker.ldflags)) {
+      ldflags = invoker.ldflags
+    }
+    if (defined(invoker.lib_dirs)) {
+      lib_dirs = invoker.lib_dirs
+    }
+    if (defined(invoker.libs)) {
+      libs = invoker.libs
+    }
+    # Copy the prebuilt mojo_shell if using it.
+    if (defined(invoker.datadeps)) {
+      datadeps = invoker.datadeps
+      if (use_prebuilt_mojo_shell) {
+        datadeps += [ "//mojo/public/tools:copy_mojo_shell" ]
+      }
+    } else {
+      if (use_prebuilt_mojo_shell) {
+        datadeps = [ "//mojo/public/tools:copy_mojo_shell" ]
+      }
+    }
+    if (defined(invoker.deps)) {
+      deps = invoker.deps
+    }
+    if (defined(invoker.forward_dependent_configs_from)) {
+      forward_dependent_configs_from = invoker.forward_dependent_configs_from
+    }
+    if (defined(invoker.public_deps)) {
+      public_deps = invoker.public_deps
+    }
+    if (defined(invoker.all_dependent_configs)) {
+      all_dependent_configs = invoker.all_dependent_configs
+    }
+    if (defined(invoker.public_configs)) {
+      public_configs = invoker.public_configs
+    }
+    if (defined(invoker.check_includes)) {
+      check_includes = invoker.check_includes
+    }
+    if (defined(invoker.configs)) {
+      configs = invoker.configs
+    }
+    if (defined(invoker.data)) {
+      data = invoker.data
+    }
+    if (defined(invoker.inputs)) {
+      inputs = invoker.inputs
+    }
+    if (defined(invoker.public)) {
+      public = invoker.public
+    }
+    if (defined(invoker.sources)) {
+      sources = invoker.sources
+    }
+    if (defined(invoker.testonly)) {
+      testonly = invoker.testonly
+    }
+
+    visibility = [
+      ":${final_target_name}",
+    ]
+  }
+
+  copy(final_target_name) {
+    if (defined(invoker.testonly)) {
+      testonly = invoker.testonly
+    }
+    if (defined(invoker.visibility)) {
+      visibility = invoker.visibility
+    }
+    deps = [
+      ":${library_target_name}",
+    ]
+    sources = [ "${root_out_dir}/${library_name}" ]
+    outputs = [ "${root_out_dir}/${output}" ]
+  }
+}
diff --git a/mojo/public/mojo_public.gyp b/mojo/public/mojo_public.gyp
index 46f22f7..f19e263 100644
--- a/mojo/public/mojo_public.gyp
+++ b/mojo/public/mojo_public.gyp
@@ -70,6 +70,7 @@
       ],
       'sources': [
         'cpp/bindings/array.h',
+        'cpp/bindings/binding.h',
         'cpp/bindings/callback.h',
         'cpp/bindings/error_handler.h',
         'cpp/bindings/interface_impl.h',
@@ -79,6 +80,7 @@
         'cpp/bindings/message_filter.h',
         'cpp/bindings/no_interface.h',
         'cpp/bindings/string.h',
+        'cpp/bindings/strong_binding.h',
         'cpp/bindings/type_converter.h',
         'cpp/bindings/lib/array_internal.h',
         'cpp/bindings/lib/array_internal.cc',
@@ -96,7 +98,6 @@
         'cpp/bindings/lib/filter_chain.h',
         'cpp/bindings/lib/fixed_buffer.cc',
         'cpp/bindings/lib/fixed_buffer.h',
-        'cpp/bindings/lib/interface_impl_internal.h',
         'cpp/bindings/lib/interface_ptr_internal.h',
         'cpp/bindings/lib/map_data_internal.h',
         'cpp/bindings/lib/map_internal.h',
@@ -123,7 +124,7 @@
       ],
     },
     {
-      # GN version: //mojo/public/js/bindings
+      # GN version: //mojo/public/js
       'target_name': 'mojo_js_bindings',
       'type': 'static_library',
       'include_dirs': [
@@ -188,16 +189,23 @@
       ],
     },
     {
+      'target_name': 'mojo_application_bindings_mojom',
+      'type': 'none',
+      'variables': {
+        'mojom_files': [
+          'interfaces/application/application.mojom',
+          'interfaces/application/service_provider.mojom',
+          'interfaces/application/shell.mojom',
+        ],
+      },
+      'includes': [ 'tools/bindings/mojom_bindings_generator_explicit.gypi' ],
+    },
+    {
       # GN version: //mojo/public/interfaces/application:application
       'target_name': 'mojo_application_bindings',
       'type': 'static_library',
-      'sources': [
-        'interfaces/application/application.mojom',
-        'interfaces/application/service_provider.mojom',
-        'interfaces/application/shell.mojom',
-      ],
-      'includes': [ 'tools/bindings/mojom_bindings_generator.gypi' ],
       'dependencies': [
+        'mojo_application_bindings_mojom',
         'mojo_cpp_bindings',
       ],
       'export_dependent_settings': [
@@ -229,9 +237,11 @@
       ],
       'dependencies': [
         'mojo_application_bindings',
+        'mojo_application_bindings_mojom',
       ],
       'export_dependent_settings': [
         'mojo_application_bindings',
+        'mojo_application_bindings_mojom',
       ],
     },
     {
@@ -313,28 +323,35 @@
       ],
     },
     {
+      'target_name': 'mojo_public_test_interfaces_mojom',
+      'type': 'none',
+      'variables': {
+        'mojom_files': [
+          'interfaces/bindings/tests/math_calculator.mojom',
+          'interfaces/bindings/tests/no_module.mojom',
+          'interfaces/bindings/tests/rect.mojom',
+          'interfaces/bindings/tests/regression_tests.mojom',
+          'interfaces/bindings/tests/sample_factory.mojom',
+          'interfaces/bindings/tests/sample_import.mojom',
+          'interfaces/bindings/tests/sample_import2.mojom',
+          'interfaces/bindings/tests/sample_interfaces.mojom',
+          'interfaces/bindings/tests/sample_service.mojom',
+          'interfaces/bindings/tests/serialization_test_structs.mojom',
+          'interfaces/bindings/tests/test_structs.mojom',
+          'interfaces/bindings/tests/validation_test_interfaces.mojom',
+        ],
+      },
+      'includes': [ 'tools/bindings/mojom_bindings_generator_explicit.gypi' ],
+    },
+    {
       # GN version: //mojo/public/interfaces/bindings/tests:test_interfaces
       'target_name': 'mojo_public_test_interfaces',
       'type': 'static_library',
-      'sources': [
-        'interfaces/bindings/tests/math_calculator.mojom',
-        'interfaces/bindings/tests/no_module.mojom',
-        'interfaces/bindings/tests/rect.mojom',
-        'interfaces/bindings/tests/regression_tests.mojom',
-        'interfaces/bindings/tests/sample_factory.mojom',
-        'interfaces/bindings/tests/sample_import.mojom',
-        'interfaces/bindings/tests/sample_import2.mojom',
-        'interfaces/bindings/tests/sample_interfaces.mojom',
-        'interfaces/bindings/tests/sample_service.mojom',
-        'interfaces/bindings/tests/serialization_test_structs.mojom',
-        'interfaces/bindings/tests/test_structs.mojom',
-        'interfaces/bindings/tests/validation_test_interfaces.mojom',
-      ],
-      'includes': [ 'tools/bindings/mojom_bindings_generator.gypi' ],
       'export_dependent_settings': [
         'mojo_cpp_bindings',
       ],
       'dependencies': [
+        'mojo_public_test_interfaces_mojom',
         'mojo_cpp_bindings',
       ],
     },
diff --git a/mojo/public/python/mojo/bindings/descriptor.py b/mojo/public/python/mojo/bindings/descriptor.py
index f566d47..f190d2b 100644
--- a/mojo/public/python/mojo/bindings/descriptor.py
+++ b/mojo/public/python/mojo/bindings/descriptor.py
@@ -41,7 +41,7 @@
   def __init__(self, typecode):
     Type.__init__(self)
     self.typecode = typecode
-    self.byte_size = struct.calcsize('=%s' % self.GetTypeCode())
+    self.byte_size = struct.calcsize('<%s' % self.GetTypeCode())
 
   def GetTypeCode(self):
     """
diff --git a/mojo/public/python/mojo/bindings/messaging.py b/mojo/public/python/mojo/bindings/messaging.py
index f9061fb..bba3c01 100644
--- a/mojo/public/python/mojo/bindings/messaging.py
+++ b/mojo/public/python/mojo/bindings/messaging.py
@@ -31,9 +31,9 @@
   """The header of a mojo message."""
 
   _SIMPLE_MESSAGE_NUM_FIELDS = 2
-  _SIMPLE_MESSAGE_STRUCT = struct.Struct("=IIII")
+  _SIMPLE_MESSAGE_STRUCT = struct.Struct("<IIII")
 
-  _REQUEST_ID_STRUCT = struct.Struct("=Q")
+  _REQUEST_ID_STRUCT = struct.Struct("<Q")
   _REQUEST_ID_OFFSET = _SIMPLE_MESSAGE_STRUCT.size
 
   _MESSAGE_WITH_REQUEST_ID_NUM_FIELDS = 3
diff --git a/mojo/public/python/mojo/bindings/serialization.py b/mojo/public/python/mojo/bindings/serialization.py
index 9a4b6a9..2c0478f 100644
--- a/mojo/public/python/mojo/bindings/serialization.py
+++ b/mojo/public/python/mojo/bindings/serialization.py
@@ -8,7 +8,7 @@
 
 
 # Format of a header for a struct or an array.
-HEADER_STRUCT = struct.Struct("=II")
+HEADER_STRUCT = struct.Struct("<II")
 
 
 class SerializationException(Exception):
@@ -110,7 +110,7 @@
 
 def _GetStruct(groups):
   index = 0
-  codes = [ '=' ]
+  codes = [ '<' ]
   for group in groups:
     code = group.GetTypeCode()
     size = group.GetByteSize()
diff --git a/mojo/public/python/mojo/c_core.pxd b/mojo/public/python/mojo/c_core.pxd
index 80b8487..1526dfe 100644
--- a/mojo/public/python/mojo/c_core.pxd
+++ b/mojo/public/python/mojo/c_core.pxd
@@ -126,6 +126,7 @@
   const MojoReadDataFlags MOJO_READ_DATA_FLAG_ALL_OR_NONE
   const MojoReadDataFlags MOJO_READ_DATA_FLAG_DISCARD
   const MojoReadDataFlags MOJO_READ_DATA_FLAG_QUERY
+  const MojoReadDataFlags MOJO_READ_DATA_FLAG_PEEK
 
   MojoResult MojoCreateDataPipe(
       const MojoCreateDataPipeOptions* options,
diff --git a/mojo/public/python/mojo/system.pyx b/mojo/public/python/mojo/system.pyx
index 8285261..4507d4d 100644
--- a/mojo/public/python/mojo/system.pyx
+++ b/mojo/public/python/mojo/system.pyx
@@ -62,6 +62,7 @@
 READ_DATA_FLAG_ALL_OR_NONE = c_core.MOJO_READ_DATA_FLAG_ALL_OR_NONE
 READ_DATA_FLAG_DISCARD = c_core.MOJO_READ_DATA_FLAG_DISCARD
 READ_DATA_FLAG_QUERY = c_core.MOJO_READ_DATA_FLAG_QUERY
+READ_DATA_FLAG_PEEK = c_core.MOJO_READ_DATA_FLAG_PEEK
 MAP_BUFFER_FLAG_NONE = c_core.MOJO_MAP_BUFFER_FLAG_NONE
 
 def GetTimeTicksNow():
diff --git a/mojo/public/tools/bindings/mojom_bindings_generator.gypi b/mojo/public/tools/bindings/mojom_bindings_generator.gypi
index 02c2813..e8843bb 100644
--- a/mojo/public/tools/bindings/mojom_bindings_generator.gypi
+++ b/mojo/public/tools/bindings/mojom_bindings_generator.gypi
@@ -3,76 +3,23 @@
 # found in the LICENSE file.
 
 {
+  'includes': [
+    'mojom_bindings_generator_variables.gypi',
+  ],
   'rules': [
     {
       'rule_name': '<(_target_name)_mojom_bindings_generator',
       'extension': 'mojom',
       'variables': {
         'mojom_base_output_dir':
-             '<!(python <(DEPTH)/build/inverse_depth.py <(DEPTH))',
-        'mojom_bindings_generator':
-            '<(DEPTH)/mojo/public/tools/bindings/mojom_bindings_generator.py',
+            '<!(python <(DEPTH)/build/inverse_depth.py <(DEPTH))',
         'java_out_dir': '<(PRODUCT_DIR)/java_mojo/<(_target_name)/src',
         'mojom_import_args%': [
          '-I<(DEPTH)'
         ],
       },
       'inputs': [
-        '<(mojom_bindings_generator)',
-        '<(DEPTH)/mojo/public/tools/bindings/generators/cpp_templates/enum_declaration.tmpl',
-        '<(DEPTH)/mojo/public/tools/bindings/generators/cpp_templates/interface_declaration.tmpl',
-        '<(DEPTH)/mojo/public/tools/bindings/generators/cpp_templates/interface_definition.tmpl',
-        '<(DEPTH)/mojo/public/tools/bindings/generators/cpp_templates/interface_macros.tmpl',
-        '<(DEPTH)/mojo/public/tools/bindings/generators/cpp_templates/interface_proxy_declaration.tmpl',
-        '<(DEPTH)/mojo/public/tools/bindings/generators/cpp_templates/interface_request_validator_declaration.tmpl',
-        '<(DEPTH)/mojo/public/tools/bindings/generators/cpp_templates/interface_response_validator_declaration.tmpl',
-        '<(DEPTH)/mojo/public/tools/bindings/generators/cpp_templates/interface_stub_declaration.tmpl',
-        '<(DEPTH)/mojo/public/tools/bindings/generators/cpp_templates/module.cc.tmpl',
-        '<(DEPTH)/mojo/public/tools/bindings/generators/cpp_templates/module.h.tmpl',
-        '<(DEPTH)/mojo/public/tools/bindings/generators/cpp_templates/module-internal.h.tmpl',
-        '<(DEPTH)/mojo/public/tools/bindings/generators/cpp_templates/params_definition.tmpl',
-        '<(DEPTH)/mojo/public/tools/bindings/generators/cpp_templates/struct_declaration.tmpl',
-        '<(DEPTH)/mojo/public/tools/bindings/generators/cpp_templates/struct_definition.tmpl',
-        '<(DEPTH)/mojo/public/tools/bindings/generators/cpp_templates/struct_macros.tmpl',
-        '<(DEPTH)/mojo/public/tools/bindings/generators/cpp_templates/struct_serialization_declaration.tmpl',
-        '<(DEPTH)/mojo/public/tools/bindings/generators/cpp_templates/struct_serialization_definition.tmpl',
-        '<(DEPTH)/mojo/public/tools/bindings/generators/cpp_templates/wrapper_class_declaration.tmpl',
-        '<(DEPTH)/mojo/public/tools/bindings/generators/cpp_templates/wrapper_class_definition.tmpl',
-        '<(DEPTH)/mojo/public/tools/bindings/generators/java_templates/constant_definition.tmpl',
-        '<(DEPTH)/mojo/public/tools/bindings/generators/java_templates/constants.java.tmpl',
-        '<(DEPTH)/mojo/public/tools/bindings/generators/java_templates/enum_definition.tmpl',
-        '<(DEPTH)/mojo/public/tools/bindings/generators/java_templates/enum.java.tmpl',
-        '<(DEPTH)/mojo/public/tools/bindings/generators/java_templates/header.java.tmpl',
-        '<(DEPTH)/mojo/public/tools/bindings/generators/java_templates/interface_definition.tmpl',
-        '<(DEPTH)/mojo/public/tools/bindings/generators/java_templates/interface.java.tmpl',
-        '<(DEPTH)/mojo/public/tools/bindings/generators/java_templates/interface_internal.java.tmpl',
-        '<(DEPTH)/mojo/public/tools/bindings/generators/java_templates/struct_definition.tmpl',
-        '<(DEPTH)/mojo/public/tools/bindings/generators/java_templates/struct.java.tmpl',
-        '<(DEPTH)/mojo/public/tools/bindings/generators/js_templates/enum_definition.tmpl',
-        '<(DEPTH)/mojo/public/tools/bindings/generators/js_templates/interface_definition.tmpl',
-        '<(DEPTH)/mojo/public/tools/bindings/generators/js_templates/module_definition.tmpl',
-        '<(DEPTH)/mojo/public/tools/bindings/generators/js_templates/module.amd.tmpl',
-        '<(DEPTH)/mojo/public/tools/bindings/generators/js_templates/module.sky.tmpl',
-        '<(DEPTH)/mojo/public/tools/bindings/generators/js_templates/struct_definition.tmpl',
-        '<(DEPTH)/mojo/public/tools/bindings/generators/python_templates/module_macros.tmpl',
-        '<(DEPTH)/mojo/public/tools/bindings/generators/python_templates/module.py.tmpl',
-        '<(DEPTH)/mojo/public/tools/bindings/generators/mojom_cpp_generator.py',
-        '<(DEPTH)/mojo/public/tools/bindings/generators/mojom_java_generator.py',
-        '<(DEPTH)/mojo/public/tools/bindings/generators/mojom_js_generator.py',
-        '<(DEPTH)/mojo/public/tools/bindings/generators/mojom_python_generator.py',
-        '<(DEPTH)/mojo/public/tools/bindings/pylib/mojom/__init__.py',
-        '<(DEPTH)/mojo/public/tools/bindings/pylib/mojom/error.py',
-        '<(DEPTH)/mojo/public/tools/bindings/pylib/mojom/generate/__init__.py',
-        '<(DEPTH)/mojo/public/tools/bindings/pylib/mojom/generate/data.py',
-        '<(DEPTH)/mojo/public/tools/bindings/pylib/mojom/generate/generator.py',
-        '<(DEPTH)/mojo/public/tools/bindings/pylib/mojom/generate/module.py',
-        '<(DEPTH)/mojo/public/tools/bindings/pylib/mojom/generate/pack.py',
-        '<(DEPTH)/mojo/public/tools/bindings/pylib/mojom/generate/template_expander.py',
-        '<(DEPTH)/mojo/public/tools/bindings/pylib/mojom/parse/__init__.py',
-        '<(DEPTH)/mojo/public/tools/bindings/pylib/mojom/parse/ast.py',
-        '<(DEPTH)/mojo/public/tools/bindings/pylib/mojom/parse/lexer.py',
-        '<(DEPTH)/mojo/public/tools/bindings/pylib/mojom/parse/parser.py',
-        '<(DEPTH)/mojo/public/tools/bindings/pylib/mojom/parse/translate.py',
+        '<@(mojom_bindings_generator_sources)',
       ],
       'outputs': [
         '<(SHARED_INTERMEDIATE_DIR)/<(mojom_base_output_dir)/<(RULE_INPUT_DIRNAME)/<(RULE_INPUT_ROOT).mojom.cc',
diff --git a/mojo/public/tools/bindings/mojom_bindings_generator_explicit.gypi b/mojo/public/tools/bindings/mojom_bindings_generator_explicit.gypi
new file mode 100644
index 0000000..68348fb
--- /dev/null
+++ b/mojo/public/tools/bindings/mojom_bindings_generator_explicit.gypi
@@ -0,0 +1,69 @@
+# 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.
+
+{
+  'includes': [
+    'mojom_bindings_generator_variables.gypi',
+  ],
+  'variables': {
+    'mojom_base_output_dir':
+        '<!(python <(DEPTH)/build/inverse_depth.py <(DEPTH))',
+    'mojom_generated_outputs': [
+      '<!@(python <(DEPTH)/mojo/public/tools/bindings/mojom_list_outputs.py --basedir <(mojom_base_output_dir) <@(mojom_files))',
+    ],
+  },
+  'actions': [
+    {
+      'action_name': '<(_target_name)_mojom_bindings_generator',
+      'variables': {
+        'java_out_dir': '<(PRODUCT_DIR)/java_mojo/<(_target_name)/src',
+        'mojom_import_args%': [
+         '-I<(DEPTH)'
+        ],
+      },
+      'inputs': [
+        '<@(mojom_bindings_generator_sources)',
+        '<@(mojom_files)',
+      ],
+      'outputs': [
+        '<@(mojom_generated_outputs)',
+      ],
+      'action': [
+        'python', '<@(mojom_bindings_generator)',
+        '<@(mojom_files)',
+        '--use_chromium_bundled_pylibs',
+        '-d', '<(DEPTH)',
+        '<@(mojom_import_args)',
+        '-o', '<(SHARED_INTERMEDIATE_DIR)',
+        '--java_output_directory=<(java_out_dir)',
+      ],
+      'message': 'Generating Mojo bindings from <@(mojom_files)',
+      'process_outputs_as_sources': 1,
+    }
+  ],
+  'direct_dependent_settings': {
+    'sources': [
+      '<@(mojom_generated_outputs)',
+    ],
+    # Include paths needed to compile the generated sources into a library.
+    'include_dirs': [
+      '<(DEPTH)',
+      '<(SHARED_INTERMEDIATE_DIR)',
+    ],
+    'direct_dependent_settings': {
+      # Include paths needed to find the generated header files and their
+      # transitive dependancies when using the library.
+      'include_dirs': [
+        '<(DEPTH)',
+        '<(SHARED_INTERMEDIATE_DIR)',
+      ],
+      'variables': {
+	'generated_src_dirs': [
+	  '<(PRODUCT_DIR)/java_mojo/<(_target_name)/src',
+	],
+      },
+    }
+  },
+  'hard_dependency': 1,
+}
diff --git a/mojo/public/tools/bindings/mojom_bindings_generator_variables.gypi b/mojo/public/tools/bindings/mojom_bindings_generator_variables.gypi
new file mode 100644
index 0000000..b4b53e6
--- /dev/null
+++ b/mojo/public/tools/bindings/mojom_bindings_generator_variables.gypi
@@ -0,0 +1,67 @@
+# 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.
+
+{
+  'variables': {
+    'mojom_bindings_generator':
+        '<(DEPTH)/mojo/public/tools/bindings/mojom_bindings_generator.py',
+    'mojom_bindings_generator_sources': [
+      '<(mojom_bindings_generator)',
+      '<(DEPTH)/mojo/public/tools/bindings/generators/cpp_templates/enum_declaration.tmpl',
+      '<(DEPTH)/mojo/public/tools/bindings/generators/cpp_templates/interface_declaration.tmpl',
+      '<(DEPTH)/mojo/public/tools/bindings/generators/cpp_templates/interface_definition.tmpl',
+      '<(DEPTH)/mojo/public/tools/bindings/generators/cpp_templates/interface_macros.tmpl',
+      '<(DEPTH)/mojo/public/tools/bindings/generators/cpp_templates/interface_proxy_declaration.tmpl',
+      '<(DEPTH)/mojo/public/tools/bindings/generators/cpp_templates/interface_request_validator_declaration.tmpl',
+      '<(DEPTH)/mojo/public/tools/bindings/generators/cpp_templates/interface_response_validator_declaration.tmpl',
+      '<(DEPTH)/mojo/public/tools/bindings/generators/cpp_templates/interface_stub_declaration.tmpl',
+      '<(DEPTH)/mojo/public/tools/bindings/generators/cpp_templates/module.cc.tmpl',
+      '<(DEPTH)/mojo/public/tools/bindings/generators/cpp_templates/module.h.tmpl',
+      '<(DEPTH)/mojo/public/tools/bindings/generators/cpp_templates/module-internal.h.tmpl',
+      '<(DEPTH)/mojo/public/tools/bindings/generators/cpp_templates/params_definition.tmpl',
+      '<(DEPTH)/mojo/public/tools/bindings/generators/cpp_templates/struct_declaration.tmpl',
+      '<(DEPTH)/mojo/public/tools/bindings/generators/cpp_templates/struct_definition.tmpl',
+      '<(DEPTH)/mojo/public/tools/bindings/generators/cpp_templates/struct_macros.tmpl',
+      '<(DEPTH)/mojo/public/tools/bindings/generators/cpp_templates/struct_serialization_declaration.tmpl',
+      '<(DEPTH)/mojo/public/tools/bindings/generators/cpp_templates/struct_serialization_definition.tmpl',
+      '<(DEPTH)/mojo/public/tools/bindings/generators/cpp_templates/wrapper_class_declaration.tmpl',
+      '<(DEPTH)/mojo/public/tools/bindings/generators/cpp_templates/wrapper_class_definition.tmpl',
+      '<(DEPTH)/mojo/public/tools/bindings/generators/java_templates/constant_definition.tmpl',
+      '<(DEPTH)/mojo/public/tools/bindings/generators/java_templates/constants.java.tmpl',
+      '<(DEPTH)/mojo/public/tools/bindings/generators/java_templates/enum_definition.tmpl',
+      '<(DEPTH)/mojo/public/tools/bindings/generators/java_templates/enum.java.tmpl',
+      '<(DEPTH)/mojo/public/tools/bindings/generators/java_templates/header.java.tmpl',
+      '<(DEPTH)/mojo/public/tools/bindings/generators/java_templates/interface_definition.tmpl',
+      '<(DEPTH)/mojo/public/tools/bindings/generators/java_templates/interface.java.tmpl',
+      '<(DEPTH)/mojo/public/tools/bindings/generators/java_templates/interface_internal.java.tmpl',
+      '<(DEPTH)/mojo/public/tools/bindings/generators/java_templates/struct_definition.tmpl',
+      '<(DEPTH)/mojo/public/tools/bindings/generators/java_templates/struct.java.tmpl',
+      '<(DEPTH)/mojo/public/tools/bindings/generators/js_templates/enum_definition.tmpl',
+      '<(DEPTH)/mojo/public/tools/bindings/generators/js_templates/interface_definition.tmpl',
+      '<(DEPTH)/mojo/public/tools/bindings/generators/js_templates/module_definition.tmpl',
+      '<(DEPTH)/mojo/public/tools/bindings/generators/js_templates/module.amd.tmpl',
+      '<(DEPTH)/mojo/public/tools/bindings/generators/js_templates/module.sky.tmpl',
+      '<(DEPTH)/mojo/public/tools/bindings/generators/js_templates/struct_definition.tmpl',
+      '<(DEPTH)/mojo/public/tools/bindings/generators/python_templates/module_macros.tmpl',
+      '<(DEPTH)/mojo/public/tools/bindings/generators/python_templates/module.py.tmpl',
+      '<(DEPTH)/mojo/public/tools/bindings/generators/mojom_cpp_generator.py',
+      '<(DEPTH)/mojo/public/tools/bindings/generators/mojom_java_generator.py',
+      '<(DEPTH)/mojo/public/tools/bindings/generators/mojom_js_generator.py',
+      '<(DEPTH)/mojo/public/tools/bindings/generators/mojom_python_generator.py',
+      '<(DEPTH)/mojo/public/tools/bindings/pylib/mojom/__init__.py',
+      '<(DEPTH)/mojo/public/tools/bindings/pylib/mojom/error.py',
+      '<(DEPTH)/mojo/public/tools/bindings/pylib/mojom/generate/__init__.py',
+      '<(DEPTH)/mojo/public/tools/bindings/pylib/mojom/generate/data.py',
+      '<(DEPTH)/mojo/public/tools/bindings/pylib/mojom/generate/generator.py',
+      '<(DEPTH)/mojo/public/tools/bindings/pylib/mojom/generate/module.py',
+      '<(DEPTH)/mojo/public/tools/bindings/pylib/mojom/generate/pack.py',
+      '<(DEPTH)/mojo/public/tools/bindings/pylib/mojom/generate/template_expander.py',
+      '<(DEPTH)/mojo/public/tools/bindings/pylib/mojom/parse/__init__.py',
+      '<(DEPTH)/mojo/public/tools/bindings/pylib/mojom/parse/ast.py',
+      '<(DEPTH)/mojo/public/tools/bindings/pylib/mojom/parse/lexer.py',
+      '<(DEPTH)/mojo/public/tools/bindings/pylib/mojom/parse/parser.py',
+      '<(DEPTH)/mojo/public/tools/bindings/pylib/mojom/parse/translate.py',
+    ]
+  }
+}
\ No newline at end of file
diff --git a/mojo/public/tools/bindings/mojom_list_outputs.py b/mojo/public/tools/bindings/mojom_list_outputs.py
new file mode 100755
index 0000000..c30ca2c
--- /dev/null
+++ b/mojo/public/tools/bindings/mojom_list_outputs.py
@@ -0,0 +1,34 @@
+#!/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
+
+def main():
+  parser = argparse.ArgumentParser(
+      description="GYP helper script for mapping mojoms => generated outputs.")
+  parser.add_argument("--basedir", required=True)
+  parser.add_argument("mojom", nargs="*")
+
+  args = parser.parse_args()
+
+  for mojom in args.mojom:
+    full = os.path.join("<(SHARED_INTERMEDIATE_DIR)", args.basedir, mojom)
+    base, ext = os.path.splitext(full)
+    assert ext == ".mojom", mojom
+    # Fix filename escaping issues on Windows.
+    base = base.replace("\\", "/")
+    print base + ".mojom.cc"
+    print base + ".mojom.h"
+    print base + ".mojom-internal.h"
+    print base + ".mojom.js"
+    print base + ".mojom.sky"
+    print base + "_mojom.py"
+
+  return 0
+
+if __name__ == "__main__":
+  sys.exit(main())
diff --git a/mojo/services/public/cpp/view_manager/lib/view.cc b/mojo/services/public/cpp/view_manager/lib/view.cc
index 84a0455..b371000 100644
--- a/mojo/services/public/cpp/view_manager/lib/view.cc
+++ b/mojo/services/public/cpp/view_manager/lib/view.cc
@@ -311,6 +311,10 @@
 }
 
 bool View::Contains(View* child) const {
+  if (!child)
+    return false;
+  if (child == this)
+    return true;
   if (manager_)
     CHECK_EQ(ViewPrivate(child).view_manager(), manager_);
   for (View* p = child->parent(); p; p = p->parent()) {
diff --git a/mojo/services/public/cpp/view_manager/lib/view_manager_client_factory.cc b/mojo/services/public/cpp/view_manager/lib/view_manager_client_factory.cc
index 91bc265..7175423 100644
--- a/mojo/services/public/cpp/view_manager/lib/view_manager_client_factory.cc
+++ b/mojo/services/public/cpp/view_manager/lib/view_manager_client_factory.cc
@@ -24,9 +24,9 @@
     ScopedMessagePipeHandle handle,
     Shell* shell,
     ViewManagerDelegate* delegate) {
-  scoped_ptr<ViewManagerClientImpl> client(
-      new ViewManagerClientImpl(delegate, shell));
-  WeakBindToPipe(client.get(), handle.Pass());
+  const bool delete_on_error = false;
+  scoped_ptr<ViewManagerClientImpl> client(new ViewManagerClientImpl(
+      delegate, shell, handle.Pass(), delete_on_error));
   return client.Pass();
 }
 
@@ -34,7 +34,9 @@
 void ViewManagerClientFactory::Create(
     ApplicationConnection* connection,
     InterfaceRequest<ViewManagerClient> request) {
-  BindToRequest(new ViewManagerClientImpl(delegate_, shell_), &request);
+  const bool delete_on_error = true;
+  new ViewManagerClientImpl(delegate_, shell_, request.PassMessagePipe(),
+                            delete_on_error);
 }
 
 }  // namespace mojo
diff --git a/mojo/services/public/cpp/view_manager/lib/view_manager_client_impl.cc b/mojo/services/public/cpp/view_manager/lib/view_manager_client_impl.cc
index 860beb5..9421e18 100644
--- a/mojo/services/public/cpp/view_manager/lib/view_manager_client_impl.cc
+++ b/mojo/services/public/cpp/view_manager/lib/view_manager_client_impl.cc
@@ -92,8 +92,16 @@
 };
 
 ViewManagerClientImpl::ViewManagerClientImpl(ViewManagerDelegate* delegate,
-                                             Shell* shell)
-    : connected_(false), connection_id_(0), next_id_(1), delegate_(delegate) {
+                                             Shell* shell,
+                                             ScopedMessagePipeHandle handle,
+                                             bool delete_on_error)
+    : connected_(false),
+      connection_id_(0),
+      next_id_(1),
+      delegate_(delegate),
+      binding_(this, handle.Pass()),
+      service_(binding_.client()),
+      delete_on_error_(delete_on_error) {
 }
 
 ViewManagerClientImpl::~ViewManagerClientImpl() {
@@ -199,8 +207,9 @@
     Id view_id,
     ServiceProviderPtr service_provider) {
   DCHECK(connected_);
-  service_->Embed(url, view_id, service_provider.Pass(),
-                  ActionCompletedCallback());
+  service_->Embed(url, view_id,
+      MakeRequest<ServiceProvider>(service_provider.PassMessagePipe()),
+      ActionCompletedCallback());
 }
 
 void ViewManagerClientImpl::AddView(View* view) {
@@ -231,13 +240,6 @@
 }
 
 ////////////////////////////////////////////////////////////////////////////////
-// ViewManagerClientImpl, InterfaceImpl overrides:
-
-void ViewManagerClientImpl::OnConnectionEstablished() {
-  service_ = client();
-}
-
-////////////////////////////////////////////////////////////////////////////////
 // ViewManagerClientImpl, ViewManagerClient implementation:
 
 void ViewManagerClientImpl::OnEmbed(
@@ -395,6 +397,13 @@
                                                   Id new_focused_window) {}
 
 ////////////////////////////////////////////////////////////////////////////////
+// OnConnectionError, private:
+void ViewManagerClientImpl::OnConnectionError() {
+  if (delete_on_error_)
+    delete this;
+}
+
+////////////////////////////////////////////////////////////////////////////////
 // ViewManagerClientImpl, private:
 
 void ViewManagerClientImpl::RemoveRoot(View* root) {
diff --git a/mojo/services/public/cpp/view_manager/lib/view_manager_client_impl.h b/mojo/services/public/cpp/view_manager/lib/view_manager_client_impl.h
index f40e3a8..2c941da 100644
--- a/mojo/services/public/cpp/view_manager/lib/view_manager_client_impl.h
+++ b/mojo/services/public/cpp/view_manager/lib/view_manager_client_impl.h
@@ -9,6 +9,7 @@
 #include "base/callback.h"
 #include "base/memory/scoped_vector.h"
 #include "base/memory/weak_ptr.h"
+#include "mojo/public/cpp/bindings/strong_binding.h"
 #include "mojo/services/public/cpp/view_manager/types.h"
 #include "mojo/services/public/cpp/view_manager/view.h"
 #include "mojo/services/public/cpp/view_manager/view_manager.h"
@@ -23,10 +24,14 @@
 
 // Manages the connection with the View Manager service.
 class ViewManagerClientImpl : public ViewManager,
-                              public InterfaceImpl<ViewManagerClient>,
-                              public WindowManagerClient {
+                              public ViewManagerClient,
+                              public WindowManagerClient,
+                              public ErrorHandler {
  public:
-  ViewManagerClientImpl(ViewManagerDelegate* delegate, Shell* shell);
+  ViewManagerClientImpl(ViewManagerDelegate* delegate,
+                        Shell* shell,
+                        ScopedMessagePipeHandle handle,
+                        bool delete_on_error);
   ~ViewManagerClientImpl() override;
 
   bool connected() const { return connected_; }
@@ -83,9 +88,6 @@
   const std::vector<View*>& GetRoots() const override;
   View* GetViewById(Id id) override;
 
-  // Overridden from InterfaceImpl:
-  void OnConnectionEstablished() override;
-
   // Overridden from ViewManagerClient:
   void OnEmbed(ConnectionSpecificId connection_id,
                const String& creator_url,
@@ -120,6 +122,9 @@
   void OnActiveWindowChanged(Id old_focused_window,
                              Id new_focused_window) override;
 
+  // ErrorHandler implementation.
+  void OnConnectionError() override;
+
   void RemoveRoot(View* root);
 
   void OnActionCompleted(bool success);
@@ -142,10 +147,12 @@
 
   IdToViewMap views_;
 
-  ViewManagerService* service_;
-
   WindowManagerPtr window_manager_;
 
+  Binding<ViewManagerClient> binding_;
+  ViewManagerService* service_;
+  const bool delete_on_error_;
+
   DISALLOW_COPY_AND_ASSIGN(ViewManagerClientImpl);
 };
 
diff --git a/mojo/services/public/cpp/view_manager/view_tracker.cc b/mojo/services/public/cpp/view_manager/view_tracker.cc
new file mode 100644
index 0000000..453d6f9
--- /dev/null
+++ b/mojo/services/public/cpp/view_manager/view_tracker.cc
@@ -0,0 +1,41 @@
+// 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/services/public/cpp/view_manager/view_tracker.h"
+
+namespace mojo {
+
+ViewTracker::ViewTracker() {
+}
+
+ViewTracker::~ViewTracker() {
+  for (Views::iterator i = views_.begin(); i != views_.end(); ++i)
+    (*i)->RemoveObserver(this);
+}
+
+void ViewTracker::Add(View* view) {
+  if (views_.count(view))
+    return;
+
+  view->AddObserver(this);
+  views_.insert(view);
+}
+
+void ViewTracker::Remove(View* view) {
+  if (views_.count(view)) {
+    views_.erase(view);
+    view->RemoveObserver(this);
+  }
+}
+
+bool ViewTracker::Contains(View* view) {
+  return views_.count(view) > 0;
+}
+
+void ViewTracker::OnViewDestroying(View* view) {
+  DCHECK_GT(views_.count(view), 0u);
+  Remove(view);
+}
+
+}  // namespace mojo
diff --git a/mojo/services/public/cpp/view_manager/view_tracker.h b/mojo/services/public/cpp/view_manager/view_tracker.h
new file mode 100644
index 0000000..71a218a
--- /dev/null
+++ b/mojo/services/public/cpp/view_manager/view_tracker.h
@@ -0,0 +1,47 @@
+// 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_SERVICES_PUBLIC_CPP_VIEW_MANAGER_VIEW_TRACKER_H_
+#define MOJO_SERVICES_PUBLIC_CPP_VIEW_MANAGER_VIEW_TRACKER_H_
+
+#include <set>
+
+#include "base/basictypes.h"
+#include "base/compiler_specific.h"
+#include "mojo/services/public/cpp/view_manager/view_observer.h"
+
+namespace mojo {
+
+class ViewTracker : public ViewObserver {
+ public:
+  using Views = std::set<View*>;
+
+  ViewTracker();
+  ~ViewTracker() override;
+
+  // Returns the set of views being observed.
+  const std::set<View*>& views() const { return views_; }
+
+  // Adds |view| to the set of Views being tracked.
+  void Add(View* view);
+
+  // Removes |view| from the set of views being tracked.
+  void Remove(View* view);
+
+  // Returns true if |view| was previously added and has not been removed or
+  // deleted.
+  bool Contains(View* view);
+
+  // ViewObserver overrides:
+  virtual void OnViewDestroying(View* view) override;
+
+ private:
+  Views views_;
+
+  DISALLOW_COPY_AND_ASSIGN(ViewTracker);
+};
+
+}  // namespace mojo
+
+#endif  // MOJO_SERVICES_PUBLIC_CPP_VIEW_MANAGER_VIEW_TRACKER_H_
diff --git a/mojo/services/public/interfaces/accessibility/accessibility.mojom b/mojo/services/public/interfaces/accessibility/accessibility.mojom
new file mode 100644
index 0000000..abc97c3
--- /dev/null
+++ b/mojo/services/public/interfaces/accessibility/accessibility.mojom
@@ -0,0 +1,35 @@
+// 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.
+
+module mojo;
+
+import "mojo/services/public/interfaces/geometry/geometry.mojom";
+
+interface AxProvider {
+  GetTree() => (array<AxNode> nodes);
+};
+
+struct AxNode {
+  // Must be non-zero.
+  uint32 id;
+
+  // Can be zero if the node has no parent or next sibling.
+  uint32 parent_id;
+  uint32 next_sibling_id;
+
+  mojo.Rect bounds;
+
+  // At most one of the below will be present.
+  // TODO(aa): These should become a union.
+  AxLink? link;
+  AxText? text;
+};
+
+struct AxLink {
+  string url;
+};
+
+struct AxText {
+  string content;
+};
diff --git a/mojo/services/public/interfaces/gpu/command_buffer.mojom b/mojo/services/public/interfaces/gpu/command_buffer.mojom
index b8b9a3d..2b938c1 100644
--- a/mojo/services/public/interfaces/gpu/command_buffer.mojom
+++ b/mojo/services/public/interfaces/gpu/command_buffer.mojom
@@ -4,6 +4,8 @@
 
 module mojo;
 
+import "mojo/services/public/interfaces/gpu/gpu_capabilities.mojom";
+
 struct CommandBufferState {
   int32 num_entries;
   int32 get_offset;
@@ -15,7 +17,7 @@
 };
 
 interface CommandBufferSyncClient {
-  DidInitialize(bool success);
+  DidInitialize(bool success, GpuCapabilities capabilities);
   DidMakeProgress(CommandBufferState? state);
 };
 
diff --git a/mojo/services/public/interfaces/gpu/gpu_capabilities.mojom b/mojo/services/public/interfaces/gpu/gpu_capabilities.mojom
new file mode 100644
index 0000000..2450139
--- /dev/null
+++ b/mojo/services/public/interfaces/gpu/gpu_capabilities.mojom
@@ -0,0 +1,54 @@
+// 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.
+
+module mojo;
+
+struct GpuShaderPrecision {
+  int32 min_range;
+  int32 max_range;
+  int32 precision;
+};
+
+struct GpuPerStagePrecisions {
+  GpuShaderPrecision low_int;
+  GpuShaderPrecision medium_int;
+  GpuShaderPrecision high_int;
+  GpuShaderPrecision low_float;
+  GpuShaderPrecision medium_float;
+  GpuShaderPrecision high_float;
+};
+
+struct GpuCapabilities {
+  GpuPerStagePrecisions vertex_shader_precisions;
+  GpuPerStagePrecisions fragment_shader_precisions;
+  int32 max_combined_texture_image_units;
+  int32 max_cube_map_texture_size;
+  int32 max_fragment_uniform_vectors;
+  int32 max_renderbuffer_size;
+  int32 max_texture_image_units;
+  int32 max_texture_size;
+  int32 max_varying_vectors;
+  int32 max_vertex_attribs;
+  int32 max_vertex_texture_image_units;
+  int32 max_vertex_uniform_vectors;
+  int32 num_compressed_texture_formats;
+  int32 num_shader_binary_formats;
+  int32 bind_generates_resource_chromium;
+
+  bool post_sub_buffer;
+  bool egl_image_external;
+  bool texture_format_bgra8888;
+  bool texture_format_etc1;
+  bool texture_format_etc1_npot;
+  bool texture_rectangle;
+  bool iosurface;
+  bool texture_usage;
+  bool texture_storage;
+  bool discard_framebuffer;
+  bool sync_query;
+  bool image;
+  bool future_sync_points;
+  bool blend_equation_advanced;
+  bool blend_equation_advanced_coherent;
+};
diff --git a/mojo/services/public/interfaces/network/cookie_store.mojom b/mojo/services/public/interfaces/network/cookie_store.mojom
index 6f2da5e..92a4241 100644
--- a/mojo/services/public/interfaces/network/cookie_store.mojom
+++ b/mojo/services/public/interfaces/network/cookie_store.mojom
@@ -5,6 +5,6 @@
 module mojo;
 
 interface CookieStore {
-  Get(string? url) => (string? cookies);
-  Set(string? url, string? cookie) => (bool success);
+  Get(string url) => (string cookies);
+  Set(string url, string cookie) => (bool success);
 };
diff --git a/mojo/services/public/interfaces/network/network_service.mojom b/mojo/services/public/interfaces/network/network_service.mojom
index e3e4070..e79dfb5 100644
--- a/mojo/services/public/interfaces/network/network_service.mojom
+++ b/mojo/services/public/interfaces/network/network_service.mojom
@@ -17,9 +17,9 @@
 // high-level origin-build requests like WebSockets and HTTP, and the other for
 // non-origin-bound low-level stuff like DNS, UDP, and TCP.
 interface NetworkService {
-  CreateURLLoader(URLLoader&? loader);
+  CreateURLLoader(URLLoader& loader);
 
-  GetCookieStore(CookieStore&? cookie_store);
+  GetCookieStore(CookieStore& cookie_store);
 
   CreateWebSocket(WebSocket& socket);
 
diff --git a/mojo/services/public/interfaces/network/url_loader.mojom b/mojo/services/public/interfaces/network/url_loader.mojom
index b258fc4..c1d2bd3 100644
--- a/mojo/services/public/interfaces/network/url_loader.mojom
+++ b/mojo/services/public/interfaces/network/url_loader.mojom
@@ -8,17 +8,17 @@
 
 struct URLRequest {
   // The URL to load.
-  string? url;
+  string url;
 
   // The HTTP method if applicable.
-  string? method = "GET";
+  string method = "GET";
 
   // Additional HTTP request headers.
-  array<string?>? headers;
+  array<string>? headers;
 
   // The payload for the request body, represented as a concatenation of data
   // streams. For HTTP requests, the method must be set to "POST" or "PUT".
-  array<handle<data_pipe_consumer>?>? body;
+  array<handle<data_pipe_consumer>>? body;
 
   // The number of bytes to be read from |body|. A Content-Length header of
   // this value will be sent. Set to -1 if length is unknown, which will cause
@@ -59,7 +59,7 @@
   string? status_line;
 
   // The HTTP response headers.
-  array<string?>? headers;
+  array<string>? headers;
 
   // The MIME type of the response body.
   string? mime_type;
@@ -92,13 +92,13 @@
   // Loads the given |request|, asynchronously producing |response|. Consult
   // |response| to determine if the request resulted in an error, was
   // redirected, or has a response body to be consumed.
-  Start(URLRequest? request) => (URLResponse? response);
+  Start(URLRequest request) => (URLResponse response);
 
   // If the request passed to |Start| had |auto_follow_redirects| set to false,
   // then upon receiving an URLResponse with a non-NULL |redirect_url| field,
   // |FollowRedirect| may be called to load the URL indicated by the redirect.
-  FollowRedirect() => (URLResponse? response);
+  FollowRedirect() => (URLResponse response);
 
   // Query status about the URLLoader.
-  QueryStatus() => (URLLoaderStatus? status);
+  QueryStatus() => (URLLoaderStatus status);
 };
diff --git a/mojo/services/public/interfaces/view_manager/view_manager.mojom b/mojo/services/public/interfaces/view_manager/view_manager.mojom
index 2a1a178..25e1f06 100644
--- a/mojo/services/public/interfaces/view_manager/view_manager.mojom
+++ b/mojo/services/public/interfaces/view_manager/view_manager.mojom
@@ -130,7 +130,7 @@
   // any services it provided are not broken and continue to be valid.
   Embed(string url,
         uint32 view_id,
-        ServiceProvider? service_provider) => (bool success);
+        ServiceProvider&? service_provider) => (bool success);
 };
 
 // Changes to views are not sent to the connection that originated the
diff --git a/mojo/services/public/interfaces/window_manager/window_manager.mojom b/mojo/services/public/interfaces/window_manager/window_manager.mojom
index 6d108f9..8fe6f21 100644
--- a/mojo/services/public/interfaces/window_manager/window_manager.mojom
+++ b/mojo/services/public/interfaces/window_manager/window_manager.mojom
@@ -10,7 +10,7 @@
 [Client=WindowManagerClient]
 interface WindowManager {
   // Requests the WindowManager to embed the app for |url| at an appropriate
-  // View. See ViewManger::Embed() for details on |service_provider|.
+  // View. See ViewMangerService::Embed() for details on |service_provider|.
   Embed(string url, ServiceProvider&? service_provider);
 
   SetCapture(uint32 view_id) => (bool success);
diff --git a/mojo/services/public/js/mojo.js b/mojo/services/public/js/mojo.js
new file mode 100644
index 0000000..ad0ed0c
--- /dev/null
+++ b/mojo/services/public/js/mojo.js
@@ -0,0 +1,169 @@
+// 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.
+
+define("mojo/services/public/js/mojo", [
+  "mojo/public/interfaces/application/service_provider.mojom",
+  "mojo/public/js/connection",
+  "mojo/public/js/core",
+  "services/js/bridge",
+], function(service, connection, core, bridge) {
+
+  function Shell() {
+    this.applications_ = new Map();
+  }
+
+  Shell.prototype.connectToApplication = function(url) {
+    var application = this.applications_.get(url);
+    if (application)
+      return application;
+    application = new ServiceProvider(bridge.connectToApplication(url));
+    this.applications_.set(url, application);
+    return application;
+  };
+
+  Shell.prototype.connectToService = function (url, service, client) {
+    return this.connectToApplication(url).connectToService(service, client);
+  };
+
+  Shell.prototype.close = function() {
+    shell().applications_.forEach(function(application, url) {
+      application.close();
+    });
+    shell().applications_.clear();
+  };
+
+  var shellValue = null;
+
+  function shell() {
+    if (!shellValue)
+      shellValue = new Shell();
+    return shellValue;
+  }
+
+  var requestorValue = null;
+
+  function requestor() {
+    if (!requestorValue) {
+      var handle = bridge.requestorMessagePipeHandle();
+      requestorValue = handle && new ServiceProvider(handle);
+    }
+    return requestorValue;
+  }
+
+  function connectToServiceImpl(serviceName, serviceHandle) {
+    var provider = this.providers_.get(serviceName);
+    if (!provider) {
+      this.pendingRequests_.set(serviceName, serviceHandle);
+      return;
+    }
+
+    var serviceConnection = new connection.Connection(
+      serviceHandle,
+      provider.service.delegatingStubClass,
+      provider.service.client && provider.service.client.proxyClass);
+
+    serviceConnection.local.connection$ = serviceConnection;
+    serviceConnection.local.delegate$ =
+      new provider.factory(serviceConnection.remote);
+
+    provider.connections.push(serviceConnection);
+  }
+
+  function ServiceProvider(messagePipeHandle) {
+    // TODO(hansmuller): if messagePipeHandle is null, throw an exception.
+    this.connections_ = new Map();
+    this.providers_ = new Map();
+    this.pendingRequests_ = new Map();
+    this.connection_ = null;
+    this.handle_ = messagePipeHandle;
+    this.connection_ =  new connection.Connection(
+      this.handle_,
+      service.ServiceProvider.client.delegatingStubClass,
+      service.ServiceProvider.proxyClass);
+    this.connection_.local.delegate$ = {
+      connectToService: connectToServiceImpl.bind(this)
+    };
+  }
+
+  ServiceProvider.prototype.provideService = function(service, factory) {
+    // TODO(hansmuller): if !factory, remove provider and close its connections.
+    // TODO(hansmuller): if this.connection_ is null, throw an error.
+    var provider = {
+      service: service,
+      factory: factory,
+      connections: [],
+    };
+    this.providers_.set(service.name, provider);
+
+    if (this.pendingRequests_.has(service.name)) {
+      connectToServiceImpl(service.name, pendingRequests_.get(service.name));
+      pendingRequests_.delete(service.name);
+    }
+
+    return this;
+  };
+
+  ServiceProvider.prototype.connectToService = function(service, client) {
+    // TODO(hansmuler): if service.name isn't defined, throw an error.
+    // TODO(hansmuller): if this.connection_ is null, throw an error.
+    var serviceConnection = this.connections_.get(service.name);
+    if (serviceConnection)
+      return serviceConnection.remote;
+
+    var pipe = core.createMessagePipe();
+    this.connection_.remote.connectToService(service.name, pipe.handle1);
+    var clientClass = client && service.client.delegatingStubClass;
+    var serviceConnection =
+      new connection.Connection(pipe.handle0, clientClass, service.proxyClass);
+    if (serviceConnection.local)
+      serviceConnection.local.delegate$ = client;
+
+    this.connections_.set(service.name, serviceConnection);
+    return serviceConnection.remote;
+  };
+
+  ServiceProvider.prototype.close = function() {
+    if (!this.connection_)
+      return;
+
+    try {
+      // Outgoing connections
+      this.connections_.forEach(function(connection, serviceName) {
+        connection.close();
+      });
+      // Incoming connections
+      this.providers_.forEach(function(provider, serviceName) {
+        provider.connections.forEach(function(connection) {
+          connection.close();
+        });
+      });
+      this.connection_.close();
+    } finally {
+      this.connections_ = null;
+      this.providers_ = null;
+      this.pendingRequests_ = null;
+      this.connection_ = null;
+      this.handle_ = null;
+
+      shell().applications_.forEach(function(application, url) {
+        if (application === this)
+          shell().applications_.delete(url);
+      }, this);
+    }
+  };
+
+  function quit() {
+    if (requestorValue)
+      requestor().close();
+    if (shellValue)
+      shell().close();
+    bridge.quit();
+  }
+
+  var exports = {};
+  exports.requestor = requestor;
+  exports.shell = shell;
+  exports.quit = quit;
+  return exports;
+});
diff --git a/mojo/services/public/mojo_services_public.gyp b/mojo/services/public/mojo_services_public.gyp
index c0e200b..701d7e5 100644
--- a/mojo/services/public/mojo_services_public.gyp
+++ b/mojo/services/public/mojo_services_public.gyp
@@ -82,6 +82,7 @@
       'sources': [
         'interfaces/gpu/command_buffer.mojom',
         'interfaces/gpu/gpu.mojom',
+        'interfaces/gpu/gpu_capabilities.mojom',
       ],
       'includes': [ '../../public/tools/bindings/mojom_bindings_generator.gypi' ],
       'dependencies': [