diff --git a/src/base_api_handler_unittest.cc b/src/base_api_handler_unittest.cc
index df78319..357385d 100644
--- a/src/base_api_handler_unittest.cc
+++ b/src/base_api_handler_unittest.cc
@@ -10,9 +10,9 @@
 #include <weave/provider/test/mock_config_store.h>
 #include <weave/provider/test/mock_http_client.h>
 #include <weave/test/mock_device.h>
+#include <weave/test/unittest_utils.h>
 
 #include "src/commands/command_manager.h"
-#include "src/commands/unittest_utils.h"
 #include "src/config.h"
 #include "src/device_registration_info.h"
 #include "src/states/mock_state_change_queue_interface.h"
diff --git a/src/commands/cloud_command_proxy.cc b/src/commands/cloud_command_proxy.cc
index 9ec3d3e..91db18c 100644
--- a/src/commands/cloud_command_proxy.cc
+++ b/src/commands/cloud_command_proxy.cc
@@ -9,8 +9,6 @@
 #include <weave/provider/task_runner.h>
 
 #include "src/commands/command_instance.h"
-#include "src/commands/prop_constraints.h"
-#include "src/commands/prop_types.h"
 #include "src/commands/schema_constants.h"
 #include "src/utils.h"
 
diff --git a/src/commands/cloud_command_proxy_unittest.cc b/src/commands/cloud_command_proxy_unittest.cc
index fdb22fc..a65a967 100644
--- a/src/commands/cloud_command_proxy_unittest.cc
+++ b/src/commands/cloud_command_proxy_unittest.cc
@@ -10,10 +10,10 @@
 #include <gmock/gmock.h>
 #include <gtest/gtest.h>
 #include <weave/provider/test/fake_task_runner.h>
+#include <weave/test/unittest_utils.h>
 
 #include "src/commands/command_dictionary.h"
 #include "src/commands/command_instance.h"
-#include "src/commands/unittest_utils.h"
 #include "src/states/mock_state_change_queue_interface.h"
 
 using testing::_;
diff --git a/src/commands/command_definition_unittest.cc b/src/commands/command_definition_unittest.cc
index ecd6e54..867d48f 100644
--- a/src/commands/command_definition_unittest.cc
+++ b/src/commands/command_definition_unittest.cc
@@ -5,8 +5,7 @@
 #include "src/commands/command_definition.h"
 
 #include <gtest/gtest.h>
-
-#include "src/commands/unittest_utils.h"
+#include <weave/test/unittest_utils.h>
 
 namespace weave {
 
diff --git a/src/commands/command_dictionary_unittest.cc b/src/commands/command_dictionary_unittest.cc
index 7298363..adae4ec 100644
--- a/src/commands/command_dictionary_unittest.cc
+++ b/src/commands/command_dictionary_unittest.cc
@@ -5,8 +5,7 @@
 #include "src/commands/command_dictionary.h"
 
 #include <gtest/gtest.h>
-
-#include "src/commands/unittest_utils.h"
+#include <weave/test/unittest_utils.h>
 
 namespace weave {
 
diff --git a/src/commands/command_instance.h b/src/commands/command_instance.h
index 30ef907..e7a6eca 100644
--- a/src/commands/command_instance.h
+++ b/src/commands/command_instance.h
@@ -15,9 +15,6 @@
 #include <weave/error.h>
 #include <weave/command.h>
 
-#include "src/commands/prop_values.h"
-#include "src/commands/schema_utils.h"
-
 namespace base {
 class Value;
 }  // namespace base
diff --git a/src/commands/command_instance_unittest.cc b/src/commands/command_instance_unittest.cc
index cacb86c..1d32cd9 100644
--- a/src/commands/command_instance_unittest.cc
+++ b/src/commands/command_instance_unittest.cc
@@ -5,9 +5,9 @@
 #include "src/commands/command_instance.h"
 
 #include <gtest/gtest.h>
+#include <weave/test/unittest_utils.h>
 
 #include "src/commands/command_dictionary.h"
-#include "src/commands/unittest_utils.h"
 
 namespace weave {
 
diff --git a/src/commands/command_manager_unittest.cc b/src/commands/command_manager_unittest.cc
index 2b2b055..f0dc95d 100644
--- a/src/commands/command_manager_unittest.cc
+++ b/src/commands/command_manager_unittest.cc
@@ -9,9 +9,9 @@
 #include <base/json/json_writer.h>
 #include <gtest/gtest.h>
 #include <weave/provider/test/mock_config_store.h>
+#include <weave/test/unittest_utils.h>
 
 #include "src/bind_lambda.h"
-#include "src/commands/unittest_utils.h"
 
 using testing::Return;
 
diff --git a/src/commands/command_queue_unittest.cc b/src/commands/command_queue_unittest.cc
index 394ae20..dc7290a 100644
--- a/src/commands/command_queue_unittest.cc
+++ b/src/commands/command_queue_unittest.cc
@@ -13,7 +13,6 @@
 #include <gtest/gtest.h>
 
 #include "src/commands/command_definition.h"
-#include "src/commands/object_schema.h"
 #include "src/string_utils.h"
 
 namespace weave {
diff --git a/src/commands/object_schema.cc b/src/commands/object_schema.cc
deleted file mode 100644
index 6cfa5f4..0000000
--- a/src/commands/object_schema.cc
+++ /dev/null
@@ -1,379 +0,0 @@
-// 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/commands/object_schema.h"
-
-#include <algorithm>
-#include <limits>
-
-#include <base/logging.h>
-#include <base/values.h>
-#include <weave/enum_to_string.h>
-
-#include "src/commands/prop_types.h"
-#include "src/commands/prop_values.h"
-#include "src/commands/schema_constants.h"
-#include "src/string_utils.h"
-
-namespace weave {
-
-namespace {
-
-// Helper function for to create a PropType based on type string.
-// Generates an error if the string identifies an unknown type.
-std::unique_ptr<PropType> CreatePropType(const std::string& type_name,
-                                         ErrorPtr* error) {
-  auto parts = SplitAtFirst(type_name, ".", false);
-  const std::string& primary_type = parts.first;
-  const std::string& array_type = parts.second;
-
-  std::unique_ptr<PropType> prop;
-  ValueType type;
-  if (PropType::GetTypeFromTypeString(primary_type, &type)) {
-    prop = PropType::Create(type);
-    if (prop && type == ValueType::Array && !array_type.empty()) {
-      auto items_type = CreatePropType(array_type, error);
-      if (items_type) {
-        prop->GetArray()->SetItemType(std::move(items_type));
-      } else {
-        prop.reset();
-        return prop;
-      }
-    }
-  }
-  if (!prop) {
-    Error::AddToPrintf(error, FROM_HERE, errors::commands::kDomain,
-                       errors::commands::kUnknownType, "Unknown type %s",
-                       type_name.c_str());
-  }
-  return prop;
-}
-
-// Generates "no_type_info" error.
-void ErrorInvalidTypeInfo(ErrorPtr* error) {
-  Error::AddTo(error, FROM_HERE, errors::commands::kDomain,
-               errors::commands::kNoTypeInfo,
-               "Unable to determine parameter type");
-}
-
-// Helper function for PropFromJson to handle the case of parameter being
-// defined as a JSON string like this:
-//   "prop":"..."
-std::unique_ptr<PropType> PropFromJsonString(const base::Value& value,
-                                             const PropType* base_schema,
-                                             ErrorPtr* error) {
-  std::string type_name;
-  CHECK(value.GetAsString(&type_name)) << "Unable to get string value";
-  std::unique_ptr<PropType> prop = CreatePropType(type_name, error);
-  base::DictionaryValue empty;
-  if (prop && !prop->FromJson(&empty, base_schema, error))
-    prop.reset();
-
-  return prop;
-}
-
-// Detects a type based on JSON array. Inspects the first element of the array
-// to deduce the PropType from. Returns the string name of the type detected
-// or empty string is type detection failed.
-std::string DetectArrayType(const base::ListValue* list,
-                            const PropType* base_schema,
-                            bool allow_arrays) {
-  std::string type_name;
-  if (base_schema) {
-    type_name = base_schema->GetTypeAsString();
-  } else if (list->GetSize() > 0) {
-    const base::Value* first_element = nullptr;
-    if (list->Get(0, &first_element)) {
-      switch (first_element->GetType()) {
-        case base::Value::TYPE_BOOLEAN:
-          type_name = PropType::GetTypeStringFromType(ValueType::Boolean);
-          break;
-        case base::Value::TYPE_INTEGER:
-          type_name = PropType::GetTypeStringFromType(ValueType::Int);
-          break;
-        case base::Value::TYPE_DOUBLE:
-          type_name = PropType::GetTypeStringFromType(ValueType::Double);
-          break;
-        case base::Value::TYPE_STRING:
-          type_name = PropType::GetTypeStringFromType(ValueType::String);
-          break;
-        case base::Value::TYPE_DICTIONARY:
-          type_name = PropType::GetTypeStringFromType(ValueType::Object);
-          break;
-        case base::Value::TYPE_LIST: {
-          if (allow_arrays) {
-            type_name = PropType::GetTypeStringFromType(ValueType::Array);
-            const base::ListValue* first_element_list = nullptr;
-            if (first_element->GetAsList(&first_element_list)) {
-              // We do not allow arrays of arrays.
-              auto child_type =
-                  DetectArrayType(first_element_list, nullptr, false);
-              if (child_type.empty()) {
-                type_name.clear();
-              } else {
-                type_name += '.' + child_type;
-              }
-            }
-          }
-          break;
-        }
-        default:
-          // The rest are unsupported.
-          break;
-      }
-    }
-  }
-  return type_name;
-}
-
-// Helper function for PropFromJson to handle the case of parameter being
-// defined as a JSON array like this:
-//   "prop":[...]
-std::unique_ptr<PropType> PropFromJsonArray(const base::Value& value,
-                                            const PropType* base_schema,
-                                            ErrorPtr* error) {
-  std::unique_ptr<PropType> prop;
-  const base::ListValue* list = nullptr;
-  CHECK(value.GetAsList(&list)) << "Unable to get array value";
-  std::string type_name = DetectArrayType(list, base_schema, true);
-  if (type_name.empty()) {
-    ErrorInvalidTypeInfo(error);
-    return prop;
-  }
-  base::DictionaryValue array_object;
-  array_object.SetWithoutPathExpansion(commands::attributes::kOneOf_Enum,
-                                       list->DeepCopy());
-  prop = CreatePropType(type_name, error);
-  if (prop && !prop->FromJson(&array_object, base_schema, error))
-    prop.reset();
-
-  return prop;
-}
-
-// Detects a type based on JSON object definition of type. Looks at various
-// members such as minimum/maximum constraints, default and enum values to
-// try to deduce the underlying type of the element. Returns the string name of
-// the type detected or empty string is type detection failed.
-std::string DetectObjectType(const base::DictionaryValue* dict,
-                             const PropType* base_schema) {
-  bool has_min_max = dict->HasKey(commands::attributes::kNumeric_Min) ||
-                     dict->HasKey(commands::attributes::kNumeric_Max);
-
-  // Here we are trying to "detect the type and read in the object based on
-  // the deduced type". Later, we'll verify that this detected type matches
-  // the expectation of the base schema, if applicable, to make sure we are not
-  // changing the expected type. This makes the vendor-side (re)definition of
-  // standard and custom commands behave exactly the same.
-  // The only problem with this approach was the double-vs-int types.
-  // If the type is meant to be a double we want to allow its definition as
-  // "min:0, max:0" instead of just forcing it to be only "min:0.0, max:0.0".
-  // If we have "minimum" or "maximum", and we have a Double schema object,
-  // treat this object as a Double (even if both min and max are integers).
-  if (has_min_max && base_schema && base_schema->GetType() == ValueType::Double)
-    return PropType::GetTypeStringFromType(ValueType::Double);
-
-  // If we have at least one "minimum" or "maximum" that is Double,
-  // it's a Double.
-  const base::Value* value = nullptr;
-  if (dict->Get(commands::attributes::kNumeric_Min, &value) &&
-      value->IsType(base::Value::TYPE_DOUBLE))
-    return PropType::GetTypeStringFromType(ValueType::Double);
-  if (dict->Get(commands::attributes::kNumeric_Max, &value) &&
-      value->IsType(base::Value::TYPE_DOUBLE))
-    return PropType::GetTypeStringFromType(ValueType::Double);
-
-  // If we have "minimum" or "maximum", it's an Integer.
-  if (has_min_max)
-    return PropType::GetTypeStringFromType(ValueType::Int);
-
-  // If we have "minLength" or "maxLength", it's a String.
-  if (dict->HasKey(commands::attributes::kString_MinLength) ||
-      dict->HasKey(commands::attributes::kString_MaxLength))
-    return PropType::GetTypeStringFromType(ValueType::String);
-
-  // If we have "properties", it's an object.
-  if (dict->HasKey(commands::attributes::kObject_Properties))
-    return PropType::GetTypeStringFromType(ValueType::Object);
-
-  // If we have "items", it's an array.
-  if (dict->HasKey(commands::attributes::kItems))
-    return PropType::GetTypeStringFromType(ValueType::Array);
-
-  // If we have "enum", it's an array. Detect type from array elements.
-  const base::ListValue* list = nullptr;
-  if (dict->GetListWithoutPathExpansion(commands::attributes::kOneOf_Enum,
-                                        &list))
-    return DetectArrayType(list, base_schema, true);
-
-  // If we have "default", try to use it for type detection.
-  if (dict->Get(commands::attributes::kDefault, &value)) {
-    if (value->IsType(base::Value::TYPE_DOUBLE))
-      return PropType::GetTypeStringFromType(ValueType::Double);
-    if (value->IsType(base::Value::TYPE_INTEGER))
-      return PropType::GetTypeStringFromType(ValueType::Int);
-    if (value->IsType(base::Value::TYPE_BOOLEAN))
-      return PropType::GetTypeStringFromType(ValueType::Boolean);
-    if (value->IsType(base::Value::TYPE_STRING))
-      return PropType::GetTypeStringFromType(ValueType::String);
-    if (value->IsType(base::Value::TYPE_LIST)) {
-      CHECK(value->GetAsList(&list)) << "List value expected";
-      std::string child_type = DetectArrayType(list, base_schema, false);
-      if (!child_type.empty()) {
-        return PropType::GetTypeStringFromType(ValueType::Array) + '.' +
-               child_type;
-      }
-    }
-  }
-
-  return std::string{};
-}
-
-// Helper function for PropFromJson to handle the case of parameter being
-// defined as a JSON object like this:
-//   "prop":{...}
-std::unique_ptr<PropType> PropFromJsonObject(const base::Value& value,
-                                             const PropType* base_schema,
-                                             ErrorPtr* error) {
-  std::unique_ptr<PropType> prop;
-  const base::DictionaryValue* dict = nullptr;
-  CHECK(value.GetAsDictionary(&dict)) << "Unable to get dictionary value";
-  std::string type_name;
-  if (dict->HasKey(commands::attributes::kType)) {
-    if (!dict->GetString(commands::attributes::kType, &type_name)) {
-      ErrorInvalidTypeInfo(error);
-      return prop;
-    }
-  } else {
-    type_name = DetectObjectType(dict, base_schema);
-  }
-  if (type_name.empty()) {
-    if (!base_schema) {
-      ErrorInvalidTypeInfo(error);
-      return prop;
-    }
-    type_name = base_schema->GetTypeAsString();
-  }
-  prop = CreatePropType(type_name, error);
-  if (prop && !prop->FromJson(dict, base_schema, error))
-    prop.reset();
-
-  return prop;
-}
-
-const EnumToStringMap<base::Value::Type>::Map kMap[] = {
-    {base::Value::TYPE_NULL, "Null"},
-    {base::Value::TYPE_BOOLEAN, "Boolean"},
-    {base::Value::TYPE_INTEGER, "Integer"},
-    {base::Value::TYPE_DOUBLE, "Double"},
-    {base::Value::TYPE_STRING, "String"},
-    {base::Value::TYPE_BINARY, "Binary"},
-    {base::Value::TYPE_DICTIONARY, "Object"},
-    {base::Value::TYPE_LIST, "Array"},
-};
-
-}  // anonymous namespace
-
-template <>
-EnumToStringMap<base::Value::Type>::EnumToStringMap() : EnumToStringMap(kMap) {}
-
-ObjectSchema::ObjectSchema() {}
-ObjectSchema::~ObjectSchema() {}
-
-std::unique_ptr<ObjectSchema> ObjectSchema::Clone() const {
-  std::unique_ptr<ObjectSchema> cloned{new ObjectSchema};
-  for (const auto& pair : properties_) {
-    cloned->properties_.insert(
-        std::make_pair(pair.first, pair.second->Clone()));
-  }
-  cloned->extra_properties_allowed_ = extra_properties_allowed_;
-  return cloned;
-}
-
-void ObjectSchema::AddProp(const std::string& name,
-                           std::unique_ptr<PropType> prop) {
-  // Not using emplace() here to make sure we override existing properties.
-  properties_[name] = std::move(prop);
-}
-
-const PropType* ObjectSchema::GetProp(const std::string& name) const {
-  auto p = properties_.find(name);
-  return p != properties_.end() ? p->second.get() : nullptr;
-}
-
-bool ObjectSchema::MarkPropRequired(const std::string& name, ErrorPtr* error) {
-  auto p = properties_.find(name);
-  if (p == properties_.end()) {
-    Error::AddToPrintf(error, FROM_HERE, errors::commands::kDomain,
-                       errors::commands::kUnknownProperty,
-                       "Unknown property '%s'", name.c_str());
-    return false;
-  }
-  p->second->MakeRequired(true);
-  return true;
-}
-
-std::unique_ptr<base::DictionaryValue> ObjectSchema::ToJson(
-    bool full_schema,
-    bool in_command_def) const {
-  std::unique_ptr<base::DictionaryValue> value(new base::DictionaryValue);
-  for (const auto& pair : properties_) {
-    auto prop_def = pair.second->ToJson(full_schema, in_command_def);
-    CHECK(prop_def);
-    value->SetWithoutPathExpansion(pair.first, prop_def.release());
-  }
-  return value;
-}
-
-bool ObjectSchema::FromJson(const base::DictionaryValue* value,
-                            const ObjectSchema* object_schema,
-                            ErrorPtr* error) {
-  Properties properties;
-  base::DictionaryValue::Iterator iter(*value);
-  while (!iter.IsAtEnd()) {
-    std::string name = iter.key();
-    const PropType* base_schema =
-        object_schema ? object_schema->GetProp(iter.key()) : nullptr;
-    auto prop_type = PropFromJson(iter.value(), base_schema, error);
-    if (prop_type) {
-      properties.insert(std::make_pair(iter.key(), std::move(prop_type)));
-    } else {
-      Error::AddToPrintf(error, FROM_HERE, errors::commands::kDomain,
-                         errors::commands::kInvalidPropDef,
-                         "Error in definition of property '%s'",
-                         iter.key().c_str());
-      return false;
-    }
-    iter.Advance();
-  }
-  properties_ = std::move(properties);
-  return true;
-}
-
-std::unique_ptr<PropType> ObjectSchema::PropFromJson(
-    const base::Value& value,
-    const PropType* base_schema,
-    ErrorPtr* error) {
-  if (value.IsType(base::Value::TYPE_STRING)) {
-    // A string value is a short-hand object specification and provides
-    // the parameter type.
-    return PropFromJsonString(value, base_schema, error);
-  } else if (value.IsType(base::Value::TYPE_LIST)) {
-    // One of the enumerated types.
-    return PropFromJsonArray(value, base_schema, error);
-  } else if (value.IsType(base::Value::TYPE_DICTIONARY)) {
-    // Full parameter definition.
-    return PropFromJsonObject(value, base_schema, error);
-  }
-  Error::AddToPrintf(error, FROM_HERE, errors::commands::kDomain,
-                     errors::commands::kUnknownType,
-                     "Unexpected JSON value type: %s",
-                     EnumToString(value.GetType()).c_str());
-  return nullptr;
-}
-
-std::unique_ptr<ObjectSchema> ObjectSchema::Create() {
-  return std::unique_ptr<ObjectSchema>{new ObjectSchema};
-}
-
-}  // namespace weave
diff --git a/src/commands/object_schema.h b/src/commands/object_schema.h
deleted file mode 100644
index 504e1dd..0000000
--- a/src/commands/object_schema.h
+++ /dev/null
@@ -1,95 +0,0 @@
-// 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_COMMANDS_OBJECT_SCHEMA_H_
-#define LIBWEAVE_SRC_COMMANDS_OBJECT_SCHEMA_H_
-
-#include <map>
-#include <memory>
-#include <string>
-
-#include <weave/error.h>
-
-namespace base {
-class Value;
-class DictionaryValue;
-}  // namespace base
-
-namespace weave {
-
-class PropType;
-
-// ObjectSchema is a class representing an object definition in GCD command
-// schema. This could represent a GCD command definition, but also it can be
-// used when defining custom object types for command properties such as
-// output media type (paper) for print command. The schema definition for
-// these type of object description is the same.
-class ObjectSchema final {
- public:
-  // Do not inline the constructor/destructor to allow forward-declared type
-  // PropType to be part of |properties_| member.
-  ObjectSchema();
-  ~ObjectSchema();
-
-  // Properties is a string-to-PropType map representing a list of
-  // properties defined for a command/object. The key is the parameter
-  // name and the value is the parameter type definition object.
-  using Properties = std::map<std::string, std::unique_ptr<PropType>>;
-
-  // Makes a full copy of this object.
-  virtual std::unique_ptr<ObjectSchema> Clone() const;
-
-  // Add a new parameter definition.
-  void AddProp(const std::string& name, std::unique_ptr<PropType> prop);
-
-  // Finds parameter type definition by name. Returns nullptr if not found.
-  const PropType* GetProp(const std::string& name) const;
-
-  // Gets the list of all the properties defined.
-  const Properties& GetProps() const { return properties_; }
-
-  // Marks the property with given name as "required". If |name| specifies
-  // an unknown property, false is returned and |error| is set with detailed
-  // error message for the failure.
-  bool MarkPropRequired(const std::string& name, ErrorPtr* error);
-
-  // Specify whether extra properties are allowed on objects described by
-  // this schema. When validating a value of an object type, we can
-  // make sure that the value has only the properties explicitly defined by
-  // the schema and no other (custom) properties are allowed.
-  // This is to support JSON Schema's "additionalProperties" specification.
-  bool GetExtraPropertiesAllowed() const { return extra_properties_allowed_; }
-  void SetExtraPropertiesAllowed(bool allowed) {
-    extra_properties_allowed_ = allowed;
-  }
-
-  // Saves the object schema to JSON. When |full_schema| is set to true,
-  // then all properties and constraints are saved, otherwise, only
-  // the overridden (not inherited) ones are saved.
-  std::unique_ptr<base::DictionaryValue> ToJson(bool full_schema,
-                                                bool in_command_def) const;
-
-  // Loads the object schema from JSON. If |object_schema| is not nullptr, it is
-  // used as a base schema to inherit omitted properties and constraints from.
-  bool FromJson(const base::DictionaryValue* value,
-                const ObjectSchema* object_schema,
-                ErrorPtr* error);
-
-  // Helper factory method to create a new instance of ObjectSchema object.
-  static std::unique_ptr<ObjectSchema> Create();
-
-  // Helper method to load property type definitions from JSON.
-  static std::unique_ptr<PropType> PropFromJson(const base::Value& value,
-                                                const PropType* base_schema,
-                                                ErrorPtr* error);
-
- private:
-  // Internal parameter type definition map.
-  Properties properties_;
-  bool extra_properties_allowed_{false};
-};
-
-}  // namespace weave
-
-#endif  // LIBWEAVE_SRC_COMMANDS_OBJECT_SCHEMA_H_
diff --git a/src/commands/object_schema_unittest.cc b/src/commands/object_schema_unittest.cc
deleted file mode 100644
index 7cdc16d..0000000
--- a/src/commands/object_schema_unittest.cc
+++ /dev/null
@@ -1,1697 +0,0 @@
-// 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/commands/object_schema.h"
-
-#include <algorithm>
-#include <limits>
-#include <memory>
-#include <vector>
-
-#include <base/json/json_reader.h>
-#include <base/json/json_writer.h>
-#include <base/values.h>
-#include <gtest/gtest.h>
-
-#include "src/commands/prop_constraints.h"
-#include "src/commands/prop_types.h"
-#include "src/commands/schema_constants.h"
-#include "src/commands/unittest_utils.h"
-
-namespace weave {
-
-using test::CreateValue;
-using test::CreateDictionaryValue;
-
-namespace {
-
-template <typename T>
-std::vector<T> GetArrayValues(const ValueVector& arr) {
-  std::vector<T> values;
-  values.reserve(arr.size());
-  for (const auto& prop_value : arr) {
-    const auto& value = static_cast<const TypedValueBase<T>&>(*prop_value);
-    values.push_back(value.GetValue());
-  }
-  return values;
-}
-
-template <typename T>
-std::vector<T> GetOneOfValues(const PropType* prop_type) {
-  auto one_of = static_cast<const ConstraintOneOf*>(
-      prop_type->GetConstraint(ConstraintType::OneOf));
-  if (!one_of)
-    return {};
-
-  return GetArrayValues<T>(one_of->set_.value);
-}
-
-bool ValidateValue(const PropType& type,
-                   const base::Value& value,
-                   ErrorPtr* error) {
-  std::unique_ptr<PropValue> val = type.CreatePropValue(value, error);
-  return val != nullptr;
-}
-
-}  // anonymous namespace
-
-TEST(CommandSchema, IntPropType_Empty) {
-  IntPropType prop;
-  EXPECT_TRUE(prop.GetConstraints().empty());
-  EXPECT_FALSE(prop.HasOverriddenAttributes());
-  EXPECT_FALSE(prop.IsBasedOnSchema());
-  EXPECT_EQ(nullptr, prop.GetDefaultValue());
-}
-
-TEST(CommandSchema, IntPropType_Types) {
-  IntPropType prop;
-  EXPECT_EQ(nullptr, prop.GetBoolean());
-  EXPECT_EQ(&prop, prop.GetInt());
-  EXPECT_EQ(nullptr, prop.GetDouble());
-  EXPECT_EQ(nullptr, prop.GetString());
-  EXPECT_EQ(nullptr, prop.GetObject());
-  EXPECT_EQ(nullptr, prop.GetArray());
-}
-
-TEST(CommandSchema, IntPropType_ToJson) {
-  IntPropType prop;
-  EXPECT_JSON_EQ("'integer'", *prop.ToJson(false, false));
-  EXPECT_JSON_EQ("{'type':'integer'}", *prop.ToJson(true, false));
-  IntPropType param2;
-  param2.FromJson(CreateDictionaryValue("{}").get(), &prop, nullptr);
-  EXPECT_JSON_EQ("{}", *param2.ToJson(false, false));
-  param2.FromJson(CreateDictionaryValue("{'minimum':3}").get(), &prop, nullptr);
-  EXPECT_JSON_EQ("{'minimum':3}", *param2.ToJson(false, false));
-  param2.FromJson(CreateDictionaryValue("{'maximum':-7}").get(), &prop,
-                  nullptr);
-  EXPECT_JSON_EQ("{'maximum':-7}", *param2.ToJson(false, false));
-  param2.FromJson(CreateDictionaryValue("{'minimum':0,'maximum':5}").get(),
-                  &prop, nullptr);
-  EXPECT_JSON_EQ("{'maximum':5,'minimum':0}", *param2.ToJson(false, false));
-  param2.FromJson(CreateDictionaryValue("{'enum':[1,2,3]}").get(), &prop,
-                  nullptr);
-  EXPECT_JSON_EQ("[1,2,3]", *param2.ToJson(false, false));
-  param2.FromJson(CreateDictionaryValue("{'default':123}").get(), &prop,
-                  nullptr);
-  EXPECT_JSON_EQ("{'default':123}", *param2.ToJson(false, false));
-}
-
-TEST(CommandSchema, IntPropType_FromJson) {
-  IntPropType prop;
-  prop.AddMinMaxConstraint(2, 8);
-  IntPropType param2;
-  param2.FromJson(CreateDictionaryValue("{}").get(), &prop, nullptr);
-  EXPECT_FALSE(param2.HasOverriddenAttributes());
-  EXPECT_TRUE(param2.IsBasedOnSchema());
-  EXPECT_EQ(2, prop.GetMinValue());
-  EXPECT_EQ(8, prop.GetMaxValue());
-  prop.AddMinMaxConstraint(-2, 30);
-  param2.FromJson(CreateDictionaryValue("{'minimum':7}").get(), &prop, nullptr);
-  EXPECT_TRUE(param2.HasOverriddenAttributes());
-  EXPECT_TRUE(param2.IsBasedOnSchema());
-  EXPECT_EQ(7, param2.GetMinValue());
-  EXPECT_EQ(30, param2.GetMaxValue());
-  param2.FromJson(CreateDictionaryValue("{'maximum':17}").get(), &prop,
-                  nullptr);
-  EXPECT_TRUE(param2.HasOverriddenAttributes());
-  EXPECT_TRUE(param2.IsBasedOnSchema());
-  EXPECT_EQ(-2, param2.GetMinValue());
-  EXPECT_EQ(17, param2.GetMaxValue());
-
-  ASSERT_TRUE(param2.FromJson(CreateDictionaryValue("{'default':3}").get(),
-                              &prop, nullptr));
-  EXPECT_TRUE(param2.HasOverriddenAttributes());
-  ASSERT_NE(nullptr, param2.GetDefaultValue());
-  EXPECT_EQ(3, param2.GetDefaultValue()->GetInt()->GetValue());
-}
-
-TEST(CommandSchema, IntPropType_Validate) {
-  IntPropType prop;
-  prop.AddMinMaxConstraint(2, 4);
-  ErrorPtr error;
-  EXPECT_FALSE(ValidateValue(prop, *CreateValue("-1"), &error));
-  EXPECT_EQ("out_of_range", error->GetCode());
-  error.reset();
-  EXPECT_FALSE(ValidateValue(prop, *CreateValue("0"), &error));
-  EXPECT_EQ("out_of_range", error->GetCode());
-  error.reset();
-  EXPECT_FALSE(ValidateValue(prop, *CreateValue("1"), &error));
-  EXPECT_EQ("out_of_range", error->GetCode());
-  error.reset();
-  EXPECT_TRUE(ValidateValue(prop, *CreateValue("2"), &error));
-  EXPECT_EQ(nullptr, error.get());
-  EXPECT_TRUE(ValidateValue(prop, *CreateValue("3"), &error));
-  EXPECT_EQ(nullptr, error.get());
-  EXPECT_TRUE(ValidateValue(prop, *CreateValue("4"), &error));
-  EXPECT_EQ(nullptr, error.get());
-  EXPECT_FALSE(ValidateValue(prop, *CreateValue("5"), &error));
-  EXPECT_EQ("out_of_range", error->GetCode());
-  error.reset();
-  EXPECT_FALSE(ValidateValue(prop, *CreateValue("true"), &error));
-  EXPECT_EQ("type_mismatch", error->GetCode());
-  error.reset();
-  EXPECT_FALSE(ValidateValue(prop, *CreateValue("3.0"), &error));
-  EXPECT_EQ("type_mismatch", error->GetCode());
-  error.reset();
-  EXPECT_FALSE(ValidateValue(prop, *CreateValue("'3'"), &error));
-  EXPECT_EQ("type_mismatch", error->GetCode());
-}
-
-TEST(CommandSchema, IntPropType_CreateValue) {
-  IntPropType prop;
-  ErrorPtr error;
-  auto val = prop.CreateValue(base::FundamentalValue{2}, &error);
-  ASSERT_NE(nullptr, val.get());
-  EXPECT_EQ(nullptr, error.get());
-  EXPECT_EQ(2, val->GetValue());
-
-  val = prop.CreateValue(base::StringValue{"blah"}, &error);
-  EXPECT_EQ(nullptr, val.get());
-  ASSERT_NE(nullptr, error.get());
-  EXPECT_EQ(errors::commands::kTypeMismatch, error->GetCode());
-}
-
-///////////////////////////////////////////////////////////////////////////////
-
-TEST(CommandSchema, BoolPropType_Empty) {
-  BooleanPropType prop;
-  EXPECT_TRUE(prop.GetConstraints().empty());
-  EXPECT_FALSE(prop.HasOverriddenAttributes());
-  EXPECT_FALSE(prop.IsBasedOnSchema());
-  EXPECT_EQ(nullptr, prop.GetDefaultValue());
-  EXPECT_FALSE(prop.IsRequired());
-}
-
-TEST(CommandSchema, BoolPropType_Types) {
-  BooleanPropType prop;
-  EXPECT_EQ(nullptr, prop.GetInt());
-  EXPECT_EQ(&prop, prop.GetBoolean());
-  EXPECT_EQ(nullptr, prop.GetDouble());
-  EXPECT_EQ(nullptr, prop.GetString());
-  EXPECT_EQ(nullptr, prop.GetObject());
-  EXPECT_EQ(nullptr, prop.GetArray());
-}
-
-TEST(CommandSchema, BoolPropType_ToJson) {
-  BooleanPropType prop;
-  EXPECT_JSON_EQ("'boolean'", *prop.ToJson(false, false));
-  EXPECT_JSON_EQ("{'type':'boolean'}", *prop.ToJson(true, false));
-  BooleanPropType param2;
-  param2.FromJson(CreateDictionaryValue("{}").get(), &prop, nullptr);
-  EXPECT_JSON_EQ("{}", *param2.ToJson(false, false));
-  param2.FromJson(CreateDictionaryValue("{'enum':[true,false]}").get(), &prop,
-                  nullptr);
-  EXPECT_JSON_EQ("[true,false]", *param2.ToJson(false, false));
-  EXPECT_JSON_EQ("{'enum':[true,false],'type':'boolean'}",
-                 *param2.ToJson(true, false));
-  param2.FromJson(CreateDictionaryValue("{'default':true}").get(), &prop,
-                  nullptr);
-  EXPECT_JSON_EQ("{'default':true}", *param2.ToJson(false, false));
-}
-
-TEST(CommandSchema, BoolPropType_FromJson) {
-  BooleanPropType prop;
-  prop.FromJson(CreateDictionaryValue("{'enum':[true]}").get(), &prop, nullptr);
-  BooleanPropType param2;
-  param2.FromJson(CreateDictionaryValue("{}").get(), &prop, nullptr);
-  EXPECT_FALSE(param2.HasOverriddenAttributes());
-  EXPECT_TRUE(param2.IsBasedOnSchema());
-  EXPECT_EQ(std::vector<bool>{true}, GetOneOfValues<bool>(&prop));
-
-  BooleanPropType prop_base;
-  BooleanPropType param3;
-  ASSERT_TRUE(param3.FromJson(CreateDictionaryValue("{'default':false}").get(),
-                              &prop_base, nullptr));
-  EXPECT_TRUE(param3.HasOverriddenAttributes());
-  ASSERT_NE(nullptr, param3.GetDefaultValue());
-  EXPECT_FALSE(param3.GetDefaultValue()->GetBoolean()->GetValue());
-}
-
-TEST(CommandSchema, BoolPropType_Validate) {
-  BooleanPropType prop;
-  prop.FromJson(CreateDictionaryValue("{'enum':[true]}").get(), &prop, nullptr);
-  ErrorPtr error;
-  EXPECT_FALSE(ValidateValue(prop, *CreateValue("false"), &error));
-  EXPECT_EQ("out_of_range", error->GetCode());
-  error.reset();
-  EXPECT_TRUE(ValidateValue(prop, *CreateValue("true"), &error));
-  error.reset();
-  EXPECT_FALSE(ValidateValue(prop, *CreateValue("1"), &error));
-  EXPECT_EQ("type_mismatch", error->GetCode());
-  error.reset();
-  EXPECT_FALSE(ValidateValue(prop, *CreateValue("3.0"), &error));
-  EXPECT_EQ("type_mismatch", error->GetCode());
-  error.reset();
-  EXPECT_FALSE(ValidateValue(prop, *CreateValue("'3'"), &error));
-  EXPECT_EQ("type_mismatch", error->GetCode());
-}
-
-TEST(CommandSchema, BoolPropType_CreateValue) {
-  BooleanPropType prop;
-  ErrorPtr error;
-  auto val = prop.CreateValue(base::FundamentalValue{true}, &error);
-  ASSERT_NE(nullptr, val.get());
-  EXPECT_EQ(nullptr, error.get());
-  EXPECT_TRUE(val->GetValue());
-
-  val = prop.CreateValue(base::StringValue{"blah"}, &error);
-  EXPECT_EQ(nullptr, val.get());
-  ASSERT_NE(nullptr, error.get());
-  EXPECT_EQ(errors::commands::kTypeMismatch, error->GetCode());
-}
-
-///////////////////////////////////////////////////////////////////////////////
-
-TEST(CommandSchema, DoublePropType_Empty) {
-  DoublePropType prop;
-  EXPECT_DOUBLE_EQ(std::numeric_limits<double>::lowest(), prop.GetMinValue());
-  EXPECT_DOUBLE_EQ((std::numeric_limits<double>::max)(), prop.GetMaxValue());
-  EXPECT_FALSE(prop.HasOverriddenAttributes());
-  EXPECT_FALSE(prop.IsBasedOnSchema());
-  EXPECT_EQ(nullptr, prop.GetDefaultValue());
-  EXPECT_FALSE(prop.IsRequired());
-}
-
-TEST(CommandSchema, DoublePropType_Types) {
-  DoublePropType prop;
-  EXPECT_EQ(nullptr, prop.GetInt());
-  EXPECT_EQ(nullptr, prop.GetBoolean());
-  EXPECT_EQ(&prop, prop.GetDouble());
-  EXPECT_EQ(nullptr, prop.GetString());
-  EXPECT_EQ(nullptr, prop.GetObject());
-  EXPECT_EQ(nullptr, prop.GetArray());
-}
-
-TEST(CommandSchema, DoublePropType_ToJson) {
-  DoublePropType prop;
-  EXPECT_JSON_EQ("'number'", *prop.ToJson(false, false));
-  EXPECT_JSON_EQ("{'type':'number'}", *prop.ToJson(true, false));
-  DoublePropType param2;
-  param2.FromJson(CreateDictionaryValue("{}").get(), &prop, nullptr);
-  EXPECT_JSON_EQ("{}", *param2.ToJson(false, false));
-  param2.FromJson(CreateDictionaryValue("{'minimum':3}").get(), &prop, nullptr);
-  EXPECT_JSON_EQ("{'minimum':3.0}", *param2.ToJson(false, false));
-  param2.FromJson(CreateDictionaryValue("{'maximum':-7}").get(), &prop,
-                  nullptr);
-  EXPECT_JSON_EQ("{'maximum':-7.0}", *param2.ToJson(false, false));
-  param2.FromJson(CreateDictionaryValue("{'minimum':0,'maximum':5}").get(),
-                  &prop, nullptr);
-  EXPECT_JSON_EQ("{'maximum':5.0,'minimum':0.0}", *param2.ToJson(false, false));
-  param2.FromJson(CreateDictionaryValue("{'default':12.3}").get(), &prop,
-                  nullptr);
-  EXPECT_JSON_EQ("{'default':12.3}", *param2.ToJson(false, false));
-}
-
-TEST(CommandSchema, DoublePropType_FromJson) {
-  DoublePropType prop;
-  prop.AddMinMaxConstraint(2.5, 8.7);
-  DoublePropType param2;
-  param2.FromJson(CreateDictionaryValue("{}").get(), &prop, nullptr);
-  EXPECT_FALSE(param2.HasOverriddenAttributes());
-  EXPECT_TRUE(param2.IsBasedOnSchema());
-  EXPECT_DOUBLE_EQ(2.5, prop.GetMinValue());
-  EXPECT_DOUBLE_EQ(8.7, prop.GetMaxValue());
-  prop.AddMinMaxConstraint(-2.2, 30.4);
-  param2.FromJson(CreateDictionaryValue("{'minimum':7}").get(), &prop, nullptr);
-  EXPECT_TRUE(param2.HasOverriddenAttributes());
-  EXPECT_TRUE(param2.IsBasedOnSchema());
-  EXPECT_DOUBLE_EQ(7.0, param2.GetMinValue());
-  EXPECT_DOUBLE_EQ(30.4, param2.GetMaxValue());
-  param2.FromJson(CreateDictionaryValue("{'maximum':17.2}").get(), &prop,
-                  nullptr);
-  EXPECT_TRUE(param2.HasOverriddenAttributes());
-  EXPECT_TRUE(param2.IsBasedOnSchema());
-  EXPECT_DOUBLE_EQ(-2.2, param2.GetMinValue());
-  EXPECT_DOUBLE_EQ(17.2, param2.GetMaxValue());
-  param2.FromJson(CreateDictionaryValue("{'minimum':0,'maximum':6.1}").get(),
-                  &prop, nullptr);
-  EXPECT_TRUE(param2.HasOverriddenAttributes());
-  EXPECT_TRUE(param2.IsBasedOnSchema());
-  EXPECT_DOUBLE_EQ(0.0, param2.GetMinValue());
-  EXPECT_DOUBLE_EQ(6.1, param2.GetMaxValue());
-
-  ASSERT_TRUE(param2.FromJson(CreateDictionaryValue("{'default':-1.234}").get(),
-                              &prop, nullptr));
-  EXPECT_TRUE(param2.HasOverriddenAttributes());
-  ASSERT_NE(nullptr, param2.GetDefaultValue());
-  EXPECT_DOUBLE_EQ(-1.234, param2.GetDefaultValue()->GetDouble()->GetValue());
-}
-
-TEST(CommandSchema, DoublePropType_Validate) {
-  DoublePropType prop;
-  prop.AddMinMaxConstraint(-1.2, 1.3);
-  ErrorPtr error;
-  EXPECT_FALSE(ValidateValue(prop, *CreateValue("-2"), &error));
-  EXPECT_EQ("out_of_range", error->GetCode());
-  error.reset();
-  EXPECT_FALSE(ValidateValue(prop, *CreateValue("-1.3"), &error));
-  EXPECT_EQ("out_of_range", error->GetCode());
-  error.reset();
-  EXPECT_TRUE(ValidateValue(prop, *CreateValue("-1.2"), &error));
-  EXPECT_EQ(nullptr, error.get());
-  EXPECT_TRUE(ValidateValue(prop, *CreateValue("0.0"), &error));
-  EXPECT_EQ(nullptr, error.get());
-  EXPECT_TRUE(ValidateValue(prop, *CreateValue("1.3"), &error));
-  EXPECT_EQ(nullptr, error.get());
-  EXPECT_FALSE(ValidateValue(prop, *CreateValue("1.31"), &error));
-  EXPECT_EQ("out_of_range", error->GetCode());
-  error.reset();
-  EXPECT_FALSE(ValidateValue(prop, *CreateValue("true"), &error));
-  EXPECT_EQ("type_mismatch", error->GetCode());
-  error.reset();
-  EXPECT_FALSE(ValidateValue(prop, *CreateValue("'0.0'"), &error));
-  EXPECT_EQ("type_mismatch", error->GetCode());
-}
-
-TEST(CommandSchema, DoublePropType_CreateValue) {
-  DoublePropType prop;
-  ErrorPtr error;
-  auto val = prop.CreateValue(base::FundamentalValue{2.0}, &error);
-  ASSERT_NE(nullptr, val.get());
-  EXPECT_EQ(nullptr, error.get());
-  EXPECT_DOUBLE_EQ(2.0, val->GetValue());
-
-  val = prop.CreateValue(base::StringValue{"blah"}, &error);
-  EXPECT_EQ(nullptr, val.get());
-  ASSERT_NE(nullptr, error.get());
-  EXPECT_EQ(errors::commands::kTypeMismatch, error->GetCode());
-}
-
-///////////////////////////////////////////////////////////////////////////////
-
-TEST(CommandSchema, StringPropType_Empty) {
-  StringPropType prop;
-  EXPECT_EQ(0, prop.GetMinLength());
-  EXPECT_EQ((std::numeric_limits<int>::max)(), prop.GetMaxLength());
-  EXPECT_FALSE(prop.HasOverriddenAttributes());
-  EXPECT_FALSE(prop.IsBasedOnSchema());
-  EXPECT_EQ(nullptr, prop.GetDefaultValue());
-  EXPECT_FALSE(prop.IsRequired());
-}
-
-TEST(CommandSchema, StringPropType_Types) {
-  StringPropType prop;
-  EXPECT_EQ(nullptr, prop.GetInt());
-  EXPECT_EQ(nullptr, prop.GetBoolean());
-  EXPECT_EQ(nullptr, prop.GetDouble());
-  EXPECT_EQ(&prop, prop.GetString());
-  EXPECT_EQ(nullptr, prop.GetObject());
-  EXPECT_EQ(nullptr, prop.GetArray());
-}
-
-TEST(CommandSchema, StringPropType_ToJson) {
-  StringPropType prop;
-  EXPECT_JSON_EQ("'string'", *prop.ToJson(false, false));
-  EXPECT_JSON_EQ("{'type':'string'}", *prop.ToJson(true, false));
-  StringPropType param2;
-  param2.FromJson(CreateDictionaryValue("{}").get(), &prop, nullptr);
-  EXPECT_JSON_EQ("{}", *param2.ToJson(false, false));
-  param2.FromJson(CreateDictionaryValue("{'minLength':3}").get(), &prop,
-                  nullptr);
-  EXPECT_JSON_EQ("{'minLength':3}", *param2.ToJson(false, false));
-  param2.FromJson(CreateDictionaryValue("{'maxLength':7}").get(), &prop,
-                  nullptr);
-  EXPECT_JSON_EQ("{'maxLength':7}", *param2.ToJson(false, false));
-  param2.FromJson(CreateDictionaryValue("{'minLength':0,'maxLength':5}").get(),
-                  &prop, nullptr);
-  EXPECT_JSON_EQ("{'maxLength':5,'minLength':0}", *param2.ToJson(false, false));
-  param2.FromJson(CreateDictionaryValue("{'default':'abcd'}").get(), &prop,
-                  nullptr);
-  EXPECT_JSON_EQ("{'default':'abcd'}", *param2.ToJson(false, false));
-}
-
-TEST(CommandSchema, StringPropType_FromJson) {
-  StringPropType prop;
-  prop.AddLengthConstraint(2, 8);
-  StringPropType param2;
-  param2.FromJson(CreateDictionaryValue("{}").get(), &prop, nullptr);
-  EXPECT_FALSE(param2.HasOverriddenAttributes());
-  EXPECT_TRUE(param2.IsBasedOnSchema());
-  EXPECT_EQ(2, prop.GetMinLength());
-  EXPECT_EQ(8, prop.GetMaxLength());
-  prop.AddLengthConstraint(3, 5);
-  param2.FromJson(CreateDictionaryValue("{'minLength':4}").get(), &prop,
-                  nullptr);
-  EXPECT_TRUE(param2.HasOverriddenAttributes());
-  EXPECT_TRUE(param2.IsBasedOnSchema());
-  EXPECT_EQ(4, param2.GetMinLength());
-  EXPECT_EQ(5, param2.GetMaxLength());
-  param2.FromJson(CreateDictionaryValue("{'maxLength':8}").get(), &prop,
-                  nullptr);
-  EXPECT_TRUE(param2.HasOverriddenAttributes());
-  EXPECT_TRUE(param2.IsBasedOnSchema());
-  EXPECT_EQ(3, param2.GetMinLength());
-  EXPECT_EQ(8, param2.GetMaxLength());
-  param2.FromJson(CreateDictionaryValue("{'minLength':1,'maxLength':7}").get(),
-                  &prop, nullptr);
-  EXPECT_TRUE(param2.HasOverriddenAttributes());
-  EXPECT_TRUE(param2.IsBasedOnSchema());
-  EXPECT_EQ(1, param2.GetMinLength());
-  EXPECT_EQ(7, param2.GetMaxLength());
-
-  ASSERT_TRUE(param2.FromJson(CreateDictionaryValue("{'default':'foo'}").get(),
-                              &prop, nullptr));
-  EXPECT_TRUE(param2.HasOverriddenAttributes());
-  ASSERT_NE(nullptr, param2.GetDefaultValue());
-  EXPECT_EQ("foo", param2.GetDefaultValue()->GetString()->GetValue());
-}
-
-TEST(CommandSchema, StringPropType_Validate) {
-  StringPropType prop;
-  prop.AddLengthConstraint(1, 3);
-  ErrorPtr error;
-  EXPECT_FALSE(ValidateValue(prop, *CreateValue("''"), &error));
-  EXPECT_EQ("out_of_range", error->GetCode());
-  error.reset();
-  prop.AddLengthConstraint(2, 3);
-  EXPECT_FALSE(ValidateValue(prop, *CreateValue("''"), &error));
-  EXPECT_EQ("out_of_range", error->GetCode());
-  error.reset();
-  EXPECT_FALSE(ValidateValue(prop, *CreateValue("'a'"), &error));
-  EXPECT_EQ("out_of_range", error->GetCode());
-  error.reset();
-  EXPECT_TRUE(ValidateValue(prop, *CreateValue("'ab'"), &error));
-  EXPECT_EQ(nullptr, error.get());
-  EXPECT_TRUE(ValidateValue(prop, *CreateValue("'abc'"), &error));
-  EXPECT_EQ(nullptr, error.get());
-  EXPECT_FALSE(ValidateValue(prop, *CreateValue("'abcd'"), &error));
-  EXPECT_EQ("out_of_range", error->GetCode());
-  error.reset();
-
-  prop.FromJson(CreateDictionaryValue("{'enum':['abc','def','xyz!!']}").get(),
-                nullptr, &error);
-  EXPECT_TRUE(ValidateValue(prop, *CreateValue("'abc'"), &error));
-  EXPECT_TRUE(ValidateValue(prop, *CreateValue("'def'"), &error));
-  EXPECT_TRUE(ValidateValue(prop, *CreateValue("'xyz!!'"), &error));
-  EXPECT_FALSE(ValidateValue(prop, *CreateValue("'xyz'"), &error));
-  EXPECT_EQ("out_of_range", error->GetCode());
-  error.reset();
-}
-
-TEST(CommandSchema, StringPropType_CreateValue) {
-  StringPropType prop;
-  ErrorPtr error;
-  auto val = prop.CreateValue(base::StringValue{"blah"}, &error);
-  ASSERT_NE(nullptr, val.get());
-  EXPECT_EQ(nullptr, error.get());
-  EXPECT_EQ("blah", val->GetValue());
-
-  val = prop.CreateValue(base::FundamentalValue{4}, &error);
-  EXPECT_EQ(nullptr, val.get());
-  ASSERT_NE(nullptr, error.get());
-  EXPECT_EQ(errors::commands::kTypeMismatch, error->GetCode());
-}
-
-///////////////////////////////////////////////////////////////////////////////
-
-TEST(CommandSchema, ObjectPropType_Empty) {
-  ObjectPropType prop;
-  EXPECT_TRUE(prop.HasOverriddenAttributes());
-  EXPECT_FALSE(prop.IsBasedOnSchema());
-  EXPECT_EQ(nullptr, prop.GetDefaultValue());
-  EXPECT_FALSE(prop.IsRequired());
-}
-
-TEST(CommandSchema, ObjectPropType_Types) {
-  ObjectPropType prop;
-  EXPECT_EQ(nullptr, prop.GetInt());
-  EXPECT_EQ(nullptr, prop.GetBoolean());
-  EXPECT_EQ(nullptr, prop.GetDouble());
-  EXPECT_EQ(nullptr, prop.GetString());
-  EXPECT_EQ(&prop, prop.GetObject());
-  EXPECT_EQ(nullptr, prop.GetArray());
-}
-
-TEST(CommandSchema, ObjectPropType_ToJson) {
-  ObjectPropType prop;
-  EXPECT_JSON_EQ("{'additionalProperties':false,'properties':{}}",
-                 *prop.ToJson(false, false));
-  EXPECT_JSON_EQ(
-      "{'additionalProperties':false,'properties':{},'type':'object'}",
-      *prop.ToJson(true, false));
-  EXPECT_FALSE(prop.IsBasedOnSchema());
-  ObjectPropType prop2;
-  prop2.FromJson(CreateDictionaryValue("{}").get(), &prop, nullptr);
-  EXPECT_JSON_EQ("{}", *prop2.ToJson(false, false));
-  EXPECT_TRUE(prop2.IsBasedOnSchema());
-
-  auto schema = ObjectSchema::Create();
-  schema->AddProp("expires", PropType::Create(ValueType::Int));
-  auto pw = PropType::Create(ValueType::String);
-  pw->GetString()->AddLengthConstraint(6, 100);
-  schema->AddProp("password", std::move(pw));
-  prop2.SetObjectSchema(std::move(schema));
-  auto expected = R"({
-    'additionalProperties': false,
-    'properties': {
-      'expires': 'integer',
-      'password': {
-        'maxLength': 100,
-        'minLength': 6
-      }
-    }
-  })";
-  EXPECT_JSON_EQ(expected, *prop2.ToJson(false, false));
-
-  expected = R"({
-    'additionalProperties': false,
-    'properties': {
-      'expires': {
-        'type': 'integer'
-      },
-      'password': {
-        'maxLength': 100,
-        'minLength': 6,
-        'type': 'string'
-      }
-    },
-    'type': 'object'
-  })";
-  EXPECT_JSON_EQ(expected, *prop2.ToJson(true, false));
-
-  ObjectPropType prop3;
-  ASSERT_TRUE(
-      prop3.FromJson(CreateDictionaryValue(
-                         "{'default':{'expires':3,'password':'abracadabra'}}")
-                         .get(),
-                     &prop2, nullptr));
-  expected = R"({
-    'default': {
-      'expires': 3,
-      'password': 'abracadabra'
-    }
-  })";
-  EXPECT_JSON_EQ(expected, *prop3.ToJson(false, false));
-
-  expected = R"({
-    'additionalProperties': false,
-    'default': {
-      'expires': 3,
-      'password': 'abracadabra'
-    },
-    'properties': {
-      'expires': {
-        'type': 'integer'
-      },
-      'password': {
-        'maxLength': 100,
-        'minLength': 6,
-        'type': 'string'
-      }
-    },
-    'type': 'object'
-  })";
-  EXPECT_JSON_EQ(expected, *prop3.ToJson(true, false));
-
-  ObjectPropType prop4;
-  ASSERT_TRUE(prop4.FromJson(
-      CreateDictionaryValue("{'additionalProperties':true,"
-                            "'default':{'expires':3,'password':'abracadabra'}}")
-          .get(),
-      &prop2, nullptr));
-  expected = R"({
-    'additionalProperties': true,
-    'default': {
-      'expires': 3,
-      'password': 'abracadabra'
-    },
-    'properties': {
-      'expires': 'integer',
-      'password': {
-        'maxLength': 100,
-        'minLength': 6
-      }
-    }
-  })";
-  EXPECT_JSON_EQ(expected, *prop4.ToJson(false, false));
-
-  expected = R"({
-    'additionalProperties': true,
-    'default': {
-      'expires': 3,
-      'password': 'abracadabra'
-    },
-    'properties': {
-      'expires': {
-        'type': 'integer'
-      },
-      'password': {
-        'maxLength': 100,
-        'minLength': 6,
-        'type': 'string'
-      }
-    },
-    'type': 'object'
-  })";
-  EXPECT_JSON_EQ(expected, *prop4.ToJson(true, false));
-}
-
-TEST(CommandSchema, ObjectPropType_FromJson) {
-  ObjectPropType base_prop;
-  EXPECT_TRUE(base_prop.FromJson(
-      CreateDictionaryValue("{'properties':{'name':'string','age':'integer'}}")
-          .get(),
-      nullptr, nullptr));
-  auto schema = base_prop.GetObject()->GetObjectSchemaPtr();
-  const PropType* prop = schema->GetProp("name");
-  EXPECT_EQ(ValueType::String, prop->GetType());
-  prop = schema->GetProp("age");
-  EXPECT_EQ(ValueType::Int, prop->GetType());
-
-  ObjectPropType prop2;
-  ASSERT_TRUE(prop2.FromJson(
-      CreateDictionaryValue("{'properties':{'name':'string','age':'integer'},"
-                            "'default':{'name':'Bob','age':33}}")
-          .get(),
-      nullptr, nullptr));
-  ASSERT_NE(nullptr, prop2.GetDefaultValue());
-  const ObjectValue* defval = prop2.GetDefaultValue()->GetObject();
-  ASSERT_NE(nullptr, defval);
-  ValueMap objval = defval->GetValue();
-  EXPECT_EQ("Bob", objval["name"]->GetString()->GetValue());
-  EXPECT_EQ(33, objval["age"]->GetInt()->GetValue());
-}
-
-TEST(CommandSchema, ObjectPropType_Validate) {
-  ObjectPropType prop;
-  prop.FromJson(
-      CreateDictionaryValue("{'properties':{'expires':'integer',"
-                            "'password':{'maxLength':100,'minLength':6}},"
-                            "'required':['expires','password']}")
-          .get(),
-      nullptr, nullptr);
-  ErrorPtr error;
-  EXPECT_TRUE(ValidateValue(
-      prop, *CreateValue("{'expires':10,'password':'abcdef'}"), &error));
-  error.reset();
-
-  EXPECT_FALSE(ValidateValue(prop, *CreateValue("{'expires':10}"), &error));
-  EXPECT_EQ("parameter_missing", error->GetCode());
-  error.reset();
-
-  EXPECT_FALSE(
-      ValidateValue(prop, *CreateValue("{'password':'abcdef'}"), &error));
-  EXPECT_EQ("parameter_missing", error->GetCode());
-  error.reset();
-
-  EXPECT_FALSE(ValidateValue(
-      prop, *CreateValue("{'expires':10,'password':'abcde'}"), &error));
-  EXPECT_EQ("out_of_range", error->GetFirstError()->GetCode());
-  error.reset();
-
-  EXPECT_FALSE(ValidateValue(prop, *CreateValue("2"), &error));
-  EXPECT_EQ("type_mismatch", error->GetCode());
-  error.reset();
-
-  EXPECT_FALSE(ValidateValue(
-      prop, *CreateValue("{'expires':10,'password':'abcdef','retry':true}"),
-      &error));
-  EXPECT_EQ("unexpected_parameter", error->GetCode());
-  error.reset();
-}
-
-TEST(CommandSchema, ObjectPropType_Validate_Enum) {
-  ObjectPropType prop;
-  EXPECT_TRUE(prop.FromJson(
-      CreateDictionaryValue(
-          "{'properties':{'width':'integer','height':'integer'},"
-          "'enum':[{'width':10,'height':20},{'width':100,'height':200}]}")
-          .get(),
-      nullptr, nullptr));
-  ErrorPtr error;
-  EXPECT_TRUE(
-      ValidateValue(prop, *CreateValue("{'height':20,'width':10}"), &error));
-  error.reset();
-
-  EXPECT_TRUE(
-      ValidateValue(prop, *CreateValue("{'height':200,'width':100}"), &error));
-  error.reset();
-
-  EXPECT_FALSE(
-      ValidateValue(prop, *CreateValue("{'height':12,'width':10}"), &error));
-  EXPECT_EQ("out_of_range", error->GetCode());
-  error.reset();
-}
-
-TEST(CommandSchema, ObjectPropType_CreateValue) {
-  ObjectPropType prop;
-  IntPropType int_type;
-  ASSERT_TRUE(prop.FromJson(
-      CreateDictionaryValue(
-          "{'properties':{'width':'integer','height':'integer'},"
-          "'enum':[{'width':10,'height':20},{'width':100,'height':200}]}")
-          .get(),
-      nullptr, nullptr));
-  ValueMap obj{
-      {"width", int_type.CreateValue(base::FundamentalValue{10}, nullptr)},
-      {"height", int_type.CreateValue(base::FundamentalValue{20}, nullptr)},
-  };
-
-  ErrorPtr error;
-  auto val = prop.CreateValue(
-      *CreateDictionaryValue("{'width': 10, 'height': 20}"), &error);
-  ASSERT_NE(nullptr, val.get());
-  EXPECT_EQ(nullptr, error.get());
-  EXPECT_EQ(obj, val->GetValue());
-
-  val = prop.CreateValue(base::StringValue{"blah"}, &error);
-  EXPECT_EQ(nullptr, val.get());
-  ASSERT_NE(nullptr, error.get());
-  EXPECT_EQ(errors::commands::kTypeMismatch, error->GetCode());
-}
-
-///////////////////////////////////////////////////////////////////////////////
-
-TEST(CommandSchema, ArrayPropType_Empty) {
-  ArrayPropType prop;
-  EXPECT_FALSE(prop.HasOverriddenAttributes());
-  EXPECT_FALSE(prop.IsBasedOnSchema());
-  EXPECT_EQ(nullptr, prop.GetDefaultValue());
-  EXPECT_EQ(nullptr, prop.GetItemTypePtr());
-  prop.SetItemType(PropType::Create(ValueType::Int));
-  EXPECT_TRUE(prop.HasOverriddenAttributes());
-  EXPECT_FALSE(prop.IsBasedOnSchema());
-  EXPECT_NE(nullptr, prop.GetItemTypePtr());
-  EXPECT_FALSE(prop.IsRequired());
-}
-
-TEST(CommandSchema, ArrayPropType_Types) {
-  ArrayPropType prop;
-  EXPECT_EQ(nullptr, prop.GetInt());
-  EXPECT_EQ(nullptr, prop.GetBoolean());
-  EXPECT_EQ(nullptr, prop.GetDouble());
-  EXPECT_EQ(nullptr, prop.GetString());
-  EXPECT_EQ(nullptr, prop.GetObject());
-  EXPECT_EQ(&prop, prop.GetArray());
-}
-
-TEST(CommandSchema, ArrayPropType_ToJson) {
-  ArrayPropType prop;
-  prop.SetItemType(PropType::Create(ValueType::Int));
-  EXPECT_JSON_EQ("{'items':'integer'}", *prop.ToJson(false, false));
-  EXPECT_JSON_EQ("{'items':{'type':'integer'},'type':'array'}",
-                 *prop.ToJson(true, false));
-  EXPECT_FALSE(prop.IsBasedOnSchema());
-  ArrayPropType prop2;
-  prop2.FromJson(CreateDictionaryValue("{}").get(), &prop, nullptr);
-  EXPECT_JSON_EQ("{}", *prop2.ToJson(false, false));
-  EXPECT_TRUE(prop2.IsBasedOnSchema());
-  prop2.FromJson(CreateDictionaryValue("{'default':[1,2,3]}").get(), &prop,
-                 nullptr);
-  EXPECT_JSON_EQ("{'default':[1,2,3]}", *prop2.ToJson(false, false));
-  EXPECT_JSON_EQ(
-      "{'default':[1,2,3],'items':{'type':'integer'},'type':'array'}",
-      *prop2.ToJson(true, false));
-}
-
-TEST(CommandSchema, ArrayPropType_FromJson) {
-  ArrayPropType prop;
-  EXPECT_TRUE(prop.FromJson(CreateDictionaryValue("{'items':'integer'}").get(),
-                            nullptr, nullptr));
-  EXPECT_EQ(ValueType::Int, prop.GetItemTypePtr()->GetType());
-
-  ArrayPropType prop2;
-  ASSERT_TRUE(
-      prop2.FromJson(CreateDictionaryValue(
-                         "{'items':'string','default':['foo', 'bar', 'baz']}")
-                         .get(),
-                     nullptr, nullptr));
-  ASSERT_NE(nullptr, prop2.GetDefaultValue());
-  const ArrayValue* defval = prop2.GetDefaultValue()->GetArray();
-  ASSERT_NE(nullptr, defval);
-  EXPECT_EQ((std::vector<std::string>{"foo", "bar", "baz"}),
-            GetArrayValues<std::string>(defval->GetValue()));
-}
-
-TEST(CommandSchema, ArrayPropType_Validate) {
-  ArrayPropType prop;
-  prop.FromJson(
-      CreateDictionaryValue("{'items':{'minimum':2.3, 'maximum':10.5}}").get(),
-      nullptr, nullptr);
-
-  ErrorPtr error;
-  EXPECT_TRUE(ValidateValue(prop, *CreateValue("[3,4,10.5]"), &error));
-  error.reset();
-
-  EXPECT_FALSE(ValidateValue(prop, *CreateValue("[2]"), &error));
-  EXPECT_EQ("out_of_range", error->GetCode());
-  error.reset();
-
-  EXPECT_FALSE(ValidateValue(prop, *CreateValue("[4, 5, 20]"), &error));
-  EXPECT_EQ("out_of_range", error->GetCode());
-  error.reset();
-}
-
-TEST(CommandSchema, ArrayPropType_Validate_Enum) {
-  ArrayPropType prop;
-  prop.FromJson(
-      CreateDictionaryValue("{'items':'integer', 'enum':[[1], [2,3], [4,5,6]]}")
-          .get(),
-      nullptr, nullptr);
-
-  ErrorPtr error;
-  EXPECT_TRUE(ValidateValue(prop, *CreateValue("[2,3]"), &error));
-  error.reset();
-
-  EXPECT_FALSE(ValidateValue(prop, *CreateValue("[2]"), &error));
-  EXPECT_EQ("out_of_range", error->GetCode());
-  error.reset();
-
-  EXPECT_FALSE(ValidateValue(prop, *CreateValue("[2,3,4]"), &error));
-  EXPECT_EQ("out_of_range", error->GetCode());
-  error.reset();
-}
-
-TEST(CommandSchema, ArrayPropType_CreateValue) {
-  ArrayPropType prop;
-  ASSERT_TRUE(prop.FromJson(
-      CreateDictionaryValue(
-          "{'items':{'properties':{'width':'integer','height':'integer'}}}")
-          .get(),
-      nullptr, nullptr));
-
-  ErrorPtr error;
-  ValueVector arr;
-
-  auto val = prop.CreateValue(base::ListValue{}, &error);
-  ASSERT_NE(nullptr, val.get());
-  EXPECT_EQ(nullptr, error.get());
-  EXPECT_EQ(arr, val->GetValue());
-  EXPECT_JSON_EQ("[]", *val->ToJson());
-
-  val = prop.CreateValue(
-      *CreateValue("[{'height':20,'width':10},{'width':17, 'height':18}]"),
-      &error);
-  ASSERT_NE(nullptr, val.get());
-  EXPECT_EQ(nullptr, error.get());
-  EXPECT_JSON_EQ("[{'height':20,'width':10},{'height':18,'width':17}]",
-                 *val->ToJson());
-
-  val = prop.CreateValue(base::StringValue{"blah"}, &error);
-  EXPECT_EQ(nullptr, val.get());
-  ASSERT_NE(nullptr, error.get());
-  EXPECT_EQ(errors::commands::kTypeMismatch, error->GetCode());
-}
-
-TEST(CommandSchema, ArrayPropType_NestedArrays_NotSupported) {
-  ArrayPropType prop;
-  ErrorPtr error;
-  EXPECT_FALSE(prop.FromJson(
-      CreateDictionaryValue("{'items':{'items':'integer'}}").get(), nullptr,
-      &error));
-  EXPECT_EQ(errors::commands::kInvalidObjectSchema, error->GetCode());
-  error.reset();
-}
-
-///////////////////////////////////////////////////////////////////////////////
-
-TEST(CommandSchema, ObjectSchema_FromJson_Shorthand_TypeName) {
-  ObjectSchema schema;
-  const char* schema_str =
-      "{"
-      "'param1':'integer',"
-      "'param2':'number',"
-      "'param3':'string'"
-      "}";
-  EXPECT_TRUE(schema.FromJson(CreateDictionaryValue(schema_str).get(), nullptr,
-                              nullptr));
-  EXPECT_EQ(ValueType::Int, schema.GetProp("param1")->GetType());
-  EXPECT_EQ(ValueType::Double, schema.GetProp("param2")->GetType());
-  EXPECT_EQ(ValueType::String, schema.GetProp("param3")->GetType());
-  EXPECT_EQ("integer", schema.GetProp("param1")->GetTypeAsString());
-  EXPECT_EQ("number", schema.GetProp("param2")->GetTypeAsString());
-  EXPECT_EQ("string", schema.GetProp("param3")->GetTypeAsString());
-  EXPECT_EQ(nullptr, schema.GetProp("param4"));
-
-  int min_int = (std::numeric_limits<int>::min)();
-  int max_int = (std::numeric_limits<int>::max)();
-  double min_dbl = (std::numeric_limits<double>::lowest)();
-  double max_dbl = (std::numeric_limits<double>::max)();
-  EXPECT_EQ(min_int, schema.GetProp("param1")->GetInt()->GetMinValue());
-  EXPECT_EQ(max_int, schema.GetProp("param1")->GetInt()->GetMaxValue());
-  EXPECT_EQ(min_dbl, schema.GetProp("param2")->GetDouble()->GetMinValue());
-  EXPECT_EQ(max_dbl, schema.GetProp("param2")->GetDouble()->GetMaxValue());
-  EXPECT_EQ(0, schema.GetProp("param3")->GetString()->GetMinLength());
-  EXPECT_EQ(max_int, schema.GetProp("param3")->GetString()->GetMaxLength());
-}
-
-TEST(CommandSchema, ObjectSchema_FromJson_Full_TypeName) {
-  ObjectSchema schema;
-  const char* schema_str =
-      "{"
-      "'param1':{'type':'integer'},"
-      "'param2':{'type':'number'},"
-      "'param3':{'type':'string'},"
-      "'param4':{'type':'array', 'items':'integer'},"
-      "'param5':{'type':'object', 'properties':{'p1':'integer'}}"
-      "}";
-  EXPECT_TRUE(schema.FromJson(CreateDictionaryValue(schema_str).get(), nullptr,
-                              nullptr));
-  EXPECT_EQ(ValueType::Int, schema.GetProp("param1")->GetType());
-  EXPECT_EQ(ValueType::Double, schema.GetProp("param2")->GetType());
-  EXPECT_EQ(ValueType::String, schema.GetProp("param3")->GetType());
-  EXPECT_EQ(ValueType::Array, schema.GetProp("param4")->GetType());
-  EXPECT_EQ(ValueType::Object, schema.GetProp("param5")->GetType());
-  EXPECT_EQ("integer", schema.GetProp("param1")->GetTypeAsString());
-  EXPECT_EQ("number", schema.GetProp("param2")->GetTypeAsString());
-  EXPECT_EQ("string", schema.GetProp("param3")->GetTypeAsString());
-  EXPECT_EQ("array", schema.GetProp("param4")->GetTypeAsString());
-  EXPECT_EQ("object", schema.GetProp("param5")->GetTypeAsString());
-  EXPECT_EQ(nullptr, schema.GetProp("param77"));
-
-  int min_int = (std::numeric_limits<int>::min)();
-  int max_int = (std::numeric_limits<int>::max)();
-  double min_dbl = (std::numeric_limits<double>::lowest)();
-  double max_dbl = (std::numeric_limits<double>::max)();
-  EXPECT_EQ(min_int, schema.GetProp("param1")->GetInt()->GetMinValue());
-  EXPECT_EQ(max_int, schema.GetProp("param1")->GetInt()->GetMaxValue());
-  EXPECT_EQ(min_dbl, schema.GetProp("param2")->GetDouble()->GetMinValue());
-  EXPECT_EQ(max_dbl, schema.GetProp("param2")->GetDouble()->GetMaxValue());
-  EXPECT_EQ(0, schema.GetProp("param3")->GetString()->GetMinLength());
-  EXPECT_EQ(max_int, schema.GetProp("param3")->GetString()->GetMaxLength());
-}
-
-TEST(CommandSchema, ObjectSchema_FromJson_Shorthand_TypeDeduction_Scalar) {
-  ObjectSchema schema;
-  const char* schema_str =
-      "{"
-      "'param1' :{'minimum':2},"
-      "'param2' :{'maximum':10},"
-      "'param3' :{'maximum':8, 'minimum':2},"
-      "'param4' :{'minimum':2.1},"
-      "'param5' :{'maximum':10.1},"
-      "'param6' :{'maximum':8.1, 'minimum':3.1},"
-      "'param7' :{'maximum':8, 'minimum':3.1},"
-      "'param8' :{'maximum':8.1, 'minimum':3},"
-      "'param9' :{'minLength':2},"
-      "'param10':{'maxLength':10},"
-      "'param11':{'maxLength':8, 'minLength':3},"
-      "'param12':{'default':12},"
-      "'param13':{'default':13.5},"
-      "'param14':{'default':true},"
-      "'param15':{'default':false},"
-      "'param16':{'default':'foobar'},"
-      "'param17':{'default':[1,2,3]},"
-      "'param18':{'items':'number', 'default':[]}"
-      "}";
-  EXPECT_TRUE(schema.FromJson(CreateDictionaryValue(schema_str).get(), nullptr,
-                              nullptr));
-  EXPECT_EQ("integer", schema.GetProp("param1")->GetTypeAsString());
-  EXPECT_EQ("integer", schema.GetProp("param2")->GetTypeAsString());
-  EXPECT_EQ("integer", schema.GetProp("param3")->GetTypeAsString());
-  EXPECT_EQ("number", schema.GetProp("param4")->GetTypeAsString());
-  EXPECT_EQ("number", schema.GetProp("param5")->GetTypeAsString());
-  EXPECT_EQ("number", schema.GetProp("param6")->GetTypeAsString());
-  EXPECT_EQ("number", schema.GetProp("param7")->GetTypeAsString());
-  EXPECT_EQ("number", schema.GetProp("param8")->GetTypeAsString());
-  EXPECT_EQ("string", schema.GetProp("param9")->GetTypeAsString());
-  EXPECT_EQ("string", schema.GetProp("param10")->GetTypeAsString());
-  EXPECT_EQ("string", schema.GetProp("param11")->GetTypeAsString());
-  EXPECT_EQ("integer", schema.GetProp("param12")->GetTypeAsString());
-  EXPECT_EQ("number", schema.GetProp("param13")->GetTypeAsString());
-  EXPECT_EQ("boolean", schema.GetProp("param14")->GetTypeAsString());
-  EXPECT_EQ("boolean", schema.GetProp("param15")->GetTypeAsString());
-  EXPECT_EQ("string", schema.GetProp("param16")->GetTypeAsString());
-  EXPECT_EQ("array", schema.GetProp("param17")->GetTypeAsString());
-  auto prop17 = schema.GetProp("param17");
-  EXPECT_EQ("integer", prop17->GetArray()->GetItemTypePtr()->GetTypeAsString());
-  EXPECT_EQ("array", schema.GetProp("param18")->GetTypeAsString());
-  auto prop18 = schema.GetProp("param18");
-  EXPECT_EQ("number", prop18->GetArray()->GetItemTypePtr()->GetTypeAsString());
-
-  int min_int = (std::numeric_limits<int>::min)();
-  int max_int = (std::numeric_limits<int>::max)();
-  double min_dbl = (std::numeric_limits<double>::lowest)();
-  double max_dbl = (std::numeric_limits<double>::max)();
-  EXPECT_EQ(2, schema.GetProp("param1")->GetInt()->GetMinValue());
-  EXPECT_EQ(max_int, schema.GetProp("param1")->GetInt()->GetMaxValue());
-  EXPECT_EQ(min_int, schema.GetProp("param2")->GetInt()->GetMinValue());
-  EXPECT_EQ(10, schema.GetProp("param2")->GetInt()->GetMaxValue());
-  EXPECT_EQ(2, schema.GetProp("param3")->GetInt()->GetMinValue());
-  EXPECT_EQ(8, schema.GetProp("param3")->GetInt()->GetMaxValue());
-  EXPECT_DOUBLE_EQ(2.1, schema.GetProp("param4")->GetDouble()->GetMinValue());
-  EXPECT_DOUBLE_EQ(max_dbl,
-                   schema.GetProp("param4")->GetDouble()->GetMaxValue());
-  EXPECT_DOUBLE_EQ(min_dbl,
-                   schema.GetProp("param5")->GetDouble()->GetMinValue());
-  EXPECT_DOUBLE_EQ(10.1, schema.GetProp("param5")->GetDouble()->GetMaxValue());
-  EXPECT_DOUBLE_EQ(3.1, schema.GetProp("param6")->GetDouble()->GetMinValue());
-  EXPECT_DOUBLE_EQ(8.1, schema.GetProp("param6")->GetDouble()->GetMaxValue());
-  EXPECT_DOUBLE_EQ(3.1, schema.GetProp("param7")->GetDouble()->GetMinValue());
-  EXPECT_DOUBLE_EQ(8.0, schema.GetProp("param7")->GetDouble()->GetMaxValue());
-  EXPECT_DOUBLE_EQ(3.0, schema.GetProp("param8")->GetDouble()->GetMinValue());
-  EXPECT_DOUBLE_EQ(8.1, schema.GetProp("param8")->GetDouble()->GetMaxValue());
-  EXPECT_EQ(2, schema.GetProp("param9")->GetString()->GetMinLength());
-  EXPECT_EQ(max_int, schema.GetProp("param9")->GetString()->GetMaxLength());
-  EXPECT_EQ(0, schema.GetProp("param10")->GetString()->GetMinLength());
-  EXPECT_EQ(10, schema.GetProp("param10")->GetString()->GetMaxLength());
-  EXPECT_EQ(3, schema.GetProp("param11")->GetString()->GetMinLength());
-  EXPECT_EQ(8, schema.GetProp("param11")->GetString()->GetMaxLength());
-  const PropValue* val = schema.GetProp("param12")->GetDefaultValue();
-  EXPECT_EQ(12, val->GetInt()->GetValue());
-  val = schema.GetProp("param13")->GetDefaultValue();
-  EXPECT_DOUBLE_EQ(13.5, val->GetDouble()->GetValue());
-  val = schema.GetProp("param14")->GetDefaultValue();
-  EXPECT_TRUE(val->GetBoolean()->GetValue());
-  val = schema.GetProp("param15")->GetDefaultValue();
-  EXPECT_FALSE(val->GetBoolean()->GetValue());
-  val = schema.GetProp("param16")->GetDefaultValue();
-  EXPECT_EQ("foobar", val->GetString()->GetValue());
-  val = schema.GetProp("param17")->GetDefaultValue();
-  EXPECT_EQ((std::vector<int>{1, 2, 3}),
-            GetArrayValues<int>(val->GetArray()->GetValue()));
-  val = schema.GetProp("param18")->GetDefaultValue();
-  EXPECT_TRUE(val->GetArray()->GetValue().empty());
-}
-
-TEST(CommandSchema, ObjectSchema_FromJson_Shorthand_TypeDeduction_Array) {
-  ObjectSchema schema;
-  const char* schema_str =
-      "{"
-      "'param1' :[0,1,2,3],"
-      "'param2' :[0.0,1.1,2.2],"
-      "'param3' :['id1', 'id2'],"
-      "'param4' :{'enum':[1,2,3]},"
-      "'param5' :{'enum':[-1.1,2.2,3]},"
-      "'param6' :{'enum':['id0', 'id1']},"
-      "'param7' :{'type':'integer', 'enum':[1,2,3]},"
-      "'param8' :{'type':'number',  'enum':[1,2,3]},"
-      "'param9' :{'type':'number',  'enum':[]},"
-      "'param10':{'type':'integer', 'enum':[]},"
-      "'param11':[[0,1],[2,3]],"
-      "'param12':[['foo','bar']],"
-      "'param13':{'enum':[['id0', 'id1']]}"
-      "}";
-  EXPECT_TRUE(schema.FromJson(CreateDictionaryValue(schema_str).get(), nullptr,
-                              nullptr));
-  EXPECT_EQ("integer", schema.GetProp("param1")->GetTypeAsString());
-  EXPECT_EQ("number", schema.GetProp("param2")->GetTypeAsString());
-  EXPECT_EQ("string", schema.GetProp("param3")->GetTypeAsString());
-  EXPECT_EQ("integer", schema.GetProp("param4")->GetTypeAsString());
-  EXPECT_EQ("number", schema.GetProp("param5")->GetTypeAsString());
-  EXPECT_EQ("string", schema.GetProp("param6")->GetTypeAsString());
-  EXPECT_EQ("integer", schema.GetProp("param7")->GetTypeAsString());
-  EXPECT_EQ("number", schema.GetProp("param8")->GetTypeAsString());
-  EXPECT_EQ("number", schema.GetProp("param9")->GetTypeAsString());
-  EXPECT_EQ("integer", schema.GetProp("param10")->GetTypeAsString());
-
-  auto prop_type11 = schema.GetProp("param11");
-  EXPECT_EQ("array", prop_type11->GetTypeAsString());
-  EXPECT_EQ("integer",
-            prop_type11->GetArray()->GetItemTypePtr()->GetTypeAsString());
-
-  auto prop_type12 = schema.GetProp("param12");
-  EXPECT_EQ("array", prop_type12->GetTypeAsString());
-  EXPECT_EQ("string",
-            prop_type12->GetArray()->GetItemTypePtr()->GetTypeAsString());
-
-  auto prop_type13 = schema.GetProp("param13");
-  EXPECT_EQ("array", prop_type12->GetTypeAsString());
-  EXPECT_EQ("string",
-            prop_type13->GetArray()->GetItemTypePtr()->GetTypeAsString());
-
-  EXPECT_EQ((std::vector<int>{0, 1, 2, 3}),
-            GetOneOfValues<int>(schema.GetProp("param1")));
-  EXPECT_EQ((std::vector<double>{0.0, 1.1, 2.2}),
-            GetOneOfValues<double>(schema.GetProp("param2")));
-  EXPECT_EQ((std::vector<std::string>{"id1", "id2"}),
-            GetOneOfValues<std::string>(schema.GetProp("param3")));
-
-  EXPECT_EQ((std::vector<int>{1, 2, 3}),
-            GetOneOfValues<int>(schema.GetProp("param4")));
-  EXPECT_EQ((std::vector<double>{-1.1, 2.2, 3.0}),
-            GetOneOfValues<double>(schema.GetProp("param5")));
-  EXPECT_EQ((std::vector<std::string>{"id0", "id1"}),
-            GetOneOfValues<std::string>(schema.GetProp("param6")));
-  EXPECT_EQ((std::vector<int>{1, 2, 3}),
-            GetOneOfValues<int>(schema.GetProp("param7")));
-  EXPECT_EQ((std::vector<double>{1.0, 2.0, 3.0}),
-            GetOneOfValues<double>(schema.GetProp("param8")));
-  EXPECT_TRUE(GetOneOfValues<double>(schema.GetProp("param9")).empty());
-  EXPECT_TRUE(GetOneOfValues<int>(schema.GetProp("param10")).empty());
-}
-
-TEST(CommandSchema, ObjectSchema_FromJson_Inheritance) {
-  const char* base_schema_str =
-      "{"
-      "'param0' :{'minimum':1, 'maximum':5},"
-      "'param1' :{'minimum':1, 'maximum':5},"
-      "'param2' :{'minimum':1, 'maximum':5},"
-      "'param3' :{'minimum':1, 'maximum':5},"
-      "'param4' :{'minimum':1, 'maximum':5},"
-      "'param5' :{'minimum':1.1, 'maximum':5.5},"
-      "'param6' :{'minimum':1.1, 'maximum':5.5},"
-      "'param7' :{'minimum':1.1, 'maximum':5.5},"
-      "'param8' :{'minimum':1.1, 'maximum':5.5},"
-      "'param9' :{'minLength':1, 'maxLength':5},"
-      "'param10':{'minLength':1, 'maxLength':5},"
-      "'param11':{'minLength':1, 'maxLength':5},"
-      "'param12':{'minLength':1, 'maxLength':5},"
-      "'param13':[1,2,3],"
-      "'param14':[1,2,3],"
-      "'param15':[1.1,2.2,3.3],"
-      "'param16':[1.1,2.2,3.3],"
-      "'param17':['id1', 'id2'],"
-      "'param18':['id1', 'id2'],"
-      "'param19':{'minimum':1, 'maximum':5},"
-      "'param20':{'default':49},"
-      "'param21':{'default':49},"
-      "'param22':'integer'"
-      "}";
-  ObjectSchema base_schema;
-  EXPECT_TRUE(base_schema.FromJson(CreateDictionaryValue(base_schema_str).get(),
-                                   nullptr, nullptr));
-  const char* schema_str =
-      "{"
-      "'param1' :{},"
-      "'param2' :{'minimum':2},"
-      "'param3' :{'maximum':9},"
-      "'param4' :{'minimum':2, 'maximum':9},"
-      "'param5' :{},"
-      "'param6' :{'minimum':2.2},"
-      "'param7' :{'maximum':9.9},"
-      "'param8' :{'minimum':2.2, 'maximum':9.9},"
-      "'param9' :{},"
-      "'param10':{'minLength':3},"
-      "'param11':{'maxLength':8},"
-      "'param12':{'minLength':3, 'maxLength':8},"
-      "'param13':{},"
-      "'param14':[1,2,3,4],"
-      "'param15':{},"
-      "'param16':[1.1,2.2,3.3,4.4],"
-      "'param17':{},"
-      "'param18':['id1', 'id3'],"
-      "'param19':{},"
-      "'param20':{},"
-      "'param21':{'default':8},"
-      "'param22':{'default':123}"
-      "}";
-  ObjectSchema schema;
-  EXPECT_TRUE(schema.FromJson(CreateDictionaryValue(schema_str).get(),
-                              &base_schema, nullptr));
-  EXPECT_EQ(nullptr, schema.GetProp("param0"));
-  EXPECT_NE(nullptr, schema.GetProp("param1"));
-  EXPECT_EQ("integer", schema.GetProp("param1")->GetTypeAsString());
-  EXPECT_EQ(1, schema.GetProp("param1")->GetInt()->GetMinValue());
-  EXPECT_EQ(5, schema.GetProp("param1")->GetInt()->GetMaxValue());
-  EXPECT_EQ("integer", schema.GetProp("param2")->GetTypeAsString());
-  EXPECT_EQ(2, schema.GetProp("param2")->GetInt()->GetMinValue());
-  EXPECT_EQ(5, schema.GetProp("param2")->GetInt()->GetMaxValue());
-  EXPECT_EQ("integer", schema.GetProp("param3")->GetTypeAsString());
-  EXPECT_EQ(1, schema.GetProp("param3")->GetInt()->GetMinValue());
-  EXPECT_EQ(9, schema.GetProp("param3")->GetInt()->GetMaxValue());
-  EXPECT_EQ("integer", schema.GetProp("param4")->GetTypeAsString());
-  EXPECT_EQ(2, schema.GetProp("param4")->GetInt()->GetMinValue());
-  EXPECT_EQ(9, schema.GetProp("param4")->GetInt()->GetMaxValue());
-  EXPECT_EQ("number", schema.GetProp("param5")->GetTypeAsString());
-  EXPECT_EQ(1.1, schema.GetProp("param5")->GetDouble()->GetMinValue());
-  EXPECT_EQ(5.5, schema.GetProp("param5")->GetDouble()->GetMaxValue());
-  EXPECT_EQ("number", schema.GetProp("param6")->GetTypeAsString());
-  EXPECT_EQ(2.2, schema.GetProp("param6")->GetDouble()->GetMinValue());
-  EXPECT_EQ(5.5, schema.GetProp("param6")->GetDouble()->GetMaxValue());
-  EXPECT_EQ("number", schema.GetProp("param7")->GetTypeAsString());
-  EXPECT_EQ(1.1, schema.GetProp("param7")->GetDouble()->GetMinValue());
-  EXPECT_EQ(9.9, schema.GetProp("param7")->GetDouble()->GetMaxValue());
-  EXPECT_EQ("number", schema.GetProp("param8")->GetTypeAsString());
-  EXPECT_EQ(2.2, schema.GetProp("param8")->GetDouble()->GetMinValue());
-  EXPECT_EQ(9.9, schema.GetProp("param8")->GetDouble()->GetMaxValue());
-  EXPECT_EQ("string", schema.GetProp("param9")->GetTypeAsString());
-  EXPECT_EQ(1, schema.GetProp("param9")->GetString()->GetMinLength());
-  EXPECT_EQ(5, schema.GetProp("param9")->GetString()->GetMaxLength());
-  EXPECT_EQ("string", schema.GetProp("param10")->GetTypeAsString());
-  EXPECT_EQ(3, schema.GetProp("param10")->GetString()->GetMinLength());
-  EXPECT_EQ(5, schema.GetProp("param10")->GetString()->GetMaxLength());
-  EXPECT_EQ("string", schema.GetProp("param11")->GetTypeAsString());
-  EXPECT_EQ(1, schema.GetProp("param11")->GetString()->GetMinLength());
-  EXPECT_EQ(8, schema.GetProp("param11")->GetString()->GetMaxLength());
-  EXPECT_EQ("string", schema.GetProp("param12")->GetTypeAsString());
-  EXPECT_EQ(3, schema.GetProp("param12")->GetString()->GetMinLength());
-  EXPECT_EQ(8, schema.GetProp("param12")->GetString()->GetMaxLength());
-  EXPECT_EQ("integer", schema.GetProp("param13")->GetTypeAsString());
-  EXPECT_EQ((std::vector<int>{1, 2, 3}),
-            GetOneOfValues<int>(schema.GetProp("param13")));
-  EXPECT_EQ("integer", schema.GetProp("param14")->GetTypeAsString());
-  EXPECT_EQ((std::vector<int>{1, 2, 3, 4}),
-            GetOneOfValues<int>(schema.GetProp("param14")));
-  EXPECT_EQ("number", schema.GetProp("param15")->GetTypeAsString());
-  EXPECT_EQ((std::vector<double>{1.1, 2.2, 3.3}),
-            GetOneOfValues<double>(schema.GetProp("param15")));
-  EXPECT_EQ("number", schema.GetProp("param16")->GetTypeAsString());
-  EXPECT_EQ((std::vector<double>{1.1, 2.2, 3.3, 4.4}),
-            GetOneOfValues<double>(schema.GetProp("param16")));
-  EXPECT_EQ("string", schema.GetProp("param17")->GetTypeAsString());
-  EXPECT_EQ((std::vector<std::string>{"id1", "id2"}),
-            GetOneOfValues<std::string>(schema.GetProp("param17")));
-  EXPECT_EQ("string", schema.GetProp("param18")->GetTypeAsString());
-  EXPECT_EQ((std::vector<std::string>{"id1", "id3"}),
-            GetOneOfValues<std::string>(schema.GetProp("param18")));
-  EXPECT_EQ("integer", schema.GetProp("param19")->GetTypeAsString());
-  EXPECT_EQ(1, schema.GetProp("param19")->GetInt()->GetMinValue());
-  EXPECT_EQ(5, schema.GetProp("param19")->GetInt()->GetMaxValue());
-  EXPECT_EQ(49,
-            schema.GetProp("param20")->GetDefaultValue()->GetInt()->GetValue());
-  EXPECT_EQ(8,
-            schema.GetProp("param21")->GetDefaultValue()->GetInt()->GetValue());
-  EXPECT_EQ(123,
-            schema.GetProp("param22")->GetDefaultValue()->GetInt()->GetValue());
-}
-
-TEST(CommandSchema, ObjectSchema_UseDefaults) {
-  ObjectPropType prop;
-  const char* schema_str =
-      "{'properties':{"
-      "'param1':{'default':true},"
-      "'param2':{'default':2},"
-      "'param3':{'default':3.3},"
-      "'param4':{'default':'four'},"
-      "'param5':{'default':{'x':5,'y':6},"
-      "'properties':{'x':'integer','y':'integer'}},"
-      "'param6':{'default':[1,2,3]}"
-      "}}";
-  ASSERT_TRUE(
-      prop.FromJson(CreateDictionaryValue(schema_str).get(), nullptr, nullptr));
-
-  // Omit all.
-  auto value =
-      prop.CreatePropValue(*CreateDictionaryValue("{}").get(), nullptr);
-  ASSERT_NE(nullptr, value);
-  ValueMap obj = value->GetObject()->GetValue();
-  EXPECT_TRUE(obj["param1"]->GetBoolean()->GetValue());
-  EXPECT_EQ(2, obj["param2"]->GetInt()->GetValue());
-  EXPECT_DOUBLE_EQ(3.3, obj["param3"]->GetDouble()->GetValue());
-  EXPECT_EQ("four", obj["param4"]->GetString()->GetValue());
-  ValueMap param5 = obj["param5"]->GetObject()->GetValue();
-  EXPECT_EQ(5, param5["x"]->GetInt()->GetValue());
-  EXPECT_EQ(6, param5["y"]->GetInt()->GetValue());
-  ValueVector param6 = obj["param6"]->GetArray()->GetValue();
-  EXPECT_EQ((std::vector<int>{1, 2, 3}), GetArrayValues<int>(param6));
-
-  // Specify some.
-  const char* val_json =
-      "{"
-      "'param1':false,"
-      "'param3':33.3,"
-      "'param5':{'x':-5,'y':-6}"
-      "}";
-  value = prop.CreatePropValue(*CreateDictionaryValue(val_json).get(), nullptr);
-  ASSERT_NE(nullptr, value);
-  obj = value->GetObject()->GetValue();
-  EXPECT_FALSE(obj["param1"]->GetBoolean()->GetValue());
-  EXPECT_EQ(2, obj["param2"]->GetInt()->GetValue());
-  EXPECT_DOUBLE_EQ(33.3, obj["param3"]->GetDouble()->GetValue());
-  EXPECT_EQ("four", obj["param4"]->GetString()->GetValue());
-  param5 = obj["param5"]->GetObject()->GetValue();
-  EXPECT_EQ(-5, param5["x"]->GetInt()->GetValue());
-  EXPECT_EQ(-6, param5["y"]->GetInt()->GetValue());
-  param6 = obj["param6"]->GetArray()->GetValue();
-  EXPECT_EQ((std::vector<int>{1, 2, 3}), GetArrayValues<int>(param6));
-
-  // Specify all.
-  val_json =
-      "{"
-      "'param1':false,"
-      "'param2':22,"
-      "'param3':333.3,"
-      "'param4':'FOUR',"
-      "'param5':{'x':-55,'y':66},"
-      "'param6':[-1, 0]"
-      "}";
-  value = prop.CreatePropValue(*CreateDictionaryValue(val_json).get(), nullptr);
-  ASSERT_NE(nullptr, value);
-  obj = value->GetObject()->GetValue();
-  EXPECT_FALSE(obj["param1"]->GetBoolean()->GetValue());
-  EXPECT_EQ(22, obj["param2"]->GetInt()->GetValue());
-  EXPECT_DOUBLE_EQ(333.3, obj["param3"]->GetDouble()->GetValue());
-  EXPECT_EQ("FOUR", obj["param4"]->GetString()->GetValue());
-  param5 = obj["param5"]->GetObject()->GetValue();
-  EXPECT_EQ(-55, param5["x"]->GetInt()->GetValue());
-  EXPECT_EQ(66, param5["y"]->GetInt()->GetValue());
-  param6 = obj["param6"]->GetArray()->GetValue();
-  EXPECT_EQ((std::vector<int>{-1, 0}), GetArrayValues<int>(param6));
-}
-
-TEST(CommandSchema, ObjectSchema_FromJson_BaseSchema_Failures) {
-  ObjectSchema schema;
-  ErrorPtr error;
-  const char* schema_str =
-      "{"
-      "'param1':{}"
-      "}";
-  EXPECT_FALSE(schema.FromJson(CreateDictionaryValue(schema_str).get(), nullptr,
-                               &error));
-  EXPECT_EQ("no_type_info", error->GetFirstError()->GetCode());
-  error.reset();
-
-  schema_str =
-      "{"
-      "'param1':{'type':'foo'}"
-      "}";
-  EXPECT_FALSE(schema.FromJson(CreateDictionaryValue(schema_str).get(), nullptr,
-                               &error));
-  EXPECT_EQ("unknown_type", error->GetFirstError()->GetCode());
-  error.reset();
-
-  schema_str =
-      "{"
-      "'param1':[]"
-      "}";
-  EXPECT_FALSE(schema.FromJson(CreateDictionaryValue(schema_str).get(), nullptr,
-                               &error));
-  EXPECT_EQ("no_type_info", error->GetFirstError()->GetCode());
-  error.reset();
-
-  schema_str =
-      "{"
-      "'param1':{'minimum':'foo'}"
-      "}";
-  EXPECT_FALSE(schema.FromJson(CreateDictionaryValue(schema_str).get(), nullptr,
-                               &error));
-  EXPECT_EQ("type_mismatch", error->GetFirstError()->GetCode());
-  error.reset();
-
-  schema_str =
-      "{"
-      "'param1':[1,2.2]"
-      "}";
-  EXPECT_FALSE(schema.FromJson(CreateDictionaryValue(schema_str).get(), nullptr,
-                               &error));
-  EXPECT_EQ("type_mismatch", error->GetFirstError()->GetCode());
-  error.reset();
-
-  schema_str =
-      "{"
-      "'param1':{'minimum':1, 'enum':[1,2,3]}"  // can't have min/max & enum.
-      "}";
-  EXPECT_FALSE(schema.FromJson(CreateDictionaryValue(schema_str).get(), nullptr,
-                               &error));
-  EXPECT_EQ("unexpected_parameter", error->GetFirstError()->GetCode());
-  error.reset();
-
-  schema_str =
-      "{"
-      "'param1':{'maximum':1, 'blah':2}"  // 'blah' is unexpected.
-      "}";
-  EXPECT_FALSE(schema.FromJson(CreateDictionaryValue(schema_str).get(), nullptr,
-                               &error));
-  EXPECT_EQ("unexpected_parameter", error->GetFirstError()->GetCode());
-  error.reset();
-
-  schema_str =
-      "{"
-      "'param1':{'enum':[1,2,3],'default':5}"  // 'default' must be 1, 2, or 3.
-      "}";
-  EXPECT_FALSE(schema.FromJson(CreateDictionaryValue(schema_str).get(), nullptr,
-                               &error));
-  EXPECT_EQ("out_of_range", error->GetFirstError()->GetCode());
-  error.reset();
-
-  schema_str =
-      "{"
-      "'param1':[[1,2.3]]"
-      "}";
-  EXPECT_FALSE(schema.FromJson(CreateDictionaryValue(schema_str).get(), nullptr,
-                               &error));
-  EXPECT_EQ("type_mismatch", error->GetFirstError()->GetCode());
-  error.reset();
-
-  schema_str =
-      "{"
-      "'param1':[[1,2],[3,4],['blah']]"
-      "}";
-  EXPECT_FALSE(schema.FromJson(CreateDictionaryValue(schema_str).get(), nullptr,
-                               &error));
-  EXPECT_EQ("type_mismatch", error->GetFirstError()->GetCode());
-  error.reset();
-
-  schema_str =
-      "{"
-      "'param1':{'default':[]}"
-      "}";
-  EXPECT_FALSE(schema.FromJson(CreateDictionaryValue(schema_str).get(), nullptr,
-                               &error));
-  EXPECT_EQ("no_type_info", error->GetFirstError()->GetCode());
-  error.reset();
-
-  schema_str =
-      "{"
-      "'param1':[[[1]],[[2]]]"
-      "}";
-  EXPECT_FALSE(schema.FromJson(CreateDictionaryValue(schema_str).get(), nullptr,
-                               &error));
-  EXPECT_EQ("no_type_info", error->GetFirstError()->GetCode());
-  error.reset();
-
-  schema_str =
-      "{"
-      "'param1':{'enum':[[['foo']]]}"
-      "}";
-  EXPECT_FALSE(schema.FromJson(CreateDictionaryValue(schema_str).get(), nullptr,
-                               &error));
-  EXPECT_EQ("no_type_info", error->GetFirstError()->GetCode());
-  error.reset();
-
-  schema_str =
-      "{"
-      "'param1':{'default':[[1],[2]]}"
-      "}";
-  EXPECT_FALSE(schema.FromJson(CreateDictionaryValue(schema_str).get(), nullptr,
-                               &error));
-  EXPECT_EQ("no_type_info", error->GetFirstError()->GetCode());
-  error.reset();
-}
-
-TEST(CommandSchema, RequiredProperties_Integral) {
-  IntPropType prop;
-
-  prop.MakeRequired(false);
-  EXPECT_JSON_EQ("{'type':'integer'}", *prop.ToJson(true, false));
-  EXPECT_JSON_EQ("{'isRequired':false,'type':'integer'}",
-                 *prop.ToJson(true, true));
-
-  prop.MakeRequired(true);
-  EXPECT_JSON_EQ("{'type':'integer'}", *prop.ToJson(true, false));
-  EXPECT_JSON_EQ("{'isRequired':true,'type':'integer'}",
-                 *prop.ToJson(true, true));
-
-  IntPropType prop2;
-  EXPECT_TRUE(
-      prop2.FromJson(CreateDictionaryValue("{}").get(), &prop, nullptr));
-  EXPECT_TRUE(prop2.IsRequired());
-
-  EXPECT_TRUE(prop2.FromJson(
-      CreateDictionaryValue("{'isRequired': false}").get(), &prop, nullptr));
-  EXPECT_FALSE(prop2.IsRequired());
-
-  EXPECT_JSON_EQ("{'type':'integer'}", *prop2.ToJson(true, false));
-  EXPECT_JSON_EQ("{'isRequired':false,'type':'integer'}",
-                 *prop2.ToJson(true, true));
-}
-
-TEST(CommandSchema, RequiredProperties_Object) {
-  ObjectPropType obj_type;
-  auto schema = ObjectSchema::Create();
-  auto type = PropType::Create(ValueType::Int);
-  type->MakeRequired(true);
-  schema->AddProp("prop1", std::move(type));
-  type = PropType::Create(ValueType::String);
-  type->MakeRequired(false);
-  schema->AddProp("prop2", std::move(type));
-  type = PropType::Create(ValueType::Boolean);
-  type->MakeRequired(true);
-  schema->AddProp("prop3", std::move(type));
-  type = PropType::Create(ValueType::Array);
-  type->GetArray()->SetItemType(PropType::Create(ValueType::String));
-  schema->AddProp("prop4", std::move(type));
-  auto expected1 = R"({
-    'prop1': 'integer',
-    'prop2': 'string',
-    'prop3': 'boolean',
-    'prop4': {'items': 'string'}
-  })";
-  EXPECT_JSON_EQ(expected1, *schema->ToJson(false, false));
-  auto expected2 = R"({
-    'prop1': {'type':'integer','isRequired': true},
-    'prop2': {'type':'string','isRequired': false},
-    'prop3': {'type':'boolean','isRequired': true},
-    'prop4': {'items': 'string'}
-  })";
-  EXPECT_JSON_EQ(expected2, *schema->ToJson(false, true));
-
-  obj_type.SetObjectSchema(std::move(schema));
-  auto expected3 = R"({
-    'additionalProperties': false,
-    'properties': {
-      'prop1': 'integer',
-      'prop2': 'string',
-      'prop3': 'boolean',
-      'prop4': {'items': 'string'}
-    },
-    'required': ['prop1','prop3']
-  })";
-  EXPECT_JSON_EQ(expected3, *obj_type.ToJson(false, false));
-  EXPECT_JSON_EQ(expected3, *obj_type.ToJson(false, true));
-}
-
-TEST(CommandSchema, RequiredProperties_Schema_FromJson) {
-  ObjectSchema schema;
-  auto schema_str = R"({
-    'prop1': {'type':'integer','isRequired': true},
-    'prop2': {'type':'string','isRequired': false},
-    'prop3': 'boolean'
-  })";
-  EXPECT_TRUE(schema.FromJson(CreateDictionaryValue(schema_str).get(), nullptr,
-                              nullptr));
-  EXPECT_TRUE(schema.GetProp("prop1")->IsRequired());
-  EXPECT_FALSE(schema.GetProp("prop2")->IsRequired());
-  EXPECT_FALSE(schema.GetProp("prop3")->IsRequired());
-  EXPECT_JSON_EQ(schema_str, *schema.ToJson(false, true));
-}
-
-TEST(CommandSchema, RequiredProperties_Schema_FromJson_Inherit) {
-  ObjectSchema base_schema;
-  auto base_schema_str = R"({
-    'prop1': {'type':'integer','isRequired': true},
-    'prop2': {'type':'integer','isRequired': false},
-    'prop3': {'type':'integer','isRequired': true},
-    'prop4': {'type':'integer','isRequired': false}
-  })";
-  EXPECT_TRUE(base_schema.FromJson(CreateDictionaryValue(base_schema_str).get(),
-                                   nullptr, nullptr));
-  ObjectSchema schema;
-  auto schema_str = R"({
-    'prop1': {'isRequired': false},
-    'prop2': {'isRequired': true},
-    'prop3': {},
-    'prop4': 'integer'
-  })";
-  EXPECT_TRUE(schema.FromJson(CreateDictionaryValue(schema_str).get(),
-                              &base_schema, nullptr));
-  EXPECT_FALSE(schema.GetProp("prop1")->IsRequired());
-  EXPECT_TRUE(schema.GetProp("prop2")->IsRequired());
-  EXPECT_TRUE(schema.GetProp("prop3")->IsRequired());
-  EXPECT_FALSE(schema.GetProp("prop4")->IsRequired());
-  auto expected = R"({
-    'prop1': {'type':'integer','isRequired': false},
-    'prop2': {'type':'integer','isRequired': true},
-    'prop3': {},
-    'prop4': {}
-  })";
-  EXPECT_JSON_EQ(expected, *schema.ToJson(false, true));
-}
-
-TEST(CommandSchema, RequiredProperties_ObjectPropType_FromJson) {
-  ObjectPropType obj_type;
-  auto type_str = R"({
-    'properties': {
-      'prop1': 'integer',
-      'prop2': 'string',
-      'prop3': {'type':'boolean','isRequired':true},
-      'prop4': {'items': 'string','isRequired':false},
-      'prop5': {'type':'number','isRequired':true}
-    },
-    'required': ['prop1','prop3','prop4','prop5']
-  })";
-  EXPECT_TRUE(obj_type.FromJson(CreateDictionaryValue(type_str).get(), nullptr,
-                                nullptr));
-  EXPECT_TRUE(obj_type.GetObjectSchemaPtr()->GetProp("prop1")->IsRequired());
-  EXPECT_FALSE(obj_type.GetObjectSchemaPtr()->GetProp("prop2")->IsRequired());
-  EXPECT_TRUE(obj_type.GetObjectSchemaPtr()->GetProp("prop3")->IsRequired());
-  // 'required' takes precedence over 'isRequired'.
-  EXPECT_TRUE(obj_type.GetObjectSchemaPtr()->GetProp("prop4")->IsRequired());
-  EXPECT_TRUE(obj_type.GetObjectSchemaPtr()->GetProp("prop5")->IsRequired());
-}
-
-TEST(CommandSchema, RequiredProperties_Failures) {
-  ObjectPropType obj_type;
-  ErrorPtr error;
-
-  auto type_str = R"({
-    'properties': {
-      'prop1': 'integer',
-      'prop2': 'string'
-    },
-    'required': ['prop1','prop3','prop4']
-  })";
-  EXPECT_FALSE(obj_type.FromJson(CreateDictionaryValue(type_str).get(), nullptr,
-                                 &error));
-  EXPECT_EQ(errors::commands::kUnknownProperty, error->GetCode());
-  error.reset();
-
-  type_str = R"({
-    'properties': {
-      'prop1': 'integer',
-      'prop2': 'string'
-    },
-    'required': 'prop1'
-  })";
-  EXPECT_FALSE(obj_type.FromJson(CreateDictionaryValue(type_str).get(), nullptr,
-                                 &error));
-  EXPECT_EQ(errors::commands::kInvalidObjectSchema, error->GetCode());
-  error.reset();
-}
-
-TEST(CommandSchema, ObjectSchema_UseRequired) {
-  ObjectPropType prop;
-  auto schema_str = R"({
-    'properties':{
-      'param1':'integer',
-      'param2':'integer',
-      'param3':{'default':3},
-      'param4':{'default':4}
-    },
-    'required':['param1','param3']
-  })";
-  ASSERT_TRUE(
-      prop.FromJson(CreateDictionaryValue(schema_str).get(), nullptr, nullptr));
-
-  auto val_json = R"({
-    'param1':10,
-    'param2':20,
-    'param3':30,
-    'param4':40
-  })";
-  auto value =
-      prop.CreatePropValue(*CreateDictionaryValue(val_json).get(), nullptr);
-  ASSERT_NE(nullptr, value);
-  ValueMap obj = value->GetObject()->GetValue();
-  EXPECT_EQ(10, obj["param1"]->GetInt()->GetValue());
-  EXPECT_EQ(20, obj["param2"]->GetInt()->GetValue());
-  EXPECT_EQ(30, obj["param3"]->GetInt()->GetValue());
-  EXPECT_EQ(40, obj["param4"]->GetInt()->GetValue());
-
-  val_json = "{'param1':100}";
-  value = prop.CreatePropValue(*CreateDictionaryValue(val_json).get(), nullptr);
-  ASSERT_NE(nullptr, value);
-  obj = value->GetObject()->GetValue();
-  EXPECT_EQ(3u, obj.size());
-
-  EXPECT_EQ(100, obj["param1"]->GetInt()->GetValue());
-  EXPECT_EQ(obj.end(), obj.find("param2"));
-  EXPECT_EQ(3, obj["param3"]->GetInt()->GetValue());
-  EXPECT_EQ(4, obj["param4"]->GetInt()->GetValue());
-}
-
-TEST(CommandSchema, ObjectSchema_UseRequired_Failure) {
-  ObjectPropType prop;
-  auto schema_str = R"({
-    'properties':{
-      'param1':'integer',
-      'param2':'integer',
-      'param3':{'default':3},
-      'param4':{'default':4}
-    },
-    'required':['param1','param3']
-  })";
-  ASSERT_TRUE(
-      prop.FromJson(CreateDictionaryValue(schema_str).get(), nullptr, nullptr));
-
-  auto val_json = "{'param2':20}";
-  ErrorPtr error;
-  auto value =
-      prop.CreatePropValue(*CreateDictionaryValue(val_json).get(), &error);
-  ASSERT_EQ(nullptr, value);
-  EXPECT_EQ(errors::commands::kPropertyMissing, error->GetCode());
-}
-
-}  // namespace weave
diff --git a/src/commands/prop_constraints.cc b/src/commands/prop_constraints.cc
deleted file mode 100644
index b7e9cf6..0000000
--- a/src/commands/prop_constraints.cc
+++ /dev/null
@@ -1,202 +0,0 @@
-// 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/commands/prop_constraints.h"
-
-#include <base/json/json_writer.h>
-#include <base/logging.h>
-
-#include "src/commands/prop_values.h"
-#include "src/commands/schema_constants.h"
-#include "src/string_utils.h"
-
-namespace weave {
-
-namespace {
-
-// Helper function to convert a property value to string, which is used for
-// error reporting.
-std::string PropValueToString(const PropValue& value) {
-  std::string result;
-  auto json = value.ToJson();
-  CHECK(json);
-  base::JSONWriter::Write(*json, &result);
-  return result;
-}
-
-}  // anonymous namespace
-
-// Constraint ----------------------------------------------------------------
-Constraint::~Constraint() {}
-
-bool Constraint::ReportErrorLessThan(ErrorPtr* error,
-                                     const std::string& val,
-                                     const std::string& limit) {
-  Error::AddToPrintf(error, FROM_HERE, errors::commands::kDomain,
-                     errors::commands::kOutOfRange,
-                     "Value %s is out of range. It must not be less than %s",
-                     val.c_str(), limit.c_str());
-  return false;
-}
-
-bool Constraint::ReportErrorGreaterThan(ErrorPtr* error,
-                                        const std::string& val,
-                                        const std::string& limit) {
-  Error::AddToPrintf(error, FROM_HERE, errors::commands::kDomain,
-                     errors::commands::kOutOfRange,
-                     "Value %s is out of range. It must not be greater than %s",
-                     val.c_str(), limit.c_str());
-  return false;
-}
-
-bool Constraint::ReportErrorNotOneOf(ErrorPtr* error,
-                                     const std::string& val,
-                                     const std::vector<std::string>& values) {
-  Error::AddToPrintf(error, FROM_HERE, errors::commands::kDomain,
-                     errors::commands::kOutOfRange,
-                     "Value %s is invalid. Expected one of [%s]", val.c_str(),
-                     Join(",", values).c_str());
-  return false;
-}
-
-void Constraint::AddToJsonDict(base::DictionaryValue* dict,
-                               bool overridden_only) const {
-  if (!overridden_only || HasOverriddenAttributes()) {
-    auto value = ToJson();
-    CHECK(value);
-    dict->SetWithoutPathExpansion(GetDictKey(), value.release());
-  }
-}
-
-// ConstraintStringLength -----------------------------------------------------
-ConstraintStringLength::ConstraintStringLength(
-    const InheritableAttribute<int>& limit)
-    : limit_(limit) {}
-ConstraintStringLength::ConstraintStringLength(int limit) : limit_(limit) {}
-
-bool ConstraintStringLength::HasOverriddenAttributes() const {
-  return !limit_.is_inherited;
-}
-
-std::unique_ptr<base::Value> ConstraintStringLength::ToJson() const {
-  return TypedValueToJson(limit_.value);
-}
-
-// ConstraintStringLengthMin --------------------------------------------------
-ConstraintStringLengthMin::ConstraintStringLengthMin(
-    const InheritableAttribute<int>& limit)
-    : ConstraintStringLength(limit) {}
-ConstraintStringLengthMin::ConstraintStringLengthMin(int limit)
-    : ConstraintStringLength(limit) {}
-
-bool ConstraintStringLengthMin::Validate(const PropValue& value,
-                                         ErrorPtr* error) const {
-  CHECK(value.GetString()) << "Expecting a string value for this constraint";
-  const std::string& str = value.GetString()->GetValue();
-  int length = static_cast<int>(str.size());
-  if (length < limit_.value) {
-    if (limit_.value == 1) {
-      Error::AddTo(error, FROM_HERE, errors::commands::kDomain,
-                   errors::commands::kOutOfRange, "String must not be empty");
-    } else {
-      Error::AddToPrintf(error, FROM_HERE, errors::commands::kDomain,
-                         errors::commands::kOutOfRange,
-                         "String must be at least %d characters long,"
-                         " actual length of string '%s' is %d",
-                         limit_.value, str.c_str(), length);
-    }
-    return false;
-  }
-  return true;
-}
-
-std::unique_ptr<Constraint> ConstraintStringLengthMin::Clone() const {
-  return std::unique_ptr<Constraint>{new ConstraintStringLengthMin{limit_}};
-}
-
-std::unique_ptr<Constraint> ConstraintStringLengthMin::CloneAsInherited()
-    const {
-  return std::unique_ptr<Constraint>{
-      new ConstraintStringLengthMin{limit_.value}};
-}
-
-// ConstraintStringLengthMax --------------------------------------------------
-ConstraintStringLengthMax::ConstraintStringLengthMax(
-    const InheritableAttribute<int>& limit)
-    : ConstraintStringLength(limit) {}
-ConstraintStringLengthMax::ConstraintStringLengthMax(int limit)
-    : ConstraintStringLength(limit) {}
-
-bool ConstraintStringLengthMax::Validate(const PropValue& value,
-                                         ErrorPtr* error) const {
-  CHECK(value.GetString()) << "Expecting a string value for this constraint";
-  const std::string& str = value.GetString()->GetValue();
-  int length = static_cast<int>(str.size());
-  if (length > limit_.value) {
-    Error::AddToPrintf(error, FROM_HERE, errors::commands::kDomain,
-                       errors::commands::kOutOfRange,
-                       "String must be no more than %d character(s) "
-                       "long, actual length of string '%s' is %d",
-                       limit_.value, str.c_str(), length);
-    return false;
-  }
-  return true;
-}
-
-std::unique_ptr<Constraint> ConstraintStringLengthMax::Clone() const {
-  return std::unique_ptr<Constraint>{new ConstraintStringLengthMax{limit_}};
-}
-
-std::unique_ptr<Constraint> ConstraintStringLengthMax::CloneAsInherited()
-    const {
-  return std::unique_ptr<Constraint>{
-      new ConstraintStringLengthMax{limit_.value}};
-}
-
-// ConstraintOneOf --------------------------------------------------
-ConstraintOneOf::ConstraintOneOf(InheritableAttribute<ValueVector> set)
-    : set_(std::move(set)) {}
-ConstraintOneOf::ConstraintOneOf(ValueVector set) : set_(std::move(set)) {}
-
-bool ConstraintOneOf::Validate(const PropValue& value, ErrorPtr* error) const {
-  for (const auto& item : set_.value) {
-    if (value.IsEqual(item.get()))
-      return true;
-  }
-  std::vector<std::string> choice_list;
-  choice_list.reserve(set_.value.size());
-  for (const auto& item : set_.value) {
-    choice_list.push_back(PropValueToString(*item));
-  }
-  return ReportErrorNotOneOf(error, PropValueToString(value), choice_list);
-}
-
-std::unique_ptr<Constraint> ConstraintOneOf::Clone() const {
-  InheritableAttribute<ValueVector> attr;
-  attr.is_inherited = set_.is_inherited;
-  attr.value.reserve(set_.value.size());
-  for (const auto& prop_value : set_.value) {
-    attr.value.push_back(prop_value->Clone());
-  }
-  return std::unique_ptr<Constraint>{new ConstraintOneOf{std::move(attr)}};
-}
-
-std::unique_ptr<Constraint> ConstraintOneOf::CloneAsInherited() const {
-  ValueVector cloned;
-  cloned.reserve(set_.value.size());
-  for (const auto& prop_value : set_.value) {
-    cloned.push_back(prop_value->Clone());
-  }
-  return std::unique_ptr<Constraint>{new ConstraintOneOf{std::move(cloned)}};
-}
-
-std::unique_ptr<base::Value> ConstraintOneOf::ToJson() const {
-  return TypedValueToJson(set_.value);
-}
-
-const char* ConstraintOneOf::GetDictKey() const {
-  return commands::attributes::kOneOf_Enum;
-}
-
-}  // namespace weave
diff --git a/src/commands/prop_constraints.h b/src/commands/prop_constraints.h
deleted file mode 100644
index 53a4d93..0000000
--- a/src/commands/prop_constraints.h
+++ /dev/null
@@ -1,315 +0,0 @@
-// 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_COMMANDS_PROP_CONSTRAINTS_H_
-#define LIBWEAVE_SRC_COMMANDS_PROP_CONSTRAINTS_H_
-
-#include <string>
-#include <type_traits>
-#include <vector>
-
-#include <base/macros.h>
-#include <base/values.h>
-#include <weave/error.h>
-
-#include "src/commands/prop_values.h"
-#include "src/commands/schema_constants.h"
-#include "src/commands/schema_utils.h"
-#include "src/string_utils.h"
-
-namespace weave {
-
-enum class ConstraintType { Min, Max, StringLengthMin, StringLengthMax, OneOf };
-
-// Abstract base class for all parameter constraints. Many constraints are
-// type-dependent. Thus, a numeric parameter could have "minimum" and/or
-// "maximum" constraints specified. Some constraints, such as "OneOf" apply to
-// any data type.
-class Constraint {
- public:
-  Constraint() = default;
-  virtual ~Constraint();
-
-  // Gets the constraint type.
-  virtual ConstraintType GetType() const = 0;
-
-  // Checks if any of the constraint properties/attributes are overridden
-  // from their base schema definition. If the constraint is inherited, then
-  // it will not be written to JSON when saving partial schema.
-  virtual bool HasOverriddenAttributes() const = 0;
-
-  // Validates a parameter against the constraint. Returns true if parameter
-  // value satisfies the constraint, otherwise fills the optional |error| with
-  // the details for the failure.
-  virtual bool Validate(const PropValue& value, ErrorPtr* error) const = 0;
-
-  // Makes a full copy of this Constraint instance.
-  virtual std::unique_ptr<Constraint> Clone() const = 0;
-
-  // Makes a copy of the constraint object, marking all the attributes
-  // as inherited from the original definition.
-  virtual std::unique_ptr<Constraint> CloneAsInherited() const = 0;
-
-  // Saves the constraint into the specified JSON |dict| object, representing
-  // the object schema. If |overridden_only| is set to true, then the
-  // inherited constraints will not be added to the schema object.
-  virtual void AddToJsonDict(base::DictionaryValue* dict,
-                             bool overridden_only) const;
-
-  // Saves the value of constraint to JSON value. E.g., if the numeric
-  // constraint was defined as {"minimum":20} this will create a JSON value
-  // of 20. The current design implies that each constraint has one value
-  // only. If this assumption changes, this interface needs to be updated
-  // accordingly.
-  virtual std::unique_ptr<base::Value> ToJson() const = 0;
-
-  // Overloaded by the concrete class implementation, it should return the
-  // JSON object property name to store the constraint's value as.
-  // E.g., if the numeric constraint was defined as {"minimum":20} this
-  // method should return "minimum".
-  virtual const char* GetDictKey() const = 0;
-
- protected:
-  // Static helper methods to format common constraint validation errors.
-  // They fill the |error| object with specific error message.
-  // Since these functions could be used by constraint objects for various
-  // data types, the values used in validation are expected to be
-  // send as strings already.
-  static bool ReportErrorLessThan(ErrorPtr* error,
-                                  const std::string& val,
-                                  const std::string& limit);
-  static bool ReportErrorGreaterThan(ErrorPtr* error,
-                                     const std::string& val,
-                                     const std::string& limit);
-
-  static bool ReportErrorNotOneOf(ErrorPtr* error,
-                                  const std::string& val,
-                                  const std::vector<std::string>& values);
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(Constraint);
-};
-
-// ConstraintMinMaxBase is a base class for numeric Minimum and Maximum
-// constraints.
-template <typename T>
-class ConstraintMinMaxBase : public Constraint {
- public:
-  explicit ConstraintMinMaxBase(const InheritableAttribute<T>& limit)
-      : limit_(limit) {}
-  explicit ConstraintMinMaxBase(const T& limit) : limit_(limit) {}
-
-  // Implementation of Constraint::HasOverriddenAttributes().
-  bool HasOverriddenAttributes() const override { return !limit_.is_inherited; }
-
-  // Implementation of Constraint::ToJson().
-  std::unique_ptr<base::Value> ToJson() const override {
-    return TypedValueToJson(limit_.value);
-  }
-
-  // Stores the upper/lower value limit for maximum/minimum constraint.
-  // |limit_.is_inherited| indicates whether the constraint is inherited
-  // from base schema or overridden.
-  InheritableAttribute<T> limit_;
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(ConstraintMinMaxBase);
-};
-
-// Implementation of Minimum value constraint for Integer/Double types.
-template <typename T>
-class ConstraintMin : public ConstraintMinMaxBase<T> {
- public:
-  explicit ConstraintMin(const InheritableAttribute<T>& limit)
-      : ConstraintMinMaxBase<T>(limit) {}
-  explicit ConstraintMin(const T& limit) : ConstraintMinMaxBase<T>(limit) {}
-
-  // Implementation of Constraint::GetType().
-  ConstraintType GetType() const override { return ConstraintType::Min; }
-
-  // Implementation of Constraint::Validate().
-  bool Validate(const PropValue& value, ErrorPtr* error) const override {
-    const T& v = static_cast<const TypedValueBase<T>&>(value).GetValue();
-    if (v < this->limit_.value) {
-      return this->ReportErrorLessThan(error, std::to_string(v),
-                                       std::to_string(this->limit_.value));
-    }
-    return true;
-  }
-
-  // Implementation of Constraint::Clone().
-  std::unique_ptr<Constraint> Clone() const override {
-    return std::unique_ptr<Constraint>{new ConstraintMin{this->limit_}};
-  }
-
-  // Implementation of Constraint::CloneAsInherited().
-  std::unique_ptr<Constraint> CloneAsInherited() const override {
-    return std::unique_ptr<Constraint>{new ConstraintMin{this->limit_.value}};
-  }
-
-  // Implementation of Constraint::GetDictKey().
-  const char* GetDictKey() const override {
-    return commands::attributes::kNumeric_Min;
-  }
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(ConstraintMin);
-};
-
-// Implementation of Maximum value constraint for Integer/Double types.
-template <typename T>
-class ConstraintMax : public ConstraintMinMaxBase<T> {
- public:
-  explicit ConstraintMax(const InheritableAttribute<T>& limit)
-      : ConstraintMinMaxBase<T>(limit) {}
-  explicit ConstraintMax(const T& limit) : ConstraintMinMaxBase<T>(limit) {}
-
-  // Implementation of Constraint::GetType().
-  ConstraintType GetType() const override { return ConstraintType::Max; }
-
-  // Implementation of Constraint::Validate().
-  bool Validate(const PropValue& value, ErrorPtr* error) const override {
-    const T& v = static_cast<const TypedValueBase<T>&>(value).GetValue();
-    if (v > this->limit_.value)
-      return this->ReportErrorGreaterThan(error, std::to_string(v),
-                                          std::to_string(this->limit_.value));
-    return true;
-  }
-
-  // Implementation of Constraint::Clone().
-  std::unique_ptr<Constraint> Clone() const override {
-    return std::unique_ptr<Constraint>{new ConstraintMax{this->limit_}};
-  }
-
-  // Implementation of Constraint::CloneAsInherited().
-  std::unique_ptr<Constraint> CloneAsInherited() const override {
-    return std::unique_ptr<Constraint>{new ConstraintMax{this->limit_.value}};
-  }
-
-  // Implementation of Constraint::GetDictKey().
-  const char* GetDictKey() const override {
-    return commands::attributes::kNumeric_Max;
-  }
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(ConstraintMax);
-};
-
-// ConstraintStringLength is a base class for Minimum/Maximum string length
-// constraints, similar to ConstraintMinMaxBase of numeric types.
-class ConstraintStringLength : public Constraint {
- public:
-  explicit ConstraintStringLength(const InheritableAttribute<int>& limit);
-  explicit ConstraintStringLength(int limit);
-
-  // Implementation of Constraint::HasOverriddenAttributes().
-  bool HasOverriddenAttributes() const override;
-  // Implementation of Constraint::ToJson().
-  std::unique_ptr<base::Value> ToJson() const override;
-
-  // Stores the upper/lower value limit for string length constraint.
-  // |limit_.is_inherited| indicates whether the constraint is inherited
-  // from base schema or overridden.
-  InheritableAttribute<int> limit_;
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(ConstraintStringLength);
-};
-
-// Implementation of Minimum string length constraint.
-class ConstraintStringLengthMin : public ConstraintStringLength {
- public:
-  explicit ConstraintStringLengthMin(const InheritableAttribute<int>& limit);
-  explicit ConstraintStringLengthMin(int limit);
-
-  // Implementation of Constraint::GetType().
-  ConstraintType GetType() const override {
-    return ConstraintType::StringLengthMin;
-  }
-
-  // Implementation of Constraint::Validate().
-  bool Validate(const PropValue& value, ErrorPtr* error) const override;
-
-  // Implementation of Constraint::Clone().
-  std::unique_ptr<Constraint> Clone() const override;
-
-  // Implementation of Constraint::CloneAsInherited().
-  std::unique_ptr<Constraint> CloneAsInherited() const override;
-  // Implementation of Constraint::GetDictKey().
-  const char* GetDictKey() const override {
-    return commands::attributes::kString_MinLength;
-  }
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(ConstraintStringLengthMin);
-};
-
-// Implementation of Maximum string length constraint.
-class ConstraintStringLengthMax : public ConstraintStringLength {
- public:
-  explicit ConstraintStringLengthMax(const InheritableAttribute<int>& limit);
-  explicit ConstraintStringLengthMax(int limit);
-
-  // Implementation of Constraint::GetType().
-  ConstraintType GetType() const override {
-    return ConstraintType::StringLengthMax;
-  }
-
-  // Implementation of Constraint::Validate().
-  bool Validate(const PropValue& value, ErrorPtr* error) const override;
-
-  // Implementation of Constraint::Clone().
-  std::unique_ptr<Constraint> Clone() const override;
-
-  // Implementation of Constraint::CloneAsInherited().
-  std::unique_ptr<Constraint> CloneAsInherited() const override;
-
-  // Implementation of Constraint::GetDictKey().
-  const char* GetDictKey() const override {
-    return commands::attributes::kString_MaxLength;
-  }
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(ConstraintStringLengthMax);
-};
-
-// Implementation of OneOf constraint for different data types.
-class ConstraintOneOf : public Constraint {
- public:
-  explicit ConstraintOneOf(InheritableAttribute<ValueVector> set);
-  explicit ConstraintOneOf(ValueVector set);
-
-  // Implementation of Constraint::GetType().
-  ConstraintType GetType() const override { return ConstraintType::OneOf; }
-
-  // Implementation of Constraint::HasOverriddenAttributes().
-  bool HasOverriddenAttributes() const override { return !set_.is_inherited; }
-
-  // Implementation of Constraint::Validate().
-  bool Validate(const PropValue& value, ErrorPtr* error) const override;
-
-  // Implementation of Constraint::Clone().
-  std::unique_ptr<Constraint> Clone() const override;
-
-  // Implementation of Constraint::CloneAsInherited().
-  std::unique_ptr<Constraint> CloneAsInherited() const override;
-
-  // Implementation of Constraint::ToJson().
-  std::unique_ptr<base::Value> ToJson() const override;
-
-  // Implementation of Constraint::GetDictKey().
-  const char* GetDictKey() const override;
-
-  // Stores the list of acceptable values for the parameter.
-  // |set_.is_inherited| indicates whether the constraint is inherited
-  // from base schema or overridden.
-  InheritableAttribute<ValueVector> set_;
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(ConstraintOneOf);
-};
-
-}  // namespace weave
-
-#endif  // LIBWEAVE_SRC_COMMANDS_PROP_CONSTRAINTS_H_
diff --git a/src/commands/prop_types.cc b/src/commands/prop_types.cc
deleted file mode 100644
index def68b1..0000000
--- a/src/commands/prop_types.cc
+++ /dev/null
@@ -1,655 +0,0 @@
-// 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/commands/prop_types.h"
-
-#include <algorithm>
-#include <limits>
-#include <set>
-
-#include <base/json/json_writer.h>
-#include <base/logging.h>
-#include <base/values.h>
-
-#include "src/commands/object_schema.h"
-#include "src/commands/prop_values.h"
-#include "src/commands/schema_constants.h"
-
-namespace weave {
-
-// PropType -------------------------------------------------------------------
-PropType::PropType() {}
-
-PropType::~PropType() {}
-
-std::string PropType::GetTypeAsString() const {
-  return GetTypeStringFromType(GetType());
-}
-
-bool PropType::HasOverriddenAttributes() const {
-  if (default_.value && !default_.is_inherited)
-    return true;
-
-  for (const auto& pair : constraints_) {
-    if (pair.second->HasOverriddenAttributes())
-      return true;
-  }
-  return false;
-}
-
-bool PropType::IsRequired() const {
-  return required_.value;
-}
-
-void PropType::MakeRequired(bool required) {
-  required_.value = required;
-  required_.is_inherited = false;
-}
-
-std::unique_ptr<base::Value> PropType::ToJson(bool full_schema,
-                                              bool in_command_def) const {
-  // Determine if we need to output "isRequired" attribute.
-  const bool include_required = in_command_def && !required_.is_inherited;
-
-  // If we must include "isRequired" attribute, then treat this as "full schema"
-  // request because there could be cases where we have just this attribute and
-  // won't be able to infer the type from the constraints only.
-  if (include_required)
-    full_schema = true;
-
-  if (!full_schema && !HasOverriddenAttributes()) {
-    if (based_on_schema_)
-      return std::unique_ptr<base::Value>(new base::DictionaryValue);
-    return TypedValueToJson(GetTypeAsString());
-  }
-
-  std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue);
-  if (full_schema) {
-    // If we are asked for full_schema definition, then we need to output every
-    // parameter property, including the "type", and any constraints.
-    // So, we write the "type" only if asked for full schema.
-    // Otherwise we will be able to infer the parameter type based on
-    // the constraints and their types.
-    // That is, the following JSONs could possibly define a parameter:
-    // {'type':'integer'} -> explicit "integer" with no constraints
-    // {'minimum':10} -> no type specified, but since we have "minimum"
-    //                   and 10 is integer, than this is an integer
-    //                   parameter with min constraint.
-    // {'enum':[1,2,3]} -> integer with OneOf constraint.
-    // And so is this: [1,2,3] -> an array of ints assume it's an "int" enum.
-    dict->SetString(commands::attributes::kType, GetTypeAsString());
-  }
-
-  if (!full_schema && constraints_.size() == 1) {
-    // If we are not asked for full schema, and we have only one constraint
-    // which is OneOf, we short-circuit the whole thing and return just
-    // the array [1,2,3] instead of an object with "enum" property like:
-    // {'enum':[1,2,3]}
-    auto p = constraints_.find(ConstraintType::OneOf);
-    if (p != constraints_.end()) {
-      return p->second->ToJson();
-    }
-  }
-
-  for (const auto& pair : constraints_)
-    pair.second->AddToJsonDict(dict.get(), !full_schema);
-
-  if (default_.value && (full_schema || !default_.is_inherited)) {
-    auto def_val = default_.value->ToJson();
-    CHECK(def_val);
-    dict->Set(commands::attributes::kDefault, def_val.release());
-  }
-
-  if (include_required)
-    dict->SetBoolean(commands::attributes::kIsRequired, required_.value);
-  return std::unique_ptr<base::Value>(dict.release());
-}
-
-std::unique_ptr<PropType> PropType::Clone() const {
-  auto cloned = PropType::Create(GetType());
-  cloned->based_on_schema_ = based_on_schema_;
-  for (const auto& pair : constraints_) {
-    cloned->constraints_.insert(
-        std::make_pair(pair.first, pair.second->Clone()));
-  }
-  cloned->default_.is_inherited = default_.is_inherited;
-  if (default_.value)
-    cloned->default_.value = default_.value->Clone();
-  cloned->required_ = required_;
-  return cloned;
-}
-
-bool PropType::FromJson(const base::DictionaryValue* value,
-                        const PropType* base_schema,
-                        ErrorPtr* error) {
-  if (base_schema && base_schema->GetType() != GetType()) {
-    Error::AddToPrintf(error, FROM_HERE, errors::commands::kDomain,
-                       errors::commands::kPropTypeChanged,
-                       "Redefining a property of type %s as %s",
-                       base_schema->GetTypeAsString().c_str(),
-                       GetTypeAsString().c_str());
-    return false;
-  }
-  based_on_schema_ = (base_schema != nullptr);
-  constraints_.clear();
-  // Add the well-known object properties first (like "type", "displayName",
-  // "default") to the list of "processed" keys so we do not complain about them
-  // when we check for unknown/unexpected keys below.
-  std::set<std::string> processed_keys{
-      commands::attributes::kType, commands::attributes::kDisplayName,
-      commands::attributes::kDefault, commands::attributes::kIsRequired,
-  };
-  if (!ObjectSchemaFromJson(value, base_schema, &processed_keys, error))
-    return false;
-  if (base_schema) {
-    for (const auto& pair : base_schema->GetConstraints()) {
-      constraints_.insert(
-          std::make_pair(pair.first, pair.second->CloneAsInherited()));
-    }
-  }
-  if (!ConstraintsFromJson(value, &processed_keys, error))
-    return false;
-
-  // Now make sure there are no unexpected/unknown keys in the property schema
-  // definition object.
-  base::DictionaryValue::Iterator iter(*value);
-  while (!iter.IsAtEnd()) {
-    std::string key = iter.key();
-    if (processed_keys.find(key) == processed_keys.end()) {
-      Error::AddToPrintf(error, FROM_HERE, errors::commands::kDomain,
-                         errors::commands::kUnknownProperty,
-                         "Unexpected property '%s'", key.c_str());
-      return false;
-    }
-    iter.Advance();
-  }
-
-  // Read the "isRequired" attribute, if specified.
-  bool required = false;
-  if (value->GetBoolean(commands::attributes::kIsRequired, &required)) {
-    required_.value = required;
-    required_.is_inherited = false;
-  } else if (base_schema) {
-    // If we have the base schema, inherit the type's required value from it.
-    if (base_schema->required_.value)
-      required_.value = base_schema->required_.value;
-    required_.is_inherited = true;
-  }
-
-  // Read the default value, if specified.
-  // We need to do this last since the current type definition must be complete,
-  // so we can parse and validate the value of the default.
-  const base::Value* defval = nullptr;  // Owned by value
-  if (value->GetWithoutPathExpansion(commands::attributes::kDefault, &defval)) {
-    std::unique_ptr<PropValue> prop_value = CreatePropValue(*defval, error);
-    if (!prop_value) {
-      Error::AddToPrintf(error, FROM_HERE, errors::commands::kDomain,
-                         errors::commands::kInvalidPropValue,
-                         "Invalid value for property '%s'",
-                         commands::attributes::kDefault);
-      return false;
-    }
-    default_.value = std::move(prop_value);
-    default_.is_inherited = false;
-  } else if (base_schema) {
-    // If we have the base schema, inherit the type's default value from it.
-    // It doesn't matter if the base schema actually has a default value
-    // specified or not. If it doesn't, then the current type definition will
-    // have no default value set either (|default_.value| is a unique_ptr to
-    // PropValue, which can be set to nullptr).
-    if (base_schema->default_.value)
-      default_.value = base_schema->default_.value->Clone();
-    default_.is_inherited = true;
-  }
-  return true;
-}
-
-void PropType::AddConstraint(std::unique_ptr<Constraint> constraint) {
-  constraints_[constraint->GetType()] = std::move(constraint);
-}
-
-void PropType::RemoveConstraint(ConstraintType constraint_type) {
-  constraints_.erase(constraint_type);
-}
-
-void PropType::RemoveAllConstraints() {
-  constraints_.clear();
-}
-
-const Constraint* PropType::GetConstraint(
-    ConstraintType constraint_type) const {
-  auto p = constraints_.find(constraint_type);
-  return p != constraints_.end() ? p->second.get() : nullptr;
-}
-
-Constraint* PropType::GetConstraint(ConstraintType constraint_type) {
-  auto p = constraints_.find(constraint_type);
-  return p != constraints_.end() ? p->second.get() : nullptr;
-}
-
-bool PropType::ValidateConstraints(const PropValue& value,
-                                   ErrorPtr* error) const {
-  for (const auto& pair : constraints_) {
-    if (!pair.second->Validate(value, error))
-      return false;
-  }
-  return true;
-}
-
-const PropType::TypeMap& PropType::GetTypeMap() {
-  static TypeMap map = {
-      {ValueType::Int, "integer"},   {ValueType::Double, "number"},
-      {ValueType::String, "string"}, {ValueType::Boolean, "boolean"},
-      {ValueType::Object, "object"}, {ValueType::Array, "array"},
-  };
-  return map;
-}
-
-std::string PropType::GetTypeStringFromType(ValueType type) {
-  for (const auto& pair : GetTypeMap()) {
-    if (pair.first == type)
-      return pair.second;
-  }
-  LOG(FATAL) << "Type map is missing a type";
-  return std::string();
-}
-
-bool PropType::GetTypeFromTypeString(const std::string& name, ValueType* type) {
-  for (const auto& pair : GetTypeMap()) {
-    if (pair.second == name) {
-      *type = pair.first;
-      return true;
-    }
-  }
-  return false;
-}
-
-std::unique_ptr<PropType> PropType::Create(ValueType type) {
-  PropType* prop = nullptr;
-  switch (type) {
-    case ValueType::Int:
-      prop = new IntPropType;
-      break;
-    case ValueType::Double:
-      prop = new DoublePropType;
-      break;
-    case ValueType::String:
-      prop = new StringPropType;
-      break;
-    case ValueType::Boolean:
-      prop = new BooleanPropType;
-      break;
-    case ValueType::Object:
-      prop = new ObjectPropType;
-      break;
-    case ValueType::Array:
-      prop = new ArrayPropType;
-      break;
-  }
-  return std::unique_ptr<PropType>(prop);
-}
-
-template <typename T>
-static std::unique_ptr<Constraint> LoadOneOfConstraint(
-    const base::DictionaryValue* value,
-    const PropType* prop_type,
-    ErrorPtr* error) {
-  std::unique_ptr<Constraint> constraint;
-  const base::Value* list = nullptr;  // Owned by |value|
-  CHECK(value->Get(commands::attributes::kOneOf_Enum, &list))
-      << "'enum' property missing in JSON dictionary";
-  ValueVector choice_list;
-  ArrayPropType array_type;
-  array_type.SetItemType(prop_type->Clone());
-  if (!TypedValueFromJson(list, &array_type, &choice_list, error))
-    return constraint;
-  InheritableAttribute<ValueVector> val(std::move(choice_list), false);
-  constraint.reset(new ConstraintOneOf{std::move(val)});
-  return constraint;
-}
-
-template <class ConstraintClass, typename T>
-static std::unique_ptr<Constraint> LoadMinMaxConstraint(
-    const char* dict_key,
-    const base::DictionaryValue* value,
-    ErrorPtr* error) {
-  std::unique_ptr<Constraint> constraint;
-  InheritableAttribute<T> limit;
-
-  const base::Value* src_val = nullptr;
-  CHECK(value->Get(dict_key, &src_val)) << "Unable to get min/max constraints";
-  if (!TypedValueFromJson(src_val, nullptr, &limit.value, error))
-    return constraint;
-  limit.is_inherited = false;
-
-  constraint.reset(new ConstraintClass{limit});
-  return constraint;
-}
-
-// PropTypeBase ----------------------------------------------------------------
-
-template <class Derived, class Value, typename T>
-bool PropTypeBase<Derived, Value, T>::ConstraintsFromJson(
-    const base::DictionaryValue* value,
-    std::set<std::string>* processed_keys,
-    ErrorPtr* error) {
-  if (!PropType::ConstraintsFromJson(value, processed_keys, error))
-    return false;
-
-  if (value->HasKey(commands::attributes::kOneOf_Enum)) {
-    auto type = Clone();
-    type->RemoveAllConstraints();
-    auto constraint = LoadOneOfConstraint<T>(value, type.get(), error);
-    if (!constraint)
-      return false;
-    this->AddConstraint(std::move(constraint));
-    this->RemoveConstraint(ConstraintType::Min);
-    this->RemoveConstraint(ConstraintType::Max);
-    processed_keys->insert(commands::attributes::kOneOf_Enum);
-  }
-
-  return true;
-}
-
-// NumericPropTypeBase ---------------------------------------------------------
-
-template <class Derived, class Value, typename T>
-bool NumericPropTypeBase<Derived, Value, T>::ConstraintsFromJson(
-    const base::DictionaryValue* value,
-    std::set<std::string>* processed_keys,
-    ErrorPtr* error) {
-  if (!Base::ConstraintsFromJson(value, processed_keys, error))
-    return false;
-
-  if (processed_keys->find(commands::attributes::kOneOf_Enum) ==
-      processed_keys->end()) {
-    // Process min/max constraints only if "enum" constraint wasn't already
-    // specified.
-    if (value->HasKey(commands::attributes::kNumeric_Min)) {
-      auto constraint = LoadMinMaxConstraint<ConstraintMin<T>, T>(
-          commands::attributes::kNumeric_Min, value, error);
-      if (!constraint)
-        return false;
-      this->AddConstraint(std::move(constraint));
-      this->RemoveConstraint(ConstraintType::OneOf);
-      processed_keys->insert(commands::attributes::kNumeric_Min);
-    }
-    if (value->HasKey(commands::attributes::kNumeric_Max)) {
-      auto constraint = LoadMinMaxConstraint<ConstraintMax<T>, T>(
-          commands::attributes::kNumeric_Max, value, error);
-      if (!constraint)
-        return false;
-      this->AddConstraint(std::move(constraint));
-      this->RemoveConstraint(ConstraintType::OneOf);
-      processed_keys->insert(commands::attributes::kNumeric_Max);
-    }
-  }
-
-  return true;
-}
-
-// StringPropType -------------------------------------------------------------
-
-bool StringPropType::ConstraintsFromJson(const base::DictionaryValue* value,
-                                         std::set<std::string>* processed_keys,
-                                         ErrorPtr* error) {
-  if (!Base::ConstraintsFromJson(value, processed_keys, error))
-    return false;
-
-  if (processed_keys->find(commands::attributes::kOneOf_Enum) ==
-      processed_keys->end()) {
-    // Process min/max constraints only if "enum" constraint wasn't already
-    // specified.
-    if (value->HasKey(commands::attributes::kString_MinLength)) {
-      auto constraint = LoadMinMaxConstraint<ConstraintStringLengthMin, int>(
-          commands::attributes::kString_MinLength, value, error);
-      if (!constraint)
-        return false;
-      AddConstraint(std::move(constraint));
-      RemoveConstraint(ConstraintType::OneOf);
-      processed_keys->insert(commands::attributes::kString_MinLength);
-    }
-    if (value->HasKey(commands::attributes::kString_MaxLength)) {
-      auto constraint = LoadMinMaxConstraint<ConstraintStringLengthMax, int>(
-          commands::attributes::kString_MaxLength, value, error);
-      if (!constraint)
-        return false;
-      AddConstraint(std::move(constraint));
-      RemoveConstraint(ConstraintType::OneOf);
-      processed_keys->insert(commands::attributes::kString_MaxLength);
-    }
-  }
-  return true;
-}
-
-void StringPropType::AddLengthConstraint(int min_len, int max_len) {
-  InheritableAttribute<int> min_attr(min_len, false);
-  InheritableAttribute<int> max_attr(max_len, false);
-  AddConstraint(std::unique_ptr<ConstraintStringLengthMin>{
-      new ConstraintStringLengthMin{min_attr}});
-  AddConstraint(std::unique_ptr<ConstraintStringLengthMax>{
-      new ConstraintStringLengthMax{max_attr}});
-}
-
-int StringPropType::GetMinLength() const {
-  auto slc = static_cast<const ConstraintStringLength*>(
-      GetConstraint(ConstraintType::StringLengthMin));
-  return slc ? slc->limit_.value : 0;
-}
-
-int StringPropType::GetMaxLength() const {
-  auto slc = static_cast<const ConstraintStringLength*>(
-      GetConstraint(ConstraintType::StringLengthMax));
-  return slc ? slc->limit_.value : std::numeric_limits<int>::max();
-}
-
-// ObjectPropType -------------------------------------------------------------
-
-ObjectPropType::ObjectPropType()
-    : object_schema_{ObjectSchema::Create(), false} {}
-
-bool ObjectPropType::HasOverriddenAttributes() const {
-  return PropType::HasOverriddenAttributes() || !object_schema_.is_inherited;
-}
-
-std::unique_ptr<PropType> ObjectPropType::Clone() const {
-  auto cloned = Base::Clone();
-
-  cloned->GetObject()->object_schema_.is_inherited =
-      object_schema_.is_inherited;
-  cloned->GetObject()->object_schema_.value = object_schema_.value->Clone();
-  return cloned;
-}
-
-std::unique_ptr<base::Value> ObjectPropType::ToJson(bool full_schema,
-                                                    bool in_command_def) const {
-  std::unique_ptr<base::Value> value =
-      PropType::ToJson(full_schema, in_command_def);
-  CHECK(value);
-  base::DictionaryValue* dict = nullptr;
-  CHECK(value->GetAsDictionary(&dict)) << "Expecting a JSON object";
-  if (!object_schema_.is_inherited || full_schema) {
-    auto object_schema = object_schema_.value->ToJson(full_schema, false);
-    CHECK(object_schema);
-
-    dict->SetWithoutPathExpansion(commands::attributes::kObject_Properties,
-                                  object_schema.release());
-    dict->SetBooleanWithoutPathExpansion(
-        commands::attributes::kObject_AdditionalProperties,
-        object_schema_.value->GetExtraPropertiesAllowed());
-    std::unique_ptr<base::ListValue> required{new base::ListValue};
-    for (const auto& pair : object_schema_.value->GetProps()) {
-      if (pair.second->IsRequired())
-        required->AppendString(pair.first);
-    }
-    if (required->GetSize() > 0) {
-      dict->Set(commands::attributes::kObject_Required, required.release());
-    }
-  }
-  return value;
-}
-
-bool ObjectPropType::ObjectSchemaFromJson(const base::DictionaryValue* value,
-                                          const PropType* base_schema,
-                                          std::set<std::string>* processed_keys,
-                                          ErrorPtr* error) {
-  if (!Base::ObjectSchemaFromJson(value, base_schema, processed_keys, error))
-    return false;
-
-  using commands::attributes::kObject_Properties;
-  using commands::attributes::kObject_AdditionalProperties;
-
-  const ObjectSchema* base_object_schema = nullptr;
-  if (base_schema)
-    base_object_schema = base_schema->GetObject()->GetObjectSchemaPtr();
-
-  const base::DictionaryValue* props = nullptr;
-  std::unique_ptr<ObjectSchema> object_schema;
-  bool inherited = false;
-  if (value->GetDictionaryWithoutPathExpansion(kObject_Properties, &props)) {
-    processed_keys->insert(kObject_Properties);
-    object_schema.reset(new ObjectSchema);
-    if (!object_schema->FromJson(props, base_object_schema, error)) {
-      Error::AddTo(error, FROM_HERE, errors::commands::kDomain,
-                   errors::commands::kInvalidObjectSchema,
-                   "Error parsing object property schema");
-      return false;
-    }
-  } else if (base_object_schema) {
-    object_schema = base_object_schema->Clone();
-    inherited = true;
-  } else {
-    Error::AddToPrintf(error, FROM_HERE, errors::commands::kDomain,
-                       errors::commands::kInvalidObjectSchema,
-                       "Object type definition must include the "
-                       "object schema ('%s' field not found)",
-                       kObject_Properties);
-    return false;
-  }
-  bool extra_properties_allowed = false;
-  if (value->GetBooleanWithoutPathExpansion(kObject_AdditionalProperties,
-                                            &extra_properties_allowed)) {
-    processed_keys->insert(kObject_AdditionalProperties);
-    object_schema->SetExtraPropertiesAllowed(extra_properties_allowed);
-    inherited = false;
-  }
-  const base::Value* required = nullptr;
-  if (value->Get(commands::attributes::kObject_Required, &required)) {
-    processed_keys->insert(commands::attributes::kObject_Required);
-    const base::ListValue* required_list = nullptr;
-    if (!required->GetAsList(&required_list)) {
-      Error::AddToPrintf(error, FROM_HERE, errors::commands::kDomain,
-                         errors::commands::kInvalidObjectSchema,
-                         "Property '%s' must be an array",
-                         commands::attributes::kObject_Required);
-      return false;
-    }
-    for (const base::Value* value : *required_list) {
-      std::string name;
-      if (!value->GetAsString(&name)) {
-        std::string json_value;
-        CHECK(base::JSONWriter::Write(*value, &json_value));
-        Error::AddToPrintf(
-            error, FROM_HERE, errors::commands::kDomain,
-            errors::commands::kInvalidObjectSchema,
-            "Property '%s' contains invalid element (%s). String expected",
-            commands::attributes::kObject_Required, json_value.c_str());
-        return false;
-      }
-      if (!object_schema->MarkPropRequired(name, error))
-        return false;
-      inherited = false;
-    }
-  }
-  object_schema_.value = std::move(object_schema);
-  object_schema_.is_inherited = inherited;
-
-  return true;
-}
-
-void ObjectPropType::SetObjectSchema(
-    std::unique_ptr<const ObjectSchema> schema) {
-  object_schema_.value = std::move(schema);
-  object_schema_.is_inherited = false;
-}
-
-// ArrayPropType -------------------------------------------------------------
-
-ArrayPropType::ArrayPropType() {}
-
-bool ArrayPropType::HasOverriddenAttributes() const {
-  return PropType::HasOverriddenAttributes() || !item_type_.is_inherited;
-}
-
-std::unique_ptr<PropType> ArrayPropType::Clone() const {
-  auto cloned = Base::Clone();
-
-  cloned->GetArray()->item_type_.is_inherited = item_type_.is_inherited;
-  cloned->GetArray()->item_type_.value = item_type_.value->Clone();
-  return cloned;
-}
-
-std::unique_ptr<base::Value> ArrayPropType::ToJson(bool full_schema,
-                                                   bool in_command_def) const {
-  std::unique_ptr<base::Value> value =
-      PropType::ToJson(full_schema, in_command_def);
-  CHECK(value);
-  if (!item_type_.is_inherited || full_schema) {
-    base::DictionaryValue* dict = nullptr;
-    CHECK(value->GetAsDictionary(&dict)) << "Expecting a JSON object";
-    auto type = item_type_.value->ToJson(full_schema, false);
-    CHECK(type);
-    dict->SetWithoutPathExpansion(commands::attributes::kItems, type.release());
-  }
-  return value;
-}
-
-bool ArrayPropType::ObjectSchemaFromJson(const base::DictionaryValue* value,
-                                         const PropType* base_schema,
-                                         std::set<std::string>* processed_keys,
-                                         ErrorPtr* error) {
-  if (!Base::ObjectSchemaFromJson(value, base_schema, processed_keys, error))
-    return false;
-
-  using commands::attributes::kItems;
-
-  const PropType* base_type = nullptr;
-  if (base_schema)
-    base_type = base_schema->GetArray()->GetItemTypePtr();
-
-  const base::Value* type_value = nullptr;
-  if (value->GetWithoutPathExpansion(kItems, &type_value)) {
-    processed_keys->insert(kItems);
-    auto item_type = ObjectSchema::PropFromJson(*type_value, base_type, error);
-    if (!item_type)
-      return false;
-    if (item_type->GetType() == ValueType::Array) {
-      Error::AddTo(error, FROM_HERE, errors::commands::kDomain,
-                   errors::commands::kInvalidObjectSchema,
-                   "Arrays of arrays are not supported");
-      return false;
-    }
-    SetItemType(std::move(item_type));
-  } else if (!item_type_.value) {
-    if (base_type) {
-      item_type_.value = base_type->Clone();
-      item_type_.is_inherited = true;
-    } else {
-      Error::AddToPrintf(error, FROM_HERE, errors::commands::kDomain,
-                         errors::commands::kInvalidObjectSchema,
-                         "Array type definition must include the "
-                         "array item type ('%s' field not found)",
-                         kItems);
-      return false;
-    }
-  }
-  return true;
-}
-
-void ArrayPropType::SetItemType(std::unique_ptr<const PropType> item_type) {
-  item_type_.value = std::move(item_type);
-  item_type_.is_inherited = false;
-}
-
-}  // namespace weave
diff --git a/src/commands/prop_types.h b/src/commands/prop_types.h
deleted file mode 100644
index f784eb6..0000000
--- a/src/commands/prop_types.h
+++ /dev/null
@@ -1,352 +0,0 @@
-// 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_COMMANDS_PROP_TYPES_H_
-#define LIBWEAVE_SRC_COMMANDS_PROP_TYPES_H_
-
-#include <limits>
-#include <map>
-#include <memory>
-#include <set>
-#include <string>
-#include <utility>
-#include <vector>
-
-#include <weave/error.h>
-
-#include "src/commands/prop_constraints.h"
-#include "src/commands/prop_values.h"
-
-namespace weave {
-
-class IntPropType;
-class DoublePropType;
-class StringPropType;
-class BooleanPropType;
-class ObjectPropType;
-class ArrayPropType;
-
-// PropType is a base class for all parameter type definition objects.
-// Property definitions of a particular type will derive from this class and
-// provide type-specific implementations.
-class PropType {
- public:
-  // ConstraintMap is a type alias for a map containing parameter
-  // constraints. It is implemented as a map for fast look-ups of constraints
-  // of particular type. Also it is expected to have at most one constraint
-  // of each type (e.g. it makes no sense to impose two "minimum" constraints
-  // onto a numeric parameter).
-  using ConstraintMap = std::map<ConstraintType, std::unique_ptr<Constraint>>;
-
-  PropType();
-  virtual ~PropType();
-
-  // Gets the parameter type as an enumeration.
-  virtual ValueType GetType() const = 0;
-  // Gets the parameter type as a string.
-  std::string GetTypeAsString() const;
-  // Returns true if this parameter definition inherits a type
-  // definition from a base object schema.
-  bool IsBasedOnSchema() const { return based_on_schema_; }
-  // Returns a default value specified for the type, or nullptr if no default
-  // is available.
-  const PropValue* GetDefaultValue() const { return default_.value.get(); }
-  // Gets the constraints specified for the parameter, if any.
-  const ConstraintMap& GetConstraints() const { return constraints_; }
-  // Returns true if this value is required. Properties are marked as required
-  // by using "isRequired" attribute or listed in "required" array.
-  bool IsRequired() const;
-  // Sets the required attribute to the value of |required| and marks it as
-  // overridden (not-inherited).
-  void MakeRequired(bool required);
-  // Checks if any of the type attributes were overridden from the base
-  // schema definition. If this type does not inherit from a base schema,
-  // this method returns true.
-  // An attribute could be the value of any of the constraints, default
-  // value of a parameter or any other data that may be specified in
-  // parameter type definition in and can be inherited from the base schema.
-  virtual bool HasOverriddenAttributes() const;
-
-  // Type conversion methods. Used in lieu of RTTI and dynamic_cast<>.
-  virtual IntPropType* GetInt() { return nullptr; }
-  virtual IntPropType const* GetInt() const { return nullptr; }
-  virtual DoublePropType* GetDouble() { return nullptr; }
-  virtual DoublePropType const* GetDouble() const { return nullptr; }
-  virtual StringPropType* GetString() { return nullptr; }
-  virtual StringPropType const* GetString() const { return nullptr; }
-  virtual BooleanPropType* GetBoolean() { return nullptr; }
-  virtual BooleanPropType const* GetBoolean() const { return nullptr; }
-  virtual ObjectPropType* GetObject() { return nullptr; }
-  virtual ObjectPropType const* GetObject() const { return nullptr; }
-  virtual ArrayPropType* GetArray() { return nullptr; }
-  virtual ArrayPropType const* GetArray() const { return nullptr; }
-
-  // Makes a full copy of this type definition.
-  virtual std::unique_ptr<PropType> Clone() const;
-
-  // Creates an instance of associated value object.
-  virtual std::unique_ptr<PropValue> CreatePropValue(const base::Value& value,
-                                                     ErrorPtr* error) const = 0;
-
-  // Saves the parameter type definition as a JSON object.
-  // If |full_schema| is set to true, the full type definition is saved,
-  // otherwise only the overridden properties and attributes from the base
-  // schema is saved. That is, inherited properties and attributes are not
-  // saved.
-  // If it fails, returns "nullptr" and fills in the |error| with additional
-  // error information.
-  // |in_command_def| is set to true if the property type describes a
-  // GCD command parameter, otherwise it is for an object property.
-  // Command definitions handle required parameters differently (using
-  // "isRequired" property as opposed to "required" list for object properties).
-  virtual std::unique_ptr<base::Value> ToJson(bool full_schema,
-                                              bool in_command_def) const;
-  // Parses an JSON parameter type definition. Optional |base_schema| may
-  // specify the base schema type definition this type should be based upon.
-  // If not specified (nullptr), the parameter type is assumed to be a full
-  // definition and any omitted required properties are treated as an error.
-  // Returns true on success, otherwise fills in the |error| with additional
-  // error information.
-  virtual bool FromJson(const base::DictionaryValue* value,
-                        const PropType* base_schema,
-                        ErrorPtr* error);
-  // Helper function to load object schema from JSON.
-  virtual bool ObjectSchemaFromJson(const base::DictionaryValue* value,
-                                    const PropType* base_schema,
-                                    std::set<std::string>* processed_keys,
-                                    ErrorPtr* error) {
-    return true;
-  }
-  // Helper function to load type-specific constraints from JSON.
-  virtual bool ConstraintsFromJson(const base::DictionaryValue* value,
-                                   std::set<std::string>* processed_keys,
-                                   ErrorPtr* error) {
-    return true;
-  }
-
-  // Additional helper static methods to help with converting a type enum
-  // value into a string and back.
-  using TypeMap = std::vector<std::pair<ValueType, std::string>>;
-  // Returns a list of value types and corresponding type names.
-  static const TypeMap& GetTypeMap();
-  // Gets the type name string for the given type.
-  static std::string GetTypeStringFromType(ValueType type);
-  // Finds the type for the given type name. Returns true on success.
-  static bool GetTypeFromTypeString(const std::string& name, ValueType* type);
-
-  // Creates an instance of PropType-derived class for the specified
-  // parameter type.
-  static std::unique_ptr<PropType> Create(ValueType type);
-
-  // Adds a constraint to the type definition.
-  void AddConstraint(std::unique_ptr<Constraint> constraint);
-  // Removes a constraint of given type, if it exists.
-  void RemoveConstraint(ConstraintType constraint_type);
-  // Removes all constraints.
-  void RemoveAllConstraints();
-
-  // Finds a constraint of given type. Returns nullptr if not found.
-  const Constraint* GetConstraint(ConstraintType constraint_type) const;
-  Constraint* GetConstraint(ConstraintType constraint_type);
-
-  // Validates the given value against all the constraints.
-  bool ValidateConstraints(const PropValue& value, ErrorPtr* error) const;
-
- protected:
-  friend class StatePackage;
-  virtual std::unique_ptr<PropValue> CreateDefaultValue() const = 0;
-
-  // Specifies if this parameter definition is derived from a base
-  // object schema.
-  bool based_on_schema_ = false;
-  // A list of constraints specified for the parameter.
-  ConstraintMap constraints_;
-  // The default value specified for the parameter, if any. If the default
-  // value is present, the parameter is treated as optional and the default
-  // value is used if the parameter value is omitted when sending a command.
-  // Otherwise the parameter is treated as required and, if it is omitted,
-  // this is treated as an error.
-  InheritableAttribute<std::unique_ptr<PropValue>> default_;
-  // Specifies whether the parameter/property is required and must be specified
-  // (either directly, or by the default value being provided in the schema).
-  // Non-required parameters can be omitted completely and their values will not
-  // be present in the object instance.
-  InheritableAttribute<bool> required_;
-};
-
-// Base class for all the derived concrete implementations of property
-// type classes. Provides implementations for common methods of PropType base.
-template <class Derived, class Value, typename T>
-class PropTypeBase : public PropType {
- public:
-  // Overrides from PropType.
-  ValueType GetType() const override { return GetValueType<T>(); }
-
-  std::unique_ptr<PropValue> CreatePropValue(const base::Value& value,
-                                             ErrorPtr* error) const override {
-    return CreateValue(value, error);
-  }
-
-  std::unique_ptr<Value> CreateValue(const base::Value& value,
-                                     ErrorPtr* error) const {
-    return Value::CreateFromJson(value, *this, error);
-  }
-
-  bool ConstraintsFromJson(const base::DictionaryValue* value,
-                           std::set<std::string>* processed_keys,
-                           ErrorPtr* error) override;
-
- protected:
-  std::unique_ptr<PropValue> CreateDefaultValue() const override {
-    if (GetDefaultValue())
-      return GetDefaultValue()->Clone();
-    return std::unique_ptr<PropValue>{new Value{*this}};
-  }
-};
-
-// Helper base class for Int and Double parameter types.
-template <class Derived, class Value, typename T>
-class NumericPropTypeBase : public PropTypeBase<Derived, Value, T> {
- public:
-  using Base = PropTypeBase<Derived, Value, T>;
-  bool ConstraintsFromJson(const base::DictionaryValue* value,
-                           std::set<std::string>* processed_keys,
-                           ErrorPtr* error) override;
-
-  // Helper method to set and obtain a min/max constraint values.
-  // Used mostly for unit testing.
-  void AddMinMaxConstraint(T min_value, T max_value) {
-    InheritableAttribute<T> min_attr(min_value, false);
-    InheritableAttribute<T> max_attr(max_value, false);
-    this->AddConstraint(
-        std::unique_ptr<ConstraintMin<T>>{new ConstraintMin<T>{min_attr}});
-    this->AddConstraint(
-        std::unique_ptr<ConstraintMax<T>>{new ConstraintMax<T>{max_attr}});
-  }
-  T GetMinValue() const {
-    auto mmc = static_cast<const ConstraintMin<T>*>(
-        this->GetConstraint(ConstraintType::Min));
-    return mmc ? mmc->limit_.value : std::numeric_limits<T>::lowest();
-  }
-  T GetMaxValue() const {
-    auto mmc = static_cast<const ConstraintMax<T>*>(
-        this->GetConstraint(ConstraintType::Max));
-    return mmc ? mmc->limit_.value : (std::numeric_limits<T>::max)();
-  }
-};
-
-// Property definition of Integer type.
-class IntPropType : public NumericPropTypeBase<IntPropType, IntValue, int> {
- public:
-  // Overrides from the PropType base class.
-  IntPropType* GetInt() override { return this; }
-  IntPropType const* GetInt() const override { return this; }
-};
-
-// Property definition of Number type.
-class DoublePropType
-    : public NumericPropTypeBase<DoublePropType, DoubleValue, double> {
- public:
-  // Overrides from the PropType base class.
-  DoublePropType* GetDouble() override { return this; }
-  DoublePropType const* GetDouble() const override { return this; }
-};
-
-// Property definition of String type.
-class StringPropType
-    : public PropTypeBase<StringPropType, StringValue, std::string> {
- public:
-  using Base = PropTypeBase<StringPropType, StringValue, std::string>;
-  // Overrides from the PropType base class.
-  StringPropType* GetString() override { return this; }
-  StringPropType const* GetString() const override { return this; }
-
-  bool ConstraintsFromJson(const base::DictionaryValue* value,
-                           std::set<std::string>* processed_keys,
-                           ErrorPtr* error) override;
-
-  // Helper methods to add and inspect simple constraints.
-  // Used mostly for unit testing.
-  void AddLengthConstraint(int min_len, int max_len);
-  int GetMinLength() const;
-  int GetMaxLength() const;
-};
-
-// Property definition of Boolean type.
-class BooleanPropType
-    : public PropTypeBase<BooleanPropType, BooleanValue, bool> {
- public:
-  // Overrides from the PropType base class.
-  BooleanPropType* GetBoolean() override { return this; }
-  BooleanPropType const* GetBoolean() const override { return this; }
-};
-
-// Parameter definition of Object type.
-class ObjectPropType
-    : public PropTypeBase<ObjectPropType, ObjectValue, ValueMap> {
- public:
-  using Base = PropTypeBase<ObjectPropType, ObjectValue, ValueMap>;
-  ObjectPropType();
-
-  // Overrides from the ParamType base class.
-  bool HasOverriddenAttributes() const override;
-
-  ObjectPropType* GetObject() override { return this; }
-  ObjectPropType const* GetObject() const override { return this; }
-
-  std::unique_ptr<PropType> Clone() const override;
-
-  std::unique_ptr<base::Value> ToJson(bool full_schema,
-                                      bool in_command_def) const override;
-  bool ObjectSchemaFromJson(const base::DictionaryValue* value,
-                            const PropType* base_schema,
-                            std::set<std::string>* processed_keys,
-                            ErrorPtr* error) override;
-
-  // Returns a schema for Object-type parameter.
-  inline const ObjectSchema* GetObjectSchemaPtr() const {
-    return object_schema_.value.get();
-  }
-  void SetObjectSchema(std::unique_ptr<const ObjectSchema> schema);
-
- private:
-  InheritableAttribute<std::unique_ptr<const ObjectSchema>> object_schema_;
-};
-
-// Parameter definition of Array type.
-class ArrayPropType
-    : public PropTypeBase<ArrayPropType, ArrayValue, ValueVector> {
- public:
-  using Base = PropTypeBase<ArrayPropType, ArrayValue, ValueVector>;
-  ArrayPropType();
-
-  // Overrides from the ParamType base class.
-  bool HasOverriddenAttributes() const override;
-
-  ArrayPropType* GetArray() override { return this; }
-  ArrayPropType const* GetArray() const override { return this; }
-
-  std::unique_ptr<PropType> Clone() const override;
-
-  std::unique_ptr<base::Value> ToJson(bool full_schema,
-                                      bool in_command_def) const override;
-
-  bool ObjectSchemaFromJson(const base::DictionaryValue* value,
-                            const PropType* base_schema,
-                            std::set<std::string>* processed_keys,
-                            ErrorPtr* error) override;
-
-  // Returns a type for Array elements.
-  inline const PropType* GetItemTypePtr() const {
-    return item_type_.value.get();
-  }
-  void SetItemType(std::unique_ptr<const PropType> item_type);
-
- private:
-  InheritableAttribute<std::unique_ptr<const PropType>> item_type_;
-};
-
-}  // namespace weave
-
-#endif  // LIBWEAVE_SRC_COMMANDS_PROP_TYPES_H_
diff --git a/src/commands/prop_values.cc b/src/commands/prop_values.cc
deleted file mode 100644
index 6f30bee..0000000
--- a/src/commands/prop_values.cc
+++ /dev/null
@@ -1,17 +0,0 @@
-// 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/commands/prop_values.h"
-
-#include "src/commands/prop_types.h"
-
-namespace weave {
-
-PropValue::PropValue(const PropType& type) : type_{type.Clone()} {}
-
-PropValue::PropValue(const PropValue& other) : PropValue{*other.type_} {}
-
-PropValue::~PropValue() {}
-
-}  // namespace weave
diff --git a/src/commands/prop_values.h b/src/commands/prop_values.h
deleted file mode 100644
index 960802b..0000000
--- a/src/commands/prop_values.h
+++ /dev/null
@@ -1,266 +0,0 @@
-// 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_COMMANDS_PROP_VALUES_H_
-#define LIBWEAVE_SRC_COMMANDS_PROP_VALUES_H_
-
-#include <map>
-#include <memory>
-#include <string>
-
-#include <weave/error.h>
-
-#include "src/commands/schema_utils.h"
-
-namespace base {
-class Value;
-class DictionaryValue;
-}  // namespace base
-
-namespace weave {
-
-// Enumeration to indicate supported command parameter types.
-enum class ValueType {
-  Int,
-  Double,
-  String,
-  Boolean,
-  Object,
-  Array,
-};
-
-class PropValue;
-class IntValue;
-class DoubleValue;
-class StringValue;
-class BooleanValue;
-class ObjectValue;
-class ArrayValue;
-
-class PropType;
-
-// Helper methods to get the parameter type enum value for the given
-// native C++ data representation.
-// The generic GetValueType<T>() is undefined, however particular
-// type specializations return the appropriate ValueType.
-template <typename T>
-ValueType GetValueType();  // Undefined.
-template <>
-inline ValueType GetValueType<int>() {
-  return ValueType::Int;
-}
-template <>
-inline ValueType GetValueType<double>() {
-  return ValueType::Double;
-}
-template <>
-inline ValueType GetValueType<std::string>() {
-  return ValueType::String;
-}
-template <>
-inline ValueType GetValueType<bool>() {
-  return ValueType::Boolean;
-}
-template <>
-inline ValueType GetValueType<ValueMap>() {
-  return ValueType::Object;
-}
-template <>
-inline ValueType GetValueType<ValueVector>() {
-  return ValueType::Array;
-}
-
-// The base class for property values.
-// Concrete value classes of various types will be derived from this base.
-// A property value is the actual command parameter value (or a concrete value
-// that can be used in constraints and presets). The PropValue is mostly
-// just parsed content of base::Value when a command is dispatched, however
-// it does have some additional functionality:
-//   - it has a reference to the type definition (PropType) which is used
-//     when validating the value, especially for "object" types.
-//   - it can be compared with another instances of values of the same type.
-//     This is used to validate the values against "enum"/"one of" constraints.
-class PropValue {
- public:
-  // Only CreateDefaultValue should use this constructor.
-  explicit PropValue(const PropType& type);
-  virtual ~PropValue();
-
-  // Gets the type of the value.
-  virtual ValueType GetType() const = 0;
-
-  // Type conversion methods. Used in lieu of RTTI and dynamic_cast<>.
-  virtual IntValue* GetInt() { return nullptr; }
-  virtual IntValue const* GetInt() const { return nullptr; }
-  virtual DoubleValue* GetDouble() { return nullptr; }
-  virtual DoubleValue const* GetDouble() const { return nullptr; }
-  virtual StringValue* GetString() { return nullptr; }
-  virtual StringValue const* GetString() const { return nullptr; }
-  virtual BooleanValue* GetBoolean() { return nullptr; }
-  virtual BooleanValue const* GetBoolean() const { return nullptr; }
-  virtual ObjectValue* GetObject() { return nullptr; }
-  virtual ObjectValue const* GetObject() const { return nullptr; }
-  virtual ArrayValue* GetArray() { return nullptr; }
-  virtual ArrayValue const* GetArray() const { return nullptr; }
-
-  // Makes a full copy of this value class.
-  virtual std::unique_ptr<PropValue> Clone() const = 0;
-
-  // Saves the value as a JSON object. Never fails.
-  virtual std::unique_ptr<base::Value> ToJson() const = 0;
-
-  // Return the type definition of this value.
-  const PropType* GetPropType() const { return type_.get(); }
-  // Compares two values and returns true if they are equal.
-  virtual bool IsEqual(const PropValue* value) const = 0;
-
- protected:
-  // Special out-of-line constructor to help implement PropValue::Clone().
-  // That method needs to clone the underlying type but can't do this in this
-  // header file since PropType is just forward-declared (it needs PropValue
-  // fully defined in its own inner workings).
-  explicit PropValue(const PropValue& other);
-
- private:
-  std::unique_ptr<const PropType> type_;
-};
-
-// A helper template base class for implementing value classes.
-template <typename T>
-class TypedValueBase : public PropValue {
- public:
-  TypedValueBase(const PropType& type) : PropValue(type) {}
-
-  // Overrides from PropValue base class.
-  ValueType GetType() const override { return GetValueType<T>(); }
-
-  std::unique_ptr<base::Value> ToJson() const override {
-    return TypedValueToJson(value_);
-  }
-
-  bool IsEqual(const PropValue* value) const override {
-    if (GetType() != value->GetType())
-      return false;
-    return CompareValue(GetValue(),
-                        static_cast<const TypedValueBase*>(value)->GetValue());
-  }
-
-  // Helper methods to get and set the C++ representation of the value.
-  const T& GetValue() const { return value_; }
-
- protected:
-  explicit TypedValueBase(const TypedValueBase& other)
-      : PropValue(other), value_(other.value_) {}
-
-  TypedValueBase(const PropType& type, T value)
-      : PropValue(type), value_(value) {}
-
- private:
-  T value_{};  // The value of the parameter in C++ data representation.
-};
-
-// A helper template base class for implementing value classes.
-template <typename Derived, typename T>
-class TypedValueWithClone : public TypedValueBase<T> {
- public:
-  TypedValueWithClone(const PropType& type) : TypedValueBase<T>(type) {}
-  TypedValueWithClone(const PropType& type, const T& value)
-      : TypedValueBase<T>(type, value) {}
-
-  std::unique_ptr<PropValue> Clone() const override {
-    return std::unique_ptr<PropValue>{
-        new Derived{*static_cast<const Derived*>(this)}};
-  }
-
-  static std::unique_ptr<Derived> CreateFromJson(const base::Value& value,
-                                                 const PropType& type,
-                                                 ErrorPtr* error) {
-    T tmp_value;
-    if (!TypedValueFromJson(&value, &type, &tmp_value, error))
-      return nullptr;
-
-    // Only place where invalid value can exist.
-    std::unique_ptr<Derived> result(new Derived(type, tmp_value));
-    if (!result->GetPropType()->ValidateConstraints(*result, error))
-      return nullptr;
-
-    return result;
-  }
-};
-
-// Value of type Integer.
-class IntValue final : public TypedValueWithClone<IntValue, int> {
- public:
-  explicit IntValue(const PropType& type)
-      : TypedValueWithClone<IntValue, int>(type) {}
-  IntValue(const PropType& type, int value)
-      : TypedValueWithClone<IntValue, int>(type, value) {}
-
-  IntValue* GetInt() override { return this; }
-  IntValue const* GetInt() const override { return this; }
-};
-
-// Value of type Number.
-class DoubleValue final : public TypedValueWithClone<DoubleValue, double> {
- public:
-  explicit DoubleValue(const PropType& type)
-      : TypedValueWithClone<DoubleValue, double>(type) {}
-  DoubleValue(const PropType& type, double value)
-      : TypedValueWithClone<DoubleValue, double>(type, value) {}
-
-  DoubleValue* GetDouble() override { return this; }
-  DoubleValue const* GetDouble() const override { return this; }
-};
-
-// Value of type String.
-class StringValue final : public TypedValueWithClone<StringValue, std::string> {
- public:
-  explicit StringValue(const PropType& type)
-      : TypedValueWithClone<StringValue, std::string>(type) {}
-  StringValue(const PropType& type, std::string value)
-      : TypedValueWithClone<StringValue, std::string>(type, value) {}
-
-  StringValue* GetString() override { return this; }
-  StringValue const* GetString() const override { return this; }
-};
-
-// Value of type Boolean.
-class BooleanValue final : public TypedValueWithClone<BooleanValue, bool> {
- public:
-  explicit BooleanValue(const PropType& type)
-      : TypedValueWithClone<BooleanValue, bool>(type) {}
-  BooleanValue(const PropType& type, bool value)
-      : TypedValueWithClone<BooleanValue, bool>(type, value) {}
-
-  BooleanValue* GetBoolean() override { return this; }
-  BooleanValue const* GetBoolean() const override { return this; }
-};
-
-// Value of type Object.
-class ObjectValue final : public TypedValueWithClone<ObjectValue, ValueMap> {
- public:
-  explicit ObjectValue(const PropType& type)
-      : TypedValueWithClone<ObjectValue, ValueMap>(type) {}
-  ObjectValue(const PropType& type, ValueMap value)
-      : TypedValueWithClone<ObjectValue, ValueMap>(type, value) {}
-
-  ObjectValue* GetObject() override { return this; }
-  ObjectValue const* GetObject() const override { return this; }
-};
-
-// Value of type Array.
-class ArrayValue final : public TypedValueWithClone<ArrayValue, ValueVector> {
- public:
-  explicit ArrayValue(const PropType& type)
-      : TypedValueWithClone<ArrayValue, ValueVector>(type) {}
-  ArrayValue(const PropType& type, ValueVector value)
-      : TypedValueWithClone<ArrayValue, ValueVector>(type, value) {}
-
-  ArrayValue* GetArray() override { return this; }
-  ArrayValue const* GetArray() const override { return this; }
-};
-
-}  // namespace weave
-
-#endif  // LIBWEAVE_SRC_COMMANDS_PROP_VALUES_H_
diff --git a/src/commands/schema_constants.cc b/src/commands/schema_constants.cc
index 7f8431f..cd8bf84 100644
--- a/src/commands/schema_constants.cc
+++ b/src/commands/schema_constants.cc
@@ -10,17 +10,9 @@
 namespace commands {
 const char kDomain[] = "command_schema";
 
-const char kOutOfRange[] = "out_of_range";
 const char kTypeMismatch[] = "type_mismatch";
-const char kPropTypeChanged[] = "param_type_changed";
-const char kUnknownType[] = "unknown_type";
-const char kInvalidPropDef[] = "invalid_parameter_definition";
 const char kInvalidPropValue[] = "invalid_parameter_value";
-const char kNoTypeInfo[] = "no_type_info";
 const char kPropertyMissing[] = "parameter_missing";
-const char kUnknownProperty[] = "unexpected_parameter";
-const char kInvalidObjectSchema[] = "invalid_object_schema";
-const char kDuplicateCommandDef[] = "duplicate_command_definition";
 const char kInvalidCommandName[] = "invalid_command_name";
 const char kCommandFailed[] = "command_failed";
 const char kInvalidMinimalRole[] = "invalid_minimal_role";
@@ -32,25 +24,6 @@
 namespace commands {
 namespace attributes {
 
-const char kType[] = "type";
-const char kDisplayName[] = "displayName";
-const char kDefault[] = "default";
-const char kItems[] = "items";
-const char kIsRequired[] = "isRequired";
-
-const char kNumeric_Min[] = "minimum";
-const char kNumeric_Max[] = "maximum";
-
-const char kString_MinLength[] = "minLength";
-const char kString_MaxLength[] = "maxLength";
-
-const char kOneOf_Enum[] = "enum";
-const char kOneOf_Metadata[] = "metadata";
-
-const char kObject_Properties[] = "properties";
-const char kObject_AdditionalProperties[] = "additionalProperties";
-const char kObject_Required[] = "required";
-
 const char kCommand_Id[] = "id";
 const char kCommand_Name[] = "name";
 const char kCommand_Parameters[] = "parameters";
diff --git a/src/commands/schema_constants.h b/src/commands/schema_constants.h
index ea59f17..57766e6 100644
--- a/src/commands/schema_constants.h
+++ b/src/commands/schema_constants.h
@@ -13,17 +13,9 @@
 extern const char kDomain[];
 
 // Common command definition error codes.
-extern const char kOutOfRange[];
 extern const char kTypeMismatch[];
-extern const char kPropTypeChanged[];
-extern const char kUnknownType[];
-extern const char kInvalidPropDef[];
 extern const char kInvalidPropValue[];
-extern const char kNoTypeInfo[];
 extern const char kPropertyMissing[];
-extern const char kUnknownProperty[];
-extern const char kInvalidObjectSchema[];
-extern const char kDuplicateCommandDef[];
 extern const char kInvalidCommandName[];
 extern const char kCommandFailed[];
 extern const char kInvalidMinimalRole[];
@@ -35,25 +27,6 @@
 namespace commands {
 namespace attributes {
 // Command description JSON schema attributes.
-extern const char kType[];
-extern const char kDisplayName[];
-extern const char kDefault[];
-extern const char kItems[];
-extern const char kIsRequired[];
-
-extern const char kNumeric_Min[];
-extern const char kNumeric_Max[];
-
-extern const char kString_MinLength[];
-extern const char kString_MaxLength[];
-
-extern const char kOneOf_Enum[];
-extern const char kOneOf_Metadata[];
-
-extern const char kObject_Properties[];
-extern const char kObject_AdditionalProperties[];
-extern const char kObject_Required[];
-
 extern const char kCommand_Id[];
 extern const char kCommand_Name[];
 extern const char kCommand_Parameters[];
diff --git a/src/commands/schema_utils.cc b/src/commands/schema_utils.cc
deleted file mode 100644
index be6cb16..0000000
--- a/src/commands/schema_utils.cc
+++ /dev/null
@@ -1,266 +0,0 @@
-// 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/commands/schema_utils.h"
-
-#include <algorithm>
-#include <set>
-#include <string>
-
-#include <base/json/json_writer.h>
-#include <base/logging.h>
-
-#include "src/commands/object_schema.h"
-#include "src/commands/prop_types.h"
-#include "src/commands/prop_values.h"
-
-namespace weave {
-namespace {
-// Helper function to report "type mismatch" errors when parsing JSON.
-void ReportJsonTypeMismatch(const tracked_objects::Location& location,
-                            const base::Value* value_in,
-                            const std::string& expected_type,
-                            ErrorPtr* error) {
-  std::string value_as_string;
-  base::JSONWriter::Write(*value_in, &value_as_string);
-  Error::AddToPrintf(error, location, errors::commands::kDomain,
-                     errors::commands::kTypeMismatch,
-                     "Unable to convert value %s into %s",
-                     value_as_string.c_str(), expected_type.c_str());
-}
-
-// Template version of ReportJsonTypeMismatch that deduces the type of expected
-// data from the value_out parameter passed to particular overload of
-// TypedValueFromJson() function. Always returns false.
-template <typename T>
-bool ReportUnexpectedJson(const tracked_objects::Location& location,
-                          const base::Value* value_in,
-                          T*,
-                          ErrorPtr* error) {
-  ReportJsonTypeMismatch(location, value_in,
-                         PropType::GetTypeStringFromType(GetValueType<T>()),
-                         error);
-  return false;
-}
-
-bool ErrorMissingProperty(ErrorPtr* error,
-                          const tracked_objects::Location& location,
-                          const char* param_name) {
-  Error::AddToPrintf(error, location, errors::commands::kDomain,
-                     errors::commands::kPropertyMissing,
-                     "Required parameter missing: %s", param_name);
-  return false;
-}
-
-}  // namespace
-
-// Specializations of TypedValueToJson<T>() for supported C++ types.
-std::unique_ptr<base::FundamentalValue> TypedValueToJson(bool value) {
-  return std::unique_ptr<base::FundamentalValue>(
-      new base::FundamentalValue(value));
-}
-
-std::unique_ptr<base::FundamentalValue> TypedValueToJson(int value) {
-  return std::unique_ptr<base::FundamentalValue>(
-      new base::FundamentalValue(value));
-}
-
-std::unique_ptr<base::FundamentalValue> TypedValueToJson(double value) {
-  return std::unique_ptr<base::FundamentalValue>(
-      new base::FundamentalValue(value));
-}
-
-std::unique_ptr<base::StringValue> TypedValueToJson(const std::string& value) {
-  return std::unique_ptr<base::StringValue>(new base::StringValue(value));
-}
-
-std::unique_ptr<base::DictionaryValue> TypedValueToJson(const ValueMap& value) {
-  std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue);
-  for (const auto& pair : value) {
-    auto prop_value = pair.second->ToJson();
-    CHECK(prop_value);
-    dict->SetWithoutPathExpansion(pair.first, prop_value.release());
-  }
-  return dict;
-}
-
-std::unique_ptr<base::ListValue> TypedValueToJson(const ValueVector& value) {
-  std::unique_ptr<base::ListValue> list(new base::ListValue);
-  for (const auto& item : value) {
-    auto json = item->ToJson();
-    CHECK(json);
-    list->Append(json.release());
-  }
-  return list;
-}
-
-bool TypedValueFromJson(const base::Value* value_in,
-                        const PropType* type,
-                        bool* value_out,
-                        ErrorPtr* error) {
-  return value_in->GetAsBoolean(value_out) ||
-         ReportUnexpectedJson(FROM_HERE, value_in, value_out, error);
-}
-
-bool TypedValueFromJson(const base::Value* value_in,
-                        const PropType* type,
-                        int* value_out,
-                        ErrorPtr* error) {
-  return value_in->GetAsInteger(value_out) ||
-         ReportUnexpectedJson(FROM_HERE, value_in, value_out, error);
-}
-
-bool TypedValueFromJson(const base::Value* value_in,
-                        const PropType* type,
-                        double* value_out,
-                        ErrorPtr* error) {
-  return value_in->GetAsDouble(value_out) ||
-         ReportUnexpectedJson(FROM_HERE, value_in, value_out, error);
-}
-
-bool TypedValueFromJson(const base::Value* value_in,
-                        const PropType* type,
-                        std::string* value_out,
-                        ErrorPtr* error) {
-  return value_in->GetAsString(value_out) ||
-         ReportUnexpectedJson(FROM_HERE, value_in, value_out, error);
-}
-
-bool TypedValueFromJson(const base::Value* value_in,
-                        const PropType* type,
-                        ValueMap* value_out,
-                        ErrorPtr* error) {
-  const base::DictionaryValue* dict = nullptr;
-  if (!value_in->GetAsDictionary(&dict))
-    return ReportUnexpectedJson(FROM_HERE, value_in, value_out, error);
-
-  CHECK(type) << "Object definition must be provided";
-  CHECK(ValueType::Object == type->GetType()) << "Type must be Object";
-
-  const ObjectSchema* object_schema = type->GetObject()->GetObjectSchemaPtr();
-  std::set<std::string> keys_processed;
-  value_out->clear();  // Clear possible default values already in |value_out|.
-  for (const auto& pair : object_schema->GetProps()) {
-    const PropValue* def_value = pair.second->GetDefaultValue();
-    if (dict->HasKey(pair.first)) {
-      const base::Value* param_value = nullptr;
-      CHECK(dict->GetWithoutPathExpansion(pair.first, &param_value))
-          << "Unable to get parameter";
-      auto value = pair.second->CreatePropValue(*param_value, error);
-      if (!value) {
-        Error::AddToPrintf(error, FROM_HERE, errors::commands::kDomain,
-                           errors::commands::kInvalidPropValue,
-                           "Invalid value for property '%s'",
-                           pair.first.c_str());
-        return false;
-      }
-      value_out->insert(std::make_pair(pair.first, std::move(value)));
-      keys_processed.insert(pair.first);
-    } else if (def_value) {
-      value_out->insert(std::make_pair(pair.first, def_value->Clone()));
-      keys_processed.insert(pair.first);
-    } else if (pair.second->IsRequired()) {
-      return ErrorMissingProperty(error, FROM_HERE, pair.first.c_str());
-    }
-  }
-
-  // Just for sanity, make sure that we processed all the necessary properties
-  // and there weren't any extra (unknown) ones specified. If so, ignore
-  // them, but log as warnings...
-  base::DictionaryValue::Iterator iter(*dict);
-  while (!iter.IsAtEnd()) {
-    std::string key = iter.key();
-    if (keys_processed.find(key) == keys_processed.end() &&
-        !object_schema->GetExtraPropertiesAllowed()) {
-      Error::AddToPrintf(error, FROM_HERE, errors::commands::kDomain,
-                         errors::commands::kUnknownProperty,
-                         "Unrecognized parameter '%s'", key.c_str());
-      return false;
-    }
-    iter.Advance();
-  }
-
-  // Now go over all property values and validate them.
-  for (const auto& pair : *value_out) {
-    const PropType* prop_type = pair.second->GetPropType();
-    CHECK(prop_type) << "Value property type must be available";
-    if (!prop_type->ValidateConstraints(*pair.second, error)) {
-      Error::AddToPrintf(error, FROM_HERE, errors::commands::kDomain,
-                         errors::commands::kInvalidPropValue,
-                         "Invalid value for property '%s'", pair.first.c_str());
-      return false;
-    }
-  }
-  return true;
-}
-
-bool TypedValueFromJson(const base::Value* value_in,
-                        const PropType* type,
-                        ValueVector* value_out,
-                        ErrorPtr* error) {
-  const base::ListValue* list = nullptr;
-  if (!value_in->GetAsList(&list))
-    return ReportUnexpectedJson(FROM_HERE, value_in, value_out, error);
-
-  CHECK(type) << "Array type definition must be provided";
-  CHECK(ValueType::Array == type->GetType()) << "Type must be Array";
-  const PropType* item_type = type->GetArray()->GetItemTypePtr();
-  CHECK(item_type) << "Incomplete array type definition";
-
-  // This value might already contain values from the type defaults.
-  // Clear them first before proceeding.
-  value_out->clear();
-  value_out->reserve(list->GetSize());
-  for (const base::Value* item : *list) {
-    std::unique_ptr<PropValue> prop_value =
-        item_type->CreatePropValue(*item, error);
-    if (!prop_value)
-      return false;
-    value_out->push_back(std::move(prop_value));
-  }
-  return true;
-}
-
-// Compares two sets of key-value pairs from two Objects.
-static bool obj_cmp(const ValueMap::value_type& v1,
-                    const ValueMap::value_type& v2) {
-  return (v1.first == v2.first) && v1.second->IsEqual(v2.second.get());
-}
-
-bool operator==(const ValueMap& obj1, const ValueMap& obj2) {
-  if (obj1.size() != obj2.size())
-    return false;
-
-  auto pair = std::mismatch(obj1.begin(), obj1.end(), obj2.begin(), obj_cmp);
-  return pair == std::make_pair(obj1.end(), obj2.end());
-}
-
-bool operator==(const ValueVector& arr1, const ValueVector& arr2) {
-  if (arr1.size() != arr2.size())
-    return false;
-
-  using Type = const ValueVector::value_type;
-  // Compare two array items.
-  auto arr_cmp = [](const Type& v1, const Type& v2) {
-    return v1->IsEqual(v2.get());
-  };
-  auto pair = std::mismatch(arr1.begin(), arr1.end(), arr2.begin(), arr_cmp);
-  return pair == std::make_pair(arr1.end(), arr2.end());
-}
-
-std::string ToString(const ValueMap& obj) {
-  auto val = TypedValueToJson(obj);
-  std::string str;
-  base::JSONWriter::Write(*val, &str);
-  return str;
-}
-
-std::string ToString(const ValueVector& arr) {
-  auto val = TypedValueToJson(arr);
-  std::string str;
-  base::JSONWriter::Write(*val, &str);
-  return str;
-}
-
-}  // namespace weave
diff --git a/src/commands/schema_utils.h b/src/commands/schema_utils.h
deleted file mode 100644
index 0c1d1b3..0000000
--- a/src/commands/schema_utils.h
+++ /dev/null
@@ -1,136 +0,0 @@
-// 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_COMMANDS_SCHEMA_UTILS_H_
-#define LIBWEAVE_SRC_COMMANDS_SCHEMA_UTILS_H_
-
-#include <cmath>
-#include <limits>
-#include <map>
-#include <memory>
-#include <string>
-#include <type_traits>
-#include <vector>
-
-#include <base/logging.h>
-#include <base/values.h>
-#include <weave/error.h>
-
-namespace weave {
-
-class PropType;
-class PropValue;
-class ObjectSchema;
-class ObjectValue;
-
-// C++ representation of object values.
-using ValueMap = std::map<std::string, std::shared_ptr<const PropValue>>;
-
-// C++ representation of array of values.
-using ValueVector = std::vector<std::shared_ptr<const PropValue>>;
-
-// Converts an object to string.
-std::string ToString(const ValueMap& obj);
-
-// Converts an array to string.
-std::string ToString(const ValueVector& arr);
-
-// InheritableAttribute class is used for specifying various command parameter
-// attributes that can be inherited from a base (parent) schema.
-// The |value| still specifies the actual attribute values, whether it
-// is inherited or overridden, while |is_inherited| can be used to identify
-// if the attribute was inherited (true) or overridden (false).
-template <typename T>
-class InheritableAttribute final {
- public:
-  InheritableAttribute() = default;
-  explicit InheritableAttribute(T val)
-      : value(std::move(val)), is_inherited(true) {}
-  InheritableAttribute(T val, bool inherited)
-      : value(std::move(val)), is_inherited(inherited) {}
-  T value{};
-  bool is_inherited{true};
-};
-
-// A bunch of helper function to create base::Value for specific C++ classes,
-// including vectors of types. These are used in template classes below
-// to simplify specialization logic.
-std::unique_ptr<base::FundamentalValue> TypedValueToJson(bool value);
-std::unique_ptr<base::FundamentalValue> TypedValueToJson(int value);
-std::unique_ptr<base::FundamentalValue> TypedValueToJson(double value);
-std::unique_ptr<base::StringValue> TypedValueToJson(const std::string& value);
-std::unique_ptr<base::DictionaryValue> TypedValueToJson(const ValueMap& value);
-std::unique_ptr<base::ListValue> TypedValueToJson(const ValueVector& value);
-template <typename T>
-std::unique_ptr<base::ListValue> TypedValueToJson(
-    const std::vector<T>& values) {
-  std::unique_ptr<base::ListValue> list(new base::ListValue);
-  for (const auto& v : values) {
-    auto json = TypedValueToJson(v);
-    CHECK(json);
-    list->Append(json.release());
-  }
-  return list;
-}
-
-// Similarly to TypedValueToJson() function above, the following overloaded
-// helper methods allow to extract specific C++ data types from base::Value.
-// Also used in template classes below to simplify specialization logic.
-// TODO(vitalybuka): Fix this. Interface is misleading. Seeing PropType internal
-// type validation is expected. In reality only ValueMap and ValueVector do
-// validation.
-bool TypedValueFromJson(const base::Value* value_in,
-                        const PropType* type,
-                        bool* value_out,
-                        ErrorPtr* error);
-bool TypedValueFromJson(const base::Value* value_in,
-                        const PropType* type,
-                        int* value_out,
-                        ErrorPtr* error);
-bool TypedValueFromJson(const base::Value* value_in,
-                        const PropType* type,
-                        double* value_out,
-                        ErrorPtr* error);
-bool TypedValueFromJson(const base::Value* value_in,
-                        const PropType* type,
-                        std::string* value_out,
-                        ErrorPtr* error);
-bool TypedValueFromJson(const base::Value* value_in,
-                        const PropType* type,
-                        ValueMap* value_out,
-                        ErrorPtr* error);
-bool TypedValueFromJson(const base::Value* value_in,
-                        const PropType* type,
-                        ValueVector* value_out,
-                        ErrorPtr* error);
-
-bool operator==(const ValueMap& obj1, const ValueMap& obj2);
-bool operator==(const ValueVector& arr1, const ValueVector& arr2);
-
-// CompareValue is a helper function to help with implementing EqualsTo operator
-// for various data types. For most scalar types it is using operator==(),
-// however, for floating point values, rounding errors in binary representation
-// of IEEE floats/doubles can cause straight == comparison to fail for seemingly
-// equivalent values. For these, use approximate comparison with the error
-// margin equal to the epsilon value defined for the corresponding data type.
-// This is used when looking up values for implementation of OneOf constraints
-// which should work reliably for floating points also ("number" type).
-
-// Compare exact types using ==.
-template <typename T>
-inline typename std::enable_if<!std::is_floating_point<T>::value, bool>::type
-CompareValue(const T& v1, const T& v2) {
-  return v1 == v2;
-}
-
-// Compare non-exact types (such as double) using precision margin (epsilon).
-template <typename T>
-inline typename std::enable_if<std::is_floating_point<T>::value, bool>::type
-CompareValue(const T& v1, const T& v2) {
-  return std::abs(v1 - v2) <= std::numeric_limits<T>::epsilon();
-}
-
-}  // namespace weave
-
-#endif  // LIBWEAVE_SRC_COMMANDS_SCHEMA_UTILS_H_
diff --git a/src/commands/schema_utils_unittest.cc b/src/commands/schema_utils_unittest.cc
deleted file mode 100644
index 1ea4c90..0000000
--- a/src/commands/schema_utils_unittest.cc
+++ /dev/null
@@ -1,212 +0,0 @@
-// 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/commands/schema_utils.h"
-
-#include <memory>
-#include <string>
-#include <vector>
-
-#include <base/values.h>
-#include <gtest/gtest.h>
-
-#include "src/commands/object_schema.h"
-#include "src/commands/prop_types.h"
-#include "src/commands/prop_values.h"
-#include "src/commands/schema_constants.h"
-#include "src/commands/unittest_utils.h"
-
-namespace weave {
-
-using test::CreateDictionaryValue;
-using test::CreateValue;
-
-TEST(CommandSchemaUtils, TypedValueToJson_Scalar) {
-  EXPECT_JSON_EQ("true", *TypedValueToJson(true));
-  EXPECT_JSON_EQ("false", *TypedValueToJson(false));
-
-  EXPECT_JSON_EQ("0", *TypedValueToJson(0));
-  EXPECT_JSON_EQ("-10", *TypedValueToJson(-10));
-  EXPECT_JSON_EQ("20", *TypedValueToJson(20));
-
-  EXPECT_JSON_EQ("0.0", *TypedValueToJson(0.0));
-  EXPECT_JSON_EQ("1.2", *TypedValueToJson(1.2));
-
-  EXPECT_JSON_EQ("'abc'", *TypedValueToJson(std::string("abc")));
-
-  std::vector<bool> bool_array{true, false};
-  EXPECT_JSON_EQ("[true,false]", *TypedValueToJson(bool_array));
-
-  std::vector<int> int_array{1, 2, 5};
-  EXPECT_JSON_EQ("[1,2,5]", *TypedValueToJson(int_array));
-
-  std::vector<double> dbl_array{1.1, 2.2};
-  EXPECT_JSON_EQ("[1.1,2.2]", *TypedValueToJson(dbl_array));
-
-  std::vector<std::string> str_array{"a", "bc"};
-  EXPECT_JSON_EQ("['a','bc']", *TypedValueToJson(str_array));
-}
-
-TEST(CommandSchemaUtils, TypedValueToJson_Object) {
-  IntPropType int_type;
-  ValueMap object;
-
-  object.insert(std::make_pair(
-      "width", int_type.CreateValue(base::FundamentalValue{640}, nullptr)));
-  object.insert(std::make_pair(
-      "height", int_type.CreateValue(base::FundamentalValue{480}, nullptr)));
-  EXPECT_JSON_EQ("{'height':480,'width':640}", *TypedValueToJson(object));
-}
-
-TEST(CommandSchemaUtils, TypedValueToJson_Array) {
-  IntPropType int_type;
-  ValueVector arr;
-
-  arr.push_back(int_type.CreateValue(base::FundamentalValue{640}, nullptr));
-  arr.push_back(int_type.CreateValue(base::FundamentalValue{480}, nullptr));
-  EXPECT_JSON_EQ("[640,480]", *TypedValueToJson(arr));
-}
-
-TEST(CommandSchemaUtils, TypedValueFromJson_Bool) {
-  bool value;
-
-  EXPECT_TRUE(
-      TypedValueFromJson(CreateValue("true").get(), nullptr, &value, nullptr));
-  EXPECT_TRUE(value);
-
-  EXPECT_TRUE(
-      TypedValueFromJson(CreateValue("false").get(), nullptr, &value, nullptr));
-  EXPECT_FALSE(value);
-
-  ErrorPtr error;
-  EXPECT_FALSE(
-      TypedValueFromJson(CreateValue("0").get(), nullptr, &value, &error));
-  EXPECT_EQ(errors::commands::kTypeMismatch, error->GetCode());
-  error.reset();
-}
-
-TEST(CommandSchemaUtils, TypedValueFromJson_Int) {
-  int value;
-
-  EXPECT_TRUE(
-      TypedValueFromJson(CreateValue("0").get(), nullptr, &value, nullptr));
-  EXPECT_EQ(0, value);
-
-  EXPECT_TRUE(
-      TypedValueFromJson(CreateValue("23").get(), nullptr, &value, nullptr));
-  EXPECT_EQ(23, value);
-
-  EXPECT_TRUE(
-      TypedValueFromJson(CreateValue("-1234").get(), nullptr, &value, nullptr));
-  EXPECT_EQ(-1234, value);
-
-  ErrorPtr error;
-  EXPECT_FALSE(
-      TypedValueFromJson(CreateValue("'abc'").get(), nullptr, &value, &error));
-  EXPECT_EQ(errors::commands::kTypeMismatch, error->GetCode());
-  error.reset();
-}
-
-TEST(CommandSchemaUtils, TypedValueFromJson_Double) {
-  double value;
-
-  EXPECT_TRUE(
-      TypedValueFromJson(CreateValue("0").get(), nullptr, &value, nullptr));
-  EXPECT_DOUBLE_EQ(0.0, value);
-  EXPECT_TRUE(
-      TypedValueFromJson(CreateValue("0.0").get(), nullptr, &value, nullptr));
-  EXPECT_DOUBLE_EQ(0.0, value);
-
-  EXPECT_TRUE(
-      TypedValueFromJson(CreateValue("23").get(), nullptr, &value, nullptr));
-  EXPECT_EQ(23.0, value);
-  EXPECT_TRUE(
-      TypedValueFromJson(CreateValue("23.1").get(), nullptr, &value, nullptr));
-  EXPECT_EQ(23.1, value);
-
-  EXPECT_TRUE(TypedValueFromJson(CreateValue("-1.23E+02").get(), nullptr,
-                                 &value, nullptr));
-  EXPECT_EQ(-123.0, value);
-
-  ErrorPtr error;
-  EXPECT_FALSE(
-      TypedValueFromJson(CreateValue("'abc'").get(), nullptr, &value, &error));
-  EXPECT_EQ(errors::commands::kTypeMismatch, error->GetCode());
-  error.reset();
-}
-
-TEST(CommandSchemaUtils, TypedValueFromJson_String) {
-  std::string value;
-
-  EXPECT_TRUE(
-      TypedValueFromJson(CreateValue("''").get(), nullptr, &value, nullptr));
-  EXPECT_EQ("", value);
-
-  EXPECT_TRUE(
-      TypedValueFromJson(CreateValue("'23'").get(), nullptr, &value, nullptr));
-  EXPECT_EQ("23", value);
-
-  EXPECT_TRUE(
-      TypedValueFromJson(CreateValue("'abc'").get(), nullptr, &value, nullptr));
-  EXPECT_EQ("abc", value);
-
-  ErrorPtr error;
-  EXPECT_FALSE(
-      TypedValueFromJson(CreateValue("12").get(), nullptr, &value, &error));
-  EXPECT_EQ(errors::commands::kTypeMismatch, error->GetCode());
-  error.reset();
-}
-
-TEST(CommandSchemaUtils, TypedValueFromJson_Object) {
-  ValueMap value;
-  std::unique_ptr<ObjectSchema> schema{new ObjectSchema};
-
-  IntPropType age_prop;
-  age_prop.AddMinMaxConstraint(0, 150);
-  schema->AddProp("age", age_prop.Clone());
-
-  StringPropType name_prop;
-  name_prop.AddLengthConstraint(1, 30);
-  schema->AddProp("name", name_prop.Clone());
-
-  ObjectPropType type;
-  type.SetObjectSchema(std::move(schema));
-  EXPECT_TRUE(TypedValueFromJson(CreateValue("{'age':20,'name':'Bob'}").get(),
-                                 &type, &value, nullptr));
-  ValueMap value2;
-  value2.insert(std::make_pair(
-      "age", age_prop.CreateValue(base::FundamentalValue{20}, nullptr)));
-  value2.insert(std::make_pair(
-      "name", name_prop.CreateValue(base::StringValue("Bob"), nullptr)));
-  EXPECT_EQ(value2, value);
-
-  ErrorPtr error;
-  EXPECT_FALSE(
-      TypedValueFromJson(CreateValue("'abc'").get(), nullptr, &value, &error));
-  EXPECT_EQ(errors::commands::kTypeMismatch, error->GetCode());
-  error.reset();
-}
-
-TEST(CommandSchemaUtils, TypedValueFromJson_Array) {
-  ValueVector arr;
-  StringPropType str_type;
-  str_type.AddLengthConstraint(3, 100);
-  ArrayPropType type;
-  type.SetItemType(str_type.Clone());
-
-  EXPECT_TRUE(TypedValueFromJson(CreateValue("['foo', 'bar']").get(), &type,
-                                 &arr, nullptr));
-  ValueVector arr2;
-  arr2.push_back(str_type.CreateValue(base::StringValue{"foo"}, nullptr));
-  arr2.push_back(str_type.CreateValue(base::StringValue{"bar"}, nullptr));
-  EXPECT_EQ(arr2, arr);
-
-  ErrorPtr error;
-  EXPECT_FALSE(TypedValueFromJson(CreateValue("['baz', 'ab']").get(), &type,
-                                  &arr, &error));
-  EXPECT_EQ(errors::commands::kOutOfRange, error->GetCode());
-  error.reset();
-}
-
-}  // namespace weave
diff --git a/src/commands/unittest_utils.h b/src/commands/unittest_utils.h
deleted file mode 100644
index 25392ee..0000000
--- a/src/commands/unittest_utils.h
+++ /dev/null
@@ -1,47 +0,0 @@
-// 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_COMMANDS_UNITTEST_UTILS_H_
-#define LIBWEAVE_SRC_COMMANDS_UNITTEST_UTILS_H_
-
-#include <memory>
-#include <string>
-
-#include <base/values.h>
-#include <gtest/gtest.h>
-#include <weave/test/unittest_utils.h>
-
-#include "src/commands/prop_types.h"
-#include "src/commands/prop_values.h"
-
-namespace weave {
-namespace test {
-
-template <typename T>
-std::unique_ptr<const PropValue> make_prop_value(const base::Value& value) {
-  auto prop_type = PropType::Create(GetValueType<T>());
-  return prop_type->CreatePropValue(value, nullptr);
-}
-
-inline std::unique_ptr<const PropValue> make_int_prop_value(int value) {
-  return make_prop_value<int>(base::FundamentalValue{value});
-}
-
-inline std::unique_ptr<const PropValue> make_double_prop_value(double value) {
-  return make_prop_value<double>(base::FundamentalValue{value});
-}
-
-inline std::unique_ptr<const PropValue> make_bool_prop_value(bool value) {
-  return make_prop_value<bool>(base::FundamentalValue{value});
-}
-
-inline std::unique_ptr<const PropValue> make_string_prop_value(
-    const std::string& value) {
-  return make_prop_value<std::string>(base::StringValue{value});
-}
-
-}  // namespace test
-}  // namespace weave
-
-#endif  // LIBWEAVE_SRC_COMMANDS_UNITTEST_UTILS_H_
diff --git a/src/config_unittest.cc b/src/config_unittest.cc
index 10ed07e..c36bb25 100644
--- a/src/config_unittest.cc
+++ b/src/config_unittest.cc
@@ -10,8 +10,7 @@
 #include <gmock/gmock.h>
 #include <gtest/gtest.h>
 #include <weave/provider/test/mock_config_store.h>
-
-#include "src/commands/unittest_utils.h"
+#include <weave/test/unittest_utils.h>
 
 using testing::_;
 using testing::Invoke;
diff --git a/src/device_registration_info_unittest.cc b/src/device_registration_info_unittest.cc
index 9b53872..f2fe4c4 100644
--- a/src/device_registration_info_unittest.cc
+++ b/src/device_registration_info_unittest.cc
@@ -11,10 +11,10 @@
 #include <weave/provider/test/fake_task_runner.h>
 #include <weave/provider/test/mock_config_store.h>
 #include <weave/provider/test/mock_http_client.h>
+#include <weave/test/unittest_utils.h>
 
 #include "src/bind_lambda.h"
 #include "src/commands/command_manager.h"
-#include "src/commands/unittest_utils.h"
 #include "src/http_constants.h"
 #include "src/states/mock_state_change_queue_interface.h"
 #include "src/states/state_manager.h"
diff --git a/src/notification/notification_parser_unittest.cc b/src/notification/notification_parser_unittest.cc
index d0b43fe..6b3916d 100644
--- a/src/notification/notification_parser_unittest.cc
+++ b/src/notification/notification_parser_unittest.cc
@@ -6,8 +6,7 @@
 
 #include <gmock/gmock.h>
 #include <gtest/gtest.h>
-
-#include "src/commands/unittest_utils.h"
+#include <weave/test/unittest_utils.h>
 
 using testing::SaveArg;
 using testing::Invoke;
diff --git a/src/states/state_change_queue.cc b/src/states/state_change_queue.cc
index 87cc18d..ba7bf65 100644
--- a/src/states/state_change_queue.cc
+++ b/src/states/state_change_queue.cc
@@ -5,6 +5,7 @@
 #include "src/states/state_change_queue.h"
 
 #include <base/logging.h>
+#include <base/values.h>
 
 namespace weave {
 
diff --git a/src/states/state_change_queue_interface.h b/src/states/state_change_queue_interface.h
index 81a2cfc..631a127 100644
--- a/src/states/state_change_queue_interface.h
+++ b/src/states/state_change_queue_interface.h
@@ -10,7 +10,9 @@
 #include <base/callback_list.h>
 #include <base/time/time.h>
 
-#include "src/commands/schema_utils.h"
+namespace base {
+class DictionaryValue;
+}  // namespace base
 
 namespace weave {
 
diff --git a/src/states/state_change_queue_unittest.cc b/src/states/state_change_queue_unittest.cc
index 865336c..bb2947a 100644
--- a/src/states/state_change_queue_unittest.cc
+++ b/src/states/state_change_queue_unittest.cc
@@ -5,9 +5,9 @@
 #include "src/states/state_change_queue.h"
 
 #include <gtest/gtest.h>
+#include <weave/test/unittest_utils.h>
 
 #include "src/bind_lambda.h"
-#include "src/commands/unittest_utils.h"
 
 namespace weave {
 
diff --git a/src/states/state_manager_unittest.cc b/src/states/state_manager_unittest.cc
index f336d42..f655e84 100644
--- a/src/states/state_manager_unittest.cc
+++ b/src/states/state_manager_unittest.cc
@@ -12,9 +12,9 @@
 #include <gmock/gmock.h>
 #include <gtest/gtest.h>
 #include <weave/provider/test/mock_config_store.h>
+#include <weave/test/unittest_utils.h>
 
 #include "src/commands/schema_constants.h"
-#include "src/commands/unittest_utils.h"
 #include "src/states/error_codes.h"
 #include "src/states/mock_state_change_queue_interface.h"
 
diff --git a/src/states/state_package_unittest.cc b/src/states/state_package_unittest.cc
index 0da005b..c116b37 100644
--- a/src/states/state_package_unittest.cc
+++ b/src/states/state_package_unittest.cc
@@ -9,9 +9,9 @@
 
 #include <base/values.h>
 #include <gtest/gtest.h>
+#include <weave/test/unittest_utils.h>
 
 #include "src/commands/schema_constants.h"
-#include "src/commands/unittest_utils.h"
 #include "src/states/error_codes.h"
 
 namespace weave {
diff --git a/src/test/mock_command.cc b/src/test/mock_command.cc
index a8564c4..65c2bab 100644
--- a/src/test/mock_command.cc
+++ b/src/test/mock_command.cc
@@ -8,8 +8,7 @@
 #include <string>
 
 #include <base/values.h>
-
-#include "src/commands/unittest_utils.h"
+#include <weave/test/unittest_utils.h>
 
 namespace weave {
 namespace test {
diff --git a/src/test/unittest_utils.cc b/src/test/unittest_utils.cc
index b9858e4..df8ccc0 100644
--- a/src/test/unittest_utils.cc
+++ b/src/test/unittest_utils.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/commands/unittest_utils.h"
+#include <weave/test/unittest_utils.h>
 
 #include <base/json/json_reader.h>
 #include <base/json/json_writer.h>
