diff --git a/chrome/browser/chromeos/chrome_browser_main_chromeos.cc b/chrome/browser/chromeos/chrome_browser_main_chromeos.cc
index dbb26359624e4..c768ca57be3b8 100644
--- a/chrome/browser/chromeos/chrome_browser_main_chromeos.cc
+++ b/chrome/browser/chromeos/chrome_browser_main_chromeos.cc
@@ -49,6 +49,7 @@
 #include "chrome/browser/chromeos/memory/oom_priority_manager.h"
 #include "chrome/browser/chromeos/net/connectivity_state_helper.h"
 #include "chrome/browser/chromeos/net/cros_network_change_notifier_factory.h"
+#include "chrome/browser/chromeos/net/managed_network_configuration_handler.h"
 #include "chrome/browser/chromeos/net/network_change_notifier_network_library.h"
 #include "chrome/browser/chromeos/net/network_portal_detector.h"
 #include "chrome/browser/chromeos/power/brightness_observer.h"
@@ -260,7 +261,12 @@ class DBusServices {
     chromeos::network_event_log::Initialize();
     chromeos::GeolocationHandler::Initialize();
     chromeos::NetworkStateHandler::Initialize();
-    chromeos::NetworkConfigurationHandler::Initialize();
+
+    if (CommandLine::ForCurrentProcess()->HasSwitch(
+            chromeos::switches::kEnableNewNetworkConfigurationHandlers)) {
+      chromeos::NetworkConfigurationHandler::Initialize();
+      chromeos::ManagedNetworkConfigurationHandler::Initialize();
+    }
 
     // Initialize the network change notifier for Chrome OS. The network
     // change notifier starts to monitor changes from the power manager and
@@ -298,9 +304,14 @@ class DBusServices {
     if (cros_initialized_ && CrosLibrary::Get())
       CrosLibrary::Shutdown();
 
+    if (CommandLine::ForCurrentProcess()->HasSwitch(
+            chromeos::switches::kEnableNewNetworkConfigurationHandlers)) {
+      chromeos::ManagedNetworkConfigurationHandler::Shutdown();
+      chromeos::NetworkConfigurationHandler::Shutdown();
+    }
+
     chromeos::ConnectivityStateHelper::Shutdown();
     chromeos::NetworkStateHandler::Shutdown();
-    chromeos::NetworkConfigurationHandler::Shutdown();
     chromeos::GeolocationHandler::Shutdown();
     chromeos::network_event_log::Shutdown();
 
diff --git a/chrome/browser/chromeos/extensions/networking_private_api.cc b/chrome/browser/chromeos/extensions/networking_private_api.cc
index 814163fb1b882..a1a669b985008 100644
--- a/chrome/browser/chromeos/extensions/networking_private_api.cc
+++ b/chrome/browser/chromeos/extensions/networking_private_api.cc
@@ -4,7 +4,10 @@
 
 #include "chrome/browser/chromeos/extensions/networking_private_api.h"
 
+#include "base/bind.h"
 #include "base/bind_helpers.h"
+#include "base/callback.h"
+#include "chrome/browser/chromeos/net/managed_network_configuration_handler.h"
 #include "chrome/browser/extensions/extension_function_registry.h"
 #include "chrome/common/extensions/api/networking_private.h"
 #include "chromeos/dbus/dbus_thread_manager.h"
@@ -25,17 +28,10 @@ namespace {
 // An error returned when no valid services were found.
 const char kInvalidResponseError[] = "Error.invalidResponse";
 
-// This creates a new ONC dictionary that only contains the information we're
-// interested in passing on to JavaScript.
+// Filters from the given ONC dictionary the information we're interested in
+// before passing it to JavaScript.
 scoped_ptr<api::NetworkProperties> CreateFilteredResult(
-    const base::DictionaryValue& properties) {
-  scoped_ptr<base::DictionaryValue> onc_properties(
-      onc::TranslateShillServiceToONCPart(
-          properties,
-          &onc::kNetworkConfigurationSignature));
-
-  // Now we filter it so we only include properties that we care about for this
-  // interface.
+    const base::DictionaryValue& onc_dictionary) {
   static const char* const desired_fields[] = {
       onc::network_config::kWiFi,
       onc::network_config::kName,
@@ -47,10 +43,12 @@ scoped_ptr<api::NetworkProperties> CreateFilteredResult(
   scoped_ptr<api::NetworkProperties> filtered_result(
       new api::NetworkProperties);
   for (size_t i = 0; i < arraysize(desired_fields); ++i) {
-    base::Value* value;
-    if (onc_properties->Get(desired_fields[i], &value))
-      filtered_result->additional_properties.Set(desired_fields[i],
-                                                 value->DeepCopy());
+    const base::Value* value;
+    if (onc_dictionary.GetWithoutPathExpansion(desired_fields[i], &value)) {
+      filtered_result->additional_properties.SetWithoutPathExpansion(
+          desired_fields[i],
+          value->DeepCopy());
+    }
   }
 
   return filtered_result.Pass();
@@ -141,8 +139,13 @@ void ResultList::ServicePropertiesCallback(
     DBusMethodCallStatus call_status,
     const base::DictionaryValue& result) {
   if (call_status == DBUS_METHOD_CALL_SUCCESS) {
+    scoped_ptr<base::DictionaryValue> onc_properties(
+        onc::TranslateShillServiceToONCPart(
+            result,
+            &onc::kNetworkConfigurationSignature));
+
     scoped_ptr<api::NetworkProperties> filtered_result(
-        CreateFilteredResult(result));
+        CreateFilteredResult(*onc_properties));
 
     std::string onc_type;
     if (filtered_result->additional_properties.GetString(
@@ -155,7 +158,7 @@ void ResultList::ServicePropertiesCallback(
       // this line so that we're sending back the actual GUID. The
       // JavaScript shouldn't care: this ID is opaque to it, and it
       // shouldn't store it anywhere.
-      filtered_result->additional_properties.SetString(
+      filtered_result->additional_properties.SetStringWithoutPathExpansion(
           onc::network_config::kGUID, service_path);
 
       Append(filtered_result.release());
@@ -176,25 +179,56 @@ bool NetworkingPrivateGetPropertiesFunction::RunImpl() {
   scoped_ptr<api::GetProperties::Params> params =
       api::GetProperties::Params::Create(*args_);
   EXTENSION_FUNCTION_VALIDATE(params);
-
-  // TODO(gspencer): Currently we're using the service path as the
-  // |network_guid|. Eventually this should be using the real GUID.
-  DBusThreadManager::Get()->GetShillServiceClient()->GetProperties(
-      dbus::ObjectPath(params->network_guid),
-      base::Bind(&NetworkingPrivateGetPropertiesFunction::ResultCallback,
-                 this));
+  if (ManagedNetworkConfigurationHandler::IsInitialized()) {
+    ManagedNetworkConfigurationHandler::Get()->GetProperties(
+        params->network_guid,
+        base::Bind(
+            &NetworkingPrivateGetPropertiesFunction::GetPropertiesSuccess,
+            this),
+        base::Bind(&NetworkingPrivateGetPropertiesFunction::GetPropertiesFailed,
+                   this));
+  } else {
+    // TODO(gspencer): Currently we're using the service path as the
+    // |network_guid|. Eventually this should be using the real GUID.
+    DBusThreadManager::Get()->GetShillServiceClient()->GetProperties(
+        dbus::ObjectPath(params->network_guid),
+        base::Bind(&NetworkingPrivateGetPropertiesFunction::ResultCallback,
+                   this,
+                   params->network_guid));
+  }
   return true;
 }
 
 void NetworkingPrivateGetPropertiesFunction::ResultCallback(
+    const std::string& service_path,
     DBusMethodCallStatus call_status,
     const base::DictionaryValue& result) {
+  scoped_ptr<base::DictionaryValue> onc_properties(
+      onc::TranslateShillServiceToONCPart(
+          result,
+          &onc::kNetworkConfigurationSignature));
+  GetPropertiesSuccess(service_path,
+                       *onc_properties);
+}
+
+void NetworkingPrivateGetPropertiesFunction::GetPropertiesSuccess(
+    const std::string& service_path,
+    const base::DictionaryValue& dictionary) {
   scoped_ptr<api::NetworkProperties> filtered_result(
-      CreateFilteredResult(result));
+      CreateFilteredResult(dictionary));
+  filtered_result->additional_properties.SetStringWithoutPathExpansion(
+      onc::network_config::kGUID, service_path);
   results_ = api::GetProperties::Results::Create(*filtered_result);
   SendResponse(true);
 }
 
+void NetworkingPrivateGetPropertiesFunction::GetPropertiesFailed(
+    const std::string& error_name,
+    scoped_ptr<base::DictionaryValue> error_data) {
+  error_ = error_name;
+  SendResponse(false);
+}
+
 ////////////////////////////////////////////////////////////////////////////////
 // NetworkingPrivateGetVisibleNetworksFunction
 
diff --git a/chrome/browser/chromeos/extensions/networking_private_api.h b/chrome/browser/chromeos/extensions/networking_private_api.h
index 2ffb978eb417e..176627715d532 100644
--- a/chrome/browser/chromeos/extensions/networking_private_api.h
+++ b/chrome/browser/chromeos/extensions/networking_private_api.h
@@ -30,8 +30,18 @@ class NetworkingPrivateGetPropertiesFunction : public AsyncExtensionFunction {
   virtual bool RunImpl() OVERRIDE;
 
  private:
-  void ResultCallback(chromeos::DBusMethodCallStatus call_status,
+  // Callback if talking to ShillServiceClient directly.
+  // TODO(pneubeck): Remove once the ManagedNetworkConfigurationHandler is
+  // stable.
+  void ResultCallback(const std::string& service_path,
+                      chromeos::DBusMethodCallStatus call_status,
                       const base::DictionaryValue& result);
+
+  // Callbacks if talking to ManagedNetworkConfigurationHandler.
+  void GetPropertiesSuccess(const std::string& service_path,
+                            const base::DictionaryValue& result);
+  void GetPropertiesFailed(const std::string& error_name,
+                           scoped_ptr<base::DictionaryValue> error_data);
   DISALLOW_COPY_AND_ASSIGN(NetworkingPrivateGetPropertiesFunction);
 };
 
diff --git a/chrome/browser/chromeos/net/OWNERS b/chrome/browser/chromeos/net/OWNERS
new file mode 100644
index 0000000000000..62b7b0d840531
--- /dev/null
+++ b/chrome/browser/chromeos/net/OWNERS
@@ -0,0 +1,5 @@
+per-file managed_network_configuration_handler.*=gspencer@chromium.org
+per-file managed_network_configuration_handler.*=pneubeck@chromium.org
+
+per-file onc_utils.*=gspencer@chromium.org
+per-file onc_utils.*=pneubeck@chromium.org
diff --git a/chrome/browser/chromeos/net/managed_network_configuration_handler.cc b/chrome/browser/chromeos/net/managed_network_configuration_handler.cc
new file mode 100644
index 0000000000000..27ea5fadea447
--- /dev/null
+++ b/chrome/browser/chromeos/net/managed_network_configuration_handler.cc
@@ -0,0 +1,207 @@
+// 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 "chrome/browser/chromeos/net/managed_network_configuration_handler.h"
+
+#include <string>
+#include <vector>
+
+#include "base/bind.h"
+#include "base/guid.h"
+#include "base/logging.h"
+#include "base/memory/ref_counted.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/values.h"
+#include "chromeos/dbus/dbus_method_call_status.h"
+#include "chromeos/dbus/dbus_thread_manager.h"
+#include "chromeos/dbus/shill_manager_client.h"
+#include "chromeos/dbus/shill_service_client.h"
+#include "chromeos/network/network_configuration_handler.h"
+#include "chromeos/network/network_event_log.h"
+#include "chromeos/network/network_state.h"
+#include "chromeos/network/network_state_handler.h"
+#include "chromeos/network/onc/onc_constants.h"
+#include "chromeos/network/onc/onc_signature.h"
+#include "chromeos/network/onc/onc_translator.h"
+#include "dbus/object_path.h"
+#include "third_party/cros_system_api/dbus/service_constants.h"
+
+namespace chromeos {
+
+namespace {
+
+ManagedNetworkConfigurationHandler* g_configuration_handler_instance = NULL;
+
+const char kLogModule[] = "ManagedNetworkConfigurationHandler";
+
+// These are error strings used for error callbacks. None of these error
+// messages are user-facing: they should only appear in logs.
+const char kServicePath[] = "servicePath";
+const char kSetOnUnconfiguredNetworkMessage[] =
+    "Unable to modify properties of an unconfigured network.";
+const char kSetOnUnconfiguredNetwork[] = "Error.SetCalledOnUnconfiguredNetwork";
+const char kUnknownServicePathMessage[] = "Service path is unknown.";
+const char kUnknownServicePath[] = "Error.UnknownServicePath";
+
+void RunErrorCallback(const std::string& service_path,
+                      const std::string& error_name,
+                      const std::string& error_message,
+                      const network_handler::ErrorCallback& error_callback) {
+  network_event_log::AddEntry(kLogModule, error_name, error_message);
+  error_callback.Run(
+      error_name,
+      make_scoped_ptr(
+          network_handler::CreateErrorData(service_path,
+                                           error_name,
+                                           error_message)));
+}
+
+void TranslatePropertiesAndRunCallback(
+    const network_handler::DictionaryResultCallback& callback,
+    const std::string& service_path,
+    const base::DictionaryValue& shill_properties) {
+  scoped_ptr<base::DictionaryValue> onc_network(
+      onc::TranslateShillServiceToONCPart(
+          shill_properties,
+          &onc::kNetworkConfigurationSignature));
+  callback.Run(service_path, *onc_network);
+}
+
+}  // namespace
+
+// static
+void ManagedNetworkConfigurationHandler::Initialize() {
+  CHECK(!g_configuration_handler_instance);
+  g_configuration_handler_instance = new ManagedNetworkConfigurationHandler;
+}
+
+// static
+bool ManagedNetworkConfigurationHandler::IsInitialized() {
+  return g_configuration_handler_instance;
+}
+
+// static
+void ManagedNetworkConfigurationHandler::Shutdown() {
+  CHECK(g_configuration_handler_instance);
+  delete g_configuration_handler_instance;
+  g_configuration_handler_instance = NULL;
+}
+
+// static
+ManagedNetworkConfigurationHandler* ManagedNetworkConfigurationHandler::Get() {
+  CHECK(g_configuration_handler_instance);
+  return g_configuration_handler_instance;
+}
+
+void ManagedNetworkConfigurationHandler::GetProperties(
+    const std::string& service_path,
+    const network_handler::DictionaryResultCallback& callback,
+    const network_handler::ErrorCallback& error_callback) const {
+  // TODO(pneubeck): Merge with policies.
+  NetworkConfigurationHandler::Get()->GetProperties(
+      service_path,
+      base::Bind(&TranslatePropertiesAndRunCallback, callback),
+      error_callback);
+}
+
+void ManagedNetworkConfigurationHandler::SetProperties(
+    const std::string& service_path,
+    const base::DictionaryValue& properties,
+    const base::Closure& callback,
+    const network_handler::ErrorCallback& error_callback) const {
+  const NetworkState* state =
+      NetworkStateHandler::Get()->GetNetworkState(service_path);
+
+  if (!state) {
+    RunErrorCallback(service_path,
+                     kUnknownServicePath,
+                     kUnknownServicePathMessage,
+                     error_callback);
+  }
+  std::string guid = state->guid();
+  if (guid.empty()) {
+    RunErrorCallback(service_path,
+                     kSetOnUnconfiguredNetwork,
+                     kSetOnUnconfiguredNetworkMessage,
+                     error_callback);
+  }
+
+  // TODO(pneubeck): Enforce policies.
+
+  scoped_ptr<base::DictionaryValue> shill_dictionary(
+      onc::TranslateONCObjectToShill(
+          &onc::kNetworkConfigurationSignature,
+          properties));
+
+  NetworkConfigurationHandler::Get()->SetProperties(service_path,
+                                                    *shill_dictionary,
+                                                    callback,
+                                                    error_callback);
+}
+
+void ManagedNetworkConfigurationHandler::Connect(
+    const std::string& service_path,
+    const base::Closure& callback,
+    const network_handler::ErrorCallback& error_callback) const {
+  // TODO(pneubeck): Update the user profile with tracked/followed settings of
+  // the shared profile.
+  NetworkConfigurationHandler::Get()->Connect(service_path,
+                                              callback,
+                                              error_callback);
+}
+
+void ManagedNetworkConfigurationHandler::Disconnect(
+    const std::string& service_path,
+    const base::Closure& callback,
+    const network_handler::ErrorCallback& error_callback) const {
+  NetworkConfigurationHandler::Get()->Disconnect(service_path,
+                                                 callback,
+                                                 error_callback);
+}
+
+void ManagedNetworkConfigurationHandler::CreateConfiguration(
+    const base::DictionaryValue& properties,
+    const network_handler::StringResultCallback& callback,
+    const network_handler::ErrorCallback& error_callback) const {
+  scoped_ptr<base::DictionaryValue> modified_properties(
+      properties.DeepCopy());
+
+  // If there isn't already a GUID attached to these properties, then
+  // generate one and add it.
+  std::string guid;
+  if (!properties.GetString(onc::network_config::kGUID, &guid)) {
+    guid = base::GenerateGUID();
+    modified_properties->SetStringWithoutPathExpansion(
+        onc::network_config::kGUID, guid);
+  } else {
+    NOTREACHED(); // TODO(pneubeck): Return an error using error_callback.
+  }
+
+  // TODO(pneubeck): Enforce policies.
+
+  scoped_ptr<base::DictionaryValue> shill_dictionary(
+      onc::TranslateONCObjectToShill(&onc::kNetworkConfigurationSignature,
+                                     properties));
+
+  NetworkConfigurationHandler::Get()->CreateConfiguration(*shill_dictionary,
+                                                          callback,
+                                                          error_callback);
+}
+
+void ManagedNetworkConfigurationHandler::RemoveConfiguration(
+    const std::string& service_path,
+    const base::Closure& callback,
+    const network_handler::ErrorCallback& error_callback) const {
+  NetworkConfigurationHandler::Get()->RemoveConfiguration(service_path,
+                                                          callback,
+                                                          error_callback);
+}
+
+ManagedNetworkConfigurationHandler::ManagedNetworkConfigurationHandler() {
+}
+
+ManagedNetworkConfigurationHandler::~ManagedNetworkConfigurationHandler() {
+}
+
+}  // namespace chromeos
diff --git a/chrome/browser/chromeos/net/managed_network_configuration_handler.h b/chrome/browser/chromeos/net/managed_network_configuration_handler.h
new file mode 100644
index 0000000000000..c0980ec94de11
--- /dev/null
+++ b/chrome/browser/chromeos/net/managed_network_configuration_handler.h
@@ -0,0 +1,121 @@
+// 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 CHROME_BROWSER_CHROMEOS_NET_MANAGED_NETWORK_CONFIGURATION_HANDLER_H_
+#define CHROME_BROWSER_CHROMEOS_NET_MANAGED_NETWORK_CONFIGURATION_HANDLER_H_
+
+#include <string>
+#include <vector>
+
+#include "base/basictypes.h"
+#include "base/callback.h"
+#include "base/gtest_prod_util.h"
+#include "chromeos/chromeos_export.h"
+#include "chromeos/network/network_handler_callbacks.h"
+
+namespace base {
+class DictionaryValue;
+}
+
+namespace chromeos {
+
+// The ManagedNetworkConfigurationHandler class is used to create and configure
+// networks in ChromeOS using ONC.
+//
+// Its interface exposes only ONC and should decouple users from Shill.
+// Internally it translates ONC to Shill dictionaries and calls through to the
+// NetworkConfigurationHandler.
+//
+// For accessing lists of visible networks, and other state information, see the
+// class NetworkStateHandler.
+//
+// This is a singleton and its lifetime is managed by the Chrome startup code.
+//
+// Network configurations are referred to by Shill's service path. These
+// identifiers should at most be used to also access network state using the
+// NetworkStateHandler, but dependencies to Shill should be avoided. In the
+// future, we may switch to other identifiers.
+//
+// Note on callbacks: Because all the functions here are meant to be
+// asynchronous, they all take a |callback| of some type, and an
+// |error_callback|. When the operation succeeds, |callback| will be called, and
+// when it doesn't, |error_callback| will be called with information about the
+// error, including a symbolic name for the error and often some error message
+// that is suitable for logging. None of the error message text is meant for
+// user consumption.
+//
+// TODO(pneubeck): Enforce network policies.
+
+class ManagedNetworkConfigurationHandler {
+ public:
+  // Initializes the singleton.
+  static void Initialize();
+
+  // Returns if the singleton is initialized.
+  static bool IsInitialized();
+
+  // Destroys the singleton.
+  static void Shutdown();
+
+  // Initialize() must be called before this.
+  static ManagedNetworkConfigurationHandler* Get();
+
+  // Provides the properties of the network with |service_path| to |callback|.
+  void GetProperties(
+      const std::string& service_path,
+      const network_handler::DictionaryResultCallback& callback,
+      const network_handler::ErrorCallback& error_callback) const;
+
+  // Sets the user's settings of an already configured network with
+  // |service_path|. A network can be initially configured by calling
+  // CreateConfiguration or if it is managed by a policy. The given properties
+  // will be merged with the existing settings, and it won't clear any existing
+  // properties.
+  void SetProperties(
+      const std::string& service_path,
+      const base::DictionaryValue& properties,
+      const base::Closure& callback,
+      const network_handler::ErrorCallback& error_callback) const;
+
+  // Initiates a connection with network that has |service_path|. |callback| is
+  // called if the connection request was successfully handled. That doesn't
+  // mean that the connection was successfully established.
+  void Connect(const std::string& service_path,
+               const base::Closure& callback,
+               const network_handler::ErrorCallback& error_callback) const;
+
+  // Initiates a disconnect with the network at |service_path|. |callback| is
+  // called if the diconnect request was successfully handled. That doesn't mean
+  // that the network is already diconnected.
+  void Disconnect(const std::string& service_path,
+                  const base::Closure& callback,
+                  const network_handler::ErrorCallback& error_callback) const;
+
+  // Initially configures an unconfigured network with the given user settings
+  // and returns the new identifier to |callback| if successful. Fails if the
+  // network was already configured by a call to this function or because of a
+  // policy.
+  void CreateConfiguration(
+      const base::DictionaryValue& properties,
+      const network_handler::StringResultCallback& callback,
+      const network_handler::ErrorCallback& error_callback) const;
+
+  // Removes the user's configuration from the network with |service_path|. The
+  // network may still show up in the visible networks after this, but no user
+  // configuration will remain. If it was managed, it will still be configured.
+  void RemoveConfiguration(
+      const std::string& service_path,
+      const base::Closure& callback,
+      const network_handler::ErrorCallback& error_callback) const;
+
+ private:
+  ManagedNetworkConfigurationHandler();
+  ~ManagedNetworkConfigurationHandler();
+
+  DISALLOW_COPY_AND_ASSIGN(ManagedNetworkConfigurationHandler);
+};
+
+}  // namespace chromeos
+
+#endif  // CHROME_BROWSER_CHROMEOS_NET_MANAGED_NETWORK_CONFIGURATION_HANDLER_H_
diff --git a/chrome/chrome_browser_chromeos.gypi b/chrome/chrome_browser_chromeos.gypi
index d5b09c0458076..a54d3b92c70b9 100644
--- a/chrome/chrome_browser_chromeos.gypi
+++ b/chrome/chrome_browser_chromeos.gypi
@@ -522,6 +522,8 @@
         'browser/chromeos/net/connectivity_state_helper.h',
         'browser/chromeos/net/cros_network_change_notifier_factory.cc',
         'browser/chromeos/net/cros_network_change_notifier_factory.h',
+        'browser/chromeos/net/managed_network_configuration_handler.cc',
+        'browser/chromeos/net/managed_network_configuration_handler.h',
         'browser/chromeos/net/network_change_notifier_network_library.cc',
         'browser/chromeos/net/network_change_notifier_network_library.h',
         'browser/chromeos/net/network_portal_detector.cc',
diff --git a/chromeos/chromeos_switches.cc b/chromeos/chromeos_switches.cc
index 440e589c21082..45e076fcc8ede 100644
--- a/chromeos/chromeos_switches.cc
+++ b/chromeos/chromeos_switches.cc
@@ -24,6 +24,10 @@ const char kEnableNewNetworkChangeNotifier[] =
 // Enables screensaver extensions.
 const char kEnableScreensaverExtensions[] = "enable-screensaver-extensions";
 
+// Enables the new NetworkConfigurationHandler class.
+const char kEnableNewNetworkConfigurationHandlers[] =
+    "enable-new-network-configuration-handlers";
+
 // Sends test messages on first call to RequestUpdate (stub only).
 const char kSmsTestMessages[] = "sms-test-messages";
 
diff --git a/chromeos/chromeos_switches.h b/chromeos/chromeos_switches.h
index 6990982f5eb36..a287962701239 100644
--- a/chromeos/chromeos_switches.h
+++ b/chromeos/chromeos_switches.h
@@ -24,6 +24,7 @@ CHROMEOS_EXPORT extern const char kChromeOSReleaseBoard[];
 CHROMEOS_EXPORT extern const char kDbusStub[];
 CHROMEOS_EXPORT extern const char kEnableLocallyManagedUserUIExperiments[];
 CHROMEOS_EXPORT extern const char kEnableNewNetworkChangeNotifier[];
+CHROMEOS_EXPORT extern const char kEnableNewNetworkConfigurationHandlers[];
 CHROMEOS_EXPORT extern const char kEnableScreensaverExtensions[];
 CHROMEOS_EXPORT extern const char kSmsTestMessages[];
 
diff --git a/chromeos/network/network_configuration_handler.cc b/chromeos/network/network_configuration_handler.cc
index 23b73f581f041..17c691fe09697 100644
--- a/chromeos/network/network_configuration_handler.cc
+++ b/chromeos/network/network_configuration_handler.cc
@@ -20,12 +20,12 @@
 
 namespace chromeos {
 
-static NetworkConfigurationHandler* g_network_configuration_handler = NULL;
-
 namespace {
 
 const char kLogModule[] = "NetworkConfigurationHandler";
 
+NetworkConfigurationHandler* g_configuration_handler_instance = NULL;
+
 // None of these error messages are user-facing: they should only appear in
 // logs.
 const char kErrorsListTag[] = "errors";
@@ -60,7 +60,7 @@ void ClearPropertiesCallback(
         network_handler::CreateErrorData(service_path,
                                          kClearPropertiesFailedError,
                                          kClearPropertiesFailedErrorMessage));
-    LOG(ERROR) << "ClearPropertiesCallback Failed for service path: "
+    LOG(ERROR) << "ClearPropertiesCallback failed for service path: "
                << service_path;
     error_data->Set("errors", result.DeepCopy());
     scoped_ptr<base::ListValue> name_list(new base::ListValue);
@@ -85,7 +85,7 @@ void RunCallbackWithDictionaryValue(
         network_handler::CreateErrorData(service_path,
                                          kDBusFailedError,
                                          kDBusFailedErrorMessage));
-    LOG(ERROR) << "CallbackWithDictionaryValue Failed for service path: "
+    LOG(ERROR) << "CallbackWithDictionaryValue failed for service path: "
                << service_path;
     error_callback.Run(kDBusFailedError, error_data.Pass());
   } else {
@@ -106,30 +106,24 @@ void IgnoreObjectPathCallback(const base::Closure& callback,
 
 }  // namespace
 
-NetworkConfigurationHandler::NetworkConfigurationHandler() {
-}
-
-NetworkConfigurationHandler::~NetworkConfigurationHandler() {
-}
-
 // static
 void NetworkConfigurationHandler::Initialize() {
-  CHECK(!g_network_configuration_handler);
-  g_network_configuration_handler = new NetworkConfigurationHandler();
+  CHECK(!g_configuration_handler_instance);
+  g_configuration_handler_instance = new NetworkConfigurationHandler;
 }
 
 // static
 void NetworkConfigurationHandler::Shutdown() {
-  CHECK(g_network_configuration_handler);
-  delete g_network_configuration_handler;
-  g_network_configuration_handler = NULL;
+  CHECK(g_configuration_handler_instance);
+  delete g_configuration_handler_instance;
+  g_configuration_handler_instance = NULL;
 }
 
 // static
 NetworkConfigurationHandler* NetworkConfigurationHandler::Get() {
-  CHECK(g_network_configuration_handler)
+  CHECK(g_configuration_handler_instance)
       << "NetworkConfigurationHandler::Get() called before Initialize()";
-  return g_network_configuration_handler;
+  return g_configuration_handler_instance;
 }
 
 void NetworkConfigurationHandler::GetProperties(
@@ -217,4 +211,10 @@ void NetworkConfigurationHandler::RemoveConfiguration(
                  kLogModule, service_path, error_callback));
 }
 
+NetworkConfigurationHandler::NetworkConfigurationHandler() {
+}
+
+NetworkConfigurationHandler::~NetworkConfigurationHandler() {
+}
+
 }  // namespace chromeos
diff --git a/chromeos/network/network_configuration_handler.h b/chromeos/network/network_configuration_handler.h
index c7f6a8283b5ed..2a0098983eba1 100644
--- a/chromeos/network/network_configuration_handler.h
+++ b/chromeos/network/network_configuration_handler.h
@@ -25,7 +25,8 @@ namespace chromeos {
 // most calls are asynchronous for that reason. No calls will block on DBus
 // calls.
 //
-// This is owned and it's lifetime managed by aura::Shell.
+// This is owned and it's lifetime managed by the Chrome startup code. It's
+// basically a singleton, but with explicit lifetime management.
 //
 // For accessing lists of remembered networks, and other state information, see
 // the class NetworkStateHandler.
@@ -93,9 +94,8 @@ class CHROMEOS_EXPORT NetworkConfigurationHandler {
 
 
   // Creates a network with the given properties in the active Shill profile,
-  // and returns the properties to |callback| if successful, along with the new
-  // service_path. See note on |callback| and |error_callback|, in class
-  // description above.
+  // and returns the new service_path to |callback| if successful. See note on
+  // |callback| and |error_callback|, in class description above.
   void CreateConfiguration(
       const base::DictionaryValue& properties,
       const network_handler::StringResultCallback& callback,
diff --git a/chromeos/network/network_configuration_handler_unittest.cc b/chromeos/network/network_configuration_handler_unittest.cc
index 88f2f3385762b..00554f6a04c1f 100644
--- a/chromeos/network/network_configuration_handler_unittest.cc
+++ b/chromeos/network/network_configuration_handler_unittest.cc
@@ -88,12 +88,12 @@ class NetworkConfigurationHandlerTest : public testing::Test {
         mock_dbus_thread_manager->mock_shill_service_client();
 
     // Initialize DBusThreadManager with a stub implementation.
-    configuration_handler_.reset(new NetworkConfigurationHandler);
+    NetworkConfigurationHandler::Initialize();
     message_loop_.RunUntilIdle();
   }
 
   virtual void TearDown() OVERRIDE {
-    configuration_handler_.reset();
+    NetworkConfigurationHandler::Shutdown();
     DBusThreadManager::Shutdown();
   }
 
@@ -159,7 +159,6 @@ class NetworkConfigurationHandlerTest : public testing::Test {
   }
 
  protected:
-  scoped_ptr<NetworkConfigurationHandler> configuration_handler_;
   MockShillManagerClient* mock_manager_client_;
   MockShillServiceClient* mock_service_client_;
   MessageLoop message_loop_;
@@ -191,7 +190,7 @@ TEST_F(NetworkConfigurationHandlerTest, GetProperties) {
               GetProperties(_, _)).WillOnce(
                   Invoke(this,
                          &NetworkConfigurationHandlerTest::OnGetProperties));
-  configuration_handler_->GetProperties(
+  NetworkConfigurationHandler::Get()->GetProperties(
       service_path,
       base::Bind(&DictionaryValueCallback,
                  service_path,
@@ -214,7 +213,7 @@ TEST_F(NetworkConfigurationHandlerTest, SetProperties) {
               ConfigureService(_, _, _)).WillOnce(
                   Invoke(this,
                          &NetworkConfigurationHandlerTest::OnSetProperties));
-  configuration_handler_->SetProperties(
+  NetworkConfigurationHandler::Get()->SetProperties(
       service_path,
       value,
       base::Bind(&base::DoNothing),
@@ -237,7 +236,7 @@ TEST_F(NetworkConfigurationHandlerTest, ClearProperties) {
               ConfigureService(_, _, _)).WillOnce(
                   Invoke(this,
                          &NetworkConfigurationHandlerTest::OnSetProperties));
-  configuration_handler_->SetProperties(
+  NetworkConfigurationHandler::Get()->SetProperties(
       service_path,
       value,
       base::Bind(&base::DoNothing),
@@ -251,7 +250,7 @@ TEST_F(NetworkConfigurationHandlerTest, ClearProperties) {
               ClearProperties(_, _, _, _)).WillOnce(
                   Invoke(this,
                          &NetworkConfigurationHandlerTest::OnClearProperties));
-  configuration_handler_->ClearProperties(
+  NetworkConfigurationHandler::Get()->ClearProperties(
       service_path,
       values_to_clear,
       base::Bind(&base::DoNothing),
@@ -274,7 +273,7 @@ TEST_F(NetworkConfigurationHandlerTest, ClearPropertiesError) {
               ConfigureService(_, _, _)).WillOnce(
                   Invoke(this,
                          &NetworkConfigurationHandlerTest::OnSetProperties));
-  configuration_handler_->SetProperties(
+  NetworkConfigurationHandler::Get()->SetProperties(
       service_path,
       value,
       base::Bind(&base::DoNothing),
@@ -289,7 +288,7 @@ TEST_F(NetworkConfigurationHandlerTest, ClearPropertiesError) {
       ClearProperties(_, _, _, _)).WillOnce(
           Invoke(this,
                  &NetworkConfigurationHandlerTest::OnClearPropertiesError));
-  configuration_handler_->ClearProperties(
+  NetworkConfigurationHandler::Get()->ClearProperties(
       service_path,
       values_to_clear,
       base::Bind(&base::DoNothing),
@@ -304,7 +303,7 @@ TEST_F(NetworkConfigurationHandlerTest, Connect) {
               Connect(_, _, _)).WillOnce(
                   Invoke(this,
                          &NetworkConfigurationHandlerTest::OnConnect));
-  configuration_handler_->Connect(
+  NetworkConfigurationHandler::Get()->Connect(
       service_path,
       base::Bind(&base::DoNothing),
       base::Bind(&ErrorCallback, false, service_path));
@@ -318,7 +317,7 @@ TEST_F(NetworkConfigurationHandlerTest, Disconnect) {
               Disconnect(_, _, _)).WillOnce(
                   Invoke(this,
                          &NetworkConfigurationHandlerTest::OnDisconnect));
-  configuration_handler_->Disconnect(
+  NetworkConfigurationHandler::Get()->Disconnect(
       service_path,
       base::Bind(&base::DoNothing),
       base::Bind(&ErrorCallback, false, service_path));
@@ -339,7 +338,7 @@ TEST_F(NetworkConfigurationHandlerTest, CreateConfiguration) {
       GetService(_, _, _)).WillOnce(
           Invoke(this,
                  &NetworkConfigurationHandlerTest::OnGetService));
-  configuration_handler_->CreateConfiguration(
+  NetworkConfigurationHandler::Get()->CreateConfiguration(
       value,
       base::Bind(&StringResultCallback, std::string("/service/2")),
       base::Bind(&ErrorCallback, false, std::string("")));
@@ -354,7 +353,7 @@ TEST_F(NetworkConfigurationHandlerTest, RemoveConfiguration) {
       Remove(_, _, _)).WillOnce(
           Invoke(this,
                  &NetworkConfigurationHandlerTest::OnRemove));
-  configuration_handler_->RemoveConfiguration(
+  NetworkConfigurationHandler::Get()->RemoveConfiguration(
       service_path,
       base::Bind(&base::DoNothing),
       base::Bind(&ErrorCallback, false, service_path));
diff --git a/chromeos/network/network_handler_callbacks.h b/chromeos/network/network_handler_callbacks.h
index 6e586b942de13..da62bbde294f8 100644
--- a/chromeos/network/network_handler_callbacks.h
+++ b/chromeos/network/network_handler_callbacks.h
@@ -9,6 +9,7 @@
 
 #include "base/basictypes.h"
 #include "base/callback.h"
+#include "chromeos/chromeos_export.h"
 
 namespace base {
 class DictionaryValue;
@@ -31,9 +32,10 @@ typedef base::Callback<
   void(const std::string& service_path)> StringResultCallback;
 
 // Create a DictionaryValue for passing to ErrorCallback
-base::DictionaryValue* CreateErrorData(const std::string& service_path,
-                                       const std::string& error_name,
-                                       const std::string& error_message);
+CHROMEOS_EXPORT base::DictionaryValue* CreateErrorData(
+    const std::string& service_path,
+    const std::string& error_name,
+    const std::string& error_message);
 
 // Callback for Shill errors. |path| may be blank if not relevant.
 // Logs an error and calls |error_callback| if not null.
diff --git a/chromeos/network/network_state.cc b/chromeos/network/network_state.cc
index 830e993820236..bbe698aac0628 100644
--- a/chromeos/network/network_state.cc
+++ b/chromeos/network/network_state.cc
@@ -37,6 +37,8 @@ bool NetworkState::PropertyChanged(const std::string& key,
     return GetStringValue(key, value, &technology_);
   } else if (key == flimflam::kDeviceProperty) {
     return GetStringValue(key, value, &device_path_);
+  } else if (key == flimflam::kGuidProperty) {
+    return GetStringValue(key, value, &guid_);
   }
   return false;
 }
diff --git a/chromeos/network/network_state.h b/chromeos/network/network_state.h
index 30228f8e806d1..3f64a07ae6b86 100644
--- a/chromeos/network/network_state.h
+++ b/chromeos/network/network_state.h
@@ -25,14 +25,17 @@ class CHROMEOS_EXPORT NetworkState : public ManagedState {
 
   // Accessors
   const std::string& security() const { return security_; }
-  const std::string& technology() const { return technology_; }
   const std::string& ip_address() const { return ip_address_; }
   const std::string& device_path() const { return device_path_; }
+  const std::string& guid() const { return guid_; }
   const std::string& connection_state() const { return connection_state_; }
   const std::string& error() const { return error_; }
+  // Wireless property accessors
+  int signal_strength() const { return signal_strength_; }
+  // Cellular property accessors
+  const std::string& technology() const { return technology_; }
   const std::string& activation_state() const { return activation_state_; }
   const std::string& roaming() const { return roaming_; }
-  int signal_strength() const { return signal_strength_; }
 
   bool IsConnectedState() const;
   bool IsConnectingState() const;
@@ -53,6 +56,7 @@ class CHROMEOS_EXPORT NetworkState : public ManagedState {
   // Common Network Service properties
   std::string security_;
   std::string device_path_;
+  std::string guid_;
   std::string ip_address_;
   std::string connection_state_;
   std::string error_;