diff --git a/lldb/source/Interpreter/OptionValueProperties.cpp b/lldb/source/Interpreter/OptionValueProperties.cpp
index 7024c36..d5f7e3f 100644
--- a/lldb/source/Interpreter/OptionValueProperties.cpp
+++ b/lldb/source/Interpreter/OptionValueProperties.cpp
@@ -1,4 +1,5 @@
-//===-- OptionValueProperties.cpp ---------------------------------*- C++ -*-===//
+//===-- OptionValueProperties.cpp ---------------------------------*- C++
+//-*-===//
 //
 //                     The LLVM Compiler Infrastructure
 //
@@ -24,89 +25,68 @@
 using namespace lldb;
 using namespace lldb_private;
 
+OptionValueProperties::OptionValueProperties(const ConstString &name)
+    : OptionValue(), m_name(name), m_properties(), m_name_to_index() {}
 
-OptionValueProperties::OptionValueProperties (const ConstString &name) :
-    OptionValue (),
-    m_name (name),
-    m_properties (),
-    m_name_to_index ()
-{
-}
-
-OptionValueProperties::OptionValueProperties (const OptionValueProperties &global_properties) :
-    OptionValue (global_properties),
-    std::enable_shared_from_this<OptionValueProperties> (),
-    m_name (global_properties.m_name),
-    m_properties (global_properties.m_properties),
-    m_name_to_index (global_properties.m_name_to_index)
-{
-    // We now have an exact copy of "global_properties". We need to now
-    // find all non-global settings and copy the property values so that
-    // all non-global settings get new OptionValue instances created for
-    // them.
-    const size_t num_properties = m_properties.size();
-    for (size_t i=0; i<num_properties; ++i)
-    {
-        // Duplicate any values that are not global when constructing properties from
-        // a global copy
-        if (m_properties[i].IsGlobal() == false)
-        {
-            lldb::OptionValueSP new_value_sp (m_properties[i].GetValue()->DeepCopy());
-            m_properties[i].SetOptionValue(new_value_sp);
-        }
+OptionValueProperties::OptionValueProperties(
+    const OptionValueProperties &global_properties)
+    : OptionValue(global_properties),
+      std::enable_shared_from_this<OptionValueProperties>(),
+      m_name(global_properties.m_name),
+      m_properties(global_properties.m_properties),
+      m_name_to_index(global_properties.m_name_to_index) {
+  // We now have an exact copy of "global_properties". We need to now
+  // find all non-global settings and copy the property values so that
+  // all non-global settings get new OptionValue instances created for
+  // them.
+  const size_t num_properties = m_properties.size();
+  for (size_t i = 0; i < num_properties; ++i) {
+    // Duplicate any values that are not global when constructing properties
+    // from
+    // a global copy
+    if (m_properties[i].IsGlobal() == false) {
+      lldb::OptionValueSP new_value_sp(m_properties[i].GetValue()->DeepCopy());
+      m_properties[i].SetOptionValue(new_value_sp);
     }
+  }
 }
 
-
-
-size_t
-OptionValueProperties::GetNumProperties() const
-{
-    return m_properties.size();
+size_t OptionValueProperties::GetNumProperties() const {
+  return m_properties.size();
 }
 
-
-void
-OptionValueProperties::Initialize (const PropertyDefinition *defs)
-{
-    for (size_t i=0; defs[i].name; ++i)
-    {
-        Property property(defs[i]);
-        assert(property.IsValid());
-        m_name_to_index.Append(property.GetName().GetCString(),m_properties.size());
-        property.GetValue()->SetParent(shared_from_this());
-        m_properties.push_back(property);
-    }
-    m_name_to_index.Sort();
-}
-
-void
-OptionValueProperties::SetValueChangedCallback (uint32_t property_idx,
-                                                OptionValueChangedCallback callback,
-                                                void *baton)
-{
-    Property *property = ProtectedGetPropertyAtIndex (property_idx);
-    if (property)
-        property->SetValueChangedCallback (callback, baton);
-}
-
-void
-OptionValueProperties::AppendProperty(const ConstString &name,
-                                      const ConstString &desc,
-                                      bool is_global,
-                                      const OptionValueSP &value_sp)
-{
-    Property property(name, desc, is_global, value_sp);
-    m_name_to_index.Append(name.GetCString(),m_properties.size());
+void OptionValueProperties::Initialize(const PropertyDefinition *defs) {
+  for (size_t i = 0; defs[i].name; ++i) {
+    Property property(defs[i]);
+    assert(property.IsValid());
+    m_name_to_index.Append(property.GetName().GetCString(),
+                           m_properties.size());
+    property.GetValue()->SetParent(shared_from_this());
     m_properties.push_back(property);
-    value_sp->SetParent (shared_from_this());
-    m_name_to_index.Sort();
+  }
+  m_name_to_index.Sort();
 }
 
+void OptionValueProperties::SetValueChangedCallback(
+    uint32_t property_idx, OptionValueChangedCallback callback, void *baton) {
+  Property *property = ProtectedGetPropertyAtIndex(property_idx);
+  if (property)
+    property->SetValueChangedCallback(callback, baton);
+}
 
+void OptionValueProperties::AppendProperty(const ConstString &name,
+                                           const ConstString &desc,
+                                           bool is_global,
+                                           const OptionValueSP &value_sp) {
+  Property property(name, desc, is_global, value_sp);
+  m_name_to_index.Append(name.GetCString(), m_properties.size());
+  m_properties.push_back(property);
+  value_sp->SetParent(shared_from_this());
+  m_name_to_index.Sort();
+}
 
-//bool
-//OptionValueProperties::GetQualifiedName (Stream &strm)
+// bool
+// OptionValueProperties::GetQualifiedName (Stream &strm)
 //{
 //    bool dumped_something = false;
 ////    lldb::OptionValuePropertiesSP parent_sp(GetParent ());
@@ -125,686 +105,589 @@
 //}
 //
 lldb::OptionValueSP
-OptionValueProperties::GetValueForKey  (const ExecutionContext *exe_ctx,
-                                        const ConstString &key,
-                                        bool will_modify) const
-{
-    lldb::OptionValueSP value_sp;
-    size_t idx = m_name_to_index.Find (key.GetCString(), SIZE_MAX);
-    if (idx < m_properties.size())
-        value_sp = GetPropertyAtIndex(exe_ctx, will_modify, idx)->GetValue();
-    return value_sp;
+OptionValueProperties::GetValueForKey(const ExecutionContext *exe_ctx,
+                                      const ConstString &key,
+                                      bool will_modify) const {
+  lldb::OptionValueSP value_sp;
+  size_t idx = m_name_to_index.Find(key.GetCString(), SIZE_MAX);
+  if (idx < m_properties.size())
+    value_sp = GetPropertyAtIndex(exe_ctx, will_modify, idx)->GetValue();
+  return value_sp;
 }
 
 lldb::OptionValueSP
-OptionValueProperties::GetSubValue (const ExecutionContext *exe_ctx,
-                                    const char *name,
-                                    bool will_modify,
-                                    Error &error) const
-{
-    lldb::OptionValueSP value_sp;
-    
-    if (name && name[0])
-    {
-        const char *sub_name = nullptr;
-        ConstString key;
-        size_t key_len = ::strcspn (name, ".[{");
-        
-        if (name[key_len])
-        {
-            key.SetCStringWithLength (name, key_len);
-            sub_name = name + key_len;
-        }
-        else
-            key.SetCString (name);
-        
-        value_sp = GetValueForKey (exe_ctx, key, will_modify);
-        if (sub_name && value_sp)
-        {
-            switch (sub_name[0])
-            {
-            case '.':
-            {
-                lldb::OptionValueSP return_val_sp;
-                return_val_sp = value_sp->GetSubValue (exe_ctx, sub_name + 1, will_modify, error);
-                if (!return_val_sp)
-                {
-                    if (Properties::IsSettingExperimental(sub_name + 1))
-                    {
-                        size_t experimental_len = strlen(Properties::GetExperimentalSettingsName()); 
-                        if (*(sub_name + experimental_len + 1) == '.')
-                        return_val_sp = value_sp->GetSubValue(exe_ctx, sub_name + experimental_len + 2, will_modify, error);
-                        // It isn't an error if an experimental setting is not present.
-                        if (!return_val_sp)
-                            error.Clear();
-                    }
-                }
-                return return_val_sp;
-            }
-            case '{':
-                // Predicate matching for predicates like
-                // "<setting-name>{<predicate>}"
-                // strings are parsed by the current OptionValueProperties subclass
-                // to mean whatever they want to. For instance a subclass of
-                // OptionValueProperties for a lldb_private::Target might implement:
-                // "target.run-args{arch==i386}"   -- only set run args if the arch is i386
-                // "target.run-args{path=/tmp/a/b/c/a.out}" -- only set run args if the path matches
-                // "target.run-args{basename==test&&arch==x86_64}" -- only set run args if executable basename is "test" and arch is "x86_64"
-                if (sub_name[1])
-                {
-                    const char *predicate_start = sub_name + 1;
-                    const char *predicate_end = strchr(predicate_start, '}');
-                    if (predicate_end)
-                    {
-                        std::string predicate(predicate_start, predicate_end);
-                        if (PredicateMatches(exe_ctx, predicate.c_str()))
-                        {
-                            if (predicate_end[1])
-                            {
-                                // Still more subvalue string to evaluate
-                                return value_sp->GetSubValue (exe_ctx, predicate_end + 1, will_modify, error);
-                            }
-                            else
-                            {
-                                // We have a match!
-                                break;
-                            }
-                        }
-                    }
-                }
-                // Predicate didn't match or wasn't correctly formed
-                value_sp.reset();
-                break;
-            
-            case '[':
-                // Array or dictionary access for subvalues like:
-                // "[12]"       -- access 12th array element
-                // "['hello']"  -- dictionary access of key named hello
-                return value_sp->GetSubValue (exe_ctx, sub_name, will_modify, error);
+OptionValueProperties::GetSubValue(const ExecutionContext *exe_ctx,
+                                   const char *name, bool will_modify,
+                                   Error &error) const {
+  lldb::OptionValueSP value_sp;
 
-            default:
-                value_sp.reset();
-                break;
-            }
+  if (name && name[0]) {
+    const char *sub_name = nullptr;
+    ConstString key;
+    size_t key_len = ::strcspn(name, ".[{");
+
+    if (name[key_len]) {
+      key.SetCStringWithLength(name, key_len);
+      sub_name = name + key_len;
+    } else
+      key.SetCString(name);
+
+    value_sp = GetValueForKey(exe_ctx, key, will_modify);
+    if (sub_name && value_sp) {
+      switch (sub_name[0]) {
+      case '.': {
+        lldb::OptionValueSP return_val_sp;
+        return_val_sp =
+            value_sp->GetSubValue(exe_ctx, sub_name + 1, will_modify, error);
+        if (!return_val_sp) {
+          if (Properties::IsSettingExperimental(sub_name + 1)) {
+            size_t experimental_len =
+                strlen(Properties::GetExperimentalSettingsName());
+            if (*(sub_name + experimental_len + 1) == '.')
+              return_val_sp = value_sp->GetSubValue(
+                  exe_ctx, sub_name + experimental_len + 2, will_modify, error);
+            // It isn't an error if an experimental setting is not present.
+            if (!return_val_sp)
+              error.Clear();
+          }
         }
+        return return_val_sp;
+      }
+      case '{':
+        // Predicate matching for predicates like
+        // "<setting-name>{<predicate>}"
+        // strings are parsed by the current OptionValueProperties subclass
+        // to mean whatever they want to. For instance a subclass of
+        // OptionValueProperties for a lldb_private::Target might implement:
+        // "target.run-args{arch==i386}"   -- only set run args if the arch is
+        // i386
+        // "target.run-args{path=/tmp/a/b/c/a.out}" -- only set run args if the
+        // path matches
+        // "target.run-args{basename==test&&arch==x86_64}" -- only set run args
+        // if executable basename is "test" and arch is "x86_64"
+        if (sub_name[1]) {
+          const char *predicate_start = sub_name + 1;
+          const char *predicate_end = strchr(predicate_start, '}');
+          if (predicate_end) {
+            std::string predicate(predicate_start, predicate_end);
+            if (PredicateMatches(exe_ctx, predicate.c_str())) {
+              if (predicate_end[1]) {
+                // Still more subvalue string to evaluate
+                return value_sp->GetSubValue(exe_ctx, predicate_end + 1,
+                                             will_modify, error);
+              } else {
+                // We have a match!
+                break;
+              }
+            }
+          }
+        }
+        // Predicate didn't match or wasn't correctly formed
+        value_sp.reset();
+        break;
+
+      case '[':
+        // Array or dictionary access for subvalues like:
+        // "[12]"       -- access 12th array element
+        // "['hello']"  -- dictionary access of key named hello
+        return value_sp->GetSubValue(exe_ctx, sub_name, will_modify, error);
+
+      default:
+        value_sp.reset();
+        break;
+      }
     }
-    return value_sp;
+  }
+  return value_sp;
 }
 
-Error
-OptionValueProperties::SetSubValue (const ExecutionContext *exe_ctx,
-                                    VarSetOperationType op,
-                                    const char *name,
-                                    const char *value)
-{
-    Error error;
-    const bool will_modify = true;
-    lldb::OptionValueSP value_sp (GetSubValue (exe_ctx, name, will_modify, error));
-    if (value_sp)
-        error = value_sp->SetValueFromString(value ? llvm::StringRef(value) : llvm::StringRef(), op);
-    else
-    {
-        if (error.AsCString() == nullptr)
-            error.SetErrorStringWithFormat("invalid value path '%s'", name);
-    }
-    return error;
+Error OptionValueProperties::SetSubValue(const ExecutionContext *exe_ctx,
+                                         VarSetOperationType op,
+                                         const char *name, const char *value) {
+  Error error;
+  const bool will_modify = true;
+  lldb::OptionValueSP value_sp(GetSubValue(exe_ctx, name, will_modify, error));
+  if (value_sp)
+    error = value_sp->SetValueFromString(
+        value ? llvm::StringRef(value) : llvm::StringRef(), op);
+  else {
+    if (error.AsCString() == nullptr)
+      error.SetErrorStringWithFormat("invalid value path '%s'", name);
+  }
+  return error;
 }
 
-
-ConstString
-OptionValueProperties::GetPropertyNameAtIndex (uint32_t idx) const
-{
-    const Property *property = GetPropertyAtIndex(nullptr, false, idx);
-    if (property)
-        return property->GetName();
-    return ConstString();
-    
+ConstString OptionValueProperties::GetPropertyNameAtIndex(uint32_t idx) const {
+  const Property *property = GetPropertyAtIndex(nullptr, false, idx);
+  if (property)
+    return property->GetName();
+  return ConstString();
 }
 
 const char *
-OptionValueProperties::GetPropertyDescriptionAtIndex (uint32_t idx) const
-{
-    const Property *property = GetPropertyAtIndex(nullptr, false, idx);
-    if (property)
-        return property->GetDescription();
-    return nullptr;
+OptionValueProperties::GetPropertyDescriptionAtIndex(uint32_t idx) const {
+  const Property *property = GetPropertyAtIndex(nullptr, false, idx);
+  if (property)
+    return property->GetDescription();
+  return nullptr;
 }
 
 uint32_t
-OptionValueProperties::GetPropertyIndex (const ConstString &name) const
-{
-    return m_name_to_index.Find (name.GetCString(), SIZE_MAX);
+OptionValueProperties::GetPropertyIndex(const ConstString &name) const {
+  return m_name_to_index.Find(name.GetCString(), SIZE_MAX);
 }
 
 const Property *
-OptionValueProperties::GetProperty (const ExecutionContext *exe_ctx, bool will_modify, const ConstString &name) const
-{
-    return GetPropertyAtIndex (exe_ctx, will_modify, m_name_to_index.Find (name.GetCString(), SIZE_MAX));
+OptionValueProperties::GetProperty(const ExecutionContext *exe_ctx,
+                                   bool will_modify,
+                                   const ConstString &name) const {
+  return GetPropertyAtIndex(exe_ctx, will_modify,
+                            m_name_to_index.Find(name.GetCString(), SIZE_MAX));
 }
 
-const Property *
-OptionValueProperties::GetPropertyAtIndex (const ExecutionContext *exe_ctx, bool will_modify, uint32_t idx) const
-{
-    return ProtectedGetPropertyAtIndex (idx);
+const Property *OptionValueProperties::GetPropertyAtIndex(
+    const ExecutionContext *exe_ctx, bool will_modify, uint32_t idx) const {
+  return ProtectedGetPropertyAtIndex(idx);
 }
 
-lldb::OptionValueSP
-OptionValueProperties::GetPropertyValueAtIndex (const ExecutionContext *exe_ctx,
-                                                bool will_modify,
-                                                uint32_t idx) const
-{
-    const Property *setting = GetPropertyAtIndex (exe_ctx, will_modify, idx);
-    if (setting)
-        return setting->GetValue();
-    return OptionValueSP();
+lldb::OptionValueSP OptionValueProperties::GetPropertyValueAtIndex(
+    const ExecutionContext *exe_ctx, bool will_modify, uint32_t idx) const {
+  const Property *setting = GetPropertyAtIndex(exe_ctx, will_modify, idx);
+  if (setting)
+    return setting->GetValue();
+  return OptionValueSP();
 }
 
 OptionValuePathMappings *
-OptionValueProperties::GetPropertyAtIndexAsOptionValuePathMappings (const ExecutionContext *exe_ctx, bool will_modify, uint32_t idx) const
-{
-    OptionValueSP value_sp(GetPropertyValueAtIndex (exe_ctx, will_modify, idx));
-    if (value_sp)
-        return value_sp->GetAsPathMappings();
-    return nullptr;
+OptionValueProperties::GetPropertyAtIndexAsOptionValuePathMappings(
+    const ExecutionContext *exe_ctx, bool will_modify, uint32_t idx) const {
+  OptionValueSP value_sp(GetPropertyValueAtIndex(exe_ctx, will_modify, idx));
+  if (value_sp)
+    return value_sp->GetAsPathMappings();
+  return nullptr;
 }
 
 OptionValueFileSpecList *
-OptionValueProperties::GetPropertyAtIndexAsOptionValueFileSpecList (const ExecutionContext *exe_ctx, bool will_modify, uint32_t idx) const
-{
-    OptionValueSP value_sp(GetPropertyValueAtIndex (exe_ctx, will_modify, idx));
-    if (value_sp)
-        return value_sp->GetAsFileSpecList();
-    return nullptr;
+OptionValueProperties::GetPropertyAtIndexAsOptionValueFileSpecList(
+    const ExecutionContext *exe_ctx, bool will_modify, uint32_t idx) const {
+  OptionValueSP value_sp(GetPropertyValueAtIndex(exe_ctx, will_modify, idx));
+  if (value_sp)
+    return value_sp->GetAsFileSpecList();
+  return nullptr;
 }
 
-OptionValueArch *
-OptionValueProperties::GetPropertyAtIndexAsOptionValueArch (const ExecutionContext *exe_ctx, uint32_t idx) const
-{
-    const Property *property = GetPropertyAtIndex (exe_ctx, false, idx);
-    if (property)
-        return property->GetValue()->GetAsArch();
-    return nullptr;
+OptionValueArch *OptionValueProperties::GetPropertyAtIndexAsOptionValueArch(
+    const ExecutionContext *exe_ctx, uint32_t idx) const {
+  const Property *property = GetPropertyAtIndex(exe_ctx, false, idx);
+  if (property)
+    return property->GetValue()->GetAsArch();
+  return nullptr;
 }
 
 OptionValueLanguage *
-OptionValueProperties::GetPropertyAtIndexAsOptionValueLanguage (const ExecutionContext *exe_ctx, uint32_t idx) const
-{
-    const Property *property = GetPropertyAtIndex (exe_ctx, false, idx);
-    if (property)
-        return property->GetValue()->GetAsLanguage();
-    return nullptr;
+OptionValueProperties::GetPropertyAtIndexAsOptionValueLanguage(
+    const ExecutionContext *exe_ctx, uint32_t idx) const {
+  const Property *property = GetPropertyAtIndex(exe_ctx, false, idx);
+  if (property)
+    return property->GetValue()->GetAsLanguage();
+  return nullptr;
 }
 
-bool
-OptionValueProperties::GetPropertyAtIndexAsArgs (const ExecutionContext *exe_ctx, uint32_t idx, Args &args) const
-{
-    const Property *property = GetPropertyAtIndex (exe_ctx, false, idx);
-    if (property)
-    {
-        OptionValue *value = property->GetValue().get();
-        if (value)
-        {
-            const OptionValueArray *array = value->GetAsArray();
-            if (array)
-                return array->GetArgs(args);
-            else
-            {
-                const OptionValueDictionary *dict = value->GetAsDictionary();
-                if (dict)
-                    return dict->GetArgs(args);
-            }
-        }
+bool OptionValueProperties::GetPropertyAtIndexAsArgs(
+    const ExecutionContext *exe_ctx, uint32_t idx, Args &args) const {
+  const Property *property = GetPropertyAtIndex(exe_ctx, false, idx);
+  if (property) {
+    OptionValue *value = property->GetValue().get();
+    if (value) {
+      const OptionValueArray *array = value->GetAsArray();
+      if (array)
+        return array->GetArgs(args);
+      else {
+        const OptionValueDictionary *dict = value->GetAsDictionary();
+        if (dict)
+          return dict->GetArgs(args);
+      }
     }
-    return false;
+  }
+  return false;
 }
 
-bool
-OptionValueProperties::SetPropertyAtIndexFromArgs (const ExecutionContext *exe_ctx, uint32_t idx, const Args &args)
-{
-    const Property *property = GetPropertyAtIndex (exe_ctx, true, idx);
-    if (property)
-    {
-        OptionValue *value = property->GetValue().get();
-        if (value)
-        {
-            OptionValueArray *array = value->GetAsArray();
-            if (array)
-                return array->SetArgs(args, eVarSetOperationAssign).Success();
-            else
-            {
-                OptionValueDictionary *dict = value->GetAsDictionary();
-                if (dict)
-                    return dict->SetArgs(args, eVarSetOperationAssign).Success();
-            }
-        }
+bool OptionValueProperties::SetPropertyAtIndexFromArgs(
+    const ExecutionContext *exe_ctx, uint32_t idx, const Args &args) {
+  const Property *property = GetPropertyAtIndex(exe_ctx, true, idx);
+  if (property) {
+    OptionValue *value = property->GetValue().get();
+    if (value) {
+      OptionValueArray *array = value->GetAsArray();
+      if (array)
+        return array->SetArgs(args, eVarSetOperationAssign).Success();
+      else {
+        OptionValueDictionary *dict = value->GetAsDictionary();
+        if (dict)
+          return dict->SetArgs(args, eVarSetOperationAssign).Success();
+      }
     }
-    return false;
+  }
+  return false;
 }
 
-bool
-OptionValueProperties::GetPropertyAtIndexAsBoolean (const ExecutionContext *exe_ctx, uint32_t idx, bool fail_value) const
-{
-    const Property *property = GetPropertyAtIndex (exe_ctx, false, idx);
-    if (property)
-    {
-        OptionValue *value = property->GetValue().get();
-        if (value)
-            return value->GetBooleanValue(fail_value);
-    }
-    return fail_value;
+bool OptionValueProperties::GetPropertyAtIndexAsBoolean(
+    const ExecutionContext *exe_ctx, uint32_t idx, bool fail_value) const {
+  const Property *property = GetPropertyAtIndex(exe_ctx, false, idx);
+  if (property) {
+    OptionValue *value = property->GetValue().get();
+    if (value)
+      return value->GetBooleanValue(fail_value);
+  }
+  return fail_value;
 }
 
-bool
-OptionValueProperties::SetPropertyAtIndexAsBoolean (const ExecutionContext *exe_ctx, uint32_t idx, bool new_value)
-{
-    const Property *property = GetPropertyAtIndex (exe_ctx, true, idx);
-    if (property)
-    {
-        OptionValue *value = property->GetValue().get();
-        if (value)
-        {
-            value->SetBooleanValue(new_value);
-            return true;
-        }
+bool OptionValueProperties::SetPropertyAtIndexAsBoolean(
+    const ExecutionContext *exe_ctx, uint32_t idx, bool new_value) {
+  const Property *property = GetPropertyAtIndex(exe_ctx, true, idx);
+  if (property) {
+    OptionValue *value = property->GetValue().get();
+    if (value) {
+      value->SetBooleanValue(new_value);
+      return true;
     }
-    return false;
+  }
+  return false;
 }
 
 OptionValueDictionary *
-OptionValueProperties::GetPropertyAtIndexAsOptionValueDictionary (const ExecutionContext *exe_ctx, uint32_t idx) const
-{
-    const Property *property = GetPropertyAtIndex (exe_ctx, false, idx);
-    if (property)
-        return property->GetValue()->GetAsDictionary();
-    return nullptr;
+OptionValueProperties::GetPropertyAtIndexAsOptionValueDictionary(
+    const ExecutionContext *exe_ctx, uint32_t idx) const {
+  const Property *property = GetPropertyAtIndex(exe_ctx, false, idx);
+  if (property)
+    return property->GetValue()->GetAsDictionary();
+  return nullptr;
 }
 
-int64_t
-OptionValueProperties::GetPropertyAtIndexAsEnumeration (const ExecutionContext *exe_ctx, uint32_t idx, int64_t fail_value) const
-{
-    const Property *property = GetPropertyAtIndex (exe_ctx, false, idx);
-    if (property)
-    {
-        OptionValue *value = property->GetValue().get();
-        if (value)
-            return value->GetEnumerationValue(fail_value);
-    }
-    return fail_value;
+int64_t OptionValueProperties::GetPropertyAtIndexAsEnumeration(
+    const ExecutionContext *exe_ctx, uint32_t idx, int64_t fail_value) const {
+  const Property *property = GetPropertyAtIndex(exe_ctx, false, idx);
+  if (property) {
+    OptionValue *value = property->GetValue().get();
+    if (value)
+      return value->GetEnumerationValue(fail_value);
+  }
+  return fail_value;
 }
 
-bool
-OptionValueProperties::SetPropertyAtIndexAsEnumeration (const ExecutionContext *exe_ctx, uint32_t idx, int64_t new_value)
-{
-    const Property *property = GetPropertyAtIndex (exe_ctx, true, idx);
-    if (property)
-    {
-        OptionValue *value = property->GetValue().get();
-        if (value)
-            return value->SetEnumerationValue(new_value);
-    }
-    return false;
+bool OptionValueProperties::SetPropertyAtIndexAsEnumeration(
+    const ExecutionContext *exe_ctx, uint32_t idx, int64_t new_value) {
+  const Property *property = GetPropertyAtIndex(exe_ctx, true, idx);
+  if (property) {
+    OptionValue *value = property->GetValue().get();
+    if (value)
+      return value->SetEnumerationValue(new_value);
+  }
+  return false;
 }
 
 const FormatEntity::Entry *
-OptionValueProperties::GetPropertyAtIndexAsFormatEntity (const ExecutionContext *exe_ctx, uint32_t idx)
-{
-    const Property *property = GetPropertyAtIndex (exe_ctx, true, idx);
-    if (property)
-    {
-        OptionValue *value = property->GetValue().get();
-        if (value)
-            return value->GetFormatEntity();
-    }
-    return nullptr;
+OptionValueProperties::GetPropertyAtIndexAsFormatEntity(
+    const ExecutionContext *exe_ctx, uint32_t idx) {
+  const Property *property = GetPropertyAtIndex(exe_ctx, true, idx);
+  if (property) {
+    OptionValue *value = property->GetValue().get();
+    if (value)
+      return value->GetFormatEntity();
+  }
+  return nullptr;
 }
 
 OptionValueFileSpec *
-OptionValueProperties::GetPropertyAtIndexAsOptionValueFileSpec (const ExecutionContext *exe_ctx, bool will_modify, uint32_t idx) const
-{
-    const Property *property = GetPropertyAtIndex (exe_ctx, false, idx);
-    if (property)
-    {
-        OptionValue *value = property->GetValue().get();
-        if (value)
-            return value->GetAsFileSpec();
-    }
-    return nullptr;
+OptionValueProperties::GetPropertyAtIndexAsOptionValueFileSpec(
+    const ExecutionContext *exe_ctx, bool will_modify, uint32_t idx) const {
+  const Property *property = GetPropertyAtIndex(exe_ctx, false, idx);
+  if (property) {
+    OptionValue *value = property->GetValue().get();
+    if (value)
+      return value->GetAsFileSpec();
+  }
+  return nullptr;
 }
 
-
-FileSpec
-OptionValueProperties::GetPropertyAtIndexAsFileSpec (const ExecutionContext *exe_ctx, uint32_t idx) const
-{
-    const Property *property = GetPropertyAtIndex (exe_ctx, false, idx);
-    if (property)
-    {
-        OptionValue *value = property->GetValue().get();
-        if (value)
-            return value->GetFileSpecValue();
-    }
-    return FileSpec();
+FileSpec OptionValueProperties::GetPropertyAtIndexAsFileSpec(
+    const ExecutionContext *exe_ctx, uint32_t idx) const {
+  const Property *property = GetPropertyAtIndex(exe_ctx, false, idx);
+  if (property) {
+    OptionValue *value = property->GetValue().get();
+    if (value)
+      return value->GetFileSpecValue();
+  }
+  return FileSpec();
 }
 
-
-bool
-OptionValueProperties::SetPropertyAtIndexAsFileSpec (const ExecutionContext *exe_ctx, uint32_t idx, const FileSpec &new_file_spec)
-{
-    const Property *property = GetPropertyAtIndex (exe_ctx, true, idx);
-    if (property)
-    {
-        OptionValue *value = property->GetValue().get();
-        if (value)
-            return value->SetFileSpecValue(new_file_spec);
-    }
-    return false;
+bool OptionValueProperties::SetPropertyAtIndexAsFileSpec(
+    const ExecutionContext *exe_ctx, uint32_t idx,
+    const FileSpec &new_file_spec) {
+  const Property *property = GetPropertyAtIndex(exe_ctx, true, idx);
+  if (property) {
+    OptionValue *value = property->GetValue().get();
+    if (value)
+      return value->SetFileSpecValue(new_file_spec);
+  }
+  return false;
 }
 
 const RegularExpression *
-OptionValueProperties::GetPropertyAtIndexAsOptionValueRegex (const ExecutionContext *exe_ctx, uint32_t idx) const
-{
-    const Property *property = GetPropertyAtIndex (exe_ctx, false, idx);
+OptionValueProperties::GetPropertyAtIndexAsOptionValueRegex(
+    const ExecutionContext *exe_ctx, uint32_t idx) const {
+  const Property *property = GetPropertyAtIndex(exe_ctx, false, idx);
+  if (property) {
+    OptionValue *value = property->GetValue().get();
+    if (value)
+      return value->GetRegexValue();
+  }
+  return nullptr;
+}
+
+OptionValueSInt64 *OptionValueProperties::GetPropertyAtIndexAsOptionValueSInt64(
+    const ExecutionContext *exe_ctx, uint32_t idx) const {
+  const Property *property = GetPropertyAtIndex(exe_ctx, false, idx);
+  if (property) {
+    OptionValue *value = property->GetValue().get();
+    if (value)
+      return value->GetAsSInt64();
+  }
+  return nullptr;
+}
+
+int64_t OptionValueProperties::GetPropertyAtIndexAsSInt64(
+    const ExecutionContext *exe_ctx, uint32_t idx, int64_t fail_value) const {
+  const Property *property = GetPropertyAtIndex(exe_ctx, false, idx);
+  if (property) {
+    OptionValue *value = property->GetValue().get();
+    if (value)
+      return value->GetSInt64Value(fail_value);
+  }
+  return fail_value;
+}
+
+bool OptionValueProperties::SetPropertyAtIndexAsSInt64(
+    const ExecutionContext *exe_ctx, uint32_t idx, int64_t new_value) {
+  const Property *property = GetPropertyAtIndex(exe_ctx, true, idx);
+  if (property) {
+    OptionValue *value = property->GetValue().get();
+    if (value)
+      return value->SetSInt64Value(new_value);
+  }
+  return false;
+}
+
+const char *OptionValueProperties::GetPropertyAtIndexAsString(
+    const ExecutionContext *exe_ctx, uint32_t idx,
+    const char *fail_value) const {
+  const Property *property = GetPropertyAtIndex(exe_ctx, false, idx);
+  if (property) {
+    OptionValue *value = property->GetValue().get();
+    if (value)
+      return value->GetStringValue(fail_value);
+  }
+  return fail_value;
+}
+
+bool OptionValueProperties::SetPropertyAtIndexAsString(
+    const ExecutionContext *exe_ctx, uint32_t idx, const char *new_value) {
+  const Property *property = GetPropertyAtIndex(exe_ctx, true, idx);
+  if (property) {
+    OptionValue *value = property->GetValue().get();
+    if (value)
+      return value->SetStringValue(new_value);
+  }
+  return false;
+}
+
+OptionValueString *OptionValueProperties::GetPropertyAtIndexAsOptionValueString(
+    const ExecutionContext *exe_ctx, bool will_modify, uint32_t idx) const {
+  OptionValueSP value_sp(GetPropertyValueAtIndex(exe_ctx, will_modify, idx));
+  if (value_sp)
+    return value_sp->GetAsString();
+  return nullptr;
+}
+
+uint64_t OptionValueProperties::GetPropertyAtIndexAsUInt64(
+    const ExecutionContext *exe_ctx, uint32_t idx, uint64_t fail_value) const {
+  const Property *property = GetPropertyAtIndex(exe_ctx, false, idx);
+  if (property) {
+    OptionValue *value = property->GetValue().get();
+    if (value)
+      return value->GetUInt64Value(fail_value);
+  }
+  return fail_value;
+}
+
+bool OptionValueProperties::SetPropertyAtIndexAsUInt64(
+    const ExecutionContext *exe_ctx, uint32_t idx, uint64_t new_value) {
+  const Property *property = GetPropertyAtIndex(exe_ctx, true, idx);
+  if (property) {
+    OptionValue *value = property->GetValue().get();
+    if (value)
+      return value->SetUInt64Value(new_value);
+  }
+  return false;
+}
+
+bool OptionValueProperties::Clear() {
+  const size_t num_properties = m_properties.size();
+  for (size_t i = 0; i < num_properties; ++i)
+    m_properties[i].GetValue()->Clear();
+  return true;
+}
+
+Error OptionValueProperties::SetValueFromString(llvm::StringRef value,
+                                                VarSetOperationType op) {
+  Error error;
+
+  //    Args args(value_cstr);
+  //    const size_t argc = args.GetArgumentCount();
+  switch (op) {
+  case eVarSetOperationClear:
+    Clear();
+    break;
+
+  case eVarSetOperationReplace:
+  case eVarSetOperationAssign:
+  case eVarSetOperationRemove:
+  case eVarSetOperationInsertBefore:
+  case eVarSetOperationInsertAfter:
+  case eVarSetOperationAppend:
+  case eVarSetOperationInvalid:
+    error = OptionValue::SetValueFromString(value, op);
+    break;
+  }
+
+  return error;
+}
+
+void OptionValueProperties::DumpValue(const ExecutionContext *exe_ctx,
+                                      Stream &strm, uint32_t dump_mask) {
+  const size_t num_properties = m_properties.size();
+  for (size_t i = 0; i < num_properties; ++i) {
+    const Property *property = GetPropertyAtIndex(exe_ctx, false, i);
+    if (property) {
+      OptionValue *option_value = property->GetValue().get();
+      assert(option_value);
+      const bool transparent_value = option_value->ValueIsTransparent();
+      property->Dump(exe_ctx, strm, dump_mask);
+      if (!transparent_value)
+        strm.EOL();
+    }
+  }
+}
+
+Error OptionValueProperties::DumpPropertyValue(const ExecutionContext *exe_ctx,
+                                               Stream &strm,
+                                               const char *property_path,
+                                               uint32_t dump_mask) {
+  Error error;
+  const bool will_modify = false;
+  lldb::OptionValueSP value_sp(
+      GetSubValue(exe_ctx, property_path, will_modify, error));
+  if (value_sp) {
+    if (!value_sp->ValueIsTransparent()) {
+      if (dump_mask & eDumpOptionName)
+        strm.PutCString(property_path);
+      if (dump_mask & ~eDumpOptionName)
+        strm.PutChar(' ');
+    }
+    value_sp->DumpValue(exe_ctx, strm, dump_mask);
+  }
+  return error;
+}
+
+lldb::OptionValueSP OptionValueProperties::DeepCopy() const {
+  assert(!"this shouldn't happen");
+  return lldb::OptionValueSP();
+}
+
+const Property *OptionValueProperties::GetPropertyAtPath(
+    const ExecutionContext *exe_ctx, bool will_modify, const char *name) const {
+  const Property *property = nullptr;
+  if (name && name[0]) {
+    const char *sub_name = nullptr;
+    ConstString key;
+    size_t key_len = ::strcspn(name, ".[{");
+
+    if (name[key_len]) {
+      key.SetCStringWithLength(name, key_len);
+      sub_name = name + key_len;
+    } else
+      key.SetCString(name);
+
+    property = GetProperty(exe_ctx, will_modify, key);
+    if (sub_name && property) {
+      if (sub_name[0] == '.') {
+        OptionValueProperties *sub_properties =
+            property->GetValue()->GetAsProperties();
+        if (sub_properties)
+          return sub_properties->GetPropertyAtPath(exe_ctx, will_modify,
+                                                   sub_name + 1);
+      }
+      property = nullptr;
+    }
+  }
+  return property;
+}
+
+void OptionValueProperties::DumpAllDescriptions(CommandInterpreter &interpreter,
+                                                Stream &strm) const {
+  size_t max_name_len = 0;
+  const size_t num_properties = m_properties.size();
+  for (size_t i = 0; i < num_properties; ++i) {
+    const Property *property = ProtectedGetPropertyAtIndex(i);
     if (property)
-    {
-        OptionValue *value = property->GetValue().get();
-        if (value)
-            return value->GetRegexValue();
-    }
-    return nullptr;
-}
-
-OptionValueSInt64 *
-OptionValueProperties::GetPropertyAtIndexAsOptionValueSInt64 (const ExecutionContext *exe_ctx, uint32_t idx) const
-{
-    const Property *property = GetPropertyAtIndex (exe_ctx, false, idx);
+      max_name_len =
+          std::max<size_t>(property->GetName().GetLength(), max_name_len);
+  }
+  for (size_t i = 0; i < num_properties; ++i) {
+    const Property *property = ProtectedGetPropertyAtIndex(i);
     if (property)
-    {
-        OptionValue *value = property->GetValue().get();
-        if (value)
-            return value->GetAsSInt64();
-    }
-    return nullptr;
+      property->DumpDescription(interpreter, strm, max_name_len, false);
+  }
 }
 
-int64_t
-OptionValueProperties::GetPropertyAtIndexAsSInt64 (const ExecutionContext *exe_ctx, uint32_t idx, int64_t fail_value) const
-{
-    const Property *property = GetPropertyAtIndex (exe_ctx, false, idx);
-    if (property)
-    {
-        OptionValue *value = property->GetValue().get();
-        if (value)
-            return value->GetSInt64Value(fail_value);
-    }
-    return fail_value;
-}
-
-bool
-OptionValueProperties::SetPropertyAtIndexAsSInt64 (const ExecutionContext *exe_ctx, uint32_t idx, int64_t new_value)
-{
-    const Property *property = GetPropertyAtIndex (exe_ctx, true, idx);
-    if (property)
-    {
-        OptionValue *value = property->GetValue().get();
-        if (value)
-            return value->SetSInt64Value(new_value);
-    }
-    return false;
-}
-
-const char *
-OptionValueProperties::GetPropertyAtIndexAsString (const ExecutionContext *exe_ctx, uint32_t idx, const char *fail_value) const
-{
-    const Property *property = GetPropertyAtIndex (exe_ctx, false, idx);
-    if (property)
-    {
-        OptionValue *value = property->GetValue().get();
-        if (value)
-            return value->GetStringValue(fail_value);
-    }
-    return fail_value;
-}
-
-bool
-OptionValueProperties::SetPropertyAtIndexAsString (const ExecutionContext *exe_ctx, uint32_t idx, const char *new_value)
-{
-    const Property *property = GetPropertyAtIndex (exe_ctx, true, idx);
-    if (property)
-    {
-        OptionValue *value = property->GetValue().get();
-        if (value)
-            return value->SetStringValue(new_value);
-    }
-    return false;
-}
-
-OptionValueString *
-OptionValueProperties::GetPropertyAtIndexAsOptionValueString (const ExecutionContext *exe_ctx, bool will_modify, uint32_t idx) const
-{
-    OptionValueSP value_sp(GetPropertyValueAtIndex (exe_ctx, will_modify, idx));
-    if (value_sp)
-        return value_sp->GetAsString();
-    return nullptr;
-}
-
-
-uint64_t
-OptionValueProperties::GetPropertyAtIndexAsUInt64 (const ExecutionContext *exe_ctx, uint32_t idx, uint64_t fail_value) const
-{
-    const Property *property = GetPropertyAtIndex (exe_ctx, false, idx);
-    if (property)
-    {
-        OptionValue *value = property->GetValue().get();
-        if (value)
-            return value->GetUInt64Value(fail_value);
-    }
-    return fail_value;
-}
-
-bool
-OptionValueProperties::SetPropertyAtIndexAsUInt64 (const ExecutionContext *exe_ctx, uint32_t idx, uint64_t new_value)
-{
-    const Property *property = GetPropertyAtIndex (exe_ctx, true, idx);
-    if (property)
-    {
-        OptionValue *value = property->GetValue().get();
-        if (value)
-            return value->SetUInt64Value(new_value);
-    }
-    return false;
-}
-
-bool
-OptionValueProperties::Clear ()
-{
-    const size_t num_properties = m_properties.size();
-    for (size_t i=0; i<num_properties; ++i)
-        m_properties[i].GetValue()->Clear();
-    return true;
-}
-
-
-Error
-OptionValueProperties::SetValueFromString (llvm::StringRef value, VarSetOperationType op)
-{
-    Error error;
-    
-//    Args args(value_cstr);
-//    const size_t argc = args.GetArgumentCount();
-    switch (op)
-    {
-        case eVarSetOperationClear:
-            Clear ();
-            break;
-            
-        case eVarSetOperationReplace:
-        case eVarSetOperationAssign:
-        case eVarSetOperationRemove:
-        case eVarSetOperationInsertBefore:
-        case eVarSetOperationInsertAfter:
-        case eVarSetOperationAppend:
-        case eVarSetOperationInvalid:
-            error = OptionValue::SetValueFromString (value, op);
-            break;
-    }
-    
-    return error;
-}
-
-void
-OptionValueProperties::DumpValue (const ExecutionContext *exe_ctx, Stream &strm, uint32_t dump_mask)
-{
-    const size_t num_properties = m_properties.size();
-    for (size_t i=0; i<num_properties; ++i)
-    {
-        const Property *property = GetPropertyAtIndex(exe_ctx, false, i);
-        if (property)
-        {
-            OptionValue *option_value = property->GetValue().get();
-            assert (option_value);
-            const bool transparent_value = option_value->ValueIsTransparent ();
-            property->Dump (exe_ctx,
-                            strm,
-                            dump_mask);
-            if (!transparent_value)
-                strm.EOL();
+void OptionValueProperties::Apropos(
+    const char *keyword,
+    std::vector<const Property *> &matching_properties) const {
+  const size_t num_properties = m_properties.size();
+  StreamString strm;
+  for (size_t i = 0; i < num_properties; ++i) {
+    const Property *property = ProtectedGetPropertyAtIndex(i);
+    if (property) {
+      const OptionValueProperties *properties =
+          property->GetValue()->GetAsProperties();
+      if (properties) {
+        properties->Apropos(keyword, matching_properties);
+      } else {
+        bool match = false;
+        const char *name = property->GetName().GetCString();
+        if (name && ::strcasestr(name, keyword))
+          match = true;
+        else {
+          const char *desc = property->GetDescription();
+          if (desc && ::strcasestr(desc, keyword))
+            match = true;
         }
-    }
-}
-
-Error
-OptionValueProperties::DumpPropertyValue (const ExecutionContext *exe_ctx,
-                                          Stream &strm,
-                                          const char *property_path,
-                                          uint32_t dump_mask)
-{
-    Error error;
-    const bool will_modify = false;
-    lldb::OptionValueSP value_sp (GetSubValue (exe_ctx, property_path, will_modify, error));
-    if (value_sp)
-    {
-        if (!value_sp->ValueIsTransparent ())
-        {
-            if (dump_mask & eDumpOptionName)
-                strm.PutCString (property_path);
-            if (dump_mask & ~eDumpOptionName)
-                strm.PutChar (' ');
+        if (match) {
+          matching_properties.push_back(property);
         }
-        value_sp->DumpValue (exe_ctx, strm, dump_mask);
+      }
     }
-    return error;
-}
-
-lldb::OptionValueSP
-OptionValueProperties::DeepCopy () const
-{
-    assert(!"this shouldn't happen");
-    return lldb::OptionValueSP();
-}
-
-const Property *
-OptionValueProperties::GetPropertyAtPath (const ExecutionContext *exe_ctx,
-                                          bool will_modify,
-                                          const char *name) const
-{
-    const Property *property = nullptr;
-    if (name && name[0])
-    {
-        const char *sub_name = nullptr;
-        ConstString key;
-        size_t key_len = ::strcspn (name, ".[{");
-        
-        if (name[key_len])
-        {
-            key.SetCStringWithLength (name, key_len);
-            sub_name = name + key_len;
-        }
-        else
-            key.SetCString (name);
-        
-        property = GetProperty (exe_ctx, will_modify, key);
-        if (sub_name && property)
-        {
-            if (sub_name[0] == '.')
-            {
-                OptionValueProperties *sub_properties = property->GetValue()->GetAsProperties();
-                if (sub_properties)
-                    return sub_properties->GetPropertyAtPath(exe_ctx, will_modify, sub_name + 1);
-            }
-            property = nullptr;
-        }
-    }
-    return property;
-}
-
-void
-OptionValueProperties::DumpAllDescriptions (CommandInterpreter &interpreter,
-                                            Stream &strm) const
-{
-    size_t max_name_len = 0;
-    const size_t num_properties = m_properties.size();
-    for (size_t i=0; i<num_properties; ++i)
-    {
-        const Property *property = ProtectedGetPropertyAtIndex(i);
-        if (property)
-            max_name_len = std::max<size_t>(property->GetName().GetLength(), max_name_len);
-    }
-    for (size_t i=0; i<num_properties; ++i)
-    {
-        const Property *property = ProtectedGetPropertyAtIndex(i);
-        if (property)
-            property->DumpDescription (interpreter, strm, max_name_len, false);
-    }
-}
-
-void
-OptionValueProperties::Apropos (const char *keyword, std::vector<const Property *> &matching_properties) const
-{
-    const size_t num_properties = m_properties.size();
-    StreamString strm;
-    for (size_t i=0; i<num_properties; ++i)
-    {
-        const Property *property = ProtectedGetPropertyAtIndex(i);
-        if (property)
-        {
-            const OptionValueProperties *properties = property->GetValue()->GetAsProperties();
-            if (properties)
-            {
-                properties->Apropos (keyword, matching_properties);
-            }
-            else
-            {
-                bool match = false;
-                const char *name = property->GetName().GetCString();
-                if (name && ::strcasestr(name, keyword))
-                    match = true;
-                else
-                {
-                    const char *desc = property->GetDescription();
-                    if (desc && ::strcasestr(desc, keyword))
-                        match = true;
-                }
-                if (match)
-                {
-                    matching_properties.push_back (property);
-                }
-            }
-        }
-    }
+  }
 }
 
 lldb::OptionValuePropertiesSP
-OptionValueProperties::GetSubProperty (const ExecutionContext *exe_ctx,
-                                       const ConstString &name)
-{
-    lldb::OptionValueSP option_value_sp(GetValueForKey(exe_ctx, name, false));
-    if (option_value_sp)
-    {
-        OptionValueProperties *ov_properties = option_value_sp->GetAsProperties ();
-        if (ov_properties)
-            return ov_properties->shared_from_this();
-    }
-    return lldb::OptionValuePropertiesSP();
+OptionValueProperties::GetSubProperty(const ExecutionContext *exe_ctx,
+                                      const ConstString &name) {
+  lldb::OptionValueSP option_value_sp(GetValueForKey(exe_ctx, name, false));
+  if (option_value_sp) {
+    OptionValueProperties *ov_properties = option_value_sp->GetAsProperties();
+    if (ov_properties)
+      return ov_properties->shared_from_this();
+  }
+  return lldb::OptionValuePropertiesSP();
 }
-
-
-
