Merge from Chromium at DEPS revision r190564

This commit was generated by merge_to_master.py.

Change-Id: Icadecbce29854b8fa25fd335b2c1949b5ca5d170
diff --git a/ppapi/shared_impl/DEPS b/ppapi/shared_impl/DEPS
index 823b983..9f93141 100644
--- a/ppapi/shared_impl/DEPS
+++ b/ppapi/shared_impl/DEPS
@@ -14,4 +14,7 @@
 
   "-ppapi/cpp",
   "-ppapi/proxy",
+
+  # For testing purpose.
+  "+ppapi/proxy/ppapi_proxy_test.h",
 ]
diff --git a/ppapi/shared_impl/api_id.h b/ppapi/shared_impl/api_id.h
index 360b8cb..00706bf 100644
--- a/ppapi/shared_impl/api_id.h
+++ b/ppapi/shared_impl/api_id.h
@@ -24,7 +24,6 @@
   API_ID_PPB_FILE_IO,
   API_ID_PPB_FILE_REF,
   API_ID_PPB_FILE_SYSTEM,
-  API_ID_PPB_FLASH,
   API_ID_PPB_FLASH_DEVICE_ID,
   API_ID_PPB_FLASH_FONTFILE,
   API_ID_PPB_FLASH_MENU,
diff --git a/ppapi/shared_impl/array_var.cc b/ppapi/shared_impl/array_var.cc
new file mode 100644
index 0000000..def1bb5
--- /dev/null
+++ b/ppapi/shared_impl/array_var.cc
@@ -0,0 +1,83 @@
+// Copyright (c) 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 "ppapi/shared_impl/array_var.h"
+
+#include <limits>
+
+#include "base/logging.h"
+#include "base/memory/ref_counted.h"
+#include "ppapi/shared_impl/ppapi_globals.h"
+#include "ppapi/shared_impl/var_tracker.h"
+
+namespace ppapi {
+
+ArrayVar::ArrayVar() {
+}
+
+ArrayVar::~ArrayVar() {
+}
+
+// static
+ArrayVar* ArrayVar::FromPPVar(const PP_Var& var) {
+  if (var.type != PP_VARTYPE_ARRAY)
+    return NULL;
+
+  scoped_refptr<Var> var_object(
+      PpapiGlobals::Get()->GetVarTracker()->GetVar(var));
+  if (!var_object.get())
+    return NULL;
+  return var_object->AsArrayVar();
+}
+
+ArrayVar* ArrayVar::AsArrayVar() {
+  return this;
+}
+
+PP_VarType ArrayVar::GetType() const {
+  return PP_VARTYPE_ARRAY;
+}
+
+PP_Var ArrayVar::Get(uint32_t index) const {
+  if (index >= elements_.size())
+    return PP_MakeUndefined();
+
+  const PP_Var& element = elements_[index].get();
+  if (PpapiGlobals::Get()->GetVarTracker()->AddRefVar(element))
+    return element;
+  else
+    return PP_MakeUndefined();
+}
+
+PP_Bool ArrayVar::Set(uint32_t index, const PP_Var& value) {
+  if (index == std::numeric_limits<uint32_t>::max())
+    return PP_FALSE;
+
+  if (index >= elements_.size()) {
+    // Insert ScopedPPVars of type PP_VARTYPE_UNDEFINED to reach the new size
+    // (index + 1).
+    elements_.resize(index + 1);
+  }
+
+  elements_[index] = value;
+  return PP_TRUE;
+}
+
+uint32_t ArrayVar::GetLength() const {
+  if (elements_.size() > std::numeric_limits<uint32_t>::max()) {
+    CHECK(false);
+    return 0;
+  }
+
+  return static_cast<uint32_t>(elements_.size());
+}
+
+PP_Bool ArrayVar::SetLength(uint32_t length) {
+  // If |length| is larger than the current size, ScopedPPVars of type
+  // PP_VARTYPE_UNDEFINED will be inserted to reach the new length.
+  elements_.resize(length);
+  return PP_TRUE;
+}
+
+}  // namespace ppapi
diff --git a/ppapi/shared_impl/array_var.h b/ppapi/shared_impl/array_var.h
new file mode 100644
index 0000000..1214d87
--- /dev/null
+++ b/ppapi/shared_impl/array_var.h
@@ -0,0 +1,59 @@
+// Copyright (c) 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 PPAPI_SHARED_IMPL_ARRAY_VAR_H_
+#define PPAPI_SHARED_IMPL_ARRAY_VAR_H_
+
+#include <vector>
+
+#include "base/basictypes.h"
+#include "base/compiler_specific.h"
+#include "ppapi/c/pp_var.h"
+#include "ppapi/shared_impl/ppapi_shared_export.h"
+#include "ppapi/shared_impl/scoped_pp_var.h"
+#include "ppapi/shared_impl/var.h"
+
+namespace ppapi {
+
+class PPAPI_SHARED_EXPORT ArrayVar : public Var {
+ public:
+  typedef std::vector<ScopedPPVar> ElementVector;
+
+  ArrayVar();
+
+  // Helper function that converts a PP_Var to an ArrayVar. This will return
+  // NULL if the PP_Var is not of type PP_VARTYPE_ARRAY or the array cannot be
+  // found from the var tracker.
+  static ArrayVar* FromPPVar(const PP_Var& var);
+
+  // Var overrides.
+  virtual ArrayVar* AsArrayVar() OVERRIDE;
+  virtual PP_VarType GetType() const OVERRIDE;
+
+  // The returned PP_Var has had a ref added on behalf of the caller.
+  PP_Var Get(uint32_t index) const;
+  PP_Bool Set(uint32_t index, const PP_Var& value);
+  uint32_t GetLength() const;
+  PP_Bool SetLength(uint32_t length);
+
+  const ElementVector& elements() const {
+    return elements_;
+  }
+
+  ElementVector& elements() {
+    return elements_;
+  }
+
+ protected:
+  virtual ~ArrayVar();
+
+ private:
+  ElementVector elements_;
+
+  DISALLOW_COPY_AND_ASSIGN(ArrayVar);
+};
+
+}  // namespace ppapi
+
+#endif  // PPAPI_SHARED_IMPL_ARRAY_VAR_H_
diff --git a/ppapi/shared_impl/array_writer.cc b/ppapi/shared_impl/array_writer.cc
index 957ff77..26ee1bd 100644
--- a/ppapi/shared_impl/array_writer.cc
+++ b/ppapi/shared_impl/array_writer.cc
@@ -9,6 +9,8 @@
 #include "ppapi/shared_impl/ppapi_globals.h"
 #include "ppapi/shared_impl/resource.h"
 #include "ppapi/shared_impl/resource_tracker.h"
+#include "ppapi/shared_impl/var.h"
+#include "ppapi/shared_impl/var_tracker.h"
 
 namespace ppapi {
 
@@ -76,4 +78,52 @@
   return true;
 }
 
+bool ArrayWriter::StoreVarVector(
+    const std::vector< scoped_refptr<Var> >& input) {
+  // Always call the alloc function, even on 0 array size.
+  void* dest = pp_array_output_.GetDataBuffer(
+      pp_array_output_.user_data,
+      static_cast<uint32_t>(input.size()),
+      sizeof(PP_Var));
+
+  // Regardless of success, we clear the output to prevent future calls on
+  // this same output object.
+  Reset();
+
+  if (input.empty())
+    return true;  // Allow plugin to return NULL on 0 elements.
+  if (!dest)
+    return false;
+
+  // Convert to PP_Vars.
+  PP_Var* dest_vars = static_cast<PP_Var*>(dest);
+  for (size_t i = 0; i < input.size(); i++)
+    dest_vars[i] = input[i]->GetPPVar();
+  return true;
+}
+
+bool ArrayWriter::StoreVarVector(const std::vector<PP_Var>& input) {
+  // Always call the alloc function, even on 0 array size.
+  void* dest = pp_array_output_.GetDataBuffer(
+      pp_array_output_.user_data,
+      static_cast<uint32_t>(input.size()),
+      sizeof(PP_Var));
+
+  // Regardless of success, we clear the output to prevent future calls on
+  // this same output object.
+  Reset();
+
+  if (input.empty())
+    return true;  // Allow plugin to return NULL on 0 elements.
+  if (!dest) {
+    // Free the vars.
+    for (size_t i = 0; i < input.size(); i++)
+      PpapiGlobals::Get()->GetVarTracker()->ReleaseVar(input[i]);
+    return false;
+  }
+
+  std::copy(input.begin(), input.end(), static_cast<PP_Var*>(dest));
+  return true;
+}
+
 }  // namespace ppapi
diff --git a/ppapi/shared_impl/array_writer.h b/ppapi/shared_impl/array_writer.h
index cabd0af..7e6c349 100644
--- a/ppapi/shared_impl/array_writer.h
+++ b/ppapi/shared_impl/array_writer.h
@@ -18,6 +18,7 @@
 namespace ppapi {
 
 class Resource;
+class Var;
 
 // Holds a PP_ArrayWriter and provides helper functions for writing arrays
 // to it. It also handles 0-initialization of the raw C struct and attempts
@@ -38,7 +39,8 @@
   // Sets the array output back to its is_null() state.
   void Reset();
 
-  // Copies the given vector of data to the plugin output array.
+  // StoreArray() and StoreVector() copy the given array/vector of data to the
+  // plugin output array.
   //
   // Returns true on success, false if the plugin reported allocation failure.
   // In either case, the object will become is_null() immediately after the
@@ -48,27 +50,35 @@
   // want to transfer a reference only on success. Likewise, if you have a
   // structure of PP_Vars or a struct that contains a PP_Resource, we need to
   // make sure that the right thing happens with the ref on success and failure.
-  template<typename T>
-  bool StoreVector(const std::vector<T>& input) {
+  template <typename T>
+  bool StoreArray(const T* input, uint32_t count) {
     // Always call the alloc function, even on 0 array size.
     void* dest = pp_array_output_.GetDataBuffer(
         pp_array_output_.user_data,
-        static_cast<uint32_t>(input.size()),
+        count,
         sizeof(T));
 
     // Regardless of success, we clear the output to prevent future calls on
     // this same output object.
     Reset();
 
-    if (input.empty())
+    if (count == 0)
       return true;  // Allow plugin to return NULL on 0 elements.
     if (!dest)
       return false;
 
-    memcpy(dest, &input[0], sizeof(T) * input.size());
+    if (input)
+      memcpy(dest, input, sizeof(T) * count);
     return true;
   }
 
+  // Copies the given array/vector of data to the plugin output array.  See
+  // comment of StoreArray() for detail.
+  template<typename T>
+  bool StoreVector(const std::vector<T>& input) {
+    return StoreArray(input.size() ? &input[0] : NULL, input.size());
+  }
+
   // Stores the given vector of resources as PP_Resources to the output vector,
   // adding one reference to each.
   //
@@ -80,13 +90,25 @@
   // Note: potentially this could be a template in case you have a vector of
   // FileRef objects, for example. However, this saves code since there's only
   // one instantiation and is sufficient for now.
-  bool StoreResourceVector(
-      const std::vector< scoped_refptr<Resource> >& input);
+  bool StoreResourceVector(const std::vector< scoped_refptr<Resource> >& input);
 
-  // Like the above version but takes an array of AddRed'ed PP_Resources. On
+  // Like the above version but takes an array of AddRef'ed PP_Resources. On
   // storage failure, this will release each resource.
   bool StoreResourceVector(const std::vector<PP_Resource>& input);
 
+  // Stores the given vector of vars as PP_Vars to the output vector,
+  // adding one reference to each.
+  //
+  // On failure this returns false, nothing will be copied, and the var
+  // refcounts will be unchanged. In either case, the object will become
+  // is_null() immediately after the call since one output function should only
+  // be issued once.
+  bool StoreVarVector(const std::vector< scoped_refptr<Var> >& input);
+
+  // Like the above version but takes an array of AddRef'ed PP_Vars. On
+  // storage failure, this will release each var.
+  bool StoreVarVector(const std::vector<PP_Var>& input);
+
  private:
   PP_ArrayOutput pp_array_output_;
 
diff --git a/ppapi/shared_impl/dictionary_var.cc b/ppapi/shared_impl/dictionary_var.cc
new file mode 100644
index 0000000..f7af7d9
--- /dev/null
+++ b/ppapi/shared_impl/dictionary_var.cc
@@ -0,0 +1,110 @@
+// Copyright (c) 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 "ppapi/shared_impl/dictionary_var.h"
+
+#include "base/memory/ref_counted.h"
+#include "base/string_util.h"
+#include "ppapi/shared_impl/array_var.h"
+#include "ppapi/shared_impl/ppapi_globals.h"
+#include "ppapi/shared_impl/var_tracker.h"
+
+namespace ppapi {
+
+DictionaryVar::DictionaryVar() {
+}
+
+DictionaryVar::~DictionaryVar() {
+}
+
+// static
+DictionaryVar* DictionaryVar::FromPPVar(const PP_Var& var) {
+  if (var.type != PP_VARTYPE_DICTIONARY)
+    return NULL;
+
+  scoped_refptr<Var> var_object(
+      PpapiGlobals::Get()->GetVarTracker()->GetVar(var));
+  if (!var_object.get())
+    return NULL;
+  return var_object->AsDictionaryVar();
+}
+
+DictionaryVar* DictionaryVar::AsDictionaryVar() {
+  return this;
+}
+
+PP_VarType DictionaryVar::GetType() const {
+  return PP_VARTYPE_DICTIONARY;
+}
+
+PP_Var DictionaryVar::Get(const PP_Var& key) const {
+  StringVar* string_var = StringVar::FromPPVar(key);
+  if (!string_var)
+    return PP_MakeUndefined();
+
+  KeyValueMap::const_iterator iter = key_value_map_.find(string_var->value());
+  if (iter != key_value_map_.end()) {
+    if (PpapiGlobals::Get()->GetVarTracker()->AddRefVar(iter->second.get()))
+      return iter->second.get();
+    else
+      return PP_MakeUndefined();
+  } else {
+    return PP_MakeUndefined();
+  }
+}
+
+PP_Bool DictionaryVar::Set(const PP_Var& key, const PP_Var& value) {
+  StringVar* string_var = StringVar::FromPPVar(key);
+  if (!string_var)
+    return PP_FALSE;
+
+  key_value_map_[string_var->value()] = value;
+  return PP_TRUE;
+}
+
+void DictionaryVar::Delete(const PP_Var& key) {
+  StringVar* string_var = StringVar::FromPPVar(key);
+  if (!string_var)
+    return;
+
+  key_value_map_.erase(string_var->value());
+}
+
+PP_Bool DictionaryVar::HasKey(const PP_Var& key) const {
+  StringVar* string_var = StringVar::FromPPVar(key);
+  if (!string_var)
+    return PP_FALSE;
+
+  bool result =
+      key_value_map_.find(string_var->value()) != key_value_map_.end();
+  return PP_FromBool(result);
+}
+
+PP_Var DictionaryVar::GetKeys() const {
+  scoped_refptr<ArrayVar> array_var(new ArrayVar());
+  array_var->elements().reserve(key_value_map_.size());
+
+  for (KeyValueMap::const_iterator iter = key_value_map_.begin();
+       iter != key_value_map_.end(); ++iter) {
+    array_var->elements().push_back(
+        ScopedPPVar(ScopedPPVar::PassRef(),
+                    StringVar::StringToPPVar(iter->first)));
+  }
+  return array_var->GetPPVar();
+}
+
+bool DictionaryVar::SetWithStringKey(const std::string& utf8_key,
+                                     const PP_Var& value) {
+  if (!IsStringUTF8(utf8_key))
+    return false;
+
+  key_value_map_[utf8_key] = value;
+  return true;
+}
+
+void DictionaryVar::DeleteWithStringKey(const std::string& utf8_key) {
+  key_value_map_.erase(utf8_key);
+}
+
+}  // namespace ppapi
diff --git a/ppapi/shared_impl/dictionary_var.h b/ppapi/shared_impl/dictionary_var.h
new file mode 100644
index 0000000..cdc63bd
--- /dev/null
+++ b/ppapi/shared_impl/dictionary_var.h
@@ -0,0 +1,63 @@
+// Copyright (c) 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 PPAPI_SHARED_IMPL_DICTIONARY_VAR_H_
+#define PPAPI_SHARED_IMPL_DICTIONARY_VAR_H_
+
+#include <map>
+#include <string>
+
+#include "base/basictypes.h"
+#include "base/compiler_specific.h"
+#include "ppapi/c/pp_var.h"
+#include "ppapi/shared_impl/ppapi_shared_export.h"
+#include "ppapi/shared_impl/scoped_pp_var.h"
+#include "ppapi/shared_impl/var.h"
+
+namespace ppapi {
+
+class PPAPI_SHARED_EXPORT DictionaryVar : public Var {
+ public:
+  typedef std::map<std::string, ScopedPPVar> KeyValueMap;
+
+  DictionaryVar();
+
+  // Helper function that converts a PP_Var to a DictionaryVar. This will
+  // return NULL if the PP_Var is not of type PP_VARTYPE_DICTIONARY or the
+  // dictionary cannot be found from the var tracker.
+  static DictionaryVar* FromPPVar(const PP_Var& var);
+
+  // Var overrides.
+  virtual DictionaryVar* AsDictionaryVar() OVERRIDE;
+  virtual PP_VarType GetType() const OVERRIDE;
+
+  // The returned PP_Var has had a ref added on behalf of the caller.
+  PP_Var Get(const PP_Var& key) const;
+  PP_Bool Set(const PP_Var& key, const PP_Var& value);
+  void Delete(const PP_Var& key);
+  PP_Bool HasKey(const PP_Var& key) const;
+  // The returned PP_Var has had a ref added on behalf of the caller.
+  PP_Var GetKeys() const;
+
+  // Returns false and keeps the dictionary unchanged if |key| is not a valid
+  // UTF-8 string.
+  bool SetWithStringKey(const std::string& utf8_key, const PP_Var& value);
+  void DeleteWithStringKey(const std::string& utf8_key);
+
+  const KeyValueMap& key_value_map() const {
+    return key_value_map_;
+  }
+
+ protected:
+  virtual ~DictionaryVar();
+
+ private:
+  KeyValueMap key_value_map_;
+
+  DISALLOW_COPY_AND_ASSIGN(DictionaryVar);
+};
+
+}  // namespace ppapi
+
+#endif  // PPAPI_SHARED_IMPL_DICTIONARY_VAR_H_
diff --git a/ppapi/shared_impl/dir_contents.h b/ppapi/shared_impl/dir_contents.h
index 98c29f3..4d895b5 100644
--- a/ppapi/shared_impl/dir_contents.h
+++ b/ppapi/shared_impl/dir_contents.h
@@ -8,12 +8,12 @@
 
 #include <vector>
 
-#include "base/file_path.h"
+#include "base/files/file_path.h"
 
 namespace ppapi {
 
 struct DirEntry {
-  FilePath name;
+  base::FilePath name;
   bool is_dir;
 };
 
diff --git a/ppapi/shared_impl/file_io_state_manager.cc b/ppapi/shared_impl/file_io_state_manager.cc
new file mode 100644
index 0000000..9c9b6ea
--- /dev/null
+++ b/ppapi/shared_impl/file_io_state_manager.cc
@@ -0,0 +1,56 @@
+// 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 "ppapi/shared_impl/file_io_state_manager.h"
+
+#include "base/logging.h"
+#include "ppapi/c/pp_errors.h"
+
+namespace ppapi {
+
+FileIOStateManager::FileIOStateManager()
+    : num_pending_ops_(0),
+      pending_op_(OPERATION_NONE),
+      file_open_(false) {
+}
+
+FileIOStateManager::~FileIOStateManager() {
+}
+
+void FileIOStateManager::SetOpenSucceed() {
+  file_open_ = true;
+}
+
+int32_t FileIOStateManager::CheckOperationState(OperationType new_op,
+                                                bool should_be_open) {
+  if (should_be_open) {
+    if (!file_open_)
+      return PP_ERROR_FAILED;
+  } else {
+    if (file_open_)
+      return PP_ERROR_FAILED;
+  }
+
+  if (pending_op_ != OPERATION_NONE &&
+      (pending_op_ != new_op || pending_op_ == OPERATION_EXCLUSIVE))
+    return PP_ERROR_INPROGRESS;
+
+  return PP_OK;
+}
+
+void FileIOStateManager::SetPendingOperation(OperationType new_op) {
+  DCHECK(pending_op_ == OPERATION_NONE ||
+         (pending_op_ != OPERATION_EXCLUSIVE && pending_op_ == new_op));
+  pending_op_ = new_op;
+  num_pending_ops_++;
+}
+
+void FileIOStateManager::SetOperationFinished() {
+  DCHECK_GT(num_pending_ops_, 0);
+  if (--num_pending_ops_ == 0)
+    pending_op_ = OPERATION_NONE;
+}
+
+}  // namespace ppapi
+
diff --git a/ppapi/shared_impl/file_io_state_manager.h b/ppapi/shared_impl/file_io_state_manager.h
new file mode 100644
index 0000000..7b5f926
--- /dev/null
+++ b/ppapi/shared_impl/file_io_state_manager.h
@@ -0,0 +1,69 @@
+// 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.
+
+#ifndef PPAPI_SHARED_IMPL_FILE_IO_STATE_MANAGER_H_
+#define PPAPI_SHARED_IMPL_FILE_IO_STATE_MANAGER_H_
+
+#include "base/basictypes.h"
+#include "base/compiler_specific.h"
+#include "ppapi/c/pp_stdint.h"
+#include "ppapi/shared_impl/ppapi_shared_export.h"
+
+namespace ppapi {
+
+// FileIOStateManager is a helper class that maintains the state of operations.
+// For example, some operations are mutually exclusive, meaning that an
+// operation could be rejected because of the current pending operation. Also,
+// most of the operations only work when the file has been opened.
+class PPAPI_SHARED_EXPORT FileIOStateManager {
+ public:
+  FileIOStateManager();
+  ~FileIOStateManager();
+
+  enum OperationType {
+    // There is no pending operation right now.
+    OPERATION_NONE,
+
+    // If there are pending reads, any other kind of async operation is not
+    // allowed.
+    OPERATION_READ,
+
+    // If there are pending writes, any other kind of async operation is not
+    // allowed.
+    OPERATION_WRITE,
+
+    // If there is a pending operation that is neither read nor write, no
+    // further async operation is allowed.
+    OPERATION_EXCLUSIVE
+  };
+
+  OperationType get_pending_operation() const { return pending_op_; }
+
+  void SetOpenSucceed();
+
+  // Called at the beginning of each operation. It is responsible to make sure
+  // that state is correct. For example, some operations are only valid after
+  // the file is opened, or operations might need to run exclusively.
+  //
+  // It returns |PP_OK| on success, or |PP_ERROR_...| for various reasons.
+  int32_t CheckOperationState(OperationType new_op, bool should_be_open);
+
+  // Marks the state of current operations as started or finished.
+  void SetPendingOperation(OperationType op);
+  void SetOperationFinished();
+
+ private:
+  int num_pending_ops_;
+  OperationType pending_op_;
+
+  // Set to true when the file has been successfully opened.
+  bool file_open_;
+
+  DISALLOW_COPY_AND_ASSIGN(FileIOStateManager);
+};
+
+}  // namespace ppapi
+
+#endif  // PPAPI_SHARED_IMPL_FILE_IO_STATE_MANAGER_H_
+
diff --git a/ppapi/shared_impl/file_path.cc b/ppapi/shared_impl/file_path.cc
index 1208b08..d05b1b3 100644
--- a/ppapi/shared_impl/file_path.cc
+++ b/ppapi/shared_impl/file_path.cc
@@ -4,48 +4,17 @@
 
 #include "ppapi/shared_impl/file_path.h"
 
-#include <string>
-
-#if defined(OS_WIN)
-#include "base/utf_string_conversions.h"
-#endif
-
 namespace ppapi {
 
-namespace {
-
-FilePath GetFilePathFromUTF8(const std::string& utf8_path) {
-#if defined(OS_WIN)
-  return FilePath(UTF8ToUTF16(utf8_path));
-#else
-  return FilePath(utf8_path);
-#endif
-}
-
-}  // namespace
-
 PepperFilePath::PepperFilePath()
     : domain_(DOMAIN_INVALID),
       path_() {
 }
 
-PepperFilePath::PepperFilePath(Domain domain, const FilePath& path)
+PepperFilePath::PepperFilePath(Domain domain, const base::FilePath& path)
     : domain_(domain),
       path_(path) {
   // TODO(viettrungluu): Should we DCHECK() some things here?
 }
 
-// static
-PepperFilePath PepperFilePath::MakeAbsolute(const FilePath& path) {
-  return PepperFilePath(DOMAIN_ABSOLUTE, path);
-}
-
-// static
-PepperFilePath PepperFilePath::MakeModuleLocal(const std::string& name,
-                                               const char* utf8_path) {
-  FilePath full_path = GetFilePathFromUTF8(name).Append(
-      GetFilePathFromUTF8(utf8_path));
-  return PepperFilePath(DOMAIN_MODULE_LOCAL, full_path);
-}
-
 }  // namespace ppapi
diff --git a/ppapi/shared_impl/file_path.h b/ppapi/shared_impl/file_path.h
index bcec9f8..7027e81 100644
--- a/ppapi/shared_impl/file_path.h
+++ b/ppapi/shared_impl/file_path.h
@@ -5,9 +5,7 @@
 #ifndef PPAPI_SHARED_IMPL_FILE_PATH_H_
 #define PPAPI_SHARED_IMPL_FILE_PATH_H_
 
-#include <string>
-
-#include "base/file_path.h"
+#include "base/files/file_path.h"
 #include "ppapi/shared_impl/ppapi_shared_export.h"
 
 namespace ppapi {
@@ -28,18 +26,14 @@
   };
 
   PepperFilePath();
-  PepperFilePath(Domain d, const FilePath& p);
-
-  static PepperFilePath MakeAbsolute(const FilePath& path);
-  static PepperFilePath MakeModuleLocal(const std::string& name,
-                                        const char* utf8_path);
+  PepperFilePath(Domain d, const base::FilePath& p);
 
   Domain domain() const { return domain_; }
-  const FilePath& path() const { return path_; }
+  const base::FilePath& path() const { return path_; }
 
  private:
   Domain domain_;
-  FilePath path_;
+  base::FilePath path_;
 };
 
 }  // namespace ppapi
diff --git a/ppapi/shared_impl/file_type_conversion.cc b/ppapi/shared_impl/file_type_conversion.cc
index a9bd435..5185daa 100644
--- a/ppapi/shared_impl/file_type_conversion.cc
+++ b/ppapi/shared_impl/file_type_conversion.cc
@@ -26,6 +26,8 @@
       return PP_ERROR_NOSPACE;
     case base::PLATFORM_FILE_ERROR_NOT_A_DIRECTORY:
       return PP_ERROR_FAILED;
+    case base::PLATFORM_FILE_ERROR_NOT_A_FILE:
+      return PP_ERROR_NOTAFILE;
     default:
       return PP_ERROR_FAILED;
   }
diff --git a/ppapi/shared_impl/host_resource.h b/ppapi/shared_impl/host_resource.h
index c98d2d6..3645edc 100644
--- a/ppapi/shared_impl/host_resource.h
+++ b/ppapi/shared_impl/host_resource.h
@@ -15,7 +15,10 @@
 // The point is to prevent mistakes where the wrong resource value is sent.
 // Resource values are remapped in the plugin so that it can talk to multiple
 // hosts. If all values were PP_Resource, it would be easy to forget to do
-// this tranformation.
+// this transformation.
+//
+// To get the corresponding plugin PP_Resource for a HostResource, use
+// PluginResourceTracker::PluginResourceForHostResource().
 //
 // All HostResources respresent IDs valid in the host.
 class PPAPI_SHARED_EXPORT HostResource {
diff --git a/ppapi/shared_impl/ppapi_globals.cc b/ppapi/shared_impl/ppapi_globals.cc
index 270d7e8..be10d4c 100644
--- a/ppapi/shared_impl/ppapi_globals.cc
+++ b/ppapi/shared_impl/ppapi_globals.cc
@@ -26,7 +26,7 @@
   main_loop_proxy_ = base::MessageLoopProxy::current();
 }
 
-PpapiGlobals::PpapiGlobals(ForTest) {
+PpapiGlobals::PpapiGlobals(PerThreadForTest) {
   DCHECK(!ppapi_globals_);
   main_loop_proxy_ = base::MessageLoopProxy::current();
 }
diff --git a/ppapi/shared_impl/ppapi_globals.h b/ppapi/shared_impl/ppapi_globals.h
index b03d35c..84b90e7 100644
--- a/ppapi/shared_impl/ppapi_globals.h
+++ b/ppapi/shared_impl/ppapi_globals.h
@@ -10,9 +10,9 @@
 #include "base/basictypes.h"
 #include "base/memory/ref_counted.h"
 #include "base/threading/thread_local.h"  // For testing purposes only.
-#include "ppapi/c/dev/ppb_console_dev.h"
 #include "ppapi/c/pp_instance.h"
 #include "ppapi/c/pp_module.h"
+#include "ppapi/c/ppb_console.h"
 #include "ppapi/shared_impl/api_id.h"
 #include "ppapi/shared_impl/ppapi_shared_export.h"
 
@@ -43,8 +43,8 @@
   // purposes. This avoids setting the global static ppapi_globals_. For unit
   // tests that use this feature, the "test" PpapiGlobals should be constructed
   // using this method. See SetPpapiGlobalsOnThreadForTest for more information.
-  struct ForTest {};
-  explicit PpapiGlobals(ForTest);
+  struct PerThreadForTest {};
+  explicit PpapiGlobals(PerThreadForTest);
 
   virtual ~PpapiGlobals();
 
@@ -64,7 +64,7 @@
   // the same process, e.g. for having 1 thread emulate the "host" and 1 thread
   // emulate the "plugin".
   //
-  // PpapiGlobals object must have been constructed using the "ForTest"
+  // PpapiGlobals object must have been constructed using the "PerThreadForTest"
   // parameter.
   static void SetPpapiGlobalsOnThreadForTest(PpapiGlobals* ptr);
 
@@ -79,7 +79,7 @@
   // Logs the given string to the JS console. If "source" is empty, the name of
   // the current module will be used, if it can be determined.
   virtual void LogWithSource(PP_Instance instance,
-                             PP_LogLevel_Dev level,
+                             PP_LogLevel level,
                              const std::string& source,
                              const std::string& value) = 0;
 
@@ -92,7 +92,7 @@
   // Note that in the plugin process, the module parameter is ignored since
   // there is only one possible one.
   virtual void BroadcastLogWithSource(PP_Module module,
-                                      PP_LogLevel_Dev level,
+                                      PP_LogLevel level,
                                       const std::string& source,
                                       const std::string& value) = 0;
 
diff --git a/ppapi/shared_impl/ppapi_preferences.cc b/ppapi/shared_impl/ppapi_preferences.cc
index c7bb0cb..a3ac413 100644
--- a/ppapi/shared_impl/ppapi_preferences.cc
+++ b/ppapi/shared_impl/ppapi_preferences.cc
@@ -11,7 +11,8 @@
       default_fixed_font_size(0),
       number_of_cpu_cores(0),
       is_3d_supported(true),
-      is_stage3d_supported(false) {
+      is_stage3d_supported(false),
+      is_stage3d_baseline_supported(false) {
 }
 
 Preferences::Preferences(const webkit_glue::WebPreferences& prefs)
@@ -24,10 +25,12 @@
       number_of_cpu_cores(prefs.number_of_cpu_cores),
       is_3d_supported(prefs.flash_3d_enabled),
       is_stage3d_supported(prefs.flash_stage3d_enabled),
+      is_stage3d_baseline_supported(prefs.flash_stage3d_baseline_enabled),
       // This determines both if webgl is supported (experimental_webgl_enabled)
-      // and if it runs in hardware (accelerated_plugins_enabled)
+      // and if it runs in hardware
+      // (accelerated_compositing_for_plugins_enabled)
       is_webgl_supported(prefs.experimental_webgl_enabled &&
-                         prefs.accelerated_plugins_enabled) {
+                         prefs.accelerated_compositing_for_plugins_enabled) {
 }
 
 Preferences::~Preferences() {
diff --git a/ppapi/shared_impl/ppapi_preferences.h b/ppapi/shared_impl/ppapi_preferences.h
index b098f55..dad7c0c 100644
--- a/ppapi/shared_impl/ppapi_preferences.h
+++ b/ppapi/shared_impl/ppapi_preferences.h
@@ -29,6 +29,7 @@
   int number_of_cpu_cores;
   bool is_3d_supported;
   bool is_stage3d_supported;
+  bool is_stage3d_baseline_supported;
   bool is_webgl_supported;
 };
 
diff --git a/ppapi/shared_impl/ppb_device_ref_shared.h b/ppapi/shared_impl/ppb_device_ref_shared.h
index 895baa5..9ea367e 100644
--- a/ppapi/shared_impl/ppb_device_ref_shared.h
+++ b/ppapi/shared_impl/ppb_device_ref_shared.h
@@ -21,6 +21,12 @@
 struct PPAPI_SHARED_EXPORT DeviceRefData {
   DeviceRefData();
 
+  bool operator==(const DeviceRefData& other) const {
+    return type == other.type &&
+           name == other.name &&
+           id == other.id;
+  }
+
   PP_DeviceType_Dev type;
   std::string name;
   std::string id;
diff --git a/ppapi/shared_impl/ppb_file_io_shared.cc b/ppapi/shared_impl/ppb_file_io_shared.cc
deleted file mode 100644
index b60e174..0000000
--- a/ppapi/shared_impl/ppb_file_io_shared.cc
+++ /dev/null
@@ -1,219 +0,0 @@
-// 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 "ppapi/shared_impl/ppb_file_io_shared.h"
-
-#include <string.h>
-
-#include "base/bind.h"
-#include "base/logging.h"
-#include "base/message_loop.h"
-#include "ppapi/c/pp_errors.h"
-#include "ppapi/shared_impl/file_type_conversion.h"
-#include "ppapi/shared_impl/time_conversion.h"
-#include "ppapi/thunk/enter.h"
-#include "ppapi/thunk/ppb_file_ref_api.h"
-
-namespace ppapi {
-
-using thunk::EnterResourceNoLock;
-using thunk::PPB_FileIO_API;
-using thunk::PPB_FileRef_API;
-
-PPB_FileIO_Shared::CallbackEntry::CallbackEntry()
-    : read_buffer(NULL),
-      info(NULL) {
-}
-
-PPB_FileIO_Shared::CallbackEntry::CallbackEntry(const CallbackEntry& entry)
-    : callback(entry.callback),
-      read_buffer(entry.read_buffer),
-      info(entry.info) {
-}
-
-PPB_FileIO_Shared::CallbackEntry::~CallbackEntry() {
-}
-
-PPB_FileIO_Shared::PPB_FileIO_Shared(PP_Instance instance)
-    : Resource(OBJECT_IS_IMPL, instance),
-      file_system_type_(PP_FILESYSTEMTYPE_INVALID),
-      file_open_(false),
-      pending_op_(OPERATION_NONE) {
-}
-
-PPB_FileIO_Shared::PPB_FileIO_Shared(const HostResource& host_resource)
-    : Resource(OBJECT_IS_PROXY, host_resource),
-      file_system_type_(PP_FILESYSTEMTYPE_INVALID),
-      file_open_(false),
-      pending_op_(OPERATION_NONE) {
-}
-
-PPB_FileIO_Shared::~PPB_FileIO_Shared() {
-}
-
-thunk::PPB_FileIO_API* PPB_FileIO_Shared::AsPPB_FileIO_API() {
-  return this;
-}
-
-int32_t PPB_FileIO_Shared::Open(PP_Resource file_ref,
-                                int32_t open_flags,
-                                scoped_refptr<TrackedCallback> callback) {
-  EnterResourceNoLock<PPB_FileRef_API> enter(file_ref, true);
-  if (enter.failed())
-    return PP_ERROR_BADRESOURCE;
-
-  int32_t rv = CommonCallValidation(false, OPERATION_EXCLUSIVE);
-  if (rv != PP_OK)
-    return rv;
-
-  PP_FileSystemType type = enter.object()->GetFileSystemType();
-  if (type != PP_FILESYSTEMTYPE_LOCALPERSISTENT &&
-      type != PP_FILESYSTEMTYPE_LOCALTEMPORARY &&
-      type != PP_FILESYSTEMTYPE_EXTERNAL)
-    return PP_ERROR_FAILED;
-  file_system_type_ = type;
-
-  return OpenValidated(file_ref, enter.object(), open_flags, callback);
-}
-
-int32_t PPB_FileIO_Shared::Query(PP_FileInfo* info,
-                                 scoped_refptr<TrackedCallback> callback) {
-  int32_t rv = CommonCallValidation(true, OPERATION_EXCLUSIVE);
-  if (rv != PP_OK)
-    return rv;
-  if (!info)
-    return PP_ERROR_BADARGUMENT;
-  return QueryValidated(info, callback);
-}
-
-int32_t PPB_FileIO_Shared::Touch(PP_Time last_access_time,
-                                 PP_Time last_modified_time,
-                                 scoped_refptr<TrackedCallback> callback) {
-  int32_t rv = CommonCallValidation(true, OPERATION_EXCLUSIVE);
-  if (rv != PP_OK)
-    return rv;
-  return TouchValidated(last_access_time, last_modified_time, callback);
-}
-
-int32_t PPB_FileIO_Shared::Read(int64_t offset,
-                                char* buffer,
-                                int32_t bytes_to_read,
-                                scoped_refptr<TrackedCallback> callback) {
-  int32_t rv = CommonCallValidation(true, OPERATION_READ);
-  if (rv != PP_OK)
-    return rv;
-  return ReadValidated(offset, buffer, bytes_to_read, callback);
-}
-
-int32_t PPB_FileIO_Shared::Write(int64_t offset,
-                                 const char* buffer,
-                                 int32_t bytes_to_write,
-                                 scoped_refptr<TrackedCallback> callback) {
-  int32_t rv = CommonCallValidation(true, OPERATION_WRITE);
-  if (rv != PP_OK)
-    return rv;
-  return WriteValidated(offset, buffer, bytes_to_write, callback);
-}
-
-int32_t PPB_FileIO_Shared::SetLength(int64_t length,
-                                     scoped_refptr<TrackedCallback> callback) {
-  int32_t rv = CommonCallValidation(true, OPERATION_EXCLUSIVE);
-  if (rv != PP_OK)
-    return rv;
-  return SetLengthValidated(length, callback);
-}
-
-int32_t PPB_FileIO_Shared::Flush(scoped_refptr<TrackedCallback> callback) {
-  int32_t rv = CommonCallValidation(true, OPERATION_EXCLUSIVE);
-  if (rv != PP_OK)
-    return rv;
-  return FlushValidated(callback);
-}
-
-void PPB_FileIO_Shared::ExecuteGeneralCallback(int32_t pp_error) {
-  RunAndRemoveFirstPendingCallback(pp_error);
-}
-
-void PPB_FileIO_Shared::ExecuteOpenFileCallback(int32_t pp_error) {
-  if (pp_error == PP_OK)
-    file_open_ = true;
-  ExecuteGeneralCallback(pp_error);
-}
-
-void PPB_FileIO_Shared::ExecuteQueryCallback(int32_t pp_error,
-                                             const PP_FileInfo& info) {
-  if (pending_op_ != OPERATION_EXCLUSIVE || callbacks_.empty() ||
-      !callbacks_.front().info) {
-    NOTREACHED();
-    return;
-  }
-  *callbacks_.front().info = info;
-  RunAndRemoveFirstPendingCallback(pp_error);
-}
-
-void PPB_FileIO_Shared::ExecuteReadCallback(int32_t pp_error,
-                                            const char* data) {
-  if (pending_op_ != OPERATION_READ || callbacks_.empty()) {
-    NOTREACHED();
-    return;
-  }
-
-  // The result code contains the number of bytes if it's positive.
-  if (pp_error > 0) {
-    char* read_buffer = callbacks_.front().read_buffer;
-    DCHECK(data);
-    DCHECK(read_buffer);
-    memcpy(read_buffer, data, pp_error);
-  }
-  RunAndRemoveFirstPendingCallback(pp_error);
-}
-
-int32_t PPB_FileIO_Shared::CommonCallValidation(bool should_be_open,
-                                                OperationType new_op) {
-  // Only asynchronous operation is supported.
-  if (should_be_open) {
-    if (!file_open_)
-      return PP_ERROR_FAILED;
-  } else {
-    if (file_open_)
-      return PP_ERROR_FAILED;
-  }
-
-  if (pending_op_ != OPERATION_NONE &&
-      (pending_op_ != new_op || pending_op_ == OPERATION_EXCLUSIVE)) {
-    return PP_ERROR_INPROGRESS;
-  }
-
-  return PP_OK;
-}
-
-void PPB_FileIO_Shared::RegisterCallback(
-    OperationType op,
-    scoped_refptr<TrackedCallback> callback,
-    char* read_buffer,
-    PP_FileInfo* info) {
-  DCHECK(pending_op_ == OPERATION_NONE ||
-         (pending_op_ != OPERATION_EXCLUSIVE && pending_op_ == op));
-
-  CallbackEntry entry;
-  entry.callback = callback;
-  entry.read_buffer = read_buffer;
-  entry.info = info;
-  callbacks_.push_back(entry);
-
-  pending_op_ = op;
-}
-
-void PPB_FileIO_Shared::RunAndRemoveFirstPendingCallback(int32_t result) {
-  DCHECK(!callbacks_.empty());
-
-  CallbackEntry front = callbacks_.front();
-  callbacks_.pop_front();
-  if (callbacks_.empty())
-    pending_op_ = OPERATION_NONE;
-
-  front.callback->Run(result);
-}
-
-}  // namespace ppapi
diff --git a/ppapi/shared_impl/ppb_file_io_shared.h b/ppapi/shared_impl/ppb_file_io_shared.h
deleted file mode 100644
index a062497..0000000
--- a/ppapi/shared_impl/ppb_file_io_shared.h
+++ /dev/null
@@ -1,156 +0,0 @@
-// 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.
-
-#ifndef PPAPI_SHARED_IMPL_PPB_FILE_IO_SHARED_H_
-#define PPAPI_SHARED_IMPL_PPB_FILE_IO_SHARED_H_
-
-#include <deque>
-
-#include "base/compiler_specific.h"
-#include "ppapi/shared_impl/ppapi_shared_export.h"
-#include "ppapi/shared_impl/resource.h"
-#include "ppapi/shared_impl/tracked_callback.h"
-#include "ppapi/thunk/ppb_file_io_api.h"
-
-namespace ppapi {
-
-namespace thunk {
-class PPB_FileRef_API;
-}
-
-class PPAPI_SHARED_EXPORT PPB_FileIO_Shared : public Resource,
-                                              public thunk::PPB_FileIO_API {
- public:
-  PPB_FileIO_Shared(PP_Instance instance);
-  PPB_FileIO_Shared(const HostResource& host_resource);
-  ~PPB_FileIO_Shared();
-
-  // Resource overrides.
-  virtual thunk::PPB_FileIO_API* AsPPB_FileIO_API() OVERRIDE;
-
-  // PPB_FileIO_API implementation.
-  virtual int32_t Open(PP_Resource file_ref,
-                       int32_t open_flags,
-                       scoped_refptr<TrackedCallback> callback) OVERRIDE;
-  virtual int32_t Query(PP_FileInfo* info,
-                        scoped_refptr<TrackedCallback> callback) OVERRIDE;
-  virtual int32_t Touch(PP_Time last_access_time,
-                        PP_Time last_modified_time,
-                        scoped_refptr<TrackedCallback> callback) OVERRIDE;
-  virtual int32_t Read(int64_t offset,
-                       char* buffer,
-                       int32_t bytes_to_read,
-                       scoped_refptr<TrackedCallback> callback) OVERRIDE;
-  virtual int32_t Write(int64_t offset,
-                        const char* buffer,
-                        int32_t bytes_to_write,
-                        scoped_refptr<TrackedCallback> callback) OVERRIDE;
-  virtual int32_t SetLength(int64_t length,
-                            scoped_refptr<TrackedCallback> callback) OVERRIDE;
-  virtual int32_t Flush(scoped_refptr<TrackedCallback> callback) OVERRIDE;
-
-  // Callback handler for different types of operations.
-  void ExecuteGeneralCallback(int32_t pp_error);
-  void ExecuteOpenFileCallback(int32_t pp_error);
-  void ExecuteQueryCallback(int32_t pp_error, const PP_FileInfo& info);
-  void ExecuteReadCallback(int32_t pp_error, const char* data);
-
- protected:
-  struct CallbackEntry {
-    CallbackEntry();
-    CallbackEntry(const CallbackEntry& entry);
-    ~CallbackEntry();
-
-    scoped_refptr<TrackedCallback> callback;
-
-    // Pointer back to the caller's read buffer; only used by |Read()|, NULL
-    // for non-read operations. Not owned.
-    char* read_buffer;
-
-    // Pointer back to the caller's PP_FileInfo structure for Query operations.
-    // NULL for non-query operations. Not owned.
-    PP_FileInfo* info;
-  };
-
-  enum OperationType {
-    // There is no pending operation right now.
-    OPERATION_NONE,
-
-    // If there are pending reads, any other kind of async operation is not
-    // allowed.
-    OPERATION_READ,
-
-    // If there are pending writes, any other kind of async operation is not
-    // allowed.
-    OPERATION_WRITE,
-
-    // If there is a pending operation that is neither read nor write, no
-    // further async operation is allowed.
-    OPERATION_EXCLUSIVE
-  };
-
-  // Validated versions of the FileIO API. Subclasses in the proxy and impl
-  // implement these so the common error checking stays here.
-  virtual int32_t OpenValidated(PP_Resource file_ref_resource,
-                                thunk::PPB_FileRef_API* file_ref_api,
-                                int32_t open_flags,
-                                scoped_refptr<TrackedCallback> callback) = 0;
-  virtual int32_t QueryValidated(PP_FileInfo* info,
-                                 scoped_refptr<TrackedCallback> callback) = 0;
-  virtual int32_t TouchValidated(PP_Time last_access_time,
-                                 PP_Time last_modified_time,
-                                 scoped_refptr<TrackedCallback> callback) = 0;
-  virtual int32_t ReadValidated(int64_t offset,
-                                char* buffer,
-                                int32_t bytes_to_read,
-                                scoped_refptr<TrackedCallback> callback) = 0;
-  virtual int32_t WriteValidated(int64_t offset,
-                                 const char* buffer,
-                                 int32_t bytes_to_write,
-                                 scoped_refptr<TrackedCallback> callback) = 0;
-  virtual int32_t SetLengthValidated(
-      int64_t length,
-      scoped_refptr<TrackedCallback> callback) = 0;
-  virtual int32_t FlushValidated(scoped_refptr<TrackedCallback> callback) = 0;
-
-  // Called for every "Validated" function.
-  //
-  // This verifies that the callback is valid and that no callback is already
-  // pending, or it is a read(write) request and currently the pending
-  // operations are reads(writes).
-  //
-  // Returns |PP_OK| to indicate that everything is valid or |PP_ERROR_...| if
-  // the call should be aborted and that code returned to the plugin.
-  int32_t CommonCallValidation(bool should_be_open, OperationType new_op);
-
-  // Sets up a pending callback. This should only be called once it is certain
-  // that |PP_OK_COMPLETIONPENDING| will be returned.
-  //
-  // |read_buffer| is only used by read operations, |info| is used only by
-  // query operations.
-  void RegisterCallback(OperationType op,
-                        scoped_refptr<TrackedCallback> callback,
-                        char* read_buffer,
-                        PP_FileInfo* info);
-
-  // Pops the oldest callback from the queue and runs it.
-  void RunAndRemoveFirstPendingCallback(int32_t result);
-
-  // The file system type specified in the Open() call. This will be
-  // PP_FILESYSTEMTYPE_INVALID before open was called. This value does not
-  // indicate that the open command actually succeeded.
-  PP_FileSystemType file_system_type_;
-
-  // Set to true when the file has been successfully opened.
-  bool file_open_;
-
-  std::deque<CallbackEntry> callbacks_;
-  OperationType pending_op_;
-
-  DISALLOW_COPY_AND_ASSIGN(PPB_FileIO_Shared);
-};
-
-}  // namespace ppapi
-
-#endif  // PPAPI_SHARED_IMPL_PPB_FILE_IO_SHARED_H_
diff --git a/ppapi/shared_impl/ppb_flash_shared.cc b/ppapi/shared_impl/ppb_flash_shared.cc
deleted file mode 100644
index c310e0e..0000000
--- a/ppapi/shared_impl/ppb_flash_shared.cc
+++ /dev/null
@@ -1,23 +0,0 @@
-// 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 "ppapi/shared_impl/ppb_flash_shared.h"
-
-namespace ppapi {
-
-PPB_Flash_Shared::PPB_Flash_Shared() {
-}
-
-PPB_Flash_Shared::~PPB_Flash_Shared() {
-}
-
-void PPB_Flash_Shared::FreeDirContents(PP_Instance instance,
-                                       PP_DirContents_Dev* contents) {
-  for (int32_t i = 0; i < contents->count; ++i)
-    delete[] contents->entries[i].name;
-  delete[] contents->entries;
-  delete contents;
-}
-
-}  // namespace ppapi
diff --git a/ppapi/shared_impl/ppb_flash_shared.h b/ppapi/shared_impl/ppb_flash_shared.h
deleted file mode 100644
index 29f8973..0000000
--- a/ppapi/shared_impl/ppb_flash_shared.h
+++ /dev/null
@@ -1,30 +0,0 @@
-// 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.
-
-#ifndef PPAPI_SHARED_IMPL_PPB_FLASH_SHARED_H_
-#define PPAPI_SHARED_IMPL_PPB_FLASH_SHARED_H_
-
-#include "base/basictypes.h"
-#include "base/compiler_specific.h"
-#include "ppapi/shared_impl/ppapi_shared_export.h"
-#include "ppapi/thunk/ppb_flash_api.h"
-
-namespace ppapi {
-
-class PPAPI_SHARED_EXPORT PPB_Flash_Shared : public thunk::PPB_Flash_API {
- public:
-  PPB_Flash_Shared();
-  virtual ~PPB_Flash_Shared();
-
-  // Shared implementation of PPB_Flash_API.
-  virtual void FreeDirContents(PP_Instance instance,
-                               PP_DirContents_Dev* contents) OVERRIDE;
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(PPB_Flash_Shared);
-};
-
-}  // namespace ppapi
-
-#endif  // PPAPI_SHARED_IMPL_PPB_FLASH_SHARED_H_
diff --git a/ppapi/shared_impl/ppb_graphics_3d_shared.cc b/ppapi/shared_impl/ppb_graphics_3d_shared.cc
index 0278c42..e2d0154 100644
--- a/ppapi/shared_impl/ppb_graphics_3d_shared.cc
+++ b/ppapi/shared_impl/ppb_graphics_3d_shared.cc
@@ -60,6 +60,8 @@
     scoped_refptr<TrackedCallback> callback) {
   ScopedNoLocking already_locked(this);
   if (HasPendingSwap()) {
+    Log(PP_LOGLEVEL_ERROR, "PPB_Graphics3D.SwapBuffers: Plugin attempted swap "
+                           "with previous swap still pending.");
     // Already a pending SwapBuffers that hasn't returned yet.
     return PP_ERROR_INPROGRESS;
   }
diff --git a/ppapi/shared_impl/ppb_graphics_3d_shared.h b/ppapi/shared_impl/ppb_graphics_3d_shared.h
index b6185f8..96bc6bb 100644
--- a/ppapi/shared_impl/ppb_graphics_3d_shared.h
+++ b/ppapi/shared_impl/ppb_graphics_3d_shared.h
@@ -99,6 +99,10 @@
   virtual void PushAlreadyLocked();
   virtual void PopAlreadyLocked();
 
+  // The VideoDecoder needs to be able to call Graphics3D Flush() after taking
+  // the proxy lock. Hence it needs access to ScopedNoLocking.
+  friend class PPB_VideoDecoder_Shared;
+
   scoped_ptr<gpu::gles2::GLES2CmdHelper> gles2_helper_;
   scoped_ptr<gpu::TransferBuffer> transfer_buffer_;
   scoped_ptr<gpu::gles2::GLES2Implementation> gles2_impl_;
diff --git a/ppapi/shared_impl/ppb_instance_shared.cc b/ppapi/shared_impl/ppb_instance_shared.cc
index dd46bec..18033fc 100644
--- a/ppapi/shared_impl/ppb_instance_shared.cc
+++ b/ppapi/shared_impl/ppb_instance_shared.cc
@@ -6,6 +6,8 @@
 
 #include <string>
 
+#include "base/debug/trace_event.h"
+#include "base/threading/platform_thread.h"
 #include "ppapi/c/pp_errors.h"
 #include "ppapi/c/ppb_input_event.h"
 #include "ppapi/shared_impl/ppapi_globals.h"
@@ -23,13 +25,13 @@
 }
 
 void PPB_Instance_Shared::Log(PP_Instance instance,
-                              PP_LogLevel_Dev level,
+                              PP_LogLevel level,
                               PP_Var value) {
   LogWithSource(instance, level, PP_MakeUndefined(), value);
 }
 
 void PPB_Instance_Shared::LogWithSource(PP_Instance instance,
-                                        PP_LogLevel_Dev level,
+                                        PP_LogLevel level,
                                         PP_Var source,
                                         PP_Var value) {
   // The source defaults to empty if it's not a string. The PpapiGlobals
diff --git a/ppapi/shared_impl/ppb_instance_shared.h b/ppapi/shared_impl/ppb_instance_shared.h
index a1845d3..61ca56d 100644
--- a/ppapi/shared_impl/ppb_instance_shared.h
+++ b/ppapi/shared_impl/ppb_instance_shared.h
@@ -19,10 +19,10 @@
 
   // Implementation of some shared PPB_Instance_FunctionAPI functions.
   virtual void Log(PP_Instance instance,
-                   PP_LogLevel_Dev log_level,
+                   PP_LogLevel log_level,
                    PP_Var value) OVERRIDE;
   virtual void LogWithSource(PP_Instance instance,
-                             PP_LogLevel_Dev log_level,
+                             PP_LogLevel log_level,
                              PP_Var source,
                              PP_Var value) OVERRIDE;
 
diff --git a/ppapi/shared_impl/ppb_trace_event_impl.cc b/ppapi/shared_impl/ppb_trace_event_impl.cc
new file mode 100644
index 0000000..439bbd4
--- /dev/null
+++ b/ppapi/shared_impl/ppb_trace_event_impl.cc
@@ -0,0 +1,74 @@
+// 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 "ppapi/shared_impl/ppb_trace_event_impl.h"
+
+#include "base/debug/trace_event.h"
+#include "ppapi/thunk/thunk.h"
+
+
+namespace ppapi {
+
+// PPB_Trace_Event_Dev is a shared implementation because Trace Events can be
+// sent from either the plugin process or renderer process depending on whether
+// the plugin is in- or out-of-process.  Also, for NaCl plugins these functions
+// will be executed from untrusted code and handled appropriately by tracing
+// functionality in the IRT.
+
+// static
+void* TraceEventImpl::GetCategoryEnabled(const char* category_name) {
+  // This casting is here because all mem_t return types in Pepper are void* and
+  // non-const.  All mem_t parameters are const void* so there is no way to
+  // return a pointer type to the caller without some const_cast.  The pointer
+  // type the tracing system works with is normally unsigned char*.
+  return const_cast<void*>(static_cast<const void*>(
+      base::debug::TraceLog::GetInstance()->GetCategoryEnabled(category_name)));
+}
+
+// static
+void TraceEventImpl::AddTraceEvent(int8_t phase,
+                                      const void* category_enabled,
+                                      const char* name,
+                                      uint64_t id,
+                                      uint32_t num_args,
+                                      const char* arg_names[],
+                                      const uint8_t arg_types[],
+                                      const uint64_t arg_values[],
+                                      uint8_t flags) {
+  base::debug::TraceLog::GetInstance()->AddTraceEvent(phase,
+      static_cast<const unsigned char*>(category_enabled), name, id, num_args,
+      arg_names, arg_types,
+      // This cast is necessary for LP64 systems, where uint64_t is defined as
+      // an unsigned long int, but trace_event internals are hermetic and
+      // accepts an |unsigned long long*|.  The pointer types are compatible but
+      // the compiler throws an error without an explicit cast.
+      reinterpret_cast<const unsigned long long*>(arg_values), flags);
+}
+
+// static
+void TraceEventImpl::SetThreadName(const char* thread_name) {
+  base::PlatformThread::SetName(thread_name);
+}
+
+namespace {
+
+const PPB_Trace_Event_Dev g_ppb_trace_event_thunk = {
+  &TraceEventImpl::GetCategoryEnabled,
+  &TraceEventImpl::AddTraceEvent,
+  &TraceEventImpl::SetThreadName,
+};
+
+}  // namespace ppapi
+
+}  // namespace
+
+namespace ppapi {
+namespace thunk {
+
+const PPB_Trace_Event_Dev_0_1* GetPPB_Trace_Event_Dev_0_1_Thunk() {
+  return &g_ppb_trace_event_thunk;
+}
+
+}  // namespace thunk
+}  // namespace ppapi
diff --git a/ppapi/shared_impl/ppb_trace_event_impl.h b/ppapi/shared_impl/ppb_trace_event_impl.h
new file mode 100644
index 0000000..21a77ac
--- /dev/null
+++ b/ppapi/shared_impl/ppb_trace_event_impl.h
@@ -0,0 +1,35 @@
+// 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.
+
+#ifndef PPAPI_SHARED_IMPL_PPB_TRACE_EVENT_IMPL_H_
+#define PPAPI_SHARED_IMPL_PPB_TRACE_EVENT_IMPL_H_
+
+#include "ppapi/c/dev/ppb_trace_event_dev.h"
+#include "ppapi/c/pp_bool.h"
+#include "ppapi/shared_impl/ppapi_shared_export.h"
+
+namespace ppapi {
+
+// Contains the implementation of the PPB_Trace_Event_Dev functions. Since these
+// functions are to be run from whatever plugin process/thread in which they
+// originated, the implementation lives in shared_impl.
+//
+class PPAPI_SHARED_EXPORT TraceEventImpl {
+ public:
+  static void* GetCategoryEnabled(const char* category_name);
+  static void AddTraceEvent(int8_t phase,
+                               const void* category_enabled,
+                               const char* name,
+                               uint64_t id,
+                               uint32_t num_args,
+                               const char* arg_names[],
+                               const uint8_t arg_types[],
+                               const uint64_t arg_values[],
+                               uint8_t flags);
+  static void SetThreadName(const char* thread_name);
+};
+
+}  // namespace ppapi
+
+#endif  // PPAPI_SHARED_IMPL_PPB_TRACE_EVENT_IMPL_H_
diff --git a/ppapi/shared_impl/ppb_url_util_shared.cc b/ppapi/shared_impl/ppb_url_util_shared.cc
index f473530..7788f4a 100644
--- a/ppapi/shared_impl/ppb_url_util_shared.cc
+++ b/ppapi/shared_impl/ppb_url_util_shared.cc
@@ -6,6 +6,7 @@
 
 #include "googleurl/src/gurl.h"
 #include "ppapi/shared_impl/ppapi_globals.h"
+#include "ppapi/shared_impl/proxy_lock.h"
 #include "ppapi/shared_impl/var.h"
 #include "ppapi/shared_impl/var_tracker.h"
 
@@ -45,6 +46,7 @@
 // static
 PP_Var PPB_URLUtil_Shared::Canonicalize(PP_Var url,
                                         PP_URLComponents_Dev* components) {
+  ProxyAutoLock lock;
   StringVar* url_string = StringVar::FromPPVar(url);
   if (!url_string)
     return PP_MakeNull();
@@ -56,6 +58,7 @@
     PP_Var base_url,
     PP_Var relative,
     PP_URLComponents_Dev* components) {
+  ProxyAutoLock lock;
   StringVar* base_url_string = StringVar::FromPPVar(base_url);
   StringVar* relative_string = StringVar::FromPPVar(relative);
   if (!base_url_string || !relative_string)
@@ -70,6 +73,7 @@
 
 // static
 PP_Bool PPB_URLUtil_Shared::IsSameSecurityOrigin(PP_Var url_a, PP_Var url_b) {
+  ProxyAutoLock lock;
   StringVar* url_a_string = StringVar::FromPPVar(url_a);
   StringVar* url_b_string = StringVar::FromPPVar(url_b);
   if (!url_a_string || !url_b_string)
diff --git a/ppapi/shared_impl/ppb_var_shared.cc b/ppapi/shared_impl/ppb_var_shared.cc
index 107058a..702a89a 100644
--- a/ppapi/shared_impl/ppb_var_shared.cc
+++ b/ppapi/shared_impl/ppb_var_shared.cc
@@ -24,17 +24,17 @@
 // PPB_Var methods -------------------------------------------------------------
 
 void AddRefVar(PP_Var var) {
-  ppapi::ProxyAutoLock lock;
+  ProxyAutoLock lock;
   PpapiGlobals::Get()->GetVarTracker()->AddRefVar(var);
 }
 
 void ReleaseVar(PP_Var var) {
-  ppapi::ProxyAutoLock lock;
+  ProxyAutoLock lock;
   PpapiGlobals::Get()->GetVarTracker()->ReleaseVar(var);
 }
 
 PP_Var VarFromUtf8(const char* data, uint32_t len) {
-  ppapi::ProxyAutoLock lock;
+  ProxyAutoLock lock;
   return StringVar::StringToPPVar(data, len);
 }
 
@@ -43,7 +43,7 @@
 }
 
 const char* VarToUtf8(PP_Var var, uint32_t* len) {
-  ppapi::ProxyAutoLock lock;
+  ProxyAutoLock lock;
   StringVar* str = StringVar::FromPPVar(var);
   if (str) {
     *len = static_cast<uint32_t>(str->value().size());
@@ -71,11 +71,13 @@
 // PPB_VarArrayBuffer methods --------------------------------------------------
 
 PP_Var CreateArrayBufferVar(uint32_t size_in_bytes) {
+  ProxyAutoLock lock;
   return PpapiGlobals::Get()->GetVarTracker()->MakeArrayBufferPPVar(
       size_in_bytes);
 }
 
 PP_Bool ByteLength(PP_Var array, uint32_t* byte_length) {
+  ProxyAutoLock lock;
   ArrayBufferVar* buffer = ArrayBufferVar::FromPPVar(array);
   if (!buffer)
     return PP_FALSE;
@@ -84,6 +86,7 @@
 }
 
 void* Map(PP_Var array) {
+  ProxyAutoLock lock;
   ArrayBufferVar* buffer = ArrayBufferVar::FromPPVar(array);
   if (!buffer)
     return NULL;
@@ -91,6 +94,7 @@
 }
 
 void Unmap(PP_Var array) {
+  ProxyAutoLock lock;
   ArrayBufferVar* buffer = ArrayBufferVar::FromPPVar(array);
   if (buffer)
     buffer->Unmap();
diff --git a/ppapi/shared_impl/ppb_video_capture_shared.cc b/ppapi/shared_impl/ppb_video_capture_shared.cc
deleted file mode 100644
index 2a51b95..0000000
--- a/ppapi/shared_impl/ppb_video_capture_shared.cc
+++ /dev/null
@@ -1,187 +0,0 @@
-// 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 "ppapi/shared_impl/ppb_video_capture_shared.h"
-
-#include "base/logging.h"
-#include "ppapi/c/pp_errors.h"
-#include "ppapi/shared_impl/ppb_device_ref_shared.h"
-#include "ppapi/shared_impl/ppb_resource_array_shared.h"
-
-namespace ppapi {
-
-PPB_VideoCapture_Shared::PPB_VideoCapture_Shared(PP_Instance instance)
-    : Resource(OBJECT_IS_IMPL, instance),
-      open_state_(BEFORE_OPEN),
-      status_(PP_VIDEO_CAPTURE_STATUS_STOPPED),
-      devices_(NULL),
-      resource_object_type_(OBJECT_IS_IMPL) {
-}
-
-PPB_VideoCapture_Shared::PPB_VideoCapture_Shared(
-    const HostResource& host_resource)
-    : Resource(OBJECT_IS_PROXY, host_resource),
-      open_state_(BEFORE_OPEN),
-      status_(PP_VIDEO_CAPTURE_STATUS_STOPPED),
-      devices_(NULL),
-      resource_object_type_(OBJECT_IS_PROXY) {
-}
-
-PPB_VideoCapture_Shared::~PPB_VideoCapture_Shared() {
-}
-
-thunk::PPB_VideoCapture_API* PPB_VideoCapture_Shared::AsPPB_VideoCapture_API() {
-  return this;
-}
-
-int32_t PPB_VideoCapture_Shared::EnumerateDevices(
-    PP_Resource* devices,
-    scoped_refptr<TrackedCallback> callback) {
-  if (TrackedCallback::IsPending(enumerate_devices_callback_))
-    return PP_ERROR_INPROGRESS;
-
-  return InternalEnumerateDevices(devices, callback);
-}
-
-int32_t PPB_VideoCapture_Shared::Open(
-    const std::string& device_id,
-    const PP_VideoCaptureDeviceInfo_Dev& requested_info,
-    uint32_t buffer_count,
-    scoped_refptr<TrackedCallback> callback) {
-  if (open_state_ != BEFORE_OPEN)
-    return PP_ERROR_FAILED;
-
-  if (TrackedCallback::IsPending(open_callback_))
-    return PP_ERROR_INPROGRESS;
-
-  return InternalOpen(device_id, requested_info, buffer_count, callback);
-}
-
-int32_t PPB_VideoCapture_Shared::StartCapture() {
-  if (open_state_ != OPENED ||
-      !SetStatus(PP_VIDEO_CAPTURE_STATUS_STARTING, false)) {
-    return PP_ERROR_FAILED;
-  }
-
-  return InternalStartCapture();
-}
-
-int32_t PPB_VideoCapture_Shared::ReuseBuffer(uint32_t buffer) {
-  return InternalReuseBuffer(buffer);
-}
-
-int32_t PPB_VideoCapture_Shared::StopCapture() {
-  if (open_state_ != OPENED ||
-      !SetStatus(PP_VIDEO_CAPTURE_STATUS_STOPPING, false)) {
-    return PP_ERROR_FAILED;
-  }
-
-  return InternalStopCapture();
-}
-
-void PPB_VideoCapture_Shared::Close() {
-  if (open_state_ == CLOSED)
-    return;
-
-  InternalClose();
-  open_state_ = CLOSED;
-
-  if (TrackedCallback::IsPending(open_callback_))
-    open_callback_->PostAbort();
-}
-
-int32_t PPB_VideoCapture_Shared::StartCapture0_1(
-    const PP_VideoCaptureDeviceInfo_Dev& requested_info,
-    uint32_t buffer_count) {
-  if (open_state_ == BEFORE_OPEN) {
-    if (TrackedCallback::IsPending(open_callback_))
-      return PP_ERROR_FAILED;
-    open_state_ = OPENED;
-  } else if (open_state_ == CLOSED) {
-    return PP_ERROR_FAILED;
-  }
-
-  if (!SetStatus(PP_VIDEO_CAPTURE_STATUS_STARTING, false))
-    return PP_ERROR_FAILED;
-
-  return InternalStartCapture0_1(requested_info, buffer_count);
-}
-
-const std::vector<DeviceRefData>& PPB_VideoCapture_Shared::GetDeviceRefData(
-    ) const {
-  return InternalGetDeviceRefData();
-}
-
-void PPB_VideoCapture_Shared::OnEnumerateDevicesComplete(
-    int32_t result,
-    const std::vector<DeviceRefData>& devices) {
-  DCHECK(TrackedCallback::IsPending(enumerate_devices_callback_));
-
-  if (result == PP_OK && devices_) {
-    *devices_ = PPB_DeviceRef_Shared::CreateResourceArray(
-        resource_object_type_, pp_instance(), devices);
-  }
-  devices_ = NULL;
-
-  enumerate_devices_callback_->Run(result);
-}
-
-void PPB_VideoCapture_Shared::OnOpenComplete(int32_t result) {
-  if (open_state_ == BEFORE_OPEN && result == PP_OK)
-    open_state_ = OPENED;
-
-  // The callback may have been aborted by Close(), or the open operation is
-  // completed synchronously.
-  if (TrackedCallback::IsPending(open_callback_))
-    open_callback_->Run(result);
-}
-
-bool PPB_VideoCapture_Shared::SetStatus(PP_VideoCaptureStatus_Dev status,
-                                        bool forced) {
-  if (!forced) {
-    switch (status) {
-      case PP_VIDEO_CAPTURE_STATUS_STOPPED:
-        if (status_ != PP_VIDEO_CAPTURE_STATUS_STOPPING)
-          return false;
-        break;
-      case PP_VIDEO_CAPTURE_STATUS_STARTING:
-        if (status_ != PP_VIDEO_CAPTURE_STATUS_STOPPED)
-          return false;
-        break;
-      case PP_VIDEO_CAPTURE_STATUS_STARTED:
-        switch (status_) {
-          case PP_VIDEO_CAPTURE_STATUS_STARTING:
-          case PP_VIDEO_CAPTURE_STATUS_PAUSED:
-            break;
-          default:
-            return false;
-        }
-        break;
-      case PP_VIDEO_CAPTURE_STATUS_PAUSED:
-        switch (status_) {
-          case PP_VIDEO_CAPTURE_STATUS_STARTING:
-          case PP_VIDEO_CAPTURE_STATUS_STARTED:
-            break;
-          default:
-            return false;
-        }
-        break;
-      case PP_VIDEO_CAPTURE_STATUS_STOPPING:
-        switch (status_) {
-          case PP_VIDEO_CAPTURE_STATUS_STARTING:
-          case PP_VIDEO_CAPTURE_STATUS_STARTED:
-          case PP_VIDEO_CAPTURE_STATUS_PAUSED:
-            break;
-          default:
-            return false;
-        }
-        break;
-    }
-  }
-
-  status_ = status;
-  return true;
-}
-
-}  // namespace ppapi
diff --git a/ppapi/shared_impl/ppb_video_capture_shared.h b/ppapi/shared_impl/ppb_video_capture_shared.h
deleted file mode 100644
index 80b29fe..0000000
--- a/ppapi/shared_impl/ppb_video_capture_shared.h
+++ /dev/null
@@ -1,100 +0,0 @@
-// 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.
-
-#ifndef PPAPI_SHARED_IMPL_PPB_VIDEO_CAPTURE_SHARED_H_
-#define PPAPI_SHARED_IMPL_PPB_VIDEO_CAPTURE_SHARED_H_
-
-#include "base/basictypes.h"
-#include "base/compiler_specific.h"
-#include "base/memory/ref_counted.h"
-#include "ppapi/shared_impl/ppapi_shared_export.h"
-#include "ppapi/shared_impl/resource.h"
-#include "ppapi/shared_impl/tracked_callback.h"
-#include "ppapi/thunk/ppb_video_capture_api.h"
-
-namespace ppapi {
-
-class PPAPI_SHARED_EXPORT PPB_VideoCapture_Shared
-    : public Resource,
-      NON_EXPORTED_BASE(public thunk::PPB_VideoCapture_API) {
- public:
-  explicit PPB_VideoCapture_Shared(PP_Instance instance);
-  explicit PPB_VideoCapture_Shared(const HostResource& host_resource);
-  virtual ~PPB_VideoCapture_Shared();
-
-  // Resource implementation.
-  virtual thunk::PPB_VideoCapture_API* AsPPB_VideoCapture_API() OVERRIDE;
-
-  // PPB_VideoCapture_API implementation.
-  virtual int32_t EnumerateDevices(
-      PP_Resource* devices,
-      scoped_refptr<TrackedCallback> callback) OVERRIDE;
-  virtual int32_t Open(const std::string& device_id,
-                       const PP_VideoCaptureDeviceInfo_Dev& requested_info,
-                       uint32_t buffer_count,
-                       scoped_refptr<TrackedCallback> callback) OVERRIDE;
-  virtual int32_t StartCapture() OVERRIDE;
-  virtual int32_t ReuseBuffer(uint32_t buffer) OVERRIDE;
-  virtual int32_t StopCapture() OVERRIDE;
-  virtual void Close() OVERRIDE;
-  virtual int32_t StartCapture0_1(
-      const PP_VideoCaptureDeviceInfo_Dev& requested_info,
-      uint32_t buffer_count) OVERRIDE;
-  virtual const std::vector<DeviceRefData>& GetDeviceRefData() const OVERRIDE;
-
-  void OnEnumerateDevicesComplete(int32_t result,
-                                  const std::vector<DeviceRefData>& devices);
-  void OnOpenComplete(int32_t result);
-
- protected:
-  enum OpenState {
-    BEFORE_OPEN,
-    OPENED,
-    CLOSED
-  };
-
-  // Subclasses should implement these methods to do impl- and proxy-specific
-  // work.
-  virtual int32_t InternalEnumerateDevices(
-      PP_Resource* devices,
-      scoped_refptr<TrackedCallback> callback) = 0;
-  virtual int32_t InternalOpen(
-      const std::string& device_id,
-      const PP_VideoCaptureDeviceInfo_Dev& requested_info,
-      uint32_t buffer_count,
-      scoped_refptr<TrackedCallback> callback) = 0;
-  virtual int32_t InternalStartCapture() = 0;
-  virtual int32_t InternalReuseBuffer(uint32_t buffer) = 0;
-  virtual int32_t InternalStopCapture() = 0;
-  virtual void InternalClose() = 0;
-  virtual int32_t InternalStartCapture0_1(
-      const PP_VideoCaptureDeviceInfo_Dev& requested_info,
-      uint32_t buffer_count) = 0;
-  virtual const std::vector<DeviceRefData>& InternalGetDeviceRefData(
-      ) const = 0;
-
-  // Checks whether |status| is expected and sets |status_| if yes. If |forced|
-  // is set to true, this method will bypass sanity check and always set
-  // |status_|.
-  bool SetStatus(PP_VideoCaptureStatus_Dev status, bool forced);
-
-  OpenState open_state_;
-  PP_VideoCaptureStatus_Dev status_;
-
-  scoped_refptr<TrackedCallback> enumerate_devices_callback_;
-  scoped_refptr<TrackedCallback> open_callback_;
-
-  // Output parameter of EnumerateDevices(). It should not be accessed after
-  // |enumerate_devices_callback_| is run.
-  PP_Resource* devices_;
-
-  ResourceObjectType resource_object_type_;
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(PPB_VideoCapture_Shared);
-};
-
-}  // namespace ppapi
-
-#endif  // PPAPI_SHARED_IMPL_PPB_VIDEO_CAPTURE_SHARED_H_
diff --git a/ppapi/shared_impl/ppb_video_decoder_shared.cc b/ppapi/shared_impl/ppb_video_decoder_shared.cc
index e2547aa..ffd422d 100644
--- a/ppapi/shared_impl/ppb_video_decoder_shared.cc
+++ b/ppapi/shared_impl/ppb_video_decoder_shared.cc
@@ -7,6 +7,7 @@
 #include "base/logging.h"
 #include "gpu/command_buffer/client/gles2_implementation.h"
 #include "ppapi/c/pp_errors.h"
+#include "ppapi/shared_impl/ppb_graphics_3d_shared.h"
 #include "ppapi/shared_impl/resource_tracker.h"
 #include "ppapi/thunk/enter.h"
 
@@ -90,8 +91,16 @@
 }
 
 void PPB_VideoDecoder_Shared::FlushCommandBuffer() {
-  if (gles2_impl_)
+  if (gles2_impl_) {
+    // To call Flush() we have to tell Graphics3D that we hold the proxy lock.
+    thunk::EnterResource<thunk::PPB_Graphics3D_API, false> enter_g3d(
+        graphics_context_, false);
+    DCHECK(enter_g3d.succeeded());
+    PPB_Graphics3D_Shared* graphics3d =
+        static_cast<PPB_Graphics3D_Shared*>(enter_g3d.object());
+    PPB_Graphics3D_Shared::ScopedNoLocking dont_lock(graphics3d);
     gles2_impl_->Flush();
+  }
 }
 
 }  // namespace ppapi
diff --git a/ppapi/shared_impl/ppb_view_shared.cc b/ppapi/shared_impl/ppb_view_shared.cc
index 54659a3..f11fe1f 100644
--- a/ppapi/shared_impl/ppb_view_shared.cc
+++ b/ppapi/shared_impl/ppb_view_shared.cc
@@ -4,11 +4,22 @@
 
 #include "ppapi/shared_impl/ppb_view_shared.h"
 
+namespace {
+
+bool IsRectNonempty(const PP_Rect& rect) {
+  return rect.size.width > 0 && rect.size.height > 0;
+}
+
+}  // namespace
+
 namespace ppapi {
 
 ViewData::ViewData() {
   // Assume POD.
   memset(this, 0, sizeof(ViewData));
+
+  device_scale = 1.0f;
+  css_scale = 1.0f;
 }
 
 ViewData::~ViewData() {
@@ -47,4 +58,38 @@
   return data_;
 }
 
+PP_Bool PPB_View_Shared::GetRect(PP_Rect* viewport) const {
+  if (!viewport)
+    return PP_FALSE;
+  *viewport = data_.rect;
+  return PP_TRUE;
+}
+
+PP_Bool PPB_View_Shared::IsFullscreen() const {
+  return PP_FromBool(data_.is_fullscreen);
+}
+
+PP_Bool PPB_View_Shared::IsVisible() const {
+  return PP_FromBool(data_.is_page_visible && IsRectNonempty(data_.clip_rect));
+}
+
+PP_Bool PPB_View_Shared::IsPageVisible() const {
+  return PP_FromBool(data_.is_page_visible);
+}
+
+PP_Bool PPB_View_Shared::GetClipRect(PP_Rect* clip) const {
+  if (!clip)
+    return PP_FALSE;
+  *clip = data_.clip_rect;
+  return PP_TRUE;
+}
+
+float PPB_View_Shared::GetDeviceScale() const {
+  return data_.device_scale;
+}
+
+float PPB_View_Shared::GetCSSScale() const {
+  return data_.css_scale;
+}
+
 }  // namespace ppapi
diff --git a/ppapi/shared_impl/ppb_view_shared.h b/ppapi/shared_impl/ppb_view_shared.h
index e3d41ac..77bf8f2 100644
--- a/ppapi/shared_impl/ppb_view_shared.h
+++ b/ppapi/shared_impl/ppb_view_shared.h
@@ -43,6 +43,14 @@
 
   // PPB_View_API implementation.
   virtual const ViewData& GetData() const OVERRIDE;
+  virtual PP_Bool GetRect(PP_Rect* viewport) const OVERRIDE;
+  virtual PP_Bool IsFullscreen() const OVERRIDE;
+  virtual PP_Bool IsVisible() const OVERRIDE;
+  virtual PP_Bool IsPageVisible() const OVERRIDE;
+  virtual PP_Bool GetClipRect(PP_Rect* clip) const
+      OVERRIDE;
+  virtual float GetDeviceScale() const OVERRIDE;
+  virtual float GetCSSScale() const OVERRIDE;
 
  private:
   ViewData data_;
diff --git a/ppapi/shared_impl/private/net_address_private_impl.cc b/ppapi/shared_impl/private/net_address_private_impl.cc
index 7a8e375..87a929f 100644
--- a/ppapi/shared_impl/private/net_address_private_impl.cc
+++ b/ppapi/shared_impl/private/net_address_private_impl.cc
@@ -24,6 +24,7 @@
 #include "build/build_config.h"
 #include "ppapi/c/pp_var.h"
 #include "ppapi/c/private/ppb_net_address_private.h"
+#include "ppapi/shared_impl/proxy_lock.h"
 #include "ppapi/shared_impl/var.h"
 #include "ppapi/thunk/thunk.h"
 
@@ -285,6 +286,9 @@
       *addr, PP_ToBool(include_port));
   if (str.empty())
     return PP_MakeUndefined();
+  // We must acquire the lock while accessing the VarTracker, which is part of
+  // the critical section of the proxy which may be accessed by other threads.
+  ProxyAutoLock lock;
   return StringVar::StringToPPVar(str);
 }
 
diff --git a/ppapi/shared_impl/private/ppb_browser_font_trusted_shared.cc b/ppapi/shared_impl/private/ppb_browser_font_trusted_shared.cc
deleted file mode 100644
index 9b2c0f5..0000000
--- a/ppapi/shared_impl/private/ppb_browser_font_trusted_shared.cc
+++ /dev/null
@@ -1,440 +0,0 @@
-// 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 "ppapi/shared_impl/private/ppb_browser_font_trusted_shared.h"
-
-#include "base/string_util.h"
-#include "base/utf_string_conversions.h"
-#include "ppapi/c/dev/ppb_font_dev.h"
-#include "ppapi/shared_impl/ppapi_preferences.h"
-#include "ppapi/shared_impl/var.h"
-#include "ppapi/thunk/enter.h"
-#include "ppapi/thunk/ppb_image_data_api.h"
-#include "ppapi/thunk/thunk.h"
-#include "skia/ext/platform_canvas.h"
-#include "third_party/skia/include/core/SkRect.h"
-#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebCanvas.h"
-#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebFloatPoint.h"
-#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebFloatRect.h"
-#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebRect.h"
-#include "third_party/WebKit/Source/WebKit/chromium/public/WebFont.h"
-#include "third_party/WebKit/Source/WebKit/chromium/public/WebFontDescription.h"
-#include "third_party/WebKit/Source/WebKit/chromium/public/WebTextRun.h"
-#include "unicode/ubidi.h"
-
-using ppapi::StringVar;
-using ppapi::thunk::EnterResourceNoLock;
-using ppapi::thunk::PPB_ImageData_API;
-using WebKit::WebFloatPoint;
-using WebKit::WebFloatRect;
-using WebKit::WebFont;
-using WebKit::WebFontDescription;
-using WebKit::WebRect;
-using WebKit::WebTextRun;
-using WebKit::WebCanvas;
-
-namespace ppapi {
-
-namespace {
-
-// Same as WebPreferences::kCommonScript. I'd use that directly here, but get an
-// undefined reference linker error.
-const char kCommonScript[] = "Zyyy";
-
-string16 GetFontFromMap(
-    const webkit_glue::WebPreferences::ScriptFontFamilyMap& map,
-    const std::string& script) {
-  webkit_glue::WebPreferences::ScriptFontFamilyMap::const_iterator it =
-      map.find(script);
-  if (it != map.end())
-    return it->second;
-  return string16();
-}
-
-// Splits a PP_BrowserFont_Trusted_TextRun into a sequence or LTR and RTL
-// WebTextRuns that can be used for WebKit. Normally WebKit does this for us,
-// but the font drawing and measurement routines we call happen after this
-// step. So for correct rendering of RTL content, we need to do it ourselves.
-class TextRunCollection {
- public:
-  explicit TextRunCollection(const PP_BrowserFont_Trusted_TextRun& run)
-      : bidi_(NULL),
-        num_runs_(0) {
-    StringVar* text_string = StringVar::FromPPVar(run.text);
-    if (!text_string)
-      return;  // Leave num_runs_ = 0 so we'll do nothing.
-    text_ = UTF8ToUTF16(text_string->value());
-
-    if (run.override_direction) {
-      // Skip autodetection.
-      num_runs_ = 1;
-      override_run_ = WebTextRun(text_, PP_ToBool(run.rtl), true);
-    } else {
-      bidi_ = ubidi_open();
-      UErrorCode uerror = U_ZERO_ERROR;
-      ubidi_setPara(bidi_, text_.data(), text_.size(), run.rtl, NULL, &uerror);
-      if (U_SUCCESS(uerror))
-        num_runs_ = ubidi_countRuns(bidi_, &uerror);
-    }
-  }
-
-  ~TextRunCollection() {
-    if (bidi_)
-      ubidi_close(bidi_);
-  }
-
-  const string16& text() const { return text_; }
-  int num_runs() const { return num_runs_; }
-
-  // Returns a WebTextRun with the info for the run at the given index.
-  // The range covered by the run is in the two output params.
-  WebTextRun GetRunAt(int index, int32_t* run_start, int32_t* run_len) const {
-    DCHECK(index < num_runs_);
-    if (bidi_) {
-      bool run_rtl = !!ubidi_getVisualRun(bidi_, index, run_start, run_len);
-      return WebTextRun(string16(&text_[*run_start], *run_len),
-                        run_rtl, true);
-    }
-
-    // Override run, return the single one.
-    DCHECK(index == 0);
-    *run_start = 0;
-    *run_len = static_cast<int32_t>(text_.size());
-    return override_run_;
-  }
-
- private:
-  // Will be null if we skipped autodetection.
-  UBiDi* bidi_;
-
-  // Text of all the runs.
-  string16 text_;
-
-  int num_runs_;
-
-  // When the content specifies override_direction (bidi_ is null) then this
-  // will contain the single text run for WebKit.
-  WebTextRun override_run_;
-
-  DISALLOW_COPY_AND_ASSIGN(TextRunCollection);
-};
-
-bool PPTextRunToWebTextRun(const PP_BrowserFont_Trusted_TextRun& text,
-                           WebTextRun* run) {
-  StringVar* text_string = StringVar::FromPPVar(text.text);
-  if (!text_string)
-    return false;
-
-  *run = WebTextRun(UTF8ToUTF16(text_string->value()),
-                    PP_ToBool(text.rtl),
-                    PP_ToBool(text.override_direction));
-  return true;
-}
-
-// The PP_* version lacks "None", so is just one value shifted from the
-// WebFontDescription version. These values are checked in
-// PPFontDescToWebFontDesc to make sure the conversion is correct. This is a
-// macro so it can also be used in the COMPILE_ASSERTS.
-#define PP_FAMILY_TO_WEB_FAMILY(f) \
-  static_cast<WebFontDescription::GenericFamily>(f + 1)
-
-// Assumes the given PP_FontDescription has been validated.
-WebFontDescription PPFontDescToWebFontDesc(
-    const PP_BrowserFont_Trusted_Description& font,
-    const Preferences& prefs) {
-  // Verify that the enums match so we can just static cast.
-  COMPILE_ASSERT(static_cast<int>(WebFontDescription::Weight100) ==
-                 static_cast<int>(PP_BROWSERFONT_TRUSTED_WEIGHT_100),
-                 FontWeight100);
-  COMPILE_ASSERT(static_cast<int>(WebFontDescription::Weight900) ==
-                 static_cast<int>(PP_BROWSERFONT_TRUSTED_WEIGHT_900),
-                 FontWeight900);
-  COMPILE_ASSERT(WebFontDescription::GenericFamilyStandard ==
-                 PP_FAMILY_TO_WEB_FAMILY(PP_FONTFAMILY_DEFAULT),
-                 StandardFamily);
-  COMPILE_ASSERT(WebFontDescription::GenericFamilySerif ==
-                 PP_FAMILY_TO_WEB_FAMILY(PP_FONTFAMILY_SERIF),
-                 SerifFamily);
-  COMPILE_ASSERT(WebFontDescription::GenericFamilySansSerif ==
-                 PP_FAMILY_TO_WEB_FAMILY(PP_FONTFAMILY_SANSSERIF),
-                 SansSerifFamily);
-  COMPILE_ASSERT(WebFontDescription::GenericFamilyMonospace ==
-                 PP_FAMILY_TO_WEB_FAMILY(PP_FONTFAMILY_MONOSPACE),
-                 MonospaceFamily);
-
-  StringVar* face_name = StringVar::FromPPVar(font.face);  // Possibly null.
-
-  WebFontDescription result;
-  string16 resolved_family;
-  if (!face_name || face_name->value().empty()) {
-    // Resolve the generic family.
-    switch (font.family) {
-      case PP_BROWSERFONT_TRUSTED_FAMILY_SERIF:
-        resolved_family = GetFontFromMap(prefs.serif_font_family_map,
-                                         kCommonScript);
-        break;
-      case PP_BROWSERFONT_TRUSTED_FAMILY_SANSSERIF:
-        resolved_family = GetFontFromMap(prefs.sans_serif_font_family_map,
-                                         kCommonScript);
-        break;
-      case PP_BROWSERFONT_TRUSTED_FAMILY_MONOSPACE:
-        resolved_family = GetFontFromMap(prefs.fixed_font_family_map,
-                                         kCommonScript);
-        break;
-      case PP_BROWSERFONT_TRUSTED_FAMILY_DEFAULT:
-      default:
-        resolved_family = GetFontFromMap(prefs.standard_font_family_map,
-                                         kCommonScript);
-        break;
-    }
-  } else {
-    // Use the exact font.
-    resolved_family = UTF8ToUTF16(face_name->value());
-  }
-  result.family = resolved_family;
-
-  result.genericFamily = PP_FAMILY_TO_WEB_FAMILY(font.family);
-
-  if (font.size == 0) {
-    // Resolve the default font size, using the resolved family to see if
-    // we should use the fixed or regular font size. It's difficult at this
-    // level to detect if the requested font is fixed width, so we only apply
-    // the alternate font size to the default fixed font family.
-    if (StringToLowerASCII(resolved_family) ==
-        StringToLowerASCII(GetFontFromMap(prefs.fixed_font_family_map,
-                                          kCommonScript)))
-      result.size = static_cast<float>(prefs.default_fixed_font_size);
-    else
-      result.size = static_cast<float>(prefs.default_font_size);
-  } else {
-    // Use the exact size.
-    result.size = static_cast<float>(font.size);
-  }
-
-  result.italic = font.italic != PP_FALSE;
-  result.smallCaps = font.small_caps != PP_FALSE;
-  result.weight = static_cast<WebFontDescription::Weight>(font.weight);
-  result.letterSpacing = static_cast<short>(font.letter_spacing);
-  result.wordSpacing = static_cast<short>(font.word_spacing);
-  return result;
-}
-
-}  // namespace
-
-// static
-bool PPB_BrowserFont_Trusted_Shared::IsPPFontDescriptionValid(
-    const PP_BrowserFont_Trusted_Description& desc) {
-  // Check validity of string. We can't check the actual text since we could
-  // be on the wrong thread and don't know if we're in the plugin or the host.
-  if (desc.face.type != PP_VARTYPE_STRING &&
-      desc.face.type != PP_VARTYPE_UNDEFINED)
-    return false;
-
-  // Check enum ranges.
-  if (static_cast<int>(desc.family) < PP_BROWSERFONT_TRUSTED_FAMILY_DEFAULT ||
-      static_cast<int>(desc.family) > PP_BROWSERFONT_TRUSTED_FAMILY_MONOSPACE)
-    return false;
-  if (static_cast<int>(desc.weight) < PP_BROWSERFONT_TRUSTED_WEIGHT_100 ||
-      static_cast<int>(desc.weight) > PP_BROWSERFONT_TRUSTED_WEIGHT_900)
-    return false;
-
-  // Check for excessive sizes which may cause layout to get confused.
-  if (desc.size > 200)
-    return false;
-
-  return true;
-}
-
-// static
-PP_Resource PPB_BrowserFont_Trusted_Shared::Create(
-    ResourceObjectType type,
-    PP_Instance instance,
-    const PP_BrowserFont_Trusted_Description& description,
-    const Preferences& prefs) {
-  if (!PPB_BrowserFont_Trusted_Shared::IsPPFontDescriptionValid(description))
-    return 0;
-  return (new PPB_BrowserFont_Trusted_Shared(type, instance,
-                                             description,
-                                             prefs))->GetReference();
-}
-
-PPB_BrowserFont_Trusted_Shared::PPB_BrowserFont_Trusted_Shared(
-    ResourceObjectType type,
-    PP_Instance instance,
-    const PP_BrowserFont_Trusted_Description& desc,
-    const Preferences& prefs)
-    : Resource(type, instance),
-      font_(WebFont::create(PPFontDescToWebFontDesc(desc, prefs))) {
-}
-
-PPB_BrowserFont_Trusted_Shared::~PPB_BrowserFont_Trusted_Shared() {
-}
-
-thunk::PPB_BrowserFont_Trusted_API*
-PPB_BrowserFont_Trusted_Shared::AsPPB_BrowserFont_Trusted_API() {
-  return this;
-}
-
-PP_Bool PPB_BrowserFont_Trusted_Shared::Describe(
-    PP_BrowserFont_Trusted_Description* description,
-    PP_BrowserFont_Trusted_Metrics* metrics) {
-  if (description->face.type != PP_VARTYPE_UNDEFINED)
-    return PP_FALSE;
-
-  // While converting the other way in PPFontDescToWebFontDesc we validated
-  // that the enums can be casted.
-  WebFontDescription web_desc = font_->fontDescription();
-  description->face = StringVar::StringToPPVar(UTF16ToUTF8(web_desc.family));
-  description->family =
-      static_cast<PP_BrowserFont_Trusted_Family>(web_desc.genericFamily);
-  description->size = static_cast<uint32_t>(web_desc.size);
-  description->weight = static_cast<PP_BrowserFont_Trusted_Weight>(
-      web_desc.weight);
-  description->italic = web_desc.italic ? PP_TRUE : PP_FALSE;
-  description->small_caps = web_desc.smallCaps ? PP_TRUE : PP_FALSE;
-  description->letter_spacing = static_cast<int32_t>(web_desc.letterSpacing);
-  description->word_spacing = static_cast<int32_t>(web_desc.wordSpacing);
-
-  metrics->height = font_->height();
-  metrics->ascent = font_->ascent();
-  metrics->descent = font_->descent();
-  metrics->line_spacing = font_->lineSpacing();
-  metrics->x_height = static_cast<int32_t>(font_->xHeight());
-
-  // Convert the string.
-  return PP_TRUE;
-}
-
-PP_Bool PPB_BrowserFont_Trusted_Shared::DrawTextAt(
-    PP_Resource image_data,
-    const PP_BrowserFont_Trusted_TextRun* text,
-    const PP_Point* position,
-    uint32_t color,
-    const PP_Rect* clip,
-    PP_Bool image_data_is_opaque) {
-  PP_Bool result = PP_FALSE;
-  // Get and map the image data we're painting to.
-  EnterResourceNoLock<PPB_ImageData_API> enter(image_data, true);
-  if (enter.failed())
-    return result;
-
-  PPB_ImageData_API* image = static_cast<PPB_ImageData_API*>(
-      enter.object());
-  skia::PlatformCanvas* canvas = image->GetPlatformCanvas();
-  bool needs_unmapping = false;
-  if (!canvas) {
-    needs_unmapping = true;
-    image->Map();
-    canvas = image->GetPlatformCanvas();
-    if (!canvas)
-      return result;  // Failure mapping.
-  }
-
-  DrawTextToCanvas(canvas, *text, position, color, clip, image_data_is_opaque);
-
-  if (needs_unmapping)
-    image->Unmap();
-  return PP_TRUE;
-}
-
-int32_t PPB_BrowserFont_Trusted_Shared::MeasureText(
-    const PP_BrowserFont_Trusted_TextRun* text) {
-  WebTextRun run;
-  if (!PPTextRunToWebTextRun(*text, &run))
-    return -1;
-  return font_->calculateWidth(run);
-}
-
-uint32_t PPB_BrowserFont_Trusted_Shared::CharacterOffsetForPixel(
-    const PP_BrowserFont_Trusted_TextRun* text,
-    int32_t pixel_position) {
-  TextRunCollection runs(*text);
-  int32_t cur_pixel_offset = 0;
-  for (int i = 0; i < runs.num_runs(); i++) {
-    int32_t run_begin = 0;
-    int32_t run_len = 0;
-    WebTextRun run = runs.GetRunAt(i, &run_begin, &run_len);
-    int run_width = font_->calculateWidth(run);
-    if (pixel_position < cur_pixel_offset + run_width) {
-      // Offset is in this run.
-      return static_cast<uint32_t>(font_->offsetForPosition(
-              run, static_cast<float>(pixel_position - cur_pixel_offset))) +
-          run_begin;
-    }
-    cur_pixel_offset += run_width;
-  }
-  return runs.text().size();
-}
-
-int32_t PPB_BrowserFont_Trusted_Shared::PixelOffsetForCharacter(
-    const PP_BrowserFont_Trusted_TextRun* text,
-    uint32_t char_offset) {
-  TextRunCollection runs(*text);
-  int32_t cur_pixel_offset = 0;
-  for (int i = 0; i < runs.num_runs(); i++) {
-    int32_t run_begin = 0;
-    int32_t run_len = 0;
-    WebTextRun run = runs.GetRunAt(i, &run_begin, &run_len);
-    if (char_offset >= static_cast<uint32_t>(run_begin) &&
-        char_offset < static_cast<uint32_t>(run_begin + run_len)) {
-      // Character we're looking for is in this run.
-      //
-      // Here we ask WebKit to give us the rectangle around the character in
-      // question, and then return the left edge. If we asked for a range of
-      // 0 characters starting at the character in question, it would give us
-      // a 0-width rect around the insertion point. But that will be on the
-      // right side of the character for an RTL run, which would be wrong.
-      WebFloatRect rect = font_->selectionRectForText(
-          run, WebFloatPoint(0.0f, 0.0f), font_->height(),
-          char_offset - run_begin, char_offset - run_begin + 1);
-      return cur_pixel_offset + static_cast<int>(rect.x);
-    } else {
-      // Character is past this run, account for the pixels and continue
-      // looking.
-      cur_pixel_offset += font_->calculateWidth(run);
-    }
-  }
-  return -1;  // Requested a char beyond the end.
-}
-
-void PPB_BrowserFont_Trusted_Shared::DrawTextToCanvas(
-    skia::PlatformCanvas* destination,
-    const PP_BrowserFont_Trusted_TextRun& text,
-    const PP_Point* position,
-    uint32_t color,
-    const PP_Rect* clip,
-    PP_Bool image_data_is_opaque) {
-  // Convert position and clip.
-  WebFloatPoint web_position(static_cast<float>(position->x),
-                             static_cast<float>(position->y));
-  WebRect web_clip;
-  if (!clip) {
-    // Use entire canvas. SkCanvas doesn't have a size on it, so we just use
-    // the current clip bounds.
-    SkRect skclip;
-    destination->getClipBounds(&skclip);
-    web_clip = WebRect(skclip.fLeft, skclip.fTop, skclip.fRight - skclip.fLeft,
-                       skclip.fBottom - skclip.fTop);
-  } else {
-    web_clip = WebRect(clip->point.x, clip->point.y,
-                       clip->size.width, clip->size.height);
-  }
-
-  TextRunCollection runs(text);
-  for (int i = 0; i < runs.num_runs(); i++) {
-    int32_t run_begin = 0;
-    int32_t run_len = 0;
-    WebTextRun run = runs.GetRunAt(i, &run_begin, &run_len);
-    font_->drawText(destination, run, web_position, color, web_clip,
-                    PP_ToBool(image_data_is_opaque));
-
-    // Advance to the next run. Note that we avoid doing this for the last run
-    // since it's unnecessary, measuring text is slow, and most of the time
-    // there will be only one run anyway.
-    if (i != runs.num_runs() - 1)
-      web_position.x += font_->calculateWidth(run);
-  }
-}
-
-}  // namespace ppapi
diff --git a/ppapi/shared_impl/private/ppb_browser_font_trusted_shared.h b/ppapi/shared_impl/private/ppb_browser_font_trusted_shared.h
deleted file mode 100644
index e77be56..0000000
--- a/ppapi/shared_impl/private/ppb_browser_font_trusted_shared.h
+++ /dev/null
@@ -1,90 +0,0 @@
-// 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.
-
-#ifndef PPAPI_SHARED_IMPL_PRIVATE_PPB_BROWSER_FONT_TRUSTED_SHARED_H_
-#define PPAPI_SHARED_IMPL_PRIVATE_PPB_BROWSER_FONT_TRUSTED_SHARED_H_
-
-#include <string>
-
-#include "base/basictypes.h"
-#include "base/memory/scoped_ptr.h"
-#include "ppapi/c/pp_bool.h"
-#include "ppapi/c/pp_instance.h"
-#include "ppapi/c/pp_resource.h"
-#include "ppapi/c/pp_stdint.h"
-#include "ppapi/shared_impl/ppapi_preferences.h"
-#include "ppapi/shared_impl/ppapi_shared_export.h"
-#include "ppapi/shared_impl/resource.h"
-#include "ppapi/thunk/ppb_browser_font_trusted_api.h"
-
-namespace skia {
-class PlatformCanvas;
-}
-
-namespace WebKit {
-class WebFont;
-}
-
-namespace ppapi {
-
-class PPAPI_SHARED_EXPORT PPB_BrowserFont_Trusted_Shared
-    : public Resource,
-      public thunk::PPB_BrowserFont_Trusted_API {
- public:
-  // Validates the parameters in thee description. Can be called on any thread.
-  static bool IsPPFontDescriptionValid(
-      const PP_BrowserFont_Trusted_Description& desc);
-
-  virtual ~PPB_BrowserFont_Trusted_Shared();
-
-  static PP_Resource Create(
-      ResourceObjectType type,
-      PP_Instance instance,
-      const PP_BrowserFont_Trusted_Description& description,
-      const ::ppapi::Preferences& prefs);
-
-  // Resource.
-  virtual ::ppapi::thunk::PPB_BrowserFont_Trusted_API*
-      AsPPB_BrowserFont_Trusted_API() OVERRIDE;
-
-  // PPB_Font implementation.
-  virtual PP_Bool Describe(PP_BrowserFont_Trusted_Description* description,
-                           PP_BrowserFont_Trusted_Metrics* metrics) OVERRIDE;
-  virtual PP_Bool DrawTextAt(PP_Resource image_data,
-                             const PP_BrowserFont_Trusted_TextRun* text,
-                             const PP_Point* position,
-                             uint32_t color,
-                             const PP_Rect* clip,
-                             PP_Bool image_data_is_opaque) OVERRIDE;
-  virtual int32_t MeasureText(
-      const PP_BrowserFont_Trusted_TextRun* text) OVERRIDE;
-  virtual uint32_t CharacterOffsetForPixel(
-      const PP_BrowserFont_Trusted_TextRun* text,
-      int32_t pixel_position) OVERRIDE;
-  virtual int32_t PixelOffsetForCharacter(
-      const PP_BrowserFont_Trusted_TextRun* text,
-      uint32_t char_offset) OVERRIDE;
-
- private:
-  PPB_BrowserFont_Trusted_Shared(ResourceObjectType type,
-                                 PP_Instance instance,
-                                 const PP_BrowserFont_Trusted_Description& desc,
-                                 const Preferences& prefs);
-
-  // Internal version of DrawTextAt that takes a mapped PlatformCanvas.
-  void DrawTextToCanvas(skia::PlatformCanvas* destination,
-                        const PP_BrowserFont_Trusted_TextRun& text,
-                        const PP_Point* position,
-                        uint32_t color,
-                        const PP_Rect* clip,
-                        PP_Bool image_data_is_opaque);
-
-  scoped_ptr<WebKit::WebFont> font_;
-
-  DISALLOW_COPY_AND_ASSIGN(PPB_BrowserFont_Trusted_Shared);
-};
-
-}  // namespace ppapi
-
-#endif  // PPAPI_SHARED_IMPL_PRIVATE_PPB_BROWSER_FONT_TRUSTED_SHARED_H_
diff --git a/ppapi/shared_impl/private/ppb_char_set_shared.cc b/ppapi/shared_impl/private/ppb_char_set_shared.cc
index 8424b00..5ce51a6 100644
--- a/ppapi/shared_impl/private/ppb_char_set_shared.cc
+++ b/ppapi/shared_impl/private/ppb_char_set_shared.cc
@@ -9,10 +9,10 @@
 #include "base/i18n/icu_string_conversions.h"
 #include "ppapi/c/dev/ppb_memory_dev.h"
 #include "ppapi/thunk/thunk.h"
-#include "unicode/ucnv.h"
-#include "unicode/ucnv_cb.h"
-#include "unicode/ucnv_err.h"
-#include "unicode/ustring.h"
+#include "third_party/icu/public/common/unicode/ucnv.h"
+#include "third_party/icu/public/common/unicode/ucnv_cb.h"
+#include "third_party/icu/public/common/unicode/ucnv_err.h"
+#include "third_party/icu/public/common/unicode/ustring.h"
 
 namespace ppapi {
 
diff --git a/ppapi/shared_impl/private/ppb_host_resolver_shared.cc b/ppapi/shared_impl/private/ppb_host_resolver_shared.cc
deleted file mode 100644
index ba026dc..0000000
--- a/ppapi/shared_impl/private/ppb_host_resolver_shared.cc
+++ /dev/null
@@ -1,99 +0,0 @@
-// 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 "ppapi/shared_impl/private/ppb_host_resolver_shared.h"
-
-#include <cstddef>
-#include <cstring>
-
-#include "base/memory/scoped_ptr.h"
-#include "ppapi/c/pp_errors.h"
-#include "ppapi/shared_impl/private/net_address_private_impl.h"
-#include "ppapi/shared_impl/var.h"
-#include "ppapi/thunk/thunk.h"
-
-namespace ppapi {
-
-PPB_HostResolver_Shared::PPB_HostResolver_Shared(PP_Instance instance)
-    : Resource(OBJECT_IS_IMPL, instance),
-      host_resolver_id_(GenerateHostResolverID()) {
-}
-
-PPB_HostResolver_Shared::PPB_HostResolver_Shared(
-    const HostResource& resource)
-    : Resource(OBJECT_IS_PROXY, resource),
-      host_resolver_id_(GenerateHostResolverID()) {
-}
-
-PPB_HostResolver_Shared::~PPB_HostResolver_Shared() {
-}
-
-thunk::PPB_HostResolver_Private_API*
-PPB_HostResolver_Shared::AsPPB_HostResolver_Private_API() {
-  return this;
-}
-
-int32_t PPB_HostResolver_Shared::Resolve(
-    const char* host,
-    uint16_t port,
-    const PP_HostResolver_Private_Hint* hint,
-    scoped_refptr<TrackedCallback> callback) {
-  if (!host)
-    return PP_ERROR_BADARGUMENT;
-  if (ResolveInProgress())
-    return PP_ERROR_INPROGRESS;
-
-  resolve_callback_ = callback;
-
-  HostPortPair host_port;
-  host_port.host = host;
-  host_port.port = port;
-
-  SendResolve(host_port, hint);
-  return PP_OK_COMPLETIONPENDING;
-}
-
-PP_Var PPB_HostResolver_Shared::GetCanonicalName() {
-  return StringVar::StringToPPVar(canonical_name_);
-}
-
-uint32_t PPB_HostResolver_Shared::GetSize() {
-  if (ResolveInProgress())
-    return 0;
-  return static_cast<uint32_t>(net_address_list_.size());
-}
-
-bool PPB_HostResolver_Shared::GetNetAddress(uint32 index,
-                                            PP_NetAddress_Private* address) {
-  if (ResolveInProgress() || index >= GetSize())
-    return false;
-  *address = net_address_list_[index];
-  return true;
-}
-
-void PPB_HostResolver_Shared::OnResolveCompleted(
-    bool succeeded,
-    const std::string& canonical_name,
-    const std::vector<PP_NetAddress_Private>& net_address_list) {
-  if (succeeded) {
-    canonical_name_ = canonical_name;
-    net_address_list_ = net_address_list;
-  } else {
-    canonical_name_.clear();
-    net_address_list_.clear();
-  }
-
-  resolve_callback_->Run(succeeded ? PP_OK : PP_ERROR_FAILED);
-}
-
-uint32 PPB_HostResolver_Shared::GenerateHostResolverID() {
-  static uint32 host_resolver_id = 0;
-  return host_resolver_id++;
-}
-
-bool PPB_HostResolver_Shared::ResolveInProgress() const {
-  return TrackedCallback::IsPending(resolve_callback_);
-}
-
-}  // namespace ppapi
diff --git a/ppapi/shared_impl/private/ppb_host_resolver_shared.h b/ppapi/shared_impl/private/ppb_host_resolver_shared.h
deleted file mode 100644
index 7372dc5..0000000
--- a/ppapi/shared_impl/private/ppb_host_resolver_shared.h
+++ /dev/null
@@ -1,76 +0,0 @@
-// 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.
-
-#ifndef PPAPI_SHARED_IMPL_PRIVATE_PPB_HOST_RESOLVER_SHARED_H_
-#define PPAPI_SHARED_IMPL_PRIVATE_PPB_HOST_RESOLVER_SHARED_H_
-
-#include <string>
-#include <vector>
-
-#include "base/compiler_specific.h"
-#include "base/memory/ref_counted.h"
-#include "ppapi/shared_impl/resource.h"
-#include "ppapi/shared_impl/tracked_callback.h"
-#include "ppapi/thunk/ppb_host_resolver_private_api.h"
-
-namespace ppapi {
-
-struct HostPortPair {
-  std::string host;
-  uint16_t port;
-};
-
-class PPAPI_SHARED_EXPORT PPB_HostResolver_Shared
-    : public thunk::PPB_HostResolver_Private_API,
-      public Resource {
- public:
-  // C-tor used in Impl case.
-  explicit PPB_HostResolver_Shared(PP_Instance instance);
-
-  // C-tor used in Proxy case.
-  explicit PPB_HostResolver_Shared(const HostResource& resource);
-
-  virtual ~PPB_HostResolver_Shared();
-
-  // Resource overrides.
-  virtual PPB_HostResolver_Private_API*
-      AsPPB_HostResolver_Private_API() OVERRIDE;
-
-  // PPB_HostResolver_Private_API implementation.
-  virtual int32_t Resolve(const char* host,
-                          uint16_t port,
-                          const PP_HostResolver_Private_Hint* hint,
-                          scoped_refptr<TrackedCallback> callback) OVERRIDE;
-  virtual PP_Var GetCanonicalName() OVERRIDE;
-  virtual uint32_t GetSize() OVERRIDE;
-  virtual bool GetNetAddress(uint32_t index,
-                             PP_NetAddress_Private* address) OVERRIDE;
-
-  void OnResolveCompleted(
-      bool succeeded,
-      const std::string& canonical_name,
-      const std::vector<PP_NetAddress_Private>& net_address_list);
-
-  // Send functions that need to be implemented differently for the
-  // proxied and non-proxied derived classes.
-  virtual void SendResolve(const HostPortPair& host_port,
-                           const PP_HostResolver_Private_Hint* hint) = 0;
-
- protected:
-  static uint32 GenerateHostResolverID();
-  bool ResolveInProgress() const;
-
-  const uint32 host_resolver_id_;
-
-  scoped_refptr<TrackedCallback> resolve_callback_;
-
-  std::string canonical_name_;
-  std::vector<PP_NetAddress_Private> net_address_list_;
-
-  DISALLOW_COPY_AND_ASSIGN(PPB_HostResolver_Shared);
-};
-
-}  // namespace ppapi
-
-#endif  // PPAPI_SHARED_IMPL_PRIVATE_PPB_HOST_RESOLVER_SHARED_H_
diff --git a/ppapi/shared_impl/private/tcp_socket_private_impl.cc b/ppapi/shared_impl/private/tcp_socket_private_impl.cc
index e2c645f..87cc600 100644
--- a/ppapi/shared_impl/private/tcp_socket_private_impl.cc
+++ b/ppapi/shared_impl/private/tcp_socket_private_impl.cc
@@ -212,11 +212,34 @@
   PostAbortIfNecessary(&ssl_handshake_callback_);
   PostAbortIfNecessary(&read_callback_);
   PostAbortIfNecessary(&write_callback_);
+  PostAbortIfNecessary(&set_option_callback_);
   read_buffer_ = NULL;
   bytes_to_read_ = -1;
   server_certificate_ = NULL;
 }
 
+int32_t TCPSocketPrivateImpl::SetOption(
+    PP_TCPSocketOption_Private name,
+    const PP_Var& value,
+    scoped_refptr<TrackedCallback> callback) {
+  if (!IsConnected())
+    return PP_ERROR_FAILED;
+  if (TrackedCallback::IsPending(set_option_callback_))
+    return PP_ERROR_INPROGRESS;
+
+  set_option_callback_ = callback;
+
+  switch (name) {
+    case PP_TCPSOCKETOPTION_NO_DELAY:
+      if (value.type != PP_VARTYPE_BOOL)
+        return PP_ERROR_BADARGUMENT;
+      SendSetBoolOption(name, PP_ToBool(value.value.as_bool));
+      return PP_OK_COMPLETIONPENDING;
+    default:
+      return PP_ERROR_BADARGUMENT;
+  }
+}
+
 void TCPSocketPrivateImpl::OnConnectCompleted(
     bool succeeded,
     const PP_NetAddress_Private& local_addr,
@@ -293,6 +316,15 @@
       succeeded ? bytes_written : static_cast<int32_t>(PP_ERROR_FAILED));
 }
 
+void TCPSocketPrivateImpl::OnSetOptionCompleted(bool succeeded) {
+  if (!TrackedCallback::IsPending(set_option_callback_)) {
+    NOTREACHED();
+    return;
+  }
+
+  set_option_callback_->Run(succeeded ? PP_OK : PP_ERROR_FAILED);
+}
+
 void TCPSocketPrivateImpl::Init(uint32 socket_id) {
   DCHECK(socket_id != 0);
   socket_id_ = socket_id;
diff --git a/ppapi/shared_impl/private/tcp_socket_private_impl.h b/ppapi/shared_impl/private/tcp_socket_private_impl.h
index 2792102..95057e7 100644
--- a/ppapi/shared_impl/private/tcp_socket_private_impl.h
+++ b/ppapi/shared_impl/private/tcp_socket_private_impl.h
@@ -66,6 +66,9 @@
                         int32_t bytes_to_write,
                         scoped_refptr<TrackedCallback> callback) OVERRIDE;
   virtual void Disconnect() OVERRIDE;
+  virtual int32_t SetOption(PP_TCPSocketOption_Private name,
+                            const PP_Var& value,
+                            scoped_refptr<TrackedCallback> callback) OVERRIDE;
 
   // Notifications on operations completion.
   void OnConnectCompleted(bool succeeded,
@@ -76,6 +79,7 @@
       const PPB_X509Certificate_Fields& certificate_fields);
   void OnReadCompleted(bool succeeded, const std::string& data);
   void OnWriteCompleted(bool succeeded, int32_t bytes_written);
+  void OnSetOptionCompleted(bool succeeded);
 
   // Send functions that need to be implemented differently for the
   // proxied and non-proxied derived classes.
@@ -89,6 +93,8 @@
   virtual void SendRead(int32_t bytes_to_read) = 0;
   virtual void SendWrite(const std::string& buffer) = 0;
   virtual void SendDisconnect() = 0;
+  virtual void SendSetBoolOption(PP_TCPSocketOption_Private name,
+                                 bool value) = 0;
 
  protected:
   enum ConnectionState {
@@ -117,6 +123,7 @@
   scoped_refptr<TrackedCallback> ssl_handshake_callback_;
   scoped_refptr<TrackedCallback> read_callback_;
   scoped_refptr<TrackedCallback> write_callback_;
+  scoped_refptr<TrackedCallback> set_option_callback_;
 
   char* read_buffer_;
   int32_t bytes_to_read_;
diff --git a/ppapi/shared_impl/private/udp_socket_private_impl.cc b/ppapi/shared_impl/private/udp_socket_private_impl.cc
deleted file mode 100644
index 288c38f..0000000
--- a/ppapi/shared_impl/private/udp_socket_private_impl.cc
+++ /dev/null
@@ -1,223 +0,0 @@
-// 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 "ppapi/shared_impl/private/udp_socket_private_impl.h"
-
-#include <string.h>
-
-#include <algorithm>
-
-#include "base/basictypes.h"
-#include "base/bind.h"
-#include "base/logging.h"
-#include "base/message_loop.h"
-#include "ppapi/c/pp_bool.h"
-#include "ppapi/c/pp_completion_callback.h"
-#include "ppapi/c/pp_errors.h"
-
-namespace ppapi {
-
-const int32_t UDPSocketPrivateImpl::kMaxReadSize = 1024 * 1024;
-const int32_t UDPSocketPrivateImpl::kMaxWriteSize = 1024 * 1024;
-
-UDPSocketPrivateImpl::UDPSocketPrivateImpl(const HostResource& resource,
-                                           uint32 socket_id)
-    : Resource(OBJECT_IS_PROXY, resource) {
-  Init(socket_id);
-}
-
-UDPSocketPrivateImpl::UDPSocketPrivateImpl(PP_Instance instance,
-                                           uint32 socket_id)
-    : Resource(OBJECT_IS_IMPL, instance) {
-  Init(socket_id);
-}
-
-UDPSocketPrivateImpl::~UDPSocketPrivateImpl() {
-}
-
-thunk::PPB_UDPSocket_Private_API*
-UDPSocketPrivateImpl::AsPPB_UDPSocket_Private_API() {
-  return this;
-}
-
-int32_t UDPSocketPrivateImpl::SetSocketFeature(PP_UDPSocketFeature_Private name,
-                                               PP_Var value) {
-  if (bound_ || closed_)
-    return PP_ERROR_FAILED;
-
-  switch (name) {
-    case PP_UDPSOCKETFEATURE_ADDRESS_REUSE:
-    case PP_UDPSOCKETFEATURE_BROADCAST:
-      if (value.type != PP_VARTYPE_BOOL)
-        return PP_ERROR_BADARGUMENT;
-      SendBoolSocketFeature(static_cast<int32_t>(name),
-                            PP_ToBool(value.value.as_bool));
-      break;
-    default:
-      return PP_ERROR_BADARGUMENT;
-  }
-  return PP_OK;
-}
-
-int32_t UDPSocketPrivateImpl::Bind(const PP_NetAddress_Private* addr,
-                                   scoped_refptr<TrackedCallback> callback) {
-  if (!addr)
-    return PP_ERROR_BADARGUMENT;
-  if (bound_ || closed_)
-    return PP_ERROR_FAILED;
-  if (TrackedCallback::IsPending(bind_callback_))
-    return PP_ERROR_INPROGRESS;
-
-  bind_callback_ = callback;
-
-  // Send the request, the browser will call us back via BindACK.
-  SendBind(*addr);
-  return PP_OK_COMPLETIONPENDING;
-}
-
-PP_Bool UDPSocketPrivateImpl::GetBoundAddress(PP_NetAddress_Private* addr) {
-  if (!addr || !bound_ || closed_)
-    return PP_FALSE;
-
-  *addr = bound_addr_;
-  return PP_TRUE;
-}
-
-int32_t UDPSocketPrivateImpl::RecvFrom(
-    char* buffer,
-    int32_t num_bytes,
-    scoped_refptr<TrackedCallback> callback) {
-  if (!buffer || num_bytes <= 0)
-    return PP_ERROR_BADARGUMENT;
-  if (!bound_)
-    return PP_ERROR_FAILED;
-  if (TrackedCallback::IsPending(recvfrom_callback_))
-    return PP_ERROR_INPROGRESS;
-
-  read_buffer_ = buffer;
-  bytes_to_read_ = std::min(num_bytes, kMaxReadSize);
-  recvfrom_callback_ = callback;
-
-  // Send the request, the browser will call us back via RecvFromACK.
-  SendRecvFrom(bytes_to_read_);
-  return PP_OK_COMPLETIONPENDING;
-}
-
-PP_Bool UDPSocketPrivateImpl::GetRecvFromAddress(PP_NetAddress_Private* addr) {
-  if (!addr)
-    return PP_FALSE;
-
-  *addr = recvfrom_addr_;
-  return PP_TRUE;
-}
-
-int32_t UDPSocketPrivateImpl::SendTo(const char* buffer,
-                                     int32_t num_bytes,
-                                     const PP_NetAddress_Private* addr,
-                                     scoped_refptr<TrackedCallback> callback) {
-  if (!buffer || num_bytes <= 0 || !addr)
-    return PP_ERROR_BADARGUMENT;
-  if (!bound_)
-    return PP_ERROR_FAILED;
-  if (TrackedCallback::IsPending(sendto_callback_))
-    return PP_ERROR_INPROGRESS;
-
-  if (num_bytes > kMaxWriteSize)
-    num_bytes = kMaxWriteSize;
-
-  sendto_callback_ = callback;
-
-  // Send the request, the browser will call us back via SendToACK.
-  SendSendTo(std::string(buffer, num_bytes), *addr);
-  return PP_OK_COMPLETIONPENDING;
-}
-
-void UDPSocketPrivateImpl::Close() {
-  if(closed_)
-    return;
-
-  bound_ = false;
-  closed_ = true;
-
-  SendClose();
-
-  socket_id_ = 0;
-
-  PostAbortIfNecessary(&bind_callback_);
-  PostAbortIfNecessary(&recvfrom_callback_);
-  PostAbortIfNecessary(&sendto_callback_);
-}
-
-void UDPSocketPrivateImpl::OnBindCompleted(
-    bool succeeded,
-    const PP_NetAddress_Private& addr) {
-  if (!TrackedCallback::IsPending(bind_callback_)) {
-    NOTREACHED();
-    return;
-  }
-
-  if (succeeded)
-    bound_ = true;
-
-  bound_addr_ = addr;
-
-  bind_callback_->Run(succeeded ? PP_OK : PP_ERROR_FAILED);
-}
-
-void UDPSocketPrivateImpl::OnRecvFromCompleted(
-    bool succeeded,
-    const std::string& data,
-    const PP_NetAddress_Private& addr) {
-  if (!TrackedCallback::IsPending(recvfrom_callback_) || !read_buffer_) {
-    NOTREACHED();
-    return;
-  }
-
-  if (succeeded) {
-    CHECK_LE(static_cast<int32_t>(data.size()), bytes_to_read_);
-    if (!data.empty())
-      memcpy(read_buffer_, data.c_str(), data.size());
-  }
-  read_buffer_ = NULL;
-  bytes_to_read_ = -1;
-  recvfrom_addr_ = addr;
-
-  recvfrom_callback_->Run(succeeded ? static_cast<int32_t>(data.size()) :
-      static_cast<int32_t>(PP_ERROR_FAILED));
-}
-
-void UDPSocketPrivateImpl::OnSendToCompleted(bool succeeded,
-                                             int32_t bytes_written) {
-  if (!TrackedCallback::IsPending(sendto_callback_)) {
-    NOTREACHED();
-    return;
-  }
-
-  sendto_callback_->Run(
-      succeeded ? bytes_written : static_cast<int32_t>(PP_ERROR_FAILED));
-}
-
-void UDPSocketPrivateImpl::Init(uint32 socket_id) {
-  DCHECK(socket_id != 0);
-  socket_id_ = socket_id;
-  bound_ = false;
-  closed_ = false;
-  read_buffer_ = NULL;
-  bytes_to_read_ = -1;
-
-  recvfrom_addr_.size = 0;
-  memset(recvfrom_addr_.data, 0,
-         arraysize(recvfrom_addr_.data) * sizeof(*recvfrom_addr_.data));
-  bound_addr_.size = 0;
-  memset(bound_addr_.data, 0,
-         arraysize(bound_addr_.data) * sizeof(*bound_addr_.data));
-}
-
-void UDPSocketPrivateImpl::PostAbortIfNecessary(
-    scoped_refptr<TrackedCallback>* callback) {
-  if (TrackedCallback::IsPending(*callback))
-    (*callback)->PostAbort();
-}
-
-}  // namespace ppapi
diff --git a/ppapi/shared_impl/private/udp_socket_private_impl.h b/ppapi/shared_impl/private/udp_socket_private_impl.h
deleted file mode 100644
index e8e3cb2..0000000
--- a/ppapi/shared_impl/private/udp_socket_private_impl.h
+++ /dev/null
@@ -1,99 +0,0 @@
-// 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.
-
-#ifndef PPAPI_SHARED_IMPL_PRIVATE_UDP_SOCKET_PRIVATE_IMPL_H_
-#define PPAPI_SHARED_IMPL_PRIVATE_UDP_SOCKET_PRIVATE_IMPL_H_
-
-#include <string>
-
-#include "base/compiler_specific.h"
-#include "ppapi/shared_impl/resource.h"
-#include "ppapi/shared_impl/tracked_callback.h"
-#include "ppapi/thunk/ppb_udp_socket_private_api.h"
-
-namespace ppapi {
-
-// This class provides the shared implementation of a
-// PPB_UDPSocket_Private.  The functions that actually send messages
-// to browser are implemented differently for the proxied and
-// non-proxied derived classes.
-class PPAPI_SHARED_EXPORT UDPSocketPrivateImpl
-    : public thunk::PPB_UDPSocket_Private_API,
-      public Resource {
- public:
-  // C-tor used in Impl case.
-  UDPSocketPrivateImpl(PP_Instance instance, uint32 socket_id);
-  // C-tor used in Proxy case.
-  UDPSocketPrivateImpl(const HostResource& resource, uint32 socket_id);
-
-  virtual ~UDPSocketPrivateImpl();
-
-  // The maximum number of bytes that each PpapiHostMsg_PPBUDPSocket_RecvFrom
-  // message is allowed to request.
-  static const int32_t kMaxReadSize;
-  // The maximum number of bytes that each PpapiHostMsg_PPBUDPSocket_SendTo
-  // message is allowed to carry.
-  static const int32_t kMaxWriteSize;
-
-  // Resource overrides.
-  virtual PPB_UDPSocket_Private_API* AsPPB_UDPSocket_Private_API() OVERRIDE;
-
-  // PPB_UDPSocket_Private_API implementation.
-  virtual int32_t SetSocketFeature(PP_UDPSocketFeature_Private name,
-                                   PP_Var value) OVERRIDE;
-  virtual int32_t Bind(const PP_NetAddress_Private* addr,
-                       scoped_refptr<TrackedCallback> callback) OVERRIDE;
-  virtual PP_Bool GetBoundAddress(PP_NetAddress_Private* addr) OVERRIDE;
-  virtual int32_t RecvFrom(char* buffer,
-                           int32_t num_bytes,
-                           scoped_refptr<TrackedCallback> callback) OVERRIDE;
-  virtual PP_Bool GetRecvFromAddress(PP_NetAddress_Private* addr) OVERRIDE;
-  virtual int32_t SendTo(const char* buffer,
-                         int32_t num_bytes,
-                         const PP_NetAddress_Private* addr,
-                         scoped_refptr<TrackedCallback> callback) OVERRIDE;
-  virtual void Close() OVERRIDE;
-
-  // Notifications from the proxy.
-  void OnBindCompleted(bool succeeded,
-                       const PP_NetAddress_Private& bound_addr);
-  void OnRecvFromCompleted(bool succeeded,
-                           const std::string& data,
-                           const PP_NetAddress_Private& addr);
-  void OnSendToCompleted(bool succeeded, int32_t bytes_written);
-
-  // Send functions that need to be implemented differently for
-  // the proxied and non-proxied derived classes.
-  virtual void SendBoolSocketFeature(int32_t name, bool value) = 0;
-  virtual void SendBind(const PP_NetAddress_Private& addr) = 0;
-  virtual void SendRecvFrom(int32_t num_bytes) = 0;
-  virtual void SendSendTo(const std::string& buffer,
-                          const PP_NetAddress_Private& addr) = 0;
-  virtual void SendClose() = 0;
-
- protected:
-  void Init(uint32 socket_id);
-  void PostAbortIfNecessary(scoped_refptr<TrackedCallback>* callback);
-
-  uint32 socket_id_;
-
-  bool bound_;
-  bool closed_;
-
-  scoped_refptr<TrackedCallback> bind_callback_;
-  scoped_refptr<TrackedCallback> recvfrom_callback_;
-  scoped_refptr<TrackedCallback> sendto_callback_;
-
-  char* read_buffer_;
-  int32_t bytes_to_read_;
-
-  PP_NetAddress_Private recvfrom_addr_;
-  PP_NetAddress_Private bound_addr_;
-
-  DISALLOW_COPY_AND_ASSIGN(UDPSocketPrivateImpl);
-};
-
-}  // namespace ppapi
-
-#endif  // PPAPI_SHARED_IMPL_PRIVATE_UDP_SOCKET_PRIVATE_IMPL_H_
diff --git a/ppapi/shared_impl/proxy_lock.cc b/ppapi/shared_impl/proxy_lock.cc
index 990130a..f9f937f 100644
--- a/ppapi/shared_impl/proxy_lock.cc
+++ b/ppapi/shared_impl/proxy_lock.cc
@@ -4,30 +4,54 @@
 
 #include "ppapi/shared_impl/proxy_lock.h"
 
+#include "base/lazy_instance.h"
 #include "base/synchronization/lock.h"
+#include "base/threading/thread_local.h"
 #include "ppapi/shared_impl/ppapi_globals.h"
 
 namespace ppapi {
 
+// Simple single-thread deadlock detector for the proxy lock.
+// |true| when the current thread has the lock.
+base::LazyInstance<base::ThreadLocalBoolean>::Leaky
+    g_proxy_locked_on_thread = LAZY_INSTANCE_INITIALIZER;
+
 // static
 void ProxyLock::Acquire() {
   base::Lock* lock(PpapiGlobals::Get()->GetProxyLock());
-  if (lock)
+  if (lock) {
+    // This thread does not already hold the lock.
+    const bool deadlock = g_proxy_locked_on_thread.Get().Get();
+    CHECK(!deadlock);
+
     lock->Acquire();
+    g_proxy_locked_on_thread.Get().Set(true);
+  }
 }
 
 // static
 void ProxyLock::Release() {
   base::Lock* lock(PpapiGlobals::Get()->GetProxyLock());
-  if (lock)
+  if (lock) {
+    // This thread currently holds the lock.
+    const bool locked = g_proxy_locked_on_thread.Get().Get();
+    CHECK(locked);
+
+    g_proxy_locked_on_thread.Get().Set(false);
     lock->Release();
+  }
 }
 
 // static
 void ProxyLock::AssertAcquired() {
   base::Lock* lock(PpapiGlobals::Get()->GetProxyLock());
-  if (lock)
+  if (lock) {
+    // This thread currently holds the lock.
+    const bool locked = g_proxy_locked_on_thread.Get().Get();
+    CHECK(locked);
+
     lock->AssertAcquired();
+  }
 }
 
 void CallWhileUnlocked(const base::Closure& closure) {
diff --git a/ppapi/shared_impl/resource.cc b/ppapi/shared_impl/resource.cc
index 88f908b..f1db8de 100644
--- a/ppapi/shared_impl/resource.cc
+++ b/ppapi/shared_impl/resource.cc
@@ -59,6 +59,10 @@
 }
 
 void Resource::NotifyInstanceWasDeleted() {
+  // Hold a reference, because InstanceWasDeleted() may cause us to be
+  // destroyed.
+  scoped_refptr<Resource> keep_alive(this);
+
   // Notify subclasses.
   InstanceWasDeleted();
 
@@ -70,7 +74,7 @@
   NOTREACHED();
 }
 
-void Resource::Log(PP_LogLevel_Dev level, const std::string& message) {
+void Resource::Log(PP_LogLevel level, const std::string& message) {
   PpapiGlobals::Get()->LogWithSource(pp_instance(), level, std::string(),
                                      message);
 }
diff --git a/ppapi/shared_impl/resource.h b/ppapi/shared_impl/resource.h
index 3f1f5ab..23522d5 100644
--- a/ppapi/shared_impl/resource.h
+++ b/ppapi/shared_impl/resource.h
@@ -13,7 +13,7 @@
 #include "base/memory/ref_counted.h"
 #include "ppapi/c/pp_instance.h"
 #include "ppapi/c/pp_resource.h"
-#include "ppapi/c/dev/ppb_console_dev.h"
+#include "ppapi/c/ppb_console.h"
 #include "ppapi/shared_impl/host_resource.h"
 
 // All resource types should be added here. This implements our hand-rolled
@@ -24,9 +24,10 @@
   F(PPB_AudioInput_API) \
   F(PPB_AudioTrusted_API) \
   F(PPB_Broker_API) \
+  F(PPB_Broker_Instance_API) \
+  F(PPB_BrowserFont_Singleton_API) \
   F(PPB_BrowserFont_Trusted_API) \
   F(PPB_Buffer_API) \
-  F(PPB_BufferTrusted_API) \
   F(PPB_DeviceRef_API) \
   F(PPB_DirectoryReader_API) \
   F(PPB_FileChooser_API) \
@@ -36,10 +37,13 @@
   F(PPB_Find_API) \
   F(PPB_Flash_Clipboard_API) \
   F(PPB_Flash_DeviceID_API) \
+  F(PPB_Flash_File_API) \
   F(PPB_Flash_FontFile_API) \
+  F(PPB_Flash_Fullscreen_API) \
   F(PPB_Flash_Functions_API) \
   F(PPB_Flash_Menu_API) \
   F(PPB_Flash_MessageLoop_API) \
+  F(PPB_Gamepad_API) \
   F(PPB_Graphics2D_API) \
   F(PPB_Graphics3D_API) \
   F(PPB_HostResolver_Private_API) \
@@ -49,11 +53,12 @@
   F(PPB_MessageLoop_API) \
   F(PPB_NetworkList_Private_API) \
   F(PPB_NetworkMonitor_Private_API) \
-  F(PPB_PDFFont_API) \
   F(PPB_Printing_API) \
   F(PPB_ResourceArray_API) \
   F(PPB_Scrollbar_API) \
   F(PPB_Talk_Private_API) \
+  F(PPB_TrueTypeFont_API) \
+  F(PPB_TrueTypeFont_Singleton_API) \
   F(PPB_TCPServerSocket_Private_API) \
   F(PPB_TCPSocket_Private_API) \
   F(PPB_UDPSocket_Private_API) \
@@ -199,7 +204,7 @@
 
  protected:
   // Logs a message to the console from this resource.
-  void Log(PP_LogLevel_Dev level, const std::string& message);
+  void Log(PP_LogLevel level, const std::string& message);
 
   // Notifications for subclasses.
   virtual void LastPluginRefWasDeleted() {}
diff --git a/ppapi/shared_impl/resource_tracker.cc b/ppapi/shared_impl/resource_tracker.cc
index 45f127a..f7e22eb 100644
--- a/ppapi/shared_impl/resource_tracker.cc
+++ b/ppapi/shared_impl/resource_tracker.cc
@@ -10,6 +10,7 @@
 #include "ppapi/shared_impl/callback_tracker.h"
 #include "ppapi/shared_impl/id_assignment.h"
 #include "ppapi/shared_impl/ppapi_globals.h"
+#include "ppapi/shared_impl/proxy_lock.h"
 #include "ppapi/shared_impl/resource.h"
 
 namespace ppapi {
@@ -24,6 +25,7 @@
 
 Resource* ResourceTracker::GetResource(PP_Resource res) const {
   CHECK(thread_checker_.CalledOnValidThread());
+  ProxyLock::AssertAcquired();
   ResourceMap::const_iterator i = live_resources_.find(res);
   if (i == live_resources_.end())
     return NULL;
@@ -78,9 +80,9 @@
 void ResourceTracker::ReleaseResourceSoon(PP_Resource res) {
   MessageLoop::current()->PostNonNestableTask(
       FROM_HERE,
-      base::Bind(&ResourceTracker::ReleaseResource,
-             weak_ptr_factory_.GetWeakPtr(),
-             res));
+      RunWhileLocked(base::Bind(&ResourceTracker::ReleaseResource,
+                                weak_ptr_factory_.GetWeakPtr(),
+                                res)));
 }
 
 void ResourceTracker::DidCreateInstance(PP_Instance instance) {
diff --git a/ppapi/shared_impl/scoped_pp_resource.cc b/ppapi/shared_impl/scoped_pp_resource.cc
index 8399208..45a1ad7 100644
--- a/ppapi/shared_impl/scoped_pp_resource.cc
+++ b/ppapi/shared_impl/scoped_pp_resource.cc
@@ -55,7 +55,8 @@
 }
 
 PP_Resource ScopedPPResource::Release() {
-  CallRelease();
+  // We do NOT call CallRelease, because we want to pass our reference to the
+  // caller.
 
   PP_Resource ret = id_;
   id_ = 0;
diff --git a/ppapi/shared_impl/scoped_pp_var.cc b/ppapi/shared_impl/scoped_pp_var.cc
index fcd6806..3ae13b0 100644
--- a/ppapi/shared_impl/scoped_pp_var.cc
+++ b/ppapi/shared_impl/scoped_pp_var.cc
@@ -47,4 +47,10 @@
   return *this;
 }
 
+PP_Var ScopedPPVar::Release() {
+  PP_Var result = var_;
+  var_ = PP_MakeUndefined();
+  return result;
+}
+
 }  // namespace ppapi
diff --git a/ppapi/shared_impl/scoped_pp_var.h b/ppapi/shared_impl/scoped_pp_var.h
index 8079a91..564401d 100644
--- a/ppapi/shared_impl/scoped_pp_var.h
+++ b/ppapi/shared_impl/scoped_pp_var.h
@@ -16,7 +16,7 @@
 
   ScopedPPVar();
 
-  // Takes one reference to the given resource.
+  // Takes one reference to the given var.
   explicit ScopedPPVar(const PP_Var& v);
 
   // Assumes responsibility for one ref that the var already has.
diff --git a/ppapi/shared_impl/singleton_resource_id.h b/ppapi/shared_impl/singleton_resource_id.h
new file mode 100644
index 0000000..ef3096d
--- /dev/null
+++ b/ppapi/shared_impl/singleton_resource_id.h
@@ -0,0 +1,29 @@
+// 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.
+
+#ifndef PPAPI_SHARED_IMPL_SINGLETON_RESOURCE_ID_H_
+#define PPAPI_SHARED_IMPL_SINGLETON_RESOURCE_ID_H_
+
+namespace ppapi {
+
+// These IDs are used to access singleton resource objects using
+// PPB_Instance_API.GetSingletonResource.
+enum SingletonResourceID {
+  // TODO(raymes): The broker resource isn't really a singleton. This is only
+  // a hack until PPB_Broker trusted has been fully refactored to the new
+  // resource model.
+  BROKER_SINGLETON_ID,
+  BROWSER_FONT_SINGLETON_ID,
+  FLASH_CLIPBOARD_SINGLETON_ID,
+  FLASH_FILE_SINGLETON_ID,
+  FLASH_FULLSCREEN_SINGLETON_ID,
+  FLASH_SINGLETON_ID,
+  GAMEPAD_SINGLETON_ID,
+  PDF_SINGLETON_ID,
+  TRUETYPE_FONT_SINGLETON_ID,
+};
+
+}  // namespace ppapi
+
+#endif  // PPAPI_SHARED_IMPL_SINGLETON_RESOURCE_ID_H_
diff --git a/ppapi/shared_impl/test_globals.cc b/ppapi/shared_impl/test_globals.cc
index b1dc0fe..913d53c 100644
--- a/ppapi/shared_impl/test_globals.cc
+++ b/ppapi/shared_impl/test_globals.cc
@@ -11,8 +11,8 @@
       callback_tracker_(new CallbackTracker) {
 }
 
-TestGlobals::TestGlobals(PpapiGlobals::ForTest for_test)
-    : ppapi::PpapiGlobals(for_test),
+TestGlobals::TestGlobals(PpapiGlobals::PerThreadForTest per_thread_for_test)
+    : ppapi::PpapiGlobals(per_thread_for_test),
       callback_tracker_(new CallbackTracker) {
 }
 
@@ -58,13 +58,13 @@
 }
 
 void TestGlobals::LogWithSource(PP_Instance instance,
-                                PP_LogLevel_Dev level,
+                                PP_LogLevel level,
                                 const std::string& source,
                                 const std::string& value) {
 }
 
 void TestGlobals::BroadcastLogWithSource(PP_Module module,
-                                         PP_LogLevel_Dev level,
+                                         PP_LogLevel level,
                                          const std::string& source,
                                          const std::string& value) {
 }
diff --git a/ppapi/shared_impl/test_globals.h b/ppapi/shared_impl/test_globals.h
index ca67e77..5579b09 100644
--- a/ppapi/shared_impl/test_globals.h
+++ b/ppapi/shared_impl/test_globals.h
@@ -6,6 +6,7 @@
 #define PPAPI_SHARED_IMPL_TEST_GLOBALS_H_
 
 #include "base/compiler_specific.h"
+#include "base/shared_memory.h"
 #include "ppapi/shared_impl/callback_tracker.h"
 #include "ppapi/shared_impl/ppapi_globals.h"
 #include "ppapi/shared_impl/resource_tracker.h"
@@ -20,8 +21,24 @@
   virtual ArrayBufferVar* CreateArrayBuffer(uint32 size_in_bytes) OVERRIDE {
     return NULL;
   }
+  virtual ArrayBufferVar* CreateShmArrayBuffer(
+      uint32 size_in_bytes,
+      base::SharedMemoryHandle handle) OVERRIDE {
+    return NULL;
+  }
   virtual void DidDeleteInstance(PP_Instance instance) OVERRIDE {
   }
+  virtual int TrackSharedMemoryHandle(PP_Instance instance,
+                                      base::SharedMemoryHandle handle,
+                                      uint32 size_in_bytes) OVERRIDE {
+    return -1;
+  }
+  virtual bool StopTrackingSharedMemoryHandle(int id,
+                                              PP_Instance instance,
+                                              base::SharedMemoryHandle* handle,
+                                              uint32* size_in_bytes) OVERRIDE {
+    return false;
+  }
 };
 
 // Implementation of PpapiGlobals for tests that don't need either the host- or
@@ -29,7 +46,7 @@
 class TestGlobals : public PpapiGlobals {
  public:
   TestGlobals();
-  TestGlobals(PpapiGlobals::ForTest);
+  explicit TestGlobals(PpapiGlobals::PerThreadForTest);
   virtual ~TestGlobals();
 
   // PpapiGlobals implementation.
@@ -46,11 +63,11 @@
   virtual void PreCacheFontForFlash(const void* logfontw) OVERRIDE;
   virtual base::Lock* GetProxyLock() OVERRIDE;
   virtual void LogWithSource(PP_Instance instance,
-                             PP_LogLevel_Dev level,
+                             PP_LogLevel level,
                              const std::string& source,
                              const std::string& value) OVERRIDE;
   virtual void BroadcastLogWithSource(PP_Module module,
-                                      PP_LogLevel_Dev level,
+                                      PP_LogLevel level,
                                       const std::string& source,
                                       const std::string& value) OVERRIDE;
   virtual MessageLoopShared* GetCurrentMessageLoop() OVERRIDE;
diff --git a/ppapi/shared_impl/thread_aware_callback.cc b/ppapi/shared_impl/thread_aware_callback.cc
new file mode 100644
index 0000000..9b1063b
--- /dev/null
+++ b/ppapi/shared_impl/thread_aware_callback.cc
@@ -0,0 +1,63 @@
+// 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 "ppapi/shared_impl/thread_aware_callback.h"
+
+#include "base/callback.h"
+#include "base/logging.h"
+#include "ppapi/shared_impl/ppapi_globals.h"
+#include "ppapi/shared_impl/ppb_message_loop_shared.h"
+
+namespace ppapi {
+namespace internal {
+
+class ThreadAwareCallbackBase::Core : public base::RefCountedThreadSafe<Core> {
+ public:
+  Core() : aborted_(false) {
+  }
+
+  void MarkAsAborted() { aborted_ = true; }
+
+  void RunIfNotAborted(const base::Closure& closure) {
+    if (!aborted_)
+      CallWhileUnlocked(closure);
+  }
+
+ private:
+  friend class base::RefCountedThreadSafe<Core>;
+  ~Core() {
+  }
+
+  bool aborted_;
+};
+
+ThreadAwareCallbackBase::ThreadAwareCallbackBase()
+    : target_loop_(PpapiGlobals::Get()->GetCurrentMessageLoop()),
+      core_(new Core()) {
+  DCHECK(target_loop_.get());
+}
+
+ThreadAwareCallbackBase::~ThreadAwareCallbackBase() {
+  core_->MarkAsAborted();
+}
+
+// static
+bool ThreadAwareCallbackBase::HasTargetLoop() {
+  return !!PpapiGlobals::Get()->GetCurrentMessageLoop();
+}
+
+void ThreadAwareCallbackBase::InternalRunOnTargetThread(
+    const base::Closure& closure) {
+  if (target_loop_ != PpapiGlobals::Get()->GetCurrentMessageLoop()) {
+    target_loop_->PostClosure(
+        FROM_HERE,
+        RunWhileLocked(base::Bind(&Core::RunIfNotAborted, core_, closure)),
+        0);
+  } else {
+    CallWhileUnlocked(closure);
+  }
+}
+
+}  // namespace internal
+}  // namespace ppapi
diff --git a/ppapi/shared_impl/thread_aware_callback.h b/ppapi/shared_impl/thread_aware_callback.h
new file mode 100644
index 0000000..b954eec
--- /dev/null
+++ b/ppapi/shared_impl/thread_aware_callback.h
@@ -0,0 +1,115 @@
+// Copyright (c) 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 PPAPI_SHARED_IMPL_THREAD_AWARE_CALLBACK_H_
+#define PPAPI_SHARED_IMPL_THREAD_AWARE_CALLBACK_H_
+
+#include "base/basictypes.h"
+#include "base/bind.h"
+#include "base/memory/ref_counted.h"
+#include "ppapi/shared_impl/ppapi_shared_export.h"
+#include "ppapi/shared_impl/proxy_lock.h"
+
+namespace ppapi {
+
+class MessageLoopShared;
+
+namespace internal {
+
+class PPAPI_SHARED_EXPORT ThreadAwareCallbackBase {
+ protected:
+  ThreadAwareCallbackBase();
+  ~ThreadAwareCallbackBase();
+
+  static bool HasTargetLoop();
+
+  void InternalRunOnTargetThread(const base::Closure& closure);
+
+ private:
+  class Core;
+
+  scoped_refptr<MessageLoopShared> target_loop_;
+  scoped_refptr<Core> core_;
+
+  DISALLOW_COPY_AND_ASSIGN(ThreadAwareCallbackBase);
+};
+
+}  // namespace internal
+
+// Some PPB interfaces have methods that set a custom callback. Usually, the
+// callback has to be called on the same thread as the one it was set on.
+// ThreadAwareCallback keeps track of the target thread, and posts a task to run
+// on it if requested from a different thread.
+//
+// Please note that:
+// - Unlike TrackedCallback, there is no restriction on how many times the
+//   callback will be called.
+// - When a ThreadAwareCallback object is destroyed, all pending tasks to run
+//   the callback will be ignored. It is designed this way so that when the
+//   resource is destroyed or the callback is cancelled by the plugin, we can
+//   simply delete the ThreadAwareCallback object to prevent touching the
+//   callback later.
+// - When RunOnTargetThread() is called on the target thread, the callback runs
+//   immediately.
+template <class FuncType>
+class ThreadAwareCallback : public internal::ThreadAwareCallbackBase {
+ public:
+  // The caller takes ownership of the returned object.
+  // NULL is returned if the current thread doesn't have an associated Pepper
+  // message loop, or |func| is NULL.
+  static ThreadAwareCallback* Create(FuncType func) {
+    if (!func || !HasTargetLoop())
+      return NULL;
+    return new ThreadAwareCallback(func);
+  }
+
+  ~ThreadAwareCallback() {
+  }
+
+  void RunOnTargetThread() {
+    InternalRunOnTargetThread(base::Bind(func_));
+  }
+
+  template <class P1>
+  void RunOnTargetThread(const P1& p1) {
+    InternalRunOnTargetThread(base::Bind(func_, p1));
+  }
+
+  template <class P1, class P2>
+  void RunOnTargetThread(const P1& p1, const P2& p2) {
+    InternalRunOnTargetThread(base::Bind(func_, p1, p2));
+  }
+
+  template <class P1, class P2, class P3>
+  void RunOnTargetThread(const P1& p1, const P2& p2, const P3& p3) {
+    InternalRunOnTargetThread(base::Bind(func_, p1, p2, p3));
+  }
+
+  template <class P1, class P2, class P3, class P4>
+  void RunOnTargetThread(const P1& p1,
+                         const P2& p2,
+                         const P3& p3,
+                         const P4& p4) {
+    InternalRunOnTargetThread(base::Bind(func_, p1, p2, p3, p4));
+  }
+
+  template <class P1, class P2, class P3, class P4, class P5>
+  void RunOnTargetThread(const P1& p1,
+                         const P2& p2,
+                         const P3& p3,
+                         const P4& p4,
+                         const P5& p5) {
+    InternalRunOnTargetThread(base::Bind(func_, p1, p2, p3, p4, p5));
+  }
+
+ private:
+  explicit ThreadAwareCallback(FuncType func) : func_(func) {
+  }
+
+  FuncType func_;
+};
+
+}  // namespace ppapi
+
+#endif  // PPAPI_SHARED_IMPL_THREAD_AWARE_CALLBACK_H_
diff --git a/ppapi/shared_impl/thread_aware_callback_unittest.cc b/ppapi/shared_impl/thread_aware_callback_unittest.cc
new file mode 100644
index 0000000..f86048a
--- /dev/null
+++ b/ppapi/shared_impl/thread_aware_callback_unittest.cc
@@ -0,0 +1,218 @@
+// 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 "ppapi/shared_impl/thread_aware_callback.h"
+
+#include "base/bind_helpers.h"
+#include "base/compiler_specific.h"
+#include "base/logging.h"
+#include "base/memory/scoped_ptr.h"
+#include "ppapi/c/pp_errors.h"
+#include "ppapi/proxy/ppapi_proxy_test.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace ppapi {
+
+namespace {
+
+class TestParameter {
+ public:
+  TestParameter() : value_(0) {
+  }
+
+  int value_;
+};
+
+int called_num = 0;
+
+void TestCallback_0() {
+  ++called_num;
+}
+
+void TestCallback_1(int p1) {
+  ++called_num;
+}
+
+void TestCallback_2(int p1, const double* p2) {
+  ++called_num;
+}
+
+void TestCallback_3(int p1, const double* p2, bool* p3) {
+  ++called_num;
+}
+
+void TestCallback_4(int p1, const double* p2, bool* p3, TestParameter p4) {
+  ++called_num;
+}
+
+void TestCallback_5(int p1,
+                    const double* p2,
+                    bool* p3,
+                    TestParameter p4,
+                    const TestParameter& p5) {
+  ++called_num;
+}
+
+typedef proxy::PluginProxyTest ThreadAwareCallbackTest;
+
+// Test that a callback created on the main thread will run on the main thread,
+// even when requested from a different thread.
+class ThreadAwareCallbackMultiThreadTest
+    : public proxy::PluginProxyMultiThreadTest {
+ public:
+  ThreadAwareCallbackMultiThreadTest() : main_thread_callback_called_(false) {
+  }
+  virtual ~ThreadAwareCallbackMultiThreadTest() {
+    CHECK(main_thread_callback_called_);
+  }
+
+  // proxy::PluginProxyMultiThreadTest implementation.
+  virtual void SetUpTestOnMainThread() OVERRIDE {
+    ProxyAutoLock auto_lock;
+
+    main_thread_callback_.reset(
+        ThreadAwareCallback<CallbackFunc>::Create(&MainThreadCallbackBody));
+  }
+
+  virtual void SetUpTestOnSecondaryThread() OVERRIDE {
+    {
+      ProxyAutoLock auto_lock;
+      main_thread_callback_->RunOnTargetThread(this);
+    }
+
+    PostQuitForSecondaryThread();
+    PostQuitForMainThread();
+  }
+
+ private:
+  typedef void (*CallbackFunc)(ThreadAwareCallbackMultiThreadTest*);
+
+  static void MainThreadCallbackBody(ThreadAwareCallbackMultiThreadTest* thiz) {
+    thiz->CheckOnThread(MAIN_THREAD);
+    thiz->main_thread_callback_called_ = true;
+
+    {
+      ProxyAutoLock auto_lock;
+      // We have to destroy it prior to the PluginGlobals instance held by the
+      // base class. Otherwise it has a ref to Pepper message loop for the main
+      // thread and the PluginGlobals destructor will complain.
+      thiz->main_thread_callback_.reset(NULL);
+    }
+  }
+
+  scoped_ptr<ThreadAwareCallback<CallbackFunc> > main_thread_callback_;
+  bool main_thread_callback_called_;
+};
+
+// Test that when a ThreadAwareCallback instance is destroyed, pending tasks to
+// run the callback will be ignored.
+class ThreadAwareCallbackAbortTest : public proxy::PluginProxyMultiThreadTest {
+ public:
+  ThreadAwareCallbackAbortTest() {
+  }
+  virtual ~ThreadAwareCallbackAbortTest() {
+  }
+
+  // proxy::PluginProxyMultiThreadTest implementation.
+  virtual void SetUpTestOnMainThread() OVERRIDE {
+    ProxyAutoLock auto_lock;
+
+    main_thread_callback_.reset(
+        ThreadAwareCallback<CallbackFunc>::Create(&MainThreadCallbackBody));
+  }
+
+  virtual void SetUpTestOnSecondaryThread() OVERRIDE {
+    {
+      ProxyAutoLock auto_lock;
+      main_thread_message_loop_proxy_->PostTask(
+          FROM_HERE,
+          base::Bind(&ThreadAwareCallbackAbortTest::DeleteCallback,
+                     base::Unretained(this)));
+      // |main_thread_callback_| is still valid, even if DeleteCallback() can be
+      // called before this following statement. That is because |auto_lock| is
+      // still held by this method, which prevents DeleteCallback() from
+      // deleting the callback.
+      main_thread_callback_->RunOnTargetThread(this);
+    }
+
+    PostQuitForSecondaryThread();
+    PostQuitForMainThread();
+  }
+
+ private:
+  typedef void (*CallbackFunc)(ThreadAwareCallbackAbortTest*);
+
+  static void MainThreadCallbackBody(ThreadAwareCallbackAbortTest* thiz) {
+    // The callback should not be called.
+    ASSERT_TRUE(false);
+  }
+
+  void DeleteCallback() {
+    ProxyAutoLock auto_lock;
+    main_thread_callback_.reset(NULL);
+  }
+
+  scoped_ptr<ThreadAwareCallback<CallbackFunc> > main_thread_callback_;
+};
+
+}  // namespace
+
+TEST_F(ThreadAwareCallbackTest, Basics) {
+  // ThreadAwareCallback should only be used when the proxy lock has been
+  // acquired.
+  ProxyAutoLock auto_lock;
+
+  double double_arg = 0.0;
+  bool bool_arg = false;
+  TestParameter object_arg;
+
+  // Exercise all the template code.
+  called_num = 0;
+  typedef void (*FuncType_0)();
+  scoped_ptr<ThreadAwareCallback<FuncType_0> > callback_0(
+      ThreadAwareCallback<FuncType_0>::Create(TestCallback_0));
+  callback_0->RunOnTargetThread();
+
+  typedef void (*FuncType_1)(int);
+  scoped_ptr<ThreadAwareCallback<FuncType_1> > callback_1(
+      ThreadAwareCallback<FuncType_1>::Create(TestCallback_1));
+  callback_1->RunOnTargetThread(1);
+
+  typedef void (*FuncType_2)(int, const double*);
+  scoped_ptr<ThreadAwareCallback<FuncType_2> > callback_2(
+      ThreadAwareCallback<FuncType_2>::Create(TestCallback_2));
+  callback_2->RunOnTargetThread(1, &double_arg);
+
+  typedef void (*FuncType_3)(int, const double*, bool*);
+  scoped_ptr<ThreadAwareCallback<FuncType_3> > callback_3(
+      ThreadAwareCallback<FuncType_3>::Create(TestCallback_3));
+  callback_3->RunOnTargetThread(1, &double_arg, &bool_arg);
+
+  typedef void (*FuncType_4)(int, const double*, bool*, TestParameter);
+  scoped_ptr<ThreadAwareCallback<FuncType_4> > callback_4(
+      ThreadAwareCallback<FuncType_4>::Create(TestCallback_4));
+  callback_4->RunOnTargetThread(1, &double_arg, &bool_arg, object_arg);
+
+  typedef void (*FuncType_5)(int,
+                             const double*,
+                             bool*,
+                             TestParameter,
+                             const TestParameter&);
+  scoped_ptr<ThreadAwareCallback<FuncType_5> > callback_5(
+      ThreadAwareCallback<FuncType_5>::Create(TestCallback_5));
+  callback_5->RunOnTargetThread(1, &double_arg, &bool_arg, object_arg,
+                               object_arg);
+
+  EXPECT_EQ(6, called_num);
+}
+
+TEST_F(ThreadAwareCallbackMultiThreadTest, RunOnTargetThread) {
+  RunTest();
+}
+
+TEST_F(ThreadAwareCallbackAbortTest, NotRunIfAborted) {
+  RunTest();
+}
+
+}  // namespace ppapi
diff --git a/ppapi/shared_impl/time_conversion.cc b/ppapi/shared_impl/time_conversion.cc
index 53d7b99..27ea494 100644
--- a/ppapi/shared_impl/time_conversion.cc
+++ b/ppapi/shared_impl/time_conversion.cc
@@ -30,6 +30,12 @@
 }
 
 base::Time PPTimeToTime(PP_Time t) {
+  // The time code handles exact "0" values as special, and produces
+  // a "null" Time object. But calling code would expect t==0 to represent the
+  // epoch (according to the description of PP_Time). Hence we just return the
+  // epoch in this case.
+  if (t == 0.0)
+    return base::Time::UnixEpoch();
   return base::Time::FromDoubleT(t);
 }
 
@@ -46,4 +52,20 @@
   return t - GetTimeToTimeTicksDeltaInSeconds();
 }
 
+double PPGetLocalTimeZoneOffset(const base::Time& time) {
+  // Explode it to local time and then unexplode it as if it were UTC. Also
+  // explode it to UTC and unexplode it (this avoids mismatching rounding or
+  // lack thereof). The time zone offset is their difference.
+  base::Time::Exploded exploded = { 0 };
+  base::Time::Exploded utc_exploded = { 0 };
+  time.LocalExplode(&exploded);
+  time.UTCExplode(&utc_exploded);
+  if (exploded.HasValidValues() && utc_exploded.HasValidValues()) {
+    base::Time adj_time = base::Time::FromUTCExploded(exploded);
+    base::Time cur = base::Time::FromUTCExploded(utc_exploded);
+    return (adj_time - cur).InSecondsF();
+  }
+  return 0.0;
+}
+
 }  // namespace ppapi
diff --git a/ppapi/shared_impl/time_conversion.h b/ppapi/shared_impl/time_conversion.h
index 0acd39e..e20d809 100644
--- a/ppapi/shared_impl/time_conversion.h
+++ b/ppapi/shared_impl/time_conversion.h
@@ -23,6 +23,11 @@
 PPAPI_SHARED_EXPORT PP_TimeTicks EventTimeToPPTimeTicks(double event_time);
 PPAPI_SHARED_EXPORT double PPTimeTicksToEventTime(PP_TimeTicks t);
 
+// Gets the local time zone offset for a given time. This works in the plugin
+// process only on Windows (the sandbox prevents this from working properly on
+// other platforms).
+PPAPI_SHARED_EXPORT double PPGetLocalTimeZoneOffset(const base::Time& time);
+
 }  // namespace ppapi
 
 #endif  // PPAPI_SHARED_IMPL_TIME_CONVERSION_H_
diff --git a/ppapi/shared_impl/time_conversion_unittest.cc b/ppapi/shared_impl/time_conversion_unittest.cc
new file mode 100644
index 0000000..1ec70bf
--- /dev/null
+++ b/ppapi/shared_impl/time_conversion_unittest.cc
@@ -0,0 +1,73 @@
+// 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 <math.h>
+#include <stdlib.h>
+
+#include "ppapi/shared_impl/time_conversion.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace ppapi {
+
+// Slop we'll allow in two Time "internal values" to consider them equal.
+// Double conversion can introduce rounding errors. The internal values are in
+// microseconds, so an error here is very small.
+static const int kTimeInternalValueSlop = 2;
+
+// Same as above in double-precision seconds units.
+static const double kTimeSecondsSlop =
+    static_cast<double>(kTimeInternalValueSlop) /
+    base::Time::kMicrosecondsPerSecond;
+
+TEST(TimeConversion, Time) {
+  // Should be able to round-trip.
+  base::Time now = base::Time::Now();
+  base::Time converted = ppapi::PPTimeToTime(TimeToPPTime(now));
+  EXPECT_GE(kTimeInternalValueSlop,
+            abs(static_cast<int>((converted - now).ToInternalValue())));
+
+  // Units should be in seconds.
+  base::Time one_second_from_now = now + base::TimeDelta::FromSeconds(1);
+  double converted_one_second_from_now =
+      ppapi::TimeToPPTime(one_second_from_now) - ppapi::TimeToPPTime(now);
+  EXPECT_GE(kTimeSecondsSlop, fabs(converted_one_second_from_now - 1));
+}
+
+TEST(TimeConversion, EventTime) {
+  // Should be able to round-trip.
+  base::Time now = base::Time::Now();
+  double event_now = now.ToDoubleT();
+  double converted =
+      ppapi::EventTimeToPPTimeTicks(ppapi::PPTimeTicksToEventTime(event_now));
+  EXPECT_GE(kTimeSecondsSlop, fabs(converted - event_now));
+
+  // Units should be in seconds.
+  base::Time one_second_from_now = now + base::TimeDelta::FromSeconds(1);
+  double event_one_second_from_now = one_second_from_now.ToDoubleT();
+  EXPECT_GE(kTimeSecondsSlop,
+            1.0 - ppapi::EventTimeToPPTimeTicks(event_one_second_from_now) -
+                ppapi::EventTimeToPPTimeTicks(event_now));
+}
+
+TEST(TimeConversion, EpochTime) {
+  // Should be able to round-trip from epoch time.
+  base::Time epoch = base::Time::UnixEpoch();
+  base::Time converted = ppapi::PPTimeToTime(TimeToPPTime(epoch));
+  EXPECT_GE(kTimeInternalValueSlop,
+            abs(static_cast<int>((converted - epoch).ToInternalValue())));
+
+  // Units should be in seconds.
+  base::Time one_second_from_epoch = epoch + base::TimeDelta::FromSeconds(1);
+  double converted_one_second_from_epoch =
+      ppapi::TimeToPPTime(one_second_from_epoch) - ppapi::TimeToPPTime(epoch);
+  EXPECT_GE(kTimeSecondsSlop, fabs(converted_one_second_from_epoch - 1));
+
+  // Epoch time should be equal to a PP_Time of 0.0.
+  EXPECT_GE(kTimeSecondsSlop, fabs(ppapi::TimeToPPTime(epoch) - 0.0));
+  EXPECT_GE(kTimeInternalValueSlop,
+            abs(static_cast<int>(
+                (ppapi::PPTimeToTime(0.0) - epoch).ToInternalValue())));
+}
+
+}  // namespace ppapi
diff --git a/ppapi/shared_impl/tracked_callback.cc b/ppapi/shared_impl/tracked_callback.cc
index bd011df..ae4656e 100644
--- a/ppapi/shared_impl/tracked_callback.cc
+++ b/ppapi/shared_impl/tracked_callback.cc
@@ -9,9 +9,9 @@
 #include "base/logging.h"
 #include "base/message_loop.h"
 #include "base/synchronization/lock.h"
-#include "ppapi/c/dev/ppb_message_loop_dev.h"
 #include "ppapi/c/pp_completion_callback.h"
 #include "ppapi/c/pp_errors.h"
+#include "ppapi/c/ppb_message_loop.h"
 #include "ppapi/shared_impl/callback_tracker.h"
 #include "ppapi/shared_impl/ppapi_globals.h"
 #include "ppapi/shared_impl/ppb_message_loop_shared.h"
diff --git a/ppapi/shared_impl/tracked_callback_unittest.cc b/ppapi/shared_impl/tracked_callback_unittest.cc
index ca4d3b1..bc1c7f3 100644
--- a/ppapi/shared_impl/tracked_callback_unittest.cc
+++ b/ppapi/shared_impl/tracked_callback_unittest.cc
@@ -220,18 +220,18 @@
   // Kill resource #1, spin the message loop to run posted calls, and check that
   // things are in the expected states.
   resource_tracker->ReleaseResource(resource_1_id);
-  MessageLoop::current()->RunAllPending();
+  MessageLoop::current()->RunUntilIdle();
   resource_1->CheckFinalState();
   resource_2->CheckIntermediateState();
 
   // Kill resource #2.
   resource_tracker->ReleaseResource(resource_2_id);
-  MessageLoop::current()->RunAllPending();
+  MessageLoop::current()->RunUntilIdle();
   resource_1->CheckFinalState();
   resource_2->CheckFinalState();
 
   // This shouldn't be needed, but make sure there are no stranded tasks.
-  MessageLoop::current()->RunAllPending();
+  MessageLoop::current()->RunUntilIdle();
 }
 
 // Test that "resurrecting" a resource (getting a new ID for a |Resource|)
@@ -247,21 +247,21 @@
   // Unref it, spin the message loop to run posted calls, and check that things
   // are in the expected states.
   resource_tracker->ReleaseResource(resource_id);
-  MessageLoop::current()->RunAllPending();
+  MessageLoop::current()->RunUntilIdle();
   resource->CheckFinalState();
 
   // "Resurrect" it and check that the callbacks are still dead.
   PP_Resource new_resource_id = resource->GetReference();
-  MessageLoop::current()->RunAllPending();
+  MessageLoop::current()->RunUntilIdle();
   resource->CheckFinalState();
 
   // Unref it again and do the same.
   resource_tracker->ReleaseResource(new_resource_id);
-  MessageLoop::current()->RunAllPending();
+  MessageLoop::current()->RunUntilIdle();
   resource->CheckFinalState();
 
   // This shouldn't be needed, but make sure there are no stranded tasks.
-  MessageLoop::current()->RunAllPending();
+  MessageLoop::current()->RunUntilIdle();
 }
 
 }  // namespace ppapi
diff --git a/ppapi/shared_impl/url_response_info_data.cc b/ppapi/shared_impl/url_response_info_data.cc
new file mode 100644
index 0000000..0b4b078
--- /dev/null
+++ b/ppapi/shared_impl/url_response_info_data.cc
@@ -0,0 +1,15 @@
+// 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 "ppapi/shared_impl/url_response_info_data.h"
+
+namespace ppapi {
+
+URLResponseInfoData::URLResponseInfoData() : status_code(-1) {
+}
+
+URLResponseInfoData::~URLResponseInfoData() {
+}
+
+}  // namespace ppapi
diff --git a/ppapi/shared_impl/url_response_info_data.h b/ppapi/shared_impl/url_response_info_data.h
new file mode 100644
index 0000000..a40ca50
--- /dev/null
+++ b/ppapi/shared_impl/url_response_info_data.h
@@ -0,0 +1,32 @@
+// 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.
+
+#ifndef PPAPI_SHARED_IMPL_URL_RESPONSE_INFO_DATA_H_
+#define PPAPI_SHARED_IMPL_URL_RESPONSE_INFO_DATA_H_
+
+#include <string>
+
+#include "ppapi/c/pp_stdint.h"
+#include "ppapi/shared_impl/ppb_file_ref_shared.h"
+#include "ppapi/shared_impl/ppapi_shared_export.h"
+
+namespace ppapi {
+
+struct PPAPI_SHARED_EXPORT URLResponseInfoData {
+  URLResponseInfoData();
+  ~URLResponseInfoData();
+
+  std::string url;
+  std::string headers;
+  int32_t status_code;
+  std::string status_text;
+  std::string redirect_url;
+
+  // Nonzero when streaming to a file.
+  PPB_FileRef_CreateInfo body_as_file_ref;
+};
+
+}  // namespace ppapi
+
+#endif  // PPAPI_SHARED_IMPL_URL_RESPONSE_INFO_DATA_H_
diff --git a/ppapi/shared_impl/var.cc b/ppapi/shared_impl/var.cc
index 2e63dbe..0aff583 100644
--- a/ppapi/shared_impl/var.cc
+++ b/ppapi/shared_impl/var.cc
@@ -56,6 +56,12 @@
     }
     case PP_VARTYPE_OBJECT:
       return "[Object]";
+    case PP_VARTYPE_ARRAY:
+      return "[Array]";
+    case PP_VARTYPE_DICTIONARY:
+      return "[Dictionary]";
+    case PP_VARTYPE_ARRAY_BUFFER:
+      return "[Array buffer]";
     default:
       return "[Invalid var]";
   }
@@ -77,6 +83,14 @@
   return NULL;
 }
 
+ArrayVar* Var::AsArrayVar() {
+  return NULL;
+}
+
+DictionaryVar* Var::AsDictionaryVar() {
+  return NULL;
+}
+
 PP_Var Var::GetPPVar() {
   int32 id = GetOrCreateVarID();
   if (!id)
diff --git a/ppapi/shared_impl/var.h b/ppapi/shared_impl/var.h
index 77f707c..50c13b9 100644
--- a/ppapi/shared_impl/var.h
+++ b/ppapi/shared_impl/var.h
@@ -9,12 +9,17 @@
 
 #include "base/compiler_specific.h"
 #include "base/memory/ref_counted.h"
+#include "base/platform_file.h"
+#include "base/shared_memory.h"
 #include "ppapi/c/pp_var.h"
+#include "ppapi/shared_impl/host_resource.h"
 #include "ppapi/shared_impl/ppapi_shared_export.h"
 
 namespace ppapi {
 
 class ArrayBufferVar;
+class ArrayVar;
+class DictionaryVar;
 class NPObjectVar;
 class ProxyObjectVar;
 class StringVar;
@@ -34,6 +39,8 @@
   virtual ArrayBufferVar* AsArrayBufferVar();
   virtual NPObjectVar* AsNPObjectVar();
   virtual ProxyObjectVar* AsProxyObjectVar();
+  virtual ArrayVar* AsArrayVar();
+  virtual DictionaryVar* AsDictionaryVar();
 
   // Creates a PP_Var corresponding to this object. The return value will have
   // one reference addrefed on behalf of the caller.
@@ -156,6 +163,18 @@
   virtual void Unmap() = 0;
   virtual uint32 ByteLength() = 0;
 
+  // Creates a new shared memory region, and copies the data in the
+  // ArrayBufferVar into it. On the plugin side, host_shm_handle_id will be set
+  // to some value that is not -1. On the host side, plugin_shm_handle will be
+  // set to a valid SharedMemoryHandle.
+  //
+  // Returns true if creating the shared memory (and copying) is successful,
+  // false otherwise.
+  virtual bool CopyToNewShmem(
+      PP_Instance instance,
+      int *host_shm_handle_id,
+      base::SharedMemoryHandle *plugin_shm_handle) = 0;
+
   // Var override.
   virtual ArrayBufferVar* AsArrayBufferVar() OVERRIDE;
   virtual PP_VarType GetType() const OVERRIDE;
diff --git a/ppapi/shared_impl/var_tracker.cc b/ppapi/shared_impl/var_tracker.cc
index 8214a30..434121e 100644
--- a/ppapi/shared_impl/var_tracker.cc
+++ b/ppapi/shared_impl/var_tracker.cc
@@ -9,7 +9,10 @@
 #include <limits>
 
 #include "base/logging.h"
+#include "base/shared_memory.h"
+#include "ppapi/shared_impl/host_resource.h"
 #include "ppapi/shared_impl/id_assignment.h"
+#include "ppapi/shared_impl/proxy_lock.h"
 #include "ppapi/shared_impl/var.h"
 
 namespace ppapi {
@@ -34,12 +37,14 @@
 
 int32 VarTracker::AddVar(Var* var) {
   DCHECK(CalledOnValidThread());
+  ProxyLock::AssertAcquired();
 
   return AddVarInternal(var, ADD_VAR_TAKE_ONE_REFERENCE);
 }
 
 Var* VarTracker::GetVar(int32 var_id) const {
   DCHECK(CalledOnValidThread());
+  ProxyLock::AssertAcquired();
 
   VarMap::const_iterator result = live_vars_.find(var_id);
   if (result == live_vars_.end())
@@ -49,6 +54,7 @@
 
 Var* VarTracker::GetVar(const PP_Var& var) const {
   DCHECK(CalledOnValidThread());
+  ProxyLock::AssertAcquired();
 
   if (!IsVarTypeRefcounted(var.type))
     return NULL;
@@ -57,6 +63,7 @@
 
 bool VarTracker::AddRefVar(int32 var_id) {
   DCHECK(CalledOnValidThread());
+  ProxyLock::AssertAcquired();
 
   DLOG_IF(ERROR, !CheckIdType(var_id, PP_ID_TYPE_VAR))
       << var_id << " is not a PP_Var ID.";
@@ -82,14 +89,16 @@
 
 bool VarTracker::AddRefVar(const PP_Var& var) {
   DCHECK(CalledOnValidThread());
+  ProxyLock::AssertAcquired();
 
   if (!IsVarTypeRefcounted(var.type))
-    return false;
+    return true;
   return AddRefVar(static_cast<int32>(var.value.as_id));
 }
 
 bool VarTracker::ReleaseVar(int32 var_id) {
   DCHECK(CalledOnValidThread());
+  ProxyLock::AssertAcquired();
 
   DLOG_IF(ERROR, !CheckIdType(var_id, PP_ID_TYPE_VAR))
       << var_id << " is not a PP_Var ID.";
@@ -121,6 +130,7 @@
 
 bool VarTracker::ReleaseVar(const PP_Var& var) {
   DCHECK(CalledOnValidThread());
+  ProxyLock::AssertAcquired();
 
   if (!IsVarTypeRefcounted(var.type))
     return false;
@@ -145,6 +155,7 @@
 
 int VarTracker::GetRefCountForObject(const PP_Var& plugin_object) {
   DCHECK(CalledOnValidThread());
+  ProxyLock::AssertAcquired();
 
   VarMap::iterator found = GetLiveVar(plugin_object);
   if (found == live_vars_.end())
@@ -155,6 +166,7 @@
 int VarTracker::GetTrackedWithNoReferenceCountForObject(
     const PP_Var& plugin_object) {
   DCHECK(CalledOnValidThread());
+  ProxyLock::AssertAcquired();
 
   VarMap::iterator found = GetLiveVar(plugin_object);
   if (found == live_vars_.end())
@@ -177,6 +189,7 @@
 
 PP_Var VarTracker::MakeArrayBufferPPVar(uint32 size_in_bytes) {
   DCHECK(CalledOnValidThread());
+  ProxyLock::AssertAcquired();
 
   scoped_refptr<ArrayBufferVar> array_buffer(CreateArrayBuffer(size_in_bytes));
   if (!array_buffer)
@@ -187,16 +200,38 @@
 PP_Var VarTracker::MakeArrayBufferPPVar(uint32 size_in_bytes,
                                         const void* data) {
   DCHECK(CalledOnValidThread());
+  ProxyLock::AssertAcquired();
 
-  scoped_refptr<ArrayBufferVar> array_buffer(CreateArrayBuffer(size_in_bytes));
+  ArrayBufferVar* array_buffer = MakeArrayBufferVar(size_in_bytes, data);
+  return array_buffer ? array_buffer->GetPPVar() : PP_MakeNull();
+}
+
+ArrayBufferVar* VarTracker::MakeArrayBufferVar(uint32 size_in_bytes,
+                                               const void* data) {
+  DCHECK(CalledOnValidThread());
+  ProxyLock::AssertAcquired();
+
+  ArrayBufferVar* array_buffer(CreateArrayBuffer(size_in_bytes));
+  if (!array_buffer)
+    return NULL;
+  memcpy(array_buffer->Map(), data, size_in_bytes);
+  return array_buffer;
+}
+
+PP_Var VarTracker::MakeArrayBufferPPVar(uint32 size_in_bytes,
+                                        base::SharedMemoryHandle handle) {
+  DCHECK(CalledOnValidThread());
+
+  scoped_refptr<ArrayBufferVar> array_buffer(
+      CreateShmArrayBuffer(size_in_bytes, handle));
   if (!array_buffer)
     return PP_MakeNull();
-  memcpy(array_buffer->Map(), data, size_in_bytes);
   return array_buffer->GetPPVar();
 }
 
 std::vector<PP_Var> VarTracker::GetLiveVars() {
   DCHECK(CalledOnValidThread());
+  ProxyLock::AssertAcquired();
 
   std::vector<PP_Var> var_vector;
   var_vector.reserve(live_vars_.size());
diff --git a/ppapi/shared_impl/var_tracker.h b/ppapi/shared_impl/var_tracker.h
index b873250..32acdeb 100644
--- a/ppapi/shared_impl/var_tracker.h
+++ b/ppapi/shared_impl/var_tracker.h
@@ -10,10 +10,13 @@
 #include "base/basictypes.h"
 #include "base/hash_tables.h"
 #include "base/memory/ref_counted.h"
+#include "base/shared_memory.h"
 #include "base/threading/non_thread_safe.h"
 #include "ppapi/c/pp_instance.h"
 #include "ppapi/c/pp_module.h"
+#include "ppapi/c/pp_resource.h"
 #include "ppapi/c/pp_var.h"
+#include "ppapi/shared_impl/host_resource.h"
 #include "ppapi/shared_impl/ppapi_shared_export.h"
 
 namespace ppapi {
@@ -72,6 +75,16 @@
   PP_Var MakeArrayBufferPPVar(uint32 size_in_bytes);
   // Same as above, but copy the contents of |data| in to the new array buffer.
   PP_Var MakeArrayBufferPPVar(uint32 size_in_bytes, const void* data);
+  // Same as above, but copy the contents of the shared memory in |h|
+  // into the new array buffer.
+  PP_Var MakeArrayBufferPPVar(uint32 size_in_bytes,
+                              base::SharedMemoryHandle h);
+
+  // Create an ArrayBuffer and copy the contents of |data| in to it. The
+  // returned object has 0 reference count in the tracker, and like all
+  // RefCounted objects, has a 0 initial internal reference count. (You should
+  // usually immediately put this in a scoped_refptr).
+  ArrayBufferVar* MakeArrayBufferVar(uint32 size_in_bytes, const void* data);
 
   // Return a vector containing all PP_Vars that are in the tracker. This is
   // to help implement PPB_Testing_Dev.GetLiveVars and should generally not be
@@ -88,6 +101,22 @@
   // Called after an instance is deleted to do var cleanup.
   virtual void DidDeleteInstance(PP_Instance instance) = 0;
 
+  // Returns an "id" for a shared memory handle that can be safely sent between
+  // the host and plugin, and resolved back into the original handle on the
+  // host. Not implemented on the plugin side.
+  virtual int TrackSharedMemoryHandle(PP_Instance instance,
+                                      base::SharedMemoryHandle handle,
+                                      uint32 size_in_bytes) = 0;
+
+  // Resolves an "id" generated by TrackSharedMemoryHandle back into
+  // a SharedMemory handle and its size on the host.
+  // Not implemented on the plugin side.
+  virtual bool StopTrackingSharedMemoryHandle(
+      int id,
+      PP_Instance instance,
+      base::SharedMemoryHandle *handle,
+      uint32* size_in_bytes) = 0;
+
  protected:
   struct VarInfo {
     VarInfo();
@@ -165,6 +194,9 @@
   // implemented by the Host and Plugin tracker separately, so that it can be
   // a real WebKit ArrayBuffer on the host side.
   virtual ArrayBufferVar* CreateArrayBuffer(uint32 size_in_bytes) = 0;
+  virtual ArrayBufferVar* CreateShmArrayBuffer(
+      uint32 size_in_bytes,
+      base::SharedMemoryHandle handle) = 0;
 
   DISALLOW_COPY_AND_ASSIGN(VarTracker);
 };
diff --git a/ppapi/shared_impl/var_value_conversions.cc b/ppapi/shared_impl/var_value_conversions.cc
new file mode 100644
index 0000000..614002a
--- /dev/null
+++ b/ppapi/shared_impl/var_value_conversions.cc
@@ -0,0 +1,344 @@
+// Copyright (c) 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 "ppapi/shared_impl/var_value_conversions.h"
+
+#include <limits>
+#include <set>
+#include <stack>
+
+#include "base/logging.h"
+#include "base/memory/ref_counted.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/stl_util.h"
+#include "base/values.h"
+#include "ppapi/c/pp_bool.h"
+#include "ppapi/c/pp_stdint.h"
+#include "ppapi/shared_impl/array_var.h"
+#include "ppapi/shared_impl/dictionary_var.h"
+#include "ppapi/shared_impl/ppapi_globals.h"
+#include "ppapi/shared_impl/scoped_pp_var.h"
+#include "ppapi/shared_impl/var.h"
+#include "ppapi/shared_impl/var_tracker.h"
+
+namespace ppapi {
+
+namespace {
+
+// In CreateValueFromVar(), a stack is used to keep track of conversion progress
+// of array and dictionary vars. VarNode represents elements of that stack.
+struct VarNode {
+  VarNode(const PP_Var& in_var, base::Value* in_value)
+      : var(in_var),
+        value(in_value),
+        sentinel(false) {
+  }
+
+  // This object doesn't hold a reference to it.
+  PP_Var var;
+  // It is not owned by this object.
+  base::Value* value;
+  // When this is set to true for a node in the stack, it means that we have
+  // finished processing the node itself. However, we keep it in the stack as
+  // a sentinel. When it becomes the top element of the stack again, we know
+  // that we have processed all the descendants of this node.
+  bool sentinel;
+};
+
+// In CreateVarFromValue(), a stack is used to keep track of conversion progress
+// of list and dictionary values. ValueNode represents elements of that stack.
+struct ValueNode {
+  ValueNode(const PP_Var& in_var, const base::Value* in_value)
+      : var(in_var),
+        value(in_value) {
+  }
+
+  // This object doesn't hold a reference to it.
+  PP_Var var;
+  // It is not owned by this object.
+  const base::Value* value;
+};
+
+// Helper function for CreateValueFromVar(). It only looks at |var| but not its
+// descendants. The conversion result is stored in |value|. If |var| is array or
+// dictionary, a new node is pushed onto |state|.
+//
+// Returns false on failure.
+bool CreateValueFromVarHelper(const std::set<int64_t>& parent_ids,
+                              const PP_Var& var,
+                              scoped_ptr<base::Value>* value,
+                              std::stack<VarNode>* state) {
+  switch (var.type) {
+    case PP_VARTYPE_UNDEFINED:
+    case PP_VARTYPE_NULL: {
+      value->reset(base::Value::CreateNullValue());
+      return true;
+    }
+    case PP_VARTYPE_BOOL: {
+      value->reset(new base::FundamentalValue(PP_ToBool(var.value.as_bool)));
+      return true;
+    }
+    case PP_VARTYPE_INT32: {
+      value->reset(new base::FundamentalValue(var.value.as_int));
+      return true;
+    }
+    case PP_VARTYPE_DOUBLE: {
+      value->reset(new base::FundamentalValue(var.value.as_double));
+      return true;
+    }
+    case PP_VARTYPE_STRING: {
+      StringVar* string_var = StringVar::FromPPVar(var);
+      if (!string_var)
+        return false;
+
+      value->reset(new base::StringValue(string_var->value()));
+      return true;
+    }
+    case PP_VARTYPE_OBJECT: {
+      return false;
+    }
+    case PP_VARTYPE_ARRAY: {
+      if (ContainsKey(parent_ids, var.value.as_id)) {
+        // A circular reference is found.
+        return false;
+      }
+
+      value->reset(new base::ListValue());
+      state->push(VarNode(var, value->get()));
+      return true;
+    }
+    case PP_VARTYPE_DICTIONARY: {
+      if (ContainsKey(parent_ids, var.value.as_id)) {
+        // A circular reference is found.
+        return false;
+      }
+
+      value->reset(new base::DictionaryValue());
+      state->push(VarNode(var, value->get()));
+      return true;
+    }
+    case PP_VARTYPE_ARRAY_BUFFER: {
+      ArrayBufferVar* array_buffer = ArrayBufferVar::FromPPVar(var);
+      if (!array_buffer)
+        return false;
+
+      base::BinaryValue* binary_value =
+          base::BinaryValue::CreateWithCopiedBuffer(
+              static_cast<const char*>(array_buffer->Map()),
+              array_buffer->ByteLength());
+      array_buffer->Unmap();
+      value->reset(binary_value);
+      return true;
+    }
+  }
+  NOTREACHED();
+  return false;
+}
+
+// Helper function for CreateVarFromValue(). It only looks at |value| but not
+// its descendants. The conversion result is stored in |var|. If |value| is list
+// or dictionary, a new node is pushed onto |state|.
+//
+// Returns false on failure.
+bool CreateVarFromValueHelper(const base::Value& value,
+                              ScopedPPVar* var,
+                              std::stack<ValueNode>* state) {
+  switch (value.GetType()) {
+    case base::Value::TYPE_NULL: {
+      *var = PP_MakeNull();
+      return true;
+    }
+    case base::Value::TYPE_BOOLEAN: {
+      bool result = false;
+      if (value.GetAsBoolean(&result)) {
+        *var = PP_MakeBool(PP_FromBool(result));
+        return true;
+      }
+      return false;
+    }
+    case base::Value::TYPE_INTEGER: {
+      int result = 0;
+      if (value.GetAsInteger(&result)) {
+        *var = PP_MakeInt32(result);
+        return true;
+      }
+      return false;
+    }
+    case base::Value::TYPE_DOUBLE: {
+      double result = 0;
+      if (value.GetAsDouble(&result)) {
+        *var = PP_MakeDouble(result);
+        return true;
+      }
+      return false;
+    }
+    case base::Value::TYPE_STRING: {
+      std::string result;
+      if (value.GetAsString(&result)) {
+        *var = ScopedPPVar(ScopedPPVar::PassRef(),
+                           StringVar::StringToPPVar(result));
+        return true;
+      }
+      return false;
+    }
+    case base::Value::TYPE_BINARY: {
+      const base::BinaryValue& binary_value =
+          static_cast<const base::BinaryValue&>(value);
+
+      size_t size = binary_value.GetSize();
+      if (size > std::numeric_limits<uint32>::max())
+        return false;
+
+      ScopedPPVar temp(
+          ScopedPPVar::PassRef(),
+          PpapiGlobals::Get()->GetVarTracker()->MakeArrayBufferPPVar(
+              static_cast<uint32>(size), binary_value.GetBuffer()));
+      if (temp.get().type == PP_VARTYPE_ARRAY_BUFFER) {
+        *var = temp;
+        return true;
+      }
+      return false;
+    }
+    case base::Value::TYPE_DICTIONARY: {
+      scoped_refptr<DictionaryVar> dict_var(new DictionaryVar());
+      *var = ScopedPPVar(ScopedPPVar::PassRef(), dict_var->GetPPVar());
+      state->push(ValueNode(var->get(), &value));
+      return true;
+    }
+    case base::Value::TYPE_LIST: {
+      scoped_refptr<ArrayVar> array_var(new ArrayVar());
+      *var = ScopedPPVar(ScopedPPVar::PassRef(), array_var->GetPPVar());
+      state->push(ValueNode(var->get(), &value));
+      return true;
+    }
+  }
+  NOTREACHED();
+  return false;
+}
+
+}  // namespace
+
+base::Value* CreateValueFromVar(const PP_Var& var) {
+  // Used to detect circular references.
+  std::set<int64_t> parent_ids;
+  std::stack<VarNode> state;
+  scoped_ptr<base::Value> root_value;
+
+  if (!CreateValueFromVarHelper(parent_ids, var, &root_value, &state))
+    return NULL;
+
+  while (!state.empty()) {
+    VarNode& top = state.top();
+    if (top.sentinel) {
+      parent_ids.erase(top.var.value.as_id);
+      state.pop();
+    } else if (top.var.type == PP_VARTYPE_DICTIONARY) {
+      parent_ids.insert(top.var.value.as_id);
+      top.sentinel = true;
+
+      DictionaryVar* dict_var = DictionaryVar::FromPPVar(top.var);
+      if (!dict_var)
+        return NULL;
+
+      DCHECK(top.value->GetType() == base::Value::TYPE_DICTIONARY);
+      base::DictionaryValue* dict_value =
+          static_cast<base::DictionaryValue*>(top.value);
+
+      for (DictionaryVar::KeyValueMap::const_iterator iter =
+               dict_var->key_value_map().begin();
+           iter != dict_var->key_value_map().end();
+           ++iter) {
+        // Skip the key-value pair if the value is undefined.
+        if (iter->second.get().type == PP_VARTYPE_UNDEFINED)
+          continue;
+
+        scoped_ptr<base::Value> child_value;
+        if (!CreateValueFromVarHelper(parent_ids, iter->second.get(),
+                                      &child_value, &state)) {
+          return NULL;
+        }
+
+        dict_value->SetWithoutPathExpansion(iter->first, child_value.release());
+      }
+    } else if (top.var.type == PP_VARTYPE_ARRAY) {
+      parent_ids.insert(top.var.value.as_id);
+      top.sentinel = true;
+
+      ArrayVar* array_var = ArrayVar::FromPPVar(top.var);
+      if (!array_var)
+        return NULL;
+
+      DCHECK(top.value->GetType() == base::Value::TYPE_LIST);
+      base::ListValue* list_value = static_cast<base::ListValue*>(top.value);
+
+      for (ArrayVar::ElementVector::const_iterator iter =
+               array_var->elements().begin();
+           iter != array_var->elements().end();
+           ++iter) {
+        scoped_ptr<base::Value> child_value;
+        if (!CreateValueFromVarHelper(parent_ids, iter->get(), &child_value,
+                                      &state)) {
+          return NULL;
+        }
+
+        list_value->Append(child_value.release());
+      }
+    } else {
+      NOTREACHED();
+      return NULL;
+    }
+  }
+  DCHECK(parent_ids.empty());
+  return root_value.release();
+}
+
+PP_Var CreateVarFromValue(const base::Value& value) {
+  std::stack<ValueNode> state;
+  ScopedPPVar root_var;
+
+  if (!CreateVarFromValueHelper(value, &root_var, &state))
+    return PP_MakeUndefined();
+
+  while (!state.empty()) {
+    ValueNode top = state.top();
+    state.pop();
+
+    if (top.value->GetType() == base::Value::TYPE_DICTIONARY) {
+      const base::DictionaryValue* dict_value =
+          static_cast<const base::DictionaryValue*>(top.value);
+      DictionaryVar* dict_var = DictionaryVar::FromPPVar(top.var);
+      DCHECK(dict_var);
+      for (base::DictionaryValue::Iterator iter(*dict_value);
+           !iter.IsAtEnd();
+           iter.Advance()) {
+        ScopedPPVar child_var;
+        if (!CreateVarFromValueHelper(iter.value(), &child_var, &state) ||
+            !dict_var->SetWithStringKey(iter.key(), child_var.get())) {
+          return PP_MakeUndefined();
+        }
+      }
+    } else if (top.value->GetType() == base::Value::TYPE_LIST) {
+      const base::ListValue* list_value =
+          static_cast<const base::ListValue*>(top.value);
+      ArrayVar* array_var = ArrayVar::FromPPVar(top.var);
+      DCHECK(array_var);
+      for (base::ListValue::const_iterator iter = list_value->begin();
+           iter != list_value->end();
+           ++iter) {
+        ScopedPPVar child_var;
+        if (!CreateVarFromValueHelper(**iter, &child_var, &state))
+          return PP_MakeUndefined();
+
+        array_var->elements().push_back(child_var);
+      }
+    } else {
+      NOTREACHED();
+      return PP_MakeUndefined();
+    }
+  }
+
+  return root_var.Release();
+}
+}  // namespace ppapi
+
diff --git a/ppapi/shared_impl/var_value_conversions.h b/ppapi/shared_impl/var_value_conversions.h
new file mode 100644
index 0000000..09145ce
--- /dev/null
+++ b/ppapi/shared_impl/var_value_conversions.h
@@ -0,0 +1,41 @@
+// Copyright (c) 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 PPAPI_SHARED_IMPL_VAR_VALUE_CONVERSIONS_H_
+#define PPAPI_SHARED_IMPL_VAR_VALUE_CONVERSIONS_H_
+
+#include "ppapi/c/pp_var.h"
+#include "ppapi/shared_impl/ppapi_shared_export.h"
+
+namespace base {
+class Value;
+}
+
+namespace ppapi {
+
+// Converts a PP_Var to a base::Value object. The caller takes ownership of the
+// returned object.
+//
+// Both PP_VARTYPE_UNDEFINED and PP_VARTYPE_NULL are converted to
+// base::Value::TYPE_NULL. In dictionary vars, key-value pairs whose value is
+// undefined (PP_VARTYPE_UNDEFINED) are ignored. If a node in |var| appears more
+// than once, it is duplicated in the result. For example, if |var| is an array
+// and it has two elements pointing to the same dictionary, the resulting list
+// value will have two copies of the dictionary.
+//
+// The conversion fails and returns NULL if
+// - |var| is object (PP_VARTYPE_OBJECT); or
+// - |var| is an array or dictionary, and calling CreateValueFromVar() on any of
+//   the array elements or dictionary values fails; or
+// - there exist circular references, i.e., an array or dictionary is its own
+//   ancestor/descendant.
+PPAPI_SHARED_EXPORT base::Value* CreateValueFromVar(const PP_Var& var);
+
+// The returned var has been added ref on behalf of the caller.
+// Returns an undefined var if the conversion fails.
+PPAPI_SHARED_EXPORT PP_Var CreateVarFromValue(const base::Value& value);
+
+}  // namespace ppapi
+
+#endif  // PPAPI_SHARED_IMPL_VAR_VALUE_CONVERSIONS_H_
diff --git a/ppapi/shared_impl/var_value_conversions_unittest.cc b/ppapi/shared_impl/var_value_conversions_unittest.cc
new file mode 100644
index 0000000..8dd2c42
--- /dev/null
+++ b/ppapi/shared_impl/var_value_conversions_unittest.cc
@@ -0,0 +1,316 @@
+// Copyright (c) 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 "ppapi/shared_impl/var_value_conversions.h"
+
+#include <cmath>
+#include <cstring>
+
+#include "base/logging.h"
+#include "base/memory/ref_counted.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/values.h"
+#include "ppapi/c/pp_bool.h"
+#include "ppapi/c/pp_var.h"
+#include "ppapi/shared_impl/array_var.h"
+#include "ppapi/shared_impl/dictionary_var.h"
+#include "ppapi/shared_impl/ppapi_globals.h"
+#include "ppapi/shared_impl/proxy_lock.h"
+#include "ppapi/shared_impl/scoped_pp_var.h"
+#include "ppapi/shared_impl/test_globals.h"
+#include "ppapi/shared_impl/var.h"
+#include "ppapi/shared_impl/var_tracker.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace ppapi {
+namespace {
+
+bool Equals(const base::Value& value, const PP_Var& var) {
+  switch (value.GetType()) {
+    case base::Value::TYPE_NULL: {
+      return var.type == PP_VARTYPE_NULL || var.type == PP_VARTYPE_UNDEFINED;
+    }
+    case base::Value::TYPE_BOOLEAN: {
+      bool result = false;
+      return var.type == PP_VARTYPE_BOOL &&
+             value.GetAsBoolean(&result) &&
+             result == PP_ToBool(var.value.as_bool);
+    }
+    case base::Value::TYPE_INTEGER: {
+      int result = 0;
+      return var.type == PP_VARTYPE_INT32 &&
+             value.GetAsInteger(&result) &&
+             result == var.value.as_int;
+    }
+    case base::Value::TYPE_DOUBLE: {
+      double result = 0;
+      return var.type == PP_VARTYPE_DOUBLE &&
+             value.GetAsDouble(&result) &&
+             fabs(result - var.value.as_double) < 1.0e-4;
+    }
+    case base::Value::TYPE_STRING: {
+      std::string result;
+      StringVar* string_var = StringVar::FromPPVar(var);
+      return string_var &&
+             value.GetAsString(&result) &&
+             result == string_var->value();
+    }
+    case base::Value::TYPE_BINARY: {
+      const base::BinaryValue& binary_value =
+          static_cast<const base::BinaryValue&>(value);
+      ArrayBufferVar* array_buffer_var = ArrayBufferVar::FromPPVar(var);
+      if (!array_buffer_var ||
+          binary_value.GetSize() != array_buffer_var->ByteLength()) {
+        return false;
+      }
+
+      bool result = !memcmp(binary_value.GetBuffer(), array_buffer_var->Map(),
+                            binary_value.GetSize());
+      array_buffer_var->Unmap();
+      return result;
+    }
+    case base::Value::TYPE_DICTIONARY: {
+      const base::DictionaryValue& dict_value =
+          static_cast<const base::DictionaryValue&>(value);
+      DictionaryVar* dict_var = DictionaryVar::FromPPVar(var);
+      if (!dict_var)
+        return false;
+
+      size_t non_undefined_count = 0;
+      for (DictionaryVar::KeyValueMap::const_iterator iter =
+               dict_var->key_value_map().begin();
+           iter != dict_var->key_value_map().end();
+           ++iter) {
+        if (iter->second.get().type == PP_VARTYPE_UNDEFINED)
+          continue;
+
+        ++non_undefined_count;
+        const base::Value* sub_value = NULL;
+        if (!dict_value.GetWithoutPathExpansion(iter->first, &sub_value) ||
+            !Equals(*sub_value, iter->second.get())) {
+          return false;
+        }
+      }
+      return non_undefined_count == dict_value.size();
+    }
+    case base::Value::TYPE_LIST: {
+      const base::ListValue& list_value =
+          static_cast<const base::ListValue&>(value);
+      ArrayVar* array_var = ArrayVar::FromPPVar(var);
+      if (!array_var || list_value.GetSize() != array_var->elements().size())
+        return false;
+
+      base::ListValue::const_iterator value_iter = list_value.begin();
+      ArrayVar::ElementVector::const_iterator var_iter =
+          array_var->elements().begin();
+      for (; value_iter != list_value.end() &&
+                 var_iter != array_var->elements().end();
+           ++value_iter, ++var_iter) {
+        if (!Equals(**value_iter, var_iter->get()))
+          return false;
+      }
+      return true;
+    }
+  }
+  NOTREACHED();
+  return false;
+}
+
+class VarValueConversionsTest : public testing::Test {
+ public:
+  VarValueConversionsTest() {
+  }
+  virtual ~VarValueConversionsTest() {
+  }
+
+  // testing::Test implementation.
+  virtual void SetUp() {
+    ProxyLock::Acquire();
+  }
+  virtual void TearDown() {
+    ASSERT_TRUE(PpapiGlobals::Get()->GetVarTracker()->GetLiveVars().empty());
+    ProxyLock::Release();
+  }
+
+ private:
+  TestGlobals globals_;
+};
+
+}  // namespace
+
+TEST_F(VarValueConversionsTest, CreateValueFromVar) {
+  {
+    // Var holding a ref to itself is not a valid input.
+    scoped_refptr<DictionaryVar> dict_var(new DictionaryVar());
+    ScopedPPVar var_1(ScopedPPVar::PassRef(), dict_var->GetPPVar());
+    scoped_refptr<ArrayVar> array_var(new ArrayVar());
+    ScopedPPVar var_2(ScopedPPVar::PassRef(), array_var->GetPPVar());
+
+    ASSERT_TRUE(dict_var->SetWithStringKey("key_1", var_2.get()));
+    scoped_ptr<base::Value> value(CreateValueFromVar(var_1.get()));
+    ASSERT_TRUE(value.get());
+
+    ASSERT_TRUE(array_var->Set(0, var_1.get()));
+    value.reset(CreateValueFromVar(var_1.get()));
+    ASSERT_EQ(NULL, value.get());
+
+    // Make sure |var_1| doesn't indirectly hold a ref to itself, otherwise it
+    // is leaked.
+    dict_var->DeleteWithStringKey("key_1");
+  }
+
+  // Vars of null or undefined type are converted to null values.
+  {
+    scoped_ptr<base::Value> value(CreateValueFromVar(PP_MakeNull()));
+    ASSERT_TRUE(value.get());
+    ASSERT_TRUE(Equals(*value, PP_MakeNull()));
+
+    value.reset(CreateValueFromVar(PP_MakeUndefined()));
+    ASSERT_TRUE(value.get());
+    ASSERT_TRUE(Equals(*value, PP_MakeUndefined()));
+  }
+
+  {
+    // Test empty dictionary.
+    scoped_refptr<DictionaryVar> dict_var(new DictionaryVar());
+    ScopedPPVar var(ScopedPPVar::PassRef(), dict_var->GetPPVar());
+
+    scoped_ptr<base::Value> value(CreateValueFromVar(var.get()));
+    ASSERT_TRUE(value.get());
+    ASSERT_TRUE(Equals(*value, var.get()));
+  }
+
+  {
+    // Key-value pairs whose value is undefined are ignored.
+    scoped_refptr<DictionaryVar> dict_var(new DictionaryVar());
+    ASSERT_TRUE(dict_var->SetWithStringKey("key_1", PP_MakeUndefined()));
+    ASSERT_TRUE(dict_var->SetWithStringKey("key_2", PP_MakeInt32(1)));
+    ScopedPPVar var(ScopedPPVar::PassRef(), dict_var->GetPPVar());
+
+    scoped_ptr<base::Value> value(CreateValueFromVar(var.get()));
+    ASSERT_TRUE(value.get());
+    ASSERT_TRUE(Equals(*value, var.get()));
+  }
+
+  {
+    // The same PP_Var is allowed to appear multiple times.
+    scoped_refptr<DictionaryVar> dict_var_1(new DictionaryVar());
+    ScopedPPVar dict_pp_var_1(ScopedPPVar::PassRef(), dict_var_1->GetPPVar());
+    scoped_refptr<DictionaryVar> dict_var_2(new DictionaryVar());
+    ScopedPPVar dict_pp_var_2(ScopedPPVar::PassRef(), dict_var_2->GetPPVar());
+    scoped_refptr<StringVar> string_var(new StringVar("string_value"));
+    ScopedPPVar string_pp_var(ScopedPPVar::PassRef(), string_var->GetPPVar());
+
+    ASSERT_TRUE(dict_var_1->SetWithStringKey("key_1", dict_pp_var_2.get()));
+    ASSERT_TRUE(dict_var_1->SetWithStringKey("key_2", dict_pp_var_2.get()));
+    ASSERT_TRUE(dict_var_1->SetWithStringKey("key_3", string_pp_var.get()));
+    ASSERT_TRUE(dict_var_2->SetWithStringKey("key_4", string_pp_var.get()));
+
+    scoped_ptr<base::Value> value(CreateValueFromVar(dict_pp_var_1.get()));
+    ASSERT_TRUE(value.get());
+    ASSERT_TRUE(Equals(*value, dict_pp_var_1.get()));
+  }
+
+  {
+    // Test basic cases for array.
+    scoped_refptr<ArrayVar> array_var(new ArrayVar());
+    ScopedPPVar var(ScopedPPVar::PassRef(), array_var->GetPPVar());
+
+    scoped_ptr<base::Value> value(CreateValueFromVar(var.get()));
+    ASSERT_TRUE(value.get());
+    ASSERT_TRUE(Equals(*value, var.get()));
+
+    ASSERT_TRUE(array_var->Set(0, PP_MakeDouble(1)));
+    value.reset(CreateValueFromVar(var.get()));
+    ASSERT_TRUE(value.get());
+    ASSERT_TRUE(Equals(*value, var.get()));
+  }
+
+  {
+    // Test more complex inputs.
+    scoped_refptr<DictionaryVar> dict_var_1(new DictionaryVar());
+    ScopedPPVar dict_pp_var_1(ScopedPPVar::PassRef(), dict_var_1->GetPPVar());
+    scoped_refptr<DictionaryVar> dict_var_2(new DictionaryVar());
+    ScopedPPVar dict_pp_var_2(ScopedPPVar::PassRef(), dict_var_2->GetPPVar());
+    scoped_refptr<ArrayVar> array_var(new ArrayVar());
+    ScopedPPVar array_pp_var(ScopedPPVar::PassRef(), array_var->GetPPVar());
+    scoped_refptr<StringVar> string_var(new StringVar("string_value"));
+    ScopedPPVar string_pp_var(ScopedPPVar::PassRef(), string_var->GetPPVar());
+
+    ASSERT_TRUE(dict_var_1->SetWithStringKey("null_key", PP_MakeNull()));
+    ASSERT_TRUE(dict_var_1->SetWithStringKey("string_key",
+                                             string_pp_var.get()));
+    ASSERT_TRUE(dict_var_1->SetWithStringKey("dict_key", dict_pp_var_2.get()));
+
+    ASSERT_TRUE(dict_var_2->SetWithStringKey("undefined_key",
+                                             PP_MakeUndefined()));
+    ASSERT_TRUE(dict_var_2->SetWithStringKey("double_key", PP_MakeDouble(1)));
+    ASSERT_TRUE(dict_var_2->SetWithStringKey("array_key", array_pp_var.get()));
+
+    ASSERT_TRUE(array_var->Set(0, PP_MakeInt32(2)));
+    ASSERT_TRUE(array_var->Set(1, PP_MakeBool(PP_TRUE)));
+    ASSERT_TRUE(array_var->SetLength(4));
+
+    scoped_ptr<base::Value> value(CreateValueFromVar(dict_pp_var_1.get()));
+    ASSERT_TRUE(value.get());
+    ASSERT_TRUE(Equals(*value, dict_pp_var_1.get()));
+  }
+
+  {
+    // Test that dictionary keys containing '.' are handled correctly.
+    scoped_refptr<DictionaryVar> dict_var(new DictionaryVar());
+    ScopedPPVar dict_pp_var(ScopedPPVar::PassRef(), dict_var->GetPPVar());
+
+    ASSERT_TRUE(dict_var->SetWithStringKey("double.key", PP_MakeDouble(1)));
+    ASSERT_TRUE(dict_var->SetWithStringKey("int.key..name", PP_MakeInt32(2)));
+
+    scoped_ptr<base::Value> value(CreateValueFromVar(dict_pp_var.get()));
+    ASSERT_TRUE(value.get());
+    ASSERT_TRUE(Equals(*value, dict_pp_var.get()));
+  }
+}
+
+TEST_F(VarValueConversionsTest, CreateVarFromValue) {
+  {
+    // Test basic cases for dictionary.
+    base::DictionaryValue dict_value;
+    ScopedPPVar var(ScopedPPVar::PassRef(), CreateVarFromValue(dict_value));
+    ASSERT_TRUE(Equals(dict_value, var.get()));
+
+    dict_value.SetInteger("int_key", 1);
+    var = ScopedPPVar(ScopedPPVar::PassRef(), CreateVarFromValue(dict_value));
+    ASSERT_TRUE(Equals(dict_value, var.get()));
+  }
+
+  {
+    // Test basic cases for array.
+    base::ListValue list_value;
+    ScopedPPVar var(ScopedPPVar::PassRef(), CreateVarFromValue(list_value));
+    ASSERT_TRUE(Equals(list_value, var.get()));
+
+    list_value.AppendInteger(1);
+    var = ScopedPPVar(ScopedPPVar::PassRef(), CreateVarFromValue(list_value));
+    ASSERT_TRUE(Equals(list_value, var.get()));
+  }
+
+  {
+    // Test more complex inputs.
+    base::DictionaryValue dict_value;
+    dict_value.Set("null_key", base::Value::CreateNullValue());
+    dict_value.SetString("string_key", "string_value");
+    dict_value.SetDouble("dict_key.double_key", 1);
+
+    scoped_ptr<base::ListValue> list_value(new base::ListValue());
+    list_value->AppendInteger(2);
+    list_value->AppendBoolean(true);
+    list_value->Append(base::Value::CreateNullValue());
+
+    dict_value.Set("dict_key.array_key", list_value.release());
+
+    ScopedPPVar var(ScopedPPVar::PassRef(), CreateVarFromValue(dict_value));
+    ASSERT_TRUE(Equals(dict_value, var.get()));
+  }
+}
+
+}  // namespace ppapi