diff --git a/buffet/commands/object_schema.cc b/buffet/commands/object_schema.cc
index 6437262..b89de98 100644
--- a/buffet/commands/object_schema.cc
+++ b/buffet/commands/object_schema.cc
@@ -9,6 +9,7 @@
 
 #include <base/logging.h>
 #include <base/values.h>
+#include <chromeos/map_utils.h>
 
 #include "buffet/commands/prop_types.h"
 #include "buffet/commands/prop_values.h"
@@ -16,49 +17,12 @@
 
 namespace buffet {
 
-void ObjectSchema::AddProp(const std::string& name,
-                           std::shared_ptr<PropType> prop) {
-  properties_[name] = prop;
-}
+namespace {
 
-const PropType* ObjectSchema::GetProp(const std::string& name) const {
-  auto p = properties_.find(name);
-  return p != properties_.end() ? p->second.get() : nullptr;
-}
-
-std::unique_ptr<base::DictionaryValue> ObjectSchema::ToJson(
-    bool full_schema, chromeos::ErrorPtr* error) const {
-  std::unique_ptr<base::DictionaryValue> value(new base::DictionaryValue);
-  for (const auto& pair : properties_) {
-    auto PropDef = pair.second->ToJson(full_schema, error);
-    if (!PropDef)
-      return std::unique_ptr<base::DictionaryValue>();
-    value->SetWithoutPathExpansion(pair.first, PropDef.release());
-  }
-  return value;
-}
-
-bool ObjectSchema::FromJson(const base::DictionaryValue* value,
-                            const ObjectSchema* object_schema,
-                            chromeos::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;
-    if (!PropFromJson(iter.key(), iter.value(), base_schema, &properties,
-                      error))
-      return false;
-    iter.Advance();
-  }
-  properties_ = std::move(properties);
-  return true;
-}
-
-static std::unique_ptr<PropType> CreatePropType(const std::string& type_name,
-                                                const std::string& prop_name,
-                                                chromeos::ErrorPtr* error) {
+// 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,
+                                         chromeos::ErrorPtr* error) {
   std::unique_ptr<PropType> prop;
   ValueType type;
   if (PropType::GetTypeFromTypeString(type_name, &type))
@@ -66,71 +30,40 @@
   if (!prop) {
     chromeos::Error::AddToPrintf(error, FROM_HERE, errors::commands::kDomain,
                                  errors::commands::kUnknownType,
-                                 "Unknown type %s for parameter %s",
-                                 type_name.c_str(), prop_name.c_str());
+                                 "Unknown type %s", type_name.c_str());
   }
   return prop;
 }
 
-static bool ErrorInvalidTypeInfo(const std::string& prop_name,
-                                 chromeos::ErrorPtr* error) {
-  chromeos::Error::AddToPrintf(error, FROM_HERE, errors::commands::kDomain,
-                               errors::commands::kNoTypeInfo,
-                               "Unable to determine parameter type for %s",
-                               prop_name.c_str());
-  return false;
+// Generates "no_type_info" error.
+void ErrorInvalidTypeInfo(chromeos::ErrorPtr* error) {
+  chromeos::Error::AddTo(error, FROM_HERE, errors::commands::kDomain,
+                         errors::commands::kNoTypeInfo,
+                         "Unable to determine parameter type");
 }
 
-bool ObjectSchema::PropFromJson(const std::string& prop_name,
-                                const base::Value& value,
-                                const PropType* base_schema,
-                                Properties* properties,
-                                chromeos::ErrorPtr* error) const {
-  if (value.IsType(base::Value::TYPE_STRING)) {
-    // A string value is a short-hand object specification and provides
-    // the parameter type.
-    return PropFromJsonString(prop_name, value, base_schema, properties,
-                              error);
-  } else if (value.IsType(base::Value::TYPE_LIST)) {
-    // One of the enumerated types.
-    return PropFromJsonArray(prop_name, value, base_schema, properties,
-                             error);
-  } else if (value.IsType(base::Value::TYPE_DICTIONARY)) {
-    // Full parameter definition.
-    return PropFromJsonObject(prop_name, value, base_schema, properties,
-                              error);
-  }
-  chromeos::Error::AddToPrintf(error, FROM_HERE, errors::commands::kDomain,
-                               errors::commands::kInvalidPropDef,
-                               "Invalid parameter definition for %s",
-                               prop_name.c_str());
-  return false;
-}
-
-bool ObjectSchema::PropFromJsonString(const std::string& prop_name,
-                                      const base::Value& value,
-                                      const PropType* base_schema,
-                                      Properties* properties,
-                                      chromeos::ErrorPtr* error) const {
+// 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,
+    chromeos::ErrorPtr* error) {
   std::string type_name;
   CHECK(value.GetAsString(&type_name)) << "Unable to get string value";
-  std::unique_ptr<PropType> prop = CreatePropType(type_name, prop_name, error);
-  if (!prop)
-    return false;
+  std::unique_ptr<PropType> prop = CreatePropType(type_name, error);
   base::DictionaryValue empty;
-  if (!prop->FromJson(&empty, base_schema, error)) {
-    chromeos::Error::AddToPrintf(error, FROM_HERE, errors::commands::kDomain,
-                                 errors::commands::kInvalidPropDef,
-                                 "Error in definition of property '%s'",
-                                 prop_name.c_str());
-    return false;
-  }
-  properties->insert(std::make_pair(prop_name, std::move(prop)));
-  return true;
+  if (prop && !prop->FromJson(&empty, base_schema, error))
+    prop.reset();
+
+  return prop;
 }
 
-static std::string DetectArrayType(const base::ListValue* list,
-                                   const PropType* base_schema) {
+// 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) {
   std::string type_name;
   if (base_schema) {
     type_name = base_schema->GetTypeAsString();
@@ -162,35 +95,37 @@
   return type_name;
 }
 
-bool ObjectSchema::PropFromJsonArray(const std::string& prop_name,
-                                     const base::Value& value,
-                                     const PropType* base_schema,
-                                     Properties* properties,
-                                     chromeos::ErrorPtr* error) const {
+// 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,
+    chromeos::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);
-  if (type_name.empty())
-    return ErrorInvalidTypeInfo(prop_name, error);
-  std::unique_ptr<PropType> prop = CreatePropType(type_name, prop_name, error);
-  if (!prop)
-    return false;
+  if (type_name.empty()) {
+    ErrorInvalidTypeInfo(error);
+    return prop;
+  }
   base::DictionaryValue array_object;
   array_object.SetWithoutPathExpansion(commands::attributes::kOneOf_Enum,
                                        list->DeepCopy());
-  if (!prop->FromJson(&array_object, base_schema, error)) {
-    chromeos::Error::AddToPrintf(error, FROM_HERE, errors::commands::kDomain,
-                                 errors::commands::kInvalidPropDef,
-                                 "Error in definition of property '%s'",
-                                 prop_name.c_str());
-    return false;
-  }
-  properties->insert(std::make_pair(prop_name, std::move(prop)));
-  return true;
+  prop = CreatePropType(type_name, error);
+  if (prop && !prop->FromJson(&array_object, base_schema, error))
+    prop.reset();
+
+  return prop;
 }
 
-static std::string DetectObjectType(const base::DictionaryValue* dict,
-                                    const PropType* base_schema) {
+// 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);
 
@@ -251,37 +186,119 @@
   return std::string();
 }
 
-bool ObjectSchema::PropFromJsonObject(const std::string& prop_name,
-                                      const base::Value& value,
-                                      const PropType* base_schema,
-                                      Properties* properties,
-                                      chromeos::ErrorPtr* error) const {
+// 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,
+    chromeos::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))
-      return ErrorInvalidTypeInfo(prop_name, error);
+    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)
-      return ErrorInvalidTypeInfo(prop_name, error);
+    if (!base_schema) {
+      ErrorInvalidTypeInfo(error);
+      return prop;
+    }
     type_name = base_schema->GetTypeAsString();
   }
-  std::unique_ptr<PropType> prop = CreatePropType(type_name, prop_name, error);
-  if (!prop)
-    return false;
-  if (!prop->FromJson(dict, base_schema, error)) {
-    chromeos::Error::AddToPrintf(error, FROM_HERE, errors::commands::kDomain,
-                                 errors::commands::kInvalidPropDef,
-                                 "Error in definition of property '%s'",
-                                 prop_name.c_str());
-    return false;
+  prop = CreatePropType(type_name, error);
+  if (prop && !prop->FromJson(dict, base_schema, error))
+    prop.reset();
+
+  return prop;
+}
+
+}  // anonymous namespace
+
+void ObjectSchema::AddProp(const std::string& name,
+                           std::shared_ptr<PropType> prop) {
+  properties_[name] = prop;
+}
+
+const PropType* ObjectSchema::GetProp(const std::string& name) const {
+  auto p = properties_.find(name);
+  return p != properties_.end() ? p->second.get() : nullptr;
+}
+
+std::unique_ptr<base::DictionaryValue> ObjectSchema::ToJson(
+    bool full_schema, chromeos::ErrorPtr* error) const {
+  std::unique_ptr<base::DictionaryValue> value(new base::DictionaryValue);
+  for (const auto& pair : properties_) {
+    auto PropDef = pair.second->ToJson(full_schema, error);
+    if (!PropDef)
+      return std::unique_ptr<base::DictionaryValue>();
+    value->SetWithoutPathExpansion(pair.first, PropDef.release());
   }
-  properties->insert(std::make_pair(prop_name, std::move(prop)));
+  return value;
+}
+
+bool ObjectSchema::FromJson(const base::DictionaryValue* value,
+                            const ObjectSchema* object_schema,
+                            chromeos::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 {
+      chromeos::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,
+    chromeos::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);
+  }
+  static const std::map<base::Value::Type, const char*> type_names = {
+    {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"},
+  };
+  const char* type_name = chromeos::GetOrDefault(type_names, value.GetType(),
+                                                 "<unknown>");
+  chromeos::Error::AddToPrintf(error, FROM_HERE, errors::commands::kDomain,
+                               errors::commands::kUnknownType,
+                               "Unexpected JSON value type: %s", type_name);
+  return {};
+}
+
 }  // namespace buffet
