libweave: Remove release() calls on scoped_ptr

Now that scoped_ptr is just a type alias to std::unique_ptr, there
is no need to do release()/aquire semantics to convert between
scoped_ptr and unique_ptr. Also, replaced base::Value::DeepCopy with
the safer smart-pointer-enabled base::Value::CreateDeepCopy.

Change-Id: I6b7ed78b3fae6d42a68b7d73ae4d9d5eebf48922
Reviewed-on: https://weave-review.googlesource.com/3067
Reviewed-by: Robert Ginda <rginda@google.com>
diff --git a/examples/daemon/light/light.cc b/examples/daemon/light/light.cc
index 07c0231..66167b4 100644
--- a/examples/daemon/light/light.cc
+++ b/examples/daemon/light/light.cc
@@ -288,7 +288,7 @@
     std::unique_ptr<base::DictionaryValue> colorXy(new base::DictionaryValue());
     colorXy->SetDouble("colorX", color_X_);
     colorXy->SetDouble("colorY", color_Y_);
-    state.Set("colorXy.colorSetting", colorXy.release());
+    state.Set("colorXy.colorSetting", std::move(colorXy));
     device_->SetStateProperties(kComponent, state, nullptr);
   }
 
diff --git a/examples/daemon/oven/oven.cc b/examples/daemon/oven/oven.cc
index daf1971..f92c838 100644
--- a/examples/daemon/oven/oven.cc
+++ b/examples/daemon/oven/oven.cc
@@ -227,11 +227,13 @@
 
     state.SetString("temperatureSensor.units", units_);
     state.SetDouble("temperatureSensor.value", current_temperature_);
-    state.Set("temperatureSensor.supportedUnits", supportedUnits.DeepCopy());
+    state.Set("temperatureSensor.supportedUnits",
+              supportedUnits.CreateDeepCopy());
 
     state.SetString("temperatureSetting.units", units_);
     state.SetDouble("temperatureSetting.tempSetting", target_temperature_);
-    state.Set("temperatureSetting.supportedUnits", supportedUnits.DeepCopy());
+    state.Set("temperatureSetting.supportedUnits",
+              supportedUnits.CreateDeepCopy());
     state.SetDouble("temperatureSetting.maxTempSetting", kMaxTemp);
     state.SetDouble("temperatureSetting.minTempSetting", kMinTemp);
 
diff --git a/src/access_api_handler.cc b/src/access_api_handler.cc
index ce92437..5e0882e 100644
--- a/src/access_api_handler.cc
+++ b/src/access_api_handler.cc
@@ -176,11 +176,11 @@
     std::unique_ptr<base::DictionaryValue> entry{new base::DictionaryValue};
     entry->SetString(kUserId, Base64Encode(e.user_id));
     entry->SetString(kApplicationId, Base64Encode(e.app_id));
-    entries->Append(entry.release());
+    entries->Append(std::move(entry));
   }
 
   base::DictionaryValue result;
-  result.Set(kRevocationList, entries.release());
+  result.Set(kRevocationList, std::move(entries));
 
   command->Complete(result, nullptr);
 }
diff --git a/src/access_api_handler_unittest.cc b/src/access_api_handler_unittest.cc
index b58facd..f53a6d1 100644
--- a/src/access_api_handler_unittest.cc
+++ b/src/access_api_handler_unittest.cc
@@ -78,7 +78,7 @@
     const base::DictionaryValue* state = nullptr;
     EXPECT_TRUE(
         component->GetDictionary("state._accessRevocationList", &state));
-    return std::unique_ptr<base::DictionaryValue>{state->DeepCopy()};
+    return state->CreateDeepCopy();
   }
 
   StrictMock<provider::test::FakeTaskRunner> task_runner_;
diff --git a/src/base_api_handler_unittest.cc b/src/base_api_handler_unittest.cc
index 2a202d1..12fb3b6 100644
--- a/src/base_api_handler_unittest.cc
+++ b/src/base_api_handler_unittest.cc
@@ -84,7 +84,7 @@
     CHECK(component);
     const base::DictionaryValue* base_state = nullptr;
     if (component->GetDictionary("state.base", &base_state))
-      state.reset(base_state->DeepCopy());
+      state = base_state->CreateDeepCopy();
     else
       state.reset(new base::DictionaryValue);
     return state;
diff --git a/src/commands/cloud_command_proxy.cc b/src/commands/cloud_command_proxy.cc
index f8f8d1f..c12e833 100644
--- a/src/commands/cloud_command_proxy.cc
+++ b/src/commands/cloud_command_proxy.cc
@@ -35,8 +35,8 @@
   std::unique_ptr<base::DictionaryValue> patch{new base::DictionaryValue};
   patch->Set(commands::attributes::kCommand_Error,
              command_instance_->GetError()
-                 ? ErrorInfoToJson(*command_instance_->GetError()).release()
-                 : base::Value::CreateNullValue().release());
+                 ? ErrorInfoToJson(*command_instance_->GetError())
+                 : base::Value::CreateNullValue());
   QueueCommandUpdate(std::move(patch));
 }
 
diff --git a/src/commands/command_instance.cc b/src/commands/command_instance.cc
index dfc3fbd..1e7e16f 100644
--- a/src/commands/command_instance.cc
+++ b/src/commands/command_instance.cc
@@ -156,7 +156,7 @@
                                 "Property '%s' must be a JSON object",
                                 commands::attributes::kCommand_Parameters);
     }
-    params.reset(params_dict->DeepCopy());
+    params = params_dict->CreateDeepCopy();
   } else {
     // "parameters" are not specified. Assume empty param list.
     params.reset(new base::DictionaryValue);
@@ -221,14 +221,14 @@
   json->SetString(commands::attributes::kCommand_Id, id_);
   json->SetString(commands::attributes::kCommand_Name, name_);
   json->SetString(commands::attributes::kCommand_Component, component_);
-  json->Set(commands::attributes::kCommand_Parameters, parameters_.DeepCopy());
-  json->Set(commands::attributes::kCommand_Progress, progress_.DeepCopy());
-  json->Set(commands::attributes::kCommand_Results, results_.DeepCopy());
+  json->Set(commands::attributes::kCommand_Parameters,
+            parameters_.CreateDeepCopy());
+  json->Set(commands::attributes::kCommand_Progress,
+            progress_.CreateDeepCopy());
+  json->Set(commands::attributes::kCommand_Results, results_.CreateDeepCopy());
   json->SetString(commands::attributes::kCommand_State, EnumToString(state_));
-  if (error_) {
-    json->Set(commands::attributes::kCommand_Error,
-              ErrorInfoToJson(*error_).release());
-  }
+  if (error_)
+    json->Set(commands::attributes::kCommand_Error, ErrorInfoToJson(*error_));
 
   return json;
 }
diff --git a/src/component_manager_impl.cc b/src/component_manager_impl.cc
index 0ac6e4d..805e57a 100644
--- a/src/component_manager_impl.cc
+++ b/src/component_manager_impl.cc
@@ -120,8 +120,8 @@
   std::unique_ptr<base::DictionaryValue> dict{new base::DictionaryValue};
   std::unique_ptr<base::ListValue> traits_list{new base::ListValue};
   traits_list->AppendStrings(traits);
-  dict->Set("traits", traits_list.release());
-  root->SetWithoutPathExpansion(name, dict.release());
+  dict->Set("traits", std::move(traits_list));
+  root->SetWithoutPathExpansion(name, std::move(dict));
   for (const auto& cb : on_componet_tree_changed_)
     cb.Run();
   return true;
@@ -146,8 +146,8 @@
   std::unique_ptr<base::DictionaryValue> dict{new base::DictionaryValue};
   std::unique_ptr<base::ListValue> traits_list{new base::ListValue};
   traits_list->AppendStrings(traits);
-  dict->Set("traits", traits_list.release());
-  array_value->Append(dict.release());
+  dict->Set("traits", std::move(traits_list));
+  array_value->Append(std::move(dict));
   for (const auto& cb : on_componet_tree_changed_)
     cb.Run();
   return true;
@@ -233,7 +233,7 @@
         break;
       }
     } else {
-      traits_.Set(it.key(), it.value().DeepCopy());
+      traits_.Set(it.key(), it.value().CreateDeepCopy());
       modified = true;
     }
   }
@@ -458,7 +458,7 @@
 
 std::unique_ptr<base::DictionaryValue>
 ComponentManagerImpl::GetComponentsForUserRole(UserRole role) const {
-  std::unique_ptr<base::DictionaryValue> components{components_.DeepCopy()};
+  auto components = components_.CreateDeepCopy();
   // Build a list of all state properties that are inaccessible to the given
   // user. These properties will be removed from the components collection
   // returned from this method.
@@ -550,7 +550,7 @@
         error, FROM_HERE, errors::commands::kPropertyMissing,
         "State property name not specified in '%s'", name.c_str());
   }
-  dict.Set(name, value.DeepCopy());
+  dict.Set(name, value.CreateDeepCopy());
   return SetStateProperties(component_path, dict, error);
 }
 
@@ -587,7 +587,7 @@
     const base::Callback<void(UpdateID)>& callback) {
   if (state_change_queues_.empty())
     callback.Run(GetLastStateChangeId());
-  return Token{on_server_state_updated_.Add(callback).release()};
+  return Token{on_server_state_updated_.Add(callback)};
 }
 
 std::string ComponentManagerImpl::FindComponentWithTrait(
diff --git a/src/device_registration_info.cc b/src/device_registration_info.cc
index b399d1f..a278e63 100644
--- a/src/device_registration_info.cc
+++ b/src/device_registration_info.cc
@@ -212,17 +212,13 @@
                        error_message.c_str(), json.c_str());
     return std::unique_ptr<base::DictionaryValue>();
   }
-  base::DictionaryValue* dict_value = nullptr;
-  if (!value->GetAsDictionary(&dict_value)) {
+  auto dict_value = base::DictionaryValue::From(std::move(value));
+  if (!dict_value) {
     Error::AddToPrintf(error, FROM_HERE, errors::json::kObjectExpected,
                        "Response is not a valid JSON object: '%s'",
                        json.c_str());
-    return std::unique_ptr<base::DictionaryValue>();
-  } else {
-    // |value| is now owned by |dict_value|, so release the scoped_ptr now.
-    base::IgnoreResult(value.release());
   }
-  return std::unique_ptr<base::DictionaryValue>(dict_value);
+  return dict_value;
 }
 
 bool IsSuccessful(const HttpClient::Response& response) {
@@ -500,9 +496,10 @@
   } else {
     channel->SetString("supportedType", "pull");
   }
-  resource->Set("channel", channel.release());
-  resource->Set("traits", component_manager_->GetTraits().DeepCopy());
-  resource->Set("components", component_manager_->GetComponents().DeepCopy());
+  resource->Set("channel", std::move(channel));
+  resource->Set("traits", component_manager_->GetTraits().CreateDeepCopy());
+  resource->Set("components",
+                component_manager_->GetComponents().CreateDeepCopy());
 
   return resource;
 }
@@ -575,7 +572,7 @@
   base::DictionaryValue req_json;
   req_json.SetString("id", registration_data.ticket_id);
   req_json.SetString("oauthClientId", registration_data.client_id);
-  req_json.Set("deviceDraft", device_draft.release());
+  req_json.Set("deviceDraft", std::move(device_draft));
 
   auto url = BuildUrl(registration_data.service_url,
                       "registrationTickets/" + registration_data.ticket_id,
@@ -904,7 +901,7 @@
                           EnumToString(Command::State::kAborted));
   if (error) {
     command_patch.Set(commands::attributes::kCommand_Error,
-                      ErrorInfoToJson(*error).release());
+                      ErrorInfoToJson(*error));
   }
   UpdateCommand(command_id, command_patch, base::Bind(&IgnoreCloudError));
 }
@@ -976,7 +973,7 @@
   auth->SetString("clientToken", token_base64);
   auth->SetString("certFingerprint", fingerprint);
   std::unique_ptr<base::DictionaryValue> root{new base::DictionaryValue};
-  root->Set("localAuthInfo", auth.release());
+  root->Set("localAuthInfo", std::move(auth));
 
   std::string url = GetDeviceUrl("upsertLocalAuthInfo", {});
   DoCloudRequest(HttpClient::Method::kPost, url, root.get(),
@@ -1141,7 +1138,7 @@
         continue;
       }
 
-      std::unique_ptr<base::DictionaryValue> cmd_copy{command_dict->DeepCopy()};
+      auto cmd_copy = command_dict->CreateDeepCopy();
       cmd_copy->SetString("state", "aborted");
       // TODO(wiley) We could consider handling this error case more gracefully.
       DoCloudRequest(HttpClient::Method::kPut,
@@ -1213,14 +1210,14 @@
     patch->SetString("timeMs",
                      std::to_string(state_change.timestamp.ToJavaTime()));
     patch->SetString("component", state_change.component);
-    patch->Set("patch", state_change.changed_properties.release());
-    patches->Append(patch.release());
+    patch->Set("patch", std::move(state_change.changed_properties));
+    patches->Append(std::move(patch));
   }
 
   base::DictionaryValue body;
   body.SetString("requestTimeMs",
                  std::to_string(base::Time::Now().ToJavaTime()));
-  body.Set("patches", patches.release());
+  body.Set("patches", std::move(patches));
 
   device_state_update_pending_ = true;
   DoCloudRequest(HttpClient::Method::kPost, GetDeviceUrl("patchState"), &body,
diff --git a/src/privet/cloud_delegate.cc b/src/privet/cloud_delegate.cc
index d7e9bef..f9d53c3 100644
--- a/src/privet/cloud_delegate.cc
+++ b/src/privet/cloud_delegate.cc
@@ -220,14 +220,12 @@
     base::ListValue list_value;
 
     for (const auto& it : command_owners_) {
-      if (CanAccessCommand(it.second, user_info, nullptr)) {
-        list_value.Append(
-            component_manager_->FindCommand(it.first)->ToJson().release());
-      }
+      if (CanAccessCommand(it.second, user_info, nullptr))
+        list_value.Append(component_manager_->FindCommand(it.first)->ToJson());
     }
 
     base::DictionaryValue commands_json;
-    commands_json.Set("commands", list_value.DeepCopy());
+    commands_json.Set("commands", list_value.CreateDeepCopy());
 
     callback.Run(commands_json, nullptr);
   }
diff --git a/src/privet/mock_delegates.h b/src/privet/mock_delegates.h
index 3742494..5338e1b 100644
--- a/src/privet/mock_delegates.h
+++ b/src/privet/mock_delegates.h
@@ -263,8 +263,7 @@
  private:
   std::unique_ptr<base::DictionaryValue> GetComponentsForUser(
       const UserInfo& user_info) const override {
-    return std::unique_ptr<base::DictionaryValue>{
-        MockGetComponentsForUser(user_info).DeepCopy()};
+    return MockGetComponentsForUser(user_info).CreateDeepCopy();
   }
 };
 
diff --git a/src/privet/privet_handler.cc b/src/privet/privet_handler.cc
index 41936b6..42a1c23 100644
--- a/src/privet/privet_handler.cc
+++ b/src/privet/privet_handler.cc
@@ -177,9 +177,9 @@
                                        it->GetLocation().file_name.c_str(),
                                        it->GetLocation().line_number, nullptr};
     inner->SetString(kErrorDebugInfoKey, location.ToString());
-    errors->Append(inner.release());
+    errors->Append(std::move(inner));
   }
-  output->Set(kErrorDebugInfoKey, errors.release());
+  output->Set(kErrorDebugInfoKey, std::move(errors));
   return output;
 }
 
@@ -190,7 +190,7 @@
     return;
   }
   parent->SetString(kStatusKey, kStatusErrorValue);
-  parent->Set(kErrorKey, ErrorToJson(*state.error()).release());
+  parent->Set(kErrorKey, ErrorToJson(*state.error()));
 }
 
 void ReturnError(const Error& error,
@@ -203,7 +203,7 @@
     }
   }
   std::unique_ptr<base::DictionaryValue> output{new base::DictionaryValue};
-  output->Set(kErrorKey, ErrorToJson(error).release());
+  output->Set(kErrorKey, ErrorToJson(error));
   callback.Run(code, *output);
 }
 
@@ -260,17 +260,17 @@
   std::unique_ptr<base::ListValue> pairing_types(new base::ListValue());
   for (PairingType type : security.GetPairingTypes())
     pairing_types->AppendString(EnumToString(type));
-  auth->Set(kPairingKey, pairing_types.release());
+  auth->Set(kPairingKey, std::move(pairing_types));
 
   std::unique_ptr<base::ListValue> auth_types(new base::ListValue());
   for (AuthType type : security.GetAuthTypes())
     auth_types->AppendString(EnumToString(type));
-  auth->Set(kAuthModeKey, auth_types.release());
+  auth->Set(kAuthModeKey, std::move(auth_types));
 
   std::unique_ptr<base::ListValue> crypto_types(new base::ListValue());
   for (CryptoType type : security.GetCryptoTypes())
     crypto_types->AppendString(EnumToString(type));
-  auth->Set(kCryptoKey, crypto_types.release());
+  auth->Set(kCryptoKey, std::move(crypto_types));
 
   return auth;
 }
@@ -282,7 +282,7 @@
   std::unique_ptr<base::ListValue> capabilities(new base::ListValue());
   for (WifiType type : wifi.GetTypes())
     capabilities->AppendString(EnumToString(type));
-  result->Set(kInfoWifiCapabilitiesKey, capabilities.release());
+  result->Set(kInfoWifiCapabilitiesKey, std::move(capabilities));
 
   result->SetString(kInfoWifiSsidKey, wifi.GetCurrentlyConnectedSsid());
 
@@ -340,9 +340,9 @@
         const base::DictionaryValue* sub_components = nullptr;
         CHECK(it.value().GetAsDictionary(&sub_components));
         clone->SetWithoutPathExpansion(
-            it.key(), CloneComponentTree(*sub_components, filter).release());
+            it.key(), CloneComponentTree(*sub_components, filter));
       } else {
-        clone->SetWithoutPathExpansion(it.key(), it.value().DeepCopy());
+        clone->SetWithoutPathExpansion(it.key(), it.value().CreateDeepCopy());
       }
     }
   }
@@ -350,8 +350,8 @@
 }
 
 // Clones a dictionary containing a bunch of component JSON objects in a manner
-// similar to that of DeepCopy(). Calls CloneComponent() on each instance of
-// the component sub-object.
+// similar to that of CreateDeepCopy(). Calls CloneComponent() on each instance
+// of the component sub-object.
 std::unique_ptr<base::DictionaryValue> CloneComponentTree(
     const base::DictionaryValue& parent,
     const std::set<std::string>& filter) {
@@ -361,7 +361,7 @@
     const base::DictionaryValue* component = nullptr;
     CHECK(it.value().GetAsDictionary(&component));
     clone->SetWithoutPathExpansion(
-        it.key(), CloneComponent(*component, filter).release());
+        it.key(), CloneComponent(*component, filter));
   }
   return clone;
 }
@@ -565,23 +565,21 @@
     output.SetString(kLocationKey, location);
 
   output.SetString(kInfoModelIdKey, model_id);
-  output.Set(kInfoModelManifestKey, CreateManifestSection(*cloud_).release());
+  output.Set(kInfoModelManifestKey, CreateManifestSection(*cloud_));
   output.Set(
       kInfoServicesKey,
-      ToValue(std::vector<std::string>{GetDeviceUiKind(cloud_->GetModelId())})
-          .release());
+      ToValue(std::vector<std::string>{GetDeviceUiKind(cloud_->GetModelId())}));
 
   output.Set(
       kInfoAuthenticationKey,
-      CreateInfoAuthSection(*security_, GetAnonymousMaxScope(*cloud_, wifi_))
-          .release());
+      CreateInfoAuthSection(*security_, GetAnonymousMaxScope(*cloud_, wifi_)));
 
-  output.Set(kInfoEndpointsKey, CreateEndpointsSection(*device_).release());
+  output.Set(kInfoEndpointsKey, CreateEndpointsSection(*device_));
 
   if (wifi_)
-    output.Set(kWifiKey, CreateWifiSection(*wifi_).release());
+    output.Set(kWifiKey, CreateWifiSection(*wifi_));
 
-  output.Set(kGcdKey, CreateGcdSection(*cloud_).release());
+  output.Set(kGcdKey, CreateGcdSection(*cloud_));
 
   output.SetDouble(kInfoTimeKey, clock_->Now().ToJsTime());
   output.SetString(kInfoSessionIdKey, security_->CreateSessionId());
@@ -882,7 +880,7 @@
                                  const UserInfo& user_info,
                                  const RequestCallback& callback) {
   base::DictionaryValue output;
-  output.Set(kTraitsKey, cloud_->GetTraits().DeepCopy());
+  output.Set(kTraitsKey, cloud_->GetTraits().CreateDeepCopy());
   output.SetString(kFingerprintKey, std::to_string(traits_fingerprint_));
 
   callback.Run(http::kOk, output);
@@ -913,13 +911,13 @@
     components.reset(new base::DictionaryValue);
     // Get the last element of the path and use it as a dictionary key here.
     auto parts = Split(path, ".", true, false);
-    components->Set(parts.back(), CloneComponent(*component, filter).release());
+    components->Set(parts.back(), CloneComponent(*component, filter));
   } else {
     components =
         CloneComponentTree(*cloud_->GetComponentsForUser(user_info), filter);
   }
   base::DictionaryValue output;
-  output.Set(kComponentsKey, components.release());
+  output.Set(kComponentsKey, std::move(components));
   output.SetString(kFingerprintKey, std::to_string(components_fingerprint_));
 
   callback.Run(http::kOk, output);
diff --git a/src/privet/privet_handler_unittest.cc b/src/privet/privet_handler_unittest.cc
index b7fb758..0c9f158 100644
--- a/src/privet/privet_handler_unittest.cc
+++ b/src/privet/privet_handler_unittest.cc
@@ -41,8 +41,7 @@
   std::string message;
   std::unique_ptr<base::Value> value(
       base::JSONReader::ReadAndReturnError(test_json, base::JSON_PARSE_RFC,
-                                           &error, &message)
-          .release());
+                                           &error, &message));
   EXPECT_TRUE(value.get()) << "\nError: " << message << "\n" << test_json;
   base::DictionaryValue* dictionary_ptr = nullptr;
   if (value->GetAsDictionary(&dictionary_ptr))
@@ -75,7 +74,7 @@
 std::unique_ptr<base::DictionaryValue> StripDebugErrorDetails(
     const std::string& path_to_error_object,
     const base::DictionaryValue& value) {
-  std::unique_ptr<base::DictionaryValue> result{value.DeepCopy()};
+  auto result = value.CreateDeepCopy();
   base::DictionaryValue* error_dict = nullptr;
   EXPECT_TRUE(result->GetDictionary(path_to_error_object, &error_dict));
   scoped_ptr<base::Value> dummy;
diff --git a/src/states/state_change_queue.cc b/src/states/state_change_queue.cc
index effe7f3..dcb19df 100644
--- a/src/states/state_change_queue.cc
+++ b/src/states/state_change_queue.cc
@@ -21,7 +21,7 @@
   if (stored_changes)
     stored_changes->MergeDictionary(&changed_properties);
   else
-    stored_changes.reset(changed_properties.DeepCopy());
+    stored_changes = changed_properties.CreateDeepCopy();
 
   while (state_changes_.size() > max_queue_size_) {
     // Queue is full.
diff --git a/src/test/unittest_utils.cc b/src/test/unittest_utils.cc
index 2176e7f..effadae 100644
--- a/src/test/unittest_utils.cc
+++ b/src/test/unittest_utils.cc
@@ -21,8 +21,7 @@
   std::string message;
   std::unique_ptr<base::Value> value{
       base::JSONReader::ReadAndReturnError(json2, base::JSON_PARSE_RFC, &error,
-                                           &message)
-          .release()};
+                                           &message)};
   CHECK(value) << "Failed to load JSON: " << message << ", " << json;
   return value;
 }
@@ -36,12 +35,10 @@
 
 std::unique_ptr<base::DictionaryValue> CreateDictionaryValue(
     const std::string& json) {
-  std::unique_ptr<base::Value> value = CreateValue(json);
-  base::DictionaryValue* dict = nullptr;
-  value->GetAsDictionary(&dict);
+  std::unique_ptr<base::DictionaryValue> dict =
+      base::DictionaryValue::From(CreateValue(json));
   CHECK(dict) << "Value is not dictionary: " << json;
-  value.release();
-  return std::unique_ptr<base::DictionaryValue>(dict);
+  return dict;
 }
 
 }  // namespace test
diff --git a/src/utils.cc b/src/utils.cc
index bd15e61..d74c81e 100644
--- a/src/utils.cc
+++ b/src/utils.cc
@@ -52,17 +52,12 @@
                        json_string.size(), error_message.c_str());
     return result;
   }
-  base::DictionaryValue* dict_value = nullptr;
-  if (!value->GetAsDictionary(&dict_value)) {
+  result = base::DictionaryValue::From(std::move(value));
+  if (!result) {
     Error::AddToPrintf(error, FROM_HERE, errors::json::kObjectExpected,
                        "JSON string '%s' is not a JSON object",
                        LimitString(json_string, kMaxStrLen).c_str());
-    return result;
-  } else {
-    // |value| is now owned by |dict_value|.
-    base::IgnoreResult(value.release());
   }
-  result.reset(dict_value);
   return result;
 }
 
diff --git a/src/weave_unittest.cc b/src/weave_unittest.cc
index d92dace..eb65149 100644
--- a/src/weave_unittest.cc
+++ b/src/weave_unittest.cc
@@ -404,14 +404,14 @@
 
   auto draft = CreateDictionaryValue(kDeviceResource);
   auto response = CreateDictionaryValue(kRegistrationResponse);
-  response->Set("deviceDraft", draft->DeepCopy());
+  response->Set("deviceDraft", draft->CreateDeepCopy());
   ExpectRequest(HttpClient::Method::kPatch,
                 "https://www.googleapis.com/weave/v1/registrationTickets/"
                 "TICKET_ID?key=TEST_API_KEY",
                 ValueToString(*response));
 
   response = CreateDictionaryValue(kRegistrationFinalResponse);
-  response->Set("deviceDraft", draft->DeepCopy());
+  response->Set("deviceDraft", draft->CreateDeepCopy());
   ExpectRequest(HttpClient::Method::kPost,
                 "https://www.googleapis.com/weave/v1/registrationTickets/"
                 "TICKET_ID/finalize?key=TEST_API_KEY",