Revert "libmojo: Uprev the library to r456626 from Chromium"

This reverts commit 8ac9103e05b66812c25348943383f9365d1ce3e0.

Reason for revert: Broke the mac_sdk
Exempt-From-Owner-Approval: Fixing mac_sdk

Change-Id: I0b74d1abaa66933a93fd6f82ff018e8948c1204e
diff --git a/mojo/common/BUILD.gn b/mojo/common/BUILD.gn
index 9e74e58..57c85d5 100644
--- a/mojo/common/BUILD.gn
+++ b/mojo/common/BUILD.gn
@@ -12,27 +12,28 @@
   ]
 }
 
+# GYP version: mojo/mojo_base.gyp:mojo_common_custom_types
 mojom("common_custom_types") {
   sources = [
-    "file.mojom",
-    "file_path.mojom",
+    "common_custom_types.mojom",
     "string16.mojom",
-    "text_direction.mojom",
-    "time.mojom",
-    "unguessable_token.mojom",
-    "values.mojom",
-    "version.mojom",
   ]
 }
 
+# GYP version: mojo/mojo_base.gyp:mojo_common_lib
 component("common_base") {
   output_name = "mojo_common_lib"
 
   sources = [
+    "common_type_converters.cc",
+    "common_type_converters.h",
     "data_pipe_drainer.cc",
     "data_pipe_drainer.h",
+    "data_pipe_file_utils.cc",
     "data_pipe_utils.cc",
     "data_pipe_utils.h",
+    "user_agent.cc",
+    "user_agent.h",
   ]
 
   defines = [ "MOJO_COMMON_IMPLEMENTATION" ]
@@ -44,21 +45,21 @@
   ]
 }
 
+# GYP version: mojo/mojo_base.gyp:mojo_test_common_custom_types
 mojom("test_common_custom_types") {
   sources = [
     "test_common_custom_types.mojom",
-    "traits_test_service.mojom",
   ]
   public_deps = [
     ":common_custom_types",
   ]
 }
 
+# GYP version: mojo/mojo_base.gyp:mojo_common_unittests
 test("mojo_common_unittests") {
   deps = [
     ":common",
     ":common_custom_types",
-    ":struct_traits",
     ":test_common_custom_types",
     "//base",
     "//base:message_loop_tests",
@@ -73,21 +74,16 @@
 
   sources = [
     "common_custom_types_unittest.cc",
-    "struct_traits_unittest.cc",
+    "common_type_converters_unittest.cc",
   ]
 }
 
-source_set("struct_traits") {
-  sources = [
-    "common_custom_types_struct_traits.cc",
-    "common_custom_types_struct_traits.h",
-  ]
+test("mojo_common_perftests") {
   deps = [
-    ":common_custom_types_shared_cpp_sources",
-    "//base:base",
-    "//mojo/public/cpp/system",
-  ]
-  public_deps = [
-    "//base:i18n",
+    ":common",
+    "//base",
+    "//mojo/edk/test:run_all_perftests",
+    "//mojo/public/cpp/test_support:test_utils",
+    "//testing/gtest",
   ]
 }
diff --git a/mojo/common/DEPS b/mojo/common/DEPS
index e8ac428..588c68d 100644
--- a/mojo/common/DEPS
+++ b/mojo/common/DEPS
@@ -1,6 +1,16 @@
 include_rules = [
   # common must not depend on embedder.
   "-mojo",
+  "+services/shell/public/cpp",
   "+mojo/common",
   "+mojo/public",
 ]
+
+specific_include_rules = {
+  "trace_controller_impl\.h": [
+    "+services/tracing/public/interfaces/tracing.mojom.h"
+  ],
+  "tracing_impl\.h": [
+    "+services/tracing/public/interfaces/tracing.mojom.h"
+  ],
+}
diff --git a/mojo/common/time.mojom b/mojo/common/common_custom_types.mojom
similarity index 67%
rename from mojo/common/time.mojom
rename to mojo/common/common_custom_types.mojom
index 43dfcc8..aa87106 100644
--- a/mojo/common/time.mojom
+++ b/mojo/common/common_custom_types.mojom
@@ -5,11 +5,19 @@
 module mojo.common.mojom;
 
 [Native]
+struct FilePath;
+
+[Native]
+struct ListValue;
+
+[Native]
+struct DictionaryValue;
+
+[Native]
 struct Time;
 
-struct TimeDelta {
-  int64 microseconds;
-};
+[Native]
+struct TimeDelta;
 
 [Native]
 struct TimeTicks;
diff --git a/mojo/common/common_custom_types.typemap b/mojo/common/common_custom_types.typemap
new file mode 100644
index 0000000..0b63f38
--- /dev/null
+++ b/mojo/common/common_custom_types.typemap
@@ -0,0 +1,24 @@
+# Copyright 2016 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+mojom = "//mojo/common/common_custom_types.mojom"
+public_headers = [
+  "//base/files/file_path.h",
+  "//base/values.h",
+  "//base/time/time.h",
+]
+traits_headers = [ "//ipc/ipc_message_utils.h" ]
+public_deps = [
+  "//ipc",
+]
+
+type_mappings = [
+  "mojo.common.mojom.FilePath=base::FilePath",
+  "mojo.common.mojom.DictionaryValue=base::DictionaryValue",
+  "mojo.common.mojom.ListValue=base::ListValue",
+  "mojo.common.mojom.String16=base::string16",
+  "mojo.common.mojom.Time=base::Time",
+  "mojo.common.mojom.TimeDelta=base::TimeDelta",
+  "mojo.common.mojom.TimeTicks=base::TimeTicks",
+]
diff --git a/mojo/common/common_custom_types_struct_traits.cc b/mojo/common/common_custom_types_struct_traits.cc
index 6289504..3f9f7d9 100644
--- a/mojo/common/common_custom_types_struct_traits.cc
+++ b/mojo/common/common_custom_types_struct_traits.cc
@@ -1,108 +1,18 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
+// Copyright 2017 The Chromium Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
 #include "mojo/common/common_custom_types_struct_traits.h"
 
-#include "mojo/public/cpp/system/platform_handle.h"
-
 namespace mojo {
 
 // static
-bool StructTraits<common::mojom::String16DataView, base::string16>::Read(
-    common::mojom::String16DataView data,
-    base::string16* out) {
-  ArrayDataView<uint16_t> view;
-  data.GetDataDataView(&view);
+bool StructTraits<common::mojom::String16, base::string16>::Read(
+    common::mojom::String16DataView data, base::string16* out) {
+  std::vector<uint16_t> view;
+  data.ReadData(&view);
   out->assign(reinterpret_cast<const base::char16*>(view.data()), view.size());
   return true;
 }
 
-// static
-const std::vector<uint32_t>&
-StructTraits<common::mojom::VersionDataView, base::Version>::components(
-    const base::Version& version) {
-  return version.components();
-}
-
-// static
-bool StructTraits<common::mojom::VersionDataView, base::Version>::Read(
-    common::mojom::VersionDataView data,
-    base::Version* out) {
-  std::vector<uint32_t> components;
-  if (!data.ReadComponents(&components))
-    return false;
-
-  *out = base::Version(base::Version(std::move(components)));
-  return out->IsValid();
-}
-
-// static
-bool StructTraits<
-    common::mojom::UnguessableTokenDataView,
-    base::UnguessableToken>::Read(common::mojom::UnguessableTokenDataView data,
-                                  base::UnguessableToken* out) {
-  uint64_t high = data.high();
-  uint64_t low = data.low();
-
-  // Receiving a zeroed UnguessableToken is a security issue.
-  if (high == 0 && low == 0)
-    return false;
-
-  *out = base::UnguessableToken::Deserialize(high, low);
-  return true;
-}
-
-mojo::ScopedHandle StructTraits<common::mojom::FileDataView, base::File>::fd(
-    base::File& file) {
-  DCHECK(file.IsValid());
-  return mojo::WrapPlatformFile(file.TakePlatformFile());
-}
-
-bool StructTraits<common::mojom::FileDataView, base::File>::Read(
-    common::mojom::FileDataView data,
-    base::File* file) {
-  base::PlatformFile platform_handle = base::kInvalidPlatformFile;
-  if (mojo::UnwrapPlatformFile(data.TakeFd(), &platform_handle) !=
-      MOJO_RESULT_OK) {
-    return false;
-  }
-  *file = base::File(platform_handle);
-  return true;
-}
-
-// static
-common::mojom::TextDirection
-EnumTraits<common::mojom::TextDirection, base::i18n::TextDirection>::ToMojom(
-    base::i18n::TextDirection text_direction) {
-  switch (text_direction) {
-    case base::i18n::UNKNOWN_DIRECTION:
-      return common::mojom::TextDirection::UNKNOWN_DIRECTION;
-    case base::i18n::RIGHT_TO_LEFT:
-      return common::mojom::TextDirection::RIGHT_TO_LEFT;
-    case base::i18n::LEFT_TO_RIGHT:
-      return common::mojom::TextDirection::LEFT_TO_RIGHT;
-  }
-  NOTREACHED();
-  return common::mojom::TextDirection::UNKNOWN_DIRECTION;
-}
-
-// static
-bool EnumTraits<common::mojom::TextDirection, base::i18n::TextDirection>::
-    FromMojom(common::mojom::TextDirection input,
-              base::i18n::TextDirection* out) {
-  switch (input) {
-    case common::mojom::TextDirection::UNKNOWN_DIRECTION:
-      *out = base::i18n::UNKNOWN_DIRECTION;
-      return true;
-    case common::mojom::TextDirection::RIGHT_TO_LEFT:
-      *out = base::i18n::RIGHT_TO_LEFT;
-      return true;
-    case common::mojom::TextDirection::LEFT_TO_RIGHT:
-      *out = base::i18n::LEFT_TO_RIGHT;
-      return true;
-  }
-  return false;
-}
-
-}  // namespace mojo
+}  // mojo
diff --git a/mojo/common/common_custom_types_struct_traits.h b/mojo/common/common_custom_types_struct_traits.h
index b20c795..22afdb6 100644
--- a/mojo/common/common_custom_types_struct_traits.h
+++ b/mojo/common/common_custom_types_struct_traits.h
@@ -1,98 +1,27 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
+// Copyright 2017 The Chromium Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
 #ifndef MOJO_COMMON_COMMON_CUSTOM_TYPES_STRUCT_TRAITS_H_
 #define MOJO_COMMON_COMMON_CUSTOM_TYPES_STRUCT_TRAITS_H_
 
-#include "base/files/file.h"
-#include "base/i18n/rtl.h"
-#include "base/strings/utf_string_conversions.h"
-#include "base/unguessable_token.h"
-#include "base/version.h"
-#include "mojo/common/file.mojom-shared.h"
-#include "mojo/common/mojo_common_export.h"
-#include "mojo/common/string16.mojom-shared.h"
-#include "mojo/common/text_direction.mojom-shared.h"
-#include "mojo/common/time.mojom-shared.h"
-#include "mojo/common/unguessable_token.mojom-shared.h"
-#include "mojo/common/version.mojom-shared.h"
+#include <stdint.h>
+#include <vector>
+
+#include "mojo/common/string16.mojom.h"
+#include "mojo/public/cpp/bindings/struct_traits.h"
 
 namespace mojo {
 
 template <>
-struct StructTraits<common::mojom::String16DataView, base::string16> {
-  static ConstCArray<uint16_t> data(const base::string16& str) {
-    return ConstCArray<uint16_t>(str.size(),
-                                 reinterpret_cast<const uint16_t*>(str.data()));
+struct StructTraits<common::mojom::String16, base::string16> {
+  static std::vector<uint16_t> data(const base::string16& str) {
+    const uint16_t* base = str.data();
+    return std::vector<uint16_t>(base, base + str.size());
   }
-
-  static bool Read(common::mojom::String16DataView data, base::string16* out);
+  static bool Read(common::mojom::String16DataView data, base::string16* output);
 };
 
-template <>
-struct StructTraits<common::mojom::VersionDataView, base::Version> {
-  static bool IsNull(const base::Version& version) {
-    return !version.IsValid();
-  }
-  static void SetToNull(base::Version* out) {
-    *out = base::Version(std::string());
-  }
-  static const std::vector<uint32_t>& components(const base::Version& version);
-  static bool Read(common::mojom::VersionDataView data, base::Version* out);
-};
-
-// If base::UnguessableToken is no longer 128 bits, the logic below and the
-// mojom::UnguessableToken type should be updated.
-static_assert(sizeof(base::UnguessableToken) == 2 * sizeof(uint64_t),
-              "base::UnguessableToken should be of size 2 * sizeof(uint64_t).");
-
-template <>
-struct StructTraits<common::mojom::UnguessableTokenDataView,
-                    base::UnguessableToken> {
-  static uint64_t high(const base::UnguessableToken& token) {
-    return token.GetHighForSerialization();
-  }
-
-  static uint64_t low(const base::UnguessableToken& token) {
-    return token.GetLowForSerialization();
-  }
-
-  static bool Read(common::mojom::UnguessableTokenDataView data,
-                   base::UnguessableToken* out);
-};
-
-template <>
-struct StructTraits<common::mojom::TimeDeltaDataView, base::TimeDelta> {
-  static int64_t microseconds(const base::TimeDelta& delta) {
-    return delta.InMicroseconds();
-  }
-
-  static bool Read(common::mojom::TimeDeltaDataView data,
-                   base::TimeDelta* delta) {
-    *delta = base::TimeDelta::FromMicroseconds(data.microseconds());
-    return true;
-  }
-};
-
-template <>
-struct StructTraits<common::mojom::FileDataView, base::File> {
-  static bool IsNull(const base::File& file) { return !file.IsValid(); }
-
-  static void SetToNull(base::File* file) { *file = base::File(); }
-
-  static mojo::ScopedHandle fd(base::File& file);
-  static bool Read(common::mojom::FileDataView data, base::File* file);
-};
-
-template <>
-struct EnumTraits<common::mojom::TextDirection, base::i18n::TextDirection> {
-  static common::mojom::TextDirection ToMojom(
-      base::i18n::TextDirection text_direction);
-  static bool FromMojom(common::mojom::TextDirection input,
-                        base::i18n::TextDirection* out);
-};
-
-}  // namespace mojo
+}  // mojo
 
 #endif  // MOJO_COMMON_COMMON_CUSTOM_TYPES_STRUCT_TRAITS_H_
diff --git a/mojo/common/common_custom_types_unittest.cc b/mojo/common/common_custom_types_unittest.cc
index e3571d9..fe6bb5d 100644
--- a/mojo/common/common_custom_types_unittest.cc
+++ b/mojo/common/common_custom_types_unittest.cc
@@ -3,13 +3,10 @@
 // found in the LICENSE file.
 
 #include "base/files/file_path.h"
-#include "base/files/scoped_temp_dir.h"
-#include "base/memory/ptr_util.h"
 #include "base/message_loop/message_loop.h"
-#include "base/numerics/safe_math.h"
 #include "base/run_loop.h"
-#include "base/strings/utf_string_conversions.h"
 #include "base/values.h"
+#include "mojo/common/common_custom_types.mojom.h"
 #include "mojo/common/test_common_custom_types.mojom.h"
 #include "mojo/public/cpp/bindings/binding.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -26,38 +23,33 @@
   }
 };
 
-template <typename T>
-struct PassTraits {
-  using Type = const T&;
+template <>
+struct BounceTestTraits<base::DictionaryValue> {
+  static void ExpectEquality(const base::DictionaryValue& a,
+                             const base::DictionaryValue& b) {
+    EXPECT_TRUE(a.Equals(&b));
+  }
 };
 
 template <>
-struct PassTraits<base::Time> {
-  using Type = base::Time;
-};
-
-template <>
-struct PassTraits<base::TimeDelta> {
-  using Type = base::TimeDelta;
-};
-
-template <>
-struct PassTraits<base::TimeTicks> {
-  using Type = base::TimeTicks;
+struct BounceTestTraits<base::ListValue> {
+  static void ExpectEquality(const base::ListValue& a,
+                             const base::ListValue& b) {
+    EXPECT_TRUE(a.Equals(&b));
+  }
 };
 
 template <typename T>
 void DoExpectResponse(T* expected_value,
                       const base::Closure& closure,
-                      typename PassTraits<T>::Type value) {
+                      const T& value) {
   BounceTestTraits<T>::ExpectEquality(*expected_value, value);
   closure.Run();
 }
 
 template <typename T>
-base::Callback<void(typename PassTraits<T>::Type)> ExpectResponse(
-    T* expected_value,
-    const base::Closure& closure) {
+base::Callback<void(const T&)> ExpectResponse(T* expected_value,
+                                              const base::Closure& closure) {
   return base::Bind(&DoExpectResponse<T>, expected_value, closure);
 }
 
@@ -76,38 +68,24 @@
   mojo::Binding<TestFilePath> binding_;
 };
 
-class TestUnguessableTokenImpl : public TestUnguessableToken {
- public:
-  explicit TestUnguessableTokenImpl(TestUnguessableTokenRequest request)
-      : binding_(this, std::move(request)) {}
-
-  // TestUnguessableToken implementation:
-  void BounceNonce(const base::UnguessableToken& in,
-                   const BounceNonceCallback& callback) override {
-    callback.Run(in);
-  }
-
- private:
-  mojo::Binding<TestUnguessableToken> binding_;
-};
-
 class TestTimeImpl : public TestTime {
  public:
   explicit TestTimeImpl(TestTimeRequest request)
       : binding_(this, std::move(request)) {}
 
   // TestTime implementation:
-  void BounceTime(base::Time in, const BounceTimeCallback& callback) override {
+  void BounceTime(const base::Time& in,
+                  const BounceTimeCallback& callback) override {
     callback.Run(in);
   }
 
-  void BounceTimeDelta(base::TimeDelta in,
-                       const BounceTimeDeltaCallback& callback) override {
+  void BounceTimeDelta(const base::TimeDelta& in,
+                  const BounceTimeDeltaCallback& callback) override {
     callback.Run(in);
   }
 
-  void BounceTimeTicks(base::TimeTicks in,
-                       const BounceTimeTicksCallback& callback) override {
+  void BounceTimeTicks(const base::TimeTicks& in,
+                  const BounceTimeTicksCallback& callback) override {
     callback.Run(in);
   }
 
@@ -122,70 +100,19 @@
 
   // TestValue implementation:
   void BounceDictionaryValue(
-      std::unique_ptr<base::DictionaryValue> in,
+      const base::DictionaryValue& in,
       const BounceDictionaryValueCallback& callback) override {
-    callback.Run(std::move(in));
+    callback.Run(in);
   }
-
-  void BounceListValue(std::unique_ptr<base::ListValue> in,
+  void BounceListValue(const base::ListValue& in,
                        const BounceListValueCallback& callback) override {
-    callback.Run(std::move(in));
-  }
-
-  void BounceValue(std::unique_ptr<base::Value> in,
-                   const BounceValueCallback& callback) override {
-    callback.Run(std::move(in));
+    callback.Run(in);
   }
 
  private:
   mojo::Binding<TestValue> binding_;
 };
 
-class TestString16Impl : public TestString16 {
- public:
-  explicit TestString16Impl(TestString16Request request)
-      : binding_(this, std::move(request)) {}
-
-  // TestString16 implementation:
-  void BounceString16(const base::string16& in,
-                      const BounceString16Callback& callback) override {
-    callback.Run(in);
-  }
-
- private:
-  mojo::Binding<TestString16> binding_;
-};
-
-class TestFileImpl : public TestFile {
- public:
-  explicit TestFileImpl(TestFileRequest request)
-      : binding_(this, std::move(request)) {}
-
-  // TestFile implementation:
-  void BounceFile(base::File in, const BounceFileCallback& callback) override {
-    callback.Run(std::move(in));
-  }
-
- private:
-  mojo::Binding<TestFile> binding_;
-};
-
-class TestTextDirectionImpl : public TestTextDirection {
- public:
-  explicit TestTextDirectionImpl(TestTextDirectionRequest request)
-      : binding_(this, std::move(request)) {}
-
-  // TestTextDirection:
-  void BounceTextDirection(
-      base::i18n::TextDirection in,
-      const BounceTextDirectionCallback& callback) override {
-    callback.Run(in);
-  }
-
- private:
-  mojo::Binding<TestTextDirection> binding_;
-};
-
 class CommonCustomTypesTest : public testing::Test {
  protected:
   CommonCustomTypesTest() {}
@@ -203,7 +130,7 @@
   base::RunLoop run_loop;
 
   TestFilePathPtr ptr;
-  TestFilePathImpl impl(MakeRequest(&ptr));
+  TestFilePathImpl impl(GetProxy(&ptr));
 
   base::FilePath dir(FILE_PATH_LITERAL("hello"));
   base::FilePath file = dir.Append(FILE_PATH_LITERAL("world"));
@@ -213,24 +140,11 @@
   run_loop.Run();
 }
 
-TEST_F(CommonCustomTypesTest, UnguessableToken) {
-  base::RunLoop run_loop;
-
-  TestUnguessableTokenPtr ptr;
-  TestUnguessableTokenImpl impl(MakeRequest(&ptr));
-
-  base::UnguessableToken token = base::UnguessableToken::Create();
-
-  ptr->BounceNonce(token, ExpectResponse(&token, run_loop.QuitClosure()));
-
-  run_loop.Run();
-}
-
 TEST_F(CommonCustomTypesTest, Time) {
   base::RunLoop run_loop;
 
   TestTimePtr ptr;
-  TestTimeImpl impl(MakeRequest(&ptr));
+  TestTimeImpl impl(GetProxy(&ptr));
 
   base::Time t = base::Time::Now();
 
@@ -243,7 +157,7 @@
   base::RunLoop run_loop;
 
   TestTimePtr ptr;
-  TestTimeImpl impl(MakeRequest(&ptr));
+  TestTimeImpl impl(GetProxy(&ptr));
 
   base::TimeDelta t = base::TimeDelta::FromDays(123);
 
@@ -256,7 +170,7 @@
   base::RunLoop run_loop;
 
   TestTimePtr ptr;
-  TestTimeImpl impl(MakeRequest(&ptr));
+  TestTimeImpl impl(GetProxy(&ptr));
 
   base::TimeTicks t = base::TimeTicks::Now();
 
@@ -267,164 +181,43 @@
 
 TEST_F(CommonCustomTypesTest, Value) {
   TestValuePtr ptr;
-  TestValueImpl impl(MakeRequest(&ptr));
+  TestValueImpl impl(GetProxy(&ptr));
 
-  std::unique_ptr<base::Value> output;
-
-  ASSERT_TRUE(ptr->BounceValue(nullptr, &output));
-  EXPECT_FALSE(output);
-
-  std::unique_ptr<base::Value> input = base::Value::CreateNullValue();
-  ASSERT_TRUE(ptr->BounceValue(input->CreateDeepCopy(), &output));
-  EXPECT_TRUE(base::Value::Equals(input.get(), output.get()));
-
-  input = base::MakeUnique<base::Value>(123);
-  ASSERT_TRUE(ptr->BounceValue(input->CreateDeepCopy(), &output));
-  EXPECT_TRUE(base::Value::Equals(input.get(), output.get()));
-
-  input = base::MakeUnique<base::Value>(1.23);
-  ASSERT_TRUE(ptr->BounceValue(input->CreateDeepCopy(), &output));
-  EXPECT_TRUE(base::Value::Equals(input.get(), output.get()));
-
-  input = base::MakeUnique<base::Value>(false);
-  ASSERT_TRUE(ptr->BounceValue(input->CreateDeepCopy(), &output));
-  EXPECT_TRUE(base::Value::Equals(input.get(), output.get()));
-
-  input = base::MakeUnique<base::Value>("test string");
-  ASSERT_TRUE(ptr->BounceValue(input->CreateDeepCopy(), &output));
-  EXPECT_TRUE(base::Value::Equals(input.get(), output.get()));
-
-  input = base::BinaryValue::CreateWithCopiedBuffer("mojo", 4);
-  ASSERT_TRUE(ptr->BounceValue(input->CreateDeepCopy(), &output));
-  EXPECT_TRUE(base::Value::Equals(input.get(), output.get()));
-
-  auto dict = base::MakeUnique<base::DictionaryValue>();
-  dict->SetBoolean("bool", false);
-  dict->SetInteger("int", 2);
-  dict->SetString("string", "some string");
-  dict->SetBoolean("nested.bool", true);
-  dict->SetInteger("nested.int", 9);
-  dict->Set("some_binary",
-            base::BinaryValue::CreateWithCopiedBuffer("mojo", 4));
-  dict->Set("null_value", base::Value::CreateNullValue());
-  dict->SetIntegerWithoutPathExpansion("non_nested.int", 10);
+  base::DictionaryValue dict;
+  dict.SetBoolean("bool", false);
+  dict.SetInteger("int", 2);
+  dict.SetString("string", "some string");
+  dict.SetBoolean("nested.bool", true);
+  dict.SetInteger("nested.int", 9);
+  dict.Set("some_binary", base::BinaryValue::CreateWithCopiedBuffer("mojo", 4));
   {
     std::unique_ptr<base::ListValue> dict_list(new base::ListValue());
     dict_list->AppendString("string");
     dict_list->AppendBoolean(true);
-    dict->Set("list", std::move(dict_list));
+    dict.Set("list", std::move(dict_list));
+  }
+  {
+    base::RunLoop run_loop;
+    ptr->BounceDictionaryValue(
+        dict, ExpectResponse(&dict, run_loop.QuitClosure()));
+    run_loop.Run();
   }
 
-  std::unique_ptr<base::DictionaryValue> dict_output;
-  ASSERT_TRUE(ptr->BounceDictionaryValue(dict->CreateDeepCopy(), &dict_output));
-  EXPECT_TRUE(base::Value::Equals(dict.get(), dict_output.get()));
-
-  input = std::move(dict);
-  ASSERT_TRUE(ptr->BounceValue(input->CreateDeepCopy(), &output));
-  EXPECT_TRUE(base::Value::Equals(input.get(), output.get()));
-
-  auto list = base::MakeUnique<base::ListValue>();
-  list->AppendString("string");
-  list->AppendDouble(42.1);
-  list->AppendBoolean(true);
-  list->Append(base::BinaryValue::CreateWithCopiedBuffer("mojo", 4));
-  list->Append(base::Value::CreateNullValue());
+  base::ListValue list;
+  list.AppendString("string");
+  list.AppendDouble(42.1);
+  list.AppendBoolean(true);
+  list.Append(base::BinaryValue::CreateWithCopiedBuffer("mojo", 4));
   {
     std::unique_ptr<base::DictionaryValue> list_dict(
         new base::DictionaryValue());
     list_dict->SetString("string", "str");
-    list->Append(std::move(list_dict));
+    list.Append(std::move(list_dict));
   }
-  std::unique_ptr<base::ListValue> list_output;
-  ASSERT_TRUE(ptr->BounceListValue(list->CreateDeepCopy(), &list_output));
-  EXPECT_TRUE(base::Value::Equals(list.get(), list_output.get()));
-
-  input = std::move(list);
-  ASSERT_TRUE(ptr->BounceValue(input->CreateDeepCopy(), &output));
-  ASSERT_TRUE(base::Value::Equals(input.get(), output.get()));
-}
-
-TEST_F(CommonCustomTypesTest, String16) {
-  base::RunLoop run_loop;
-
-  TestString16Ptr ptr;
-  TestString16Impl impl(MakeRequest(&ptr));
-
-  base::string16 str16 = base::ASCIIToUTF16("hello world");
-
-  ptr->BounceString16(str16, ExpectResponse(&str16, run_loop.QuitClosure()));
-
-  run_loop.Run();
-}
-
-TEST_F(CommonCustomTypesTest, EmptyString16) {
-  base::RunLoop run_loop;
-
-  TestString16Ptr ptr;
-  TestString16Impl impl(MakeRequest(&ptr));
-
-  base::string16 str16;
-
-  ptr->BounceString16(str16, ExpectResponse(&str16, run_loop.QuitClosure()));
-
-  run_loop.Run();
-}
-
-TEST_F(CommonCustomTypesTest, File) {
-  base::ScopedTempDir temp_dir;
-  ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
-
-  TestFilePtr ptr;
-  TestFileImpl impl(MakeRequest(&ptr));
-
-  base::File file(
-      temp_dir.GetPath().AppendASCII("test_file.txt"),
-      base::File::FLAG_CREATE | base::File::FLAG_WRITE | base::File::FLAG_READ);
-  const base::StringPiece test_content =
-      "A test string to be stored in a test file";
-  file.WriteAtCurrentPos(
-      test_content.data(),
-      base::CheckedNumeric<int>(test_content.size()).ValueOrDie());
-
-  base::File file_out;
-  ASSERT_TRUE(ptr->BounceFile(std::move(file), &file_out));
-  std::vector<char> content(test_content.size());
-  ASSERT_TRUE(file_out.IsValid());
-  ASSERT_EQ(static_cast<int>(test_content.size()),
-            file_out.Read(
-                0, content.data(),
-                base::CheckedNumeric<int>(test_content.size()).ValueOrDie()));
-  EXPECT_EQ(test_content,
-            base::StringPiece(content.data(), test_content.size()));
-}
-
-TEST_F(CommonCustomTypesTest, InvalidFile) {
-  TestFilePtr ptr;
-  TestFileImpl impl(MakeRequest(&ptr));
-
-  base::ScopedTempDir temp_dir;
-  ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
-  // Test that |file_out| is set to an invalid file.
-  base::File file_out(
-      temp_dir.GetPath().AppendASCII("test_file.txt"),
-      base::File::FLAG_CREATE | base::File::FLAG_WRITE | base::File::FLAG_READ);
-
-  ASSERT_TRUE(ptr->BounceFile(base::File(), &file_out));
-  EXPECT_FALSE(file_out.IsValid());
-}
-
-TEST_F(CommonCustomTypesTest, TextDirection) {
-  base::i18n::TextDirection kTestDirections[] = {base::i18n::LEFT_TO_RIGHT,
-                                                 base::i18n::RIGHT_TO_LEFT,
-                                                 base::i18n::UNKNOWN_DIRECTION};
-
-  TestTextDirectionPtr ptr;
-  TestTextDirectionImpl impl(MakeRequest(&ptr));
-
-  for (size_t i = 0; i < arraysize(kTestDirections); i++) {
-    base::i18n::TextDirection direction_out;
-    ASSERT_TRUE(ptr->BounceTextDirection(kTestDirections[i], &direction_out));
-    EXPECT_EQ(kTestDirections[i], direction_out);
+  {
+    base::RunLoop run_loop;
+    ptr->BounceListValue(list, ExpectResponse(&list, run_loop.QuitClosure()));
+    run_loop.Run();
   }
 }
 
diff --git a/mojo/common/common_type_converters.cc b/mojo/common/common_type_converters.cc
new file mode 100644
index 0000000..92ae3e2
--- /dev/null
+++ b/mojo/common/common_type_converters.cc
@@ -0,0 +1,84 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "mojo/common/common_type_converters.h"
+
+#include <stdint.h>
+
+#include <string>
+
+#include "base/strings/utf_string_conversions.h"
+
+namespace mojo {
+
+// static
+String TypeConverter<String, base::StringPiece>::Convert(
+    const base::StringPiece& input) {
+  if (input.empty()) {
+    char c = 0;
+    return String(&c, 0);
+  }
+  return String(input.data(), input.size());
+}
+// static
+base::StringPiece TypeConverter<base::StringPiece, String>::Convert(
+    const String& input) {
+  return input.get();
+}
+
+// static
+String TypeConverter<String, base::string16>::Convert(
+    const base::string16& input) {
+  return TypeConverter<String, base::StringPiece>::Convert(
+      base::UTF16ToUTF8(input));
+}
+// static
+base::string16 TypeConverter<base::string16, String>::Convert(
+    const String& input) {
+  return base::UTF8ToUTF16(input.To<base::StringPiece>());
+}
+
+std::string TypeConverter<std::string, Array<uint8_t>>::Convert(
+    const Array<uint8_t>& input) {
+  if (input.is_null() || input.empty())
+    return std::string();
+
+  return std::string(reinterpret_cast<const char*>(&input.front()),
+                     input.size());
+}
+
+Array<uint8_t> TypeConverter<Array<uint8_t>, std::string>::Convert(
+    const std::string& input) {
+  Array<uint8_t> result(input.size());
+  if (!input.empty())
+    memcpy(&result.front(), input.c_str(), input.size());
+  return result;
+}
+
+Array<uint8_t> TypeConverter<Array<uint8_t>, base::StringPiece>::Convert(
+    const base::StringPiece& input) {
+  Array<uint8_t> result(input.size());
+  if (!input.empty())
+    memcpy(&result.front(), input.data(), input.size());
+  return result;
+}
+
+base::string16 TypeConverter<base::string16, Array<uint8_t>>::Convert(
+    const Array<uint8_t>& input) {
+  if (input.is_null() || input.empty())
+    return base::string16();
+
+  return base::string16(reinterpret_cast<const base::char16*>(&input.front()),
+                        input.size() / sizeof(base::char16));
+}
+
+Array<uint8_t> TypeConverter<Array<uint8_t>, base::string16>::Convert(
+    const base::string16& input) {
+  Array<uint8_t> result(input.size() * sizeof(base::char16));
+  if (!input.empty())
+    memcpy(&result.front(), input.c_str(), input.size() * sizeof(base::char16));
+  return result;
+}
+
+}  // namespace mojo
diff --git a/mojo/common/common_type_converters.h b/mojo/common/common_type_converters.h
new file mode 100644
index 0000000..a065f05
--- /dev/null
+++ b/mojo/common/common_type_converters.h
@@ -0,0 +1,66 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef MOJO_COMMON_COMMON_TYPE_CONVERTERS_H_
+#define MOJO_COMMON_COMMON_TYPE_CONVERTERS_H_
+
+#include <stdint.h>
+
+#include "base/strings/string16.h"
+#include "base/strings/string_piece.h"
+#include "mojo/common/mojo_common_export.h"
+#include "mojo/public/cpp/bindings/array.h"
+#include "mojo/public/cpp/bindings/string.h"
+#include "mojo/public/cpp/bindings/type_converter.h"
+
+namespace mojo {
+
+template <>
+struct MOJO_COMMON_EXPORT TypeConverter<String, base::StringPiece> {
+  static String Convert(const base::StringPiece& input);
+};
+
+template <>
+struct MOJO_COMMON_EXPORT TypeConverter<base::StringPiece, String> {
+  static base::StringPiece Convert(const String& input);
+};
+
+template <>
+struct MOJO_COMMON_EXPORT TypeConverter<String, base::string16> {
+  static String Convert(const base::string16& input);
+};
+
+template <>
+struct MOJO_COMMON_EXPORT TypeConverter<base::string16, String> {
+  static base::string16 Convert(const String& input);
+};
+
+template <>
+struct MOJO_COMMON_EXPORT TypeConverter<std::string, Array<uint8_t>> {
+  static std::string Convert(const Array<uint8_t>& input);
+};
+
+template <>
+struct MOJO_COMMON_EXPORT TypeConverter<Array<uint8_t>, std::string> {
+  static Array<uint8_t> Convert(const std::string& input);
+};
+
+template <>
+struct MOJO_COMMON_EXPORT TypeConverter<Array<uint8_t>, base::StringPiece> {
+  static Array<uint8_t> Convert(const base::StringPiece& input);
+};
+
+template <>
+struct MOJO_COMMON_EXPORT TypeConverter<base::string16, Array<uint8_t>> {
+  static base::string16 Convert(const Array<uint8_t>& input);
+};
+
+template <>
+struct MOJO_COMMON_EXPORT TypeConverter<Array<uint8_t>, base::string16> {
+  static Array<uint8_t> Convert(const base::string16& input);
+};
+
+}  // namespace mojo
+
+#endif  // MOJO_COMMON_COMMON_TYPE_CONVERTERS_H_
diff --git a/mojo/common/common_type_converters_unittest.cc b/mojo/common/common_type_converters_unittest.cc
new file mode 100644
index 0000000..1740d06
--- /dev/null
+++ b/mojo/common/common_type_converters_unittest.cc
@@ -0,0 +1,130 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "mojo/common/common_type_converters.h"
+
+#include <stdint.h>
+
+#include "base/strings/utf_string_conversions.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "url/gurl.h"
+
+namespace mojo {
+namespace common {
+namespace test {
+namespace {
+
+void ExpectEqualsStringPiece(const std::string& expected,
+                             const base::StringPiece& str) {
+  EXPECT_EQ(expected, str.as_string());
+}
+
+void ExpectEqualsMojoString(const std::string& expected,
+                            const String& str) {
+  EXPECT_EQ(expected, str.get());
+}
+
+void ExpectEqualsString16(const base::string16& expected,
+                          const base::string16& actual) {
+  EXPECT_EQ(expected, actual);
+}
+
+void ExpectEqualsMojoString(const base::string16& expected,
+                            const String& str) {
+  EXPECT_EQ(expected, str.To<base::string16>());
+}
+
+}  // namespace
+
+TEST(CommonTypeConvertersTest, StringPiece) {
+  std::string kText("hello world");
+
+  base::StringPiece string_piece(kText);
+  String mojo_string(String::From(string_piece));
+
+  ExpectEqualsMojoString(kText, mojo_string);
+  ExpectEqualsStringPiece(kText, mojo_string.To<base::StringPiece>());
+
+  // Test implicit construction and conversion:
+  ExpectEqualsMojoString(kText, String::From(string_piece));
+  ExpectEqualsStringPiece(kText, mojo_string.To<base::StringPiece>());
+
+  // Test null String:
+  base::StringPiece empty_string_piece = String().To<base::StringPiece>();
+  EXPECT_TRUE(empty_string_piece.empty());
+}
+
+TEST(CommonTypeConvertersTest, String16) {
+  const base::string16 string16(base::ASCIIToUTF16("hello world"));
+  const String mojo_string(String::From(string16));
+
+  ExpectEqualsMojoString(string16, mojo_string);
+  EXPECT_EQ(string16, mojo_string.To<base::string16>());
+
+  // Test implicit construction and conversion:
+  ExpectEqualsMojoString(string16, String::From(string16));
+  ExpectEqualsString16(string16, mojo_string.To<base::string16>());
+
+  // Test empty string conversion.
+  ExpectEqualsMojoString(base::string16(), String::From(base::string16()));
+}
+
+TEST(CommonTypeConvertersTest, ArrayUint8ToStdString) {
+  Array<uint8_t> data(4);
+  data[0] = 'd';
+  data[1] = 'a';
+  data[2] = 't';
+  data[3] = 'a';
+
+  EXPECT_EQ("data", data.To<std::string>());
+}
+
+TEST(CommonTypeConvertersTest, StdStringToArrayUint8) {
+  std::string input("data");
+  Array<uint8_t> data = Array<uint8_t>::From(input);
+
+  ASSERT_EQ(4ul, data.size());
+  EXPECT_EQ('d', data[0]);
+  EXPECT_EQ('a', data[1]);
+  EXPECT_EQ('t', data[2]);
+  EXPECT_EQ('a', data[3]);
+}
+
+TEST(CommonTypeConvertersTest, ArrayUint8ToString16) {
+  Array<uint8_t> data(8);
+  data[0] = 'd';
+  data[2] = 'a';
+  data[4] = 't';
+  data[6] = 'a';
+
+  EXPECT_EQ(base::ASCIIToUTF16("data"), data.To<base::string16>());
+}
+
+TEST(CommonTypeConvertersTest, String16ToArrayUint8) {
+  base::string16 input(base::ASCIIToUTF16("data"));
+  Array<uint8_t> data = Array<uint8_t>::From(input);
+
+  ASSERT_EQ(8ul, data.size());
+  EXPECT_EQ('d', data[0]);
+  EXPECT_EQ('a', data[2]);
+  EXPECT_EQ('t', data[4]);
+  EXPECT_EQ('a', data[6]);
+}
+
+TEST(CommonTypeConvertersTest, String16ToArrayUint8AndBack) {
+  base::string16 input(base::ASCIIToUTF16("data"));
+  Array<uint8_t> data = Array<uint8_t>::From(input);
+  EXPECT_EQ(input, data.To<base::string16>());
+}
+
+TEST(CommonTypeConvertersTest, EmptyStringToArrayUint8) {
+  Array<uint8_t> data = Array<uint8_t>::From(std::string());
+
+  ASSERT_EQ(0ul, data.size());
+  EXPECT_FALSE(data.is_null());
+}
+
+}  // namespace test
+}  // namespace common
+}  // namespace mojo
diff --git a/mojo/common/data_pipe_drainer.cc b/mojo/common/data_pipe_drainer.cc
index 27bd893..1133e11 100644
--- a/mojo/common/data_pipe_drainer.cc
+++ b/mojo/common/data_pipe_drainer.cc
@@ -15,10 +15,7 @@
 
 DataPipeDrainer::DataPipeDrainer(Client* client,
                                  mojo::ScopedDataPipeConsumerHandle source)
-    : client_(client),
-      source_(std::move(source)),
-      handle_watcher_(FROM_HERE),
-      weak_factory_(this) {
+    : client_(client), source_(std::move(source)), weak_factory_(this) {
   DCHECK(client_);
   handle_watcher_.Start(
       source_.get(), MOJO_HANDLE_SIGNAL_READABLE,
diff --git a/mojo/common/data_pipe_file_utils.cc b/mojo/common/data_pipe_file_utils.cc
new file mode 100644
index 0000000..841dfde
--- /dev/null
+++ b/mojo/common/data_pipe_file_utils.cc
@@ -0,0 +1,81 @@
+// 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/common/data_pipe_utils.h"
+
+#include <stdint.h>
+
+#include "base/files/file_path.h"
+#include "base/files/file_util.h"
+#include "base/files/scoped_file.h"
+#include "base/location.h"
+#include "base/task_runner_util.h"
+
+namespace mojo {
+namespace common {
+namespace {
+
+bool BlockingCopyFromFile(const base::FilePath& source,
+                          ScopedDataPipeProducerHandle destination,
+                          uint32_t skip) {
+  base::File file(source, base::File::FLAG_OPEN | base::File::FLAG_READ);
+  if (!file.IsValid())
+    return false;
+  if (file.Seek(base::File::FROM_BEGIN, skip) != skip) {
+    LOG(ERROR) << "Seek of " << skip << " in " << source.value() << " failed";
+    return false;
+  }
+  for (;;) {
+    void* buffer = nullptr;
+    uint32_t buffer_num_bytes = 0;
+    MojoResult result =
+        BeginWriteDataRaw(destination.get(), &buffer, &buffer_num_bytes,
+                          MOJO_WRITE_DATA_FLAG_NONE);
+    if (result == MOJO_RESULT_OK) {
+      int bytes_read =
+          file.ReadAtCurrentPos(static_cast<char*>(buffer), buffer_num_bytes);
+      if (bytes_read >= 0) {
+        EndWriteDataRaw(destination.get(), bytes_read);
+        if (bytes_read == 0) {
+          // eof
+          return true;
+        }
+      } else {
+        // error
+        EndWriteDataRaw(destination.get(), 0);
+        return false;
+      }
+    } else if (result == MOJO_RESULT_SHOULD_WAIT) {
+      result = Wait(destination.get(), MOJO_HANDLE_SIGNAL_WRITABLE,
+                    MOJO_DEADLINE_INDEFINITE, nullptr);
+      if (result != MOJO_RESULT_OK) {
+        // If the consumer handle was closed, then treat as EOF.
+        return result == MOJO_RESULT_FAILED_PRECONDITION;
+      }
+    } else {
+      // If the consumer handle was closed, then treat as EOF.
+      return result == MOJO_RESULT_FAILED_PRECONDITION;
+    }
+  }
+#if !defined(OS_WIN)
+  NOTREACHED();
+  return false;
+#endif
+}
+
+}  // namespace
+
+void CopyFromFile(const base::FilePath& source,
+                  ScopedDataPipeProducerHandle destination,
+                  uint32_t skip,
+                  base::TaskRunner* task_runner,
+                  const base::Callback<void(bool)>& callback) {
+  base::PostTaskAndReplyWithResult(task_runner, FROM_HERE,
+                                   base::Bind(&BlockingCopyFromFile, source,
+                                              base::Passed(&destination), skip),
+                                   callback);
+}
+
+}  // namespace common
+}  // namespace mojo
diff --git a/mojo/common/data_pipe_utils.cc b/mojo/common/data_pipe_utils.cc
index bed5e85..8540ac6 100644
--- a/mojo/common/data_pipe_utils.cc
+++ b/mojo/common/data_pipe_utils.cc
@@ -4,9 +4,16 @@
 
 #include "mojo/common/data_pipe_utils.h"
 
+#include <stddef.h>
+#include <stdint.h>
+#include <stdio.h>
 #include <utility>
 
-#include "base/bind.h"
+#include "base/files/file_path.h"
+#include "base/files/file_util.h"
+#include "base/files/scoped_file.h"
+#include "base/message_loop/message_loop.h"
+#include "base/task_runner_util.h"
 
 namespace mojo {
 namespace common {
@@ -51,7 +58,12 @@
   return num_bytes;
 }
 
-}  // namespace
+size_t CopyToFileHelper(FILE* fp, const void* buffer, uint32_t num_bytes) {
+  return fwrite(buffer, 1, num_bytes, fp);
+}
+
+} // namespace
+
 
 // TODO(hansmuller): Add a max_size parameter.
 bool BlockingCopyToString(ScopedDataPipeConsumerHandle source,
@@ -95,5 +107,25 @@
   }
 }
 
+bool BlockingCopyToFile(ScopedDataPipeConsumerHandle source,
+                        const base::FilePath& destination) {
+  base::ScopedFILE fp(base::OpenFile(destination, "wb"));
+  if (!fp)
+    return false;
+  return BlockingCopyHelper(std::move(source),
+                            base::Bind(&CopyToFileHelper, fp.get()));
+}
+
+void CopyToFile(ScopedDataPipeConsumerHandle source,
+                const base::FilePath& destination,
+                base::TaskRunner* task_runner,
+                const base::Callback<void(bool)>& callback) {
+  base::PostTaskAndReplyWithResult(
+      task_runner,
+      FROM_HERE,
+      base::Bind(&BlockingCopyToFile, base::Passed(&source), destination),
+      callback);
+}
+
 }  // namespace common
 }  // namespace mojo
diff --git a/mojo/common/data_pipe_utils.h b/mojo/common/data_pipe_utils.h
index a3f7c09..426912c 100644
--- a/mojo/common/data_pipe_utils.h
+++ b/mojo/common/data_pipe_utils.h
@@ -2,19 +2,41 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef MOJO_COMMON_DATA_PIPE_UTILS_H_
-#define MOJO_COMMON_DATA_PIPE_UTILS_H_
+#ifndef MOJO_SHELL_DATA_PIPE_UTILS_H_
+#define MOJO_SHELL_DATA_PIPE_UTILS_H_
 
 #include <stdint.h>
 
 #include <string>
 
+#include "base/callback_forward.h"
 #include "mojo/common/mojo_common_export.h"
-#include "mojo/public/cpp/system/data_pipe.h"
+#include "mojo/public/cpp/system/core.h"
+
+namespace base {
+class FilePath;
+class TaskRunner;
+}
 
 namespace mojo {
 namespace common {
 
+// Asynchronously copies data from source to the destination file. The given
+// |callback| is run upon completion. File writes will be scheduled to the
+// given |task_runner|.
+void MOJO_COMMON_EXPORT CopyToFile(
+    ScopedDataPipeConsumerHandle source,
+    const base::FilePath& destination,
+    base::TaskRunner* task_runner,
+    const base::Callback<void(bool /*success*/)>& callback);
+
+void MOJO_COMMON_EXPORT
+CopyFromFile(const base::FilePath& source,
+             ScopedDataPipeProducerHandle destination,
+             uint32_t skip,
+             base::TaskRunner* task_runner,
+             const base::Callback<void(bool /*success*/)>& callback);
+
 // Copies the data from |source| into |contents| and returns true on success and
 // false on error.  In case of I/O error, |contents| holds the data that could
 // be read from source before the error occurred.
@@ -26,7 +48,13 @@
     const std::string& source,
     const ScopedDataPipeProducerHandle& destination);
 
+// Synchronously copies data from source to the destination file returning true
+// on success and false on error.  In case of an error, |destination| holds the
+// data that could be read from the source before the error occured.
+bool MOJO_COMMON_EXPORT BlockingCopyToFile(ScopedDataPipeConsumerHandle source,
+                                           const base::FilePath& destination);
+
 }  // namespace common
 }  // namespace mojo
 
-#endif  // MOJO_COMMON_DATA_PIPE_UTILS_H_
+#endif  // MOJO_SHELL_DATA_PIPE_UTILS_H_
diff --git a/mojo/common/file.mojom b/mojo/common/file.mojom
deleted file mode 100644
index fe22473..0000000
--- a/mojo/common/file.mojom
+++ /dev/null
@@ -1,10 +0,0 @@
-// Copyright 2016 The Chromium 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.common.mojom;
-
-// Corresponds to |base::File| in base/files/file.h
-struct File {
-  handle fd;
-};
diff --git a/mojo/common/file.typemap b/mojo/common/file.typemap
deleted file mode 100644
index 26d4941..0000000
--- a/mojo/common/file.typemap
+++ /dev/null
@@ -1,13 +0,0 @@
-# Copyright 2016 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-mojom = "//mojo/common/file.mojom"
-public_headers = [ "//base/files/file.h" ]
-traits_headers = [ "//mojo/common/common_custom_types_struct_traits.h" ]
-public_deps = [
-  "//mojo/common:struct_traits",
-]
-
-type_mappings =
-    [ "mojo.common.mojom.File=base::File[move_only,nullable_is_same_type]" ]
diff --git a/mojo/common/string16.mojom b/mojo/common/string16.mojom
index 173c867..eb1ace2 100644
--- a/mojo/common/string16.mojom
+++ b/mojo/common/string16.mojom
@@ -10,3 +10,4 @@
 struct String16 {
   array<uint16> data;
 };
+
diff --git a/mojo/common/string16.typemap b/mojo/common/string16.typemap
deleted file mode 100644
index 223de29..0000000
--- a/mojo/common/string16.typemap
+++ /dev/null
@@ -1,12 +0,0 @@
-# Copyright 2016 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-mojom = "//mojo/common/string16.mojom"
-public_headers = [ "//base/strings/string16.h" ]
-traits_headers = [ "//mojo/common/common_custom_types_struct_traits.h" ]
-public_deps = [
-  "//mojo/common:struct_traits",
-]
-
-type_mappings = [ "mojo.common.mojom.String16=base::string16" ]
diff --git a/mojo/common/test_common_custom_types.mojom b/mojo/common/test_common_custom_types.mojom
index 0f13680..db91a4f 100644
--- a/mojo/common/test_common_custom_types.mojom
+++ b/mojo/common/test_common_custom_types.mojom
@@ -4,24 +4,13 @@
 
 module mojo.common.test;
 
-import "mojo/common/file.mojom";
-import "mojo/common/file_path.mojom";
-import "mojo/common/string16.mojom";
-import "mojo/common/text_direction.mojom";
-import "mojo/common/time.mojom";
-import "mojo/common/unguessable_token.mojom";
-import "mojo/common/values.mojom";
+import "mojo/common/common_custom_types.mojom";
 
 interface TestFilePath {
   BounceFilePath(mojo.common.mojom.FilePath in)
       => (mojo.common.mojom.FilePath out);
 };
 
-interface TestUnguessableToken {
-  BounceNonce(mojo.common.mojom.UnguessableToken in)
-      => (mojo.common.mojom.UnguessableToken out);
-};
-
 interface TestTime {
   BounceTime(mojo.common.mojom.Time time) => (mojo.common.mojom.Time time);
   BounceTimeDelta(mojo.common.mojom.TimeDelta time_delta)
@@ -31,31 +20,8 @@
 };
 
 interface TestValue {
-  [Sync]
   BounceDictionaryValue(mojo.common.mojom.DictionaryValue in)
       => (mojo.common.mojom.DictionaryValue out);
-  [Sync]
   BounceListValue(mojo.common.mojom.ListValue in)
       => (mojo.common.mojom.ListValue out);
-  [Sync]
-  BounceValue(mojo.common.mojom.Value? in)
-      => (mojo.common.mojom.Value? out);
-};
-
-interface TestString16 {
-  [Sync]
-  BounceString16(mojo.common.mojom.String16 in)
-      => (mojo.common.mojom.String16 out);
-};
-
-interface TestFile {
-  [Sync]
-  BounceFile(mojo.common.mojom.File? in)
-      => (mojo.common.mojom.File? out);
-};
-
-interface TestTextDirection {
-  [Sync]
-  BounceTextDirection(mojo.common.mojom.TextDirection in)
-      => (mojo.common.mojom.TextDirection out);
 };
diff --git a/mojo/common/text_direction.mojom b/mojo/common/text_direction.mojom
deleted file mode 100644
index 7d65124..0000000
--- a/mojo/common/text_direction.mojom
+++ /dev/null
@@ -1,12 +0,0 @@
-// Copyright 2017 The Chromium 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.common.mojom;
-
-// Corresponds to |base::i18n::TextDirection| in base/i18n/rtl.h
-enum TextDirection {	
-  UNKNOWN_DIRECTION,	
-  RIGHT_TO_LEFT,	
-  LEFT_TO_RIGHT	
-};	
diff --git a/mojo/common/text_direction.typemap b/mojo/common/text_direction.typemap
deleted file mode 100644
index 1f5be8e..0000000
--- a/mojo/common/text_direction.typemap
+++ /dev/null
@@ -1,12 +0,0 @@
-# Copyright 2017 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-mojom = "//mojo/common/text_direction.mojom"
-public_headers = [ "//base/i18n/rtl.h" ]
-traits_headers = [ "//mojo/common/common_custom_types_struct_traits.h" ]
-public_deps = [
-  "//base:i18n",
-  "//mojo/common:struct_traits",
-]
-type_mappings = [ "mojo.common.mojom.TextDirection=base::i18n::TextDirection" ]
diff --git a/mojo/common/time.typemap b/mojo/common/time.typemap
deleted file mode 100644
index 99e9e3a..0000000
--- a/mojo/common/time.typemap
+++ /dev/null
@@ -1,20 +0,0 @@
-# Copyright 2016 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-mojom = "//mojo/common/time.mojom"
-public_headers = [ "//base/time/time.h" ]
-traits_headers = [
-  "//ipc/ipc_message_utils.h",
-  "//mojo/common/common_custom_types_struct_traits.h",
-]
-public_deps = [
-  "//ipc",
-  "//mojo/common:struct_traits",
-]
-
-type_mappings = [
-  "mojo.common.mojom.Time=base::Time[copyable_pass_by_value]",
-  "mojo.common.mojom.TimeDelta=base::TimeDelta[copyable_pass_by_value]",
-  "mojo.common.mojom.TimeTicks=base::TimeTicks[copyable_pass_by_value]",
-]
diff --git a/mojo/common/unguessable_token.mojom b/mojo/common/unguessable_token.mojom
deleted file mode 100644
index 3279717..0000000
--- a/mojo/common/unguessable_token.mojom
+++ /dev/null
@@ -1,11 +0,0 @@
-// Copyright 2016 The Chromium 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.common.mojom;
-
-// Corresponds to |base::UnguessableToken| in base/unguessable_token.h
-struct UnguessableToken {
-  uint64 high;
-  uint64 low;
-};
diff --git a/mojo/common/unguessable_token.typemap b/mojo/common/unguessable_token.typemap
deleted file mode 100644
index ec7b194..0000000
--- a/mojo/common/unguessable_token.typemap
+++ /dev/null
@@ -1,12 +0,0 @@
-# Copyright 2016 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-mojom = "//mojo/common/unguessable_token.mojom"
-public_headers = [ "//base/unguessable_token.h" ]
-traits_headers = [ "//mojo/common/common_custom_types_struct_traits.h" ]
-public_deps = [
-  "//mojo/common:struct_traits",
-]
-
-type_mappings = [ "mojo.common.mojom.UnguessableToken=base::UnguessableToken" ]
diff --git a/mojo/common/user_agent.cc b/mojo/common/user_agent.cc
new file mode 100644
index 0000000..6055cbe
--- /dev/null
+++ b/mojo/common/user_agent.cc
@@ -0,0 +1,25 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "mojo/common/user_agent.h"
+
+#include "build/build_config.h"
+
+namespace mojo {
+namespace common {
+
+std::string GetUserAgent() {
+  // TODO(jam): change depending on OS
+#if defined(OS_ANDROID)
+  return "Mozilla/5.0 (Linux; Android 5.1.1; Nexus 7 Build/LMY48G) "
+         "AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.68 "
+         "Safari/537.36";
+#else
+  return "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like "
+         "Gecko) Chrome/42.0.2311.68 Safari/537.36";
+#endif
+}
+
+}  // namespace common
+}  // namespace mojo
diff --git a/mojo/common/user_agent.h b/mojo/common/user_agent.h
new file mode 100644
index 0000000..031b102
--- /dev/null
+++ b/mojo/common/user_agent.h
@@ -0,0 +1,20 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef MOJO_COMMON_USER_AGENT_H_
+#define MOJO_COMMON_USER_AGENT_H_
+
+#include <string>
+
+#include "mojo/common/mojo_common_export.h"
+
+namespace mojo {
+namespace common {
+
+std::string MOJO_COMMON_EXPORT GetUserAgent();
+
+}  // namespace common
+}  // namespace mojo
+
+#endif  // MOJO_COMMON_USER_AGENT_H_
diff --git a/mojo/common/version.mojom b/mojo/common/version.mojom
deleted file mode 100644
index 6ddf6e6..0000000
--- a/mojo/common/version.mojom
+++ /dev/null
@@ -1,10 +0,0 @@
-// Copyright 2016 The Chromium 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.common.mojom;
-
-// Corresponds to |base::Version| in base/version.h
-struct Version {
-  array<uint32> components;
-};
diff --git a/mojo/common/version.typemap b/mojo/common/version.typemap
deleted file mode 100644
index fa7fed9..0000000
--- a/mojo/common/version.typemap
+++ /dev/null
@@ -1,12 +0,0 @@
-# Copyright 2016 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-mojom = "//mojo/common/version.mojom"
-public_headers = [ "//base/version.h" ]
-traits_headers = [ "//mojo/common/common_custom_types_struct_traits.h" ]
-public_deps = [
-  "//mojo/common:struct_traits",
-]
-
-type_mappings = [ "mojo.common.mojom.Version=base::Version" ]