diff --git a/buffet/buffet_client.cc b/buffet/buffet_client.cc
index edd6e87..dba2f4d 100644
--- a/buffet/buffet_client.cc
+++ b/buffet/buffet_client.cc
@@ -8,17 +8,21 @@
 #include <base/command_line.h>
 #include <base/logging.h>
 #include <base/memory/scoped_ptr.h>
+#include <base/values.h>
 #include <dbus/bus.h>
 #include <dbus/object_proxy.h>
 #include <dbus/message.h>
 #include <sysexits.h>
+#include <dbus/values_util.h>
 
 #include "buffet/dbus_constants.h"
 #include "buffet/dbus_manager.h"
+#include "buffet/data_encoding.h"
 
 using namespace buffet::dbus_constants;
 
 namespace {
+static const int default_timeout_ms = 1000;
 
 dbus::ObjectProxy* GetBuffetDBusProxy(dbus::Bus *bus,
                                       const std::string& object_path) {
@@ -28,11 +32,10 @@
 }
 
 bool CallTestMethod(dbus::ObjectProxy* proxy) {
-  int timeout_ms = 1000;
   dbus::MethodCall method_call(buffet::dbus_constants::kRootInterface,
                                buffet::dbus_constants::kRootTestMethod);
-  scoped_ptr<dbus::Response> response(proxy->CallMethodAndBlock(&method_call,
-                                                                timeout_ms));
+  scoped_ptr<dbus::Response> response(
+    proxy->CallMethodAndBlock(&method_call, default_timeout_ms));
   if (!response) {
     std::cout << "Failed to receive a response." << std::endl;
     return false;
@@ -41,33 +44,119 @@
   return true;
 }
 
-bool CallManagerRegisterDevice(dbus::ObjectProxy* proxy,
-                               const std::string& client_id,
-                               const std::string& client_secret,
-                               const std::string& api_key) {
+bool CallManagerCheckDeviceRegistered(dbus::ObjectProxy* proxy) {
   dbus::MethodCall method_call(
-      buffet::dbus_constants::kManagerInterface,
-      buffet::dbus_constants::kManagerRegisterDeviceMethod);
-  dbus::MessageWriter writer(&method_call);
-  writer.AppendString(client_id);
-  writer.AppendString(client_secret);
-  writer.AppendString(api_key);
-  int timeout_ms = 1000;
+    buffet::dbus_constants::kManagerInterface,
+    buffet::dbus_constants::kManagerCheckDeviceRegistered);
+
   scoped_ptr<dbus::Response> response(
-      proxy->CallMethodAndBlock(&method_call, timeout_ms));
+    proxy->CallMethodAndBlock(&method_call, default_timeout_ms));
   if (!response) {
     std::cout << "Failed to receive a response." << std::endl;
     return false;
   }
 
   dbus::MessageReader reader(response.get());
-  std::string registration_id;
-  if (!reader.PopString(&registration_id)) {
-    std::cout << "No registration id in response." << std::endl;
+  std::string device_id;
+  if (!reader.PopString(&device_id)) {
+    std::cout << "No device ID in response." << std::endl;
     return false;
   }
 
-  std::cout << "Registration ID is " << registration_id << std::endl;
+  std::cout << "Device ID: "
+            << (device_id.empty() ? std::string("<unregistered>") : device_id)
+            << std::endl;
+  return true;
+}
+
+bool CallManagerGetDeviceInfo(dbus::ObjectProxy* proxy) {
+  dbus::MethodCall method_call(
+    buffet::dbus_constants::kManagerInterface,
+    buffet::dbus_constants::kManagerGetDeviceInfo);
+
+  scoped_ptr<dbus::Response> response(
+    proxy->CallMethodAndBlock(&method_call, default_timeout_ms));
+  if (!response) {
+    std::cout << "Failed to receive a response." << std::endl;
+    return false;
+  }
+
+  dbus::MessageReader reader(response.get());
+  std::string device_info;
+  if (!reader.PopString(&device_info)) {
+    std::cout << "No device info in response." << std::endl;
+    return false;
+  }
+
+  std::cout << "Device Info: "
+    << (device_info.empty() ? std::string("<unregistered>") : device_info)
+    << std::endl;
+  return true;
+}
+
+bool CallManagerStartRegisterDevice(
+    dbus::ObjectProxy* proxy,
+    const std::map<std::string, std::shared_ptr<base::Value>>& params) {
+  dbus::MethodCall method_call(
+      buffet::dbus_constants::kManagerInterface,
+      buffet::dbus_constants::kManagerStartRegisterDevice);
+  dbus::MessageWriter writer(&method_call);
+  dbus::MessageWriter dict_writer(nullptr);
+  writer.OpenArray("{sv}", &dict_writer);
+  for (auto&& pair : params) {
+    dbus::MessageWriter dict_entry_writer(nullptr);
+    dict_writer.OpenDictEntry(&dict_entry_writer);
+    dict_entry_writer.AppendString(pair.first);
+    dbus::AppendBasicTypeValueDataAsVariant(&dict_entry_writer,
+                                            *pair.second.get());
+    dict_writer.CloseContainer(&dict_entry_writer);
+  }
+  writer.CloseContainer(&dict_writer);
+
+  static const int timeout_ms = 3000;
+  scoped_ptr<dbus::Response> response(
+    proxy->CallMethodAndBlock(&method_call, timeout_ms));
+  if (!response) {
+    std::cout << "Failed to receive a response." << std::endl;
+    return false;
+  }
+
+  dbus::MessageReader reader(response.get());
+  std::string info;
+  if (!reader.PopString(&info)) {
+    std::cout << "No valid response." << std::endl;
+    return false;
+  }
+
+  std::cout << "Registration started: " << info << std::endl;
+  return true;
+}
+
+bool CallManagerFinishRegisterDevice(dbus::ObjectProxy* proxy,
+                                     const std::string& user_auth_code) {
+  dbus::MethodCall method_call(
+    buffet::dbus_constants::kManagerInterface,
+    buffet::dbus_constants::kManagerFinishRegisterDevice);
+  dbus::MessageWriter writer(&method_call);
+  writer.AppendString(user_auth_code);
+  static const int timeout_ms = 10000;
+  scoped_ptr<dbus::Response> response(
+    proxy->CallMethodAndBlock(&method_call, timeout_ms));
+  if (!response) {
+    std::cout << "Failed to receive a response." << std::endl;
+    return false;
+  }
+
+  dbus::MessageReader reader(response.get());
+  std::string device_id;
+  if (!reader.PopString(&device_id)) {
+    std::cout << "No device ID in response." << std::endl;
+    return false;
+  }
+
+  std::cout << "Device ID is "
+            << (device_id.empty() ? std::string("<unregistered>") : device_id)
+            << std::endl;
   return true;
 }
 
@@ -78,9 +167,8 @@
       buffet::dbus_constants::kManagerUpdateStateMethod);
   dbus::MessageWriter writer(&method_call);
   writer.AppendString(json_blob);
-  int timeout_ms = 1000;
   scoped_ptr<dbus::Response> response(
-      proxy->CallMethodAndBlock(&method_call, timeout_ms));
+    proxy->CallMethodAndBlock(&method_call, default_timeout_ms));
   if (!response) {
     std::cout << "Failed to receive a response." << std::endl;
     return false;
@@ -91,8 +179,12 @@
 void usage() {
   std::cerr << "Possible commands:" << std::endl;
   std::cerr << "  " << kRootTestMethod << std::endl;
-  std::cerr << "  " << kManagerRegisterDeviceMethod
-            << "  " << " <client id> <client secret> <api key>" << std::endl;
+  std::cerr << "  " << kManagerCheckDeviceRegistered << std::endl;
+  std::cerr << "  " << kManagerGetDeviceInfo << std::endl;
+  std::cerr << "  " << kManagerStartRegisterDevice
+                    << " param1 = val1&param2 = val2..." << std::endl;
+  std::cerr << "  " << kManagerFinishRegisterDevice
+                    << " device_id" << std::endl;
   std::cerr << "  " << kManagerUpdateStateMethod << std::endl;
 }
 
@@ -107,39 +199,86 @@
   scoped_refptr<dbus::Bus> bus(new dbus::Bus(options));
 
   CommandLine::StringVector args = cl->GetArgs();
-  if (args.size() < 1) {
+  if (args.empty()) {
     usage();
     return EX_USAGE;
   }
 
   // Pop the command off of the args list.
-  std::string command = args[0];
+  std::string command = args.front();
   args.erase(args.begin());
   bool success = false;
   if (command.compare(kRootTestMethod) == 0) {
     auto proxy = GetBuffetDBusProxy(
         bus, buffet::dbus_constants::kRootServicePath);
     success = CallTestMethod(proxy);
-  } else if (command.compare(kManagerRegisterDeviceMethod) == 0) {
-    if (args.size() != 3) {
+  } else if (command.compare(kManagerCheckDeviceRegistered) == 0 ||
+             command.compare("cr") == 0) {
+    if (!args.empty()) {
       std::cerr << "Invalid number of arguments for "
-                << "Manager.RegisterDevice" << std::endl;
+        << "Manager." << kManagerCheckDeviceRegistered << std::endl;
+      usage();
+      return EX_USAGE;
+    }
+    auto proxy = GetBuffetDBusProxy(
+      bus, buffet::dbus_constants::kManagerServicePath);
+    success = CallManagerCheckDeviceRegistered(proxy);
+  } else if (command.compare(kManagerGetDeviceInfo) == 0 ||
+             command.compare("di") == 0) {
+    if (!args.empty()) {
+      std::cerr << "Invalid number of arguments for "
+        << "Manager." << kManagerGetDeviceInfo << std::endl;
+      usage();
+      return EX_USAGE;
+    }
+    auto proxy = GetBuffetDBusProxy(
+      bus, buffet::dbus_constants::kManagerServicePath);
+    success = CallManagerGetDeviceInfo(proxy);
+  } else if (command.compare(kManagerStartRegisterDevice) == 0 ||
+             command.compare("sr") == 0) {
+    if (args.size() > 1) {
+      std::cerr << "Invalid number of arguments for "
+                << "Manager." << kManagerStartRegisterDevice << std::endl;
       usage();
       return EX_USAGE;
     }
     auto proxy = GetBuffetDBusProxy(
         bus, buffet::dbus_constants::kManagerServicePath);
-    success = CallManagerRegisterDevice(proxy, args[0], args[1], args[2]);
-  } else if (command.compare(kManagerUpdateStateMethod) == 0) {
+    std::map<std::string, std::shared_ptr<base::Value>> params;
+
+    if (!args.empty()) {
+      auto key_values = chromeos::data_encoding::WebParamsDecode(args.front());
+      for (auto&& pair : key_values) {
+        params.insert(std::make_pair(
+          pair.first, std::shared_ptr<base::Value>(
+              base::Value::CreateStringValue(pair.second))));
+      }
+    }
+
+    success = CallManagerStartRegisterDevice(proxy, params);
+  } else if (command.compare(kManagerFinishRegisterDevice) == 0 ||
+             command.compare("fr") == 0) {
+    if (args.size() > 1) {
+      std::cerr << "Invalid number of arguments for "
+                << "Manager." << kManagerFinishRegisterDevice << std::endl;
+      usage();
+      return EX_USAGE;
+    }
+    auto proxy = GetBuffetDBusProxy(
+        bus, buffet::dbus_constants::kManagerServicePath);
+    success = CallManagerFinishRegisterDevice(
+        proxy, !args.empty() ? args.front() : std::string());
+  } else if (command.compare(kManagerUpdateStateMethod) == 0 ||
+             command.compare("us") == 0) {
     if (args.size() != 1) {
       std::cerr << "Invalid number of arguments for "
-                << "Manager.UpdateState" << std::endl;
+                << "Manager." << kManagerUpdateStateMethod << std::endl;
       usage();
       return EX_USAGE;
     }
     auto proxy = GetBuffetDBusProxy(
         bus, buffet::dbus_constants::kManagerServicePath);
-    success = CallManagerUpdateState(proxy, args[0]);
+    success = CallManagerUpdateState(proxy, args.front());
   } else {
     std::cerr << "Unknown command: " << command << std::endl;
     usage();
