diff --git a/src/component_manager.cc b/src/component_manager.cc
index 67a0524..bf92a78 100644
--- a/src/component_manager.cc
+++ b/src/component_manager.cc
@@ -9,12 +9,19 @@
 #include <base/strings/string_util.h>
 
 #include "src/commands/schema_constants.h"
+#include "src/json_error_codes.h"
 #include "src/string_utils.h"
 #include "src/utils.h"
 
 namespace weave {
 
+namespace {
+// Max of 100 state update events should be enough in the queue.
+const size_t kMaxStateChangeQueueSize = 100;
+}  // namespace
+
 ComponentManager::ComponentManager() {}
+ComponentManager::ComponentManager(base::Clock* clock) : clock_{clock} {}
 ComponentManager::~ComponentManager() {}
 
 bool ComponentManager::AddComponent(const std::string& path,
@@ -49,6 +56,8 @@
   traits_list->AppendStrings(traits);
   dict->Set("traits", traits_list.release());
   root->SetWithoutPathExpansion(name, dict.release());
+  for (const auto& cb : on_componet_tree_changed_)
+    cb.Run();
   return true;
 }
 
@@ -73,9 +82,17 @@
   traits_list->AppendStrings(traits);
   dict->Set("traits", traits_list.release());
   array_value->Append(dict.release());
+  for (const auto& cb : on_componet_tree_changed_)
+    cb.Run();
   return true;
 }
 
+void ComponentManager::AddComponentTreeChangedCallback(
+    const base::Closure& callback) {
+  on_componet_tree_changed_.push_back(callback);
+  callback.Run();
+}
+
 bool ComponentManager::LoadTraits(const base::DictionaryValue& dict,
                                   ErrorPtr* error) {
   bool modified = false;
@@ -100,9 +117,10 @@
         result = false;
         break;
       }
+    } else {
+      traits_.Set(it.key(), it.value().DeepCopy());
+      modified = true;
     }
-    traits_.Set(it.key(), it.value().DeepCopy());
-    modified = true;
   }
 
   if (modified) {
@@ -119,7 +137,8 @@
   return LoadTraits(*dict, error);
 }
 
-void ComponentManager::AddTraitDefChanged(const base::Closure& callback) {
+void ComponentManager::AddTraitDefChangedCallback(
+    const base::Closure& callback) {
   on_trait_changed_.push_back(callback);
   callback.Run();
 }
@@ -163,7 +182,7 @@
     command_instance->SetComponent(component_path);
   }
 
-  const auto* component = FindComponent(component_path, error);
+  const base::DictionaryValue* component = FindComponent(component_path, error);
   if (!component)
     return false;
 
@@ -266,11 +285,139 @@
   return true;
 }
 
+void ComponentManager::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) {
+  base::DictionaryValue* component =
+      FindMutableComponent(component_path, error);
+  if (!component)
+    return false;
+
+  base::DictionaryValue* state = nullptr;
+  if (!component->GetDictionary("state", &state)) {
+    state = new base::DictionaryValue;
+    component->Set("state", state);
+  }
+  state->MergeDictionary(&dict);
+  last_state_change_id_++;
+  auto& queue = state_change_queues_[component_path];
+  if (!queue)
+    queue.reset(new StateChangeQueue{kMaxStateChangeQueueSize});
+  base::Time timestamp = clock_ ? clock_->Now() : base::Time::Now();
+  queue->NotifyPropertiesUpdated(timestamp, dict);
+  for (const auto& cb : on_state_changed_)
+    cb.Run();
+  return true;
+}
+
+bool ComponentManager::SetStatePropertiesFromJson(
+    const std::string& component_path,
+    const std::string& json,
+    ErrorPtr* error) {
+  std::unique_ptr<const base::DictionaryValue> dict = LoadJsonDict(json, error);
+  return dict && SetStateProperties(component_path, *dict, error);
+}
+
+const base::Value* ComponentManager::GetStateProperty(
+    const std::string& component_path,
+    const std::string& name,
+    ErrorPtr* error) const {
+  const base::DictionaryValue* component = FindComponent(component_path, error);
+  if (!component)
+    return false;
+  auto pair = SplitAtFirst(name, ".", true);
+  if (pair.first.empty()) {
+    Error::AddToPrintf(error, FROM_HERE, errors::commands::kDomain,
+                       errors::commands::kPropertyMissing,
+                       "Empty state package in '%s'", name.c_str());
+    return false;
+  }
+  if (pair.second.empty()) {
+    Error::AddToPrintf(error, FROM_HERE, errors::commands::kDomain,
+                       errors::commands::kPropertyMissing,
+                       "State property name not specified in '%s'",
+                       name.c_str());
+    return false;
+  }
+  std::string key = base::StringPrintf("state.%s", name.c_str());
+  const base::Value* value = nullptr;
+  if (!component->Get(key, &value)) {
+    Error::AddToPrintf(error, FROM_HERE, errors::commands::kDomain,
+                       errors::commands::kPropertyMissing,
+                       "State property '%s' not found in component '%s'",
+                       name.c_str(), component_path.c_str());
+  }
+  return value;
+}
+
+bool ComponentManager::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()) {
+    Error::AddToPrintf(error, FROM_HERE, errors::commands::kDomain,
+                       errors::commands::kPropertyMissing,
+                       "Empty state package in '%s'", name.c_str());
+    return false;
+  }
+  if (pair.second.empty()) {
+    Error::AddToPrintf(error, FROM_HERE, errors::commands::kDomain,
+                       errors::commands::kPropertyMissing,
+                       "State property name not specified in '%s'",
+                       name.c_str());
+    return false;
+  }
+  dict.Set(name, value.DeepCopy());
+  return SetStateProperties(component_path, dict, error);
+}
+
+ComponentManager::StateSnapshot
+ComponentManager::GetAndClearRecordedStateChanges() {
+  StateSnapshot snapshot;
+  snapshot.update_id = GetLastStateChangeId();
+  for (auto& pair : state_change_queues_) {
+    auto changes = pair.second->GetAndClearRecordedStateChanges();
+    auto component = pair.first;
+    auto conv = [component](weave::StateChange& change) {
+      return ComponentStateChange{change.timestamp, component,
+                                  std::move(change.changed_properties)};
+    };
+    std::transform(changes.begin(), changes.end(),
+                   std::back_inserter(snapshot.state_changes), conv);
+  }
+
+  // Sort events by the timestamp.
+  auto pred = [](const ComponentStateChange& lhs,
+                 const ComponentStateChange& rhs) {
+    return lhs.timestamp < rhs.timestamp;
+  };
+  std::sort(snapshot.state_changes.begin(), snapshot.state_changes.end(), pred);
+  state_change_queues_.clear();
+  return snapshot;
+}
+
+void ComponentManager::NotifyStateUpdatedOnServer(UpdateID id) {
+  on_server_state_updated_.Notify(id);
+}
+
+ComponentManager::Token ComponentManager::AddServerStateUpdatedCallback(
+    const base::Callback<void(UpdateID)>& callback) {
+  if (state_change_queues_.empty())
+    callback.Run(GetLastStateChangeId());
+  return Token{on_server_state_updated_.Add(callback).release()};
+}
+
 base::DictionaryValue* ComponentManager::FindComponentGraftNode(
     const std::string& path, ErrorPtr* error) {
   base::DictionaryValue* root = nullptr;
-  auto component = const_cast<base::DictionaryValue*>(FindComponentAt(
-      &components_, path, error));
+  base::DictionaryValue* component = FindMutableComponent(path, error);
   if (component && !component->GetDictionary("components", &root)) {
     root = new base::DictionaryValue;
     component->Set("components", root);
@@ -278,6 +425,13 @@
   return root;
 }
 
+base::DictionaryValue* ComponentManager::FindMutableComponent(
+    const std::string& path,
+    ErrorPtr* error) {
+  return const_cast<base::DictionaryValue*>(
+      FindComponentAt(&components_, path, error));
+}
+
 const base::DictionaryValue* ComponentManager::FindComponentAt(
     const base::DictionaryValue* root,
     const std::string& path,
diff --git a/src/component_manager.h b/src/component_manager.h
index d9de8ea..2deaa30 100644
--- a/src/component_manager.h
+++ b/src/component_manager.h
@@ -5,21 +5,49 @@
 #ifndef LIBWEAVE_SRC_COMPONENT_MANAGER_H_
 #define LIBWEAVE_SRC_COMPONENT_MANAGER_H_
 
+#include <map>
 #include <memory>
 
+#include <base/callback_list.h>
+#include <base/time/clock.h>
 #include <base/values.h>
 #include <weave/error.h>
 
 #include "src/commands/command_dictionary.h"
 #include "src/commands/command_queue.h"
+#include "src/states/state_change_queue.h"
 
 namespace weave {
 
 class CommandInstance;
 
+// A simple notification record event to track component state changes.
+// The |timestamp| records the time of the state change.
+// |changed_properties| contains a property set with the new property values
+// which were updated at the time the event was recorded.
+struct ComponentStateChange {
+  ComponentStateChange(base::Time time,
+                       const std::string& path,
+                       std::unique_ptr<base::DictionaryValue> properties)
+      : timestamp{time}, component{path},
+        changed_properties{std::move(properties)} {}
+  base::Time timestamp;
+  std::string component;
+  std::unique_ptr<base::DictionaryValue> changed_properties;
+};
+
 class ComponentManager final {
  public:
+  using UpdateID = uint64_t;
+  using Token =
+      std::unique_ptr<base::CallbackList<void(UpdateID)>::Subscription>;
+  struct StateSnapshot {
+    UpdateID update_id;
+    std::vector<ComponentStateChange> state_changes;
+  };
+
   ComponentManager();
+  explicit ComponentManager(base::Clock* clock);
   ~ComponentManager();
 
   // Loads trait definition schema.
@@ -30,7 +58,7 @@
   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);
+  void AddTraitDefChangedCallback(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
@@ -51,6 +79,9 @@
                              const std::vector<std::string>& traits,
                              ErrorPtr* error);
 
+  // Sets callback which is called when new components are added.
+  void AddComponentTreeChangedCallback(const base::Closure& callback);
+
   // 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.
@@ -102,11 +133,49 @@
   // Returns the full JSON dictionary containing component instances.
   const base::DictionaryValue& GetComponents() const { return components_; }
 
+  // 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);
+
+  void AddStateChangedCallback(const base::Closure& callback);
+
+  // Returns the recorded state changes since last time this method was called.
+  StateSnapshot GetAndClearRecordedStateChanges();
+
+  // Called to notify that the state patch with |id| has been successfully sent
+  // to the server and processed.
+  void NotifyStateUpdatedOnServer(UpdateID id);
+
+  // Returns an ID of last state change update. Each SetStatePropertyNNN()
+  // invocation increments this value by 1.
+  UpdateID GetLastStateChangeId() const { 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);
+
  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.
@@ -115,13 +184,22 @@
       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::Callback<void()>> on_trait_changed_;
+  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(ComponentManager);
 };
 
diff --git a/src/component_manager_unittest.cc b/src/component_manager_unittest.cc
index ba6bc34..83f9933 100644
--- a/src/component_manager_unittest.cc
+++ b/src/component_manager_unittest.cc
@@ -30,6 +30,71 @@
   return false;
 }
 
+// Creates sample trait/component trees:
+// {
+//   "traits": {
+//     "t1": {},
+//     "t2": {},
+//     "t3": {},
+//     "t4": {},
+//     "t5": {},
+//     "t6": {},
+//   },
+//   "components": {
+//     "comp1": {
+//       "traits": [ "t1" ],
+//       "components": {
+//         "comp2": [
+//           { "traits": [ "t2" ] },
+//           {
+//             "traits": [ "t3" ],
+//             "components": {
+//               "comp3": {
+//                 "traits": [ "t4" ],
+//                 "components": {
+//                   "comp4": {
+//                     "traits": [ "t5", "t6" ]
+//                   }
+//                 }
+//               }
+//             }
+//           }
+//         ],
+//       }
+//     }
+//   }
+// }
+void CreateTestComponentTree(ComponentManager* manager) {
+  const char kTraits[] = R"({"t1":{},"t2":{},"t3":{},"t4":{},"t5":{},"t6":{}})";
+  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", "t6"}, nullptr));
+}
+
+// Test clock class to record predefined time intervals.
+// Implementation from base/test/simple_test_clock.{h|cc}
+class SimpleTestClock : public base::Clock {
+ public:
+  base::Time Now() override { return now_; }
+
+  // Advances the clock by |delta|.
+  void Advance(base::TimeDelta delta) { now_ += delta; }
+
+  // Sets the clock to the given time.
+  void SetNow(base::Time now) { now_ = now; }
+
+ private:
+  base::Time now_;
+};
+
 }  // anonymous namespace
 
 TEST(ComponentManager, Empty) {
@@ -176,6 +241,63 @@
   EXPECT_FALSE(manager.LoadTraits(*json, nullptr));
 }
 
+TEST(ComponentManager, AddTraitDefChangedCallback) {
+  ComponentManager manager;
+  int count = 0;
+  int count2 = 0;
+  manager.AddTraitDefChangedCallback(base::Bind([&count]() { count++; }));
+  manager.AddTraitDefChangedCallback(base::Bind([&count2]() { count2++; }));
+  EXPECT_EQ(1, count);
+  EXPECT_EQ(1, count2);
+  // New definitions.
+  const char kTraits1[] = R"({
+    "trait1": {
+      "state": {
+        "property1": {"type": "boolean"}
+      }
+    },
+    "trait2": {
+      "state": {
+        "property2": {"type": "string"}
+      }
+    }
+  })";
+  auto json = CreateDictionaryValue(kTraits1);
+  EXPECT_TRUE(manager.LoadTraits(*json, nullptr));
+  EXPECT_EQ(2, count);
+  // Duplicate definition, shouldn't call the callback.
+  const char kTraits2[] = R"({
+    "trait1": {
+      "state": {
+        "property1": {"type": "boolean"}
+      }
+    }
+  })";
+  json = CreateDictionaryValue(kTraits2);
+  EXPECT_TRUE(manager.LoadTraits(*json, nullptr));
+  EXPECT_EQ(2, count);
+  // New definition, should call the callback now.
+  const char kTraits3[] = R"({
+    "trait3": {
+      "state": {
+        "property3": {"type": "string"}
+      }
+    }
+  })";
+  json = CreateDictionaryValue(kTraits3);
+  EXPECT_TRUE(manager.LoadTraits(*json, nullptr));
+  EXPECT_EQ(3, count);
+  // Wrong definition, shouldn't call the callback.
+  const char kTraits4[] = R"({
+    "trait4": "foo"
+  })";
+  json = CreateDictionaryValue(kTraits4);
+  EXPECT_FALSE(manager.LoadTraits(*json, nullptr));
+  EXPECT_EQ(3, count);
+  // Make sure both callbacks were called the same number of times.
+  EXPECT_EQ(count2, count);
+}
+
 TEST(ComponentManager, LoadTraitsNotAnObject) {
   ComponentManager manager;
   const char kTraits1[] = R"({"trait1": 0})";
@@ -426,18 +548,32 @@
   EXPECT_FALSE(manager.AddComponent("comp1", "comp2", {}, nullptr));
 }
 
+TEST(ComponentManager, AddComponentTreeChangedCallback) {
+  ComponentManager manager;
+  int count = 0;
+  int count2 = 0;
+  manager.AddComponentTreeChangedCallback(base::Bind([&count]() { count++; }));
+  manager.AddComponentTreeChangedCallback(
+      base::Bind([&count2]() { count2++; }));
+  EXPECT_EQ(1, count);
+  EXPECT_EQ(1, count2);
+  EXPECT_TRUE(manager.AddComponent("", "comp1", {}, nullptr));
+  EXPECT_EQ(2, count);
+  EXPECT_TRUE(manager.AddComponent("comp1", "comp2", {}, nullptr));
+  EXPECT_EQ(3, count);
+  EXPECT_TRUE(manager.AddComponent("comp1.comp2", "comp4", {}, nullptr));
+  EXPECT_EQ(4, count);
+  EXPECT_TRUE(manager.AddComponentArrayItem("comp1", "comp3", {}, nullptr));
+  EXPECT_EQ(5, count);
+  EXPECT_TRUE(manager.AddComponentArrayItem("comp1", "comp3", {}, nullptr));
+  EXPECT_EQ(6, count);
+  // Make sure both callbacks were called the same number of times.
+  EXPECT_EQ(count2, count);
+}
+
 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));
+  CreateTestComponentTree(&manager);
 
   const base::DictionaryValue* comp = manager.FindComponent("comp1", nullptr);
   ASSERT_NE(nullptr, comp);
@@ -606,4 +742,347 @@
   last_tags.clear();
 }
 
+TEST(ComponentManager, SetStateProperties) {
+  ComponentManager manager;
+  CreateTestComponentTree(&manager);
+
+  const char kState1[] = R"({"t1": {"p1": 0, "p2": "foo"}})";
+  auto state1 = CreateDictionaryValue(kState1);
+  ASSERT_TRUE(manager.SetStateProperties("comp1", *state1, nullptr));
+  const char kExpected1[] = R"({
+    "comp1": {
+      "traits": [ "t1" ],
+      "state": {"t1": {"p1": 0, "p2": "foo"}},
+      "components": {
+        "comp2": [
+          {
+            "traits": [ "t2" ]
+          },
+          {
+            "traits": [ "t3" ],
+            "components": {
+              "comp3": {
+                "traits": [ "t4" ],
+                "components": {
+                  "comp4": {
+                    "traits": [ "t5", "t6" ]
+                  }
+                }
+              }
+            }
+          }
+        ]
+      }
+    }
+  })";
+  EXPECT_JSON_EQ(kExpected1, manager.GetComponents());
+
+  const char kState2[] = R"({"t1": {"p1": {"bar": "baz"}}})";
+  auto state2 = CreateDictionaryValue(kState2);
+  ASSERT_TRUE(manager.SetStateProperties("comp1", *state2, nullptr));
+
+  const char kExpected2[] = R"({
+    "comp1": {
+      "traits": [ "t1" ],
+      "state": {"t1": {"p1": {"bar": "baz"}, "p2": "foo"}},
+      "components": {
+        "comp2": [
+          {
+            "traits": [ "t2" ]
+          },
+          {
+            "traits": [ "t3" ],
+            "components": {
+              "comp3": {
+                "traits": [ "t4" ],
+                "components": {
+                  "comp4": {
+                    "traits": [ "t5", "t6" ]
+                  }
+                }
+              }
+            }
+          }
+        ]
+      }
+    }
+  })";
+  EXPECT_JSON_EQ(kExpected2, manager.GetComponents());
+
+  const char kState3[] = R"({"t5": {"p1": 1}})";
+  auto state3 = CreateDictionaryValue(kState3);
+  ASSERT_TRUE(manager.SetStateProperties("comp1.comp2[1].comp3.comp4", *state3,
+                                         nullptr));
+
+  const char kExpected3[] = R"({
+    "comp1": {
+      "traits": [ "t1" ],
+      "state": {"t1": {"p1": {"bar": "baz"}, "p2": "foo"}},
+      "components": {
+        "comp2": [
+          {
+            "traits": [ "t2" ]
+          },
+          {
+            "traits": [ "t3" ],
+            "components": {
+              "comp3": {
+                "traits": [ "t4" ],
+                "components": {
+                  "comp4": {
+                    "traits": [ "t5", "t6" ],
+                    "state": { "t5": { "p1": 1 } }
+                  }
+                }
+              }
+            }
+          }
+        ]
+      }
+    }
+  })";
+  EXPECT_JSON_EQ(kExpected3, manager.GetComponents());
+}
+
+TEST(ComponentManager, SetStatePropertiesFromJson) {
+  ComponentManager manager;
+  CreateTestComponentTree(&manager);
+
+  ASSERT_TRUE(manager.SetStatePropertiesFromJson(
+      "comp1.comp2[1].comp3.comp4", R"({"t5": {"p1": 3}, "t6": {"p2": 5}})",
+      nullptr));
+
+  const char kExpected[] = R"({
+    "comp1": {
+      "traits": [ "t1" ],
+      "components": {
+        "comp2": [
+          {
+            "traits": [ "t2" ]
+          },
+          {
+            "traits": [ "t3" ],
+            "components": {
+              "comp3": {
+                "traits": [ "t4" ],
+                "components": {
+                  "comp4": {
+                    "traits": [ "t5", "t6" ],
+                    "state": {
+                      "t5": { "p1": 3 },
+                      "t6": { "p2": 5 }
+                    }
+                  }
+                }
+              }
+            }
+          }
+        ]
+      }
+    }
+  })";
+  EXPECT_JSON_EQ(kExpected, manager.GetComponents());
+}
+
+TEST(ComponentManager, SetGetStateProperty) {
+  ComponentManager manager;
+  const char kTraits[] = R"({
+    "trait1": {
+      "state": {
+        "prop1": { "type": "string" },
+        "prop2": { "type": "integer" }
+      }
+    },
+    "trait2": {
+      "state": {
+        "prop3": { "type": "string" },
+        "prop4": { "type": "string" }
+      }
+    }
+  })";
+  auto traits = CreateDictionaryValue(kTraits);
+  ASSERT_TRUE(manager.LoadTraits(*traits, nullptr));
+  ASSERT_TRUE(manager.AddComponent("", "comp1", {"trait1", "trait2"}, nullptr));
+
+  base::StringValue p1("foo");
+  ASSERT_TRUE(manager.SetStateProperty("comp1", "trait1.prop1", p1, nullptr));
+
+  const char kExpected1[] = R"({
+    "comp1": {
+      "traits": [ "trait1", "trait2" ],
+      "state": {
+        "trait1": { "prop1": "foo" }
+      }
+    }
+  })";
+  EXPECT_JSON_EQ(kExpected1, manager.GetComponents());
+
+  base::FundamentalValue p2(2);
+  ASSERT_TRUE(manager.SetStateProperty("comp1", "trait2.prop3", p2, nullptr));
+
+  const char kExpected2[] = R"({
+    "comp1": {
+      "traits": [ "trait1", "trait2" ],
+      "state": {
+        "trait1": { "prop1": "foo" },
+        "trait2": { "prop3": 2 }
+      }
+    }
+  })";
+  EXPECT_JSON_EQ(kExpected2, manager.GetComponents());
+  // Just the package name without property:
+  EXPECT_FALSE(manager.SetStateProperty("comp1", "trait2", p2, nullptr));
+
+  const base::Value* value = manager.GetStateProperty("comp1", "trait1.prop1",
+                                                      nullptr);
+  ASSERT_NE(nullptr, value);
+  EXPECT_TRUE(p1.Equals(value));
+  value = manager.GetStateProperty("comp1", "trait2.prop3", nullptr);
+  ASSERT_NE(nullptr, value);
+  EXPECT_TRUE(p2.Equals(value));
+
+  // Non-existing property:
+  EXPECT_EQ(nullptr, manager.GetStateProperty("comp1", "trait2.p", nullptr));
+  // Non-existing component
+  EXPECT_EQ(nullptr, manager.GetStateProperty("comp2", "trait.prop", nullptr));
+  // Just the package name without property:
+  EXPECT_EQ(nullptr, manager.GetStateProperty("comp1", "trait2", nullptr));
+}
+
+TEST(ComponentManager, AddStateChangedCallback) {
+  SimpleTestClock clock;
+  ComponentManager manager{&clock};
+  const char kTraits[] = R"({
+    "trait1": {
+      "state": {
+        "prop1": { "type": "string" },
+        "prop2": { "type": "string" }
+      }
+    }
+  })";
+  auto traits = CreateDictionaryValue(kTraits);
+  ASSERT_TRUE(manager.LoadTraits(*traits, nullptr));
+  ASSERT_TRUE(manager.AddComponent("", "comp1", {"trait1"}, nullptr));
+
+  int count = 0;
+  int count2 = 0;
+  manager.AddStateChangedCallback(base::Bind([&count]() { count++; }));
+  manager.AddStateChangedCallback(base::Bind([&count2]() { count2++; }));
+  EXPECT_EQ(1, count);
+  EXPECT_EQ(1, count2);
+  EXPECT_EQ(0, manager.GetLastStateChangeId());
+
+  base::StringValue p1("foo");
+  ASSERT_TRUE(manager.SetStateProperty("comp1", "trait1.prop1", p1, nullptr));
+  EXPECT_EQ(2, count);
+  EXPECT_EQ(2, count2);
+  EXPECT_EQ(1, manager.GetLastStateChangeId());
+
+  ASSERT_TRUE(manager.SetStateProperty("comp1", "trait1.prop2", p1, nullptr));
+  EXPECT_EQ(3, count);
+  EXPECT_EQ(3, count2);
+  EXPECT_EQ(2, manager.GetLastStateChangeId());
+
+  // Fail - no component.
+  ASSERT_FALSE(manager.SetStateProperty("comp2", "trait1.prop2", p1, nullptr));
+  EXPECT_EQ(3, count);
+  EXPECT_EQ(3, count2);
+  EXPECT_EQ(2, manager.GetLastStateChangeId());
+}
+
+TEST(ComponentManager, ComponentStateUpdates) {
+  SimpleTestClock clock;
+  ComponentManager manager{&clock};
+  const char kTraits[] = R"({
+    "trait1": {
+      "state": {
+        "prop1": { "type": "string" },
+        "prop2": { "type": "string" }
+      }
+    },
+    "trait2": {
+      "state": {
+        "prop3": { "type": "string" },
+        "prop4": { "type": "string" }
+      }
+    }
+  })";
+  auto traits = CreateDictionaryValue(kTraits);
+  ASSERT_TRUE(manager.LoadTraits(*traits, nullptr));
+  ASSERT_TRUE(manager.AddComponent("", "comp1", {"trait1", "trait2"}, nullptr));
+  ASSERT_TRUE(manager.AddComponent("", "comp2", {"trait1", "trait2"}, nullptr));
+
+  std::vector<ComponentManager::UpdateID> updates1;
+  auto callback1 = [&updates1](ComponentManager::UpdateID id) {
+    updates1.push_back(id);
+  };
+  // State change queue is empty, callback should be called immediately.
+  auto token1 = manager.AddServerStateUpdatedCallback(base::Bind(callback1));
+  ASSERT_EQ(1u, updates1.size());
+  EXPECT_EQ(manager.GetLastStateChangeId(), updates1.front());
+  updates1.clear();
+
+  base::StringValue foo("foo");
+  base::Time time1 = base::Time::Now();
+  clock.SetNow(time1);
+  // These three updates should be grouped into two separate state change queue
+  // items, since they all happen at the same time, but for two different
+  // components.
+  ASSERT_TRUE(manager.SetStateProperty("comp1", "trait1.prop1", foo, nullptr));
+  ASSERT_TRUE(manager.SetStateProperty("comp2", "trait2.prop3", foo, nullptr));
+  ASSERT_TRUE(manager.SetStateProperty("comp1", "trait1.prop2", foo, nullptr));
+
+  std::vector<ComponentManager::UpdateID> updates2;
+  auto callback2 = [&updates2](ComponentManager::UpdateID id) {
+    updates2.push_back(id);
+  };
+  // State change queue is not empty, so callback will be called later.
+  auto token2 = manager.AddServerStateUpdatedCallback(base::Bind(callback2));
+  EXPECT_TRUE(updates2.empty());
+
+  base::StringValue bar("bar");
+  base::Time time2 = time1 + base::TimeDelta::FromSeconds(1);
+  clock.SetNow(time2);
+  // Two more update events (as above) but at |time2|.
+  ASSERT_TRUE(manager.SetStateProperty("comp1", "trait1.prop1", bar, nullptr));
+  ASSERT_TRUE(manager.SetStateProperty("comp2", "trait2.prop3", bar, nullptr));
+  ASSERT_TRUE(manager.SetStateProperty("comp1", "trait1.prop2", bar, nullptr));
+
+  auto snapshot = manager.GetAndClearRecordedStateChanges();
+  EXPECT_EQ(manager.GetLastStateChangeId(), snapshot.update_id);
+  ASSERT_EQ(4u, snapshot.state_changes.size());
+
+  EXPECT_EQ("comp1", snapshot.state_changes[0].component);
+  EXPECT_EQ(time1, snapshot.state_changes[0].timestamp);
+  EXPECT_JSON_EQ(R"({"trait1":{"prop1":"foo","prop2":"foo"}})",
+                 *snapshot.state_changes[0].changed_properties);
+
+  EXPECT_EQ("comp2", snapshot.state_changes[1].component);
+  EXPECT_EQ(time1, snapshot.state_changes[1].timestamp);
+  EXPECT_JSON_EQ(R"({"trait2":{"prop3":"foo"}})",
+                 *snapshot.state_changes[1].changed_properties);
+
+  EXPECT_EQ("comp1", snapshot.state_changes[2].component);
+  EXPECT_EQ(time2, snapshot.state_changes[2].timestamp);
+  EXPECT_JSON_EQ(R"({"trait1":{"prop1":"bar","prop2":"bar"}})",
+                 *snapshot.state_changes[2].changed_properties);
+
+  EXPECT_EQ("comp2", snapshot.state_changes[3].component);
+  EXPECT_EQ(time2, snapshot.state_changes[3].timestamp);
+  EXPECT_JSON_EQ(R"({"trait2":{"prop3":"bar"}})",
+                 *snapshot.state_changes[3].changed_properties);
+
+  // Make sure previous GetAndClearRecordedStateChanges() clears the queue.
+  auto snapshot2 = manager.GetAndClearRecordedStateChanges();
+  EXPECT_EQ(manager.GetLastStateChangeId(), snapshot2.update_id);
+  EXPECT_TRUE(snapshot2.state_changes.empty());
+
+  // Now indicate that we have update the changes on the server.
+  manager.NotifyStateUpdatedOnServer(snapshot.update_id);
+  ASSERT_EQ(1u, updates1.size());
+  EXPECT_EQ(snapshot.update_id, updates1.front());
+  ASSERT_EQ(1u, updates2.size());
+  EXPECT_EQ(snapshot.update_id, updates2.front());
+}
+
 }  // namespace weave
