diff --git a/libweave.gypi b/libweave.gypi
index 5930e8f..f74a9bf 100644
--- a/libweave.gypi
+++ b/libweave.gypi
@@ -12,6 +12,7 @@
       'src/commands/command_manager.cc',
       'src/commands/command_queue.cc',
       'src/commands/schema_constants.cc',
+      'src/component_manager.cc',
       'src/config.cc',
       'src/data_encoding.cc',
       'src/device_manager.cc',
@@ -64,6 +65,7 @@
       'src/commands/command_instance_unittest.cc',
       'src/commands/command_manager_unittest.cc',
       'src/commands/command_queue_unittest.cc',
+      'src/component_manager_unittest.cc',
       'src/config_unittest.cc',
       'src/data_encoding_unittest.cc',
       'src/device_registration_info_unittest.cc',
diff --git a/src/component_manager.cc b/src/component_manager.cc
new file mode 100644
index 0000000..67a0524
--- /dev/null
+++ b/src/component_manager.cc
@@ -0,0 +1,376 @@
+// 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.
+
+#include "src/component_manager.h"
+
+#include <base/strings/stringprintf.h>
+#include <base/strings/string_number_conversions.h>
+#include <base/strings/string_util.h>
+
+#include "src/commands/schema_constants.h"
+#include "src/string_utils.h"
+#include "src/utils.h"
+
+namespace weave {
+
+ComponentManager::ComponentManager() {}
+ComponentManager::~ComponentManager() {}
+
+bool ComponentManager::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);
+    if (!root)
+      return false;
+  }
+  if (root->GetWithoutPathExpansion(name, nullptr)) {
+    Error::AddToPrintf(error, FROM_HERE, errors::commands::kDomain,
+                       errors::commands::kInvalidState,
+                       "Component '%s' already exists at path '%s'",
+                       name.c_str(), path.c_str());
+    return false;
+  }
+
+  // Check to make sure the declared traits are already defined.
+  for (const std::string& trait : traits) {
+    if (!FindTraitDefinition(trait)) {
+      Error::AddToPrintf(error, FROM_HERE, errors::commands::kDomain,
+                         errors::commands::kInvalidPropValue,
+                         "Trait '%s' is undefined", trait.c_str());
+      return false;
+    }
+  }
+  std::unique_ptr<base::DictionaryValue> dict{new base::DictionaryValue};
+  std::unique_ptr<base::ListValue> traits_list{new base::ListValue};
+  traits_list->AppendStrings(traits);
+  dict->Set("traits", traits_list.release());
+  root->SetWithoutPathExpansion(name, dict.release());
+  return true;
+}
+
+bool ComponentManager::AddComponentArrayItem(
+    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);
+    if (!root)
+      return false;
+  }
+  base::ListValue* array_value = nullptr;
+  if (!root->GetListWithoutPathExpansion(name, &array_value)) {
+    array_value = new base::ListValue;
+    root->SetWithoutPathExpansion(name, array_value);
+  }
+  std::unique_ptr<base::DictionaryValue> dict{new base::DictionaryValue};
+  std::unique_ptr<base::ListValue> traits_list{new base::ListValue};
+  traits_list->AppendStrings(traits);
+  dict->Set("traits", traits_list.release());
+  array_value->Append(dict.release());
+  return true;
+}
+
+bool ComponentManager::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
+  // definition is exactly the same, or else this is an error.
+  for (base::DictionaryValue::Iterator it(dict); !it.IsAtEnd(); it.Advance()) {
+    if (it.value().GetType() != base::Value::TYPE_DICTIONARY) {
+      Error::AddToPrintf(error, FROM_HERE, errors::commands::kDomain,
+                         errors::commands::kTypeMismatch,
+                         "Trait '%s' must be an object", it.key().c_str());
+      result = false;
+      break;
+    }
+    const base::DictionaryValue* existing_def = nullptr;
+    if (traits_.GetDictionary(it.key(), &existing_def)) {
+      if (!existing_def->Equals(&it.value())) {
+        Error::AddToPrintf(error, FROM_HERE, errors::commands::kDomain,
+                           errors::commands::kTypeMismatch,
+                           "Trait '%s' cannot be redefined",
+                           it.key().c_str());
+        result = false;
+        break;
+      }
+    }
+    traits_.Set(it.key(), it.value().DeepCopy());
+    modified = true;
+  }
+
+  if (modified) {
+    for (const auto& cb : on_trait_changed_)
+      cb.Run();
+  }
+  return result;
+}
+
+bool ComponentManager::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::AddTraitDefChanged(const base::Closure& callback) {
+  on_trait_changed_.push_back(callback);
+  callback.Run();
+}
+
+void ComponentManager::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) {
+  auto command_instance = CommandInstance::FromJson(
+      &command, Command::Origin::kLocal, nullptr, error);
+  if (!command_instance)
+    return false;
+
+  UserRole minimal_role;
+  if (!GetMinimalRole(command_instance->GetName(), &minimal_role, error))
+    return false;
+
+  if (role < minimal_role) {
+    Error::AddToPrintf(
+        error, FROM_HERE, errors::commands::kDomain, "access_denied",
+        "User role '%s' less than minimal: '%s'", EnumToString(role).c_str(),
+        EnumToString(minimal_role).c_str());
+    return false;
+  }
+
+  std::string component_path = command_instance->GetComponent();
+  if (component_path.empty()) {
+    // Get the name of the first top-level component.
+    base::DictionaryValue::Iterator it(components_);
+    if (it.IsAtEnd()) {
+      Error::AddTo(error, FROM_HERE, errors::commands::kDomain,
+                   "component_not_found", "There are no components defined");
+      return false;
+    }
+    component_path = it.key();
+    command_instance->SetComponent(component_path);
+  }
+
+  const auto* component = FindComponent(component_path, error);
+  if (!component)
+    return false;
+
+  // Check that the command's trait is supported by the given component.
+  auto pair = SplitAtFirst(command_instance->GetName(), ".", true);
+
+  bool trait_supported = false;
+  const base::ListValue* supported_traits = nullptr;
+  if (component->GetList("traits", &supported_traits)) {
+    for (const base::Value* value : *supported_traits) {
+      std::string trait;
+      CHECK(value->GetAsString(&trait));
+      if (trait == pair.first) {
+        trait_supported = true;
+        break;
+      }
+    }
+  }
+
+  if (!trait_supported) {
+    Error::AddToPrintf(error, FROM_HERE, errors::commands::kDomain,
+                       "trait_not_supported",
+                       "Component '%s' doesn't support trait '%s'",
+                       component_path.c_str(), pair.first.c_str());
+    return false;
+  }
+
+  std::string command_id = std::to_string(++next_command_id_);
+  command_instance->SetID(command_id);
+  if (id)
+    *id = command_id;
+  AddCommand(std::move(command_instance));
+  return true;
+}
+
+CommandInstance* ComponentManager::FindCommand(const std::string& id) {
+  return command_queue_.Find(id);
+}
+
+void ComponentManager::AddCommandAddedCallback(
+    const CommandQueue::CommandCallback& callback) {
+  command_queue_.AddCommandAddedCallback(callback);
+}
+
+void ComponentManager::AddCommandRemovedCallback(
+    const CommandQueue::CommandCallback& callback) {
+  command_queue_.AddCommandRemovedCallback(callback);
+}
+
+void ComponentManager::AddCommandHandler(
+    const std::string& component_path,
+    const std::string& command_name,
+    const Device::CommandHandlerCallback& callback) {
+  CHECK(FindCommandDefinition(command_name))
+      << "Command undefined: " << command_name;
+  command_queue_.AddCommandHandler(component_path, command_name, callback);
+}
+
+const base::DictionaryValue* ComponentManager::FindComponent(
+    const std::string& path, ErrorPtr* error) const {
+  return FindComponentAt(&components_, path, error);
+}
+
+const base::DictionaryValue* ComponentManager::FindTraitDefinition(
+    const std::string& name) const {
+  const base::DictionaryValue* trait = nullptr;
+  traits_.GetDictionaryWithoutPathExpansion(name, &trait);
+  return trait;
+}
+
+const base::DictionaryValue* ComponentManager::FindCommandDefinition(
+    const std::string& command_name) const {
+  const base::DictionaryValue* definition = nullptr;
+  std::vector<std::string> components = Split(command_name, ".", true, false);
+  // Make sure the |command_name| came in form of trait_name.command_name.
+  if (components.size() != 2)
+    return definition;
+  std::string key = base::StringPrintf("%s.commands.%s", components[0].c_str(),
+                                       components[1].c_str());
+  traits_.GetDictionary(key, &definition);
+  return definition;
+}
+
+bool ComponentManager::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,
+                       errors::commands::kInvalidCommandName,
+                       "Command definition for '%s' not found",
+                       command_name.c_str());
+    return false;
+  }
+  std::string value;
+  // The JSON definition has been pre-validated already in LoadCommands, so
+  // just using CHECKs here.
+  CHECK(command->GetString(commands::attributes::kCommand_Role, &value));
+  CHECK(StringToEnum(value, minimal_role));
+  return true;
+}
+
+base::DictionaryValue* ComponentManager::FindComponentGraftNode(
+    const std::string& path, ErrorPtr* error) {
+  base::DictionaryValue* root = nullptr;
+  auto component = const_cast<base::DictionaryValue*>(FindComponentAt(
+      &components_, path, error));
+  if (component && !component->GetDictionary("components", &root)) {
+    root = new base::DictionaryValue;
+    component->Set("components", root);
+  }
+  return root;
+}
+
+const base::DictionaryValue* ComponentManager::FindComponentAt(
+    const base::DictionaryValue* root,
+    const std::string& path,
+    ErrorPtr* error) {
+  auto parts = Split(path, ".", true, false);
+  std::string root_path;
+  for (size_t i = 0; i < parts.size(); i++) {
+    auto element = SplitAtFirst(parts[i], "[", true);
+    int array_index = -1;
+    if (element.first.empty()) {
+      Error::AddToPrintf(error, FROM_HERE, errors::commands::kDomain,
+                         errors::commands::kPropertyMissing,
+                         "Empty path element at '%s'", root_path.c_str());
+      return nullptr;
+    }
+    if (!element.second.empty()) {
+      if (element.second.back() != ']') {
+        Error::AddToPrintf(error, FROM_HERE, errors::commands::kDomain,
+                           errors::commands::kPropertyMissing,
+                           "Invalid array element syntax '%s'",
+                           parts[i].c_str());
+        return nullptr;
+      }
+      element.second.pop_back();
+      std::string index_str;
+      base::TrimWhitespaceASCII(element.second, base::TrimPositions::TRIM_ALL,
+                                &index_str);
+      if (!base::StringToInt(index_str, &array_index) || array_index < 0) {
+        Error::AddToPrintf(error, FROM_HERE, errors::commands::kDomain,
+                           errors::commands::kInvalidPropValue,
+                           "Invalid array index '%s'", element.second.c_str());
+        return nullptr;
+      }
+    }
+
+    if (!root_path.empty()) {
+      // We have processed at least one item in the path before, so now |root|
+      // points to the actual parent component. We need the root to point to
+      // the 'components' element containing child sub-components instead.
+      if (!root->GetDictionary("components", &root)) {
+        Error::AddToPrintf(error, FROM_HERE, errors::commands::kDomain,
+                           errors::commands::kPropertyMissing,
+                           "Component '%s' does not exist at '%s'",
+                           element.first.c_str(), root_path.c_str());
+        return nullptr;
+      }
+    }
+
+    const base::Value* value = nullptr;
+    if (!root->GetWithoutPathExpansion(element.first, &value)) {
+      Error::AddToPrintf(error, FROM_HERE, errors::commands::kDomain,
+                         errors::commands::kPropertyMissing,
+                         "Component '%s' does not exist at '%s'",
+                         element.first.c_str(), root_path.c_str());
+      return nullptr;
+    }
+
+    if (value->GetType() == base::Value::TYPE_LIST && array_index < 0) {
+      Error::AddToPrintf(error, FROM_HERE, errors::commands::kDomain,
+                         errors::commands::kTypeMismatch,
+                         "Element '%s.%s' is an array",
+                         root_path.c_str(), element.first.c_str());
+      return nullptr;
+    }
+    if (value->GetType() == base::Value::TYPE_DICTIONARY && array_index >= 0) {
+      Error::AddToPrintf(error, FROM_HERE, errors::commands::kDomain,
+                         errors::commands::kTypeMismatch,
+                         "Element '%s.%s' is not an array",
+                         root_path.c_str(), element.first.c_str());
+      return nullptr;
+    }
+
+    if (value->GetType() == base::Value::TYPE_DICTIONARY) {
+      CHECK(value->GetAsDictionary(&root));
+    } else {
+      const base::ListValue* component_array = nullptr;
+      CHECK(value->GetAsList(&component_array));
+      const base::Value* component_value = nullptr;
+      if (!component_array->Get(array_index, &component_value) ||
+          !component_value->GetAsDictionary(&root)) {
+        Error::AddToPrintf(error, FROM_HERE, errors::commands::kDomain,
+                           errors::commands::kPropertyMissing,
+                           "Element '%s.%s' does not contain item #%d",
+                           root_path.c_str(), element.first.c_str(),
+                           array_index);
+        return nullptr;
+      }
+    }
+    if (!root_path.empty())
+      root_path += '.';
+    root_path += parts[i];
+  }
+  return root;
+}
+
+}  // namespace weave
diff --git a/src/component_manager.h b/src/component_manager.h
new file mode 100644
index 0000000..d9de8ea
--- /dev/null
+++ b/src/component_manager.h
@@ -0,0 +1,130 @@
+// 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_H_
+#define LIBWEAVE_SRC_COMPONENT_MANAGER_H_
+
+#include <memory>
+
+#include <base/values.h>
+#include <weave/error.h>
+
+#include "src/commands/command_dictionary.h"
+#include "src/commands/command_queue.h"
+
+namespace weave {
+
+class CommandInstance;
+
+class ComponentManager final {
+ public:
+  ComponentManager();
+  ~ComponentManager();
+
+  // Loads trait definition schema.
+  bool LoadTraits(const base::DictionaryValue& dict, ErrorPtr* error);
+
+  // Same as the overload above, but takes a json string to read the trait
+  // definitions from.
+  bool LoadTraits(const std::string& json, ErrorPtr* error);
+
+  // Sets callback which is called when new trait definitions are added.
+  void AddTraitDefChanged(const base::Closure& callback);
+
+  // 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);
+
+  // 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);
+
+  // 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);
+
+  // 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);
+
+  // Find a command instance with the given ID in the command queue.
+  CommandInstance* FindCommand(const std::string& id);
+
+  // 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);
+
+  // 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);
+
+  // Finds a component instance by its full path.
+  const base::DictionaryValue* FindComponent(const std::string& path,
+                                             ErrorPtr* error) const;
+  // Finds a definition of trait with the given |name|.
+  const base::DictionaryValue* FindTraitDefinition(
+      const std::string& name) const;
+
+  // Finds a command definition, where |command_name| is in the form of
+  // "trait.command".
+  const base::DictionaryValue* FindCommandDefinition(
+      const std::string& command_name) const;
+
+  // Checks the minimum required user role for a given command.
+  bool GetMinimalRole(const std::string& command_name,
+                      UserRole* minimal_role,
+                      ErrorPtr* error) const;
+
+  // Returns the full JSON dictionary containing trait definitions.
+  const base::DictionaryValue& GetTraits() const { return traits_; }
+
+  // Returns the full JSON dictionary containing component instances.
+  const base::DictionaryValue& GetComponents() const { return components_; }
+
+ 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);
+
+  // 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::DictionaryValue traits_;  // Trait definitions.
+  base::DictionaryValue components_;  // Component instances.
+  CommandQueue command_queue_;  // Command queue containing command instances.
+  std::vector<base::Callback<void()>> on_trait_changed_;
+  uint32_t next_command_id_{0};
+
+  DISALLOW_COPY_AND_ASSIGN(ComponentManager);
+};
+
+}  // namespace weave
+
+#endif  // LIBWEAVE_SRC_COMPONENT_MANAGER_H_
diff --git a/src/component_manager_unittest.cc b/src/component_manager_unittest.cc
new file mode 100644
index 0000000..ba6bc34
--- /dev/null
+++ b/src/component_manager_unittest.cc
@@ -0,0 +1,609 @@
+// 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.
+
+#include "src/component_manager.h"
+
+#include <map>
+
+#include <gtest/gtest.h>
+#include <weave/test/unittest_utils.h>
+
+#include "src/bind_lambda.h"
+#include "src/commands/schema_constants.h"
+
+namespace weave {
+
+using test::CreateDictionaryValue;
+
+namespace {
+
+bool HasTrait(const base::DictionaryValue& comp, const std::string& trait) {
+  const base::ListValue* list = nullptr;
+  if (!comp.GetList("traits", &list))
+    return false;
+  for (const base::Value* item : *list) {
+    std::string value;
+    if (item->GetAsString(&value) && value == trait)
+      return true;
+  }
+  return false;
+}
+
+}  // anonymous namespace
+
+TEST(ComponentManager, Empty) {
+  ComponentManager manager;
+  EXPECT_TRUE(manager.GetTraits().empty());
+  EXPECT_TRUE(manager.GetComponents().empty());
+}
+
+TEST(ComponentManager, LoadTraits) {
+  ComponentManager manager;
+  const char kTraits[] = R"({
+    "trait1": {
+      "commands": {
+        "command1": {
+          "minimalRole": "user",
+          "parameters": {"height": {"type": "integer"}}
+        }
+      },
+      "state": {
+        "property1": {"type": "boolean"}
+      }
+    },
+    "trait2": {
+      "state": {
+        "property2": {"type": "string"}
+      }
+    }
+  })";
+  auto json = CreateDictionaryValue(kTraits);
+  EXPECT_TRUE(manager.LoadTraits(*json, nullptr));
+  EXPECT_JSON_EQ(kTraits, manager.GetTraits());
+  EXPECT_TRUE(manager.GetComponents().empty());
+}
+
+TEST(ComponentManager, LoadTraitsDuplicateIdentical) {
+  ComponentManager manager;
+  const char kTraits1[] = R"({
+    "trait1": {
+      "commands": {
+        "command1": {
+          "minimalRole": "user",
+          "parameters": {"height": {"type": "integer"}}
+        }
+      },
+      "state": {
+        "property1": {"type": "boolean"}
+      }
+    },
+    "trait2": {
+      "state": {
+        "property2": {"type": "string"}
+      }
+    }
+  })";
+  auto json = CreateDictionaryValue(kTraits1);
+  EXPECT_TRUE(manager.LoadTraits(*json, nullptr));
+  const char kTraits2[] = R"({
+    "trait1": {
+      "commands": {
+        "command1": {
+          "minimalRole": "user",
+          "parameters": {"height": {"type": "integer"}}
+        }
+      },
+      "state": {
+        "property1": {"type": "boolean"}
+      }
+    },
+    "trait3": {
+      "state": {
+        "property3": {"type": "string"}
+      }
+    }
+  })";
+  json = CreateDictionaryValue(kTraits2);
+  EXPECT_TRUE(manager.LoadTraits(*json, nullptr));
+  const char kExpected[] = R"({
+    "trait1": {
+      "commands": {
+        "command1": {
+          "minimalRole": "user",
+          "parameters": {"height": {"type": "integer"}}
+        }
+      },
+      "state": {
+        "property1": {"type": "boolean"}
+      }
+    },
+    "trait2": {
+      "state": {
+        "property2": {"type": "string"}
+      }
+    },
+    "trait3": {
+      "state": {
+        "property3": {"type": "string"}
+      }
+    }
+  })";
+  EXPECT_JSON_EQ(kExpected, manager.GetTraits());
+}
+
+TEST(ComponentManager, LoadTraitsDuplicateOverride) {
+  ComponentManager manager;
+  const char kTraits1[] = R"({
+    "trait1": {
+      "commands": {
+        "command1": {
+          "minimalRole": "user",
+          "parameters": {"height": {"type": "integer"}}
+        }
+      },
+      "state": {
+        "property1": {"type": "boolean"}
+      }
+    },
+    "trait2": {
+      "state": {
+        "property2": {"type": "string"}
+      }
+    }
+  })";
+  auto json = CreateDictionaryValue(kTraits1);
+  EXPECT_TRUE(manager.LoadTraits(*json, nullptr));
+  const char kTraits2[] = R"({
+    "trait1": {
+      "commands": {
+        "command1": {
+          "minimalRole": "user",
+          "parameters": {"height": {"type": "string"}}
+        }
+      },
+      "state": {
+        "property1": {"type": "boolean"}
+      }
+    },
+    "trait3": {
+      "state": {
+        "property3": {"type": "string"}
+      }
+    }
+  })";
+  json = CreateDictionaryValue(kTraits2);
+  EXPECT_FALSE(manager.LoadTraits(*json, nullptr));
+}
+
+TEST(ComponentManager, LoadTraitsNotAnObject) {
+  ComponentManager manager;
+  const char kTraits1[] = R"({"trait1": 0})";
+  auto json = CreateDictionaryValue(kTraits1);
+  ErrorPtr error;
+  EXPECT_FALSE(manager.LoadTraits(*json, &error));
+  EXPECT_EQ(errors::commands::kTypeMismatch, error->GetCode());
+}
+
+TEST(ComponentManager, FindTraitDefinition) {
+  ComponentManager manager;
+  const char kTraits[] = R"({
+    "trait1": {
+      "commands": {
+        "command1": {
+          "minimalRole": "user",
+          "parameters": {"height": {"type": "integer"}}
+        }
+      },
+      "state": {
+        "property1": {"type": "boolean"}
+      }
+    },
+    "trait2": {
+      "state": {
+        "property2": {"type": "string"}
+      }
+    }
+  })";
+  auto json = CreateDictionaryValue(kTraits);
+  ASSERT_TRUE(manager.LoadTraits(*json, nullptr));
+
+  const base::DictionaryValue* trait = manager.FindTraitDefinition("trait1");
+  ASSERT_NE(nullptr, trait);
+  const char kExpected1[] = R"({
+    "commands": {
+      "command1": {
+        "minimalRole": "user",
+        "parameters": {"height": {"type": "integer"}}
+      }
+    },
+    "state": {
+      "property1": {"type": "boolean"}
+    }
+  })";
+  EXPECT_JSON_EQ(kExpected1, *trait);
+
+  trait = manager.FindTraitDefinition("trait2");
+  ASSERT_NE(nullptr, trait);
+  const char kExpected2[] = R"({
+    "state": {
+      "property2": {"type": "string"}
+    }
+  })";
+  EXPECT_JSON_EQ(kExpected2, *trait);
+
+  EXPECT_EQ(nullptr, manager.FindTraitDefinition("trait3"));
+}
+
+TEST(ComponentManager, FindCommandDefinition) {
+  ComponentManager manager;
+  const char kTraits[] = R"({
+    "trait1": {
+      "commands": {
+        "command1": {
+          "minimalRole": "user",
+          "parameters": {"height": {"type": "integer"}}
+        }
+      }
+    },
+    "trait2": {
+      "commands": {
+        "command1": {
+          "minimalRole": "manager"
+        },
+        "command2": {
+          "minimalRole": "owner"
+        }
+      }
+    }
+  })";
+  auto json = CreateDictionaryValue(kTraits);
+  ASSERT_TRUE(manager.LoadTraits(*json, nullptr));
+
+  const auto* cmd_def = manager.FindCommandDefinition("trait1.command1");
+  ASSERT_NE(nullptr, cmd_def);
+  const char kExpected1[] = R"({
+    "minimalRole": "user",
+    "parameters": {"height": {"type": "integer"}}
+  })";
+  EXPECT_JSON_EQ(kExpected1, *cmd_def);
+
+  cmd_def = manager.FindCommandDefinition("trait2.command1");
+  ASSERT_NE(nullptr, cmd_def);
+  const char kExpected2[] = R"({
+    "minimalRole": "manager"
+  })";
+  EXPECT_JSON_EQ(kExpected2, *cmd_def);
+
+  cmd_def = manager.FindCommandDefinition("trait2.command2");
+  ASSERT_NE(nullptr, cmd_def);
+  const char kExpected3[] = R"({
+    "minimalRole": "owner"
+  })";
+  EXPECT_JSON_EQ(kExpected3, *cmd_def);
+
+  EXPECT_EQ(nullptr, manager.FindTraitDefinition("trait1.command2"));
+  EXPECT_EQ(nullptr, manager.FindTraitDefinition("trait3.command1"));
+  EXPECT_EQ(nullptr, manager.FindTraitDefinition("trait"));
+  EXPECT_EQ(nullptr, manager.FindTraitDefinition("trait1.command1.parameters"));
+}
+
+TEST(ComponentManager, GetMinimalRole) {
+  ComponentManager manager;
+  const char kTraits[] = R"({
+    "trait1": {
+      "commands": {
+        "command1": { "minimalRole": "user" },
+        "command2": { "minimalRole": "viewer" }
+      }
+    },
+    "trait2": {
+      "commands": {
+        "command1": { "minimalRole": "manager" },
+        "command2": { "minimalRole": "owner" }
+      }
+    }
+  })";
+  auto json = CreateDictionaryValue(kTraits);
+  ASSERT_TRUE(manager.LoadTraits(*json, nullptr));
+
+  UserRole role;
+  ASSERT_TRUE(manager.GetMinimalRole("trait1.command1", &role, nullptr));
+  EXPECT_EQ(UserRole::kUser, role);
+
+  ASSERT_TRUE(manager.GetMinimalRole("trait1.command2", &role, nullptr));
+  EXPECT_EQ(UserRole::kViewer, role);
+
+  ASSERT_TRUE(manager.GetMinimalRole("trait2.command1", &role, nullptr));
+  EXPECT_EQ(UserRole::kManager, role);
+
+  ASSERT_TRUE(manager.GetMinimalRole("trait2.command2", &role, nullptr));
+  EXPECT_EQ(UserRole::kOwner, role);
+
+  EXPECT_FALSE(manager.GetMinimalRole("trait1.command3", &role, nullptr));
+}
+
+TEST(ComponentManager, AddComponent) {
+  ComponentManager manager;
+  const char kTraits[] = R"({"trait1": {}, "trait2": {}, "trait3": {}})";
+  auto json = CreateDictionaryValue(kTraits);
+  ASSERT_TRUE(manager.LoadTraits(*json, nullptr));
+  EXPECT_TRUE(manager.AddComponent("", "comp1", {"trait1", "trait2"}, nullptr));
+  EXPECT_TRUE(manager.AddComponent("", "comp2", {"trait3"}, nullptr));
+  const char kExpected[] = R"({
+    "comp1": {
+      "traits": ["trait1", "trait2"]
+    },
+    "comp2": {
+      "traits": ["trait3"]
+    }
+  })";
+  EXPECT_JSON_EQ(kExpected, manager.GetComponents());
+
+  // 'trait4' is undefined, so can't add a component referring to it.
+  EXPECT_FALSE(manager.AddComponent("", "comp3", {"trait4"}, nullptr));
+}
+
+TEST(ComponentManager, AddSubComponent) {
+  ComponentManager manager;
+  EXPECT_TRUE(manager.AddComponent("", "comp1", {}, nullptr));
+  EXPECT_TRUE(manager.AddComponent("comp1", "comp2", {}, nullptr));
+  EXPECT_TRUE(manager.AddComponent("comp1", "comp3", {}, nullptr));
+  EXPECT_TRUE(manager.AddComponent("comp1.comp2", "comp4", {}, nullptr));
+  const char kExpected[] = R"({
+    "comp1": {
+      "traits": [],
+      "components": {
+        "comp2": {
+          "traits": [],
+          "components": {
+            "comp4": {
+              "traits": []
+            }
+          }
+        },
+        "comp3": {
+          "traits": []
+        }
+      }
+    }
+  })";
+  EXPECT_JSON_EQ(kExpected, manager.GetComponents());
+}
+
+TEST(ComponentManager, AddComponentArrayItem) {
+  ComponentManager manager;
+  const char kTraits[] = R"({"foo": {}, "bar": {}})";
+  auto json = CreateDictionaryValue(kTraits);
+  ASSERT_TRUE(manager.LoadTraits(*json, nullptr));
+
+  EXPECT_TRUE(manager.AddComponent("", "comp1", {}, nullptr));
+  EXPECT_TRUE(manager.AddComponentArrayItem("comp1", "comp2", {"foo"},
+                                            nullptr));
+  EXPECT_TRUE(manager.AddComponentArrayItem("comp1", "comp2", {"bar"},
+                                            nullptr));
+  EXPECT_TRUE(manager.AddComponent("comp1.comp2[1]", "comp3", {}, nullptr));
+  EXPECT_TRUE(manager.AddComponent("comp1.comp2[1].comp3", "comp4", {},
+                                   nullptr));
+  const char kExpected[] = R"({
+    "comp1": {
+      "traits": [],
+      "components": {
+        "comp2": [
+          {
+            "traits": ["foo"]
+          },
+          {
+            "traits": ["bar"],
+            "components": {
+              "comp3": {
+                "traits": [],
+                "components": {
+                  "comp4": {
+                    "traits": []
+                  }
+                }
+              }
+            }
+          }
+        ]
+      }
+    }
+  })";
+  EXPECT_JSON_EQ(kExpected, manager.GetComponents());
+}
+
+TEST(ComponentManager, AddComponentExist) {
+  ComponentManager manager;
+  EXPECT_TRUE(manager.AddComponent("", "comp1", {}, nullptr));
+  EXPECT_FALSE(manager.AddComponent("", "comp1", {}, nullptr));
+  EXPECT_TRUE(manager.AddComponent("comp1", "comp2", {}, nullptr));
+  EXPECT_FALSE(manager.AddComponent("comp1", "comp2", {}, nullptr));
+}
+
+TEST(ComponentManager, AddComponentDoesNotExist) {
+  ComponentManager manager;
+  EXPECT_FALSE(manager.AddComponent("comp1", "comp2", {}, nullptr));
+}
+
+TEST(ComponentManager, FindComponent) {
+  ComponentManager manager;
+  const char kTraits[] = R"({"t1":{}, "t2":{}, "t3":{}, "t4":{}, "t5":{}})";
+  auto json = CreateDictionaryValue(kTraits);
+  ASSERT_TRUE(manager.LoadTraits(*json, nullptr));
+
+  EXPECT_TRUE(manager.AddComponent("", "comp1", {"t1"}, nullptr));
+  EXPECT_TRUE(manager.AddComponentArrayItem("comp1", "comp2", {"t2"}, nullptr));
+  EXPECT_TRUE(manager.AddComponentArrayItem("comp1", "comp2", {"t3"}, nullptr));
+  EXPECT_TRUE(manager.AddComponent("comp1.comp2[1]", "comp3", {"t4"}, nullptr));
+  EXPECT_TRUE(manager.AddComponent("comp1.comp2[1].comp3", "comp4", {"t5"},
+                                   nullptr));
+
+  const base::DictionaryValue* comp = manager.FindComponent("comp1", nullptr);
+  ASSERT_NE(nullptr, comp);
+  EXPECT_TRUE(HasTrait(*comp, "t1"));
+
+  comp = manager.FindComponent("comp1.comp2[0]", nullptr);
+  ASSERT_NE(nullptr, comp);
+  EXPECT_TRUE(HasTrait(*comp, "t2"));
+
+  comp = manager.FindComponent("comp1.comp2[1]", nullptr);
+  ASSERT_NE(nullptr, comp);
+  EXPECT_TRUE(HasTrait(*comp, "t3"));
+
+  comp = manager.FindComponent("comp1.comp2[1].comp3", nullptr);
+  ASSERT_NE(nullptr, comp);
+  EXPECT_TRUE(HasTrait(*comp, "t4"));
+
+  comp = manager.FindComponent("comp1.comp2[1].comp3.comp4", nullptr);
+  ASSERT_NE(nullptr, comp);
+  EXPECT_TRUE(HasTrait(*comp, "t5"));
+
+  // Some whitespaces don't hurt.
+  comp = manager.FindComponent(" comp1 . comp2 [  \t 1 ] .   comp3.comp4 ",
+                               nullptr);
+  EXPECT_NE(nullptr, comp);
+
+  // Now check some failure cases.
+  ErrorPtr error;
+  EXPECT_EQ(nullptr, manager.FindComponent("", &error));
+  EXPECT_NE(nullptr, error.get());
+  // 'comp2' doesn't exist:
+  EXPECT_EQ(nullptr, manager.FindComponent("comp2", nullptr));
+  // 'comp1.comp2' is an array, not a component:
+  EXPECT_EQ(nullptr, manager.FindComponent("comp1.comp2", nullptr));
+  // 'comp1.comp2[3]' doesn't exist:
+  EXPECT_EQ(nullptr, manager.FindComponent("comp1.comp2[3]", nullptr));
+  // Empty component names:
+  EXPECT_EQ(nullptr, manager.FindComponent(".comp2[1]", nullptr));
+  EXPECT_EQ(nullptr, manager.FindComponent("comp1.[1]", nullptr));
+  // Invalid array indices:
+  EXPECT_EQ(nullptr, manager.FindComponent("comp1.comp2[s]", nullptr));
+  EXPECT_EQ(nullptr, manager.FindComponent("comp1.comp2[-2]", nullptr));
+  EXPECT_EQ(nullptr, manager.FindComponent("comp1.comp2[1e1]", nullptr));
+  EXPECT_EQ(nullptr, manager.FindComponent("comp1.comp2[1", nullptr));
+}
+
+TEST(ComponentManager, AddCommand) {
+  ComponentManager manager;
+  const char kTraits[] = R"({
+    "trait1": {
+      "commands": {
+        "command1": { "minimalRole": "user" },
+        "command2": { "minimalRole": "viewer" }
+      }
+    },
+    "trait2": {
+      "commands": {
+        "command1": { "minimalRole": "manager" },
+        "command2": { "minimalRole": "owner" }
+      }
+    }
+  })";
+  auto traits = CreateDictionaryValue(kTraits);
+  ASSERT_TRUE(manager.LoadTraits(*traits, nullptr));
+  ASSERT_TRUE(manager.AddComponent("", "comp1", {"trait1"}, nullptr));
+  ASSERT_TRUE(manager.AddComponent("", "comp2", {"trait2"}, nullptr));
+
+  std::string id;
+  const char kCommand1[] = R"({
+    "name": "trait1.command1",
+    "component": "comp1",
+    "parameters": {}
+  })";
+  auto command1 = CreateDictionaryValue(kCommand1);
+  EXPECT_TRUE(manager.AddCommand(*command1, UserRole::kUser, &id, nullptr));
+  // Not enough access rights
+  EXPECT_FALSE(manager.AddCommand(*command1, UserRole::kViewer, &id, nullptr));
+
+  const char kCommand2[] = R"({
+    "name": "trait1.command3",
+    "component": "comp1",
+    "parameters": {}
+  })";
+  auto command2 = CreateDictionaryValue(kCommand2);
+  // trait1.command3 doesn't exist
+  EXPECT_FALSE(manager.AddCommand(*command2, UserRole::kOwner, &id, nullptr));
+
+  const char kCommand3[] = R"({
+    "name": "trait2.command1",
+    "component": "comp1",
+    "parameters": {}
+  })";
+  auto command3 = CreateDictionaryValue(kCommand3);
+  // Component comp1 doesn't have trait2.
+  EXPECT_FALSE(manager.AddCommand(*command3, UserRole::kOwner, &id, nullptr));
+
+  // No component specified, use the first top-level component (comp1)
+  const char kCommand4[] = R"({
+    "name": "trait1.command1",
+    "parameters": {}
+  })";
+  auto command4 = CreateDictionaryValue(kCommand4);
+  EXPECT_TRUE(manager.AddCommand(*command4, UserRole::kOwner, &id, nullptr));
+  auto cmd = manager.FindCommand(id);
+  ASSERT_NE(nullptr, cmd);
+  EXPECT_EQ("comp1", cmd->GetComponent());
+}
+
+TEST(ComponentManager, AddCommandHandler) {
+  ComponentManager manager;
+  const char kTraits[] = R"({
+    "trait1": {
+      "commands": {
+        "command1": { "minimalRole": "user" }
+      }
+    },
+    "trait2": {
+      "commands": {
+        "command2": { "minimalRole": "user" }
+      }
+    }
+  })";
+  auto traits = CreateDictionaryValue(kTraits);
+  ASSERT_TRUE(manager.LoadTraits(*traits, nullptr));
+  ASSERT_TRUE(manager.AddComponent("", "comp1", {"trait1"}, nullptr));
+  ASSERT_TRUE(manager.AddComponent("", "comp2", {"trait1", "trait2"}, nullptr));
+
+  std::string last_tags;
+  auto handler = [&last_tags](int tag, const std::weak_ptr<Command>& command) {
+    if (!last_tags.empty())
+      last_tags += ',';
+    last_tags += std::to_string(tag);
+  };
+
+  manager.AddCommandHandler("comp1", "trait1.command1", base::Bind(handler, 1));
+  manager.AddCommandHandler("comp2", "trait1.command1", base::Bind(handler, 2));
+  manager.AddCommandHandler("comp2", "trait2.command2", base::Bind(handler, 3));
+  EXPECT_TRUE(last_tags.empty());
+
+  const char kCommand1[] = R"({
+    "name": "trait1.command1",
+    "component": "comp1"
+  })";
+  auto command1 = CreateDictionaryValue(kCommand1);
+  EXPECT_TRUE(manager.AddCommand(*command1, UserRole::kUser, nullptr, nullptr));
+  EXPECT_EQ("1", last_tags);
+  last_tags.clear();
+
+  const char kCommand2[] = R"({
+    "name": "trait1.command1",
+    "component": "comp2"
+  })";
+  auto command2 = CreateDictionaryValue(kCommand2);
+  EXPECT_TRUE(manager.AddCommand(*command2, UserRole::kUser, nullptr, nullptr));
+  EXPECT_EQ("2", last_tags);
+  last_tags.clear();
+
+  const char kCommand3[] = R"({
+    "name": "trait2.command2",
+    "component": "comp2",
+    "parameters": {}
+  })";
+  auto command3 = CreateDictionaryValue(kCommand3);
+  EXPECT_TRUE(manager.AddCommand(*command3, UserRole::kUser, nullptr, nullptr));
+  EXPECT_EQ("3", last_tags);
+  last_tags.clear();
+}
+
+}  // namespace weave
