diff --git a/buffet/privet/ap_manager_client.cc b/buffet/privet/ap_manager_client.cc
new file mode 100644
index 0000000..b123f1f
--- /dev/null
+++ b/buffet/privet/ap_manager_client.cc
@@ -0,0 +1,115 @@
+// Copyright 2014 The Chromium OS 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 "buffet/privet/ap_manager_client.h"
+
+namespace privetd {
+
+using org::chromium::apmanager::ConfigProxy;
+using org::chromium::apmanager::ManagerProxy;
+using org::chromium::apmanager::ServiceProxy;
+
+ApManagerClient::ApManagerClient(const scoped_refptr<dbus::Bus>& bus)
+    : bus_(bus) {
+}
+
+ApManagerClient::~ApManagerClient() {
+  Stop();
+}
+
+void ApManagerClient::Start(const std::string& ssid) {
+  if (service_path_.IsValid()) {
+    return;
+  }
+
+  ssid_ = ssid;
+
+  object_manager_proxy_.reset(
+      new org::chromium::apmanager::ObjectManagerProxy{bus_});
+  object_manager_proxy_->SetManagerAddedCallback(base::Bind(
+      &ApManagerClient::OnManagerAdded, weak_ptr_factory_.GetWeakPtr()));
+  object_manager_proxy_->SetServiceAddedCallback(base::Bind(
+      &ApManagerClient::OnServiceAdded, weak_ptr_factory_.GetWeakPtr()));
+
+  object_manager_proxy_->SetServiceRemovedCallback(base::Bind(
+      &ApManagerClient::OnServiceRemoved, weak_ptr_factory_.GetWeakPtr()));
+  object_manager_proxy_->SetManagerRemovedCallback(base::Bind(
+      &ApManagerClient::OnManagerRemoved, weak_ptr_factory_.GetWeakPtr()));
+}
+
+void ApManagerClient::Stop() {
+  if (manager_proxy_ && service_path_.IsValid()) {
+    RemoveService(service_path_);
+  }
+  service_path_ = dbus::ObjectPath();
+  service_proxy_ = nullptr;
+  manager_proxy_ = nullptr;
+  object_manager_proxy_.reset();
+  ssid_.clear();
+}
+
+void ApManagerClient::RemoveService(const dbus::ObjectPath& object_path) {
+  CHECK(object_path.IsValid());
+  chromeos::ErrorPtr error;
+  if (!manager_proxy_->RemoveService(object_path, &error)) {
+    LOG(ERROR) << "RemoveService failed: " << error->GetMessage();
+  }
+}
+
+void ApManagerClient::OnManagerAdded(ManagerProxy* manager_proxy) {
+  VLOG(1) << "manager added: " << manager_proxy->GetObjectPath().value();
+  manager_proxy_ = manager_proxy;
+
+  if (service_path_.IsValid())
+    return;
+
+  chromeos::ErrorPtr error;
+  if (!manager_proxy_->CreateService(&service_path_, &error)) {
+    LOG(ERROR) << "CreateService failed: " << error->GetMessage();
+  }
+}
+
+void ApManagerClient::OnServiceAdded(ServiceProxy* service_proxy) {
+  VLOG(1) << "service added: " << service_proxy->GetObjectPath().value();
+  if (service_proxy->GetObjectPath() != service_path_) {
+    RemoveService(service_proxy->GetObjectPath());
+    return;
+  }
+  service_proxy_ = service_proxy;
+
+  ConfigProxy* config_proxy =
+      object_manager_proxy_->GetConfigProxy(service_proxy->config());
+  ConfigProxy::PropertySet* properties = config_proxy->GetProperties();
+  properties->ssid.Set(ssid_, base::Bind(&ApManagerClient::OnSsidSet,
+                                         weak_ptr_factory_.GetWeakPtr()));
+}
+
+void ApManagerClient::OnSsidSet(bool success) {
+  if (!success || !service_proxy_) {
+    LOG(ERROR) << "Failed to set ssid.";
+    return;
+  }
+  VLOG(1) << "SSID is set: " << ssid_;
+
+  chromeos::ErrorPtr error;
+  if (!service_proxy_->Start(&error)) {
+    LOG(ERROR) << "Service start failed: " << error->GetMessage();
+  }
+}
+
+void ApManagerClient::OnServiceRemoved(const dbus::ObjectPath& object_path) {
+  VLOG(1) << "service removed: " << object_path.value();
+  if (object_path != service_path_)
+    return;
+  service_path_ = dbus::ObjectPath();
+  service_proxy_ = nullptr;
+}
+
+void ApManagerClient::OnManagerRemoved(const dbus::ObjectPath& object_path) {
+  VLOG(1) << "manager removed: " << object_path.value();
+  manager_proxy_ = nullptr;
+  Stop();
+}
+
+}  // namespace privetd
diff --git a/buffet/privet/ap_manager_client.h b/buffet/privet/ap_manager_client.h
new file mode 100644
index 0000000..ec99a6a
--- /dev/null
+++ b/buffet/privet/ap_manager_client.h
@@ -0,0 +1,57 @@
+// Copyright 2014 The Chromium OS 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 BUFFET_PRIVET_AP_MANAGER_CLIENT_H_
+#define BUFFET_PRIVET_AP_MANAGER_CLIENT_H_
+
+#include <memory>
+#include <string>
+
+#include <base/callback.h>
+#include <base/memory/ref_counted.h>
+
+#include "apmanager/dbus-proxies.h"
+
+namespace privetd {
+
+// Manages soft AP for wifi bootstrapping.
+// Once created can handle multiple Start/Stop requests.
+class ApManagerClient final {
+ public:
+  explicit ApManagerClient(const scoped_refptr<dbus::Bus>& bus);
+  ~ApManagerClient();
+
+  void Start(const std::string& ssid);
+  void Stop();
+
+  std::string GetSsid() const { return ssid_; }
+
+ private:
+  void RemoveService(const dbus::ObjectPath& object_path);
+
+  void OnManagerAdded(org::chromium::apmanager::ManagerProxy* manager_proxy);
+  void OnServiceAdded(org::chromium::apmanager::ServiceProxy* service_proxy);
+
+  void OnSsidSet(bool success);
+
+  void OnServiceRemoved(const dbus::ObjectPath& object_path);
+  void OnManagerRemoved(const dbus::ObjectPath& object_path);
+
+  scoped_refptr<dbus::Bus> bus_;
+
+  std::unique_ptr<org::chromium::apmanager::ObjectManagerProxy>
+      object_manager_proxy_;
+  org::chromium::apmanager::ManagerProxy* manager_proxy_{nullptr};
+
+  dbus::ObjectPath service_path_;
+  org::chromium::apmanager::ServiceProxy* service_proxy_{nullptr};
+
+  std::string ssid_;
+
+  base::WeakPtrFactory<ApManagerClient> weak_ptr_factory_{this};
+};
+
+}  // namespace privetd
+
+#endif  // BUFFET_PRIVET_AP_MANAGER_CLIENT_H_
diff --git a/buffet/privet/cloud_delegate.cc b/buffet/privet/cloud_delegate.cc
new file mode 100644
index 0000000..5de432e
--- /dev/null
+++ b/buffet/privet/cloud_delegate.cc
@@ -0,0 +1,532 @@
+// Copyright 2014 The Chromium OS 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 "buffet/privet/cloud_delegate.h"
+
+#include <map>
+#include <vector>
+
+#include <base/bind.h>
+#include <base/json/json_reader.h>
+#include <base/json/json_writer.h>
+#include <base/logging.h>
+#include <base/memory/weak_ptr.h>
+#include <base/message_loop/message_loop.h>
+#include <base/values.h>
+#include <chromeos/errors/error.h>
+#include <chromeos/variant_dictionary.h>
+#include <dbus/bus.h>
+
+#include "buffet/dbus-proxies.h"
+#include "buffet/privet/constants.h"
+
+namespace privetd {
+
+namespace {
+
+using chromeos::ErrorPtr;
+using chromeos::VariantDictionary;
+using org::chromium::Buffet::ManagerProxy;
+using org::chromium::Buffet::ObjectManagerProxy;
+
+const int kMaxSetupRetries = 5;
+const int kFirstRetryTimeoutSec = 1;
+
+class CloudDelegateImpl : public CloudDelegate {
+ public:
+  CloudDelegateImpl(const scoped_refptr<dbus::Bus>& bus,
+                    bool is_gcd_setup_enabled)
+      : object_manager_{bus}, is_gcd_setup_enabled_(is_gcd_setup_enabled) {
+    object_manager_.SetManagerAddedCallback(
+        base::Bind(&CloudDelegateImpl::OnManagerAdded,
+                   weak_factory_.GetWeakPtr()));
+    object_manager_.SetManagerRemovedCallback(
+        base::Bind(&CloudDelegateImpl::OnManagerRemoved,
+                   weak_factory_.GetWeakPtr()));
+    object_manager_.SetCommandRemovedCallback(base::Bind(
+        &CloudDelegateImpl::OnCommandRemoved, weak_factory_.GetWeakPtr()));
+  }
+
+  ~CloudDelegateImpl() override = default;
+
+  bool GetModelId(std::string* id, chromeos::ErrorPtr* error) const override {
+    if (!IsManagerReady(error))
+      return false;
+    if (manager_->model_id().size() != 5) {
+      chromeos::Error::AddToPrintf(
+          error, FROM_HERE, errors::kDomain, errors::kInvalidState,
+          "Model ID is invalid: %s", manager_->model_id().c_str());
+      return false;
+    }
+    *id = manager_->model_id();
+    return true;
+  }
+
+  bool GetName(std::string* name, chromeos::ErrorPtr* error) const override {
+    if (!IsManagerReady(error))
+      return false;
+    *name = manager_->name();
+    return true;
+  }
+
+  std::string GetDescription() const override {
+    return manager_ ? manager_->description() : std::string{};
+  }
+
+  std::string GetLocation() const override {
+    return manager_ ? manager_->location() : std::string{};
+  }
+
+  void UpdateDeviceInfo(const std::string& name,
+                        const std::string& description,
+                        const std::string& location,
+                        const base::Closure& success_callback,
+                        const ErrorCallback& error_callback) override {
+    chromeos::ErrorPtr error;
+    if (!IsManagerReady(&error))
+      return error_callback.Run(error.get());
+
+    if (name == manager_->name() && description == manager_->description() &&
+        location == manager_->location()) {
+      return success_callback.Run();
+    }
+
+    manager_->UpdateDeviceInfoAsync(name, description, location,
+                                    success_callback, error_callback);
+  }
+
+  std::string GetOemName() const override {
+    return manager_ ? manager_->oem_name() : std::string{};
+  }
+
+  std::string GetModelName() const override {
+    return manager_ ? manager_->model_name() : std::string{};
+  }
+
+  std::set<std::string> GetServices() const override {
+    std::set<std::string> result;
+    for (base::DictionaryValue::Iterator it{command_defs_}; !it.IsAtEnd();
+         it.Advance()) {
+      result.emplace(it.key());
+    }
+    return result;
+  }
+
+  AuthScope GetAnonymousMaxScope() const override {
+    if (manager_) {
+      AuthScope scope;
+      if (StringToAuthScope(manager_->anonymous_access_role(), &scope))
+        return scope;
+    }
+    return AuthScope::kNone;
+  }
+
+  const ConnectionState& GetConnectionState() const override {
+    return connection_state_;
+  }
+
+  const SetupState& GetSetupState() const override { return setup_state_; }
+
+  bool Setup(const std::string& ticket_id,
+             const std::string& user,
+             chromeos::ErrorPtr* error) override {
+    if (!is_gcd_setup_enabled_) {
+      chromeos::Error::AddTo(error, FROM_HERE, errors::kDomain,
+                             errors::kSetupUnavailable,
+                             "GCD setup unavailible");
+      return false;
+    }
+    if (!object_manager_.GetManagerProxy()) {
+      chromeos::Error::AddTo(error, FROM_HERE, errors::kDomain,
+                             errors::kDeviceBusy, "Buffet is not ready");
+      return false;
+    }
+    if (setup_state_.IsStatusEqual(SetupState::kInProgress)) {
+      chromeos::Error::AddTo(error, FROM_HERE, errors::kDomain,
+                             errors::kDeviceBusy, "Setup in progress");
+      return false;
+    }
+    VLOG(1) << "GCD Setup started. ticket_id: " << ticket_id
+            << ", user:" << user;
+    setup_state_ = SetupState(SetupState::kInProgress);
+    setup_weak_factory_.InvalidateWeakPtrs();
+    base::MessageLoop::current()->PostDelayedTask(
+        FROM_HERE, base::Bind(&CloudDelegateImpl::CallManagerRegisterDevice,
+                              setup_weak_factory_.GetWeakPtr(), ticket_id, 0),
+        base::TimeDelta::FromSeconds(kSetupDelaySeconds));
+    // Return true because we tried setup.
+    return true;
+  }
+
+  std::string GetCloudId() const override {
+    return manager_ ? manager_->device_id() : std::string{};
+  }
+
+  const base::DictionaryValue& GetState() const override { return state_; }
+
+  const base::DictionaryValue& GetCommandDef() const override {
+    return command_defs_;
+  }
+
+  void AddCommand(const base::DictionaryValue& command,
+                  const UserInfo& user_info,
+                  const SuccessCallback& success_callback,
+                  const ErrorCallback& error_callback) override {
+    CHECK(user_info.scope() != AuthScope::kNone);
+
+    chromeos::ErrorPtr error;
+    if (!IsManagerReady(&error))
+      return error_callback.Run(error.get());
+
+    std::string command_str;
+    base::JSONWriter::Write(&command, &command_str);
+    manager_->AddCommandAsync(
+        command_str, AuthScopeToString(user_info.scope()),
+        base::Bind(&CloudDelegateImpl::OnAddCommandSucceeded,
+                   weak_factory_.GetWeakPtr(), success_callback,
+                   error_callback),
+        error_callback);
+  }
+
+  void GetCommand(const std::string& id,
+                  const UserInfo& user_info,
+                  const SuccessCallback& success_callback,
+                  const ErrorCallback& error_callback) override {
+    CHECK(user_info.scope() != AuthScope::kNone);
+    chromeos::ErrorPtr error;
+    if (!CanAccessCommand(id, user_info)) {
+      chromeos::Error::AddTo(&error, FROM_HERE, errors::kDomain,
+                             errors::kAccessDenied,
+                             "Need to be owner of the command.");
+      return error_callback.Run(error.get());
+    }
+
+    GetCommandInternal(id, success_callback, error_callback);
+  }
+
+  void CancelCommand(const std::string& id,
+                     const UserInfo& user_info,
+                     const SuccessCallback& success_callback,
+                     const ErrorCallback& error_callback) override {
+    CHECK(user_info.scope() != AuthScope::kNone);
+    chromeos::ErrorPtr error;
+    if (!CanAccessCommand(id, user_info)) {
+      chromeos::Error::AddTo(&error, FROM_HERE, errors::kDomain,
+                             errors::kAccessDenied,
+                             "Need to be owner of the command.");
+      return error_callback.Run(error.get());
+    }
+
+    for (auto command : object_manager_.GetCommandInstances()) {
+      if (command->id() == id) {
+        return command->CancelAsync(
+            base::Bind(&CloudDelegateImpl::GetCommandInternal,
+                       weak_factory_.GetWeakPtr(), id, success_callback,
+                       error_callback),
+            error_callback);
+      }
+    }
+
+    chromeos::Error::AddToPrintf(&error, FROM_HERE, errors::kDomain,
+                                 errors::kNotFound,
+                                 "Command not found, ID='%s'", id.c_str());
+    error_callback.Run(error.get());
+  }
+
+  void ListCommands(const UserInfo& user_info,
+                    const SuccessCallback& success_callback,
+                    const ErrorCallback& error_callback) override {
+    CHECK(user_info.scope() != AuthScope::kNone);
+
+    std::vector<org::chromium::Buffet::CommandProxy*> commands{
+        object_manager_.GetCommandInstances()};
+
+    auto ids = std::make_shared<std::vector<std::string>>();
+    for (auto command : commands) {
+      if (CanAccessCommand(command->id(), user_info))
+        ids->push_back(command->id());
+    }
+
+    GetNextCommand(ids, std::make_shared<base::ListValue>(), success_callback,
+                   error_callback, base::DictionaryValue{});
+  }
+
+ private:
+  void GetCommandInternal(const std::string& id,
+                          const SuccessCallback& success_callback,
+                          const ErrorCallback& error_callback) {
+    chromeos::ErrorPtr error;
+    if (!IsManagerReady(&error))
+      return error_callback.Run(error.get());
+    manager_->GetCommandAsync(
+        id, base::Bind(&CloudDelegateImpl::OnGetCommandSucceeded,
+                       weak_factory_.GetWeakPtr(), success_callback,
+                       error_callback),
+        error_callback);
+  }
+
+  void OnManagerAdded(ManagerProxy* manager) {
+    manager_ = manager;
+    manager_->SetPropertyChangedCallback(
+        base::Bind(&CloudDelegateImpl::OnManagerPropertyChanged,
+                   weak_factory_.GetWeakPtr()));
+    // Read all initial values.
+    OnManagerPropertyChanged(manager, std::string{});
+  }
+
+  void OnCommandRemoved(const dbus::ObjectPath& object_path) {
+    command_owners_.erase(object_manager_.GetCommandProxy(object_path)->id());
+  }
+
+  void OnManagerPropertyChanged(ManagerProxy* manager,
+                                const std::string& property_name) {
+    CHECK_EQ(manager_, manager);
+
+    if (property_name.empty() || property_name == ManagerProxy::StatusName()) {
+      OnStatusPropertyChanged();
+    }
+
+    if (property_name.empty() ||
+        property_name == ManagerProxy::DeviceIdName() ||
+        property_name == ManagerProxy::OemNameName() ||
+        property_name == ManagerProxy::ModelNameName() ||
+        property_name == ManagerProxy::ModelIdName() ||
+        property_name == ManagerProxy::NameName() ||
+        property_name == ManagerProxy::DescriptionName() ||
+        property_name == ManagerProxy::LocationName() ||
+        property_name == ManagerProxy::AnonymousAccessRoleName()) {
+      NotifyOnDeviceInfoChanged();
+    }
+
+    if (property_name.empty() || property_name == ManagerProxy::StateName()) {
+      OnStatePropertyChanged();
+    }
+
+    if (property_name.empty() ||
+        property_name == ManagerProxy::CommandDefsName()) {
+      OnCommandDefsPropertyChanged();
+    }
+  }
+
+  void OnStatusPropertyChanged() {
+    const std::string& status = manager_->status();
+    if (status == "unconfigured") {
+      connection_state_ = ConnectionState{ConnectionState::kUnconfigured};
+    } else if (status == "connecting") {
+      // TODO(vitalybuka): Find conditions for kOffline.
+      connection_state_ = ConnectionState{ConnectionState::kConnecting};
+    } else if (status == "connected") {
+      connection_state_ = ConnectionState{ConnectionState::kOnline};
+    } else {
+      chromeos::ErrorPtr error;
+      chromeos::Error::AddToPrintf(
+          &error, FROM_HERE, errors::kDomain, errors::kInvalidState,
+          "Unexpected buffet status: %s", status.c_str());
+      connection_state_ = ConnectionState{std::move(error)};
+    }
+    NotifyOnDeviceInfoChanged();
+  }
+
+  void OnStatePropertyChanged() {
+    state_.Clear();
+    std::unique_ptr<base::Value> value{
+        base::JSONReader::Read(manager_->state())};
+    const base::DictionaryValue* state{nullptr};
+    if (value && value->GetAsDictionary(&state))
+      state_.MergeDictionary(state);
+    NotifyOnStateChanged();
+  }
+
+  void OnCommandDefsPropertyChanged() {
+    command_defs_.Clear();
+    std::unique_ptr<base::Value> value{
+        base::JSONReader::Read(manager_->command_defs())};
+    const base::DictionaryValue* defs{nullptr};
+    if (value && value->GetAsDictionary(&defs))
+      command_defs_.MergeDictionary(defs);
+    NotifyOnCommandDefsChanged();
+  }
+
+  void OnManagerRemoved(const dbus::ObjectPath& path) {
+    manager_ = nullptr;
+    connection_state_ = ConnectionState(ConnectionState::kDisabled);
+    state_.Clear();
+    command_defs_.Clear();
+    command_owners_.clear();
+    NotifyOnDeviceInfoChanged();
+    NotifyOnCommandDefsChanged();
+    NotifyOnStateChanged();
+  }
+
+  void RetryRegister(const std::string& ticket_id,
+                     int retries,
+                     chromeos::Error* error) {
+    if (retries >= kMaxSetupRetries) {
+      chromeos::ErrorPtr new_error{error ? error->Clone() : nullptr};
+      chromeos::Error::AddTo(&new_error, FROM_HERE, errors::kDomain,
+                             errors::kInvalidState,
+                             "Failed to register device");
+      setup_state_ = SetupState{std::move(new_error)};
+      return;
+    }
+    base::MessageLoop::current()->PostDelayedTask(
+        FROM_HERE,
+        base::Bind(&CloudDelegateImpl::CallManagerRegisterDevice,
+                   setup_weak_factory_.GetWeakPtr(), ticket_id, retries + 1),
+        base::TimeDelta::FromSeconds(kFirstRetryTimeoutSec << retries));
+  }
+
+  void OnRegisterSuccess(const std::string& device_id) {
+    VLOG(1) << "Device registered: " << device_id;
+    setup_state_ = SetupState(SetupState::kSuccess);
+  }
+
+  void CallManagerRegisterDevice(const std::string& ticket_id, int retries) {
+    auto manager_proxy = object_manager_.GetManagerProxy();
+    if (!manager_proxy) {
+      LOG(ERROR) << "Couldn't register because Buffet was offline.";
+      RetryRegister(ticket_id, retries, nullptr);
+      return;
+    }
+    manager_proxy->RegisterDeviceAsync(
+        ticket_id, base::Bind(&CloudDelegateImpl::OnRegisterSuccess,
+                              setup_weak_factory_.GetWeakPtr()),
+        base::Bind(&CloudDelegateImpl::RetryRegister,
+                   setup_weak_factory_.GetWeakPtr(), ticket_id, retries));
+  }
+
+  void OnAddCommandSucceeded(const SuccessCallback& success_callback,
+                             const ErrorCallback& error_callback,
+                             const std::string& id) {
+    GetCommandInternal(id, success_callback, error_callback);
+  }
+
+  void OnGetCommandSucceeded(const SuccessCallback& success_callback,
+                             const ErrorCallback& error_callback,
+                             const std::string& json_command) {
+    std::unique_ptr<base::Value> value{base::JSONReader::Read(json_command)};
+    base::DictionaryValue* command{nullptr};
+    if (!value || !value->GetAsDictionary(&command)) {
+      chromeos::ErrorPtr error;
+      chromeos::Error::AddTo(&error, FROM_HERE, errors::kDomain,
+                             errors::kInvalidFormat,
+                             "Buffet returned invalid JSON");
+      return error_callback.Run(error.get());
+    }
+    success_callback.Run(*command);
+  }
+
+  void GetNextCommandSkipError(
+      const std::shared_ptr<std::vector<std::string>>& ids,
+      const std::shared_ptr<base::ListValue>& commands,
+      const SuccessCallback& success_callback,
+      const ErrorCallback& error_callback,
+      chromeos::Error*) {
+    // Ignore if we can't get some commands. Maybe they were removed.
+    GetNextCommand(ids, commands, success_callback, error_callback,
+                   base::DictionaryValue{});
+  }
+
+  void GetNextCommand(const std::shared_ptr<std::vector<std::string>>& ids,
+                      const std::shared_ptr<base::ListValue>& commands,
+                      const SuccessCallback& success_callback,
+                      const ErrorCallback& error_callback,
+                      const base::DictionaryValue& json) {
+    if (!json.empty())
+      commands->Append(json.DeepCopy());
+
+    if (ids->empty()) {
+      base::DictionaryValue commands_json;
+      commands_json.Set("commands", commands->DeepCopy());
+      return success_callback.Run(commands_json);
+    }
+
+    std::string next_id = ids->back();
+    ids->pop_back();
+
+    auto on_success = base::Bind(&CloudDelegateImpl::GetNextCommand,
+                                 weak_factory_.GetWeakPtr(), ids, commands,
+                                 success_callback, error_callback);
+
+    auto on_error = base::Bind(&CloudDelegateImpl::GetNextCommandSkipError,
+                               weak_factory_.GetWeakPtr(), ids, commands,
+                               success_callback, error_callback);
+
+    GetCommandInternal(next_id, on_success, on_error);
+  }
+
+  bool IsManagerReady(chromeos::ErrorPtr* error) const {
+    if (!manager_) {
+      chromeos::Error::AddTo(error, FROM_HERE, errors::kDomain,
+                             errors::kDeviceBusy, "Buffet is not ready");
+      return false;
+    }
+    return true;
+  }
+
+  bool CanAccessCommand(const std::string& command_id,
+                        const UserInfo& user_info) const {
+    if (user_info.scope() == AuthScope::kOwner)
+      return true;
+    auto it = command_owners_.find(command_id);
+    return it != command_owners_.end() && it->second == user_info.user_id();
+  }
+
+  ObjectManagerProxy object_manager_;
+
+  bool is_gcd_setup_enabled_{false};
+
+  ManagerProxy* manager_{nullptr};
+
+  // Primary state of GCD.
+  ConnectionState connection_state_{ConnectionState::kDisabled};
+
+  // State of the current or last setup.
+  SetupState setup_state_{SetupState::kNone};
+
+  // Current device state.
+  base::DictionaryValue state_;
+
+  // Current commands definitions.
+  base::DictionaryValue command_defs_;
+
+  // Map of command IDs to user IDs.
+  std::map<std::string, uint64_t> command_owners_;
+
+  // |setup_weak_factory_| tracks the lifetime of callbacks used in connection
+  // with a particular invocation of Setup().
+  base::WeakPtrFactory<CloudDelegateImpl> setup_weak_factory_{this};
+  // |weak_factory_| tracks the lifetime of |this|.
+  base::WeakPtrFactory<CloudDelegateImpl> weak_factory_{this};
+};
+
+}  // namespace
+
+CloudDelegate::CloudDelegate() {
+}
+
+CloudDelegate::~CloudDelegate() {
+}
+
+// static
+std::unique_ptr<CloudDelegate> CloudDelegate::CreateDefault(
+    const scoped_refptr<dbus::Bus>& bus,
+    bool is_gcd_setup_enabled) {
+  return std::unique_ptr<CloudDelegateImpl>{
+      new CloudDelegateImpl{bus, is_gcd_setup_enabled}};
+}
+
+void CloudDelegate::NotifyOnDeviceInfoChanged() {
+  FOR_EACH_OBSERVER(Observer, observer_list_, OnDeviceInfoChanged());
+}
+
+void CloudDelegate::NotifyOnCommandDefsChanged() {
+  FOR_EACH_OBSERVER(Observer, observer_list_, OnCommandDefsChanged());
+}
+
+void CloudDelegate::NotifyOnStateChanged() {
+  FOR_EACH_OBSERVER(Observer, observer_list_, OnStateChanged());
+}
+
+}  // namespace privetd
diff --git a/buffet/privet/cloud_delegate.h b/buffet/privet/cloud_delegate.h
new file mode 100644
index 0000000..0d027f9
--- /dev/null
+++ b/buffet/privet/cloud_delegate.h
@@ -0,0 +1,143 @@
+// Copyright 2014 The Chromium OS 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 BUFFET_PRIVET_CLOUD_DELEGATE_H_
+#define BUFFET_PRIVET_CLOUD_DELEGATE_H_
+
+#include <memory>
+#include <set>
+#include <string>
+
+#include <base/callback.h>
+#include <base/memory/ref_counted.h>
+#include <base/observer_list.h>
+
+#include "buffet/privet/privet_types.h"
+#include "buffet/privet/security_delegate.h"
+
+namespace base {
+class DictionaryValue;
+}  // namespace base
+
+namespace dbus {
+class Bus;
+}  // namespace dbus
+
+namespace privetd {
+
+// Interface to provide GCD functionality for PrivetHandler.
+// TODO(vitalybuka): Rename to BuffetDelegate.
+class CloudDelegate {
+ public:
+  CloudDelegate();
+  virtual ~CloudDelegate();
+
+  using SuccessCallback = base::Callback<void(const base::DictionaryValue&)>;
+  using ErrorCallback = base::Callback<void(chromeos::Error*)>;
+
+  class Observer {
+   public:
+    virtual ~Observer() = default;
+
+    virtual void OnDeviceInfoChanged() {}
+    virtual void OnCommandDefsChanged() {}
+    virtual void OnStateChanged() {}
+  };
+
+  // Returns the model ID of the device.
+  virtual bool GetModelId(std::string* id, chromeos::ErrorPtr* error) const = 0;
+
+  // Returns the name of device.
+  virtual bool GetName(std::string* name, chromeos::ErrorPtr* error) const = 0;
+
+  // Returns the description of the device.
+  virtual std::string GetDescription() const = 0;
+
+  // Returns the location of the device.
+  virtual std::string GetLocation() const = 0;
+
+  // Update basic device information.
+  virtual void UpdateDeviceInfo(const std::string& name,
+                                const std::string& description,
+                                const std::string& location,
+                                const base::Closure& success_callback,
+                                const ErrorCallback& error_callback) = 0;
+
+  // Returns the name of the maker.
+  virtual std::string GetOemName() const = 0;
+
+  // Returns the model name of the device.
+  virtual std::string GetModelName() const = 0;
+
+  // Returns the list of services supported by device.
+  // E.g. printer, scanner etc. Should match services published on mDNS.
+  virtual std::set<std::string> GetServices() const = 0;
+
+  // Returns max scope available for anonymous user.
+  virtual AuthScope GetAnonymousMaxScope() const = 0;
+
+  // Returns status of the GCD connection.
+  virtual const ConnectionState& GetConnectionState() const = 0;
+
+  // Returns status of the last setup.
+  virtual const SetupState& GetSetupState() const = 0;
+
+  // Starts GCD setup.
+  virtual bool Setup(const std::string& ticket_id,
+                     const std::string& user,
+                     chromeos::ErrorPtr* error) = 0;
+
+  // Returns cloud id if the registered device or empty string if unregistered.
+  virtual std::string GetCloudId() const = 0;
+
+  // Returns dictionary with device state.
+  virtual const base::DictionaryValue& GetState() const = 0;
+
+  // Returns dictionary with commands definitions.
+  virtual const base::DictionaryValue& GetCommandDef() const = 0;
+
+  // Adds command created from the given JSON representation.
+  virtual void AddCommand(const base::DictionaryValue& command,
+                          const UserInfo& user_info,
+                          const SuccessCallback& success_callback,
+                          const ErrorCallback& error_callback) = 0;
+
+  // Returns command with the given ID.
+  virtual void GetCommand(const std::string& id,
+                          const UserInfo& user_info,
+                          const SuccessCallback& success_callback,
+                          const ErrorCallback& error_callback) = 0;
+
+  // Cancels command with the given ID.
+  virtual void CancelCommand(const std::string& id,
+                             const UserInfo& user_info,
+                             const SuccessCallback& success_callback,
+                             const ErrorCallback& error_callback) = 0;
+
+  // Lists commands.
+  virtual void ListCommands(const UserInfo& user_info,
+                            const SuccessCallback& success_callback,
+                            const ErrorCallback& error_callback) = 0;
+
+  void AddObserver(Observer* observer) { observer_list_.AddObserver(observer); }
+  void RemoveObserver(Observer* observer) {
+    observer_list_.RemoveObserver(observer);
+  }
+
+  void NotifyOnDeviceInfoChanged();
+  void NotifyOnCommandDefsChanged();
+  void NotifyOnStateChanged();
+
+  // Create default instance.
+  static std::unique_ptr<CloudDelegate> CreateDefault(
+      const scoped_refptr<dbus::Bus>& bus,
+      bool is_gcd_setup_enabled);
+
+ private:
+  ObserverList<Observer> observer_list_;
+};
+
+}  // namespace privetd
+
+#endif  // BUFFET_PRIVET_CLOUD_DELEGATE_H_
diff --git a/buffet/privet/constants.cc b/buffet/privet/constants.cc
new file mode 100644
index 0000000..e94b541
--- /dev/null
+++ b/buffet/privet/constants.cc
@@ -0,0 +1,36 @@
+// Copyright 2014 The Chromium OS 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 "buffet/privet/constants.h"
+
+namespace privetd {
+
+namespace errors {
+
+const char kDomain[] = "privetd";
+
+const char kInvalidClientCommitment[] = "invalidClientCommitment";
+const char kInvalidFormat[] = "invalidFormat";
+const char kMissingAuthorization[] = "missingAuthorization";
+const char kInvalidAuthorization[] = "invalidAuthorization";
+const char kInvalidAuthorizationScope[] = "invalidAuthorizationScope";
+const char kAuthorizationExpired[] = "authorizationExpired";
+const char kCommitmentMismatch[] = "commitmentMismatch";
+const char kUnknownSession[] = "unknownSession";
+const char kInvalidAuthCode[] = "invalidAuthCode";
+const char kInvalidAuthMode[] = "invalidAuthMode";
+const char kInvalidRequestedScope[] = "invalidRequestedScope";
+const char kAccessDenied[] = "accessDenied";
+const char kInvalidParams[] = "invalidParams";
+const char kSetupUnavailable[] = "setupUnavailable";
+const char kDeviceBusy[] = "deviceBusy";
+const char kInvalidState[] = "invalidState";
+const char kInvalidSsid[] = "invalidSsid";
+const char kInvalidPassphrase[] = "invalidPassphrase";
+const char kNotFound[] = "notFound";
+const char kNotImplemented[] = "notImplemented";
+
+}  // namespace errors
+
+}  // namespace privetd
diff --git a/buffet/privet/constants.h b/buffet/privet/constants.h
new file mode 100644
index 0000000..c408ca1
--- /dev/null
+++ b/buffet/privet/constants.h
@@ -0,0 +1,41 @@
+// Copyright 2014 The Chromium OS 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 BUFFET_PRIVET_CONSTANTS_H_
+#define BUFFET_PRIVET_CONSTANTS_H_
+
+namespace privetd {
+
+namespace errors {
+
+extern const char kDomain[];
+
+extern const char kInvalidClientCommitment[];
+extern const char kInvalidFormat[];
+extern const char kMissingAuthorization[];
+extern const char kInvalidAuthorization[];
+extern const char kInvalidAuthorizationScope[];
+extern const char kAuthorizationExpired[];
+extern const char kCommitmentMismatch[];
+extern const char kUnknownSession[];
+extern const char kInvalidAuthCode[];
+extern const char kInvalidAuthMode[];
+extern const char kInvalidRequestedScope[];
+extern const char kAccessDenied[];
+extern const char kInvalidParams[];
+extern const char kSetupUnavailable[];
+extern const char kDeviceBusy[];
+extern const char kInvalidState[];
+extern const char kInvalidSsid[];
+extern const char kInvalidPassphrase[];
+extern const char kNotFound[];
+extern const char kNotImplemented[];
+}  // namespace errors
+
+// Time to reply on privet HTTP.
+const int kSetupDelaySeconds = 1;
+
+}  // namespace privetd
+
+#endif  // BUFFET_PRIVET_CONSTANTS_H_
diff --git a/buffet/privet/daemon_state.cc b/buffet/privet/daemon_state.cc
new file mode 100644
index 0000000..cdbe808
--- /dev/null
+++ b/buffet/privet/daemon_state.cc
@@ -0,0 +1,33 @@
+// Copyright 2014 The Chromium OS 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 "buffet/privet/daemon_state.h"
+
+namespace privetd {
+
+namespace state_key {
+
+const char kDeviceId[] = "id";
+const char kDeviceName[] = "name";
+const char kDeviceDescription[] = "description";
+const char kDeviceLocation[] = "description";
+
+const char kWifiHasBeenBootstrapped[] = "have_ever_been_bootstrapped";
+const char kWifiLastConfiguredSSID[] = "last_configured_ssid";
+
+}  // namespace state_key
+
+DaemonState::DaemonState(const base::FilePath& state_path)
+    : state_path_(state_path) {
+}
+
+void DaemonState::Init() {
+  Load(state_path_);
+}
+
+void DaemonState::Save() const {
+  KeyValueStore::Save(state_path_);
+}
+
+}  // namespace privetd
diff --git a/buffet/privet/daemon_state.h b/buffet/privet/daemon_state.h
new file mode 100644
index 0000000..a2d7616
--- /dev/null
+++ b/buffet/privet/daemon_state.h
@@ -0,0 +1,42 @@
+// Copyright 2014 The Chromium OS 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 BUFFET_PRIVET_DAEMON_STATE_H_
+#define BUFFET_PRIVET_DAEMON_STATE_H_
+
+#include <base/files/file_path.h>
+#include <base/macros.h>
+#include <chromeos/key_value_store.h>
+
+namespace privetd {
+
+namespace state_key {
+
+extern const char kDeviceId[];
+extern const char kDeviceName[];
+extern const char kDeviceDescription[];
+extern const char kDeviceLocation[];
+
+extern const char kWifiHasBeenBootstrapped[];
+extern const char kWifiLastConfiguredSSID[];
+
+}  // namespace state_key
+
+class DaemonState : public chromeos::KeyValueStore {
+ public:
+  explicit DaemonState(const base::FilePath& state_path);
+  // Load initial state from disk.
+  void Init();
+  // Save state to disk.
+  void Save() const;
+
+ private:
+  const base::FilePath state_path_;
+
+  DISALLOW_COPY_AND_ASSIGN(DaemonState);
+};
+
+}  // namespace privetd
+
+#endif  // BUFFET_PRIVET_DAEMON_STATE_H_
diff --git a/buffet/privet/dbus_manager.cc b/buffet/privet/dbus_manager.cc
new file mode 100644
index 0000000..a336a19
--- /dev/null
+++ b/buffet/privet/dbus_manager.cc
@@ -0,0 +1,140 @@
+// Copyright 2015 The Chromium OS 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 "buffet/privet/dbus_manager.h"
+
+#include <base/memory/ref_counted.h>
+#include <chromeos/any.h>
+
+#include "buffet/privet/constants.h"
+#include "buffet/privet/security_delegate.h"
+#include "buffet/privet/security_manager.h"
+
+using chromeos::Any;
+using chromeos::dbus_utils::AsyncEventSequencer;
+using chromeos::dbus_utils::DBusObject;
+using chromeos::dbus_utils::ExportedObjectManager;
+using org::chromium::privetd::ManagerAdaptor;
+
+namespace privetd {
+
+namespace {
+
+const char kPingResponse[] = "Hello world!";
+const char kPairingSessionIdKey[] = "sessionId";
+const char kPairingModeKey[] = "mode";
+const char kPairingCodeKey[] = "code";
+
+}  // namespace
+
+DBusManager::DBusManager(ExportedObjectManager* object_manager,
+                         WifiBootstrapManager* wifi_bootstrap_manager,
+                         CloudDelegate* cloud_delegate,
+                         SecurityManager* security_manager)
+  : dbus_object_{new DBusObject{object_manager,
+                                object_manager->GetBus(),
+                                ManagerAdaptor::GetObjectPath()}} {
+  if (wifi_bootstrap_manager) {
+    wifi_bootstrap_manager->RegisterStateListener(
+        base::Bind(&DBusManager::UpdateWiFiBootstrapState,
+                   weak_ptr_factory_.GetWeakPtr()));
+  } else {
+    UpdateWiFiBootstrapState(WifiBootstrapManager::kDisabled);
+  }
+  security_manager->RegisterPairingListeners(
+      base::Bind(&DBusManager::OnPairingStart,
+                 weak_ptr_factory_.GetWeakPtr()),
+      base::Bind(&DBusManager::OnPairingEnd,
+                 weak_ptr_factory_.GetWeakPtr()));
+  // TODO(wiley) Watch for appropriate state variables from |cloud_delegate|.
+}
+
+void DBusManager::RegisterAsync(const CompletionAction& on_done) {
+  scoped_refptr<AsyncEventSequencer> sequencer(new AsyncEventSequencer());
+  dbus_adaptor_.RegisterWithDBusObject(dbus_object_.get());
+  dbus_object_->RegisterAsync(
+      sequencer->GetHandler("Failed exporting DBusManager.", true));
+  sequencer->OnAllTasksCompletedCall({on_done});
+}
+
+bool DBusManager::EnableWiFiBootstrapping(
+    chromeos::ErrorPtr* error,
+    const dbus::ObjectPath& in_listener_path,
+    const chromeos::VariantDictionary& in_options) {
+  chromeos::Error::AddTo(error, FROM_HERE, errors::kDomain,
+                         errors::kNotImplemented,
+                         "Manual WiFi bootstrapping is not implemented");
+  return false;
+}
+
+bool DBusManager::DisableWiFiBootstrapping(chromeos::ErrorPtr* error) {
+  chromeos::Error::AddTo(error, FROM_HERE, errors::kDomain,
+                         errors::kNotImplemented,
+                         "Manual WiFi bootstrapping is not implemented");
+  return false;
+}
+
+bool DBusManager::EnableGCDBootstrapping(
+    chromeos::ErrorPtr* error,
+    const dbus::ObjectPath& in_listener_path,
+    const chromeos::VariantDictionary& in_options) {
+  chromeos::Error::AddTo(error, FROM_HERE, errors::kDomain,
+                         errors::kNotImplemented,
+                         "Manual GCD bootstrapping is not implemented");
+  return false;
+}
+
+bool DBusManager::DisableGCDBootstrapping(chromeos::ErrorPtr* error) {
+  chromeos::Error::AddTo(error, FROM_HERE, errors::kDomain,
+                         errors::kNotImplemented,
+                         "Manual GCD bootstrapping is not implemented");
+  return false;
+}
+
+std::string DBusManager::Ping() {
+  return kPingResponse;
+}
+
+void DBusManager::UpdateWiFiBootstrapState(WifiBootstrapManager::State state) {
+  switch (state) {
+    case WifiBootstrapManager::kDisabled:
+      dbus_adaptor_.SetWiFiBootstrapState("disabled");
+      break;
+    case WifiBootstrapManager::kBootstrapping:
+      dbus_adaptor_.SetWiFiBootstrapState("waiting");
+      break;
+    case WifiBootstrapManager::kMonitoring:
+      dbus_adaptor_.SetWiFiBootstrapState("monitoring");
+      break;
+    case WifiBootstrapManager::kConnecting:
+      dbus_adaptor_.SetWiFiBootstrapState("connecting");
+      break;
+  }
+}
+
+void DBusManager::OnPairingStart(const std::string& session_id,
+                                 PairingType pairing_type,
+                                 const std::vector<uint8_t>& code) {
+  // For now, just overwrite the exposed PairInfo with
+  // the most recent pairing attempt.
+  dbus_adaptor_.SetPairingInfo(chromeos::VariantDictionary{
+      {kPairingSessionIdKey, session_id},
+      {kPairingModeKey, PairingTypeToString(pairing_type)},
+      {kPairingCodeKey, code},
+  });
+}
+
+void DBusManager::OnPairingEnd(const std::string& session_id) {
+  auto exposed_pairing_attempt = dbus_adaptor_.GetPairingInfo();
+  auto it = exposed_pairing_attempt.find(kPairingSessionIdKey);
+  if (it == exposed_pairing_attempt.end()) {
+    return;
+  }
+  std::string exposed_session{it->second.TryGet<std::string>()};
+  if (exposed_session == session_id) {
+    dbus_adaptor_.SetPairingInfo(chromeos::VariantDictionary{});
+  }
+}
+
+}  // namespace privetd
diff --git a/buffet/privet/dbus_manager.h b/buffet/privet/dbus_manager.h
new file mode 100644
index 0000000..03cce45
--- /dev/null
+++ b/buffet/privet/dbus_manager.h
@@ -0,0 +1,76 @@
+// Copyright 2015 The Chromium OS 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 BUFFET_PRIVET_DBUS_MANAGER_H_
+#define BUFFET_PRIVET_DBUS_MANAGER_H_
+
+#include <memory>
+#include <string>
+#include <vector>
+
+#include <base/macros.h>
+#include <chromeos/dbus/async_event_sequencer.h>
+#include <chromeos/dbus/dbus_object.h>
+#include <chromeos/errors/error.h>
+#include <chromeos/variant_dictionary.h>
+#include <dbus/object_path.h>
+
+#include "buffet/privet/org.chromium.privetd.Manager.h"
+#include "buffet/privet/wifi_bootstrap_manager.h"
+
+namespace chromeos {
+namespace dbus_utils {
+class ExportedObjectManager;
+}  // dbus_utils
+}  // chromeos
+
+namespace privetd {
+
+class CloudDelegate;
+class SecurityManager;
+enum class PairingType;
+
+// Exposes most of the privetd DBus interface.
+class DBusManager : public org::chromium::privetd::ManagerInterface {
+ public:
+  using CompletionAction =
+      chromeos::dbus_utils::AsyncEventSequencer::CompletionAction;
+
+  DBusManager(chromeos::dbus_utils::ExportedObjectManager* object_manager,
+              WifiBootstrapManager* wifi_bootstrap_manager,
+              CloudDelegate* cloud_delegate,
+              SecurityManager* security_manager);
+  ~DBusManager() override = default;
+  void RegisterAsync(const CompletionAction& on_done);
+
+  // DBus handlers
+  bool EnableWiFiBootstrapping(
+      chromeos::ErrorPtr* error,
+      const dbus::ObjectPath& in_listener_path,
+      const chromeos::VariantDictionary& in_options) override;
+  bool DisableWiFiBootstrapping(chromeos::ErrorPtr* error) override;
+  bool EnableGCDBootstrapping(
+      chromeos::ErrorPtr* error,
+      const dbus::ObjectPath& in_listener_path,
+      const chromeos::VariantDictionary& in_options) override;
+  bool DisableGCDBootstrapping(chromeos::ErrorPtr* error) override;
+  std::string Ping() override;
+
+ private:
+  void UpdateWiFiBootstrapState(WifiBootstrapManager::State state);
+  void OnPairingStart(const std::string& session_id,
+                      PairingType pairing_type,
+                      const std::vector<uint8_t>& code);
+  void OnPairingEnd(const std::string& session_id);
+
+  org::chromium::privetd::ManagerAdaptor dbus_adaptor_{this};
+  std::unique_ptr<chromeos::dbus_utils::DBusObject> dbus_object_;
+  base::WeakPtrFactory<DBusManager> weak_ptr_factory_{this};
+
+  DISALLOW_COPY_AND_ASSIGN(DBusManager);
+};
+
+}  // namespace privetd
+
+#endif  // BUFFET_PRIVET_DBUS_MANAGER_H_
diff --git a/buffet/privet/device_delegate.cc b/buffet/privet/device_delegate.cc
new file mode 100644
index 0000000..2953284
--- /dev/null
+++ b/buffet/privet/device_delegate.cc
@@ -0,0 +1,58 @@
+// Copyright 2014 The Chromium OS 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 "buffet/privet/device_delegate.h"
+
+#include <base/files/file_util.h>
+#include <base/guid.h>
+
+#include "buffet/privet/constants.h"
+
+namespace privetd {
+
+namespace {
+
+class DeviceDelegateImpl : public DeviceDelegate {
+ public:
+  DeviceDelegateImpl() = default;
+  ~DeviceDelegateImpl() override = default;
+
+  std::pair<uint16_t, uint16_t> GetHttpEnpoint() const override {
+    return std::make_pair(http_port_, http_port_);
+  }
+  std::pair<uint16_t, uint16_t> GetHttpsEnpoint() const override {
+    return std::make_pair(https_port_, https_port_);
+  }
+  base::TimeDelta GetUptime() const override {
+    return base::Time::Now() - start_time_;
+  }
+
+  void SetHttpPort(uint16_t port) override {
+    http_port_ = port;
+  }
+
+  void SetHttpsPort(uint16_t port) override {
+    https_port_ = port;
+  }
+
+ private:
+  uint16_t http_port_{0};
+  uint16_t https_port_{0};
+  base::Time start_time_{base::Time::Now()};
+};
+
+}  // namespace
+
+DeviceDelegate::DeviceDelegate() {
+}
+
+DeviceDelegate::~DeviceDelegate() {
+}
+
+// static
+std::unique_ptr<DeviceDelegate> DeviceDelegate::CreateDefault() {
+  return std::unique_ptr<DeviceDelegate>(new DeviceDelegateImpl());
+}
+
+}  // namespace privetd
diff --git a/buffet/privet/device_delegate.h b/buffet/privet/device_delegate.h
new file mode 100644
index 0000000..9888dfd
--- /dev/null
+++ b/buffet/privet/device_delegate.h
@@ -0,0 +1,45 @@
+// Copyright 2014 The Chromium OS 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 BUFFET_PRIVET_DEVICE_DELEGATE_H_
+#define BUFFET_PRIVET_DEVICE_DELEGATE_H_
+
+#include <memory>
+#include <utility>
+
+#include <base/time/time.h>
+
+namespace privetd {
+
+// Interface to provide access to general information about device.
+class DeviceDelegate {
+ public:
+  DeviceDelegate();
+  virtual ~DeviceDelegate();
+
+  // Returns HTTP ports for Privet. The first one is the primary port,
+  // the second is the port for a pooling updates requests. The second value
+  // could be 0. In this case the first port would be use for regular and for
+  // updates requests.
+  virtual std::pair<uint16_t, uint16_t> GetHttpEnpoint() const = 0;
+
+  // The same |GetHttpEnpoint| but for HTTPS.
+  virtual std::pair<uint16_t, uint16_t> GetHttpsEnpoint() const = 0;
+
+  // Returns device update.
+  virtual base::TimeDelta GetUptime() const = 0;
+
+  // Updates the HTTP port value.
+  virtual void SetHttpPort(uint16_t port) = 0;
+
+  // Updates the HTTPS port value.
+  virtual void SetHttpsPort(uint16_t port) = 0;
+
+  // Create default instance.
+  static std::unique_ptr<DeviceDelegate> CreateDefault();
+};
+
+}  // namespace privetd
+
+#endif  // BUFFET_PRIVET_DEVICE_DELEGATE_H_
diff --git a/buffet/privet/identity_delegate.h b/buffet/privet/identity_delegate.h
new file mode 100644
index 0000000..5ab97d1
--- /dev/null
+++ b/buffet/privet/identity_delegate.h
@@ -0,0 +1,24 @@
+// Copyright 2015 The Chromium OS 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 BUFFET_PRIVET_IDENTITY_DELEGATE_H_
+#define BUFFET_PRIVET_IDENTITY_DELEGATE_H_
+
+#include <string>
+
+namespace privetd {
+
+// Interface for an object that can identify ourselves.
+class IdentityDelegate {
+ public:
+  IdentityDelegate() = default;
+  virtual ~IdentityDelegate() = default;
+
+  // Returns a unique identifier for this device.
+  virtual std::string GetId() const = 0;
+};
+
+}  // namespace privetd
+
+#endif  // BUFFET_PRIVET_IDENTITY_DELEGATE_H_
diff --git a/buffet/privet/main.cc b/buffet/privet/main.cc
new file mode 100644
index 0000000..a590776
--- /dev/null
+++ b/buffet/privet/main.cc
@@ -0,0 +1,311 @@
+// Copyright 2014 The Chromium OS 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 <memory>
+#include <set>
+#include <string>
+#include <sysexits.h>
+
+#include <base/bind.h>
+#include <base/command_line.h>
+#include <base/json/json_reader.h>
+#include <base/memory/weak_ptr.h>
+#include <base/scoped_observer.h>
+#include <base/strings/string_number_conversions.h>
+#include <base/values.h>
+#include <chromeos/daemons/dbus_daemon.h>
+#include <chromeos/flag_helper.h>
+#include <chromeos/http/http_request.h>
+#include <chromeos/key_value_store.h>
+#include <chromeos/mime_utils.h>
+#include <chromeos/strings/string_utils.h>
+#include <chromeos/syslog_logging.h>
+#include <libwebserv/protocol_handler.h>
+#include <libwebserv/request.h>
+#include <libwebserv/response.h>
+#include <libwebserv/server.h>
+
+#include "buffet/privet/ap_manager_client.h"
+#include "buffet/privet/cloud_delegate.h"
+#include "buffet/privet/constants.h"
+#include "buffet/privet/daemon_state.h"
+#include "buffet/privet/dbus_manager.h"
+#include "buffet/privet/device_delegate.h"
+#include "buffet/privet/peerd_client.h"
+#include "buffet/privet/privet_handler.h"
+#include "buffet/privet/privetd_conf_parser.h"
+#include "buffet/privet/security_manager.h"
+#include "buffet/privet/shill_client.h"
+#include "buffet/privet/wifi_bootstrap_manager.h"
+
+namespace privetd {
+
+namespace {
+
+using chromeos::dbus_utils::AsyncEventSequencer;
+using libwebserv::ProtocolHandler;
+using libwebserv::Request;
+using libwebserv::Response;
+
+const char kDefaultConfigFilePath[] = "/etc/privetd/privetd.conf";
+const char kDefaultStateFilePath[] = "/var/lib/privetd/privetd.state";
+
+std::string GetFirstHeader(const Request& request, const std::string& name) {
+  std::vector<std::string> headers = request.GetHeader(name);
+  return headers.empty() ? std::string() : headers.front();
+}
+
+const char kServiceName[] = "org.chromium.privetd";
+const char kRootPath[] = "/org/chromium/privetd";
+
+class Daemon : public chromeos::DBusServiceDaemon,
+               public CloudDelegate::Observer {
+ public:
+  Daemon(bool disable_security,
+         bool enable_ping,
+         const std::set<std::string>& device_whitelist,
+         const base::FilePath& config_path,
+         const base::FilePath& state_path)
+      : DBusServiceDaemon(kServiceName, kRootPath),
+        disable_security_(disable_security),
+        enable_ping_(enable_ping),
+        device_whitelist_(device_whitelist),
+        config_path_(config_path),
+        state_store_(new DaemonState(state_path)) {}
+
+  void RegisterDBusObjectsAsync(AsyncEventSequencer* sequencer) override {
+    chromeos::KeyValueStore config_store;
+    if (!config_store.Load(config_path_)) {
+      LOG(ERROR) << "Failed to read privetd config file from "
+                 << config_path_.value();
+    } else {
+      CHECK(parser_.Parse(config_store))
+          << "Failed to read configuration file.";
+    }
+    state_store_->Init();
+    // This state store key doesn't exist naturally, but developers
+    // sometime put it in their state store to cause the device to bring
+    // up WiFi bootstrapping while being connected to an ethernet interface.
+    std::string test_device_whitelist;
+    if (device_whitelist_.empty() &&
+        state_store_->GetString(kWiFiBootstrapInterfaces,
+                                &test_device_whitelist)) {
+      auto interfaces =
+          chromeos::string_utils::Split(test_device_whitelist, ",", true, true);
+      device_whitelist_.insert(interfaces.begin(), interfaces.end());
+    }
+    device_ = DeviceDelegate::CreateDefault();
+    cloud_ = CloudDelegate::CreateDefault(
+        bus_, parser_.gcd_bootstrap_mode() != GcdBootstrapMode::kDisabled);
+    cloud_observer_.Add(cloud_.get());
+    security_.reset(new SecurityManager(parser_.pairing_modes(),
+                                        parser_.embedded_code_path(),
+                                        disable_security_));
+    shill_client_.reset(new ShillClient(
+        bus_, device_whitelist_.empty() ? parser_.automatic_wifi_interfaces()
+                                        : device_whitelist_));
+    shill_client_->RegisterConnectivityListener(
+        base::Bind(&Daemon::OnConnectivityChanged, base::Unretained(this)));
+    ap_manager_client_.reset(new ApManagerClient(bus_));
+
+    if (parser_.wifi_bootstrap_mode() != WiFiBootstrapMode::kDisabled) {
+      VLOG(1) << "Enabling WiFi bootstrapping.";
+      wifi_bootstrap_manager_.reset(new WifiBootstrapManager(
+          state_store_.get(), shill_client_.get(), ap_manager_client_.get(),
+          cloud_.get(), parser_.connect_timeout_seconds(),
+          parser_.bootstrap_timeout_seconds(),
+          parser_.monitor_timeout_seconds()));
+      wifi_bootstrap_manager_->Init();
+    }
+
+    peerd_client_.reset(new PeerdClient(bus_, device_.get(), cloud_.get(),
+                                        wifi_bootstrap_manager_.get()));
+
+    privet_handler_.reset(new PrivetHandler(cloud_.get(), device_.get(),
+                                            security_.get(),
+                                            wifi_bootstrap_manager_.get(),
+                                            peerd_client_.get()));
+
+    web_server_.OnProtocolHandlerConnected(
+        base::Bind(&Daemon::OnProtocolHandlerConnected,
+                   weak_ptr_factory_.GetWeakPtr()));
+    web_server_.OnProtocolHandlerDisconnected(
+        base::Bind(&Daemon::OnProtocolHandlerDisconnected,
+                   weak_ptr_factory_.GetWeakPtr()));
+
+    web_server_.Connect(
+        bus_,
+        kServiceName,
+        sequencer->GetHandler("Server::Connect failed.", true),
+        base::Bind(&base::DoNothing),
+        base::Bind(&base::DoNothing));
+
+    web_server_.GetDefaultHttpHandler()->AddHandlerCallback(
+        "/privet/", "",
+        base::Bind(&Daemon::PrivetRequestHandler, base::Unretained(this)));
+    web_server_.GetDefaultHttpsHandler()->AddHandlerCallback(
+        "/privet/", "",
+        base::Bind(&Daemon::PrivetRequestHandler, base::Unretained(this)));
+    if (enable_ping_) {
+      web_server_.GetDefaultHttpHandler()->AddHandlerCallback(
+          "/privet/ping", chromeos::http::request_type::kGet,
+          base::Bind(&Daemon::HelloWorldHandler, base::Unretained(this)));
+      web_server_.GetDefaultHttpsHandler()->AddHandlerCallback(
+          "/privet/ping", chromeos::http::request_type::kGet,
+          base::Bind(&Daemon::HelloWorldHandler, base::Unretained(this)));
+    }
+
+    dbus_manager_.reset(new DBusManager{object_manager_.get(),
+                                        wifi_bootstrap_manager_.get(),
+                                        cloud_.get(),
+                                        security_.get()});
+    dbus_manager_->RegisterAsync(
+        sequencer->GetHandler("DBusManager.RegisterAsync() failed.", true));
+  }
+
+  void OnShutdown(int* return_code) override {
+    web_server_.Disconnect();
+    DBusDaemon::OnShutdown(return_code);
+  }
+
+  void OnDeviceInfoChanged() override { OnChanged(); };
+
+ private:
+  void PrivetRequestHandler(std::unique_ptr<Request> request,
+                            std::unique_ptr<Response> response) {
+    std::string auth_header = GetFirstHeader(
+        *request, chromeos::http::request_header::kAuthorization);
+    if (auth_header.empty() && disable_security_)
+      auth_header = "Privet anonymous";
+    std::string data(request->GetData().begin(), request->GetData().end());
+    VLOG(3) << "Input: " << data;
+
+    base::DictionaryValue empty;
+    std::unique_ptr<base::Value> value;
+    const base::DictionaryValue* dictionary = nullptr;
+
+    if (data.empty()) {
+      dictionary = &empty;
+    } else {
+      std::string content_type =
+          chromeos::mime::RemoveParameters(GetFirstHeader(
+              *request, chromeos::http::request_header::kContentType));
+      if (content_type == chromeos::mime::application::kJson) {
+        value.reset(base::JSONReader::Read(data));
+        if (value)
+          value->GetAsDictionary(&dictionary);
+      }
+    }
+
+    privet_handler_->HandleRequest(
+        request->GetPath(), auth_header, dictionary,
+        base::Bind(&Daemon::PrivetResponseHandler, base::Unretained(this),
+                   base::Passed(&response)));
+  }
+
+  void PrivetResponseHandler(std::unique_ptr<Response> response,
+                             int status,
+                             const base::DictionaryValue& output) {
+    VLOG(3) << "status: " << status << ", Output: " << output;
+    response->ReplyWithJson(status, &output);
+  }
+
+  void HelloWorldHandler(std::unique_ptr<Request> request,
+                         std::unique_ptr<Response> response) {
+    response->ReplyWithText(chromeos::http::status_code::Ok, "Hello, world!",
+                            chromeos::mime::text::kPlain);
+  }
+
+  void OnChanged() {
+    if (peerd_client_)
+      peerd_client_->Update();
+  }
+
+  void OnConnectivityChanged(bool online) {
+    OnChanged();
+  }
+
+  void OnProtocolHandlerConnected(ProtocolHandler* protocol_handler) {
+    if (protocol_handler->GetName() == ProtocolHandler::kHttp) {
+      device_->SetHttpPort(*protocol_handler->GetPorts().begin());
+      if (peerd_client_)
+        peerd_client_->Update();
+    } else if (protocol_handler->GetName() == ProtocolHandler::kHttps) {
+      device_->SetHttpsPort(*protocol_handler->GetPorts().begin());
+      security_->SetCertificateFingerprint(
+          protocol_handler->GetCertificateFingerprint());
+    }
+  }
+
+  void OnProtocolHandlerDisconnected(ProtocolHandler* protocol_handler) {
+    if (protocol_handler->GetName() == ProtocolHandler::kHttp) {
+      device_->SetHttpPort(0);
+      if (peerd_client_)
+        peerd_client_->Update();
+    } else if (protocol_handler->GetName() == ProtocolHandler::kHttps) {
+      device_->SetHttpsPort(0);
+      security_->SetCertificateFingerprint({});
+    }
+  }
+
+  bool disable_security_;
+  bool enable_ping_;
+  PrivetdConfigParser parser_;
+  std::set<std::string> device_whitelist_;
+  base::FilePath config_path_;
+  std::unique_ptr<DaemonState> state_store_;
+  std::unique_ptr<CloudDelegate> cloud_;
+  std::unique_ptr<DeviceDelegate> device_;
+  std::unique_ptr<SecurityManager> security_;
+  std::unique_ptr<ShillClient> shill_client_;
+  std::unique_ptr<ApManagerClient> ap_manager_client_;
+  std::unique_ptr<WifiBootstrapManager> wifi_bootstrap_manager_;
+  std::unique_ptr<PeerdClient> peerd_client_;
+  std::unique_ptr<PrivetHandler> privet_handler_;
+  ScopedObserver<CloudDelegate, CloudDelegate::Observer> cloud_observer_{this};
+  std::unique_ptr<DBusManager> dbus_manager_;
+  libwebserv::Server web_server_;
+
+  base::WeakPtrFactory<Daemon> weak_ptr_factory_{this};
+  DISALLOW_COPY_AND_ASSIGN(Daemon);
+};
+
+}  // anonymous namespace
+
+}  // namespace privetd
+
+int main(int argc, char* argv[]) {
+  DEFINE_bool(disable_security, false, "disable Privet security for tests");
+  DEFINE_bool(enable_ping, false, "enable test HTTP handler at /privet/ping");
+  DEFINE_bool(log_to_stderr, false, "log trace messages to stderr as well");
+  DEFINE_string(config_path, privetd::kDefaultConfigFilePath,
+                "Path to file containing config information.");
+  DEFINE_string(state_path, privetd::kDefaultStateFilePath,
+                "Path to file containing state information.");
+  DEFINE_string(device_whitelist, "",
+                "Comma separated list of network interfaces to monitor for "
+                "connectivity (an empty list enables all interfaces).");
+
+  chromeos::FlagHelper::Init(argc, argv, "Privet protocol handler daemon");
+
+  int flags = chromeos::kLogToSyslog;
+  if (FLAGS_log_to_stderr)
+    flags |= chromeos::kLogToStderr;
+  chromeos::InitLog(flags | chromeos::kLogHeader);
+
+  if (FLAGS_config_path.empty())
+    FLAGS_config_path = privetd::kDefaultConfigFilePath;
+
+  if (FLAGS_state_path.empty())
+    FLAGS_state_path = privetd::kDefaultStateFilePath;
+
+  auto device_whitelist =
+      chromeos::string_utils::Split(FLAGS_device_whitelist, ",", true, true);
+
+  privetd::Daemon daemon(
+      FLAGS_disable_security, FLAGS_enable_ping,
+      std::set<std::string>(device_whitelist.begin(), device_whitelist.end()),
+      base::FilePath(FLAGS_config_path), base::FilePath(FLAGS_state_path));
+  return daemon.Run();
+}
diff --git a/buffet/privet/mock_delegates.h b/buffet/privet/mock_delegates.h
new file mode 100644
index 0000000..ff8c11b
--- /dev/null
+++ b/buffet/privet/mock_delegates.h
@@ -0,0 +1,229 @@
+// Copyright 2014 The Chromium OS 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 BUFFET_PRIVET_MOCK_DELEGATES_H_
+#define BUFFET_PRIVET_MOCK_DELEGATES_H_
+
+#include <set>
+#include <string>
+#include <utility>
+
+#include <base/values.h>
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+
+#include "buffet/privet/cloud_delegate.h"
+#include "buffet/privet/device_delegate.h"
+#include "buffet/privet/identity_delegate.h"
+#include "buffet/privet/security_delegate.h"
+#include "buffet/privet/wifi_delegate.h"
+
+using testing::_;
+using testing::Return;
+using testing::ReturnRef;
+using testing::SetArgPointee;
+
+namespace privetd {
+
+ACTION_TEMPLATE(RunCallback,
+                HAS_1_TEMPLATE_PARAMS(int, k),
+                AND_0_VALUE_PARAMS()) {
+  return std::get<k>(args).Run();
+}
+
+ACTION_TEMPLATE(RunCallback,
+                HAS_1_TEMPLATE_PARAMS(int, k),
+                AND_1_VALUE_PARAMS(p0)) {
+  return std::get<k>(args).Run(p0);
+}
+
+class MockDeviceDelegate : public DeviceDelegate {
+  using IntPair = std::pair<uint16_t, uint16_t>;
+
+ public:
+  MOCK_CONST_METHOD0(GetHttpEnpoint, IntPair());
+  MOCK_CONST_METHOD0(GetHttpsEnpoint, IntPair());
+  MOCK_CONST_METHOD0(GetUptime, base::TimeDelta());
+  MOCK_METHOD1(SetHttpPort, void(uint16_t));
+  MOCK_METHOD1(SetHttpsPort, void(uint16_t));
+
+  MockDeviceDelegate() {
+    EXPECT_CALL(*this, GetHttpEnpoint())
+        .WillRepeatedly(Return(std::make_pair(0, 0)));
+    EXPECT_CALL(*this, GetHttpsEnpoint())
+        .WillRepeatedly(Return(std::make_pair(0, 0)));
+    EXPECT_CALL(*this, GetUptime())
+        .WillRepeatedly(Return(base::TimeDelta::FromHours(1)));
+  }
+};
+
+class MockSecurityDelegate : public SecurityDelegate {
+ public:
+  MOCK_METHOD2(CreateAccessToken,
+               std::string(const UserInfo&, const base::Time&));
+  MOCK_CONST_METHOD2(ParseAccessToken,
+                     UserInfo(const std::string&, base::Time*));
+  MOCK_CONST_METHOD0(GetPairingTypes, std::set<PairingType>());
+  MOCK_CONST_METHOD0(GetCryptoTypes, std::set<CryptoType>());
+  MOCK_CONST_METHOD1(IsValidPairingCode, bool(const std::string&));
+  MOCK_METHOD5(StartPairing,
+               bool(PairingType,
+                    CryptoType,
+                    std::string*,
+                    std::string*,
+                    chromeos::ErrorPtr*));
+  MOCK_METHOD5(ConfirmPairing,
+               bool(const std::string&,
+                    const std::string&,
+                    std::string*,
+                    std::string*,
+                    chromeos::ErrorPtr*));
+  MOCK_METHOD2(CancelPairing, bool(const std::string&, chromeos::ErrorPtr*));
+
+  MockSecurityDelegate() {
+    EXPECT_CALL(*this, CreateAccessToken(_, _))
+        .WillRepeatedly(Return("GuestAccessToken"));
+
+    EXPECT_CALL(*this, ParseAccessToken(_, _))
+        .WillRepeatedly(DoAll(SetArgPointee<1>(base::Time::Now()),
+                              Return(UserInfo{AuthScope::kViewer, 1234567})));
+
+    EXPECT_CALL(*this, GetPairingTypes())
+        .WillRepeatedly(Return(std::set<PairingType>{
+            PairingType::kPinCode,
+            PairingType::kEmbeddedCode,
+            PairingType::kUltrasound32,
+            PairingType::kAudible32,
+        }));
+
+    EXPECT_CALL(*this, GetCryptoTypes())
+        .WillRepeatedly(Return(std::set<CryptoType>{
+            CryptoType::kSpake_p224, CryptoType::kSpake_p256,
+        }));
+
+    EXPECT_CALL(*this, StartPairing(_, _, _, _, _))
+        .WillRepeatedly(DoAll(SetArgPointee<2>("testSession"),
+                              SetArgPointee<3>("testCommitment"),
+                              Return(true)));
+
+    EXPECT_CALL(*this, ConfirmPairing(_, _, _, _, _))
+        .WillRepeatedly(DoAll(SetArgPointee<2>("testFingerprint"),
+                              SetArgPointee<3>("testSignature"), Return(true)));
+    EXPECT_CALL(*this, CancelPairing(_, _)).WillRepeatedly(Return(true));
+  }
+};
+
+class MockWifiDelegate : public WifiDelegate {
+ public:
+  MOCK_CONST_METHOD0(GetConnectionState, const ConnectionState&());
+  MOCK_CONST_METHOD0(GetSetupState, const SetupState&());
+  MOCK_METHOD3(ConfigureCredentials,
+               bool(const std::string&,
+                    const std::string&,
+                    chromeos::ErrorPtr*));
+  MOCK_CONST_METHOD0(GetCurrentlyConnectedSsid, std::string());
+  MOCK_CONST_METHOD0(GetHostedSsid, std::string());
+  MOCK_CONST_METHOD0(GetTypes, std::set<WifiType>());
+
+  MockWifiDelegate() {
+    EXPECT_CALL(*this, GetConnectionState())
+        .WillRepeatedly(ReturnRef(connection_state_));
+    EXPECT_CALL(*this, GetSetupState()).WillRepeatedly(ReturnRef(setup_state_));
+    EXPECT_CALL(*this, GetCurrentlyConnectedSsid())
+        .WillRepeatedly(Return("TestSsid"));
+    EXPECT_CALL(*this, GetHostedSsid()).WillRepeatedly(Return(""));
+    EXPECT_CALL(*this, GetTypes())
+        .WillRepeatedly(Return(std::set<WifiType>{WifiType::kWifi24}));
+  }
+
+  ConnectionState connection_state_{ConnectionState::kOffline};
+  SetupState setup_state_{SetupState::kNone};
+};
+
+class MockCloudDelegate : public CloudDelegate {
+ public:
+  MOCK_CONST_METHOD2(GetModelId, bool(std::string*, chromeos::ErrorPtr*));
+  MOCK_CONST_METHOD2(GetName, bool(std::string*, chromeos::ErrorPtr*));
+  MOCK_CONST_METHOD0(GetDescription, std::string());
+  MOCK_CONST_METHOD0(GetLocation, std::string());
+  MOCK_METHOD5(UpdateDeviceInfo,
+               void(const std::string&,
+                    const std::string&,
+                    const std::string&,
+                    const base::Closure&,
+                    const ErrorCallback&));
+  MOCK_CONST_METHOD0(GetOemName, std::string());
+  MOCK_CONST_METHOD0(GetModelName, std::string());
+  MOCK_CONST_METHOD0(GetServices, std::set<std::string>());
+  MOCK_CONST_METHOD0(GetAnonymousMaxScope, AuthScope());
+  MOCK_CONST_METHOD0(GetConnectionState, const ConnectionState&());
+  MOCK_CONST_METHOD0(GetSetupState, const SetupState&());
+  MOCK_METHOD3(Setup,
+               bool(const std::string&,
+                    const std::string&,
+                    chromeos::ErrorPtr*));
+  MOCK_CONST_METHOD0(GetCloudId, std::string());
+  MOCK_CONST_METHOD0(GetState, const base::DictionaryValue&());
+  MOCK_CONST_METHOD0(GetCommandDef, const base::DictionaryValue&());
+  MOCK_METHOD4(AddCommand,
+               void(const base::DictionaryValue&,
+                    const UserInfo&,
+                    const SuccessCallback&,
+                    const ErrorCallback&));
+  MOCK_METHOD4(GetCommand,
+               void(const std::string&,
+                    const UserInfo&,
+                    const SuccessCallback&,
+                    const ErrorCallback&));
+  MOCK_METHOD4(CancelCommand,
+               void(const std::string&,
+                    const UserInfo&,
+                    const SuccessCallback&,
+                    const ErrorCallback&));
+  MOCK_METHOD3(ListCommands,
+               void(const UserInfo&,
+                    const SuccessCallback&,
+                    const ErrorCallback&));
+
+  MockCloudDelegate() {
+    EXPECT_CALL(*this, GetModelId(_, _))
+        .WillRepeatedly(DoAll(SetArgPointee<0>("ABMID"), Return(true)));
+    EXPECT_CALL(*this, GetName(_, _))
+        .WillRepeatedly(DoAll(SetArgPointee<0>("TestDevice"), Return(true)));
+    EXPECT_CALL(*this, GetDescription()).WillRepeatedly(Return(""));
+    EXPECT_CALL(*this, GetLocation()).WillRepeatedly(Return(""));
+    EXPECT_CALL(*this, UpdateDeviceInfo(_, _, _, _, _))
+        .WillRepeatedly(RunCallback<3>());
+    EXPECT_CALL(*this, GetOemName()).WillRepeatedly(Return("Chromium"));
+    EXPECT_CALL(*this, GetModelName()).WillRepeatedly(Return("Brillo"));
+    EXPECT_CALL(*this, GetServices())
+        .WillRepeatedly(Return(std::set<std::string>{}));
+    EXPECT_CALL(*this, GetAnonymousMaxScope())
+        .WillRepeatedly(Return(AuthScope::kUser));
+    EXPECT_CALL(*this, GetConnectionState())
+        .WillRepeatedly(ReturnRef(connection_state_));
+    EXPECT_CALL(*this, GetSetupState()).WillRepeatedly(ReturnRef(setup_state_));
+    EXPECT_CALL(*this, GetCloudId()).WillRepeatedly(Return("TestCloudId"));
+    test_dict_.Set("test", new base::DictionaryValue);
+    EXPECT_CALL(*this, GetCommandDef()).WillRepeatedly(ReturnRef(test_dict_));
+    EXPECT_CALL(*this, GetState()).WillRepeatedly(ReturnRef(test_dict_));
+  }
+
+  ConnectionState connection_state_{ConnectionState::kOnline};
+  SetupState setup_state_{SetupState::kNone};
+  base::DictionaryValue test_dict_;
+};
+
+class MockIdentityDelegate : public IdentityDelegate {
+ public:
+  MOCK_CONST_METHOD0(GetId, std::string());
+
+  MockIdentityDelegate() {
+    EXPECT_CALL(*this, GetId()).WillRepeatedly(Return("TestId"));
+  }
+};
+
+}  // namespace privetd
+
+#endif  // BUFFET_PRIVET_MOCK_DELEGATES_H_
diff --git a/buffet/privet/openssl_utils.cc b/buffet/privet/openssl_utils.cc
new file mode 100644
index 0000000..17cc16f
--- /dev/null
+++ b/buffet/privet/openssl_utils.cc
@@ -0,0 +1,26 @@
+// Copyright 2014 The Chromium OS 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 "buffet/privet/openssl_utils.h"
+
+#include <algorithm>
+
+#include <openssl/evp.h>
+#include <openssl/hmac.h>
+
+#include <base/logging.h>
+
+namespace privetd {
+
+chromeos::Blob HmacSha256(const chromeos::SecureBlob& key,
+                          const chromeos::Blob& data) {
+  chromeos::Blob mac(kSha256OutputSize);
+  uint32_t len = 0;
+  CHECK(HMAC(EVP_sha256(), key.data(), key.size(), data.data(),
+             data.size(), mac.data(), &len));
+  CHECK_EQ(len, kSha256OutputSize);
+  return mac;
+}
+
+}  // namespace privetd
diff --git a/buffet/privet/openssl_utils.h b/buffet/privet/openssl_utils.h
new file mode 100644
index 0000000..587b60c
--- /dev/null
+++ b/buffet/privet/openssl_utils.h
@@ -0,0 +1,22 @@
+// Copyright 2014 The Chromium OS 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 BUFFET_PRIVET_OPENSSL_UTILS_H_
+#define BUFFET_PRIVET_OPENSSL_UTILS_H_
+
+#include <string>
+#include <vector>
+
+#include <chromeos/secure_blob.h>
+
+namespace privetd {
+
+const size_t kSha256OutputSize = 32;
+
+chromeos::Blob HmacSha256(const chromeos::SecureBlob& key,
+                          const chromeos::Blob& data);
+
+}  // namespace privetd
+
+#endif  // BUFFET_PRIVET_OPENSSL_UTILS_H_
diff --git a/buffet/privet/peerd_client.cc b/buffet/privet/peerd_client.cc
new file mode 100644
index 0000000..76f88ce
--- /dev/null
+++ b/buffet/privet/peerd_client.cc
@@ -0,0 +1,170 @@
+// Copyright 2014 The Chromium OS 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 "buffet/privet/peerd_client.h"
+
+#include <map>
+
+#include <base/message_loop/message_loop.h>
+#include <chromeos/errors/error.h>
+#include <chromeos/strings/string_utils.h>
+
+#include "buffet/privet/cloud_delegate.h"
+#include "buffet/privet/device_delegate.h"
+#include "buffet/privet/wifi_bootstrap_manager.h"
+#include "buffet/privet/wifi_ssid_generator.h"
+
+using chromeos::string_utils::Join;
+using org::chromium::peerd::PeerProxy;
+
+namespace privetd {
+
+namespace {
+
+// Commit changes only if no update request happened during the timeout.
+// Usually updates happen in batches, so we don't want to flood network with
+// updates relevant for a short amount of time.
+const int kCommitTimeoutSeconds = 1;
+
+// The name of the service we'll expose via peerd.
+const char kPrivetServiceId[] = "privet";
+const char kSelfPath[] = "/org/chromium/peerd/Self";
+
+void OnError(const std::string& operation, chromeos::Error* error) {
+  LOG(ERROR) << operation << " failed:" << error->GetMessage();
+}
+
+}  // namespace
+
+PeerdClient::PeerdClient(const scoped_refptr<dbus::Bus>& bus,
+                         const DeviceDelegate* device,
+                         const CloudDelegate* cloud,
+                         const WifiDelegate* wifi)
+    : peerd_object_manager_proxy_{bus},
+      device_{device},
+      cloud_{cloud},
+      wifi_{wifi} {
+  CHECK(device_);
+  CHECK(cloud_);
+  peerd_object_manager_proxy_.SetManagerAddedCallback(
+      base::Bind(&PeerdClient::OnPeerdOnline, weak_ptr_factory_.GetWeakPtr()));
+  peerd_object_manager_proxy_.SetManagerRemovedCallback(
+      base::Bind(&PeerdClient::OnPeerdOffline, weak_ptr_factory_.GetWeakPtr()));
+  peerd_object_manager_proxy_.SetPeerAddedCallback(
+      base::Bind(&PeerdClient::OnNewPeer, weak_ptr_factory_.GetWeakPtr()));
+}
+
+PeerdClient::~PeerdClient() {
+  RemoveService();
+}
+
+std::string PeerdClient::GetId() const {
+  return device_id_;
+}
+
+void PeerdClient::Update() {
+  // Abort pending updates, and wait for more changes.
+  restart_weak_ptr_factory_.InvalidateWeakPtrs();
+  base::MessageLoop::current()->PostDelayedTask(
+      FROM_HERE, base::Bind(&PeerdClient::UpdateImpl,
+                            restart_weak_ptr_factory_.GetWeakPtr()),
+      base::TimeDelta::FromSeconds(kCommitTimeoutSeconds));
+}
+
+void PeerdClient::OnNewPeer(PeerProxy* peer) {
+  if (!peer || peer->GetObjectPath().value() != kSelfPath)
+    return;
+  peer->SetPropertyChangedCallback(
+      base::Bind(&PeerdClient::OnPeerPropertyChanged,
+                 weak_ptr_factory_.GetWeakPtr()));
+  OnPeerPropertyChanged(peer, PeerProxy::UUIDName());
+}
+
+void PeerdClient::OnPeerPropertyChanged(
+    PeerProxy* peer,
+    const std::string& property_name) {
+  if (property_name != PeerProxy::UUIDName() ||
+      peer->GetObjectPath().value() != kSelfPath)
+    return;
+  const std::string new_id{peer->uuid()};
+  if (new_id != device_id_) {
+    device_id_ = new_id;
+    Update();
+  }
+}
+
+void PeerdClient::OnPeerdOnline(
+    org::chromium::peerd::ManagerProxy* manager_proxy) {
+  peerd_manager_proxy_ = manager_proxy;
+  VLOG(1) << "Peerd manager is online at '"
+          << manager_proxy->GetObjectPath().value() << "'.";
+  Update();
+}
+
+void PeerdClient::OnPeerdOffline(const dbus::ObjectPath& object_path) {
+  peerd_manager_proxy_ = nullptr;
+  VLOG(1) << "Peerd manager is now offline.";
+}
+
+void PeerdClient::ExposeService() {
+  // Do nothing if peerd hasn't started yet.
+  if (peerd_manager_proxy_ == nullptr)
+    return;
+
+  std::string name;
+  std::string model_id;
+  if (!cloud_->GetName(&name, nullptr) ||
+      !cloud_->GetModelId(&model_id, nullptr)) {
+    return;
+  }
+  DCHECK_EQ(model_id.size(), 5U);
+
+  VLOG(1) << "Starting peerd advertising.";
+  const uint16_t port = device_->GetHttpEnpoint().first;
+  std::map<std::string, chromeos::Any> mdns_options{
+      {"port", chromeos::Any{port}},
+  };
+  DCHECK_NE(port, 0);
+
+  std::string services;
+  if (!cloud_->GetServices().empty())
+    services += "_";
+  services += Join(",_", cloud_->GetServices());
+
+  std::map<std::string, std::string> txt_record{
+      {"txtvers", "3"},
+      {"ty", name},
+      {"services", services},
+      {"id", GetId()},
+      {"mmid", model_id},
+      {"flags", WifiSsidGenerator{cloud_, wifi_}.GenerateFlags()},
+  };
+
+  if (!cloud_->GetCloudId().empty())
+    txt_record.emplace("gcd_id", cloud_->GetCloudId());
+
+  if (!cloud_->GetDescription().empty())
+    txt_record.emplace("note", cloud_->GetDescription());
+
+  peerd_manager_proxy_->ExposeServiceAsync(
+      kPrivetServiceId, txt_record, {{"mdns", mdns_options}}, base::Closure(),
+      base::Bind(&OnError, "ExposeService"));
+}
+
+void PeerdClient::RemoveService() {
+  if (peerd_manager_proxy_ == nullptr)
+    return;
+
+  VLOG(1) << "Stopping peerd advertising.";
+  peerd_manager_proxy_->RemoveExposedServiceAsync(
+      kPrivetServiceId, base::Closure(), base::Bind(&OnError, "RemoveService"));
+}
+
+void PeerdClient::UpdateImpl() {
+  if (device_->GetHttpEnpoint().first == 0)
+    return RemoveService();
+  ExposeService();
+}
+
+}  // namespace privetd
diff --git a/buffet/privet/peerd_client.h b/buffet/privet/peerd_client.h
new file mode 100644
index 0000000..ae3d306
--- /dev/null
+++ b/buffet/privet/peerd_client.h
@@ -0,0 +1,72 @@
+// Copyright 2014 The Chromium OS 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 BUFFET_PRIVET_PEERD_CLIENT_H_
+#define BUFFET_PRIVET_PEERD_CLIENT_H_
+
+#include <memory>
+#include <string>
+
+#include <base/callback.h>
+#include <base/memory/ref_counted.h>
+
+#include "buffet/privet/identity_delegate.h"
+#include "peerd/dbus-proxies.h"
+
+namespace dbus {
+class Bus;
+}  // namespace dbus
+
+namespace privetd {
+
+class CloudDelegate;
+class DeviceDelegate;
+class WifiDelegate;
+
+// Publishes prived service on mDns using peerd.
+class PeerdClient : public IdentityDelegate {
+ public:
+  PeerdClient(const scoped_refptr<dbus::Bus>& bus,
+              const DeviceDelegate* device,
+              const CloudDelegate* cloud,
+              const WifiDelegate* wifi);
+  ~PeerdClient();
+
+  // Get the unique identifier for this device.  Note that if peerd has
+  // never been seen, this may be the empty string.
+  std::string GetId() const override;
+
+  // Updates published information.  Removes service if HTTP is not alive.
+  void Update();
+
+ private:
+  void OnPeerdOnline(org::chromium::peerd::ManagerProxy* manager_proxy);
+  void OnPeerdOffline(const dbus::ObjectPath& object_path);
+  void OnNewPeer(org::chromium::peerd::PeerProxy* peer_proxy);
+  void OnPeerPropertyChanged(org::chromium::peerd::PeerProxy* peer_proxy,
+                             const std::string& property_name);
+
+  void ExposeService();
+  void RemoveService();
+
+  void UpdateImpl();
+
+  org::chromium::peerd::ObjectManagerProxy peerd_object_manager_proxy_;
+  // |peerd_manager_proxy_| is owned by |peerd_object_manager_proxy_|.
+  org::chromium::peerd::ManagerProxy* peerd_manager_proxy_{nullptr};
+
+  const DeviceDelegate* device_{nullptr};
+  const CloudDelegate* cloud_{nullptr};
+  const WifiDelegate* wifi_{nullptr};
+
+  // Cached value of the device ID that we got from peerd.
+  std::string device_id_;
+
+  base::WeakPtrFactory<PeerdClient> restart_weak_ptr_factory_{this};
+  base::WeakPtrFactory<PeerdClient> weak_ptr_factory_{this};
+};
+
+}  // namespace privetd
+
+#endif  // BUFFET_PRIVET_PEERD_CLIENT_H_
diff --git a/buffet/privet/privet_handler.cc b/buffet/privet/privet_handler.cc
new file mode 100644
index 0000000..5c3d0c2
--- /dev/null
+++ b/buffet/privet/privet_handler.cc
@@ -0,0 +1,948 @@
+// Copyright 2014 The Chromium OS 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 "buffet/privet/privet_handler.h"
+
+#include <memory>
+#include <set>
+#include <string>
+#include <utility>
+
+#include <base/bind.h>
+#include <base/location.h>
+#include <base/stl_util.h>
+#include <base/strings/string_number_conversions.h>
+#include <base/strings/stringprintf.h>
+#include <base/values.h>
+#include <chromeos/http/http_request.h>
+#include <chromeos/strings/string_utils.h>
+
+#include "buffet/privet/cloud_delegate.h"
+#include "buffet/privet/constants.h"
+#include "buffet/privet/device_delegate.h"
+#include "buffet/privet/identity_delegate.h"
+#include "buffet/privet/security_delegate.h"
+#include "buffet/privet/wifi_delegate.h"
+
+namespace privetd {
+
+namespace {
+
+const char kInfoVersionKey[] = "version";
+const char kInfoVersionValue[] = "3.0";
+
+const char kNameKey[] = "name";
+const char kDescrptionKey[] = "description";
+const char kLocationKey[] = "location";
+
+const char kGcdKey[] = "gcd";
+const char kWifiKey[] = "wifi";
+const char kStatusKey[] = "status";
+const char kErrorKey[] = "error";
+const char kCryptoKey[] = "crypto";
+const char kStatusErrorValue[] = "error";
+
+const char kInfoIdKey[] = "id";
+const char kInfoServicesKey[] = "services";
+
+const char kInfoEndpointsKey[] = "endpoints";
+const char kInfoEndpointsHttpPortKey[] = "httpPort";
+const char kInfoEndpointsHttpUpdatePortKey[] = "httpUpdatesPort";
+const char kInfoEndpointsHttpsPortKey[] = "httpsPort";
+const char kInfoEndpointsHttpsUpdatePortKey[] = "httpsUpdatesPort";
+
+const char kInfoModelIdKey[] = "modelManifestId";
+const char kInfoModelManifestKey[] = "basicModelManifest";
+const char kInfoManifestUiDeviceKind[] = "uiDeviceKind";
+const char kInfoManifestOemName[] = "oemName";
+const char kInfoManifestModelName[] = "modelName";
+
+const char kInfoAuthenticationKey[] = "authentication";
+
+const char kInfoAuthAnonymousMaxScopeKey[] = "anonymousMaxScope";
+
+const char kInfoWifiCapabilitiesKey[] = "capabilities";
+const char kInfoWifiSsidKey[] = "ssid";
+const char kInfoWifiHostedSsidKey[] = "hostedSsid";
+
+const char kInfoUptimeKey[] = "uptime";
+
+const char kPairingKey[] = "pairing";
+const char kPairingSessionIdKey[] = "sessionId";
+const char kPairingDeviceCommitmentKey[] = "deviceCommitment";
+const char kPairingClientCommitmentKey[] = "clientCommitment";
+const char kPairingFingerprintKey[] = "certFingerprint";
+const char kPairingSignatureKey[] = "certSignature";
+
+const char kAuthTypeAnonymousValue[] = "anonymous";
+const char kAuthTypePairingValue[] = "pairing";
+
+const char kAuthModeKey[] = "mode";
+const char kAuthCodeKey[] = "authCode";
+const char kAuthRequestedScopeKey[] = "requestedScope";
+const char kAuthScopeAutoValue[] = "auto";
+
+const char kAuthAccessTokenKey[] = "accessToken";
+const char kAuthTokenTypeKey[] = "tokenType";
+const char kAuthExpiresInKey[] = "expiresIn";
+const char kAuthScopeKey[] = "scope";
+
+const char kAuthorizationHeaderPrefix[] = "Privet";
+
+const char kErrorCodeKey[] = "code";
+const char kErrorMessageKey[] = "message";
+const char kErrorDebugInfoKey[] = "debugInfo";
+
+const char kSetupStartSsidKey[] = "ssid";
+const char kSetupStartPassKey[] = "passphrase";
+const char kSetupStartTicketIdKey[] = "ticketId";
+const char kSetupStartUserKey[] = "user";
+
+const char kFingerprintKey[] = "fingerprint";
+const char kStateKey[] = "state";
+const char kCommandsKey[] = "commands";
+const char kCommandsIdKey[] = "id";
+
+const char kInvalidParamValueFormat[] = "Invalid parameter: '%s'='%s'";
+
+const int kAccessTokenExpirationSeconds = 3600;
+
+// Threshold to reduce probability of expiration because of clock difference
+// between device and client. Value is just a guess.
+const int kAccessTokenExpirationThresholdSeconds = 300;
+
+template <class Container>
+std::unique_ptr<base::ListValue> ToValue(const Container& list) {
+  std::unique_ptr<base::ListValue> value_list(new base::ListValue());
+  for (const std::string& val : list)
+    value_list->AppendString(val);
+  return value_list;
+}
+
+template <typename T>
+class EnumToStringMap final {
+ public:
+  static std::string FindNameById(T id) {
+    for (const Map& m : kMap) {
+      if (m.id == id) {
+        CHECK(m.name);
+        return m.name;
+      }
+    }
+    NOTREACHED() << static_cast<int>(id) << " is not part of "
+                 << typeid(T).name();
+    return std::string();
+  }
+
+  static bool FindIdByName(const std::string& name, T* id) {
+    for (const Map& m : kMap) {
+      if (m.name && m.name == name) {
+        *id = m.id;
+        return true;
+      }
+    }
+    return false;
+  }
+
+ private:
+  struct Map {
+    const T id;
+    const char* const name;
+  };
+  static const Map kMap[];
+};
+
+template <>
+const EnumToStringMap<ConnectionState::Status>::Map
+    EnumToStringMap<ConnectionState::Status>::kMap[] = {
+        {ConnectionState::kDisabled, "disabled"},
+        {ConnectionState::kUnconfigured, "unconfigured"},
+        {ConnectionState::kConnecting, "connecting"},
+        {ConnectionState::kOnline, "online"},
+        {ConnectionState::kOffline, "offline"},
+};
+
+template <>
+const EnumToStringMap<SetupState::Status>::Map
+    EnumToStringMap<SetupState::Status>::kMap[] = {
+        {SetupState::kNone, nullptr},
+        {SetupState::kInProgress, "inProgress"},
+        {SetupState::kSuccess, "success"},
+};
+
+template <>
+const EnumToStringMap<WifiType>::Map EnumToStringMap<WifiType>::kMap[] = {
+    {WifiType::kWifi24, "2.4GHz"},
+    {WifiType::kWifi50, "5.0GHz"},
+};
+
+template <>
+const EnumToStringMap<PairingType>::Map EnumToStringMap<PairingType>::kMap[] = {
+    {PairingType::kPinCode, "pinCode"},
+    {PairingType::kEmbeddedCode, "embeddedCode"},
+    {PairingType::kUltrasound32, "ultrasound32"},
+    {PairingType::kAudible32, "audible32"},
+};
+
+template <>
+const EnumToStringMap<CryptoType>::Map EnumToStringMap<CryptoType>::kMap[] = {
+    {CryptoType::kNone, "none"},
+    {CryptoType::kSpake_p224, "p224_spake2"},
+    {CryptoType::kSpake_p256, "p256_spake2"},
+};
+
+template <>
+const EnumToStringMap<AuthScope>::Map EnumToStringMap<AuthScope>::kMap[] = {
+    {AuthScope::kNone, "none"},
+    {AuthScope::kViewer, "viewer"},
+    {AuthScope::kUser, "user"},
+    {AuthScope::kOwner, "owner"},
+};
+
+struct {
+  const char* const reason;
+  int code;
+} kReasonToCode[] = {
+    {errors::kInvalidClientCommitment, chromeos::http::status_code::Forbidden},
+    {errors::kInvalidFormat, chromeos::http::status_code::BadRequest},
+    {errors::kMissingAuthorization, chromeos::http::status_code::Denied},
+    {errors::kInvalidAuthorization, chromeos::http::status_code::Denied},
+    {errors::kInvalidAuthorizationScope,
+     chromeos::http::status_code::Forbidden},
+    {errors::kAuthorizationExpired, chromeos::http::status_code::Forbidden},
+    {errors::kCommitmentMismatch, chromeos::http::status_code::Forbidden},
+    {errors::kUnknownSession, chromeos::http::status_code::NotFound},
+    {errors::kInvalidAuthCode, chromeos::http::status_code::Forbidden},
+    {errors::kInvalidAuthMode, chromeos::http::status_code::BadRequest},
+    {errors::kInvalidRequestedScope, chromeos::http::status_code::BadRequest},
+    {errors::kAccessDenied, chromeos::http::status_code::Forbidden},
+    {errors::kInvalidParams, chromeos::http::status_code::BadRequest},
+    {errors::kSetupUnavailable, chromeos::http::status_code::BadRequest},
+    {errors::kDeviceBusy, chromeos::http::status_code::ServiceUnavailable},
+    {errors::kInvalidState, chromeos::http::status_code::InternalServerError},
+    {errors::kNotFound, chromeos::http::status_code::NotFound},
+    {errors::kNotImplemented, chromeos::http::status_code::NotSupported},
+};
+
+template <typename T>
+std::string EnumToString(T id) {
+  return EnumToStringMap<T>::FindNameById(id);
+}
+
+template <typename T>
+bool StringToEnum(const std::string& name, T* id) {
+  return EnumToStringMap<T>::FindIdByName(name, id);
+}
+
+AuthScope AuthScopeFromString(const std::string& scope, AuthScope auto_scope) {
+  if (scope == kAuthScopeAutoValue)
+    return auto_scope;
+  AuthScope scope_id = AuthScope::kNone;
+  StringToEnum(scope, &scope_id);
+  return scope_id;
+}
+
+std::string GetAuthTokenFromAuthHeader(const std::string& auth_header) {
+  std::string name;
+  std::string value;
+  chromeos::string_utils::SplitAtFirst(auth_header, " ", &name, &value);
+  return value;
+}
+
+std::unique_ptr<base::DictionaryValue> ErrorInfoToJson(
+    const chromeos::Error& error) {
+  std::unique_ptr<base::DictionaryValue> output{new base::DictionaryValue};
+  output->SetString(kErrorMessageKey, error.GetMessage());
+  output->SetString(kErrorCodeKey, error.GetCode());
+  return output;
+}
+
+// Creates JSON similar to GCD server error format.
+std::unique_ptr<base::DictionaryValue> ErrorToJson(
+    const chromeos::Error& error) {
+  std::unique_ptr<base::DictionaryValue> output{ErrorInfoToJson(error)};
+
+  // Optional debug information.
+  std::unique_ptr<base::ListValue> errors{new base::ListValue};
+  for (const chromeos::Error* it = &error; it; it = it->GetInnerError()) {
+    std::unique_ptr<base::DictionaryValue> inner{ErrorInfoToJson(*it)};
+    tracked_objects::Location location{it->GetLocation().function_name.c_str(),
+                                       it->GetLocation().file_name.c_str(),
+                                       it->GetLocation().line_number,
+                                       nullptr};
+    inner->SetString(kErrorDebugInfoKey, location.ToString());
+    errors->Append(inner.release());
+  }
+  output->Set(kErrorDebugInfoKey, errors.release());
+  return output;
+}
+
+template <class T>
+void SetState(const T& state, base::DictionaryValue* parent) {
+  if (!state.error()) {
+    parent->SetString(kStatusKey, EnumToString(state.status()));
+    return;
+  }
+  parent->SetString(kStatusKey, kStatusErrorValue);
+  parent->Set(kErrorKey, ErrorToJson(*state.error()).release());
+}
+
+void ReturnError(const chromeos::Error& error,
+                 const PrivetHandler::RequestCallback& callback) {
+  int code = chromeos::http::status_code::InternalServerError;
+  for (const auto& it : kReasonToCode) {
+    if (error.HasError(errors::kDomain, it.reason)) {
+      code = it.code;
+      break;
+    }
+  }
+  std::unique_ptr<base::DictionaryValue> output{new base::DictionaryValue};
+  output->Set(kErrorKey, ErrorToJson(error).release());
+  callback.Run(code, *output);
+}
+
+void OnCommandRequestSucceeded(const PrivetHandler::RequestCallback& callback,
+                               const base::DictionaryValue& output) {
+  callback.Run(chromeos::http::status_code::Ok, output);
+}
+
+void OnCommandRequestFailed(const PrivetHandler::RequestCallback& callback,
+                            chromeos::Error* error) {
+  if (error->HasError("gcd", "unknown_command")) {
+    chromeos::ErrorPtr new_error = error->Clone();
+    chromeos::Error::AddTo(&new_error, FROM_HERE, errors::kDomain,
+                           errors::kNotFound, "Unknown command ID");
+    return ReturnError(*new_error, callback);
+  }
+  if (error->HasError("gcd", "access_denied")) {
+    chromeos::ErrorPtr new_error = error->Clone();
+    chromeos::Error::AddTo(&new_error, FROM_HERE, errors::kDomain,
+                           errors::kAccessDenied, error->GetMessage());
+    return ReturnError(*new_error, callback);
+  }
+  return ReturnError(*error, callback);
+}
+
+std::string GetDeviceKind(const std::string& manifest_id) {
+  CHECK_EQ(5u, manifest_id.size());
+  std::string kind = manifest_id.substr(0, 2);
+  if (kind == "AC")
+    return "accessPoint";
+  if (kind == "AK")
+    return "aggregator";
+  if (kind == "AM")
+    return "camera";
+  if (kind == "AB")
+    return "developmentBoard";
+  if (kind == "AE")
+    return "printer";
+  if (kind == "AF")
+    return "scanner";
+  if (kind == "AD")
+    return "speaker";
+  if (kind == "AL")
+    return "storage";
+  if (kind == "AJ")
+    return "toy";
+  if (kind == "AA")
+    return "vendor";
+  if (kind == "AN")
+    return "video";
+  LOG(FATAL) << "Invalid model id: " << manifest_id;
+  return std::string();
+}
+
+std::unique_ptr<base::DictionaryValue> CreateManifestSection(
+    const std::string& model_id,
+    const CloudDelegate& cloud) {
+  std::unique_ptr<base::DictionaryValue> manifest(new base::DictionaryValue());
+  manifest->SetString(kInfoManifestUiDeviceKind, GetDeviceKind(model_id));
+  manifest->SetString(kInfoManifestOemName, cloud.GetOemName());
+  manifest->SetString(kInfoManifestModelName, cloud.GetModelName());
+  return manifest;
+}
+
+std::unique_ptr<base::DictionaryValue> CreateEndpointsSection(
+    const DeviceDelegate& device) {
+  std::unique_ptr<base::DictionaryValue> endpoints(new base::DictionaryValue());
+  auto http_endpoint = device.GetHttpEnpoint();
+  endpoints->SetInteger(kInfoEndpointsHttpPortKey, http_endpoint.first);
+  endpoints->SetInteger(kInfoEndpointsHttpUpdatePortKey, http_endpoint.second);
+
+  auto https_endpoint = device.GetHttpsEnpoint();
+  endpoints->SetInteger(kInfoEndpointsHttpsPortKey, https_endpoint.first);
+  endpoints->SetInteger(kInfoEndpointsHttpsUpdatePortKey,
+                        https_endpoint.second);
+
+  return endpoints;
+}
+
+std::unique_ptr<base::DictionaryValue> CreateInfoAuthSection(
+    const SecurityDelegate& security,
+    AuthScope anonymous_max_scope) {
+  std::unique_ptr<base::DictionaryValue> auth(new base::DictionaryValue());
+
+  auth->SetString(kInfoAuthAnonymousMaxScopeKey,
+                  EnumToString(anonymous_max_scope));
+
+  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());
+
+  std::unique_ptr<base::ListValue> auth_types(new base::ListValue());
+  auth_types->AppendString(kAuthTypeAnonymousValue);
+  auth_types->AppendString(kAuthTypePairingValue);
+
+  // TODO(vitalybuka): Implement cloud auth.
+  // if (cloud.GetConnectionState().IsStatusEqual(ConnectionState::kOnline)) {
+  //   auth_types->AppendString(kAuthTypeCloudValue);
+  // }
+  auth->Set(kAuthModeKey, auth_types.release());
+
+  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());
+
+  return auth;
+}
+
+std::unique_ptr<base::DictionaryValue> CreateWifiSection(
+    const WifiDelegate& wifi) {
+  std::unique_ptr<base::DictionaryValue> result(new base::DictionaryValue());
+
+  std::unique_ptr<base::ListValue> capabilities(new base::ListValue());
+  for (WifiType type : wifi.GetTypes())
+    capabilities->AppendString(EnumToString(type));
+  result->Set(kInfoWifiCapabilitiesKey, capabilities.release());
+
+  result->SetString(kInfoWifiSsidKey, wifi.GetCurrentlyConnectedSsid());
+
+  std::string hosted_ssid = wifi.GetHostedSsid();
+  const ConnectionState& state = wifi.GetConnectionState();
+  if (!hosted_ssid.empty()) {
+    DCHECK(!state.IsStatusEqual(ConnectionState::kDisabled));
+    DCHECK(!state.IsStatusEqual(ConnectionState::kOnline));
+    result->SetString(kInfoWifiHostedSsidKey, hosted_ssid);
+  }
+  SetState(state, result.get());
+  return result;
+}
+
+std::unique_ptr<base::DictionaryValue> CreateGcdSection(
+    const CloudDelegate& cloud) {
+  std::unique_ptr<base::DictionaryValue> gcd(new base::DictionaryValue());
+  gcd->SetString(kInfoIdKey, cloud.GetCloudId());
+  SetState(cloud.GetConnectionState(), gcd.get());
+  return gcd;
+}
+
+AuthScope GetAnonymousMaxScope(const CloudDelegate& cloud,
+                               const WifiDelegate* wifi) {
+  if (wifi && !wifi->GetHostedSsid().empty())
+    return AuthScope::kNone;
+  return cloud.GetAnonymousMaxScope();
+}
+
+}  // namespace
+
+PrivetHandler::PrivetHandler(CloudDelegate* cloud,
+                             DeviceDelegate* device,
+                             SecurityDelegate* security,
+                             WifiDelegate* wifi,
+                             IdentityDelegate* identity)
+    : cloud_(cloud),
+      device_(device),
+      security_(security),
+      wifi_(wifi),
+      identity_(identity) {
+  CHECK(cloud_);
+  CHECK(device_);
+  CHECK(security_);
+  cloud_observer_.Add(cloud_);
+
+  AddHandler("/privet/info", &PrivetHandler::HandleInfo, AuthScope::kNone);
+  AddHandler("/privet/v3/pairing/start", &PrivetHandler::HandlePairingStart,
+             AuthScope::kNone);
+  AddHandler("/privet/v3/pairing/confirm", &PrivetHandler::HandlePairingConfirm,
+             AuthScope::kNone);
+  AddHandler("/privet/v3/pairing/cancel", &PrivetHandler::HandlePairingCancel,
+             AuthScope::kNone);
+  AddHandler("/privet/v3/auth", &PrivetHandler::HandleAuth, AuthScope::kNone);
+  AddHandler("/privet/v3/setup/start", &PrivetHandler::HandleSetupStart,
+             AuthScope::kOwner);
+  AddHandler("/privet/v3/setup/status", &PrivetHandler::HandleSetupStatus,
+             AuthScope::kOwner);
+  AddHandler("/privet/v3/state", &PrivetHandler::HandleState,
+             AuthScope::kViewer);
+  AddHandler("/privet/v3/commandDefs", &PrivetHandler::HandleCommandDefs,
+             AuthScope::kViewer);
+  AddHandler("/privet/v3/commands/execute",
+             &PrivetHandler::HandleCommandsExecute, AuthScope::kViewer);
+  AddHandler("/privet/v3/commands/status", &PrivetHandler::HandleCommandsStatus,
+             AuthScope::kViewer);
+  AddHandler("/privet/v3/commands/cancel", &PrivetHandler::HandleCommandsCancel,
+             AuthScope::kViewer);
+  AddHandler("/privet/v3/commands/list", &PrivetHandler::HandleCommandsList,
+             AuthScope::kViewer);
+}
+
+PrivetHandler::~PrivetHandler() {
+}
+
+void PrivetHandler::OnCommandDefsChanged() {
+  ++command_defs_fingerprint_;
+}
+
+void PrivetHandler::OnStateChanged() {
+  ++state_fingerprint_;
+}
+
+void PrivetHandler::HandleRequest(const std::string& api,
+                                  const std::string& auth_header,
+                                  const base::DictionaryValue* input,
+                                  const RequestCallback& callback) {
+  chromeos::ErrorPtr error;
+  if (!input) {
+    chromeos::Error::AddTo(&error, FROM_HERE, errors::kDomain,
+                           errors::kInvalidFormat, "Malformed JSON");
+    return ReturnError(*error, callback);
+  }
+  auto handler = handlers_.find(api);
+  if (handler == handlers_.end()) {
+    chromeos::Error::AddTo(&error, FROM_HERE, errors::kDomain,
+                           errors::kNotFound, "Path not found");
+    return ReturnError(*error, callback);
+  }
+  if (auth_header.empty()) {
+    chromeos::Error::AddTo(&error, FROM_HERE, errors::kDomain,
+                           errors::kMissingAuthorization,
+                           "Authorization header must not be empty");
+    return ReturnError(*error, callback);
+  }
+  std::string token = GetAuthTokenFromAuthHeader(auth_header);
+  if (token.empty()) {
+    chromeos::Error::AddToPrintf(
+        &error, FROM_HERE, errors::kDomain, errors::kInvalidAuthorization,
+        "Invalid authorization header: %s", auth_header.c_str());
+    return ReturnError(*error, callback);
+  }
+  UserInfo user_info;
+  if (token != kAuthTypeAnonymousValue) {
+    base::Time time;
+    user_info = security_->ParseAccessToken(token, &time);
+    if (user_info.scope() == AuthScope::kNone) {
+      chromeos::Error::AddToPrintf(&error, FROM_HERE, errors::kDomain,
+                                   errors::kInvalidAuthorization,
+                                   "Invalid access token: %s", token.c_str());
+      return ReturnError(*error, callback);
+    }
+    time += base::TimeDelta::FromSeconds(kAccessTokenExpirationSeconds);
+    time +=
+        base::TimeDelta::FromSeconds(kAccessTokenExpirationThresholdSeconds);
+    if (time < base::Time::Now()) {
+      chromeos::Error::AddToPrintf(&error, FROM_HERE, errors::kDomain,
+                                   errors::kAuthorizationExpired,
+                                   "Token expired: %s", token.c_str());
+      return ReturnError(*error, callback);
+    }
+  }
+
+  if (handler->second.first > user_info.scope()) {
+    chromeos::Error::AddToPrintf(
+        &error, FROM_HERE, errors::kDomain, errors::kInvalidAuthorizationScope,
+        "Scope '%s' does not allow '%s'",
+        EnumToString(user_info.scope()).c_str(), api.c_str());
+    return ReturnError(*error, callback);
+  }
+  (this->*handler->second.second)(*input, user_info, callback);
+}
+
+void PrivetHandler::AddHandler(const std::string& path,
+                               ApiHandler handler,
+                               AuthScope scope) {
+  CHECK(handlers_.emplace(path, std::make_pair(scope, handler)).second);
+}
+
+void PrivetHandler::HandleInfo(const base::DictionaryValue&,
+                               const UserInfo& user_info,
+                               const RequestCallback& callback) {
+  base::DictionaryValue output;
+
+  chromeos::ErrorPtr error;
+
+  std::string name;
+  std::string model_id;
+  if (!cloud_->GetName(&name, &error) ||
+      !cloud_->GetModelId(&model_id, &error)) {
+    return ReturnError(*error, callback);
+  }
+
+  output.SetString(kInfoVersionKey, kInfoVersionValue);
+  output.SetString(kInfoIdKey, identity_->GetId());
+  output.SetString(kNameKey, name);
+
+  std::string description{cloud_->GetDescription()};
+  if (!description.empty())
+    output.SetString(kDescrptionKey, description);
+
+  std::string location{cloud_->GetLocation()};
+  if (!location.empty())
+    output.SetString(kLocationKey, location);
+
+  output.SetString(kInfoModelIdKey, model_id);
+  output.Set(kInfoModelManifestKey,
+             CreateManifestSection(model_id, *cloud_).release());
+  output.Set(kInfoServicesKey, ToValue(cloud_->GetServices()).release());
+
+  output.Set(kInfoAuthenticationKey,
+             CreateInfoAuthSection(
+                 *security_, GetAnonymousMaxScope(*cloud_, wifi_)).release());
+
+  output.Set(kInfoEndpointsKey, CreateEndpointsSection(*device_).release());
+
+  if (wifi_)
+    output.Set(kWifiKey, CreateWifiSection(*wifi_).release());
+
+  output.Set(kGcdKey, CreateGcdSection(*cloud_).release());
+
+  output.SetInteger(kInfoUptimeKey, device_->GetUptime().InSeconds());
+
+  callback.Run(chromeos::http::status_code::Ok, output);
+}
+
+void PrivetHandler::HandlePairingStart(const base::DictionaryValue& input,
+                                       const UserInfo& user_info,
+                                       const RequestCallback& callback) {
+  chromeos::ErrorPtr error;
+
+  std::string pairing_str;
+  input.GetString(kPairingKey, &pairing_str);
+
+  std::string crypto_str;
+  input.GetString(kCryptoKey, &crypto_str);
+
+  PairingType pairing;
+  std::set<PairingType> modes = security_->GetPairingTypes();
+  if (!StringToEnum(pairing_str, &pairing) || !ContainsKey(modes, pairing)) {
+    chromeos::Error::AddToPrintf(
+        &error, FROM_HERE, errors::kDomain, errors::kInvalidParams,
+        kInvalidParamValueFormat, kPairingKey, pairing_str.c_str());
+    return ReturnError(*error, callback);
+  }
+
+  CryptoType crypto;
+  std::set<CryptoType> cryptos = security_->GetCryptoTypes();
+  if (!StringToEnum(crypto_str, &crypto) || !ContainsKey(cryptos, crypto)) {
+    chromeos::Error::AddToPrintf(
+        &error, FROM_HERE, errors::kDomain, errors::kInvalidParams,
+        kInvalidParamValueFormat, kCryptoKey, crypto_str.c_str());
+    return ReturnError(*error, callback);
+  }
+
+  std::string id;
+  std::string commitment;
+  if (!security_->StartPairing(pairing, crypto, &id, &commitment, &error))
+    return ReturnError(*error, callback);
+
+  base::DictionaryValue output;
+  output.SetString(kPairingSessionIdKey, id);
+  output.SetString(kPairingDeviceCommitmentKey, commitment);
+  callback.Run(chromeos::http::status_code::Ok, output);
+}
+
+void PrivetHandler::HandlePairingConfirm(const base::DictionaryValue& input,
+                                         const UserInfo& user_info,
+                                         const RequestCallback& callback) {
+  std::string id;
+  input.GetString(kPairingSessionIdKey, &id);
+
+  std::string commitment;
+  input.GetString(kPairingClientCommitmentKey, &commitment);
+
+  std::string fingerprint;
+  std::string signature;
+  chromeos::ErrorPtr error;
+  if (!security_->ConfirmPairing(id, commitment, &fingerprint, &signature,
+                                 &error)) {
+    return ReturnError(*error, callback);
+  }
+
+  base::DictionaryValue output;
+  output.SetString(kPairingFingerprintKey, fingerprint);
+  output.SetString(kPairingSignatureKey, signature);
+  callback.Run(chromeos::http::status_code::Ok, output);
+}
+
+void PrivetHandler::HandlePairingCancel(const base::DictionaryValue& input,
+                                        const UserInfo& user_info,
+                                        const RequestCallback& callback) {
+  std::string id;
+  input.GetString(kPairingSessionIdKey, &id);
+
+  chromeos::ErrorPtr error;
+  if (!security_->CancelPairing(id, &error))
+    return ReturnError(*error, callback);
+
+  base::DictionaryValue output;
+  callback.Run(chromeos::http::status_code::Ok, output);
+}
+
+void PrivetHandler::HandleAuth(const base::DictionaryValue& input,
+                               const UserInfo& user_info,
+                               const RequestCallback& callback) {
+  chromeos::ErrorPtr error;
+
+  std::string auth_code_type;
+  input.GetString(kAuthModeKey, &auth_code_type);
+
+  std::string auth_code;
+  input.GetString(kAuthCodeKey, &auth_code);
+
+  AuthScope max_auth_scope = AuthScope::kNone;
+  if (auth_code_type == kAuthTypeAnonymousValue) {
+    max_auth_scope = GetAnonymousMaxScope(*cloud_, wifi_);
+  } else if (auth_code_type == kAuthTypePairingValue) {
+    if (!security_->IsValidPairingCode(auth_code)) {
+      chromeos::Error::AddToPrintf(
+          &error, FROM_HERE, errors::kDomain, errors::kInvalidAuthCode,
+          kInvalidParamValueFormat, kAuthCodeKey, auth_code.c_str());
+      return ReturnError(*error, callback);
+    }
+    max_auth_scope = AuthScope::kOwner;
+  } else {
+    chromeos::Error::AddToPrintf(
+        &error, FROM_HERE, errors::kDomain, errors::kInvalidAuthMode,
+        kInvalidParamValueFormat, kAuthModeKey, auth_code_type.c_str());
+    return ReturnError(*error, callback);
+  }
+
+  std::string requested_scope;
+  input.GetString(kAuthRequestedScopeKey, &requested_scope);
+
+  AuthScope requested_auth_scope =
+      AuthScopeFromString(requested_scope, max_auth_scope);
+  if (requested_auth_scope == AuthScope::kNone) {
+    chromeos::Error::AddToPrintf(
+        &error, FROM_HERE, errors::kDomain, errors::kInvalidRequestedScope,
+        kInvalidParamValueFormat, kAuthRequestedScopeKey,
+        requested_scope.c_str());
+    return ReturnError(*error, callback);
+  }
+
+  if (requested_auth_scope > max_auth_scope) {
+    chromeos::Error::AddToPrintf(
+        &error, FROM_HERE, errors::kDomain, errors::kAccessDenied,
+        "Scope '%s' is not allowed for '%s'",
+        EnumToString(requested_auth_scope).c_str(), auth_code.c_str());
+    return ReturnError(*error, callback);
+  }
+
+  base::DictionaryValue output;
+  output.SetString(
+      kAuthAccessTokenKey,
+      security_->CreateAccessToken(
+          UserInfo{requested_auth_scope, ++last_user_id_}, base::Time::Now()));
+  output.SetString(kAuthTokenTypeKey, kAuthorizationHeaderPrefix);
+  output.SetInteger(kAuthExpiresInKey, kAccessTokenExpirationSeconds);
+  output.SetString(kAuthScopeKey, EnumToString(requested_auth_scope));
+  callback.Run(chromeos::http::status_code::Ok, output);
+}
+
+void PrivetHandler::HandleSetupStart(const base::DictionaryValue& input,
+                                     const UserInfo& user_info,
+                                     const RequestCallback& callback) {
+  std::string name;
+  chromeos::ErrorPtr error;
+  if (!cloud_->GetName(&name, &error))
+    return ReturnError(*error, callback);
+  input.GetString(kNameKey, &name);
+
+  std::string description{cloud_->GetDescription()};
+  input.GetString(kDescrptionKey, &description);
+
+  std::string location{cloud_->GetLocation()};
+  input.GetString(kLocationKey, &location);
+
+  std::string ssid;
+  std::string passphrase;
+  std::string ticket;
+  std::string user;
+
+  const base::DictionaryValue* wifi = nullptr;
+  if (input.GetDictionary(kWifiKey, &wifi)) {
+    if (!wifi_ || wifi_->GetTypes().empty()) {
+      chromeos::Error::AddTo(&error, FROM_HERE, errors::kDomain,
+                             errors::kSetupUnavailable,
+                             "WiFi setup unavailible");
+      return ReturnError(*error, callback);
+    }
+    wifi->GetString(kSetupStartSsidKey, &ssid);
+    if (ssid.empty()) {
+      chromeos::Error::AddToPrintf(
+          &error, FROM_HERE, errors::kDomain, errors::kInvalidParams,
+          kInvalidParamValueFormat, kSetupStartSsidKey, "");
+      return ReturnError(*error, callback);
+    }
+    wifi->GetString(kSetupStartPassKey, &passphrase);
+  }
+
+  const base::DictionaryValue* registration = nullptr;
+  if (input.GetDictionary(kGcdKey, &registration)) {
+    registration->GetString(kSetupStartTicketIdKey, &ticket);
+    if (ticket.empty()) {
+      chromeos::Error::AddToPrintf(
+          &error, FROM_HERE, errors::kDomain, errors::kInvalidParams,
+          kInvalidParamValueFormat, kSetupStartTicketIdKey, "");
+      return ReturnError(*error, callback);
+    }
+    registration->GetString(kSetupStartUserKey, &user);
+  }
+
+  cloud_->UpdateDeviceInfo(name, description, location,
+                           base::Bind(&PrivetHandler::OnUpdateDeviceInfoDone,
+                                      weak_ptr_factory_.GetWeakPtr(), ssid,
+                                      passphrase, ticket, user, callback),
+                           base::Bind(&OnCommandRequestFailed, callback));
+}
+
+void PrivetHandler::OnUpdateDeviceInfoDone(
+    const std::string& ssid,
+    const std::string& passphrase,
+    const std::string& ticket,
+    const std::string& user,
+    const RequestCallback& callback) const {
+  chromeos::ErrorPtr error;
+
+  if (!ssid.empty() && !wifi_->ConfigureCredentials(ssid, passphrase, &error))
+    return ReturnError(*error, callback);
+
+  if (!ticket.empty() && !cloud_->Setup(ticket, user, &error))
+    return ReturnError(*error, callback);
+
+  ReplyWithSetupStatus(callback);
+}
+
+void PrivetHandler::HandleSetupStatus(const base::DictionaryValue&,
+                                      const UserInfo& user_info,
+                                      const RequestCallback& callback) {
+  ReplyWithSetupStatus(callback);
+}
+
+void PrivetHandler::ReplyWithSetupStatus(
+    const RequestCallback& callback) const {
+  base::DictionaryValue output;
+
+  const SetupState& state = cloud_->GetSetupState();
+  if (!state.IsStatusEqual(SetupState::kNone)) {
+    base::DictionaryValue* gcd = new base::DictionaryValue;
+    output.Set(kGcdKey, gcd);
+    SetState(state, gcd);
+    if (state.IsStatusEqual(SetupState::kSuccess))
+      gcd->SetString(kInfoIdKey, cloud_->GetCloudId());
+  }
+
+  if (wifi_) {
+    const SetupState& state = wifi_->GetSetupState();
+    if (!state.IsStatusEqual(SetupState::kNone)) {
+      base::DictionaryValue* wifi = new base::DictionaryValue;
+      output.Set(kWifiKey, wifi);
+      SetState(state, wifi);
+      if (state.IsStatusEqual(SetupState::kSuccess))
+        wifi->SetString(kInfoWifiSsidKey, wifi_->GetCurrentlyConnectedSsid());
+    }
+  }
+
+  callback.Run(chromeos::http::status_code::Ok, output);
+}
+
+void PrivetHandler::HandleState(const base::DictionaryValue& input,
+                                const UserInfo& user_info,
+                                const RequestCallback& callback) {
+  base::DictionaryValue output;
+  base::DictionaryValue* defs = cloud_->GetState().DeepCopy();
+  output.Set(kStateKey, defs);
+  output.SetString(kFingerprintKey, base::IntToString(state_fingerprint_));
+
+  callback.Run(chromeos::http::status_code::Ok, output);
+}
+
+void PrivetHandler::HandleCommandDefs(const base::DictionaryValue& input,
+                                      const UserInfo& user_info,
+                                      const RequestCallback& callback) {
+  base::DictionaryValue output;
+  base::DictionaryValue* defs = cloud_->GetCommandDef().DeepCopy();
+  output.Set(kCommandsKey, defs);
+  output.SetString(kFingerprintKey,
+                   base::IntToString(command_defs_fingerprint_));
+
+  callback.Run(chromeos::http::status_code::Ok, output);
+}
+
+void PrivetHandler::HandleCommandsExecute(const base::DictionaryValue& input,
+                                          const UserInfo& user_info,
+                                          const RequestCallback& callback) {
+  cloud_->AddCommand(input, user_info,
+                     base::Bind(&OnCommandRequestSucceeded, callback),
+                     base::Bind(&OnCommandRequestFailed, callback));
+}
+
+void PrivetHandler::HandleCommandsStatus(const base::DictionaryValue& input,
+                                         const UserInfo& user_info,
+                                         const RequestCallback& callback) {
+  std::string id;
+  if (!input.GetString(kCommandsIdKey, &id)) {
+    chromeos::ErrorPtr error;
+    chromeos::Error::AddToPrintf(
+        &error, FROM_HERE, errors::kDomain, errors::kInvalidParams,
+        kInvalidParamValueFormat, kCommandsIdKey, id.c_str());
+    return ReturnError(*error, callback);
+  }
+  cloud_->GetCommand(id, user_info,
+                     base::Bind(&OnCommandRequestSucceeded, callback),
+                     base::Bind(&OnCommandRequestFailed, callback));
+}
+
+void PrivetHandler::HandleCommandsList(const base::DictionaryValue& input,
+                                       const UserInfo& user_info,
+                                       const RequestCallback& callback) {
+  cloud_->ListCommands(user_info,
+                       base::Bind(&OnCommandRequestSucceeded, callback),
+                       base::Bind(&OnCommandRequestFailed, callback));
+}
+
+void PrivetHandler::HandleCommandsCancel(const base::DictionaryValue& input,
+                                         const UserInfo& user_info,
+                                         const RequestCallback& callback) {
+  std::string id;
+  if (!input.GetString(kCommandsIdKey, &id)) {
+    chromeos::ErrorPtr error;
+    chromeos::Error::AddToPrintf(
+        &error, FROM_HERE, errors::kDomain, errors::kInvalidParams,
+        kInvalidParamValueFormat, kCommandsIdKey, id.c_str());
+    return ReturnError(*error, callback);
+  }
+  cloud_->CancelCommand(id, user_info,
+                        base::Bind(&OnCommandRequestSucceeded, callback),
+                        base::Bind(&OnCommandRequestFailed, callback));
+}
+
+bool StringToPairingType(const std::string& mode, PairingType* id) {
+  return StringToEnum(mode, id);
+}
+
+std::string PairingTypeToString(PairingType id) {
+  return EnumToString(id);
+}
+
+bool StringToAuthScope(const std::string& scope, AuthScope* id) {
+  return StringToEnum(scope, id);
+}
+
+std::string AuthScopeToString(AuthScope id) {
+  return EnumToString(id);
+}
+
+}  // namespace privetd
diff --git a/buffet/privet/privet_handler.h b/buffet/privet/privet_handler.h
new file mode 100644
index 0000000..bb86c0a
--- /dev/null
+++ b/buffet/privet/privet_handler.h
@@ -0,0 +1,139 @@
+// Copyright 2014 The Chromium OS 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 BUFFET_PRIVET_PRIVET_HANDLER_H_
+#define BUFFET_PRIVET_PRIVET_HANDLER_H_
+
+#include <map>
+#include <string>
+#include <utility>
+
+#include <base/macros.h>
+#include <base/memory/weak_ptr.h>
+#include <base/scoped_observer.h>
+
+#include "buffet/privet/cloud_delegate.h"
+
+namespace base {
+class Value;
+class DictionaryValue;
+}  // namespace base
+
+namespace privetd {
+
+class DeviceDelegate;
+class IdentityDelegate;
+class SecurityDelegate;
+class WifiDelegate;
+
+enum class AuthScope;
+
+// Privet V3 HTTP/HTTPS requests handler.
+// API details at https://developers.google.com/cloud-devices/
+class PrivetHandler : public CloudDelegate::Observer {
+ public:
+  // Callback to handle requests asynchronously.
+  // |status| is HTTP status code.
+  // |output| is result returned in HTTP response. Contains result of
+  // successfully request of information about error.
+  using RequestCallback =
+      base::Callback<void(int status, const base::DictionaryValue& output)>;
+
+  PrivetHandler(CloudDelegate* cloud,
+                DeviceDelegate* device,
+                SecurityDelegate* pairing,
+                WifiDelegate* wifi,
+                IdentityDelegate* identity);
+  ~PrivetHandler() override;
+
+  void OnCommandDefsChanged() override;
+  void OnStateChanged() override;
+
+  // Handles HTTP/HTTPS Privet request.
+  // |api| is the path from the HTTP request, e.g /privet/info.
+  // |auth_header| is the Authentication header from HTTP request.
+  // |input| is the the POST data from HTTP request. If nullptr, data format is
+  // not valid JSON.
+  // |callback| will be called exactly once during or after |HandleRequest|
+  // call.
+  void HandleRequest(const std::string& api,
+                     const std::string& auth_header,
+                     const base::DictionaryValue* input,
+                     const RequestCallback& callback);
+
+ private:
+  using ApiHandler = void (PrivetHandler::*)(const base::DictionaryValue&,
+                                             const UserInfo&,
+                                             const RequestCallback&);
+
+  void AddHandler(const std::string& path, ApiHandler handler, AuthScope scope);
+
+  void HandleInfo(const base::DictionaryValue&,
+                  const UserInfo& user_info,
+                  const RequestCallback& callback);
+  void HandlePairingStart(const base::DictionaryValue& input,
+                          const UserInfo& user_info,
+                          const RequestCallback& callback);
+  void HandlePairingConfirm(const base::DictionaryValue& input,
+                            const UserInfo& user_info,
+                            const RequestCallback& callback);
+  void HandlePairingCancel(const base::DictionaryValue& input,
+                           const UserInfo& user_info,
+                           const RequestCallback& callback);
+  void HandleAuth(const base::DictionaryValue& input,
+                  const UserInfo& user_info,
+                  const RequestCallback& callback);
+  void HandleSetupStart(const base::DictionaryValue& input,
+                        const UserInfo& user_info,
+                        const RequestCallback& callback);
+  void HandleSetupStatus(const base::DictionaryValue&,
+                         const UserInfo& user_info,
+                         const RequestCallback& callback);
+  void HandleState(const base::DictionaryValue& input,
+                   const UserInfo& user_info,
+                   const RequestCallback& callback);
+  void HandleCommandDefs(const base::DictionaryValue& input,
+                         const UserInfo& user_info,
+                         const RequestCallback& callback);
+  void HandleCommandsExecute(const base::DictionaryValue& input,
+                             const UserInfo& user_info,
+                             const RequestCallback& callback);
+  void HandleCommandsStatus(const base::DictionaryValue& input,
+                            const UserInfo& user_info,
+                            const RequestCallback& callback);
+  void HandleCommandsList(const base::DictionaryValue& input,
+                          const UserInfo& user_info,
+                          const RequestCallback& callback);
+  void HandleCommandsCancel(const base::DictionaryValue& input,
+                            const UserInfo& user_info,
+                            const RequestCallback& callback);
+
+  void OnUpdateDeviceInfoDone(const std::string& ssid,
+                              const std::string& passphrase,
+                              const std::string& ticket,
+                              const std::string& user,
+                              const RequestCallback& callback) const;
+  void ReplyWithSetupStatus(const RequestCallback& callback) const;
+
+  CloudDelegate* cloud_ = nullptr;
+  DeviceDelegate* device_ = nullptr;
+  SecurityDelegate* security_ = nullptr;
+  WifiDelegate* wifi_ = nullptr;
+  IdentityDelegate* identity_ = nullptr;
+
+  std::map<std::string, std::pair<AuthScope, ApiHandler>> handlers_;
+
+  uint64_t last_user_id_{0};
+  int state_fingerprint_{0};
+  int command_defs_fingerprint_{0};
+  ScopedObserver<CloudDelegate, CloudDelegate::Observer> cloud_observer_{this};
+
+  base::WeakPtrFactory<PrivetHandler> weak_ptr_factory_{this};
+
+  DISALLOW_COPY_AND_ASSIGN(PrivetHandler);
+};
+
+}  // namespace privetd
+
+#endif  // BUFFET_PRIVET_PRIVET_HANDLER_H_
diff --git a/buffet/privet/privet_handler_unittest.cc b/buffet/privet/privet_handler_unittest.cc
new file mode 100644
index 0000000..e2dcfd3
--- /dev/null
+++ b/buffet/privet/privet_handler_unittest.cc
@@ -0,0 +1,724 @@
+// Copyright 2014 The Chromium OS 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 "buffet/privet/privet_handler.h"
+
+#include <set>
+#include <string>
+#include <utility>
+
+#include <base/bind.h>
+#include <base/json/json_reader.h>
+#include <base/json/json_writer.h>
+#include <base/run_loop.h>
+#include <base/strings/string_util.h>
+#include <base/values.h>
+#include <chromeos/http/http_request.h>
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+
+#include "buffet/privet/constants.h"
+#include "buffet/privet/mock_delegates.h"
+
+using testing::_;
+using testing::DoAll;
+using testing::Invoke;
+using testing::Return;
+using testing::SetArgPointee;
+
+namespace privetd {
+
+namespace {
+
+void LoadTestJson(const std::string& test_json,
+                  base::DictionaryValue* dictionary) {
+  std::string json = test_json;
+  base::ReplaceChars(json, "'", "\"", &json);
+  int error = 0;
+  std::string message;
+  std::unique_ptr<base::Value> value(base::JSONReader::ReadAndReturnError(
+      json, base::JSON_PARSE_RFC, &error, &message));
+  EXPECT_TRUE(value.get()) << "\nError: " << message << "\n" << json;
+  base::DictionaryValue* dictionary_ptr = nullptr;
+  if (value->GetAsDictionary(&dictionary_ptr))
+    dictionary->MergeDictionary(dictionary_ptr);
+}
+
+bool IsEqualValue(const base::Value& val1, const base::Value& val2) {
+  return val1.Equals(&val2);
+}
+
+struct CodeWithReason {
+  CodeWithReason(int code_in, const std::string& reason_in)
+      : code(code_in), reason(reason_in) {}
+  int code;
+  std::string reason;
+};
+
+std::ostream& operator<<(std::ostream& stream, const CodeWithReason& error) {
+  return stream << "{" << error.code << ", " << error.reason << "}";
+}
+
+bool IsEqualError(const CodeWithReason& expected,
+                  const base::DictionaryValue& dictionary) {
+  std::string reason;
+  int code = 0;
+  return dictionary.GetInteger("error.http_status", &code) &&
+         code == expected.code && dictionary.GetString("error.code", &reason) &&
+         reason == expected.reason;
+}
+
+bool IsEqualDictionary(const base::DictionaryValue& dictionary1,
+                       const base::DictionaryValue& dictionary2) {
+  base::DictionaryValue::Iterator it1(dictionary1);
+  base::DictionaryValue::Iterator it2(dictionary2);
+  for (; !it1.IsAtEnd() && !it2.IsAtEnd(); it1.Advance(), it2.Advance()) {
+    // Output mismatched keys.
+    EXPECT_EQ(it1.key(), it2.key());
+    if (it1.key() != it2.key())
+      return false;
+
+    if (it1.key() == "error") {
+      std::string code1;
+      std::string code2;
+      const char kCodeKey[] = "error.code";
+      if (!dictionary1.GetString(kCodeKey, &code1) ||
+          !dictionary2.GetString(kCodeKey, &code2) || code1 != code2) {
+        return false;
+      }
+      continue;
+    }
+
+    const base::DictionaryValue* d1{nullptr};
+    const base::DictionaryValue* d2{nullptr};
+    if (it1.value().GetAsDictionary(&d1) && it2.value().GetAsDictionary(&d2)) {
+      if (!IsEqualDictionary(*d1, *d2))
+        return false;
+      continue;
+    }
+
+    // Output mismatched values.
+    EXPECT_PRED2(IsEqualValue, it1.value(), it2.value());
+    if (!IsEqualValue(it1.value(), it2.value()))
+      return false;
+  }
+
+  return it1.IsAtEnd() && it2.IsAtEnd();
+}
+
+bool IsEqualJson(const std::string& test_json,
+                 const base::DictionaryValue& dictionary) {
+  base::DictionaryValue dictionary2;
+  LoadTestJson(test_json, &dictionary2);
+  return IsEqualDictionary(dictionary2, dictionary);
+}
+
+}  // namespace
+
+class PrivetHandlerTest : public testing::Test {
+ public:
+  PrivetHandlerTest() {}
+
+ protected:
+  void SetUp() override {
+    auth_header_ = "Privet anonymous";
+    handler_.reset(
+        new PrivetHandler(&cloud_, &device_, &security_, &wifi_, &identity_));
+  }
+
+  const base::DictionaryValue& HandleRequest(
+      const std::string& api,
+      const base::DictionaryValue* input) {
+    output_.Clear();
+    handler_->HandleRequest(api, auth_header_, input,
+                            base::Bind(&PrivetHandlerTest::HandlerCallback,
+                                       base::Unretained(this)));
+    base::RunLoop().RunUntilIdle();
+    return output_;
+  }
+
+  const base::DictionaryValue& HandleRequest(const std::string& api,
+                                             const std::string& json_input) {
+    base::DictionaryValue dictionary;
+    LoadTestJson(json_input, &dictionary);
+    return HandleRequest(api, &dictionary);
+  }
+
+  void HandleUnknownRequest(const std::string& api) {
+    output_.Clear();
+    base::DictionaryValue dictionary;
+    handler_->HandleRequest(api, auth_header_, &dictionary,
+                            base::Bind(&PrivetHandlerTest::HandlerNoFound));
+    base::RunLoop().RunUntilIdle();
+  }
+
+  void SetNoWifiAndGcd() {
+    handler_.reset(
+        new PrivetHandler(&cloud_, &device_, &security_, nullptr, &identity_));
+    EXPECT_CALL(cloud_, GetCloudId()).WillRepeatedly(Return(""));
+    EXPECT_CALL(cloud_, GetConnectionState())
+        .WillRepeatedly(ReturnRef(gcd_disabled_state_));
+    auto set_error =
+        [](const std::string&, const std::string&, chromeos::ErrorPtr* error) {
+          chromeos::Error::AddTo(error, FROM_HERE, errors::kDomain,
+                                 "setupUnavailable", "");
+        };
+    EXPECT_CALL(cloud_, Setup(_, _, _))
+        .WillRepeatedly(DoAll(Invoke(set_error), Return(false)));
+  }
+
+  testing::StrictMock<MockCloudDelegate> cloud_;
+  testing::StrictMock<MockDeviceDelegate> device_;
+  testing::StrictMock<MockSecurityDelegate> security_;
+  testing::StrictMock<MockWifiDelegate> wifi_;
+  testing::StrictMock<MockIdentityDelegate> identity_;
+  std::string auth_header_;
+
+ private:
+  void HandlerCallback(int status, const base::DictionaryValue& output) {
+    output_.MergeDictionary(&output);
+    if (!output_.HasKey("error")) {
+      EXPECT_EQ(chromeos::http::status_code::Ok, status);
+      return;
+    }
+    EXPECT_NE(chromeos::http::status_code::Ok, status);
+    output_.SetInteger("error.http_status", status);
+  }
+
+  static void HandlerNoFound(int status, const base::DictionaryValue&) {
+    EXPECT_EQ(status, 404);
+  }
+
+  base::MessageLoop message_loop_;
+  std::unique_ptr<PrivetHandler> handler_;
+  base::DictionaryValue output_;
+  ConnectionState gcd_disabled_state_{ConnectionState::kDisabled};
+};
+
+TEST_F(PrivetHandlerTest, UnknownApi) {
+  HandleUnknownRequest("/privet/foo");
+}
+
+TEST_F(PrivetHandlerTest, InvalidFormat) {
+  auth_header_ = "";
+  EXPECT_PRED2(IsEqualError, CodeWithReason(400, "invalidFormat"),
+               HandleRequest("/privet/info", nullptr));
+}
+
+TEST_F(PrivetHandlerTest, MissingAuth) {
+  auth_header_ = "";
+  EXPECT_PRED2(IsEqualError, CodeWithReason(401, "missingAuthorization"),
+               HandleRequest("/privet/info", "{}"));
+}
+
+TEST_F(PrivetHandlerTest, InvalidAuth) {
+  auth_header_ = "foo";
+  EXPECT_PRED2(IsEqualError, CodeWithReason(401, "invalidAuthorization"),
+               HandleRequest("/privet/info", "{}"));
+}
+
+TEST_F(PrivetHandlerTest, ExpiredAuth) {
+  auth_header_ = "Privet 123";
+  EXPECT_CALL(security_, ParseAccessToken(_, _))
+      .WillRepeatedly(DoAll(SetArgPointee<1>(base::Time()),
+                            Return(UserInfo{AuthScope::kOwner, 1})));
+  EXPECT_PRED2(IsEqualError, CodeWithReason(403, "authorizationExpired"),
+               HandleRequest("/privet/info", "{}"));
+}
+
+TEST_F(PrivetHandlerTest, InvalidAuthScope) {
+  EXPECT_PRED2(IsEqualError, CodeWithReason(403, "invalidAuthorizationScope"),
+               HandleRequest("/privet/v3/setup/start", "{}"));
+}
+
+TEST_F(PrivetHandlerTest, InfoMinimal) {
+  SetNoWifiAndGcd();
+  EXPECT_CALL(security_, GetPairingTypes())
+      .WillRepeatedly(Return(std::set<PairingType>{}));
+  EXPECT_CALL(security_, GetCryptoTypes())
+      .WillRepeatedly(Return(std::set<CryptoType>{}));
+
+  const char kExpected[] = R"({
+    'version': '3.0',
+    'id': 'TestId',
+    'name': 'TestDevice',
+    'services': [],
+    'modelManifestId': "ABMID",
+    'basicModelManifest': {
+      'uiDeviceKind': 'developmentBoard',
+      'oemName': 'Chromium',
+      'modelName': 'Brillo'
+    },
+    'endpoints': {
+      'httpPort': 0,
+      'httpUpdatesPort': 0,
+      'httpsPort': 0,
+      'httpsUpdatesPort': 0
+    },
+    'authentication': {
+      'anonymousMaxScope': 'user',
+      'mode': [
+        'anonymous',
+        'pairing'
+      ],
+      'pairing': [
+      ],
+      'crypto': [
+      ]
+    },
+    'gcd': {
+      'id': '',
+      'status': 'disabled'
+    },
+    'uptime': 3600
+  })";
+  EXPECT_PRED2(IsEqualJson, kExpected, HandleRequest("/privet/info", "{}"));
+}
+
+TEST_F(PrivetHandlerTest, Info) {
+  EXPECT_CALL(cloud_, GetDescription())
+      .WillRepeatedly(Return("TestDescription"));
+  EXPECT_CALL(cloud_, GetLocation()).WillRepeatedly(Return("TestLocation"));
+  EXPECT_CALL(cloud_, GetServices())
+      .WillRepeatedly(Return(std::set<std::string>{"service1", "service2"}));
+  EXPECT_CALL(device_, GetHttpEnpoint())
+      .WillRepeatedly(Return(std::make_pair(80, 10080)));
+  EXPECT_CALL(device_, GetHttpsEnpoint())
+      .WillRepeatedly(Return(std::make_pair(443, 10443)));
+  EXPECT_CALL(wifi_, GetHostedSsid())
+      .WillRepeatedly(Return("Test_device.BBABCLAprv"));
+
+  const char kExpected[] = R"({
+    'version': '3.0',
+    'id': 'TestId',
+    'name': 'TestDevice',
+    'description': 'TestDescription',
+    'location': 'TestLocation',
+    'services': [
+      "service1",
+      "service2"
+    ],
+    'modelManifestId': "ABMID",
+    'basicModelManifest': {
+      'uiDeviceKind': 'developmentBoard',
+      'oemName': 'Chromium',
+      'modelName': 'Brillo'
+    },
+    'endpoints': {
+      'httpPort': 80,
+      'httpUpdatesPort': 10080,
+      'httpsPort': 443,
+      'httpsUpdatesPort': 10443
+    },
+    'authentication': {
+      'anonymousMaxScope': 'none',
+      'mode': [
+        'anonymous',
+        'pairing'
+      ],
+      'pairing': [
+        'pinCode',
+        'embeddedCode',
+        'ultrasound32',
+        'audible32'
+      ],
+      'crypto': [
+        'p224_spake2',
+        'p256_spake2'
+      ]
+    },
+    'wifi': {
+      'capabilities': [
+        '2.4GHz'
+      ],
+      'ssid': 'TestSsid',
+      'hostedSsid': 'Test_device.BBABCLAprv',
+      'status': 'offline'
+    },
+    'gcd': {
+      'id': 'TestCloudId',
+      'status': 'online'
+    },
+    'uptime': 3600
+  })";
+  EXPECT_PRED2(IsEqualJson, kExpected, HandleRequest("/privet/info", "{}"));
+}
+
+TEST_F(PrivetHandlerTest, PairingStartInvalidParams) {
+  EXPECT_PRED2(IsEqualError, CodeWithReason(400, "invalidParams"),
+               HandleRequest("/privet/v3/pairing/start",
+                             "{'pairing':'embeddedCode','crypto':'crypto'}"));
+
+  EXPECT_PRED2(IsEqualError, CodeWithReason(400, "invalidParams"),
+               HandleRequest("/privet/v3/pairing/start",
+                             "{'pairing':'code','crypto':'p256_spake2'}"));
+}
+
+TEST_F(PrivetHandlerTest, PairingStart) {
+  EXPECT_PRED2(
+      IsEqualJson,
+      "{'deviceCommitment': 'testCommitment', 'sessionId': 'testSession'}",
+      HandleRequest("/privet/v3/pairing/start",
+                    "{'pairing': 'embeddedCode', 'crypto': 'p256_spake2'}"));
+}
+
+TEST_F(PrivetHandlerTest, PairingConfirm) {
+  EXPECT_PRED2(
+      IsEqualJson,
+      "{'certFingerprint':'testFingerprint','certSignature':'testSignature'}",
+      HandleRequest(
+          "/privet/v3/pairing/confirm",
+          "{'sessionId':'testSession','clientCommitment':'testCommitment'}"));
+}
+
+TEST_F(PrivetHandlerTest, PairingCancel) {
+  EXPECT_PRED2(IsEqualJson, "{}",
+               HandleRequest("/privet/v3/pairing/cancel",
+                             "{'sessionId': 'testSession'}"));
+}
+
+TEST_F(PrivetHandlerTest, AuthErrorNoType) {
+  EXPECT_PRED2(IsEqualError, CodeWithReason(400, "invalidAuthMode"),
+               HandleRequest("/privet/v3/auth", "{}"));
+}
+
+TEST_F(PrivetHandlerTest, AuthErrorInvalidType) {
+  EXPECT_PRED2(IsEqualError, CodeWithReason(400, "invalidAuthMode"),
+               HandleRequest("/privet/v3/auth", "{'mode':'unknown'}"));
+}
+
+TEST_F(PrivetHandlerTest, AuthErrorNoScope) {
+  EXPECT_PRED2(IsEqualError, CodeWithReason(400, "invalidRequestedScope"),
+               HandleRequest("/privet/v3/auth", "{'mode':'anonymous'}"));
+}
+
+TEST_F(PrivetHandlerTest, AuthErrorInvalidScope) {
+  EXPECT_PRED2(
+      IsEqualError, CodeWithReason(400, "invalidRequestedScope"),
+      HandleRequest("/privet/v3/auth",
+                    "{'mode':'anonymous','requestedScope':'unknown'}"));
+}
+
+TEST_F(PrivetHandlerTest, AuthErrorAccessDenied) {
+  EXPECT_PRED2(IsEqualError, CodeWithReason(403, "accessDenied"),
+               HandleRequest("/privet/v3/auth",
+                             "{'mode':'anonymous','requestedScope':'owner'}"));
+}
+
+TEST_F(PrivetHandlerTest, AuthErrorInvalidAuthCode) {
+  EXPECT_CALL(security_, IsValidPairingCode("testToken"))
+      .WillRepeatedly(Return(false));
+  const char kInput[] = R"({
+    'mode': 'pairing',
+    'requestedScope': 'user',
+    'authCode': 'testToken'
+  })";
+  EXPECT_PRED2(IsEqualError, CodeWithReason(403, "invalidAuthCode"),
+               HandleRequest("/privet/v3/auth", kInput));
+}
+
+TEST_F(PrivetHandlerTest, AuthAnonymous) {
+  const char kExpected[] = R"({
+    'accessToken': 'GuestAccessToken',
+    'expiresIn': 3600,
+    'scope': 'user',
+    'tokenType': 'Privet'
+  })";
+  EXPECT_PRED2(IsEqualJson, kExpected,
+               HandleRequest("/privet/v3/auth",
+                             "{'mode':'anonymous','requestedScope':'auto'}"));
+}
+
+TEST_F(PrivetHandlerTest, AuthPairing) {
+  EXPECT_CALL(security_, IsValidPairingCode("testToken"))
+      .WillRepeatedly(Return(true));
+  EXPECT_CALL(security_, CreateAccessToken(_, _))
+      .WillRepeatedly(Return("OwnerAccessToken"));
+  const char kInput[] = R"({
+    'mode': 'pairing',
+    'requestedScope': 'owner',
+    'authCode': 'testToken'
+  })";
+  const char kExpected[] = R"({
+    'accessToken': 'OwnerAccessToken',
+    'expiresIn': 3600,
+    'scope': 'owner',
+    'tokenType': 'Privet'
+  })";
+  EXPECT_PRED2(
+      IsEqualJson, kExpected, HandleRequest("/privet/v3/auth", kInput));
+}
+
+class PrivetHandlerSetupTest : public PrivetHandlerTest {
+ public:
+  void SetUp() override {
+    PrivetHandlerTest::SetUp();
+    auth_header_ = "Privet 123";
+    EXPECT_CALL(security_, ParseAccessToken(_, _))
+        .WillRepeatedly(DoAll(SetArgPointee<1>(base::Time::Now()),
+                              Return(UserInfo{AuthScope::kOwner, 1})));
+  }
+};
+
+TEST_F(PrivetHandlerSetupTest, StatusEmpty) {
+  SetNoWifiAndGcd();
+  EXPECT_PRED2(
+      IsEqualJson, "{}", HandleRequest("/privet/v3/setup/status", "{}"));
+}
+
+TEST_F(PrivetHandlerSetupTest, StatusWifi) {
+  wifi_.setup_state_ = SetupState{SetupState::kSuccess};
+
+  const char kExpected[] = R"({
+    'wifi': {
+        'ssid': 'TestSsid',
+        'status': 'success'
+     }
+  })";
+  EXPECT_PRED2(
+      IsEqualJson, kExpected, HandleRequest("/privet/v3/setup/status", "{}"));
+}
+
+TEST_F(PrivetHandlerSetupTest, StatusWifiError) {
+  chromeos::ErrorPtr error;
+  chromeos::Error::AddTo(&error, FROM_HERE, "test", "invalidPassphrase", "");
+  wifi_.setup_state_ = SetupState{std::move(error)};
+
+  const char kExpected[] = R"({
+    'wifi': {
+        'status': 'error',
+        'error': {
+          'code': 'invalidPassphrase'
+        }
+     }
+  })";
+  EXPECT_PRED2(
+      IsEqualJson, kExpected, HandleRequest("/privet/v3/setup/status", "{}"));
+}
+
+TEST_F(PrivetHandlerSetupTest, StatusGcd) {
+  cloud_.setup_state_ = SetupState{SetupState::kSuccess};
+
+  const char kExpected[] = R"({
+    'gcd': {
+        'id': 'TestCloudId',
+        'status': 'success'
+     }
+  })";
+  EXPECT_PRED2(
+      IsEqualJson, kExpected, HandleRequest("/privet/v3/setup/status", "{}"));
+}
+
+TEST_F(PrivetHandlerSetupTest, StatusGcdError) {
+  chromeos::ErrorPtr error;
+  chromeos::Error::AddTo(&error, FROM_HERE, "test", "invalidTicket", "");
+  cloud_.setup_state_ = SetupState{std::move(error)};
+
+  const char kExpected[] = R"({
+    'gcd': {
+        'status': 'error',
+        'error': {
+          'code': 'invalidTicket'
+        }
+     }
+  })";
+  EXPECT_PRED2(
+      IsEqualJson, kExpected, HandleRequest("/privet/v3/setup/status", "{}"));
+}
+
+TEST_F(PrivetHandlerSetupTest, SetupNameDescriptionLocation) {
+  EXPECT_CALL(cloud_, UpdateDeviceInfo("testName", "testDescription",
+                                       "testLocation", _, _)).Times(1);
+  const char kInput[] = R"({
+    'name': 'testName',
+    'description': 'testDescription',
+    'location': 'testLocation'
+  })";
+  EXPECT_PRED2(IsEqualJson, "{}",
+               HandleRequest("/privet/v3/setup/start", kInput));
+}
+
+TEST_F(PrivetHandlerSetupTest, InvalidParams) {
+  const char kInputWifi[] = R"({
+    'wifi': {
+      'ssid': ''
+    }
+  })";
+  EXPECT_PRED2(IsEqualError, CodeWithReason(400, "invalidParams"),
+               HandleRequest("/privet/v3/setup/start", kInputWifi));
+
+  const char kInputRegistration[] = R"({
+    'gcd': {
+      'ticketId': ''
+    }
+  })";
+  EXPECT_PRED2(IsEqualError, CodeWithReason(400, "invalidParams"),
+               HandleRequest("/privet/v3/setup/start", kInputRegistration));
+}
+
+TEST_F(PrivetHandlerSetupTest, WifiSetupUnavailable) {
+  SetNoWifiAndGcd();
+  EXPECT_PRED2(IsEqualError, CodeWithReason(400, "setupUnavailable"),
+               HandleRequest("/privet/v3/setup/start", "{'wifi': {}}"));
+}
+
+TEST_F(PrivetHandlerSetupTest, WifiSetup) {
+  const char kInput[] = R"({
+    'wifi': {
+      'ssid': 'testSsid',
+      'passphrase': 'testPass'
+    }
+  })";
+  auto set_error = [](const std::string&, const std::string&,
+                      chromeos::ErrorPtr* error) {
+    chromeos::Error::AddTo(error, FROM_HERE, errors::kDomain, "deviceBusy", "");
+  };
+  EXPECT_CALL(wifi_, ConfigureCredentials(_, _, _))
+      .WillOnce(DoAll(Invoke(set_error), Return(false)));
+  EXPECT_PRED2(IsEqualError, CodeWithReason(503, "deviceBusy"),
+               HandleRequest("/privet/v3/setup/start", kInput));
+
+  const char kExpected[] = R"({
+    'wifi': {
+      'status': 'inProgress'
+    }
+  })";
+  wifi_.setup_state_ = SetupState{SetupState::kInProgress};
+  EXPECT_CALL(wifi_, ConfigureCredentials("testSsid", "testPass", _))
+      .WillOnce(Return(true));
+  EXPECT_PRED2(IsEqualJson, kExpected,
+               HandleRequest("/privet/v3/setup/start", kInput));
+}
+
+TEST_F(PrivetHandlerSetupTest, GcdSetupUnavailable) {
+  SetNoWifiAndGcd();
+  const char kInput[] = R"({
+    'gcd': {
+      'ticketId': 'testTicket',
+      'user': 'testUser'
+    }
+  })";
+
+  EXPECT_PRED2(IsEqualError, CodeWithReason(400, "setupUnavailable"),
+               HandleRequest("/privet/v3/setup/start", kInput));
+}
+
+TEST_F(PrivetHandlerSetupTest, GcdSetup) {
+  const char kInput[] = R"({
+    'gcd': {
+      'ticketId': 'testTicket',
+      'user': 'testUser'
+    }
+  })";
+
+  auto set_error = [](const std::string&, const std::string&,
+                      chromeos::ErrorPtr* error) {
+    chromeos::Error::AddTo(error, FROM_HERE, errors::kDomain, "deviceBusy", "");
+  };
+  EXPECT_CALL(cloud_, Setup(_, _, _))
+      .WillOnce(DoAll(Invoke(set_error), Return(false)));
+  EXPECT_PRED2(IsEqualError, CodeWithReason(503, "deviceBusy"),
+               HandleRequest("/privet/v3/setup/start", kInput));
+
+  const char kExpected[] = R"({
+    'gcd': {
+      'status': 'inProgress'
+    }
+  })";
+  cloud_.setup_state_ = SetupState{SetupState::kInProgress};
+  EXPECT_CALL(cloud_, Setup("testTicket", "testUser", _))
+      .WillOnce(Return(true));
+  EXPECT_PRED2(IsEqualJson, kExpected,
+               HandleRequest("/privet/v3/setup/start", kInput));
+}
+
+TEST_F(PrivetHandlerSetupTest, State) {
+  EXPECT_PRED2(IsEqualJson, "{'state': {'test': {}}, 'fingerprint': '0'}",
+               HandleRequest("/privet/v3/state", "{}"));
+
+  cloud_.NotifyOnStateChanged();
+
+  EXPECT_PRED2(IsEqualJson, "{'state': {'test': {}}, 'fingerprint': '1'}",
+               HandleRequest("/privet/v3/state", "{}"));
+}
+
+TEST_F(PrivetHandlerSetupTest, CommandsDefs) {
+  EXPECT_PRED2(IsEqualJson, "{'commands': {'test':{}}, 'fingerprint': '0'}",
+               HandleRequest("/privet/v3/commandDefs", "{}"));
+
+  cloud_.NotifyOnCommandDefsChanged();
+
+  EXPECT_PRED2(IsEqualJson, "{'commands': {'test':{}}, 'fingerprint': '1'}",
+               HandleRequest("/privet/v3/commandDefs", "{}"));
+}
+
+TEST_F(PrivetHandlerSetupTest, CommandsExecute) {
+  const char kInput[] = "{'name': 'test'}";
+  base::DictionaryValue command;
+  LoadTestJson(kInput, &command);
+  LoadTestJson("{'id':'5'}", &command);
+  EXPECT_CALL(cloud_, AddCommand(_, _, _, _))
+      .WillOnce(RunCallback<2, const base::DictionaryValue&>(command));
+
+  EXPECT_PRED2(IsEqualJson, "{'name':'test', 'id':'5'}",
+               HandleRequest("/privet/v3/commands/execute", kInput));
+}
+
+TEST_F(PrivetHandlerSetupTest, CommandsStatus) {
+  const char kInput[] = "{'id': '5'}";
+  base::DictionaryValue command;
+  LoadTestJson(kInput, &command);
+  LoadTestJson("{'name':'test'}", &command);
+  EXPECT_CALL(cloud_, GetCommand(_, _, _, _))
+      .WillOnce(RunCallback<2, const base::DictionaryValue&>(command));
+
+  EXPECT_PRED2(IsEqualJson, "{'name':'test', 'id':'5'}",
+               HandleRequest("/privet/v3/commands/status", kInput));
+
+  chromeos::ErrorPtr error;
+  chromeos::Error::AddTo(&error, FROM_HERE, errors::kDomain, "notFound", "");
+  EXPECT_CALL(cloud_, GetCommand(_, _, _, _))
+      .WillOnce(RunCallback<3>(error.get()));
+
+  EXPECT_PRED2(IsEqualError, CodeWithReason(404, "notFound"),
+               HandleRequest("/privet/v3/commands/status", "{'id': '15'}"));
+}
+
+TEST_F(PrivetHandlerSetupTest, CommandsCancel) {
+  const char kExpected[] = "{'id': '5', 'name':'test', 'state':'cancelled'}";
+  base::DictionaryValue command;
+  LoadTestJson(kExpected, &command);
+  EXPECT_CALL(cloud_, CancelCommand(_, _, _, _))
+      .WillOnce(RunCallback<2, const base::DictionaryValue&>(command));
+
+  EXPECT_PRED2(IsEqualJson, kExpected,
+               HandleRequest("/privet/v3/commands/cancel", "{'id': '8'}"));
+
+  chromeos::ErrorPtr error;
+  chromeos::Error::AddTo(&error, FROM_HERE, errors::kDomain, "notFound", "");
+  EXPECT_CALL(cloud_, CancelCommand(_, _, _, _))
+      .WillOnce(RunCallback<3>(error.get()));
+
+  EXPECT_PRED2(IsEqualError, CodeWithReason(404, "notFound"),
+               HandleRequest("/privet/v3/commands/cancel", "{'id': '11'}"));
+}
+
+TEST_F(PrivetHandlerSetupTest, CommandsList) {
+  const char kExpected[] = R"({
+    'commands' : [
+        {'id':'5', 'state':'cancelled'},
+        {'id':'15', 'state':'inProgress'}
+     ]})";
+
+  base::DictionaryValue commands;
+  LoadTestJson(kExpected, &commands);
+
+  EXPECT_CALL(cloud_, ListCommands(_, _, _))
+      .WillOnce(RunCallback<1, const base::DictionaryValue&>(commands));
+
+  EXPECT_PRED2(IsEqualJson, kExpected,
+               HandleRequest("/privet/v3/commands/list", "{}"));
+}
+
+}  // namespace privetd
diff --git a/buffet/privet/privet_types.h b/buffet/privet/privet_types.h
new file mode 100644
index 0000000..c1e2ba0
--- /dev/null
+++ b/buffet/privet/privet_types.h
@@ -0,0 +1,98 @@
+// Copyright 2014 The Chromium OS 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 BUFFET_PRIVET_PRIVET_TYPES_H_
+#define BUFFET_PRIVET_PRIVET_TYPES_H_
+
+#include <string>
+
+#include <chromeos/errors/error.h>
+
+namespace privetd {
+
+// Scopes in order of increasing privileges.
+enum class AuthScope {
+  kNone,
+  kViewer,
+  kUser,
+  kOwner,
+};
+
+class UserInfo {
+ public:
+  explicit UserInfo(AuthScope scope = AuthScope::kNone, uint64_t user_id = 0)
+      : scope_{scope}, user_id_{scope == AuthScope::kNone ? 0 : user_id} {}
+  AuthScope scope() const { return scope_; }
+  uint64_t user_id() const { return user_id_; }
+
+ private:
+  AuthScope scope_;
+  uint64_t user_id_;
+};
+
+class ConnectionState final {
+ public:
+  enum Status {
+    kDisabled,
+    kUnconfigured,
+    kConnecting,
+    kOnline,
+    kOffline,
+  };
+
+  explicit ConnectionState(Status status) : status_(status) {}
+  explicit ConnectionState(chromeos::ErrorPtr error)
+      : status_(kOffline), error_(std::move(error)) {}
+
+  Status status() const {
+    CHECK(!error_);
+    return status_;
+  }
+
+  bool IsStatusEqual(Status status) const {
+    if (error_)
+      return false;
+    return status_ == status;
+  }
+
+  const chromeos::Error* error() const { return error_.get(); }
+
+ private:
+  Status status_;
+  chromeos::ErrorPtr error_;
+};
+
+class SetupState final {
+ public:
+  enum Status {
+    kNone,
+    kInProgress,
+    kSuccess,
+  };
+
+  explicit SetupState(Status status) : status_(status) {}
+  explicit SetupState(chromeos::ErrorPtr error)
+      : status_(kNone), error_(std::move(error)) {}
+
+  Status status() const {
+    CHECK(!error_);
+    return status_;
+  }
+
+  bool IsStatusEqual(Status status) const {
+    if (error_)
+      return false;
+    return status_ == status;
+  }
+
+  const chromeos::Error* error() const { return error_.get(); }
+
+ private:
+  Status status_;
+  chromeos::ErrorPtr error_;
+};
+
+}  // namespace privetd
+
+#endif  // BUFFET_PRIVET_PRIVET_TYPES_H_
diff --git a/buffet/privet/privetd_conf_parser.cc b/buffet/privet/privetd_conf_parser.cc
new file mode 100644
index 0000000..6ebe155
--- /dev/null
+++ b/buffet/privet/privetd_conf_parser.cc
@@ -0,0 +1,146 @@
+// Copyright 2015 The Chromium OS 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 "buffet/privet/privetd_conf_parser.h"
+
+#include <base/logging.h>
+#include <base/strings/string_number_conversions.h>
+#include <chromeos/strings/string_utils.h>
+
+#include "buffet/privet/security_delegate.h"
+
+namespace privetd {
+
+namespace {
+
+const char kWiFiBootstrapMode[] = "wifi_bootstrapping_mode";
+const char kGcdBootstrapMode[] = "gcd_bootstrapping_mode";
+const char kConnectTimeout[] = "connect_timeout_seconds";
+const char kBootstrapTimeout[] = "bootstrap_timeout_seconds";
+const char kMonitorTimeout[] = "monitor_timeout_seconds";
+const char kPairingModes[] = "pairing_modes";
+const char kEmbeddedCodePath[] = "embedded_code_path";
+
+const char kBootstrapModeOff[] = "off";
+const char kBootstrapModeAutomatic[] = "automatic";
+const char kBootstrapModeManual[] = "manual";
+
+}  // namespace
+
+const char kWiFiBootstrapInterfaces[] = "automatic_mode_interfaces";
+
+PrivetdConfigParser::PrivetdConfigParser()
+    : wifi_bootstrap_mode_{WiFiBootstrapMode::kDisabled},
+      gcd_bootstrap_mode_{GcdBootstrapMode::kDisabled},
+      connect_timeout_seconds_{60u},
+      bootstrap_timeout_seconds_{600u},
+      monitor_timeout_seconds_{120u},
+      pairing_modes_{PairingType::kPinCode} {
+}
+
+bool PrivetdConfigParser::Parse(const chromeos::KeyValueStore& config_store) {
+  std::string wifi_bootstrap_mode_str;
+  if (config_store.GetString(kWiFiBootstrapMode, &wifi_bootstrap_mode_str)) {
+    if (wifi_bootstrap_mode_str.compare(kBootstrapModeOff) == 0) {
+      wifi_bootstrap_mode_ = WiFiBootstrapMode::kDisabled;
+    } else if (wifi_bootstrap_mode_str.compare(kBootstrapModeAutomatic) == 0) {
+      wifi_bootstrap_mode_ = WiFiBootstrapMode::kAutomatic;
+    } else if (wifi_bootstrap_mode_str.compare(kBootstrapModeManual) == 0) {
+      LOG(ERROR) << "Manual WiFi bootstrapping mode is unsupported.";
+      return false;
+    } else {
+      LOG(ERROR) << "Unrecognized WiFi bootstrapping mode: "
+                 << wifi_bootstrap_mode_str;
+      return false;
+    }
+  }
+
+  std::string gcd_bootstrap_mode_str;
+  if (config_store.GetString(kGcdBootstrapMode, &gcd_bootstrap_mode_str)) {
+    if (gcd_bootstrap_mode_str.compare(kBootstrapModeOff) == 0) {
+      gcd_bootstrap_mode_ = GcdBootstrapMode::kDisabled;
+    } else if (gcd_bootstrap_mode_str.compare(kBootstrapModeAutomatic) == 0) {
+      gcd_bootstrap_mode_ = GcdBootstrapMode::kAutomatic;
+    } else if (gcd_bootstrap_mode_str.compare(kBootstrapModeManual) == 0) {
+      LOG(ERROR) << "Manual GCD bootstrapping mode is unsupported.";
+      return false;
+    } else {
+      LOG(ERROR) << "Unrecognized GCD bootstrapping mode: "
+                 << gcd_bootstrap_mode_str;
+      return false;
+    }
+  }
+
+  std::string wifi_interface_list_str;
+  if (config_store.GetString(kWiFiBootstrapInterfaces,
+                             &wifi_interface_list_str)) {
+    auto interfaces =
+        chromeos::string_utils::Split(wifi_interface_list_str, ",", true, true);
+    automatic_wifi_interfaces_.insert(interfaces.begin(), interfaces.end());
+  }
+
+  auto parse_timeout = [](const std::string& input, uint32_t* parsed_value) {
+    uint32_t temp{0};
+    // Tragically, this will set |temp| even for invalid parsings.
+    if (base::StringToUint(input, &temp)) {
+      *parsed_value = temp;  // Parse worked, use that value.
+      return true;
+    }
+    return false;
+  };
+
+  std::string connect_timeout_seconds_str;
+  if (config_store.GetString(kConnectTimeout, &connect_timeout_seconds_str) &&
+      !parse_timeout(connect_timeout_seconds_str, &connect_timeout_seconds_)) {
+    LOG(ERROR) << "Invalid string given for connect timeout: "
+               << connect_timeout_seconds_str;
+    return false;
+  }
+
+  std::string bootstrap_timeout_seconds_str;
+  if (config_store.GetString(kBootstrapTimeout,
+                             &bootstrap_timeout_seconds_str) &&
+      !parse_timeout(bootstrap_timeout_seconds_str,
+                     &bootstrap_timeout_seconds_)) {
+    LOG(ERROR) << "Invalid string given for bootstrap timeout: "
+               << bootstrap_timeout_seconds_str;
+    return false;
+  }
+
+  std::string monitor_timeout_seconds_str;
+  if (config_store.GetString(kMonitorTimeout, &monitor_timeout_seconds_str) &&
+      !parse_timeout(monitor_timeout_seconds_str, &monitor_timeout_seconds_)) {
+    LOG(ERROR) << "Invalid string given for monitor timeout: "
+               << monitor_timeout_seconds_str;
+    return false;
+  }
+
+  std::set<PairingType> pairing_modes;
+  std::string embedded_code_path;
+  if (config_store.GetString(kEmbeddedCodePath, &embedded_code_path)) {
+    embedded_code_path_ = base::FilePath(embedded_code_path);
+    if (!embedded_code_path_.empty())
+      pairing_modes.insert(PairingType::kEmbeddedCode);
+  }
+
+  std::string modes_str;
+  if (config_store.GetString(kPairingModes, &modes_str)) {
+    for (const std::string& mode :
+         chromeos::string_utils::Split(modes_str, ",", true, true)) {
+      PairingType pairing_mode;
+      if (!StringToPairingType(mode, &pairing_mode)) {
+        LOG(ERROR) << "Invalid pairing mode : " << mode;
+        return false;
+      }
+      pairing_modes.insert(pairing_mode);
+    }
+  }
+
+  if (!pairing_modes.empty())
+    pairing_modes_ = std::move(pairing_modes);
+
+  return true;
+}
+
+}  // namespace privetd
diff --git a/buffet/privet/privetd_conf_parser.h b/buffet/privet/privetd_conf_parser.h
new file mode 100644
index 0000000..846342f
--- /dev/null
+++ b/buffet/privet/privetd_conf_parser.h
@@ -0,0 +1,65 @@
+// Copyright 2015 The Chromium OS 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 BUFFET_PRIVET_PRIVETD_CONF_PARSER_H_
+#define BUFFET_PRIVET_PRIVETD_CONF_PARSER_H_
+
+#include <set>
+#include <string>
+
+#include <chromeos/key_value_store.h>
+
+namespace privetd {
+
+extern const char kWiFiBootstrapInterfaces[];
+
+enum class WiFiBootstrapMode {
+  kDisabled,
+  kManual,
+  kAutomatic,
+};
+
+enum class GcdBootstrapMode {
+  kDisabled,
+  kManual,
+  kAutomatic,
+};
+
+enum class PairingType;
+
+class PrivetdConfigParser final {
+ public:
+  PrivetdConfigParser();
+
+  bool Parse(const chromeos::KeyValueStore& config_store);
+
+  WiFiBootstrapMode wifi_bootstrap_mode() const { return wifi_bootstrap_mode_; }
+  GcdBootstrapMode gcd_bootstrap_mode() const { return gcd_bootstrap_mode_; }
+  const std::set<std::string>& automatic_wifi_interfaces() const {
+    return automatic_wifi_interfaces_;
+  }
+  uint32_t connect_timeout_seconds() const { return connect_timeout_seconds_; }
+  uint32_t bootstrap_timeout_seconds() const {
+    return bootstrap_timeout_seconds_;
+  }
+  uint32_t monitor_timeout_seconds() const { return monitor_timeout_seconds_; }
+  const std::set<PairingType>& pairing_modes() { return pairing_modes_; }
+  const base::FilePath& embedded_code_path() const {
+    return embedded_code_path_;
+  }
+
+ private:
+  WiFiBootstrapMode wifi_bootstrap_mode_;
+  GcdBootstrapMode gcd_bootstrap_mode_;
+  std::set<std::string> automatic_wifi_interfaces_;
+  uint32_t connect_timeout_seconds_;
+  uint32_t bootstrap_timeout_seconds_;
+  uint32_t monitor_timeout_seconds_;
+  std::set<PairingType> pairing_modes_;
+  base::FilePath embedded_code_path_;
+};
+
+}  // namespace privetd
+
+#endif  // BUFFET_PRIVET_PRIVETD_CONF_PARSER_H_
diff --git a/buffet/privet/privetd_conf_parser_unittest.cc b/buffet/privet/privetd_conf_parser_unittest.cc
new file mode 100644
index 0000000..8060dd7
--- /dev/null
+++ b/buffet/privet/privetd_conf_parser_unittest.cc
@@ -0,0 +1,138 @@
+// Copyright 2015 The Chromium OS 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 "buffet/privet/privetd_conf_parser.h"
+
+#include <map>
+#include <set>
+#include <string>
+#include <vector>
+
+#include <base/files/file_util.h>
+#include <base/files/scoped_temp_dir.h>
+#include <base/logging.h>
+#include <chromeos/strings/string_utils.h>
+#include <gtest/gtest.h>
+
+#include "buffet/privet/security_delegate.h"
+
+using chromeos::string_utils::Join;
+using chromeos::KeyValueStore;
+using std::map;
+using std::string;
+
+namespace privetd {
+
+namespace {
+
+const char kWiFiBootstrapMode[] = "wifi_bootstrapping_mode";
+const char kGcdBootstrapMode[] = "gcd_bootstrapping_mode";
+const char kConnectTimeout[] = "connect_timeout_seconds";
+const char kBootstrapTimeout[] = "bootstrap_timeout_seconds";
+const char kMonitorTimeout[] = "monitor_timeout_seconds";
+const char kPairingModes[] = "pairing_modes";
+const char kEmbeddedCodePath[] = "embedded_code_path";
+
+}  // namespace
+
+class PrivetdConfParserTest : public testing::Test {
+ public:
+  using ConfDict = map<string, string>;
+
+  void SetUp() override {
+    CHECK(temp_dir_.CreateUniqueTempDir());
+    temp_file_ = temp_dir_.path().Append("temp.conf");
+  }
+
+  bool IsValid(const ConfDict& conf_dict) {
+    KeyValueStore store;
+    FillKeyValueStore(conf_dict, &store);
+    PrivetdConfigParser config;
+    return config.Parse(store);
+  }
+
+  void FillKeyValueStore(const ConfDict& conf_dict, KeyValueStore* store) {
+    std::vector<string> file_pieces;
+    for (const auto& it : conf_dict) {
+      file_pieces.push_back(Join("=", it.first, it.second));
+    }
+    string blob{Join("\n", file_pieces)};
+    int expected_len = blob.length();
+    CHECK(expected_len == base::WriteFile(temp_file_,
+                                          blob.c_str(),
+                                          expected_len));
+    CHECK(store->Load(temp_file_));
+  }
+
+ private:
+  base::FilePath temp_file_;
+  base::ScopedTempDir temp_dir_;
+};
+
+TEST_F(PrivetdConfParserTest, ShouldRejectInvalidTimeouts) {
+  EXPECT_FALSE(IsValid({{kConnectTimeout, "-1"}}));
+  EXPECT_FALSE(IsValid({{kConnectTimeout, "a"}}));
+  EXPECT_FALSE(IsValid({{kConnectTimeout, ""}}));
+  EXPECT_FALSE(IsValid({{kConnectTimeout, "30 430"}}));
+}
+
+TEST_F(PrivetdConfParserTest, ShouldRejectInvalidWiFiBootstrapModes) {
+  EXPECT_FALSE(IsValid({{kWiFiBootstrapMode, ""}}));
+  EXPECT_FALSE(IsValid({{kWiFiBootstrapMode, "clown_shoes"}}));
+  EXPECT_FALSE(IsValid({{kWiFiBootstrapMode, "off is invalid"}}));
+  EXPECT_FALSE(IsValid({{kWiFiBootstrapMode, "30"}}));
+}
+
+TEST_F(PrivetdConfParserTest, ShouldRejectInvalidGcdBootstrapModes) {
+  EXPECT_FALSE(IsValid({{kGcdBootstrapMode, ""}}));
+  EXPECT_FALSE(IsValid({{kGcdBootstrapMode, "clown_shoes"}}));
+  EXPECT_FALSE(IsValid({{kGcdBootstrapMode, "off is invalid"}}));
+  EXPECT_FALSE(IsValid({{kGcdBootstrapMode, "30"}}));
+}
+
+TEST_F(PrivetdConfParserTest, ShouldParseSettings) {
+  const std::set<std::string> kExpectedWiFiInterfaces{"eth1", "clown shoes"};
+  const uint32_t kExpectedConnectTimeout{1};
+  const uint32_t kExpectedBootstrapTimeout{2};
+  const uint32_t kExpectedMonitorTimeout{3};
+  const std::set<PairingType> kExpectedPairingModes{PairingType::kEmbeddedCode,
+                                                    PairingType::kPinCode};
+  static const char kExpectedEmbeddedCodePath[]{"123ABC"};
+  const ConfDict conf_dict{
+      {kWiFiBootstrapMode, "automatic"},
+      {kGcdBootstrapMode, "automatic"},
+      {kWiFiBootstrapInterfaces, Join(",", kExpectedWiFiInterfaces)},
+      {kConnectTimeout, std::to_string(kExpectedConnectTimeout)},
+      {kBootstrapTimeout, std::to_string(kExpectedBootstrapTimeout)},
+      {kMonitorTimeout, std::to_string(kExpectedMonitorTimeout)},
+      {kPairingModes, "pinCode"},
+      {kEmbeddedCodePath, kExpectedEmbeddedCodePath},
+  };
+  KeyValueStore store;
+  FillKeyValueStore(conf_dict, &store);
+  PrivetdConfigParser parser;
+  EXPECT_TRUE(parser.Parse(store));
+  EXPECT_EQ(WiFiBootstrapMode::kAutomatic, parser.wifi_bootstrap_mode());
+  EXPECT_EQ(GcdBootstrapMode::kAutomatic, parser.gcd_bootstrap_mode());
+  EXPECT_EQ(kExpectedWiFiInterfaces, parser.automatic_wifi_interfaces());
+  EXPECT_EQ(kExpectedConnectTimeout, parser.connect_timeout_seconds());
+  EXPECT_EQ(kExpectedBootstrapTimeout, parser.bootstrap_timeout_seconds());
+  EXPECT_EQ(kExpectedMonitorTimeout, parser.monitor_timeout_seconds());
+  EXPECT_EQ(kExpectedPairingModes, parser.pairing_modes());
+  EXPECT_EQ(kExpectedEmbeddedCodePath, parser.embedded_code_path().value());
+}
+
+TEST_F(PrivetdConfParserTest, CriticalDefaults) {
+  PrivetdConfigParser parser;
+  EXPECT_EQ(WiFiBootstrapMode::kDisabled, parser.wifi_bootstrap_mode());
+  EXPECT_EQ(GcdBootstrapMode::kDisabled, parser.gcd_bootstrap_mode());
+  EXPECT_GT(parser.connect_timeout_seconds(), 0);
+  EXPECT_GT(parser.bootstrap_timeout_seconds(), 0);
+  EXPECT_GT(parser.monitor_timeout_seconds(), 0);
+  EXPECT_EQ(std::set<PairingType>{PairingType::kPinCode},
+            parser.pairing_modes());
+  EXPECT_TRUE(parser.embedded_code_path().empty());
+}
+
+}  // namespace privetd
diff --git a/buffet/privet/security_delegate.h b/buffet/privet/security_delegate.h
new file mode 100644
index 0000000..f69ffb2
--- /dev/null
+++ b/buffet/privet/security_delegate.h
@@ -0,0 +1,79 @@
+// Copyright 2014 The Chromium OS 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 BUFFET_PRIVET_SECURITY_DELEGATE_H_
+#define BUFFET_PRIVET_SECURITY_DELEGATE_H_
+
+#include <memory>
+#include <set>
+#include <string>
+
+#include <base/time/time.h>
+#include <chromeos/secure_blob.h>
+
+#include "buffet/privet/privet_types.h"
+
+namespace privetd {
+
+enum class PairingType {
+  kPinCode,
+  kEmbeddedCode,
+  kUltrasound32,
+  kAudible32,
+};
+
+enum class CryptoType {
+  kNone,
+  kSpake_p224,
+  kSpake_p256,
+};
+
+// Interface to provide Security related logic for |PrivetHandler|.
+class SecurityDelegate {
+ public:
+  virtual ~SecurityDelegate() = default;
+
+  // Creates access token for the given scope, user id and |time|.
+  virtual std::string CreateAccessToken(const UserInfo& user_info,
+                                        const base::Time& time) = 0;
+
+  // Validates |token| and returns scope and user id parsed from that.
+  virtual UserInfo ParseAccessToken(const std::string& token,
+                                    base::Time* time) const = 0;
+
+  // Returns list of pairing methods by device.
+  virtual std::set<PairingType> GetPairingTypes() const = 0;
+
+  // Returns list of crypto methods supported by devices.
+  virtual std::set<CryptoType> GetCryptoTypes() const = 0;
+
+  // Returns true if |auth_code| provided by client is valid. Client should
+  // obtain |auth_code| during pairing process.
+  virtual bool IsValidPairingCode(const std::string& auth_code) const = 0;
+
+  virtual bool StartPairing(PairingType mode,
+                            CryptoType crypto,
+                            std::string* session_id,
+                            std::string* device_commitment,
+                            chromeos::ErrorPtr* error) = 0;
+
+  virtual bool ConfirmPairing(const std::string& session_id,
+                              const std::string& client_commitment,
+                              std::string* fingerprint,
+                              std::string* signature,
+                              chromeos::ErrorPtr* error) = 0;
+
+  virtual bool CancelPairing(const std::string& session_id,
+                             chromeos::ErrorPtr* error) = 0;
+};
+
+bool StringToPairingType(const std::string& mode, PairingType* id);
+std::string PairingTypeToString(PairingType id);
+
+bool StringToAuthScope(const std::string& scope, AuthScope* id);
+std::string AuthScopeToString(AuthScope id);
+
+}  // namespace privetd
+
+#endif  // BUFFET_PRIVET_SECURITY_DELEGATE_H_
diff --git a/buffet/privet/security_manager.cc b/buffet/privet/security_manager.cc
new file mode 100644
index 0000000..5dc3b0c
--- /dev/null
+++ b/buffet/privet/security_manager.cc
@@ -0,0 +1,415 @@
+// Copyright 2014 The Chromium OS 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 "buffet/privet/security_manager.h"
+
+#include <algorithm>
+#include <limits>
+#include <memory>
+#include <set>
+
+#include <base/bind.h>
+#include <base/guid.h>
+#include <base/logging.h>
+#include <base/message_loop/message_loop.h>
+#include <base/rand_util.h>
+#include <base/stl_util.h>
+#include <base/strings/string_number_conversions.h>
+#include <base/strings/stringprintf.h>
+#include <base/time/time.h>
+#include <chromeos/data_encoding.h>
+#include <chromeos/key_value_store.h>
+#include <chromeos/strings/string_utils.h>
+#include <crypto/p224_spake.h>
+
+#include "buffet/privet/constants.h"
+#include "buffet/privet/openssl_utils.h"
+
+namespace privetd {
+
+namespace {
+
+const char kTokenDelimeter[] = ":";
+const int kSessionExpirationTimeMinutes = 5;
+const int kPairingExpirationTimeMinutes = 5;
+const int kMaxAllowedPairingAttemts = 3;
+const int kPairingBlockingTimeMinutes = 1;
+
+const char kEmbeddedCode[] = "embedded_code";
+
+// Returns "scope:id:time".
+std::string CreateTokenData(const UserInfo& user_info, const base::Time& time) {
+  return base::IntToString(static_cast<int>(user_info.scope())) +
+         kTokenDelimeter + base::Uint64ToString(user_info.user_id()) +
+         kTokenDelimeter + base::Int64ToString(time.ToTimeT());
+}
+
+// Splits string of "scope:id:time" format.
+UserInfo SplitTokenData(const std::string& token, base::Time* time) {
+  const UserInfo kNone;
+  auto parts = chromeos::string_utils::Split(token, kTokenDelimeter);
+  if (parts.size() != 3)
+    return kNone;
+  int scope = 0;
+  if (!base::StringToInt(parts[0], &scope) ||
+      scope < static_cast<int>(AuthScope::kNone) ||
+      scope > static_cast<int>(AuthScope::kOwner)) {
+    return kNone;
+  }
+
+  uint64_t id{0};
+  if (!base::StringToUint64(parts[1], &id))
+    return kNone;
+
+  int64_t timestamp{0};
+  if (!base::StringToInt64(parts[2], &timestamp))
+    return kNone;
+  *time = base::Time::FromTimeT(timestamp);
+  return UserInfo{static_cast<AuthScope>(scope), id};
+}
+
+std::string LoadEmbeddedCode(const base::FilePath& path) {
+  std::string code;
+  chromeos::KeyValueStore store;
+  if (store.Load(path))
+    store.GetString(kEmbeddedCode, &code);
+  return code;
+}
+
+class Spakep224Exchanger : public SecurityManager::KeyExchanger {
+ public:
+  explicit Spakep224Exchanger(const std::string& password)
+      : spake_(crypto::P224EncryptedKeyExchange::kPeerTypeServer, password) {}
+  ~Spakep224Exchanger() override = default;
+
+  // SecurityManager::KeyExchanger methods.
+  const std::string& GetMessage() override { return spake_.GetNextMessage(); }
+
+  bool ProcessMessage(const std::string& message,
+                      chromeos::ErrorPtr* error) override {
+    switch (spake_.ProcessMessage(message)) {
+      case crypto::P224EncryptedKeyExchange::kResultPending:
+        return true;
+      case crypto::P224EncryptedKeyExchange::kResultFailed:
+        chromeos::Error::AddTo(error, FROM_HERE, errors::kDomain,
+                               errors::kInvalidClientCommitment,
+                               spake_.error());
+        return false;
+      default:
+        LOG(FATAL) << "SecurityManager uses only one round trip";
+    }
+    return false;
+  }
+
+  const std::string& GetKey() const override {
+    return spake_.GetUnverifiedKey();
+  }
+
+ private:
+  crypto::P224EncryptedKeyExchange spake_;
+};
+
+class UnsecureKeyExchanger : public SecurityManager::KeyExchanger {
+ public:
+  explicit UnsecureKeyExchanger(const std::string& password)
+      : password_(password) {}
+  ~UnsecureKeyExchanger() override = default;
+
+  // SecurityManager::KeyExchanger methods.
+  const std::string& GetMessage() override { return password_; }
+
+  bool ProcessMessage(const std::string& message,
+                      chromeos::ErrorPtr* error) override {
+    return true;
+  }
+
+  const std::string& GetKey() const override { return password_; }
+
+ private:
+  std::string password_;
+};
+
+}  // namespace
+
+SecurityManager::SecurityManager(const std::set<PairingType>& pairing_modes,
+                                 const base::FilePath& embedded_code_path,
+                                 bool disable_security)
+    : is_security_disabled_(disable_security),
+      pairing_modes_(pairing_modes),
+      embedded_code_path_(embedded_code_path),
+      secret_(kSha256OutputSize) {
+  base::RandBytes(secret_.data(), kSha256OutputSize);
+
+  CHECK_EQ(embedded_code_path_.empty(),
+           std::find(pairing_modes_.begin(), pairing_modes_.end(),
+                     PairingType::kEmbeddedCode) == pairing_modes_.end());
+}
+
+SecurityManager::~SecurityManager() {
+  while (!pending_sessions_.empty())
+    ClosePendingSession(pending_sessions_.begin()->first);
+}
+
+// Returns "base64([hmac]scope:id:time)".
+std::string SecurityManager::CreateAccessToken(const UserInfo& user_info,
+                                               const base::Time& time) {
+  chromeos::SecureBlob data(CreateTokenData(user_info, time));
+  chromeos::Blob hash(HmacSha256(secret_, data));
+  return chromeos::data_encoding::Base64Encode(chromeos::SecureBlob::Combine(
+      chromeos::SecureBlob(hash.begin(), hash.end()), data));
+}
+
+// Parses "base64([hmac]scope:id:time)".
+UserInfo SecurityManager::ParseAccessToken(const std::string& token,
+                                           base::Time* time) const {
+  chromeos::Blob decoded;
+  if (!chromeos::data_encoding::Base64Decode(token, &decoded) ||
+      decoded.size() <= kSha256OutputSize) {
+    return UserInfo{};
+  }
+  chromeos::SecureBlob data(decoded.begin() + kSha256OutputSize, decoded.end());
+  decoded.resize(kSha256OutputSize);
+  if (decoded != HmacSha256(secret_, data))
+    return UserInfo{};
+  return SplitTokenData(data.to_string(), time);
+}
+
+std::set<PairingType> SecurityManager::GetPairingTypes() const {
+  return pairing_modes_;
+}
+
+std::set<CryptoType> SecurityManager::GetCryptoTypes() const {
+  std::set<CryptoType> result{CryptoType::kSpake_p224};
+  if (is_security_disabled_)
+    result.insert(CryptoType::kNone);
+  return result;
+}
+
+bool SecurityManager::IsValidPairingCode(const std::string& auth_code) const {
+  if (is_security_disabled_)
+    return true;
+  chromeos::Blob auth_decoded;
+  if (!chromeos::data_encoding::Base64Decode(auth_code, &auth_decoded))
+    return false;
+  for (const auto& session : confirmed_sessions_) {
+    if (auth_decoded ==
+        HmacSha256(chromeos::SecureBlob{session.second->GetKey()},
+                   chromeos::SecureBlob{session.first})) {
+      pairing_attemts_ = 0;
+      block_pairing_until_ = base::Time{};
+      return true;
+    }
+  }
+  LOG(ERROR) << "Attempt to authenticate with invalide code.";
+  return false;
+}
+
+bool SecurityManager::StartPairing(PairingType mode,
+                                   CryptoType crypto,
+                                   std::string* session_id,
+                                   std::string* device_commitment,
+                                   chromeos::ErrorPtr* error) {
+  if (!CheckIfPairingAllowed(error))
+    return false;
+
+  if (std::find(pairing_modes_.begin(), pairing_modes_.end(), mode) ==
+      pairing_modes_.end()) {
+    chromeos::Error::AddTo(error, FROM_HERE, errors::kDomain,
+                           errors::kInvalidParams,
+                           "Pairing mode is not enabled");
+    return false;
+  }
+
+  std::string code;
+  switch (mode) {
+    case PairingType::kEmbeddedCode:
+      CHECK(!embedded_code_path_.empty());
+
+      if (embedded_code_.empty())
+        embedded_code_ = LoadEmbeddedCode(embedded_code_path_);
+
+      if (embedded_code_.empty()) {  // File is not created yet.
+        chromeos::Error::AddTo(error, FROM_HERE, errors::kDomain,
+                               errors::kDeviceBusy,
+                               "Embedded code is not ready");
+        return false;
+      }
+
+      code = embedded_code_;
+      break;
+    case PairingType::kUltrasound32:
+    case PairingType::kAudible32: {
+      code = base::RandBytesAsString(4);
+      break;
+    }
+    case PairingType::kPinCode:
+      code = base::StringPrintf("%04i", base::RandInt(0, 9999));
+      break;
+    default:
+      chromeos::Error::AddTo(error, FROM_HERE, errors::kDomain,
+                             errors::kInvalidParams,
+                             "Unsupported pairing mode");
+      return false;
+  }
+
+  std::unique_ptr<KeyExchanger> spake;
+  switch (crypto) {
+    case CryptoType::kSpake_p224:
+      spake.reset(new Spakep224Exchanger(code));
+      break;
+    case CryptoType::kNone:
+      if (is_security_disabled_) {
+        spake.reset(new UnsecureKeyExchanger(code));
+        break;
+      }
+    // Fall through...
+    default:
+      chromeos::Error::AddTo(error, FROM_HERE, errors::kDomain,
+                             errors::kInvalidParams, "Unsupported crypto");
+      return false;
+  }
+
+  // Allow only a single session at a time for now.
+  while (!pending_sessions_.empty())
+    ClosePendingSession(pending_sessions_.begin()->first);
+
+  std::string session;
+  do {
+    session = base::GenerateGUID();
+  } while (confirmed_sessions_.find(session) != confirmed_sessions_.end() ||
+           pending_sessions_.find(session) != pending_sessions_.end());
+  std::string commitment = spake->GetMessage();
+  pending_sessions_.emplace(session, std::move(spake));
+
+  base::MessageLoop::current()->PostDelayedTask(
+      FROM_HERE,
+      base::Bind(base::IgnoreResult(&SecurityManager::ClosePendingSession),
+                 weak_ptr_factory_.GetWeakPtr(), session),
+      base::TimeDelta::FromMinutes(kPairingExpirationTimeMinutes));
+
+  *session_id = session;
+  *device_commitment = chromeos::data_encoding::Base64Encode(commitment);
+  LOG(INFO) << "Pairing code for session " << *session_id << " is " << code;
+  // TODO(vitalybuka): Handle case when device can't start multiple pairing
+  // simultaneously and implement throttling to avoid brute force attack.
+  if (!on_start_.is_null()) {
+    on_start_.Run(session, mode,
+                  chromeos::string_utils::GetStringAsBytes(code));
+  }
+
+  return true;
+}
+
+bool SecurityManager::ConfirmPairing(const std::string& session_id,
+                                     const std::string& client_commitment,
+                                     std::string* fingerprint,
+                                     std::string* signature,
+                                     chromeos::ErrorPtr* error) {
+  auto session = pending_sessions_.find(session_id);
+  if (session == pending_sessions_.end()) {
+    chromeos::Error::AddToPrintf(
+        error, FROM_HERE, errors::kDomain, errors::kUnknownSession,
+        "Unknown session id: '%s'", session_id.c_str());
+    return false;
+  }
+  CHECK(!certificate_fingerprint_.empty());
+
+  chromeos::Blob commitment;
+  if (!chromeos::data_encoding::Base64Decode(client_commitment, &commitment)) {
+    ClosePendingSession(session_id);
+    chromeos::Error::AddToPrintf(
+        error, FROM_HERE, errors::kDomain, errors::kInvalidFormat,
+        "Invalid commitment string: '%s'", client_commitment.c_str());
+    return false;
+  }
+
+  if (!session->second->ProcessMessage(
+          std::string(commitment.begin(), commitment.end()), error)) {
+    ClosePendingSession(session_id);
+    chromeos::Error::AddTo(error, FROM_HERE, errors::kDomain,
+                           errors::kCommitmentMismatch,
+                           "Pairing code or crypto implementation mismatch");
+    return false;
+  }
+
+  std::string key = session->second->GetKey();
+  VLOG(3) << "KEY " << base::HexEncode(key.data(), key.size());
+
+  *fingerprint =
+      chromeos::data_encoding::Base64Encode(certificate_fingerprint_);
+  chromeos::Blob cert_hmac =
+      HmacSha256(chromeos::SecureBlob(session->second->GetKey()),
+                 certificate_fingerprint_);
+  *signature = chromeos::data_encoding::Base64Encode(cert_hmac);
+  confirmed_sessions_.emplace(session->first, std::move(session->second));
+  base::MessageLoop::current()->PostDelayedTask(
+      FROM_HERE,
+      base::Bind(base::IgnoreResult(&SecurityManager::CloseConfirmedSession),
+                 weak_ptr_factory_.GetWeakPtr(), session_id),
+      base::TimeDelta::FromMinutes(kSessionExpirationTimeMinutes));
+  ClosePendingSession(session_id);
+  return true;
+}
+
+bool SecurityManager::CancelPairing(const std::string& session_id,
+                                    chromeos::ErrorPtr* error) {
+  bool confirmed = CloseConfirmedSession(session_id);
+  bool pending = ClosePendingSession(session_id);
+  if (pending) {
+    CHECK_GE(pairing_attemts_, 1);
+    --pairing_attemts_;
+  }
+  CHECK(!confirmed || !pending);
+  if (confirmed || pending)
+    return true;
+  chromeos::Error::AddToPrintf(error, FROM_HERE, errors::kDomain,
+                               errors::kUnknownSession,
+                               "Unknown session id: '%s'", session_id.c_str());
+  return false;
+}
+
+void SecurityManager::RegisterPairingListeners(
+    const PairingStartListener& on_start,
+    const PairingEndListener& on_end) {
+  CHECK(on_start_.is_null() && on_end_.is_null());
+  on_start_ = on_start;
+  on_end_  = on_end;
+}
+
+bool SecurityManager::CheckIfPairingAllowed(chromeos::ErrorPtr* error) {
+  if (is_security_disabled_)
+    return true;
+
+  if (block_pairing_until_ > base::Time::Now()) {
+    chromeos::Error::AddTo(error, FROM_HERE, errors::kDomain,
+                           errors::kDeviceBusy, "Too many pairing attempts");
+    return false;
+  }
+
+  if (++pairing_attemts_ >= kMaxAllowedPairingAttemts) {
+    LOG(INFO) << "Pairing blocked for" << kPairingBlockingTimeMinutes
+              << "minutes.";
+    block_pairing_until_ = base::Time::Now();
+    block_pairing_until_ +=
+        base::TimeDelta::FromMinutes(kPairingBlockingTimeMinutes);
+  }
+
+  return true;
+}
+
+bool SecurityManager::ClosePendingSession(const std::string& session_id) {
+  // The most common source of these session_id values is the map containing
+  // the sessions, which we're about to clear out.  Make a local copy.
+  const std::string safe_session_id{session_id};
+  const size_t num_erased = pending_sessions_.erase(safe_session_id);
+  if (num_erased > 0 && !on_end_.is_null())
+    on_end_.Run(safe_session_id);
+  return num_erased != 0;
+}
+
+bool SecurityManager::CloseConfirmedSession(const std::string& session_id) {
+  return confirmed_sessions_.erase(session_id) != 0;
+}
+
+}  // namespace privetd
diff --git a/buffet/privet/security_manager.h b/buffet/privet/security_manager.h
new file mode 100644
index 0000000..04a942e
--- /dev/null
+++ b/buffet/privet/security_manager.h
@@ -0,0 +1,110 @@
+// Copyright 2014 The Chromium OS 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 BUFFET_PRIVET_SECURITY_MANAGER_H_
+#define BUFFET_PRIVET_SECURITY_MANAGER_H_
+
+#include <map>
+#include <memory>
+#include <set>
+#include <string>
+#include <vector>
+
+#include <base/callback.h>
+#include <base/files/file_path.h>
+#include <base/memory/weak_ptr.h>
+#include <chromeos/errors/error.h>
+#include <chromeos/secure_blob.h>
+
+#include "buffet/privet/security_delegate.h"
+
+namespace crypto {
+class P224EncryptedKeyExchange;
+}  // namespace crypto
+
+namespace privetd {
+
+class SecurityManager : public SecurityDelegate {
+ public:
+  using PairingStartListener =
+      base::Callback<void(const std::string& session_id,
+                          PairingType pairing_type,
+                          const std::vector<uint8_t>& code)>;
+  using PairingEndListener =
+      base::Callback<void(const std::string& session_id)>;
+
+  class KeyExchanger {
+   public:
+    virtual ~KeyExchanger() = default;
+
+    virtual const std::string& GetMessage() = 0;
+    virtual bool ProcessMessage(const std::string& message,
+                                chromeos::ErrorPtr* error) = 0;
+    virtual const std::string& GetKey() const = 0;
+  };
+
+  SecurityManager(const std::set<PairingType>& pairing_modes,
+                  const base::FilePath& embedded_code_path,
+                  bool disable_security = false);
+  ~SecurityManager() override;
+
+  // SecurityDelegate methods
+  std::string CreateAccessToken(const UserInfo& user_info,
+                                const base::Time& time) override;
+  UserInfo ParseAccessToken(const std::string& token,
+                            base::Time* time) const override;
+  std::set<PairingType> GetPairingTypes() const override;
+  std::set<CryptoType> GetCryptoTypes() const override;
+  bool IsValidPairingCode(const std::string& auth_code) const override;
+
+  bool StartPairing(PairingType mode,
+                    CryptoType crypto,
+                    std::string* session_id,
+                    std::string* device_commitment,
+                    chromeos::ErrorPtr* error) override;
+
+  bool ConfirmPairing(const std::string& session_id,
+                      const std::string& client_commitment,
+                      std::string* fingerprint,
+                      std::string* signature,
+                      chromeos::ErrorPtr* error) override;
+  bool CancelPairing(const std::string& session_id,
+                     chromeos::ErrorPtr* error) override;
+
+  void RegisterPairingListeners(const PairingStartListener& on_start,
+                                const PairingEndListener& on_end);
+
+  void SetCertificateFingerprint(const chromeos::Blob& fingerprint) {
+    certificate_fingerprint_ = fingerprint;
+  }
+
+ private:
+  FRIEND_TEST_ALL_PREFIXES(SecurityManagerTest, ThrottlePairing);
+  // Allows limited number of new sessions without successful authorization.
+  bool CheckIfPairingAllowed(chromeos::ErrorPtr* error);
+  bool ClosePendingSession(const std::string& session_id);
+  bool CloseConfirmedSession(const std::string& session_id);
+
+  // If true allows unencrypted pairing and accepts any access code.
+  bool is_security_disabled_{false};
+  std::set<PairingType> pairing_modes_;
+  const base::FilePath embedded_code_path_;
+  std::string embedded_code_;
+  std::map<std::string, std::unique_ptr<KeyExchanger>> pending_sessions_;
+  std::map<std::string, std::unique_ptr<KeyExchanger>> confirmed_sessions_;
+  mutable int pairing_attemts_{0};
+  mutable base::Time block_pairing_until_;
+  chromeos::SecureBlob secret_;
+  chromeos::Blob certificate_fingerprint_;
+  PairingStartListener on_start_;
+  PairingEndListener on_end_;
+
+  base::WeakPtrFactory<SecurityManager> weak_ptr_factory_{this};
+
+  DISALLOW_COPY_AND_ASSIGN(SecurityManager);
+};
+
+}  // namespace privetd
+
+#endif  // BUFFET_PRIVET_SECURITY_MANAGER_H_
diff --git a/buffet/privet/security_manager_unittest.cc b/buffet/privet/security_manager_unittest.cc
new file mode 100644
index 0000000..32b7463
--- /dev/null
+++ b/buffet/privet/security_manager_unittest.cc
@@ -0,0 +1,316 @@
+// Copyright 2014 The Chromium OS 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 "buffet/privet/security_manager.h"
+
+#include <algorithm>
+#include <cctype>
+#include <functional>
+#include <memory>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include <base/bind.h>
+#include <base/files/file_util.h>
+#include <base/logging.h>
+#include <base/message_loop/message_loop.h>
+#include <base/rand_util.h>
+#include <base/strings/string_number_conversions.h>
+#include <base/strings/string_util.h>
+#include <chromeos/data_encoding.h>
+#include <chromeos/key_value_store.h>
+#include <chromeos/strings/string_utils.h>
+#include <crypto/p224_spake.h>
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+
+#include "buffet/privet/openssl_utils.h"
+
+using testing::Eq;
+using testing::_;
+
+namespace privetd {
+
+namespace {
+
+bool IsBase64Char(char c) {
+  return isalnum(c) || (c == '+') || (c == '/') || (c == '=');
+}
+
+bool IsBase64(const std::string& text) {
+  return !text.empty() &&
+         !std::any_of(text.begin(), text.end(),
+                      std::not1(std::ref(IsBase64Char)));
+}
+
+class MockPairingCallbacks {
+ public:
+  MOCK_METHOD3(OnPairingStart,
+               void(const std::string& session_id,
+                    PairingType pairing_type,
+                    const std::vector<uint8_t>& code));
+  MOCK_METHOD1(OnPairingEnd, void(const std::string& session_id));
+};
+
+base::FilePath GetTempFilePath() {
+  base::FilePath file_path;
+  EXPECT_TRUE(base::CreateTemporaryFile(&file_path));
+  return file_path;
+}
+
+}  // namespace
+
+class SecurityManagerTest : public testing::Test {
+ public:
+  void SetUp() override {
+    chromeos::Blob fingerprint;
+    fingerprint.resize(256 / 8);
+    base::RandBytes(fingerprint.data(), fingerprint.size());
+    security_.SetCertificateFingerprint(fingerprint);
+
+    chromeos::KeyValueStore store;
+    store.SetString("embedded_code", "1234");
+    EXPECT_TRUE(store.Save(embedded_code_path_));
+  }
+
+  void TearDown() override { base::DeleteFile(embedded_code_path_, false); }
+
+ protected:
+  void PairAndAuthenticate(std::string* fingerprint, std::string* signature) {
+    std::string session_id;
+    std::string device_commitment_base64;
+
+    EXPECT_TRUE(security_.StartPairing(PairingType::kEmbeddedCode,
+                                       CryptoType::kSpake_p224, &session_id,
+                                       &device_commitment_base64, nullptr));
+    EXPECT_FALSE(session_id.empty());
+    EXPECT_FALSE(device_commitment_base64.empty());
+
+    crypto::P224EncryptedKeyExchange spake{
+        crypto::P224EncryptedKeyExchange::kPeerTypeClient, "1234"};
+
+    std::string client_commitment_base64{
+        chromeos::data_encoding::Base64Encode(spake.GetNextMessage())};
+
+    EXPECT_TRUE(security_.ConfirmPairing(session_id, client_commitment_base64,
+                                         fingerprint, signature, nullptr));
+    EXPECT_TRUE(IsBase64(*fingerprint));
+    EXPECT_TRUE(IsBase64(*signature));
+
+    chromeos::Blob device_commitment;
+    ASSERT_TRUE(chromeos::data_encoding::Base64Decode(device_commitment_base64,
+                                                      &device_commitment));
+    spake.ProcessMessage(
+        chromeos::string_utils::GetBytesAsString(device_commitment));
+
+    chromeos::Blob auth_code{
+        HmacSha256(chromeos::SecureBlob{spake.GetUnverifiedKey()},
+                   chromeos::SecureBlob{session_id})};
+
+    std::string auth_code_base64{
+        chromeos::data_encoding::Base64Encode(auth_code)};
+
+    EXPECT_TRUE(security_.IsValidPairingCode(auth_code_base64));
+  }
+
+  const base::Time time_ = base::Time::FromTimeT(1410000000);
+  base::MessageLoop message_loop_;
+  base::FilePath embedded_code_path_{GetTempFilePath()};
+  SecurityManager security_{{PairingType::kEmbeddedCode}, embedded_code_path_};
+};
+
+TEST_F(SecurityManagerTest, IsBase64) {
+  EXPECT_TRUE(IsBase64(
+      security_.CreateAccessToken(UserInfo{AuthScope::kUser, 7}, time_)));
+}
+
+TEST_F(SecurityManagerTest, CreateSameToken) {
+  EXPECT_EQ(
+      security_.CreateAccessToken(UserInfo{AuthScope::kViewer, 555}, time_),
+      security_.CreateAccessToken(UserInfo{AuthScope::kViewer, 555}, time_));
+}
+
+TEST_F(SecurityManagerTest, CreateTokenDifferentScope) {
+  EXPECT_NE(
+      security_.CreateAccessToken(UserInfo{AuthScope::kViewer, 456}, time_),
+      security_.CreateAccessToken(UserInfo{AuthScope::kOwner, 456}, time_));
+}
+
+TEST_F(SecurityManagerTest, CreateTokenDifferentUser) {
+  EXPECT_NE(
+      security_.CreateAccessToken(UserInfo{AuthScope::kOwner, 456}, time_),
+      security_.CreateAccessToken(UserInfo{AuthScope::kOwner, 789}, time_));
+}
+
+TEST_F(SecurityManagerTest, CreateTokenDifferentTime) {
+  EXPECT_NE(
+      security_.CreateAccessToken(UserInfo{AuthScope::kOwner, 567}, time_),
+      security_.CreateAccessToken(UserInfo{AuthScope::kOwner, 567},
+                                  base::Time::FromTimeT(1400000000)));
+}
+
+TEST_F(SecurityManagerTest, CreateTokenDifferentInstance) {
+  EXPECT_NE(security_.CreateAccessToken(UserInfo{AuthScope::kUser, 123}, time_),
+            SecurityManager({}, base::FilePath{})
+                .CreateAccessToken(UserInfo{AuthScope::kUser, 123}, time_));
+}
+
+TEST_F(SecurityManagerTest, ParseAccessToken) {
+  // Multiple attempts with random secrets.
+  for (size_t i = 0; i < 1000; ++i) {
+    SecurityManager security{{}, base::FilePath{}};
+
+    std::string token =
+        security.CreateAccessToken(UserInfo{AuthScope::kUser, 5}, time_);
+    base::Time time2;
+    EXPECT_EQ(AuthScope::kUser,
+              security.ParseAccessToken(token, &time2).scope());
+    EXPECT_EQ(5u, security.ParseAccessToken(token, &time2).user_id());
+    // Token timestamp resolution is one second.
+    EXPECT_GE(1, std::abs((time_ - time2).InSeconds()));
+  }
+}
+
+TEST_F(SecurityManagerTest, PairingNoSession) {
+  std::string fingerprint;
+  std::string signature;
+  chromeos::ErrorPtr error;
+  ASSERT_FALSE(
+      security_.ConfirmPairing("123", "345", &fingerprint, &signature, &error));
+  EXPECT_EQ("unknownSession", error->GetCode());
+}
+
+TEST_F(SecurityManagerTest, Pairing) {
+  std::vector<std::pair<std::string, std::string> > fingerprints(2);
+  for (auto& it : fingerprints) {
+    PairAndAuthenticate(&it.first, &it.second);
+  }
+
+  // Same certificate.
+  EXPECT_EQ(fingerprints.front().first, fingerprints.back().first);
+
+  // Signed with different secret.
+  EXPECT_NE(fingerprints.front().second, fingerprints.back().second);
+}
+
+TEST_F(SecurityManagerTest, NotifiesListenersOfSessionStartAndEnd) {
+  testing::StrictMock<MockPairingCallbacks> callbacks;
+  security_.RegisterPairingListeners(
+      base::Bind(&MockPairingCallbacks::OnPairingStart,
+                 base::Unretained(&callbacks)),
+      base::Bind(&MockPairingCallbacks::OnPairingEnd,
+                 base::Unretained(&callbacks)));
+  for (auto commitment_suffix :
+       std::vector<std::string>{"", "invalid_commitment"}) {
+    // StartPairing should notify us that a new session has begun.
+    std::string session_id;
+    std::string device_commitment;
+    EXPECT_CALL(callbacks, OnPairingStart(_, PairingType::kEmbeddedCode, _));
+    EXPECT_TRUE(security_.StartPairing(PairingType::kEmbeddedCode,
+                                       CryptoType::kSpake_p224, &session_id,
+                                       &device_commitment, nullptr));
+    EXPECT_FALSE(session_id.empty());
+    EXPECT_FALSE(device_commitment.empty());
+    testing::Mock::VerifyAndClearExpectations(&callbacks);
+
+    // ConfirmPairing should notify us that the session has ended.
+    EXPECT_CALL(callbacks, OnPairingEnd(Eq(session_id)));
+    crypto::P224EncryptedKeyExchange spake{
+        crypto::P224EncryptedKeyExchange::kPeerTypeServer, "1234"};
+    std::string client_commitment =
+        chromeos::data_encoding::Base64Encode(spake.GetNextMessage());
+    std::string fingerprint, signature;
+    // Regardless of whether the commitment is valid or not, we should get a
+    // callback indicating that the pairing session is gone.
+    security_.ConfirmPairing(session_id, client_commitment + commitment_suffix,
+                             &fingerprint, &signature, nullptr);
+    testing::Mock::VerifyAndClearExpectations(&callbacks);
+  }
+}
+
+TEST_F(SecurityManagerTest, CancelPairing) {
+  testing::StrictMock<MockPairingCallbacks> callbacks;
+  security_.RegisterPairingListeners(
+      base::Bind(&MockPairingCallbacks::OnPairingStart,
+                 base::Unretained(&callbacks)),
+      base::Bind(&MockPairingCallbacks::OnPairingEnd,
+                 base::Unretained(&callbacks)));
+  std::string session_id;
+  std::string device_commitment;
+  EXPECT_CALL(callbacks, OnPairingStart(_, PairingType::kEmbeddedCode, _));
+  EXPECT_TRUE(security_.StartPairing(PairingType::kEmbeddedCode,
+                                     CryptoType::kSpake_p224, &session_id,
+                                     &device_commitment, nullptr));
+  EXPECT_CALL(callbacks, OnPairingEnd(Eq(session_id)));
+  EXPECT_TRUE(security_.CancelPairing(session_id, nullptr));
+}
+
+TEST_F(SecurityManagerTest, ThrottlePairing) {
+  auto pair = [this]() {
+    std::string session_id;
+    std::string device_commitment;
+    chromeos::ErrorPtr error;
+    bool result = security_.StartPairing(PairingType::kEmbeddedCode,
+                                         CryptoType::kSpake_p224, &session_id,
+                                         &device_commitment, &error);
+    EXPECT_TRUE(result || error->GetCode() == "deviceBusy");
+    return result;
+  };
+
+  EXPECT_TRUE(pair());
+  EXPECT_TRUE(pair());
+  EXPECT_TRUE(pair());
+  EXPECT_FALSE(pair());
+  EXPECT_GT(security_.block_pairing_until_, base::Time::Now());
+  EXPECT_LE(security_.block_pairing_until_,
+            base::Time::Now() + base::TimeDelta::FromMinutes(15));
+
+  // Wait timeout.
+  security_.block_pairing_until_ =
+      base::Time::Now() - base::TimeDelta::FromMinutes(1);
+
+  // Allow exactly one attempt.
+  EXPECT_TRUE(pair());
+  EXPECT_FALSE(pair());
+
+  // Wait timeout.
+  security_.block_pairing_until_ =
+      base::Time::Now() - base::TimeDelta::FromMinutes(1);
+
+  // Completely unblock by successfully pairing.
+  std::string fingerprint;
+  std::string signature;
+  PairAndAuthenticate(&fingerprint, &signature);
+
+  // Now we have 3 attempts again.
+  EXPECT_TRUE(pair());
+  EXPECT_TRUE(pair());
+  EXPECT_TRUE(pair());
+  EXPECT_FALSE(pair());
+}
+
+TEST_F(SecurityManagerTest, DontBlockForCanceledSessions) {
+  for (int i = 0; i < 20; ++i) {
+    std::string session_id;
+    std::string device_commitment;
+    EXPECT_TRUE(security_.StartPairing(PairingType::kEmbeddedCode,
+                                       CryptoType::kSpake_p224, &session_id,
+                                       &device_commitment, nullptr));
+    EXPECT_TRUE(security_.CancelPairing(session_id, nullptr));
+  }
+}
+
+TEST_F(SecurityManagerTest, EmbeddedCodeNotReady) {
+  std::string session_id;
+  std::string device_commitment;
+  base::DeleteFile(embedded_code_path_, false);
+  chromeos::ErrorPtr error;
+  ASSERT_FALSE(security_.StartPairing(PairingType::kEmbeddedCode,
+                                      CryptoType::kSpake_p224, &session_id,
+                                      &device_commitment, &error));
+  EXPECT_EQ("deviceBusy", error->GetCode());
+}
+
+}  // namespace privetd
diff --git a/buffet/privet/shill_client.cc b/buffet/privet/shill_client.cc
new file mode 100644
index 0000000..335d568
--- /dev/null
+++ b/buffet/privet/shill_client.cc
@@ -0,0 +1,515 @@
+// Copyright 2014 The Chromium OS 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 "buffet/privet/shill_client.h"
+
+#include <set>
+
+#include <base/message_loop/message_loop.h>
+#include <base/stl_util.h>
+#include <chromeos/any.h>
+#include <chromeos/dbus/service_constants.h>
+#include <chromeos/errors/error.h>
+#include <chromeos/errors/error_codes.h>
+
+using chromeos::Any;
+using chromeos::VariantDictionary;
+using dbus::ObjectPath;
+using org::chromium::flimflam::DeviceProxy;
+using org::chromium::flimflam::ServiceProxy;
+using std::map;
+using std::set;
+using std::string;
+using std::vector;
+
+namespace privetd {
+
+namespace {
+
+void IgnoreDetachEvent() { }
+
+bool GetStateForService(ServiceProxy* service, string* state) {
+  CHECK(service) << "|service| was nullptr in GetStateForService()";
+  VariantDictionary properties;
+  if (!service->GetProperties(&properties, nullptr)) {
+    LOG(WARNING) << "Failed to read properties from service.";
+    return false;
+  }
+  auto property_it = properties.find(shill::kStateProperty);
+  if (property_it == properties.end()) {
+    LOG(WARNING) << "No state found in service properties.";
+    return false;
+  }
+  string new_state = property_it->second.TryGet<string>();
+  if (new_state.empty()) {
+    LOG(WARNING) << "Invalid state value.";
+    return false;
+  }
+  *state = new_state;
+  return true;
+}
+
+ServiceState ShillServiceStateToServiceState(const string& state) {
+  // TODO(wiley) What does "unconfigured" mean in a world with multiple sets
+  //             of WiFi credentials?
+  // TODO(wiley) Detect disabled devices, update state appropriately.
+  if ((state.compare(shill::kStateReady) == 0) ||
+      (state.compare(shill::kStatePortal) == 0) ||
+      (state.compare(shill::kStateOnline) == 0)) {
+    return ServiceState::kConnected;
+  }
+  if ((state.compare(shill::kStateAssociation) == 0) ||
+      (state.compare(shill::kStateConfiguration) == 0)) {
+    return ServiceState::kConnecting;
+  }
+  if ((state.compare(shill::kStateFailure) == 0) ||
+      (state.compare(shill::kStateActivationFailure) == 0)) {
+    // TODO(wiley) Get error information off the service object.
+    return ServiceState::kFailure;
+  }
+  if ((state.compare(shill::kStateIdle) == 0) ||
+      (state.compare(shill::kStateOffline) == 0) ||
+      (state.compare(shill::kStateDisconnect) == 0)) {
+    return ServiceState::kOffline;
+  }
+  LOG(WARNING) << "Unknown state found: '" << state << "'";
+  return ServiceState::kOffline;
+}
+
+}  // namespace
+
+std::string ServiceStateToString(ServiceState state) {
+  switch (state) {
+    case ServiceState::kOffline:
+      return "offline";
+    case ServiceState::kFailure:
+      return "failure";
+    case ServiceState::kConnecting:
+      return "connecting";
+    case ServiceState::kConnected:
+      return "connected";
+  }
+  LOG(ERROR) << "Unknown ServiceState value!";
+  return "unknown";
+}
+
+ShillClient::ShillClient(const scoped_refptr<dbus::Bus>& bus,
+                         const set<string>& device_whitelist)
+    : bus_{bus},
+      manager_proxy_{bus_, ObjectPath{"/"}},
+      device_whitelist_{device_whitelist} {
+  manager_proxy_.RegisterPropertyChangedSignalHandler(
+      base::Bind(&ShillClient::OnManagerPropertyChange,
+                 weak_factory_.GetWeakPtr()),
+      base::Bind(&ShillClient::OnManagerPropertyChangeRegistration,
+                 weak_factory_.GetWeakPtr()));
+  auto owner_changed_cb = base::Bind(&ShillClient::OnShillServiceOwnerChange,
+                                     weak_factory_.GetWeakPtr());
+  bus_->GetObjectProxy(
+      shill::kFlimflamServiceName,
+      ObjectPath{"/"})->SetNameOwnerChangedCallback(owner_changed_cb);
+}
+
+void ShillClient::Init() {
+  VLOG(2) << "ShillClient::Init();";
+  CleanupConnectingService(false);
+  devices_.clear();
+  connectivity_state_ = ServiceState::kOffline;
+  VariantDictionary properties;
+  if (!manager_proxy_.GetProperties(&properties, nullptr)) {
+    LOG(ERROR) << "Unable to get properties from Manager, waiting for "
+                  "Manager to come back online.";
+    return;
+  }
+  auto it = properties.find(shill::kDevicesProperty);
+  CHECK(it != properties.end()) << "shill should always publish a device list.";
+  OnManagerPropertyChange(shill::kDevicesProperty, it->second);
+}
+
+bool ShillClient::ConnectToService(const string& ssid,
+                                   const string& passphrase,
+                                   const base::Closure& on_success,
+                                   chromeos::ErrorPtr* error) {
+  CleanupConnectingService(false);
+  VariantDictionary service_properties;
+  service_properties[shill::kTypeProperty] = Any{string{shill::kTypeWifi}};
+  service_properties[shill::kSSIDProperty] = Any{ssid};
+  service_properties[shill::kPassphraseProperty] = Any{passphrase};
+  service_properties[shill::kSecurityProperty] = Any{
+      string{passphrase.empty() ? shill::kSecurityNone : shill::kSecurityPsk}};
+  service_properties[shill::kSaveCredentialsProperty] = Any{true};
+  service_properties[shill::kAutoConnectProperty] = Any{true};
+  ObjectPath service_path;
+  if (!manager_proxy_.ConfigureService(service_properties,
+                                       &service_path,
+                                       error)) {
+    return false;
+  }
+  if (!manager_proxy_.RequestScan(shill::kTypeWifi, error)) {
+    return false;
+  }
+  connecting_service_.reset(new ServiceProxy{bus_, service_path});
+  on_connect_success_.Reset(on_success);
+  connecting_service_->RegisterPropertyChangedSignalHandler(
+      base::Bind(&ShillClient::OnServicePropertyChange,
+                 weak_factory_.GetWeakPtr(),
+                 service_path),
+      base::Bind(&ShillClient::OnServicePropertyChangeRegistration,
+                 weak_factory_.GetWeakPtr(),
+                 service_path));
+  return true;
+}
+
+ServiceState ShillClient::GetConnectionState() const {
+  return connectivity_state_;
+}
+
+bool ShillClient::AmOnline() const {
+  return connectivity_state_ == ServiceState::kConnected;
+}
+
+void ShillClient::RegisterConnectivityListener(
+    const ConnectivityListener& listener) {
+  connectivity_listeners_.push_back(listener);
+}
+
+bool ShillClient::IsMonitoredDevice(DeviceProxy* device) {
+  if (device_whitelist_.empty()) {
+    return true;
+  }
+  VariantDictionary device_properties;
+  if (!device->GetProperties(&device_properties, nullptr)) {
+    LOG(ERROR) << "Devices without properties aren't whitelisted.";
+    return false;
+  }
+  auto it = device_properties.find(shill::kInterfaceProperty);
+  if (it == device_properties.end()) {
+    LOG(ERROR) << "Failed to find interface property in device properties.";
+    return false;
+  }
+  return ContainsKey(device_whitelist_, it->second.TryGet<string>());
+}
+
+void ShillClient::OnShillServiceOwnerChange(const string& old_owner,
+                                            const string& new_owner) {
+  VLOG(1) << "Shill service owner name changed to '" << new_owner << "'";
+  if (new_owner.empty()) {
+    CleanupConnectingService(false);
+    devices_.clear();
+    connectivity_state_ = ServiceState::kOffline;
+  } else {
+    Init();  // New service owner means shill reset!
+  }
+}
+
+void ShillClient::OnManagerPropertyChangeRegistration(const string& interface,
+                                                      const string& signal_name,
+                                                      bool success) {
+  VLOG(3) << "Registered ManagerPropertyChange handler.";
+  CHECK(success) << "privetd requires Manager signals.";
+  VariantDictionary properties;
+  if (!manager_proxy_.GetProperties(&properties, nullptr)) {
+    LOG(ERROR) << "Unable to get properties from Manager, waiting for "
+                  "Manager to come back online.";
+    return;
+  }
+  auto it = properties.find(shill::kDevicesProperty);
+  CHECK(it != properties.end()) << "Shill should always publish a device list.";
+  OnManagerPropertyChange(shill::kDevicesProperty, it->second);
+}
+
+void ShillClient::OnManagerPropertyChange(const string& property_name,
+                                          const Any& property_value) {
+  if (property_name != shill::kDevicesProperty) {
+    return;
+  }
+  VLOG(3) << "Manager's device list has changed.";
+  // We're going to remove every device we haven't seen in the update.
+  set<ObjectPath> device_paths_to_remove;
+  for (const auto& kv : devices_) {
+    device_paths_to_remove.insert(kv.first);
+  }
+  for (const auto& device_path : property_value.TryGet<vector<ObjectPath>>()) {
+    if (!device_path.IsValid()) {
+      LOG(ERROR) << "Ignoring invalid device path in Manager's device list.";
+      return;
+    }
+    auto it = devices_.find(device_path);
+    if (it != devices_.end()) {
+      // Found an existing proxy.  Since the whitelist never changes,
+      // this still a valid device.
+      device_paths_to_remove.erase(device_path);
+      continue;
+    }
+    std::unique_ptr<DeviceProxy> device{new DeviceProxy{bus_, device_path}};
+    if (!IsMonitoredDevice(device.get())) {
+      continue;
+    }
+    device->RegisterPropertyChangedSignalHandler(
+        base::Bind(&ShillClient::OnDevicePropertyChange,
+                   weak_factory_.GetWeakPtr(),
+                   device_path),
+        base::Bind(&ShillClient::OnDevicePropertyChangeRegistration,
+                   weak_factory_.GetWeakPtr(),
+                   device_path));
+    VLOG(3) << "Creating device proxy at " << device_path.value();
+    devices_[device_path].device = std::move(device);
+  }
+  // Clean up devices/services related to removed devices.
+  if (!device_paths_to_remove.empty()) {
+    for (const ObjectPath& device_path : device_paths_to_remove) {
+      devices_.erase(device_path);
+    }
+    UpdateConnectivityState();
+  }
+}
+
+void ShillClient::OnDevicePropertyChangeRegistration(
+    const ObjectPath& device_path,
+    const string& interface,
+    const string& signal_name,
+    bool success) {
+  VLOG(3) << "Registered DevicePropertyChange handler.";
+  auto it = devices_.find(device_path);
+  if (it == devices_.end()) {
+    return;
+  }
+  CHECK(success) << "Failed to subscribe to Device property changes.";
+  DeviceProxy* device = it->second.device.get();
+  VariantDictionary properties;
+  if (!device->GetProperties(&properties, nullptr)) {
+    LOG(WARNING) << "Failed to get device properties?";
+    return;
+  }
+  auto prop_it = properties.find(shill::kSelectedServiceProperty);
+  if (prop_it == properties.end()) {
+    LOG(WARNING) << "Failed to get device's selected service?";
+    return;
+  }
+  OnDevicePropertyChange(device_path,
+                         shill::kSelectedServiceProperty,
+                         prop_it->second);
+}
+
+void ShillClient::OnDevicePropertyChange(const ObjectPath& device_path,
+                                         const string& property_name,
+                                         const Any& property_value) {
+  // We only care about selected services anyway.
+  if (property_name != shill::kSelectedServiceProperty) {
+    return;
+  }
+  // If the device isn't our list of whitelisted devices, ignore it.
+  auto it = devices_.find(device_path);
+  if (it == devices_.end()) {
+    return;
+  }
+  DeviceState& device_state = it->second;
+  ObjectPath service_path{property_value.TryGet<ObjectPath>()};
+  if (!service_path.IsValid()) {
+    LOG(ERROR) << "Device at " << device_path.value()
+               << " selected invalid service path.";
+    return;
+  }
+  VLOG(3) << "Device at " << it->first.value()
+          << " has selected service at " << service_path.value();
+  bool removed_old_service{false};
+  if (device_state.selected_service) {
+    if (device_state.selected_service->GetObjectPath() == service_path) {
+      return;  // Spurious update?
+    }
+    device_state.selected_service.reset();
+    device_state.service_state = ServiceState::kOffline;
+    removed_old_service = true;
+  }
+  std::shared_ptr<ServiceProxy> new_service;
+  const bool reuse_connecting_service =
+      service_path.value() != "/" &&
+      connecting_service_ &&
+      connecting_service_->GetObjectPath() == service_path;
+  if (reuse_connecting_service) {
+    new_service = connecting_service_;
+    // When we reuse the connecting service, we need to make sure that our
+    // cached state is correct.  Normally, we do this by relying reading the
+    // state when our signal handlers finish registering, but this may have
+    // happened long in the past for the connecting service.
+    string state;
+    if (GetStateForService(new_service.get(), &state)) {
+      device_state.service_state = ShillServiceStateToServiceState(state);
+    } else {
+      LOG(WARNING) << "Failed to read properties from existing service "
+                      "on selection.";
+    }
+  } else if (service_path.value() != "/") {
+    // The device has selected a new service we haven't see before.
+    new_service.reset(new ServiceProxy{bus_, service_path});
+    new_service->RegisterPropertyChangedSignalHandler(
+        base::Bind(&ShillClient::OnServicePropertyChange,
+                   weak_factory_.GetWeakPtr(),
+                   service_path),
+        base::Bind(&ShillClient::OnServicePropertyChangeRegistration,
+                   weak_factory_.GetWeakPtr(),
+                   service_path));
+  }
+  device_state.selected_service = new_service;
+  if (reuse_connecting_service || removed_old_service) {
+    UpdateConnectivityState();
+  }
+}
+
+void ShillClient::OnServicePropertyChangeRegistration(const ObjectPath& path,
+                                                      const string& interface,
+                                                      const string& signal_name,
+                                                      bool success) {
+  VLOG(3) << "OnServicePropertyChangeRegistration(" << path.value() << ");";
+  ServiceProxy* service{nullptr};
+  if (connecting_service_ && connecting_service_->GetObjectPath() == path) {
+    // Note that the connecting service might also be a selected service.
+    service = connecting_service_.get();
+    if (!success) {
+      CleanupConnectingService(false);
+    }
+  } else {
+    for (const auto& kv : devices_) {
+      if (kv.second.selected_service &&
+          kv.second.selected_service->GetObjectPath() == path) {
+        service = kv.second.selected_service.get();
+        break;
+      }
+    }
+  }
+  if (service == nullptr || !success) {
+    return;  // A failure or success for a proxy we no longer care about.
+  }
+  VariantDictionary properties;
+  if (!service->GetProperties(&properties, nullptr)) {
+    return;
+  }
+  // Give ourselves property changed signals for the initial property
+  // values.
+  auto it = properties.find(shill::kStateProperty);
+  if (it != properties.end()) {
+    OnServicePropertyChange(path, shill::kStateProperty,
+                            it->second);
+  }
+  it = properties.find(shill::kSignalStrengthProperty);
+  if (it != properties.end()) {
+    OnServicePropertyChange(path, shill::kSignalStrengthProperty,
+                            it->second);
+  }
+}
+
+void ShillClient::OnServicePropertyChange(const ObjectPath& service_path,
+                                          const string& property_name,
+                                          const Any& property_value) {
+  VLOG(3) << "ServicePropertyChange(" << service_path.value() << ", "
+          << property_name << ", ...);";
+  if (property_name == shill::kStateProperty) {
+    const string state{property_value.TryGet<string>()};
+    if (state.empty()) {
+      VLOG(3) << "Invalid service state update.";
+      return;
+    }
+    VLOG(3) << "New service state=" << state;
+    OnStateChangeForSelectedService(service_path, state);
+    OnStateChangeForConnectingService(service_path, state);
+  } else if (property_name == shill::kSignalStrengthProperty) {
+    OnStrengthChangeForConnectingService(
+        service_path, property_value.TryGet<uint8_t>());
+  }
+}
+
+void ShillClient::OnStateChangeForConnectingService(
+    const ObjectPath& service_path,
+    const string& state) {
+  if (!connecting_service_ ||
+      connecting_service_->GetObjectPath() != service_path ||
+      ShillServiceStateToServiceState(state) != ServiceState::kConnected) {
+    return;
+  }
+  connecting_service_reset_pending_ = true;
+  on_connect_success_.callback().Run();
+  CleanupConnectingService(true);
+}
+
+void ShillClient::OnStrengthChangeForConnectingService(
+    const ObjectPath& service_path,
+    uint8_t signal_strength) {
+  if (!connecting_service_ ||
+      connecting_service_->GetObjectPath() != service_path ||
+      signal_strength <= 0 ||
+      have_called_connect_) {
+    return;
+  }
+  VLOG(1) << "Connecting service has signal. Calling Connect().";
+  have_called_connect_ = true;
+  // Failures here indicate that we've already connected,
+  // or are connecting, or some other very unexciting thing.
+  // Ignore all that, and rely on state changes to detect
+  // connectivity.
+  connecting_service_->Connect(nullptr);
+}
+
+void ShillClient::OnStateChangeForSelectedService(
+    const ObjectPath& service_path,
+    const string& state) {
+  // Find the device/service pair responsible for this update
+  VLOG(3) << "State for potentially selected service " << service_path.value()
+          << " have changed to " << state;
+  for (auto& kv : devices_) {
+    if (kv.second.selected_service &&
+        kv.second.selected_service->GetObjectPath() == service_path) {
+      VLOG(3) << "Updated cached connection state for selected service.";
+      kv.second.service_state = ShillServiceStateToServiceState(state);
+      UpdateConnectivityState();
+      return;
+    }
+  }
+}
+
+void ShillClient::UpdateConnectivityState() {
+  // Update the connectivity state of the device by picking the
+  // state of the currently most connected selected service.
+  ServiceState new_connectivity_state{ServiceState::kOffline};
+  for (const auto& kv : devices_) {
+    if (kv.second.service_state > new_connectivity_state) {
+      new_connectivity_state = kv.second.service_state;
+    }
+  }
+  VLOG(3) << "New connectivity state is "
+          << ServiceStateToString(new_connectivity_state);
+  if (new_connectivity_state != connectivity_state_) {
+    connectivity_state_ = new_connectivity_state;
+    // We may call UpdateConnectivityState whenever we mutate a data structure
+    // such that our connectivity status could change.  However, we don't want
+    // to allow people to call into ShillClient while some other operation is
+    // underway.  Therefore, call our callbacks later, when we're in a good
+    // state.
+    base::MessageLoop::current()->PostTask(
+        FROM_HERE,
+        base::Bind(&ShillClient::NotifyConnectivityListeners,
+                   weak_factory_.GetWeakPtr(), AmOnline()));
+  }
+}
+
+void ShillClient::NotifyConnectivityListeners(bool am_online) {
+  VLOG(3) << "Notifying connectivity listeners that online=" << am_online;
+  for (const auto& listener : connectivity_listeners_) {
+    listener.Run(am_online);
+  }
+}
+
+void ShillClient::CleanupConnectingService(bool check_for_reset_pending) {
+  if (check_for_reset_pending && !connecting_service_reset_pending_) {
+    return;  // Must have called connect before we got here.
+  }
+  if (connecting_service_) {
+    connecting_service_->ReleaseObjectProxy(base::Bind(&IgnoreDetachEvent));
+    connecting_service_.reset();
+  }
+  on_connect_success_.Cancel();
+  have_called_connect_ = false;
+  connecting_service_reset_pending_ = false;
+}
+
+}  // namespace privetd
diff --git a/buffet/privet/shill_client.h b/buffet/privet/shill_client.h
new file mode 100644
index 0000000..d8e6959
--- /dev/null
+++ b/buffet/privet/shill_client.h
@@ -0,0 +1,134 @@
+// Copyright 2014 The Chromium OS 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 BUFFET_PRIVET_SHILL_CLIENT_H_
+#define BUFFET_PRIVET_SHILL_CLIENT_H_
+
+#include <map>
+#include <set>
+#include <string>
+#include <vector>
+
+#include <base/callback.h>
+#include <base/cancelable_callback.h>
+#include <base/macros.h>
+#include <base/memory/ref_counted.h>
+#include <base/memory/weak_ptr.h>
+#include <dbus/bus.h>
+
+#include "shill/dbus-proxies.h"
+
+namespace privetd {
+
+enum class ServiceState {
+  kOffline = 0,
+  kFailure,
+  kConnecting,
+  kConnected,
+};
+
+std::string ServiceStateToString(ServiceState state);
+
+class ShillClient final {
+ public:
+  // A callback that interested parties can register to be notified of
+  // transitions from online to offline and vice versa.  The boolean
+  // parameter will be true if we're online, and false if we're offline.
+  using ConnectivityListener = base::Callback<void(bool)>;
+
+  ShillClient(const scoped_refptr<dbus::Bus>& bus,
+              const std::set<std::string>& device_whitelist);
+  ~ShillClient() = default;
+
+
+  void Init();
+  void RegisterConnectivityListener(const ConnectivityListener& listener);
+  // Causes shill to attempt to connect to the given network with the given
+  // passphrase.  This is accomplished by:
+  //  1) Configuring a service through the Manager with the SSID and passphrase.
+  //  2) Calling Connect() on the service.
+  //  2) Monitoring the returned Service object until we reach an online state,
+  //     an error state, or another call to ConnectToService() occurs.
+  // Returns false on immediate failures with some descriptive codes in |error|.
+  bool ConnectToService(const std::string& ssid,
+                        const std::string& passphrase,
+                        const base::Closure& on_success,
+                        chromeos::ErrorPtr* error);
+  ServiceState GetConnectionState() const;
+  bool AmOnline() const;
+
+ private:
+  struct DeviceState {
+    std::unique_ptr<org::chromium::flimflam::DeviceProxy> device;
+    // ServiceProxy objects are shared because the connecting service will
+    // also be the selected service for a device, but is not always the selected
+    // service (for instance, in the period between configuring a WiFi service
+    // with credentials, and when Connect() is called.)
+    std::shared_ptr<org::chromium::flimflam::ServiceProxy> selected_service;
+    ServiceState service_state{ServiceState::kOffline};
+  };
+
+  bool IsMonitoredDevice(org::chromium::flimflam::DeviceProxy* device);
+  void OnShillServiceOwnerChange(const std::string& old_owner,
+                                 const std::string& new_owner);
+  void OnManagerPropertyChangeRegistration(const std::string& interface,
+                                           const std::string& signal_name,
+                                           bool success);
+  void OnManagerPropertyChange(const std::string& property_name,
+                               const chromeos::Any& property_value);
+  void OnDevicePropertyChangeRegistration(const dbus::ObjectPath& device_path,
+                                          const std::string& interface,
+                                          const std::string& signal_name,
+                                          bool success);
+  void OnDevicePropertyChange(const dbus::ObjectPath& device_path,
+                              const std::string& property_name,
+                              const chromeos::Any& property_value);
+  void OnServicePropertyChangeRegistration(const dbus::ObjectPath& path,
+                                           const std::string& interface,
+                                           const std::string& signal_name,
+                                           bool success);
+  void OnServicePropertyChange(const dbus::ObjectPath& service_path,
+                               const std::string& property_name,
+                               const chromeos::Any& property_value);
+
+  void OnStateChangeForConnectingService(const dbus::ObjectPath& service_path,
+                                         const std::string& state);
+  void OnStrengthChangeForConnectingService(
+      const dbus::ObjectPath& service_path,
+      uint8_t signal_strength);
+  void OnStateChangeForSelectedService(const dbus::ObjectPath& service_path,
+                                       const std::string& state);
+  void UpdateConnectivityState();
+  void NotifyConnectivityListeners(bool am_online);
+  // Clean up state related to a connecting service.  If
+  // |check_for_reset_pending| is set, then we'll check to see if we've called
+  // ConnectToService() in the time since a task to call this function was
+  // posted.
+  void CleanupConnectingService(bool check_for_reset_pending);
+
+  const scoped_refptr<dbus::Bus> bus_;
+  org::chromium::flimflam::ManagerProxy manager_proxy_;
+  // There is logic that assumes we will never change this device list
+  // in OnManagerPropertyChange.  Do not be tempted to remove this const.
+  const std::set<std::string> device_whitelist_;
+  std::vector<ConnectivityListener> connectivity_listeners_;
+
+  // State for tracking where we are in our attempts to connect to a service.
+  bool connecting_service_reset_pending_{false};
+  bool have_called_connect_{false};
+  std::shared_ptr<org::chromium::flimflam::ServiceProxy> connecting_service_;
+  base::CancelableClosure on_connect_success_;
+
+  // State for tracking our online connectivity.
+  std::map<dbus::ObjectPath, DeviceState> devices_;
+  ServiceState connectivity_state_{ServiceState::kOffline};
+
+  base::WeakPtrFactory<ShillClient> weak_factory_{this};
+
+  DISALLOW_COPY_AND_ASSIGN(ShillClient);
+};
+
+}  // namespace privetd
+
+#endif  // BUFFET_PRIVET_SHILL_CLIENT_H_
diff --git a/buffet/privet/wifi_bootstrap_manager.cc b/buffet/privet/wifi_bootstrap_manager.cc
new file mode 100644
index 0000000..6c2bc4f
--- /dev/null
+++ b/buffet/privet/wifi_bootstrap_manager.cc
@@ -0,0 +1,293 @@
+// Copyright 2014 The Chromium OS 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 "buffet/privet/wifi_bootstrap_manager.h"
+
+#include <base/logging.h>
+#include <base/memory/weak_ptr.h>
+#include <base/message_loop/message_loop.h>
+#include <chromeos/bind_lambda.h>
+#include <chromeos/key_value_store.h>
+
+#include "buffet/privet/ap_manager_client.h"
+#include "buffet/privet/constants.h"
+#include "buffet/privet/shill_client.h"
+
+namespace privetd {
+
+WifiBootstrapManager::WifiBootstrapManager(DaemonState* state_store,
+                                           ShillClient* shill_client,
+                                           ApManagerClient* ap_manager_client,
+                                           CloudDelegate* gcd,
+                                           uint32_t connect_timeout_seconds,
+                                           uint32_t bootstrap_timeout_seconds,
+                                           uint32_t monitor_timeout_seconds)
+    : state_store_(state_store),
+      shill_client_(shill_client),
+      ap_manager_client_(ap_manager_client),
+      ssid_generator_(gcd, this),
+      connect_timeout_seconds_(connect_timeout_seconds),
+      bootstrap_timeout_seconds_(bootstrap_timeout_seconds),
+      monitor_timeout_seconds_(monitor_timeout_seconds) {
+  cloud_observer_.Add(gcd);
+}
+
+void WifiBootstrapManager::Init() {
+  CHECK(!is_initialized_);
+  std::string ssid = ssid_generator_.GenerateSsid();
+  if (ssid.empty())
+    return;  // Delay initialization until ssid_generator_ is ready.
+  chromeos::KeyValueStore state_store;
+  if (!state_store_->GetBoolean(state_key::kWifiHasBeenBootstrapped,
+                                &have_ever_been_bootstrapped_) ||
+      !state_store_->GetString(state_key::kWifiLastConfiguredSSID,
+                               &last_configured_ssid_)) {
+    have_ever_been_bootstrapped_ = false;
+  }
+  UpdateConnectionState();
+  shill_client_->RegisterConnectivityListener(
+      base::Bind(&WifiBootstrapManager::OnConnectivityChange,
+                 lifetime_weak_factory_.GetWeakPtr()));
+  if (!have_ever_been_bootstrapped_) {
+    StartBootstrapping();
+  } else {
+    StartMonitoring();
+  }
+  is_initialized_ = true;
+}
+
+void WifiBootstrapManager::RegisterStateListener(
+    const StateListener& listener) {
+  // Notify about current state.
+  listener.Run(state_);
+  state_listeners_.push_back(listener);
+}
+
+void WifiBootstrapManager::StartBootstrapping() {
+  if (shill_client_->AmOnline()) {
+    // If one of the devices we monitor for connectivity is online, we need not
+    // start an AP.  For most devices, this is a situation which happens in
+    // testing when we have an ethernet connection.  If you need to always
+    // start an AP to bootstrap WiFi credentials, then add your WiFi interface
+    // to the device whitelist.
+    StartMonitoring();
+    return;
+  }
+
+  UpdateState(kBootstrapping);
+  if (have_ever_been_bootstrapped_) {
+    // If we have been configured before, we'd like to periodically take down
+    // our AP and find out if we can connect again.  Many kinds of failures are
+    // transient, and having an AP up prohibits us from connecting as a client.
+    base::MessageLoop::current()->PostDelayedTask(
+        FROM_HERE, base::Bind(&WifiBootstrapManager::OnBootstrapTimeout,
+                              tasks_weak_factory_.GetWeakPtr()),
+        base::TimeDelta::FromSeconds(bootstrap_timeout_seconds_));
+  }
+  // TODO(vitalybuka): Add SSID probing.
+  std::string ssid = ssid_generator_.GenerateSsid();
+  CHECK(!ssid.empty());
+  ap_manager_client_->Start(ssid);
+}
+
+void WifiBootstrapManager::EndBootstrapping() {
+  ap_manager_client_->Stop();
+}
+
+void WifiBootstrapManager::StartConnecting(const std::string& ssid,
+                                           const std::string& passphrase) {
+  VLOG(1) << "WiFi is attempting to connect. (ssid=" << ssid
+          << ", pass=" << passphrase << ").";
+  UpdateState(kConnecting);
+  base::MessageLoop::current()->PostDelayedTask(
+      FROM_HERE, base::Bind(&WifiBootstrapManager::OnConnectTimeout,
+                            tasks_weak_factory_.GetWeakPtr()),
+      base::TimeDelta::FromSeconds(connect_timeout_seconds_));
+  shill_client_->ConnectToService(
+      ssid, passphrase, base::Bind(&WifiBootstrapManager::OnConnectSuccess,
+                                   tasks_weak_factory_.GetWeakPtr(), ssid),
+      nullptr);
+}
+
+void WifiBootstrapManager::EndConnecting() {
+}
+
+void WifiBootstrapManager::StartMonitoring() {
+  VLOG(1) << "Monitoring connectivity.";
+  // We already have a callback in place with |shill_client_| to update our
+  // connectivity state.  See OnConnectivityChange().
+  UpdateState(kMonitoring);
+}
+
+void WifiBootstrapManager::EndMonitoring() {
+}
+
+void WifiBootstrapManager::UpdateState(State new_state) {
+  VLOG(3) << "Switching state from " << state_ << " to " << new_state;
+  // Abort irrelevant tasks.
+  tasks_weak_factory_.InvalidateWeakPtrs();
+
+  switch (state_) {
+    case kDisabled:
+      break;
+    case kBootstrapping:
+      EndBootstrapping();
+      break;
+    case kMonitoring:
+      EndMonitoring();
+      break;
+    case kConnecting:
+      EndConnecting();
+      break;
+  }
+
+  if (new_state != state_) {
+    state_ = new_state;
+    // Post with weak ptr to avoid notification after this object destroyed.
+    base::MessageLoop::current()->PostTask(
+        FROM_HERE, base::Bind(&WifiBootstrapManager::NotifyStateListeners,
+                              lifetime_weak_factory_.GetWeakPtr(), new_state));
+  } else {
+    VLOG(3) << "Not notifying listeners of state change, "
+            << "because the states are the same.";
+  }
+}
+
+void WifiBootstrapManager::NotifyStateListeners(State new_state) const {
+  for (const StateListener& listener : state_listeners_)
+    listener.Run(new_state);
+}
+
+const ConnectionState& WifiBootstrapManager::GetConnectionState() const {
+  return connection_state_;
+}
+
+const SetupState& WifiBootstrapManager::GetSetupState() const {
+  return setup_state_;
+}
+
+bool WifiBootstrapManager::ConfigureCredentials(const std::string& ssid,
+                                                const std::string& passphrase,
+                                                chromeos::ErrorPtr* error) {
+  setup_state_ = SetupState{SetupState::kInProgress};
+  // TODO(vitalybuka): Find more reliable way to finish request or move delay
+  // into PrivetHandler as it's very HTTP specific.
+  base::MessageLoop::current()->PostDelayedTask(
+      FROM_HERE, base::Bind(&WifiBootstrapManager::StartConnecting,
+                            tasks_weak_factory_.GetWeakPtr(), ssid, passphrase),
+      base::TimeDelta::FromSeconds(kSetupDelaySeconds));
+  return true;
+}
+
+std::string WifiBootstrapManager::GetCurrentlyConnectedSsid() const {
+  // TODO(vitalybuka): Get from shill, if possible.
+  return last_configured_ssid_;
+}
+
+std::string WifiBootstrapManager::GetHostedSsid() const {
+  return ap_manager_client_->GetSsid();
+}
+
+std::set<WifiType> WifiBootstrapManager::GetTypes() const {
+  // TODO(wiley) This should do some system work to figure this out.
+  return {WifiType::kWifi24};
+}
+
+void WifiBootstrapManager::OnDeviceInfoChanged() {
+  // Initialization was delayed until buffet is ready.
+  if (!is_initialized_)
+    Init();
+}
+
+void WifiBootstrapManager::OnConnectSuccess(const std::string& ssid) {
+  VLOG(1) << "Wifi was connected successfully";
+  have_ever_been_bootstrapped_ = true;
+  last_configured_ssid_ = ssid;
+  state_store_->SetBoolean(state_key::kWifiHasBeenBootstrapped,
+                           have_ever_been_bootstrapped_);
+  state_store_->SetString(state_key::kWifiLastConfiguredSSID,
+                          last_configured_ssid_);
+  state_store_->Save();
+  setup_state_ = SetupState{SetupState::kSuccess};
+  StartMonitoring();
+}
+
+void WifiBootstrapManager::OnBootstrapTimeout() {
+  VLOG(1) << "Bootstrapping has timed out.";
+  StartMonitoring();
+}
+
+void WifiBootstrapManager::OnConnectTimeout() {
+  VLOG(1) << "Wifi timed out while connecting";
+  chromeos::ErrorPtr error;
+  chromeos::Error::AddTo(&error, FROM_HERE, errors::kDomain,
+                         errors::kInvalidState,
+                         "Failed to connect to provided network");
+  setup_state_ = SetupState{std::move(error)};
+  StartBootstrapping();
+}
+
+void WifiBootstrapManager::OnConnectivityChange(bool is_connected) {
+  VLOG(3) << "ConnectivityChanged: " << is_connected;
+  UpdateConnectionState();
+
+  if (state_ == kBootstrapping) {
+    StartMonitoring();
+    return;
+  }
+  if (state_ == kMonitoring) {
+    if (is_connected) {
+      tasks_weak_factory_.InvalidateWeakPtrs();
+    } else {
+      // Tasks queue may have more than one OnMonitorTimeout enqueued. The
+      // first one could be executed as it would change the state and abort the
+      // rest.
+      base::MessageLoop::current()->PostDelayedTask(
+          FROM_HERE, base::Bind(&WifiBootstrapManager::OnMonitorTimeout,
+                                tasks_weak_factory_.GetWeakPtr()),
+          base::TimeDelta::FromSeconds(monitor_timeout_seconds_));
+    }
+  }
+}
+
+void WifiBootstrapManager::OnMonitorTimeout() {
+  VLOG(1) << "Spent too long offline.  Entering bootstrap mode.";
+  // TODO(wiley) Retrieve relevant errors from shill.
+  StartBootstrapping();
+}
+
+void WifiBootstrapManager::UpdateConnectionState() {
+  connection_state_ = ConnectionState{ConnectionState::kUnconfigured};
+  if (!have_ever_been_bootstrapped_) {
+    return;
+  }
+  ServiceState service_state{shill_client_->GetConnectionState()};
+  switch (service_state) {
+    case ServiceState::kOffline:
+      connection_state_ = ConnectionState{ConnectionState::kOffline};
+      return;
+    case ServiceState::kFailure: {
+      // TODO(wiley) Pull error information from somewhere.
+      chromeos::ErrorPtr error;
+      chromeos::Error::AddTo(&error, FROM_HERE, errors::kDomain,
+                             errors::kInvalidState, "Unknown WiFi error");
+      connection_state_ = ConnectionState{std::move(error)};
+      return;
+    }
+    case ServiceState::kConnecting:
+      connection_state_ = ConnectionState{ConnectionState::kConnecting};
+      return;
+    case ServiceState::kConnected:
+      connection_state_ = ConnectionState{ConnectionState::kOnline};
+      return;
+  }
+  chromeos::ErrorPtr error;
+  chromeos::Error::AddToPrintf(
+      &error, FROM_HERE, errors::kDomain, errors::kInvalidState,
+      "Unknown state returned from ShillClient: %s",
+      ServiceStateToString(service_state).c_str());
+  connection_state_ = ConnectionState{std::move(error)};
+}
+
+}  // namespace privetd
diff --git a/buffet/privet/wifi_bootstrap_manager.h b/buffet/privet/wifi_bootstrap_manager.h
new file mode 100644
index 0000000..bb7d3ea
--- /dev/null
+++ b/buffet/privet/wifi_bootstrap_manager.h
@@ -0,0 +1,130 @@
+// Copyright 2014 The Chromium OS 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 BUFFET_PRIVET_WIFI_BOOTSTRAP_MANAGER_H_
+#define BUFFET_PRIVET_WIFI_BOOTSTRAP_MANAGER_H_
+
+#include <set>
+#include <string>
+#include <vector>
+
+#include <base/callback.h>
+#include <base/files/file_path.h>
+#include <base/macros.h>
+#include <base/memory/weak_ptr.h>
+#include <base/scoped_observer.h>
+
+#include "buffet/privet/cloud_delegate.h"
+#include "buffet/privet/daemon_state.h"
+#include "buffet/privet/privet_types.h"
+#include "buffet/privet/wifi_delegate.h"
+#include "buffet/privet/wifi_ssid_generator.h"
+
+namespace privetd {
+
+class ApManagerClient;
+class CloudDelegate;
+class DeviceDelegate;
+class ShillClient;
+
+class WifiBootstrapManager : public WifiDelegate,
+                             public CloudDelegate::Observer {
+ public:
+  enum State {
+    kDisabled,
+    kBootstrapping,
+    kMonitoring,
+    kConnecting,
+  };
+
+  using StateListener = base::Callback<void(State)>;
+
+  WifiBootstrapManager(DaemonState* state_store,
+                       ShillClient* shill_client,
+                       ApManagerClient* ap_manager_client,
+                       CloudDelegate* gcd,
+                       uint32_t connect_timeout_seconds,
+                       uint32_t bootstrap_timeout_seconds,
+                       uint32_t monitor_timeout_seconds);
+  ~WifiBootstrapManager() override = default;
+  virtual void Init();
+  void RegisterStateListener(const StateListener& listener);
+
+  // Overrides from WifiDelegate.
+  const ConnectionState& GetConnectionState() const override;
+  const SetupState& GetSetupState() const override;
+  bool ConfigureCredentials(const std::string& ssid,
+                            const std::string& passphrase,
+                            chromeos::ErrorPtr* error) override;
+  std::string GetCurrentlyConnectedSsid() const override;
+  std::string GetHostedSsid() const override;
+  std::set<WifiType> GetTypes() const override;
+
+  // Overrides from CloudDelegate::Observer.
+  void OnDeviceInfoChanged() override;
+
+ private:
+  // These Start* tasks:
+  //   1) Do state appropriate work for entering the indicated state.
+  //   2) Update the state variable to reflect that we're in a new state
+  //   3) Call StateListeners to notify that we've transitioned.
+  // These End* tasks perform cleanup on leaving indicated state.
+  void StartBootstrapping();
+  void EndBootstrapping();
+
+  void StartConnecting(const std::string& ssid, const std::string& passphrase);
+  void EndConnecting();
+
+  void StartMonitoring();
+  void EndMonitoring();
+
+  // Update the current state, post tasks to notify listeners accordingly to
+  // the MessageLoop.
+  void UpdateState(State new_state);
+  void NotifyStateListeners(State new_state) const;
+
+  // If we've been bootstrapped successfully before, and we're bootstrapping
+  // again because we slipped offline for a sufficiently longtime, we want
+  // to return to monitoring mode periodically in case our connectivity issues
+  // were temporary.
+  void OnBootstrapTimeout();
+  void OnConnectTimeout();
+  void OnConnectSuccess(const std::string& ssid);
+  void OnConnectivityChange(bool is_connected);
+  void OnMonitorTimeout();
+  void UpdateConnectionState();
+
+  // Initialization could be delayed if ssid_generator_ is not ready.
+  bool is_initialized_{false};
+  State state_{kDisabled};
+  // Setup state is the temporal state of the most recent bootstrapping attempt.
+  // It is not persisted to disk.
+  SetupState setup_state_{SetupState::kNone};
+  ConnectionState connection_state_{ConnectionState::kDisabled};
+  DaemonState* state_store_;
+  ShillClient* shill_client_;
+  ApManagerClient* ap_manager_client_;
+  WifiSsidGenerator ssid_generator_;
+
+  uint32_t connect_timeout_seconds_;
+  uint32_t bootstrap_timeout_seconds_;
+  uint32_t monitor_timeout_seconds_;
+  std::vector<StateListener> state_listeners_;
+  bool have_ever_been_bootstrapped_{false};
+  bool currently_online_{false};
+  std::string last_configured_ssid_;
+
+  ScopedObserver<CloudDelegate, CloudDelegate::Observer> cloud_observer_{this};
+
+  // Helps to reset irrelevant tasks switching state.
+  base::WeakPtrFactory<WifiBootstrapManager> tasks_weak_factory_{this};
+
+  base::WeakPtrFactory<WifiBootstrapManager> lifetime_weak_factory_{this};
+
+  DISALLOW_COPY_AND_ASSIGN(WifiBootstrapManager);
+};
+
+}  // namespace privetd
+
+#endif  // BUFFET_PRIVET_WIFI_BOOTSTRAP_MANAGER_H_
diff --git a/buffet/privet/wifi_delegate.h b/buffet/privet/wifi_delegate.h
new file mode 100644
index 0000000..f350652
--- /dev/null
+++ b/buffet/privet/wifi_delegate.h
@@ -0,0 +1,55 @@
+// Copyright 2014 The Chromium OS 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 BUFFET_PRIVET_WIFI_DELEGATE_H_
+#define BUFFET_PRIVET_WIFI_DELEGATE_H_
+
+#include <memory>
+#include <set>
+#include <string>
+
+#include "buffet/privet/privet_types.h"
+
+namespace privetd {
+
+enum class WifiType {
+  kWifi24,
+  kWifi50,
+};
+
+// Interface to provide WiFi functionality for PrivetHandler.
+class WifiDelegate {
+ public:
+  WifiDelegate() = default;
+  virtual ~WifiDelegate() = default;
+
+  // Returns status of the WiFi connection.
+  virtual const ConnectionState& GetConnectionState() const = 0;
+
+  // Returns status of the last WiFi setup.
+  virtual const SetupState& GetSetupState() const = 0;
+
+  // Starts WiFi setup. Device should try to connect to provided SSID and
+  // password and store them on success. Result of setup should be available
+  // using GetSetupState().
+  // Final setup state can be retrieved with GetSetupState().
+  virtual bool ConfigureCredentials(const std::string& ssid,
+                                    const std::string& password,
+                                    chromeos::ErrorPtr* error) = 0;
+
+  // Returns SSID of the currently configured WiFi network. Empty string, if
+  // WiFi has not been configured yet.
+  virtual std::string GetCurrentlyConnectedSsid() const = 0;
+
+  // Returns SSID of the WiFi network hosted by this device. Empty if device is
+  // not in setup or P2P modes.
+  virtual std::string GetHostedSsid() const = 0;
+
+  // Returns list of supported WiFi types. Currently it's just frequencies.
+  virtual std::set<WifiType> GetTypes() const = 0;
+};
+
+}  // namespace privetd
+
+#endif  // BUFFET_PRIVET_WIFI_DELEGATE_H_
diff --git a/buffet/privet/wifi_ssid_generator.cc b/buffet/privet/wifi_ssid_generator.cc
new file mode 100644
index 0000000..0fa0c7c
--- /dev/null
+++ b/buffet/privet/wifi_ssid_generator.cc
@@ -0,0 +1,92 @@
+// Copyright 2014 The Chromium OS 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 "buffet/privet/wifi_ssid_generator.h"
+
+#include <bitset>
+
+#include <base/bind.h>
+#include <base/rand_util.h>
+#include <base/strings/string_number_conversions.h>
+#include <base/strings/stringprintf.h>
+
+#include "buffet/privet/cloud_delegate.h"
+#include "buffet/privet/device_delegate.h"
+#include "buffet/privet/wifi_delegate.h"
+
+namespace privetd {
+
+namespace {
+
+const int kDeviceNameSize = 20;
+// [DeviceName+Idx <= 20].[modelID == 5][flags == 2]prv
+const char kSsidFormat[] = "%s %s.%5.5s%2.2sprv";
+
+const char base64chars[] =
+    "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+
+bool IsSetupNeeded(const ConnectionState& state) {
+  if (state.error())
+    return true;
+  switch (state.status()) {
+    case ConnectionState::kUnconfigured:
+      return true;
+    case ConnectionState::kDisabled:
+    case ConnectionState::kConnecting:
+    case ConnectionState::kOnline:
+    case ConnectionState::kOffline:
+      return false;
+  }
+  CHECK(false);
+  return false;
+}
+
+}  // namespace
+
+WifiSsidGenerator::WifiSsidGenerator(const CloudDelegate* cloud,
+                                     const WifiDelegate* wifi)
+    : gcd_(cloud), wifi_(wifi), get_random_(base::Bind(&base::RandInt, 0, 99)) {
+  CHECK(gcd_);
+}
+
+std::string WifiSsidGenerator::GenerateFlags() const {
+  std::bitset<6> flags1;
+  // Device needs WiFi configuration.
+  flags1[0] = wifi_ && IsSetupNeeded(wifi_->GetConnectionState());
+  // Device needs GCD registration.
+  flags1[1] = IsSetupNeeded(gcd_->GetConnectionState());
+
+  std::bitset<6> flags2;
+  // Device is discoverable over WiFi.
+  flags2[0] = true;
+
+  std::string result{2, base64chars[0]};
+  result[0] = base64chars[flags1.to_ulong()];
+  result[1] = base64chars[flags2.to_ulong()];
+  return result;
+}
+
+std::string WifiSsidGenerator::GenerateSsid() const {
+  std::string name;
+  std::string model_id;
+  if (!gcd_ || !gcd_->GetName(&name, nullptr) ||
+      !gcd_->GetModelId(&model_id, nullptr)) {
+    return std::string();
+  }
+  std::string idx{base::IntToString(get_random_.Run())};
+  name = name.substr(0, kDeviceNameSize - idx.size() - 1);
+  CHECK_EQ(5u, model_id.size());
+
+  std::string result =
+      base::StringPrintf(kSsidFormat, name.c_str(), idx.c_str(),
+                         model_id.c_str(), GenerateFlags().c_str());
+  CHECK_EQ(result[result.size() - 11], '.');
+  return result;
+}
+
+void WifiSsidGenerator::SetRandomForTests(int n) {
+  get_random_ = base::Bind(&base::RandInt, n, n);
+}
+
+}  // namespace privetd
diff --git a/buffet/privet/wifi_ssid_generator.h b/buffet/privet/wifi_ssid_generator.h
new file mode 100644
index 0000000..33e9628
--- /dev/null
+++ b/buffet/privet/wifi_ssid_generator.h
@@ -0,0 +1,43 @@
+// Copyright 2014 The Chromium OS 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 BUFFET_PRIVET_WIFI_SSID_GENERATOR_H_
+#define BUFFET_PRIVET_WIFI_SSID_GENERATOR_H_
+
+#include <string>
+
+#include <base/callback.h>
+
+namespace privetd {
+
+class CloudDelegate;
+class WifiDelegate;
+
+class WifiSsidGenerator final {
+ public:
+  WifiSsidGenerator(const CloudDelegate* gcd, const WifiDelegate* wifi);
+  ~WifiSsidGenerator() = default;
+
+  std::string GenerateFlags() const;
+
+  // Can return empty string if CloudDelegate is not ready.
+  std::string GenerateSsid() const;
+
+ private:
+  friend class WifiSsidGeneratorTest;
+
+  // Sets object to use |n| instead of random number for SSID generation.
+  void SetRandomForTests(int n);
+
+  const CloudDelegate* gcd_{nullptr};
+  const WifiDelegate* wifi_{nullptr};
+
+  base::Callback<int(void)> get_random_;
+
+  DISALLOW_COPY_AND_ASSIGN(WifiSsidGenerator);
+};
+
+}  // namespace privetd
+
+#endif  // BUFFET_PRIVET_WIFI_SSID_GENERATOR_H_
diff --git a/buffet/privet/wifi_ssid_generator_unittest.cc b/buffet/privet/wifi_ssid_generator_unittest.cc
new file mode 100644
index 0000000..16c4475
--- /dev/null
+++ b/buffet/privet/wifi_ssid_generator_unittest.cc
@@ -0,0 +1,68 @@
+// Copyright 2014 The Chromium OS 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 "buffet/privet/wifi_ssid_generator.h"
+
+#include <base/strings/utf_string_conversions.h>
+#include <gtest/gtest.h>
+
+#include "buffet/privet/mock_delegates.h"
+#include "buffet/privet/openssl_utils.h"
+
+namespace privetd {
+
+class WifiSsidGeneratorTest : public testing::Test {
+ protected:
+  void SetRandomForTests(int n) { ssid_generator_.SetRandomForTests(n); }
+
+  testing::StrictMock<MockCloudDelegate> gcd_;
+  testing::StrictMock<MockWifiDelegate> wifi_;
+
+  WifiSsidGenerator ssid_generator_{&gcd_, &wifi_};
+};
+
+TEST_F(WifiSsidGeneratorTest, GenerateFlags) {
+  EXPECT_EQ(ssid_generator_.GenerateFlags().size(), 2);
+
+  wifi_.connection_state_ = ConnectionState{ConnectionState::kUnconfigured};
+  gcd_.connection_state_ = ConnectionState{ConnectionState::kUnconfigured};
+  EXPECT_EQ("DB", ssid_generator_.GenerateFlags());
+
+  wifi_.connection_state_ = ConnectionState{ConnectionState::kOnline};
+  EXPECT_EQ("CB", ssid_generator_.GenerateFlags());
+
+  gcd_.connection_state_ = ConnectionState{ConnectionState::kOffline};
+  EXPECT_EQ("AB", ssid_generator_.GenerateFlags());
+
+  wifi_.connection_state_ = ConnectionState{ConnectionState::kUnconfigured};
+  EXPECT_EQ("BB", ssid_generator_.GenerateFlags());
+}
+
+TEST_F(WifiSsidGeneratorTest, GenerateSsid31orLess) {
+  EXPECT_LE(ssid_generator_.GenerateSsid().size(), 31);
+}
+
+TEST_F(WifiSsidGeneratorTest, GenerateSsidValue) {
+  SetRandomForTests(47);
+  EXPECT_EQ("TestDevice 47.ABMIDABprv", ssid_generator_.GenerateSsid());
+
+  SetRandomForTests(9);
+  EXPECT_EQ("TestDevice 9.ABMIDABprv", ssid_generator_.GenerateSsid());
+}
+
+TEST_F(WifiSsidGeneratorTest, GenerateSsidLongName) {
+  SetRandomForTests(99);
+  EXPECT_CALL(gcd_, GetName(_, _))
+      .WillRepeatedly(
+          DoAll(SetArgPointee<0>("Very Long Device Name"), Return(true)));
+  EXPECT_EQ("Very Long Device  99.ABMIDABprv", ssid_generator_.GenerateSsid());
+}
+
+TEST_F(WifiSsidGeneratorTest, GenerateSsidNoName) {
+  SetRandomForTests(99);
+  EXPECT_CALL(gcd_, GetName(_, _)).WillRepeatedly(Return(false));
+  EXPECT_EQ("", ssid_generator_.GenerateSsid());
+}
+
+}  // namespace privetd
