diff --git a/ipc/ipc_message_utils.cc b/ipc/ipc_message_utils.cc
new file mode 100644
index 0000000..60c12ab
--- /dev/null
+++ b/ipc/ipc_message_utils.cc
@@ -0,0 +1,1220 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ipc/ipc_message_utils.h"
+
+#include <stddef.h>
+#include <stdint.h>
+
+#include "base/files/file_path.h"
+#include "base/json/json_writer.h"
+#include "base/strings/nullable_string16.h"
+#include "base/strings/string_number_conversions.h"
+#include "base/strings/utf_string_conversions.h"
+#include "base/time/time.h"
+#include "base/values.h"
+#include "build/build_config.h"
+#include "ipc/ipc_channel_handle.h"
+#include "ipc/ipc_message_attachment.h"
+#include "ipc/ipc_message_attachment_set.h"
+#include "ipc/ipc_mojo_param_traits.h"
+
+#if defined(OS_POSIX)
+#include "ipc/ipc_platform_file_attachment_posix.h"
+#endif
+
+#if (defined(OS_MACOSX) && !defined(OS_IOS)) || defined(OS_WIN)
+#include "base/memory/shared_memory_handle.h"
+#endif  // (defined(OS_MACOSX) && !defined(OS_IOS)) || defined(OS_WIN)
+
+#if defined(OS_MACOSX) && !defined(OS_IOS)
+#include "ipc/mach_port_mac.h"
+#endif
+
+#if defined(OS_WIN)
+#include <tchar.h>
+#include "ipc/handle_win.h"
+#endif
+
+namespace IPC {
+
+namespace {
+
+const int kMaxRecursionDepth = 100;
+
+template<typename CharType>
+void LogBytes(const std::vector<CharType>& data, std::string* out) {
+#if defined(OS_WIN)
+  // Windows has a GUI for logging, which can handle arbitrary binary data.
+  for (size_t i = 0; i < data.size(); ++i)
+    out->push_back(data[i]);
+#else
+  // On POSIX, we log to stdout, which we assume can display ASCII.
+  static const size_t kMaxBytesToLog = 100;
+  for (size_t i = 0; i < std::min(data.size(), kMaxBytesToLog); ++i) {
+    if (isprint(data[i]))
+      out->push_back(data[i]);
+    else
+      out->append(
+          base::StringPrintf("[%02X]", static_cast<unsigned char>(data[i])));
+  }
+  if (data.size() > kMaxBytesToLog) {
+    out->append(base::StringPrintf(
+        " and %u more bytes",
+        static_cast<unsigned>(data.size() - kMaxBytesToLog)));
+  }
+#endif
+}
+
+bool ReadValue(const base::Pickle* m,
+               base::PickleIterator* iter,
+               base::Value** value,
+               int recursion);
+
+void GetValueSize(base::PickleSizer* sizer,
+                  const base::Value* value,
+                  int recursion) {
+  if (recursion > kMaxRecursionDepth) {
+    LOG(WARNING) << "Max recursion depth hit in GetValueSize.";
+    return;
+  }
+
+  sizer->AddInt();
+  switch (value->GetType()) {
+    case base::Value::TYPE_NULL:
+      break;
+    case base::Value::TYPE_BOOLEAN:
+      sizer->AddBool();
+      break;
+    case base::Value::TYPE_INTEGER:
+      sizer->AddInt();
+      break;
+    case base::Value::TYPE_DOUBLE:
+      sizer->AddDouble();
+      break;
+    case base::Value::TYPE_STRING: {
+      const base::StringValue* result;
+      value->GetAsString(&result);
+      if (value->GetAsString(&result)) {
+        DCHECK(result);
+        GetParamSize(sizer, result->GetString());
+      } else {
+        std::string str;
+        bool as_string_result = value->GetAsString(&str);
+        DCHECK(as_string_result);
+        GetParamSize(sizer, str);
+      }
+      break;
+    }
+    case base::Value::TYPE_BINARY: {
+      const base::BinaryValue* binary =
+          static_cast<const base::BinaryValue*>(value);
+      sizer->AddData(static_cast<int>(binary->GetSize()));
+      break;
+    }
+    case base::Value::TYPE_DICTIONARY: {
+      sizer->AddInt();
+      const base::DictionaryValue* dict =
+          static_cast<const base::DictionaryValue*>(value);
+      for (base::DictionaryValue::Iterator it(*dict); !it.IsAtEnd();
+           it.Advance()) {
+        GetParamSize(sizer, it.key());
+        GetValueSize(sizer, &it.value(), recursion + 1);
+      }
+      break;
+    }
+    case base::Value::TYPE_LIST: {
+      sizer->AddInt();
+      const base::ListValue* list = static_cast<const base::ListValue*>(value);
+      for (const auto& entry : *list) {
+        GetValueSize(sizer, entry.get(), recursion + 1);
+      }
+      break;
+    }
+    default:
+      NOTREACHED() << "Invalid base::Value type.";
+  }
+}
+
+void WriteValue(base::Pickle* m, const base::Value* value, int recursion) {
+  bool result;
+  if (recursion > kMaxRecursionDepth) {
+    LOG(WARNING) << "Max recursion depth hit in WriteValue.";
+    return;
+  }
+
+  m->WriteInt(value->GetType());
+
+  switch (value->GetType()) {
+    case base::Value::TYPE_NULL:
+    break;
+    case base::Value::TYPE_BOOLEAN: {
+      bool val;
+      result = value->GetAsBoolean(&val);
+      DCHECK(result);
+      WriteParam(m, val);
+      break;
+    }
+    case base::Value::TYPE_INTEGER: {
+      int val;
+      result = value->GetAsInteger(&val);
+      DCHECK(result);
+      WriteParam(m, val);
+      break;
+    }
+    case base::Value::TYPE_DOUBLE: {
+      double val;
+      result = value->GetAsDouble(&val);
+      DCHECK(result);
+      WriteParam(m, val);
+      break;
+    }
+    case base::Value::TYPE_STRING: {
+      std::string val;
+      result = value->GetAsString(&val);
+      DCHECK(result);
+      WriteParam(m, val);
+      break;
+    }
+    case base::Value::TYPE_BINARY: {
+      const base::BinaryValue* binary =
+          static_cast<const base::BinaryValue*>(value);
+      m->WriteData(binary->GetBuffer(), static_cast<int>(binary->GetSize()));
+      break;
+    }
+    case base::Value::TYPE_DICTIONARY: {
+      const base::DictionaryValue* dict =
+          static_cast<const base::DictionaryValue*>(value);
+
+      WriteParam(m, static_cast<int>(dict->size()));
+
+      for (base::DictionaryValue::Iterator it(*dict); !it.IsAtEnd();
+           it.Advance()) {
+        WriteParam(m, it.key());
+        WriteValue(m, &it.value(), recursion + 1);
+      }
+      break;
+    }
+    case base::Value::TYPE_LIST: {
+      const base::ListValue* list = static_cast<const base::ListValue*>(value);
+      WriteParam(m, static_cast<int>(list->GetSize()));
+      for (const auto& entry : *list) {
+        WriteValue(m, entry.get(), recursion + 1);
+      }
+      break;
+    }
+  }
+}
+
+// Helper for ReadValue that reads a DictionaryValue into a pre-allocated
+// object.
+bool ReadDictionaryValue(const base::Pickle* m,
+                         base::PickleIterator* iter,
+                         base::DictionaryValue* value,
+                         int recursion) {
+  int size;
+  if (!ReadParam(m, iter, &size))
+    return false;
+
+  for (int i = 0; i < size; ++i) {
+    std::string key;
+    base::Value* subval;
+    if (!ReadParam(m, iter, &key) ||
+        !ReadValue(m, iter, &subval, recursion + 1))
+      return false;
+    value->SetWithoutPathExpansion(key, subval);
+  }
+
+  return true;
+}
+
+// Helper for ReadValue that reads a ReadListValue into a pre-allocated
+// object.
+bool ReadListValue(const base::Pickle* m,
+                   base::PickleIterator* iter,
+                   base::ListValue* value,
+                   int recursion) {
+  int size;
+  if (!ReadParam(m, iter, &size))
+    return false;
+
+  for (int i = 0; i < size; ++i) {
+    base::Value* subval;
+    if (!ReadValue(m, iter, &subval, recursion + 1))
+      return false;
+    value->Set(i, subval);
+  }
+
+  return true;
+}
+
+bool ReadValue(const base::Pickle* m,
+               base::PickleIterator* iter,
+               base::Value** value,
+               int recursion) {
+  if (recursion > kMaxRecursionDepth) {
+    LOG(WARNING) << "Max recursion depth hit in ReadValue.";
+    return false;
+  }
+
+  int type;
+  if (!ReadParam(m, iter, &type))
+    return false;
+
+  switch (type) {
+    case base::Value::TYPE_NULL:
+      *value = base::Value::CreateNullValue().release();
+    break;
+    case base::Value::TYPE_BOOLEAN: {
+      bool val;
+      if (!ReadParam(m, iter, &val))
+        return false;
+      *value = new base::FundamentalValue(val);
+      break;
+    }
+    case base::Value::TYPE_INTEGER: {
+      int val;
+      if (!ReadParam(m, iter, &val))
+        return false;
+      *value = new base::FundamentalValue(val);
+      break;
+    }
+    case base::Value::TYPE_DOUBLE: {
+      double val;
+      if (!ReadParam(m, iter, &val))
+        return false;
+      *value = new base::FundamentalValue(val);
+      break;
+    }
+    case base::Value::TYPE_STRING: {
+      std::string val;
+      if (!ReadParam(m, iter, &val))
+        return false;
+      *value = new base::StringValue(val);
+      break;
+    }
+    case base::Value::TYPE_BINARY: {
+      const char* data;
+      int length;
+      if (!iter->ReadData(&data, &length))
+        return false;
+      std::unique_ptr<base::BinaryValue> val =
+          base::BinaryValue::CreateWithCopiedBuffer(data, length);
+      *value = val.release();
+      break;
+    }
+    case base::Value::TYPE_DICTIONARY: {
+      std::unique_ptr<base::DictionaryValue> val(new base::DictionaryValue());
+      if (!ReadDictionaryValue(m, iter, val.get(), recursion))
+        return false;
+      *value = val.release();
+      break;
+    }
+    case base::Value::TYPE_LIST: {
+      std::unique_ptr<base::ListValue> val(new base::ListValue());
+      if (!ReadListValue(m, iter, val.get(), recursion))
+        return false;
+      *value = val.release();
+      break;
+    }
+    default:
+    return false;
+  }
+
+  return true;
+}
+
+}  // namespace
+
+// -----------------------------------------------------------------------------
+
+LogData::LogData()
+    : routing_id(0),
+      type(0),
+      sent(0),
+      receive(0),
+      dispatch(0) {
+}
+
+LogData::LogData(const LogData& other) = default;
+
+LogData::~LogData() {
+}
+
+void ParamTraits<bool>::Log(const param_type& p, std::string* l) {
+  l->append(p ? "true" : "false");
+}
+
+void ParamTraits<signed char>::GetSize(base::PickleSizer* sizer,
+                                       const param_type& p) {
+  sizer->AddBytes(sizeof(param_type));
+}
+
+void ParamTraits<signed char>::Write(base::Pickle* m, const param_type& p) {
+  m->WriteBytes(&p, sizeof(param_type));
+}
+
+bool ParamTraits<signed char>::Read(const base::Pickle* m,
+                                    base::PickleIterator* iter,
+                                    param_type* r) {
+  const char* data;
+  if (!iter->ReadBytes(&data, sizeof(param_type)))
+    return false;
+  memcpy(r, data, sizeof(param_type));
+  return true;
+}
+
+void ParamTraits<signed char>::Log(const param_type& p, std::string* l) {
+  l->append(base::IntToString(p));
+}
+
+void ParamTraits<unsigned char>::GetSize(base::PickleSizer* sizer,
+                                       const param_type& p) {
+  sizer->AddBytes(sizeof(param_type));
+}
+
+void ParamTraits<unsigned char>::Write(base::Pickle* m, const param_type& p) {
+  m->WriteBytes(&p, sizeof(param_type));
+}
+
+bool ParamTraits<unsigned char>::Read(const base::Pickle* m,
+                                      base::PickleIterator* iter,
+                                      param_type* r) {
+  const char* data;
+  if (!iter->ReadBytes(&data, sizeof(param_type)))
+    return false;
+  memcpy(r, data, sizeof(param_type));
+  return true;
+}
+
+void ParamTraits<unsigned char>::Log(const param_type& p, std::string* l) {
+  l->append(base::UintToString(p));
+}
+
+void ParamTraits<unsigned short>::GetSize(base::PickleSizer* sizer,
+                                          const param_type& p) {
+  sizer->AddBytes(sizeof(param_type));
+}
+
+void ParamTraits<unsigned short>::Write(base::Pickle* m, const param_type& p) {
+  m->WriteBytes(&p, sizeof(param_type));
+}
+
+bool ParamTraits<unsigned short>::Read(const base::Pickle* m,
+                                       base::PickleIterator* iter,
+                                       param_type* r) {
+  const char* data;
+  if (!iter->ReadBytes(&data, sizeof(param_type)))
+    return false;
+  memcpy(r, data, sizeof(param_type));
+  return true;
+}
+
+void ParamTraits<unsigned short>::Log(const param_type& p, std::string* l) {
+  l->append(base::UintToString(p));
+}
+
+void ParamTraits<int>::Log(const param_type& p, std::string* l) {
+  l->append(base::IntToString(p));
+}
+
+void ParamTraits<unsigned int>::Log(const param_type& p, std::string* l) {
+  l->append(base::UintToString(p));
+}
+
+#if defined(OS_WIN) || defined(OS_LINUX) || \
+    (defined(OS_ANDROID) && defined(ARCH_CPU_64_BITS))
+void ParamTraits<long>::Log(const param_type& p, std::string* l) {
+  l->append(base::Int64ToString(static_cast<int64_t>(p)));
+}
+
+void ParamTraits<unsigned long>::Log(const param_type& p, std::string* l) {
+  l->append(base::Uint64ToString(static_cast<uint64_t>(p)));
+}
+#endif
+
+void ParamTraits<long long>::Log(const param_type& p, std::string* l) {
+  l->append(base::Int64ToString(static_cast<int64_t>(p)));
+}
+
+void ParamTraits<unsigned long long>::Log(const param_type& p, std::string* l) {
+  l->append(base::Uint64ToString(p));
+}
+
+void ParamTraits<float>::Log(const param_type& p, std::string* l) {
+  l->append(base::StringPrintf("%e", p));
+}
+
+void ParamTraits<double>::GetSize(base::PickleSizer* sizer,
+                                  const param_type& p) {
+  sizer->AddBytes(sizeof(param_type));
+}
+
+void ParamTraits<double>::Write(base::Pickle* m, const param_type& p) {
+  m->WriteBytes(reinterpret_cast<const char*>(&p), sizeof(param_type));
+}
+
+bool ParamTraits<double>::Read(const base::Pickle* m,
+                               base::PickleIterator* iter,
+                               param_type* r) {
+  const char *data;
+  if (!iter->ReadBytes(&data, sizeof(*r))) {
+    NOTREACHED();
+    return false;
+  }
+  memcpy(r, data, sizeof(param_type));
+  return true;
+}
+
+void ParamTraits<double>::Log(const param_type& p, std::string* l) {
+  l->append(base::StringPrintf("%e", p));
+}
+
+
+void ParamTraits<std::string>::Log(const param_type& p, std::string* l) {
+  l->append(p);
+}
+
+void ParamTraits<base::string16>::Log(const param_type& p, std::string* l) {
+  l->append(base::UTF16ToUTF8(p));
+}
+
+void ParamTraits<std::vector<char>>::GetSize(base::PickleSizer* sizer,
+                                             const param_type& p) {
+  sizer->AddData(static_cast<int>(p.size()));
+}
+
+void ParamTraits<std::vector<char>>::Write(base::Pickle* m,
+                                           const param_type& p) {
+  if (p.empty()) {
+    m->WriteData(NULL, 0);
+  } else {
+    m->WriteData(&p.front(), static_cast<int>(p.size()));
+  }
+}
+
+bool ParamTraits<std::vector<char>>::Read(const base::Pickle* m,
+                                          base::PickleIterator* iter,
+                                          param_type* r) {
+  const char *data;
+  int data_size = 0;
+  if (!iter->ReadData(&data, &data_size) || data_size < 0)
+    return false;
+  r->resize(data_size);
+  if (data_size)
+    memcpy(&r->front(), data, data_size);
+  return true;
+}
+
+void ParamTraits<std::vector<char> >::Log(const param_type& p, std::string* l) {
+  LogBytes(p, l);
+}
+
+void ParamTraits<std::vector<unsigned char>>::GetSize(base::PickleSizer* sizer,
+                                                      const param_type& p) {
+  sizer->AddData(static_cast<int>(p.size()));
+}
+
+void ParamTraits<std::vector<unsigned char>>::Write(base::Pickle* m,
+                                                    const param_type& p) {
+  if (p.empty()) {
+    m->WriteData(NULL, 0);
+  } else {
+    m->WriteData(reinterpret_cast<const char*>(&p.front()),
+                 static_cast<int>(p.size()));
+  }
+}
+
+bool ParamTraits<std::vector<unsigned char>>::Read(const base::Pickle* m,
+                                                   base::PickleIterator* iter,
+                                                   param_type* r) {
+  const char *data;
+  int data_size = 0;
+  if (!iter->ReadData(&data, &data_size) || data_size < 0)
+    return false;
+  r->resize(data_size);
+  if (data_size)
+    memcpy(&r->front(), data, data_size);
+  return true;
+}
+
+void ParamTraits<std::vector<unsigned char> >::Log(const param_type& p,
+                                                   std::string* l) {
+  LogBytes(p, l);
+}
+
+void ParamTraits<std::vector<bool>>::GetSize(base::PickleSizer* sizer,
+                                             const param_type& p) {
+  GetParamSize(sizer, static_cast<int>(p.size()));
+  for (size_t i = 0; i < p.size(); ++i)
+    GetParamSize(sizer, static_cast<bool>(p[i]));
+}
+
+void ParamTraits<std::vector<bool>>::Write(base::Pickle* m,
+                                           const param_type& p) {
+  WriteParam(m, static_cast<int>(p.size()));
+  // Cast to bool below is required because libc++'s
+  // vector<bool>::const_reference is different from bool, and we want to avoid
+  // writing an extra specialization of ParamTraits for it.
+  for (size_t i = 0; i < p.size(); i++)
+    WriteParam(m, static_cast<bool>(p[i]));
+}
+
+bool ParamTraits<std::vector<bool>>::Read(const base::Pickle* m,
+                                          base::PickleIterator* iter,
+                                          param_type* r) {
+  int size;
+  // ReadLength() checks for < 0 itself.
+  if (!iter->ReadLength(&size))
+    return false;
+  r->resize(size);
+  for (int i = 0; i < size; i++) {
+    bool value;
+    if (!ReadParam(m, iter, &value))
+      return false;
+    (*r)[i] = value;
+  }
+  return true;
+}
+
+void ParamTraits<std::vector<bool> >::Log(const param_type& p, std::string* l) {
+  for (size_t i = 0; i < p.size(); ++i) {
+    if (i != 0)
+      l->push_back(' ');
+    LogParam(static_cast<bool>(p[i]), l);
+  }
+}
+
+void ParamTraits<BrokerableAttachment::AttachmentId>::Write(
+    base::Pickle* m,
+    const param_type& p) {
+  m->WriteBytes(p.nonce, BrokerableAttachment::kNonceSize);
+}
+
+bool ParamTraits<BrokerableAttachment::AttachmentId>::Read(
+    const base::Pickle* m,
+    base::PickleIterator* iter,
+    param_type* r) {
+  const char* data;
+  if (!iter->ReadBytes(&data, BrokerableAttachment::kNonceSize))
+    return false;
+  memcpy(r->nonce, data, BrokerableAttachment::kNonceSize);
+  return true;
+}
+
+void ParamTraits<BrokerableAttachment::AttachmentId>::Log(const param_type& p,
+                                                          std::string* l) {
+  l->append(base::HexEncode(p.nonce, BrokerableAttachment::kNonceSize));
+}
+
+void ParamTraits<base::DictionaryValue>::GetSize(base::PickleSizer* sizer,
+                                                 const param_type& p) {
+  GetValueSize(sizer, &p, 0);
+}
+
+void ParamTraits<base::DictionaryValue>::Write(base::Pickle* m,
+                                               const param_type& p) {
+  WriteValue(m, &p, 0);
+}
+
+bool ParamTraits<base::DictionaryValue>::Read(const base::Pickle* m,
+                                              base::PickleIterator* iter,
+                                              param_type* r) {
+  int type;
+  if (!ReadParam(m, iter, &type) || type != base::Value::TYPE_DICTIONARY)
+    return false;
+
+  return ReadDictionaryValue(m, iter, r, 0);
+}
+
+void ParamTraits<base::DictionaryValue>::Log(const param_type& p,
+                                             std::string* l) {
+  std::string json;
+  base::JSONWriter::Write(p, &json);
+  l->append(json);
+}
+
+#if defined(OS_POSIX)
+void ParamTraits<base::FileDescriptor>::GetSize(base::PickleSizer* sizer,
+                                                const param_type& p) {
+  GetParamSize(sizer, p.fd >= 0);
+  if (p.fd >= 0)
+    sizer->AddAttachment();
+}
+
+void ParamTraits<base::FileDescriptor>::Write(base::Pickle* m,
+                                              const param_type& p) {
+  const bool valid = p.fd >= 0;
+  WriteParam(m, valid);
+
+  if (!valid)
+    return;
+
+  if (p.auto_close) {
+    if (!m->WriteAttachment(
+            new internal::PlatformFileAttachment(base::ScopedFD(p.fd))))
+      NOTREACHED();
+  } else {
+    if (!m->WriteAttachment(new internal::PlatformFileAttachment(p.fd)))
+      NOTREACHED();
+  }
+}
+
+bool ParamTraits<base::FileDescriptor>::Read(const base::Pickle* m,
+                                             base::PickleIterator* iter,
+                                             param_type* r) {
+  *r = base::FileDescriptor();
+
+  bool valid;
+  if (!ReadParam(m, iter, &valid))
+    return false;
+
+  // TODO(morrita): Seems like this should return false.
+  if (!valid)
+    return true;
+
+  scoped_refptr<base::Pickle::Attachment> attachment;
+  if (!m->ReadAttachment(iter, &attachment))
+    return false;
+
+  *r = base::FileDescriptor(
+      static_cast<MessageAttachment*>(attachment.get())->TakePlatformFile(),
+      true);
+  return true;
+}
+
+void ParamTraits<base::FileDescriptor>::Log(const param_type& p,
+                                            std::string* l) {
+  if (p.auto_close) {
+    l->append(base::StringPrintf("FD(%d auto-close)", p.fd));
+  } else {
+    l->append(base::StringPrintf("FD(%d)", p.fd));
+  }
+}
+#endif  // defined(OS_POSIX)
+
+#if defined(OS_MACOSX) && !defined(OS_IOS)
+void ParamTraits<base::SharedMemoryHandle>::GetSize(base::PickleSizer* sizer,
+                                                    const param_type& p) {
+  GetParamSize(sizer, p.GetMemoryObject());
+  uint32_t dummy = 0;
+  GetParamSize(sizer, dummy);
+}
+
+void ParamTraits<base::SharedMemoryHandle>::Write(base::Pickle* m,
+                                                  const param_type& p) {
+  MachPortMac mach_port_mac(p.GetMemoryObject());
+  ParamTraits<MachPortMac>::Write(m, mach_port_mac);
+  size_t size = 0;
+  bool result = p.GetSize(&size);
+  DCHECK(result);
+  ParamTraits<uint32_t>::Write(m, static_cast<uint32_t>(size));
+
+  // If the caller intended to pass ownership to the IPC stack, release a
+  // reference.
+  if (p.OwnershipPassesToIPC())
+    p.Close();
+}
+
+bool ParamTraits<base::SharedMemoryHandle>::Read(const base::Pickle* m,
+                                                 base::PickleIterator* iter,
+                                                 param_type* r) {
+  MachPortMac mach_port_mac;
+  if (!ParamTraits<MachPortMac>::Read(m, iter, &mach_port_mac))
+    return false;
+
+  uint32_t size;
+  if (!ParamTraits<uint32_t>::Read(m, iter, &size))
+    return false;
+
+  *r = base::SharedMemoryHandle(mach_port_mac.get_mach_port(),
+                                static_cast<size_t>(size),
+                                base::GetCurrentProcId());
+  return true;
+}
+
+void ParamTraits<base::SharedMemoryHandle>::Log(const param_type& p,
+                                                std::string* l) {
+  l->append("Mach port: ");
+  LogParam(p.GetMemoryObject(), l);
+}
+
+#elif defined(OS_WIN)
+void ParamTraits<base::SharedMemoryHandle>::GetSize(base::PickleSizer* s,
+                                                    const param_type& p) {
+  GetParamSize(s, p.NeedsBrokering());
+  if (p.NeedsBrokering()) {
+    GetParamSize(s, p.GetHandle());
+  } else {
+    GetParamSize(s, HandleToLong(p.GetHandle()));
+  }
+}
+
+void ParamTraits<base::SharedMemoryHandle>::Write(base::Pickle* m,
+                                                  const param_type& p) {
+  m->WriteBool(p.NeedsBrokering());
+
+  if (p.NeedsBrokering()) {
+    HandleWin handle_win(p.GetHandle(), HandleWin::DUPLICATE);
+    ParamTraits<HandleWin>::Write(m, handle_win);
+
+    // If the caller intended to pass ownership to the IPC stack, release a
+    // reference.
+    if (p.OwnershipPassesToIPC() && p.BelongsToCurrentProcess())
+      p.Close();
+  } else {
+    m->WriteInt(HandleToLong(p.GetHandle()));
+  }
+}
+
+bool ParamTraits<base::SharedMemoryHandle>::Read(const base::Pickle* m,
+                                                 base::PickleIterator* iter,
+                                                 param_type* r) {
+  bool needs_brokering;
+  if (!iter->ReadBool(&needs_brokering))
+    return false;
+
+  if (needs_brokering) {
+    HandleWin handle_win;
+    if (!ParamTraits<HandleWin>::Read(m, iter, &handle_win))
+      return false;
+    *r = base::SharedMemoryHandle(handle_win.get_handle(),
+                                  base::GetCurrentProcId());
+    return true;
+  }
+
+  int handle_int;
+  if (!iter->ReadInt(&handle_int))
+    return false;
+  HANDLE handle = LongToHandle(handle_int);
+  *r = base::SharedMemoryHandle(handle, base::GetCurrentProcId());
+  return true;
+}
+
+void ParamTraits<base::SharedMemoryHandle>::Log(const param_type& p,
+                                                std::string* l) {
+  LogParam(p.GetHandle(), l);
+  l->append(" needs brokering: ");
+  LogParam(p.NeedsBrokering(), l);
+}
+#endif  // defined(OS_MACOSX) && !defined(OS_IOS)
+
+void ParamTraits<base::FilePath>::GetSize(base::PickleSizer* sizer,
+                                          const param_type& p) {
+  p.GetSizeForPickle(sizer);
+}
+
+void ParamTraits<base::FilePath>::Write(base::Pickle* m, const param_type& p) {
+  p.WriteToPickle(m);
+}
+
+bool ParamTraits<base::FilePath>::Read(const base::Pickle* m,
+                                       base::PickleIterator* iter,
+                                       param_type* r) {
+  return r->ReadFromPickle(iter);
+}
+
+void ParamTraits<base::FilePath>::Log(const param_type& p, std::string* l) {
+  ParamTraits<base::FilePath::StringType>::Log(p.value(), l);
+}
+
+void ParamTraits<base::ListValue>::GetSize(base::PickleSizer* sizer,
+                                           const param_type& p) {
+  GetValueSize(sizer, &p, 0);
+}
+
+void ParamTraits<base::ListValue>::Write(base::Pickle* m, const param_type& p) {
+  WriteValue(m, &p, 0);
+}
+
+bool ParamTraits<base::ListValue>::Read(const base::Pickle* m,
+                                        base::PickleIterator* iter,
+                                        param_type* r) {
+  int type;
+  if (!ReadParam(m, iter, &type) || type != base::Value::TYPE_LIST)
+    return false;
+
+  return ReadListValue(m, iter, r, 0);
+}
+
+void ParamTraits<base::ListValue>::Log(const param_type& p, std::string* l) {
+  std::string json;
+  base::JSONWriter::Write(p, &json);
+  l->append(json);
+}
+
+void ParamTraits<base::NullableString16>::GetSize(base::PickleSizer* sizer,
+                                                  const param_type& p) {
+  GetParamSize(sizer, p.string());
+  GetParamSize(sizer, p.is_null());
+}
+
+void ParamTraits<base::NullableString16>::Write(base::Pickle* m,
+                                                const param_type& p) {
+  WriteParam(m, p.string());
+  WriteParam(m, p.is_null());
+}
+
+bool ParamTraits<base::NullableString16>::Read(const base::Pickle* m,
+                                               base::PickleIterator* iter,
+                                               param_type* r) {
+  base::string16 string;
+  if (!ReadParam(m, iter, &string))
+    return false;
+  bool is_null;
+  if (!ReadParam(m, iter, &is_null))
+    return false;
+  *r = base::NullableString16(string, is_null);
+  return true;
+}
+
+void ParamTraits<base::NullableString16>::Log(const param_type& p,
+                                              std::string* l) {
+  l->append("(");
+  LogParam(p.string(), l);
+  l->append(", ");
+  LogParam(p.is_null(), l);
+  l->append(")");
+}
+
+void ParamTraits<base::File::Info>::GetSize(base::PickleSizer* sizer,
+                                            const param_type& p) {
+  GetParamSize(sizer, p.size);
+  GetParamSize(sizer, p.is_directory);
+  GetParamSize(sizer, p.last_modified.ToDoubleT());
+  GetParamSize(sizer, p.last_accessed.ToDoubleT());
+  GetParamSize(sizer, p.creation_time.ToDoubleT());
+}
+
+void ParamTraits<base::File::Info>::Write(base::Pickle* m,
+                                          const param_type& p) {
+  WriteParam(m, p.size);
+  WriteParam(m, p.is_directory);
+  WriteParam(m, p.last_modified.ToDoubleT());
+  WriteParam(m, p.last_accessed.ToDoubleT());
+  WriteParam(m, p.creation_time.ToDoubleT());
+}
+
+bool ParamTraits<base::File::Info>::Read(const base::Pickle* m,
+                                         base::PickleIterator* iter,
+                                         param_type* p) {
+  double last_modified, last_accessed, creation_time;
+  if (!ReadParam(m, iter, &p->size) ||
+      !ReadParam(m, iter, &p->is_directory) ||
+      !ReadParam(m, iter, &last_modified) ||
+      !ReadParam(m, iter, &last_accessed) ||
+      !ReadParam(m, iter, &creation_time))
+    return false;
+  p->last_modified = base::Time::FromDoubleT(last_modified);
+  p->last_accessed = base::Time::FromDoubleT(last_accessed);
+  p->creation_time = base::Time::FromDoubleT(creation_time);
+  return true;
+}
+
+void ParamTraits<base::File::Info>::Log(const param_type& p,
+                                        std::string* l) {
+  l->append("(");
+  LogParam(p.size, l);
+  l->append(",");
+  LogParam(p.is_directory, l);
+  l->append(",");
+  LogParam(p.last_modified.ToDoubleT(), l);
+  l->append(",");
+  LogParam(p.last_accessed.ToDoubleT(), l);
+  l->append(",");
+  LogParam(p.creation_time.ToDoubleT(), l);
+  l->append(")");
+}
+
+void ParamTraits<base::Time>::GetSize(base::PickleSizer* sizer,
+                                      const param_type& p) {
+  sizer->AddInt64();
+}
+
+void ParamTraits<base::Time>::Write(base::Pickle* m, const param_type& p) {
+  ParamTraits<int64_t>::Write(m, p.ToInternalValue());
+}
+
+bool ParamTraits<base::Time>::Read(const base::Pickle* m,
+                                   base::PickleIterator* iter,
+                                   param_type* r) {
+  int64_t value;
+  if (!ParamTraits<int64_t>::Read(m, iter, &value))
+    return false;
+  *r = base::Time::FromInternalValue(value);
+  return true;
+}
+
+void ParamTraits<base::Time>::Log(const param_type& p, std::string* l) {
+  ParamTraits<int64_t>::Log(p.ToInternalValue(), l);
+}
+
+void ParamTraits<base::TimeDelta>::GetSize(base::PickleSizer* sizer,
+                                           const param_type& p) {
+  sizer->AddInt64();
+}
+
+void ParamTraits<base::TimeDelta>::Write(base::Pickle* m, const param_type& p) {
+  ParamTraits<int64_t>::Write(m, p.ToInternalValue());
+}
+
+bool ParamTraits<base::TimeDelta>::Read(const base::Pickle* m,
+                                        base::PickleIterator* iter,
+                                        param_type* r) {
+  int64_t value;
+  bool ret = ParamTraits<int64_t>::Read(m, iter, &value);
+  if (ret)
+    *r = base::TimeDelta::FromInternalValue(value);
+
+  return ret;
+}
+
+void ParamTraits<base::TimeDelta>::Log(const param_type& p, std::string* l) {
+  ParamTraits<int64_t>::Log(p.ToInternalValue(), l);
+}
+
+void ParamTraits<base::TimeTicks>::GetSize(base::PickleSizer* sizer,
+                                           const param_type& p) {
+  sizer->AddInt64();
+}
+
+void ParamTraits<base::TimeTicks>::Write(base::Pickle* m, const param_type& p) {
+  ParamTraits<int64_t>::Write(m, p.ToInternalValue());
+}
+
+bool ParamTraits<base::TimeTicks>::Read(const base::Pickle* m,
+                                        base::PickleIterator* iter,
+                                        param_type* r) {
+  int64_t value;
+  bool ret = ParamTraits<int64_t>::Read(m, iter, &value);
+  if (ret)
+    *r = base::TimeTicks::FromInternalValue(value);
+
+  return ret;
+}
+
+void ParamTraits<base::TimeTicks>::Log(const param_type& p, std::string* l) {
+  ParamTraits<int64_t>::Log(p.ToInternalValue(), l);
+}
+
+void ParamTraits<IPC::ChannelHandle>::GetSize(base::PickleSizer* sizer,
+                                              const param_type& p) {
+  GetParamSize(sizer, p.name);
+#if defined(OS_POSIX)
+  GetParamSize(sizer, p.socket);
+#endif
+  GetParamSize(sizer, p.mojo_handle);
+}
+
+void ParamTraits<IPC::ChannelHandle>::Write(base::Pickle* m,
+                                            const param_type& p) {
+#if defined(OS_WIN)
+  // On Windows marshalling pipe handle is not supported.
+  DCHECK(p.pipe.handle == NULL);
+#endif  // defined (OS_WIN)
+  WriteParam(m, p.name);
+#if defined(OS_POSIX)
+  WriteParam(m, p.socket);
+#endif
+  WriteParam(m, p.mojo_handle);
+}
+
+bool ParamTraits<IPC::ChannelHandle>::Read(const base::Pickle* m,
+                                           base::PickleIterator* iter,
+                                           param_type* r) {
+  return ReadParam(m, iter, &r->name)
+#if defined(OS_POSIX)
+      && ReadParam(m, iter, &r->socket)
+#endif
+      && ReadParam(m, iter, &r->mojo_handle);
+}
+
+void ParamTraits<IPC::ChannelHandle>::Log(const param_type& p,
+                                          std::string* l) {
+  l->append(base::StringPrintf("ChannelHandle(%s", p.name.c_str()));
+#if defined(OS_POSIX)
+  l->append(", ");
+  ParamTraits<base::FileDescriptor>::Log(p.socket, l);
+#endif
+  l->append(", ");
+  LogParam(p.mojo_handle, l);
+  l->append(")");
+}
+
+void ParamTraits<LogData>::GetSize(base::PickleSizer* sizer,
+                                   const param_type& p) {
+  GetParamSize(sizer, p.channel);
+  GetParamSize(sizer, p.routing_id);
+  GetParamSize(sizer, p.type);
+  GetParamSize(sizer, p.flags);
+  GetParamSize(sizer, p.sent);
+  GetParamSize(sizer, p.receive);
+  GetParamSize(sizer, p.dispatch);
+  GetParamSize(sizer, p.message_name);
+  GetParamSize(sizer, p.params);
+}
+
+void ParamTraits<LogData>::Write(base::Pickle* m, const param_type& p) {
+  WriteParam(m, p.channel);
+  WriteParam(m, p.routing_id);
+  WriteParam(m, p.type);
+  WriteParam(m, p.flags);
+  WriteParam(m, p.sent);
+  WriteParam(m, p.receive);
+  WriteParam(m, p.dispatch);
+  WriteParam(m, p.message_name);
+  WriteParam(m, p.params);
+}
+
+bool ParamTraits<LogData>::Read(const base::Pickle* m,
+                                base::PickleIterator* iter,
+                                param_type* r) {
+  return
+      ReadParam(m, iter, &r->channel) &&
+      ReadParam(m, iter, &r->routing_id) &&
+      ReadParam(m, iter, &r->type) &&
+      ReadParam(m, iter, &r->flags) &&
+      ReadParam(m, iter, &r->sent) &&
+      ReadParam(m, iter, &r->receive) &&
+      ReadParam(m, iter, &r->dispatch) &&
+      ReadParam(m, iter, &r->message_name) &&
+      ReadParam(m, iter, &r->params);
+}
+
+void ParamTraits<LogData>::Log(const param_type& p, std::string* l) {
+  // Doesn't make sense to implement this!
+}
+
+void ParamTraits<Message>::Write(base::Pickle* m, const Message& p) {
+#if defined(OS_POSIX)
+  // We don't serialize the file descriptors in the nested message, so there
+  // better not be any.
+  DCHECK(!p.HasAttachments());
+#endif
+
+  // Don't just write out the message. This is used to send messages between
+  // NaCl (Posix environment) and the browser (could be on Windows). The message
+  // header formats differ between these systems (so does handle sharing, but
+  // we already asserted we don't have any handles). So just write out the
+  // parts of the header we use.
+  //
+  // Be careful also to use only explicitly-sized types. The NaCl environment
+  // could be 64-bit and the host browser could be 32-bits. The nested message
+  // may or may not be safe to send between 32-bit and 64-bit systems, but we
+  // leave that up to the code sending the message to ensure.
+  m->WriteUInt32(static_cast<uint32_t>(p.routing_id()));
+  m->WriteUInt32(p.type());
+  m->WriteUInt32(p.flags());
+  m->WriteData(p.payload(), static_cast<uint32_t>(p.payload_size()));
+}
+
+bool ParamTraits<Message>::Read(const base::Pickle* m,
+                                base::PickleIterator* iter,
+                                Message* r) {
+  uint32_t routing_id, type, flags;
+  if (!iter->ReadUInt32(&routing_id) ||
+      !iter->ReadUInt32(&type) ||
+      !iter->ReadUInt32(&flags))
+    return false;
+
+  int payload_size;
+  const char* payload;
+  if (!iter->ReadData(&payload, &payload_size))
+    return false;
+
+  r->SetHeaderValues(static_cast<int32_t>(routing_id), type, flags);
+  return r->WriteBytes(payload, payload_size);
+}
+
+void ParamTraits<Message>::Log(const Message& p, std::string* l) {
+  l->append("<IPC::Message>");
+}
+
+#if defined(OS_WIN)
+void ParamTraits<HANDLE>::GetSize(base::PickleSizer* sizer,
+                                  const param_type& p) {
+  sizer->AddInt();
+}
+
+// Note that HWNDs/HANDLE/HCURSOR/HACCEL etc are always 32 bits, even on 64
+// bit systems. That's why we use the Windows macros to convert to 32 bits.
+void ParamTraits<HANDLE>::Write(base::Pickle* m, const param_type& p) {
+  m->WriteInt(HandleToLong(p));
+}
+
+bool ParamTraits<HANDLE>::Read(const base::Pickle* m,
+                               base::PickleIterator* iter,
+                               param_type* r) {
+  int32_t temp;
+  if (!iter->ReadInt(&temp))
+    return false;
+  *r = LongToHandle(temp);
+  return true;
+}
+
+void ParamTraits<HANDLE>::Log(const param_type& p, std::string* l) {
+  l->append(base::StringPrintf("0x%p", p));
+}
+
+void ParamTraits<LOGFONT>::GetSize(base::PickleSizer* sizer,
+                                   const param_type& p) {
+  sizer->AddData(sizeof(LOGFONT));
+}
+
+void ParamTraits<LOGFONT>::Write(base::Pickle* m, const param_type& p) {
+  m->WriteData(reinterpret_cast<const char*>(&p), sizeof(LOGFONT));
+}
+
+bool ParamTraits<LOGFONT>::Read(const base::Pickle* m,
+                                base::PickleIterator* iter,
+                                param_type* r) {
+  const char *data;
+  int data_size = 0;
+  if (iter->ReadData(&data, &data_size) && data_size == sizeof(LOGFONT)) {
+    const LOGFONT *font = reinterpret_cast<LOGFONT*>(const_cast<char*>(data));
+    if (_tcsnlen(font->lfFaceName, LF_FACESIZE) < LF_FACESIZE) {
+      memcpy(r, data, sizeof(LOGFONT));
+      return true;
+    }
+  }
+
+  NOTREACHED();
+  return false;
+}
+
+void ParamTraits<LOGFONT>::Log(const param_type& p, std::string* l) {
+  l->append(base::StringPrintf("<LOGFONT>"));
+}
+
+void ParamTraits<MSG>::GetSize(base::PickleSizer* sizer, const param_type& p) {
+  sizer->AddData(sizeof(MSG));
+}
+
+void ParamTraits<MSG>::Write(base::Pickle* m, const param_type& p) {
+  m->WriteData(reinterpret_cast<const char*>(&p), sizeof(MSG));
+}
+
+bool ParamTraits<MSG>::Read(const base::Pickle* m,
+                            base::PickleIterator* iter,
+                            param_type* r) {
+  const char *data;
+  int data_size = 0;
+  bool result = iter->ReadData(&data, &data_size);
+  if (result && data_size == sizeof(MSG)) {
+    memcpy(r, data, sizeof(MSG));
+  } else {
+    result = false;
+    NOTREACHED();
+  }
+
+  return result;
+}
+
+void ParamTraits<MSG>::Log(const param_type& p, std::string* l) {
+  l->append("<MSG>");
+}
+
+#endif  // OS_WIN
+
+}  // namespace IPC
