Convert ComponentManager into an interface and create a mock

This will help to mock out ComponentManager's functionality for unit
tests in the future.

Change-Id: Ie74c49c6b31b00b0c4d38bf0db715a62a9532bc7
Reviewed-on: https://weave-review.googlesource.com/1785
Reviewed-by: Vitaly Buka <vitalybuka@google.com>
diff --git a/libweave.gypi b/libweave.gypi
index f74a9bf..dc2e6f0 100644
--- a/libweave.gypi
+++ b/libweave.gypi
@@ -12,7 +12,7 @@
       'src/commands/command_manager.cc',
       'src/commands/command_queue.cc',
       'src/commands/schema_constants.cc',
-      'src/component_manager.cc',
+      'src/component_manager_impl.cc',
       'src/config.cc',
       'src/data_encoding.cc',
       'src/device_manager.cc',
diff --git a/src/component_manager.h b/src/component_manager.h
index 031b88a..426a4cc 100644
--- a/src/component_manager.h
+++ b/src/component_manager.h
@@ -15,7 +15,6 @@
 
 #include "src/commands/command_dictionary.h"
 #include "src/commands/command_queue.h"
-#include "src/states/state_change_queue.h"
 
 namespace weave {
 
@@ -36,7 +35,7 @@
   std::unique_ptr<base::DictionaryValue> changed_properties;
 };
 
-class ComponentManager final {
+class ComponentManager {
  public:
   using UpdateID = uint64_t;
   using Token =
@@ -46,128 +45,134 @@
     std::vector<ComponentStateChange> state_changes;
   };
 
-  ComponentManager();
-  explicit ComponentManager(base::Clock* clock);
-  ~ComponentManager();
+  ComponentManager() {}
+  virtual ~ComponentManager() {}
 
   // Loads trait definition schema.
-  bool LoadTraits(const base::DictionaryValue& dict, ErrorPtr* error);
+  virtual bool LoadTraits(const base::DictionaryValue& dict,
+                          ErrorPtr* error) = 0;
 
   // Same as the overload above, but takes a json string to read the trait
   // definitions from.
-  bool LoadTraits(const std::string& json, ErrorPtr* error);
+  virtual bool LoadTraits(const std::string& json, ErrorPtr* error) = 0;
 
   // Sets callback which is called when new trait definitions are added.
-  void AddTraitDefChangedCallback(const base::Closure& callback);
+  virtual void AddTraitDefChangedCallback(const base::Closure& callback) = 0;
 
   // Adds a new component instance to device.
   // |path| is a path to the parent component (or empty string if a root-level
   // component is being added).
   // |name| is a component name being added.
   // |traits| is a list of trait names this component supports.
-  bool AddComponent(const std::string& path,
-                    const std::string& name,
-                    const std::vector<std::string>& traits,
-                    ErrorPtr* error);
+  virtual bool AddComponent(const std::string& path,
+                            const std::string& name,
+                            const std::vector<std::string>& traits,
+                            ErrorPtr* error) = 0;
 
   // Adds a new component instance to device, as a part of component array.
   // |path| is a path to the parent component.
   // |name| is an array root element inside the child components.
   // |traits| is a list of trait names this component supports.
-  bool AddComponentArrayItem(const std::string& path,
-                             const std::string& name,
-                             const std::vector<std::string>& traits,
-                             ErrorPtr* error);
+  virtual bool AddComponentArrayItem(const std::string& path,
+                                     const std::string& name,
+                                     const std::vector<std::string>& traits,
+                                     ErrorPtr* error) = 0;
 
   // Sets callback which is called when new components are added.
-  void AddComponentTreeChangedCallback(const base::Closure& callback);
+  virtual void AddComponentTreeChangedCallback(
+      const base::Closure& callback) = 0;
 
   // Adds a new command instance to the command queue. The command specified in
   // |command_instance| must be fully initialized and have its name, component,
   // id populated.
-  void AddCommand(std::unique_ptr<CommandInstance> command_instance);
+  virtual void AddCommand(
+      std::unique_ptr<CommandInstance> command_instance) = 0;
 
   // Parses the command definition from a json dictionary and adds it to the
   // command queue. The new command ID is returned through optional |id| param.
-  bool AddCommand(const base::DictionaryValue& command,
-                  UserRole role,
-                  std::string* id,
-                  ErrorPtr* error);
+  virtual bool AddCommand(const base::DictionaryValue& command,
+                          UserRole role,
+                          std::string* id,
+                          ErrorPtr* error) = 0;
 
   // Find a command instance with the given ID in the command queue.
-  CommandInstance* FindCommand(const std::string& id);
+  virtual CommandInstance* FindCommand(const std::string& id) = 0;
 
   // Command queue monitoring callbacks (called when a new command is added to
   // or removed from the queue).
-  void AddCommandAddedCallback(const CommandQueue::CommandCallback& callback);
-  void AddCommandRemovedCallback(const CommandQueue::CommandCallback& callback);
+  virtual void AddCommandAddedCallback(
+      const CommandQueue::CommandCallback& callback) = 0;
+  virtual void AddCommandRemovedCallback(
+      const CommandQueue::CommandCallback& callback) = 0;
 
   // Adds a command handler for specific component's command.
   // |component_path| is a path to target component (e.g. "stove.burners[2]").
   // |command_name| is a full path of the command, including trait name and
   // command name (e.g. "burner.setPower").
-  void AddCommandHandler(const std::string& component_path,
-                         const std::string& command_name,
-                         const Device::CommandHandlerCallback& callback);
+  virtual void AddCommandHandler(
+      const std::string& component_path,
+      const std::string& command_name,
+      const Device::CommandHandlerCallback& callback) = 0;
 
   // Finds a component instance by its full path.
-  const base::DictionaryValue* FindComponent(const std::string& path,
-                                             ErrorPtr* error) const;
+  virtual const base::DictionaryValue* FindComponent(
+      const std::string& path,
+      ErrorPtr* error) const = 0;
   // Finds a definition of trait with the given |name|.
-  const base::DictionaryValue* FindTraitDefinition(
-      const std::string& name) const;
+  virtual const base::DictionaryValue* FindTraitDefinition(
+      const std::string& name) const = 0;
 
   // Finds a command definition, where |command_name| is in the form of
   // "trait.command".
-  const base::DictionaryValue* FindCommandDefinition(
-      const std::string& command_name) const;
+  virtual const base::DictionaryValue* FindCommandDefinition(
+      const std::string& command_name) const = 0;
 
   // Checks the minimum required user role for a given command.
-  bool GetMinimalRole(const std::string& command_name,
-                      UserRole* minimal_role,
-                      ErrorPtr* error) const;
+  virtual bool GetMinimalRole(const std::string& command_name,
+                              UserRole* minimal_role,
+                              ErrorPtr* error) const = 0;
 
   // Returns the full JSON dictionary containing trait definitions.
-  const base::DictionaryValue& GetTraits() const { return traits_; }
+  virtual const base::DictionaryValue& GetTraits() const = 0;
 
   // Returns the full JSON dictionary containing component instances.
-  const base::DictionaryValue& GetComponents() const { return components_; }
+  virtual const base::DictionaryValue& GetComponents() const = 0;
 
   // Component state manipulation methods.
-  bool SetStateProperties(const std::string& component_path,
-                          const base::DictionaryValue& dict,
-                          ErrorPtr* error);
-  bool SetStatePropertiesFromJson(const std::string& component_path,
-                                  const std::string& json,
-                                  ErrorPtr* error);
-  const base::Value* GetStateProperty(const std::string& component_path,
-                                      const std::string& name,
-                                      ErrorPtr* error) const;
-  bool SetStateProperty(const std::string& component_path,
-                        const std::string& name,
-                        const base::Value& value,
-                        ErrorPtr* error);
+  virtual bool SetStateProperties(const std::string& component_path,
+                                  const base::DictionaryValue& dict,
+                                  ErrorPtr* error) = 0;
+  virtual bool SetStatePropertiesFromJson(const std::string& component_path,
+                                          const std::string& json,
+                                          ErrorPtr* error) = 0;
+  virtual const base::Value* GetStateProperty(const std::string& component_path,
+                                              const std::string& name,
+                                              ErrorPtr* error) const = 0;
+  virtual bool SetStateProperty(const std::string& component_path,
+                                const std::string& name,
+                                const base::Value& value,
+                                ErrorPtr* error) = 0;
 
-  void AddStateChangedCallback(const base::Closure& callback);
+  virtual void AddStateChangedCallback(const base::Closure& callback) = 0;
 
   // Returns the recorded state changes since last time this method was called.
-  StateSnapshot GetAndClearRecordedStateChanges();
+  virtual StateSnapshot GetAndClearRecordedStateChanges() = 0;
 
   // Called to notify that the state patch with |id| has been successfully sent
   // to the server and processed.
-  void NotifyStateUpdatedOnServer(UpdateID id);
+  virtual void NotifyStateUpdatedOnServer(UpdateID id) = 0;
 
   // Returns an ID of last state change update. Each SetStatePropertyNNN()
   // invocation increments this value by 1.
-  UpdateID GetLastStateChangeId() const { return last_state_change_id_; }
+  virtual UpdateID GetLastStateChangeId() const = 0;
 
   // Subscribes for device state update notifications from cloud server.
   // The |callback| will be called every time a state patch with given ID is
   // successfully received and processed by Weave server.
   // Returns a subscription token. As soon as this token is destroyed, the
   // respective callback is removed from the callback list.
-  Token AddServerStateUpdatedCallback(
-      const base::Callback<void(UpdateID)>& callback);
+  virtual Token AddServerStateUpdatedCallback(
+      const base::Callback<void(UpdateID)>& callback) = 0;
 
   // Helper method for legacy API to obtain first component that implements
   // the given trait. This is useful for routing commands that have no component
@@ -175,38 +180,8 @@
   // Returns empty string if no components are found.
   // This method only searches for component on the top level of components
   // tree. No sub-components are searched.
-  std::string FindComponentWithTrait(const std::string& trait) const;
-
- private:
-  // A helper method to find a JSON element of component at |path| to add new
-  // sub-components to.
-  base::DictionaryValue* FindComponentGraftNode(const std::string& path,
-                                                ErrorPtr* error);
-  base::DictionaryValue* FindMutableComponent(const std::string& path,
-                                              ErrorPtr* error);
-
-  // Helper method to find a sub-component given a root node and a relative path
-  // from the root to the target component.
-  static const base::DictionaryValue* FindComponentAt(
-      const base::DictionaryValue* root,
-      const std::string& path,
-      ErrorPtr* error);
-
-  base::Clock* clock_{nullptr};
-  base::DictionaryValue traits_;  // Trait definitions.
-  base::DictionaryValue components_;  // Component instances.
-  CommandQueue command_queue_;  // Command queue containing command instances.
-  std::vector<base::Closure> on_trait_changed_;
-  std::vector<base::Closure> on_componet_tree_changed_;
-  std::vector<base::Closure> on_state_changed_;
-  uint32_t next_command_id_{0};
-
-  std::map<std::string, std::unique_ptr<StateChangeQueue>> state_change_queues_;
-  // An ID of last state change update. Each NotifyPropertiesUpdated()
-  // invocation increments this value by 1.
-  UpdateID last_state_change_id_{0};
-  // Callback list for state change queue event sinks.
-  base::CallbackList<void(UpdateID)> on_server_state_updated_;
+  virtual std::string FindComponentWithTrait(
+      const std::string& trait) const = 0;
 
   DISALLOW_COPY_AND_ASSIGN(ComponentManager);
 };
diff --git a/src/component_manager.cc b/src/component_manager_impl.cc
similarity index 85%
rename from src/component_manager.cc
rename to src/component_manager_impl.cc
index 98001bb..6950969 100644
--- a/src/component_manager.cc
+++ b/src/component_manager_impl.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "src/component_manager.h"
+#include "src/component_manager_impl.h"
 
 #include <base/strings/stringprintf.h>
 #include <base/strings/string_number_conversions.h>
@@ -20,14 +20,17 @@
 const size_t kMaxStateChangeQueueSize = 100;
 }  // namespace
 
-ComponentManager::ComponentManager() {}
-ComponentManager::ComponentManager(base::Clock* clock) : clock_{clock} {}
-ComponentManager::~ComponentManager() {}
+ComponentManagerImpl::ComponentManagerImpl() {}
 
-bool ComponentManager::AddComponent(const std::string& path,
-                                    const std::string& name,
-                                    const std::vector<std::string>& traits,
-                                    ErrorPtr* error) {
+ComponentManagerImpl::ComponentManagerImpl(base::Clock* clock) : clock_{clock} {
+}
+
+ComponentManagerImpl::~ComponentManagerImpl() {}
+
+bool ComponentManagerImpl::AddComponent(const std::string& path,
+                                        const std::string& name,
+                                        const std::vector<std::string>& traits,
+                                        ErrorPtr* error) {
   base::DictionaryValue* root = &components_;
   if (!path.empty()) {
     root = FindComponentGraftNode(path, error);
@@ -61,7 +64,7 @@
   return true;
 }
 
-bool ComponentManager::AddComponentArrayItem(
+bool ComponentManagerImpl::AddComponentArrayItem(
     const std::string& path,
     const std::string& name,
     const std::vector<std::string>& traits,
@@ -87,14 +90,14 @@
   return true;
 }
 
-void ComponentManager::AddComponentTreeChangedCallback(
+void ComponentManagerImpl::AddComponentTreeChangedCallback(
     const base::Closure& callback) {
   on_componet_tree_changed_.push_back(callback);
   callback.Run();
 }
 
-bool ComponentManager::LoadTraits(const base::DictionaryValue& dict,
-                                  ErrorPtr* error) {
+bool ComponentManagerImpl::LoadTraits(const base::DictionaryValue& dict,
+                                      ErrorPtr* error) {
   bool modified = false;
   bool result = true;
   // Check if any of the new traits are already defined. If so, make sure the
@@ -130,28 +133,29 @@
   return result;
 }
 
-bool ComponentManager::LoadTraits(const std::string& json, ErrorPtr* error) {
+bool ComponentManagerImpl::LoadTraits(const std::string& json,
+                                      ErrorPtr* error) {
   std::unique_ptr<const base::DictionaryValue> dict = LoadJsonDict(json, error);
   if (!dict)
     return false;
   return LoadTraits(*dict, error);
 }
 
-void ComponentManager::AddTraitDefChangedCallback(
+void ComponentManagerImpl::AddTraitDefChangedCallback(
     const base::Closure& callback) {
   on_trait_changed_.push_back(callback);
   callback.Run();
 }
 
-void ComponentManager::AddCommand(
+void ComponentManagerImpl::AddCommand(
     std::unique_ptr<CommandInstance> command_instance) {
   command_queue_.Add(std::move(command_instance));
 }
 
-bool ComponentManager::AddCommand(const base::DictionaryValue& command,
-                                  UserRole role,
-                                  std::string* id,
-                                  ErrorPtr* error) {
+bool ComponentManagerImpl::AddCommand(const base::DictionaryValue& command,
+                                      UserRole role,
+                                      std::string* id,
+                                      ErrorPtr* error) {
   auto command_instance = CommandInstance::FromJson(
       &command, Command::Origin::kLocal, nullptr, error);
   if (!command_instance)
@@ -222,21 +226,21 @@
   return true;
 }
 
-CommandInstance* ComponentManager::FindCommand(const std::string& id) {
+CommandInstance* ComponentManagerImpl::FindCommand(const std::string& id) {
   return command_queue_.Find(id);
 }
 
-void ComponentManager::AddCommandAddedCallback(
+void ComponentManagerImpl::AddCommandAddedCallback(
     const CommandQueue::CommandCallback& callback) {
   command_queue_.AddCommandAddedCallback(callback);
 }
 
-void ComponentManager::AddCommandRemovedCallback(
+void ComponentManagerImpl::AddCommandRemovedCallback(
     const CommandQueue::CommandCallback& callback) {
   command_queue_.AddCommandRemovedCallback(callback);
 }
 
-void ComponentManager::AddCommandHandler(
+void ComponentManagerImpl::AddCommandHandler(
     const std::string& component_path,
     const std::string& command_name,
     const Device::CommandHandlerCallback& callback) {
@@ -245,19 +249,19 @@
   command_queue_.AddCommandHandler(component_path, command_name, callback);
 }
 
-const base::DictionaryValue* ComponentManager::FindComponent(
+const base::DictionaryValue* ComponentManagerImpl::FindComponent(
     const std::string& path, ErrorPtr* error) const {
   return FindComponentAt(&components_, path, error);
 }
 
-const base::DictionaryValue* ComponentManager::FindTraitDefinition(
+const base::DictionaryValue* ComponentManagerImpl::FindTraitDefinition(
     const std::string& name) const {
   const base::DictionaryValue* trait = nullptr;
   traits_.GetDictionaryWithoutPathExpansion(name, &trait);
   return trait;
 }
 
-const base::DictionaryValue* ComponentManager::FindCommandDefinition(
+const base::DictionaryValue* ComponentManagerImpl::FindCommandDefinition(
     const std::string& command_name) const {
   const base::DictionaryValue* definition = nullptr;
   std::vector<std::string> components = Split(command_name, ".", true, false);
@@ -270,9 +274,9 @@
   return definition;
 }
 
-bool ComponentManager::GetMinimalRole(const std::string& command_name,
-                                      UserRole* minimal_role,
-                                      ErrorPtr* error) const {
+bool ComponentManagerImpl::GetMinimalRole(const std::string& command_name,
+                                          UserRole* minimal_role,
+                                          ErrorPtr* error) const {
   const base::DictionaryValue* command = FindCommandDefinition(command_name);
   if (!command) {
     Error::AddToPrintf(error, FROM_HERE, errors::commands::kDomain,
@@ -289,14 +293,15 @@
   return true;
 }
 
-void ComponentManager::AddStateChangedCallback(const base::Closure& callback) {
+void ComponentManagerImpl::AddStateChangedCallback(
+    const base::Closure& callback) {
   on_state_changed_.push_back(callback);
   callback.Run();  // Force to read current state.
 }
 
-bool ComponentManager::SetStateProperties(const std::string& component_path,
-                                          const base::DictionaryValue& dict,
-                                          ErrorPtr* error) {
+bool ComponentManagerImpl::SetStateProperties(const std::string& component_path,
+                                              const base::DictionaryValue& dict,
+                                              ErrorPtr* error) {
   base::DictionaryValue* component =
       FindMutableComponent(component_path, error);
   if (!component)
@@ -319,7 +324,7 @@
   return true;
 }
 
-bool ComponentManager::SetStatePropertiesFromJson(
+bool ComponentManagerImpl::SetStatePropertiesFromJson(
     const std::string& component_path,
     const std::string& json,
     ErrorPtr* error) {
@@ -327,7 +332,7 @@
   return dict && SetStateProperties(component_path, *dict, error);
 }
 
-const base::Value* ComponentManager::GetStateProperty(
+const base::Value* ComponentManagerImpl::GetStateProperty(
     const std::string& component_path,
     const std::string& name,
     ErrorPtr* error) const {
@@ -359,10 +364,10 @@
   return value;
 }
 
-bool ComponentManager::SetStateProperty(const std::string& component_path,
-                                        const std::string& name,
-                                        const base::Value& value,
-                                        ErrorPtr* error) {
+bool ComponentManagerImpl::SetStateProperty(const std::string& component_path,
+                                            const std::string& name,
+                                            const base::Value& value,
+                                            ErrorPtr* error) {
   base::DictionaryValue dict;
   auto pair = SplitAtFirst(name, ".", true);
   if (pair.first.empty()) {
@@ -383,7 +388,7 @@
 }
 
 ComponentManager::StateSnapshot
-ComponentManager::GetAndClearRecordedStateChanges() {
+ComponentManagerImpl::GetAndClearRecordedStateChanges() {
   StateSnapshot snapshot;
   snapshot.update_id = GetLastStateChangeId();
   for (auto& pair : state_change_queues_) {
@@ -407,18 +412,18 @@
   return snapshot;
 }
 
-void ComponentManager::NotifyStateUpdatedOnServer(UpdateID id) {
+void ComponentManagerImpl::NotifyStateUpdatedOnServer(UpdateID id) {
   on_server_state_updated_.Notify(id);
 }
 
-ComponentManager::Token ComponentManager::AddServerStateUpdatedCallback(
+ComponentManager::Token ComponentManagerImpl::AddServerStateUpdatedCallback(
     const base::Callback<void(UpdateID)>& callback) {
   if (state_change_queues_.empty())
     callback.Run(GetLastStateChangeId());
   return Token{on_server_state_updated_.Add(callback).release()};
 }
 
-std::string ComponentManager::FindComponentWithTrait(
+std::string ComponentManagerImpl::FindComponentWithTrait(
     const std::string& trait) const {
   for (base::DictionaryValue::Iterator it(components_); !it.IsAtEnd();
        it.Advance()) {
@@ -437,7 +442,7 @@
   return std::string{};
 }
 
-base::DictionaryValue* ComponentManager::FindComponentGraftNode(
+base::DictionaryValue* ComponentManagerImpl::FindComponentGraftNode(
     const std::string& path, ErrorPtr* error) {
   base::DictionaryValue* root = nullptr;
   base::DictionaryValue* component = FindMutableComponent(path, error);
@@ -448,14 +453,14 @@
   return root;
 }
 
-base::DictionaryValue* ComponentManager::FindMutableComponent(
+base::DictionaryValue* ComponentManagerImpl::FindMutableComponent(
     const std::string& path,
     ErrorPtr* error) {
   return const_cast<base::DictionaryValue*>(
       FindComponentAt(&components_, path, error));
 }
 
-const base::DictionaryValue* ComponentManager::FindComponentAt(
+const base::DictionaryValue* ComponentManagerImpl::FindComponentAt(
     const base::DictionaryValue* root,
     const std::string& path,
     ErrorPtr* error) {
diff --git a/src/component_manager_impl.h b/src/component_manager_impl.h
new file mode 100644
index 0000000..f4f25a3
--- /dev/null
+++ b/src/component_manager_impl.h
@@ -0,0 +1,190 @@
+// Copyright 2015 The Weave 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 LIBWEAVE_SRC_COMPONENT_MANAGER_IMPL_H_
+#define LIBWEAVE_SRC_COMPONENT_MANAGER_IMPL_H_
+
+#include "src/commands/command_queue.h"
+#include "src/component_manager.h"
+#include "src/states/state_change_queue.h"
+
+namespace weave {
+
+class ComponentManagerImpl final : public ComponentManager {
+ public:
+  ComponentManagerImpl();
+  explicit ComponentManagerImpl(base::Clock* clock);
+  ~ComponentManagerImpl() override;
+
+  // Loads trait definition schema.
+  bool LoadTraits(const base::DictionaryValue& dict, ErrorPtr* error) override;
+
+  // Same as the overload above, but takes a json string to read the trait
+  // definitions from.
+  bool LoadTraits(const std::string& json, ErrorPtr* error) override;
+
+  // Sets callback which is called when new trait definitions are added.
+  void AddTraitDefChangedCallback(const base::Closure& callback) override;
+
+  // Adds a new component instance to device.
+  // |path| is a path to the parent component (or empty string if a root-level
+  // component is being added).
+  // |name| is a component name being added.
+  // |traits| is a list of trait names this component supports.
+  bool AddComponent(const std::string& path,
+                    const std::string& name,
+                    const std::vector<std::string>& traits,
+                    ErrorPtr* error) override;
+
+  // Adds a new component instance to device, as a part of component array.
+  // |path| is a path to the parent component.
+  // |name| is an array root element inside the child components.
+  // |traits| is a list of trait names this component supports.
+  bool AddComponentArrayItem(const std::string& path,
+                             const std::string& name,
+                             const std::vector<std::string>& traits,
+                             ErrorPtr* error) override;
+
+  // Sets callback which is called when new components are added.
+  void AddComponentTreeChangedCallback(const base::Closure& callback) override;
+
+  // Adds a new command instance to the command queue. The command specified in
+  // |command_instance| must be fully initialized and have its name, component,
+  // id populated.
+  void AddCommand(std::unique_ptr<CommandInstance> command_instance) override;
+
+  // Parses the command definition from a json dictionary and adds it to the
+  // command queue. The new command ID is returned through optional |id| param.
+  bool AddCommand(const base::DictionaryValue& command,
+                  UserRole role,
+                  std::string* id,
+                  ErrorPtr* error) override;
+
+  // Find a command instance with the given ID in the command queue.
+  CommandInstance* FindCommand(const std::string& id) override;
+
+  // Command queue monitoring callbacks (called when a new command is added to
+  // or removed from the queue).
+  void AddCommandAddedCallback(
+      const CommandQueue::CommandCallback& callback) override;
+  void AddCommandRemovedCallback(
+      const CommandQueue::CommandCallback& callback) override;
+
+  // Adds a command handler for specific component's command.
+  // |component_path| is a path to target component (e.g. "stove.burners[2]").
+  // |command_name| is a full path of the command, including trait name and
+  // command name (e.g. "burner.setPower").
+  void AddCommandHandler(
+      const std::string& component_path,
+      const std::string& command_name,
+      const Device::CommandHandlerCallback& callback) override;
+
+  // Finds a component instance by its full path.
+  const base::DictionaryValue* FindComponent(const std::string& path,
+                                             ErrorPtr* error) const override;
+  // Finds a definition of trait with the given |name|.
+  const base::DictionaryValue* FindTraitDefinition(
+      const std::string& name) const override;
+
+  // Finds a command definition, where |command_name| is in the form of
+  // "trait.command".
+  const base::DictionaryValue* FindCommandDefinition(
+      const std::string& command_name) const override;
+
+  // Checks the minimum required user role for a given command.
+  bool GetMinimalRole(const std::string& command_name,
+                      UserRole* minimal_role,
+                      ErrorPtr* error) const override;
+
+  // Returns the full JSON dictionary containing trait definitions.
+  const base::DictionaryValue& GetTraits() const override { return traits_; }
+
+  // Returns the full JSON dictionary containing component instances.
+  const base::DictionaryValue& GetComponents() const override {
+    return components_;
+  }
+
+  // Component state manipulation methods.
+  bool SetStateProperties(const std::string& component_path,
+                          const base::DictionaryValue& dict,
+                          ErrorPtr* error) override;
+  bool SetStatePropertiesFromJson(const std::string& component_path,
+                                  const std::string& json,
+                                  ErrorPtr* error) override;
+  const base::Value* GetStateProperty(const std::string& component_path,
+                                      const std::string& name,
+                                      ErrorPtr* error) const override;
+  bool SetStateProperty(const std::string& component_path,
+                        const std::string& name,
+                        const base::Value& value,
+                        ErrorPtr* error) override;
+
+  void AddStateChangedCallback(const base::Closure& callback) override;
+
+  // Returns the recorded state changes since last time this method was called.
+  StateSnapshot GetAndClearRecordedStateChanges() override;
+
+  // Called to notify that the state patch with |id| has been successfully sent
+  // to the server and processed.
+  void NotifyStateUpdatedOnServer(UpdateID id) override;
+
+  // Returns an ID of last state change update. Each SetStatePropertyNNN()
+  // invocation increments this value by 1.
+  UpdateID GetLastStateChangeId() const override {
+    return last_state_change_id_;
+  }
+
+  // Subscribes for device state update notifications from cloud server.
+  // The |callback| will be called every time a state patch with given ID is
+  // successfully received and processed by Weave server.
+  // Returns a subscription token. As soon as this token is destroyed, the
+  // respective callback is removed from the callback list.
+  Token AddServerStateUpdatedCallback(
+      const base::Callback<void(UpdateID)>& callback) override;
+
+  // Helper method for legacy API to obtain first component that implements
+  // the given trait. This is useful for routing commands that have no component
+  // path specified.
+  // Returns empty string if no components are found.
+  // This method only searches for component on the top level of components
+  // tree. No sub-components are searched.
+  std::string FindComponentWithTrait(const std::string& trait) const override;
+
+ private:
+  // A helper method to find a JSON element of component at |path| to add new
+  // sub-components to.
+  base::DictionaryValue* FindComponentGraftNode(const std::string& path,
+                                                ErrorPtr* error);
+  base::DictionaryValue* FindMutableComponent(const std::string& path,
+                                              ErrorPtr* error);
+
+  // Helper method to find a sub-component given a root node and a relative path
+  // from the root to the target component.
+  static const base::DictionaryValue* FindComponentAt(
+      const base::DictionaryValue* root,
+      const std::string& path,
+      ErrorPtr* error);
+
+  base::Clock* clock_{nullptr};
+  base::DictionaryValue traits_;  // Trait definitions.
+  base::DictionaryValue components_;  // Component instances.
+  CommandQueue command_queue_;  // Command queue containing command instances.
+  std::vector<base::Closure> on_trait_changed_;
+  std::vector<base::Closure> on_componet_tree_changed_;
+  std::vector<base::Closure> on_state_changed_;
+  uint32_t next_command_id_{0};
+
+  std::map<std::string, std::unique_ptr<StateChangeQueue>> state_change_queues_;
+  // An ID of last state change update. Each NotifyPropertiesUpdated()
+  // invocation increments this value by 1.
+  UpdateID last_state_change_id_{0};
+  // Callback list for state change queue event sinks.
+  base::CallbackList<void(UpdateID)> on_server_state_updated_;
+
+  DISALLOW_COPY_AND_ASSIGN(ComponentManagerImpl);
+};
+
+}  // namespace weave
+
+#endif  // LIBWEAVE_SRC_COMPONENT_MANAGER_IMPL_H_
diff --git a/src/component_manager_unittest.cc b/src/component_manager_unittest.cc
index 31949d7..0c34041 100644
--- a/src/component_manager_unittest.cc
+++ b/src/component_manager_unittest.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "src/component_manager.h"
+#include "src/component_manager_impl.h"
 
 #include <map>
 
@@ -11,6 +11,7 @@
 
 #include "src/bind_lambda.h"
 #include "src/commands/schema_constants.h"
+#include "src/mock_component_manager.h"
 
 namespace weave {
 
@@ -98,13 +99,13 @@
 }  // anonymous namespace
 
 TEST(ComponentManager, Empty) {
-  ComponentManager manager;
+  ComponentManagerImpl manager;
   EXPECT_TRUE(manager.GetTraits().empty());
   EXPECT_TRUE(manager.GetComponents().empty());
 }
 
 TEST(ComponentManager, LoadTraits) {
-  ComponentManager manager;
+  ComponentManagerImpl manager;
   const char kTraits[] = R"({
     "trait1": {
       "commands": {
@@ -130,7 +131,7 @@
 }
 
 TEST(ComponentManager, LoadTraitsDuplicateIdentical) {
-  ComponentManager manager;
+  ComponentManagerImpl manager;
   const char kTraits1[] = R"({
     "trait1": {
       "commands": {
@@ -198,7 +199,7 @@
 }
 
 TEST(ComponentManager, LoadTraitsDuplicateOverride) {
-  ComponentManager manager;
+  ComponentManagerImpl manager;
   const char kTraits1[] = R"({
     "trait1": {
       "commands": {
@@ -242,7 +243,7 @@
 }
 
 TEST(ComponentManager, AddTraitDefChangedCallback) {
-  ComponentManager manager;
+  ComponentManagerImpl manager;
   int count = 0;
   int count2 = 0;
   manager.AddTraitDefChangedCallback(base::Bind([&count]() { count++; }));
@@ -299,7 +300,7 @@
 }
 
 TEST(ComponentManager, LoadTraitsNotAnObject) {
-  ComponentManager manager;
+  ComponentManagerImpl manager;
   const char kTraits1[] = R"({"trait1": 0})";
   auto json = CreateDictionaryValue(kTraits1);
   ErrorPtr error;
@@ -308,7 +309,7 @@
 }
 
 TEST(ComponentManager, FindTraitDefinition) {
-  ComponentManager manager;
+  ComponentManagerImpl manager;
   const char kTraits[] = R"({
     "trait1": {
       "commands": {
@@ -358,7 +359,7 @@
 }
 
 TEST(ComponentManager, FindCommandDefinition) {
-  ComponentManager manager;
+  ComponentManagerImpl manager;
   const char kTraits[] = R"({
     "trait1": {
       "commands": {
@@ -411,7 +412,7 @@
 }
 
 TEST(ComponentManager, GetMinimalRole) {
-  ComponentManager manager;
+  ComponentManagerImpl manager;
   const char kTraits[] = R"({
     "trait1": {
       "commands": {
@@ -446,7 +447,7 @@
 }
 
 TEST(ComponentManager, AddComponent) {
-  ComponentManager manager;
+  ComponentManagerImpl manager;
   const char kTraits[] = R"({"trait1": {}, "trait2": {}, "trait3": {}})";
   auto json = CreateDictionaryValue(kTraits);
   ASSERT_TRUE(manager.LoadTraits(*json, nullptr));
@@ -467,7 +468,7 @@
 }
 
 TEST(ComponentManager, AddSubComponent) {
-  ComponentManager manager;
+  ComponentManagerImpl manager;
   EXPECT_TRUE(manager.AddComponent("", "comp1", {}, nullptr));
   EXPECT_TRUE(manager.AddComponent("comp1", "comp2", {}, nullptr));
   EXPECT_TRUE(manager.AddComponent("comp1", "comp3", {}, nullptr));
@@ -494,7 +495,7 @@
 }
 
 TEST(ComponentManager, AddComponentArrayItem) {
-  ComponentManager manager;
+  ComponentManagerImpl manager;
   const char kTraits[] = R"({"foo": {}, "bar": {}})";
   auto json = CreateDictionaryValue(kTraits);
   ASSERT_TRUE(manager.LoadTraits(*json, nullptr));
@@ -536,7 +537,7 @@
 }
 
 TEST(ComponentManager, AddComponentExist) {
-  ComponentManager manager;
+  ComponentManagerImpl manager;
   EXPECT_TRUE(manager.AddComponent("", "comp1", {}, nullptr));
   EXPECT_FALSE(manager.AddComponent("", "comp1", {}, nullptr));
   EXPECT_TRUE(manager.AddComponent("comp1", "comp2", {}, nullptr));
@@ -544,12 +545,12 @@
 }
 
 TEST(ComponentManager, AddComponentDoesNotExist) {
-  ComponentManager manager;
+  ComponentManagerImpl manager;
   EXPECT_FALSE(manager.AddComponent("comp1", "comp2", {}, nullptr));
 }
 
 TEST(ComponentManager, AddComponentTreeChangedCallback) {
-  ComponentManager manager;
+  ComponentManagerImpl manager;
   int count = 0;
   int count2 = 0;
   manager.AddComponentTreeChangedCallback(base::Bind([&count]() { count++; }));
@@ -572,7 +573,7 @@
 }
 
 TEST(ComponentManager, FindComponent) {
-  ComponentManager manager;
+  ComponentManagerImpl manager;
   CreateTestComponentTree(&manager);
 
   const base::DictionaryValue* comp = manager.FindComponent("comp1", nullptr);
@@ -621,7 +622,7 @@
 }
 
 TEST(ComponentManager, AddCommand) {
-  ComponentManager manager;
+  ComponentManagerImpl manager;
   const char kTraits[] = R"({
     "trait1": {
       "commands": {
@@ -693,7 +694,7 @@
 }
 
 TEST(ComponentManager, AddCommandHandler) {
-  ComponentManager manager;
+  ComponentManagerImpl manager;
   const char kTraits[] = R"({
     "trait1": {
       "commands": {
@@ -753,7 +754,7 @@
 }
 
 TEST(ComponentManager, SetStateProperties) {
-  ComponentManager manager;
+  ComponentManagerImpl manager;
   CreateTestComponentTree(&manager);
 
   const char kState1[] = R"({"t1": {"p1": 0, "p2": "foo"}})";
@@ -855,7 +856,7 @@
 }
 
 TEST(ComponentManager, SetStatePropertiesFromJson) {
-  ComponentManager manager;
+  ComponentManagerImpl manager;
   CreateTestComponentTree(&manager);
 
   ASSERT_TRUE(manager.SetStatePropertiesFromJson(
@@ -895,7 +896,7 @@
 }
 
 TEST(ComponentManager, SetGetStateProperty) {
-  ComponentManager manager;
+  ComponentManagerImpl manager;
   const char kTraits[] = R"({
     "trait1": {
       "state": {
@@ -961,7 +962,7 @@
 
 TEST(ComponentManager, AddStateChangedCallback) {
   SimpleTestClock clock;
-  ComponentManager manager{&clock};
+  ComponentManagerImpl manager{&clock};
   const char kTraits[] = R"({
     "trait1": {
       "state": {
@@ -1002,7 +1003,7 @@
 
 TEST(ComponentManager, ComponentStateUpdates) {
   SimpleTestClock clock;
-  ComponentManager manager{&clock};
+  ComponentManagerImpl manager{&clock};
   const char kTraits[] = R"({
     "trait1": {
       "state": {
@@ -1096,7 +1097,7 @@
 }
 
 TEST(ComponentManager, FindComponentWithTrait) {
-  ComponentManager manager;
+  ComponentManagerImpl manager;
   const char kTraits[] = R"({
     "trait1": {},
     "trait2": {},
@@ -1113,4 +1114,9 @@
   EXPECT_EQ("", manager.FindComponentWithTrait("trait4"));
 }
 
+TEST(ComponentManager, TestMockComponentManager) {
+  // Check that all the virtual methods are mocked out.
+  MockComponentManager mock;
+}
+
 }  // namespace weave
diff --git a/src/device_manager.cc b/src/device_manager.cc
index 64a8093..a44f0db 100644
--- a/src/device_manager.cc
+++ b/src/device_manager.cc
@@ -10,7 +10,7 @@
 
 #include "src/base_api_handler.h"
 #include "src/commands/command_manager.h"
-#include "src/component_manager.h"
+#include "src/component_manager_impl.h"
 #include "src/config.h"
 #include "src/device_registration_info.h"
 #include "src/privet/privet_manager.h"
@@ -34,7 +34,7 @@
                              provider::HttpServer* http_server,
                              provider::Wifi* wifi,
                              provider::Bluetooth* bluetooth) {
-  component_manager_.reset(new ComponentManager);
+  component_manager_.reset(new ComponentManagerImpl);
   command_manager_ = std::make_shared<CommandManager>();
   state_change_queue_.reset(new StateChangeQueue(kMaxStateChangeQueueSize));
   state_manager_ = std::make_shared<StateManager>(state_change_queue_.get());
diff --git a/src/mock_component_manager.h b/src/mock_component_manager.h
new file mode 100644
index 0000000..66b32d5
--- /dev/null
+++ b/src/mock_component_manager.h
@@ -0,0 +1,99 @@
+// Copyright 2015 The Weave 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 LIBWEAVE_SRC_MOCK_COMPONENT_MANAGER_H_
+#define LIBWEAVE_SRC_MOCK_COMPONENT_MANAGER_H_
+
+#include "src/component_manager.h"
+
+#include <gmock/gmock.h>
+
+namespace weave {
+
+class MockComponentManager : public ComponentManager {
+ public:
+  ~MockComponentManager() override {}
+  MOCK_METHOD2(LoadTraits, bool(const base::DictionaryValue& dict,
+                                ErrorPtr* error));
+  MOCK_METHOD2(LoadTraits, bool(const std::string& json, ErrorPtr* error));
+  MOCK_METHOD1(AddTraitDefChangedCallback, void(const base::Closure& callback));
+  MOCK_METHOD4(AddComponent, bool(const std::string& path,
+                                  const std::string& name,
+                                  const std::vector<std::string>& traits,
+                                  ErrorPtr* error));
+  MOCK_METHOD4(AddComponentArrayItem,
+               bool(const std::string& path,
+                    const std::string& name,
+                    const std::vector<std::string>& traits,
+                    ErrorPtr* error));
+  MOCK_METHOD1(AddComponentTreeChangedCallback,
+               void(const base::Closure& callback));
+  MOCK_METHOD1(MockAddCommand, void(CommandInstance* command_instance));
+  MOCK_METHOD4(AddCommand, bool(const base::DictionaryValue& command,
+                                UserRole role,
+                                std::string* id,
+                                ErrorPtr* error));
+  MOCK_METHOD1(FindCommand, CommandInstance*(const std::string& id));
+  MOCK_METHOD1(AddCommandAddedCallback,
+               void(const CommandQueue::CommandCallback& callback));
+  MOCK_METHOD1(AddCommandRemovedCallback,
+               void(const CommandQueue::CommandCallback& callback));
+  MOCK_METHOD3(AddCommandHandler,
+               void(const std::string& component_path,
+                    const std::string& command_name,
+                    const Device::CommandHandlerCallback& callback));
+  MOCK_CONST_METHOD2(FindComponent,
+                     const base::DictionaryValue*(const std::string& path,
+                                                  ErrorPtr* error));
+  MOCK_CONST_METHOD1(FindTraitDefinition,
+                     const base::DictionaryValue*(const std::string& name));
+  MOCK_CONST_METHOD1(
+      FindCommandDefinition,
+      const base::DictionaryValue*(const std::string& command_name));
+  MOCK_CONST_METHOD3(GetMinimalRole, bool(const std::string& command_name,
+                                          UserRole* minimal_role,
+                                          ErrorPtr* error));
+  MOCK_CONST_METHOD0(GetTraits, const base::DictionaryValue&());
+  MOCK_CONST_METHOD0(GetComponents, const base::DictionaryValue&());
+  MOCK_METHOD3(SetStateProperties, bool(const std::string& component_path,
+                                        const base::DictionaryValue& dict,
+                                        ErrorPtr* error));
+  MOCK_METHOD3(SetStatePropertiesFromJson,
+               bool(const std::string& component_path,
+                    const std::string& json,
+                    ErrorPtr* error));
+  MOCK_CONST_METHOD3(GetStateProperty,
+                     const base::Value*(const std::string& component_path,
+                                        const std::string& name,
+                                        ErrorPtr* error));
+  MOCK_METHOD4(SetStateProperty, bool(const std::string& component_path,
+                                      const std::string& name,
+                                      const base::Value& value,
+                                      ErrorPtr* error));
+  MOCK_METHOD1(AddStateChangedCallback, void(const base::Closure& callback));
+  MOCK_METHOD0(MockGetAndClearRecordedStateChanges, StateSnapshot&());
+  MOCK_METHOD1(NotifyStateUpdatedOnServer, void(UpdateID id));
+  MOCK_CONST_METHOD0(GetLastStateChangeId, UpdateID());
+  MOCK_METHOD1(MockAddServerStateUpdatedCallback,
+               base::CallbackList<void(UpdateID)>::Subscription*(
+                  const base::Callback<void(UpdateID)>& callback));
+  MOCK_CONST_METHOD1(FindComponentWithTrait,
+                     std::string(const std::string& trait));
+
+ private:
+  void AddCommand(std::unique_ptr<CommandInstance> command_instance) override {
+    MockAddCommand(command_instance.get());
+  }
+  StateSnapshot GetAndClearRecordedStateChanges() override {
+    return std::move(MockGetAndClearRecordedStateChanges());
+  }
+  Token AddServerStateUpdatedCallback(
+      const base::Callback<void(UpdateID)>& callback) override {
+    return Token{MockAddServerStateUpdatedCallback(callback)};
+  }
+};
+
+}  // namespace weave
+
+#endif  // LIBWEAVE_SRC_COMPONENT_MANAGER_H_