Reimplemented the code that backed the "settings" in lldb. There were many issues with the previous implementation:
- no setting auto completion
- very manual and error prone way of getting/setting variables
- tons of code duplication
- useless instance names for processes, threads

Now settings can easily be defined like option values. The new settings makes use of the "OptionValue" classes so we can re-use the option value code that we use to set settings in command options. No more instances, just "does the right thing".



git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@162366 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/source/Interpreter/CommandInterpreter.cpp b/source/Interpreter/CommandInterpreter.cpp
index 979e21a..05384e4 100644
--- a/source/Interpreter/CommandInterpreter.cpp
+++ b/source/Interpreter/CommandInterpreter.cpp
@@ -84,17 +84,10 @@
     m_truncation_warning(eNoTruncation),
     m_command_source_depth (0)
 {
-    const char *dbg_name = debugger.GetInstanceName().AsCString();
-    std::string lang_name = ScriptInterpreter::LanguageToString (script_language);
-    StreamString var_name;
-    var_name.Printf ("[%s].script-lang", dbg_name);
-    debugger.GetSettingsController()->SetVariable (var_name.GetData(), lang_name.c_str(), 
-                                                   eVarSetOperationAssign, false, 
-                                                   m_debugger.GetInstanceName().AsCString());                                                   
+    debugger.SetScriptLanguage (script_language);
     SetEventName (eBroadcastBitThreadShouldExit, "thread-should-exit");
     SetEventName (eBroadcastBitResetPrompt, "reset-prompt");
-    SetEventName (eBroadcastBitQuitCommandReceived, "quit");
-    
+    SetEventName (eBroadcastBitQuitCommandReceived, "quit");    
     CheckInWithManager ();
 }
 
@@ -2505,6 +2498,7 @@
                 while (end > start
                        && text[end] != ' ' && text[end] != '\t' && text[end] != '\n')
                     end--;
+                assert (end > 0);
             }
 
             sub_len = end - start;
diff --git a/source/Interpreter/NamedOptionValue.cpp b/source/Interpreter/NamedOptionValue.cpp
deleted file mode 100644
index 33753b9..0000000
--- a/source/Interpreter/NamedOptionValue.cpp
+++ /dev/null
@@ -1,503 +0,0 @@
-//===-- NamedOptionValue.cpp ------------------------------------*- C++ -*-===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "lldb/Interpreter/NamedOptionValue.h"
-
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
-// Project includes
-#include "lldb/Core/FormatManager.h"
-#include "lldb/Core/State.h"
-#include "lldb/Core/Stream.h"
-#include "lldb/Interpreter/Args.h"
-
-using namespace lldb;
-using namespace lldb_private;
-
-
-//-------------------------------------------------------------------------
-// OptionValue
-//-------------------------------------------------------------------------
-
-// Get this value as a uint64_t value if it is encoded as a boolean,
-// uint64_t or int64_t. Other types will cause "fail_value" to be 
-// returned
-uint64_t
-OptionValue::GetUInt64Value (uint64_t fail_value, bool *success_ptr)
-{
-    if (success_ptr)
-        *success_ptr = true;
-    switch (GetType())
-    {
-    case OptionValue::eTypeBoolean: return static_cast<OptionValueBoolean *>(this)->GetCurrentValue();
-    case OptionValue::eTypeSInt64:  return static_cast<OptionValueSInt64 *>(this)->GetCurrentValue();
-    case OptionValue::eTypeUInt64:  return static_cast<OptionValueUInt64 *>(this)->GetCurrentValue();
-    default: 
-        break;
-    }
-    if (success_ptr)
-        *success_ptr = false;
-    return fail_value;
-}
-
-
-OptionValueBoolean *
-OptionValue::GetAsBoolean ()
-{
-    if (GetType () == OptionValue::eTypeBoolean)
-        return static_cast<OptionValueBoolean *>(this);
-    return NULL;
-}
-
-OptionValueSInt64 *
-OptionValue::GetAsSInt64 ()
-{
-    if (GetType () == OptionValue::eTypeSInt64)
-        return static_cast<OptionValueSInt64 *>(this);
-    return NULL;
-}
-
-OptionValueUInt64 *
-OptionValue::GetAsUInt64 ()
-{
-    if (GetType () == OptionValue::eTypeUInt64)
-        return static_cast<OptionValueUInt64 *>(this);
-    return NULL;
-}
-
-OptionValueString *
-OptionValue::GetAsString ()
-{
-    if (GetType () == OptionValue::eTypeString)
-        return static_cast<OptionValueString *>(this);
-    return NULL;
-}
-
-OptionValueFileSpec *
-OptionValue::GetAsFileSpec ()
-{
-    if (GetType () == OptionValue::eTypeFileSpec)
-        return static_cast<OptionValueFileSpec *>(this);
-    return NULL;
-
-}
-
-OptionValueFormat *
-OptionValue::GetAsFormat ()
-{
-    if (GetType () == OptionValue::eTypeFormat)
-        return static_cast<OptionValueFormat *>(this);
-    return NULL;
-}
-
-OptionValueUUID *
-OptionValue::GetAsUUID ()
-{
-    if (GetType () == OptionValue::eTypeUUID)
-        return static_cast<OptionValueUUID *>(this);
-    return NULL;
-    
-}
-
-
-OptionValueArray *
-OptionValue::GetAsArray ()
-{
-    if (GetType () == OptionValue::eTypeArray)
-        return static_cast<OptionValueArray *>(this);
-    return NULL;
-}
-
-OptionValueDictionary *
-OptionValue::GetAsDictionary ()
-{
-    if (GetType () == OptionValue::eTypeDictionary)
-        return static_cast<OptionValueDictionary *>(this);
-    return NULL;
-}
-
-const char *
-OptionValue::GetStringValue (const char *fail_value)
-{
-    OptionValueString *option_value = GetAsString ();
-    if (option_value)
-        return option_value->GetCurrentValue();
-    return fail_value;
-}
-
-uint64_t
-OptionValue::GetUInt64Value (uint64_t fail_value)
-{
-    OptionValueUInt64 *option_value = GetAsUInt64 ();
-    if (option_value)
-        return option_value->GetCurrentValue();
-    return fail_value;
-}
-
-lldb::Format
-OptionValue::GetFormatValue (lldb::Format fail_value)
-{
-    OptionValueFormat *option_value = GetAsFormat ();
-    if (option_value)
-        return option_value->GetCurrentValue();
-    return fail_value;
-}
-
-//-------------------------------------------------------------------------
-// OptionValueCollection
-//-------------------------------------------------------------------------
-
-void
-OptionValueCollection::GetQualifiedName (Stream &strm)
-{
-    if (m_parent)
-    {
-        m_parent->GetQualifiedName (strm);
-        strm.PutChar('.');
-    }
-    strm << m_name;
-}
-
-
-//-------------------------------------------------------------------------
-// OptionValueBoolean
-//-------------------------------------------------------------------------
-void
-OptionValueBoolean::DumpValue (Stream &strm)
-{
-    strm.PutCString (m_current_value ? "true" : "false");
-}
-
-Error
-OptionValueBoolean::SetValueFromCString (const char *value_cstr)
-{
-    Error error;
-    bool success = false;
-    bool value = Args::StringToBoolean(value_cstr, false, &success);
-    if (success)
-    {
-        m_value_was_set = true;
-        m_current_value = value;
-    }
-    else
-    {
-        if (value_cstr == NULL)
-            error.SetErrorString ("invalid boolean string value: NULL");
-        else if (value_cstr[0] == '\0')
-            error.SetErrorString ("invalid boolean string value <empty>");
-        else
-            error.SetErrorStringWithFormat ("invalid boolean string value: '%s'", value_cstr);
-    }
-    return error;
-}
-
-//-------------------------------------------------------------------------
-// OptionValueSInt64
-//-------------------------------------------------------------------------
-void
-OptionValueSInt64::DumpValue (Stream &strm)
-{
-    strm.Printf ("%lli", m_current_value);
-}
-
-Error
-OptionValueSInt64::SetValueFromCString (const char *value_cstr)
-{
- 
-    Error error;
-    bool success = false;
-    int64_t value = Args::StringToSInt64 (value_cstr, 0, 0, &success);
-    if (success)
-    {
-        m_value_was_set = true;
-        m_current_value = value;
-    }
-    else
-    {
-        error.SetErrorStringWithFormat ("invalid int64_t string value: '%s'", value_cstr);
-    }
-    return error;
-}
-
-//-------------------------------------------------------------------------
-// OptionValueUInt64
-//-------------------------------------------------------------------------
-
-lldb::OptionValueSP
-OptionValueUInt64::Create (const char *value_cstr, Error &error)
-{
-    lldb::OptionValueSP value_sp (new OptionValueUInt64());
-    error = value_sp->SetValueFromCString (value_cstr);
-    if (error.Fail())
-        value_sp.reset();
-    return value_sp;
-}
-
-
-void
-OptionValueUInt64::DumpValue (Stream &strm)
-{
-    strm.Printf ("0x%llx", m_current_value);
-}
-
-Error
-OptionValueUInt64::SetValueFromCString (const char *value_cstr)
-{
-    Error error;
-    bool success = false;
-    uint64_t value = Args::StringToUInt64 (value_cstr, 0, 0, &success);
-    if (success)
-    {
-        m_value_was_set = true;
-        m_current_value = value;
-    }
-    else
-    {
-        error.SetErrorStringWithFormat ("invalid uint64_t string value: '%s'", value_cstr);
-    }
-    return error;
-}
-
-//-------------------------------------------------------------------------
-// OptionValueDictionary
-//-------------------------------------------------------------------------
-void
-OptionValueString::DumpValue (Stream &strm)
-{
-    strm.Printf ("\"%s\"", m_current_value.c_str());
-}
-
-Error
-OptionValueString::SetValueFromCString (const char *value_cstr)
-{
-    m_value_was_set = true;
-    SetCurrentValue (value_cstr);
-    return Error ();
-}
-
-//-------------------------------------------------------------------------
-// OptionValueFileSpec
-//-------------------------------------------------------------------------
-void
-OptionValueFileSpec::DumpValue (Stream &strm)
-{
-    if (m_current_value)
-    {
-        if (m_current_value.GetDirectory())
-        {
-            strm << '"' << m_current_value.GetDirectory();
-            if (m_current_value.GetFilename())
-                strm << '/' << m_current_value.GetFilename();
-            strm << '"';
-        }
-        else
-        {
-            strm << '"' << m_current_value.GetFilename() << '"';
-        }
-    }
-}
-
-Error
-OptionValueFileSpec::SetValueFromCString (const char *value_cstr)
-{
-    if (value_cstr && value_cstr[0])
-        m_current_value.SetFile(value_cstr, false);
-    else
-        m_current_value.Clear();
-    m_value_was_set = true;
-    return Error();
-}
-
-//-------------------------------------------------------------------------
-// OptionValueFileSpecList
-//-------------------------------------------------------------------------
-void
-OptionValueFileSpecList::DumpValue (Stream &strm)
-{
-    m_current_value.Dump(&strm, "\n");
-}
-
-Error
-OptionValueFileSpecList::SetValueFromCString (const char *value_cstr)
-{
-    if (value_cstr && value_cstr[0])
-    {
-        FileSpec file (value_cstr, false);
-        m_current_value.Append(file);
-    }
-    m_value_was_set = true;
-    return Error();
-}
-
-
-//-------------------------------------------------------------------------
-// OptionValueUUID
-//-------------------------------------------------------------------------
-void
-OptionValueUUID::DumpValue (Stream &strm)
-{
-    m_uuid.Dump (&strm);
-}
-
-Error
-OptionValueUUID::SetValueFromCString (const char *value_cstr)
-{
-    Error error;
-    if (m_uuid.SetfromCString(value_cstr) == 0)
-        error.SetErrorStringWithFormat ("invalid uuid string value '%s'", value_cstr);
-    return error;
-}
-
-//-------------------------------------------------------------------------
-// OptionValueFormat
-//-------------------------------------------------------------------------
-void
-OptionValueFormat::DumpValue (Stream &strm)
-{
-    strm.PutCString (FormatManager::GetFormatAsCString (m_current_value));
-}
-
-Error
-OptionValueFormat::SetValueFromCString (const char *value_cstr)
-{
-    Format new_format;
-    Error error (Args::StringToFormat (value_cstr, new_format, NULL));
-    if (error.Success())
-    {
-        m_value_was_set = true;
-        m_current_value = new_format;
-    }
-    return error;
-}
-
-
-//-------------------------------------------------------------------------
-// OptionValueArray
-//-------------------------------------------------------------------------
-void
-OptionValueArray::DumpValue (Stream &strm)
-{
-    const uint32_t size = m_values.size();
-    for (uint32_t i = 0; i<size; ++i)
-    {
-        strm.Printf("[%u] ", i);
-        m_values[i]->DumpValue (strm);
-    }
-}
-
-Error
-OptionValueArray::SetValueFromCString (const char *value_cstr)
-{
-    Error error;
-    error.SetErrorStringWithFormat ("array option values don't yet support being set by string: '%s'", value_cstr);
-    return error;
-}
-
-//-------------------------------------------------------------------------
-// OptionValueDictionary
-//-------------------------------------------------------------------------
-void
-OptionValueDictionary::DumpValue (Stream &strm)
-{
-    collection::iterator pos, end = m_values.end();
-
-    for (pos = m_values.begin(); pos != end; ++pos)
-    {
-        strm.Printf("%s=", pos->first.GetCString());
-        pos->second->DumpValue (strm);
-    }
-}
-
-Error
-OptionValueDictionary::SetValueFromCString (const char *value_cstr)
-{
-    Error error;
-    error.SetErrorStringWithFormat ("dictionary option values don't yet support being set by string: '%s'", value_cstr);
-    return error;
-}
-
-lldb::OptionValueSP
-OptionValueDictionary::GetValueForKey (const ConstString &key) const
-{
-    lldb::OptionValueSP value_sp;
-    collection::const_iterator pos = m_values.find (key);
-    if (pos != m_values.end())
-        value_sp = pos->second;
-    return value_sp;
-}
-
-const char *
-OptionValueDictionary::GetStringValueForKey (const ConstString &key)
-{
-    collection::const_iterator pos = m_values.find (key);
-    if (pos != m_values.end())
-    {
-        if (pos->second->GetType() == OptionValue::eTypeString)
-            return static_cast<OptionValueString *>(pos->second.get())->GetCurrentValue();
-    }
-    return NULL;
-}
-
-
-bool
-OptionValueDictionary::SetStringValueForKey (const ConstString &key, 
-                                             const char *value, 
-                                             bool can_replace)
-{
-    collection::const_iterator pos = m_values.find (key);
-    if (pos != m_values.end())
-    {
-        if (!can_replace)
-            return false;
-        if (pos->second->GetType() == OptionValue::eTypeString)
-        {
-            pos->second->SetValueFromCString(value);
-            return true;
-        }
-    }
-    m_values[key] = OptionValueSP (new OptionValueString (value));
-    return true;
-
-}
-
-bool
-OptionValueDictionary::SetValueForKey (const ConstString &key, 
-                                       const lldb::OptionValueSP &value_sp, 
-                                       bool can_replace)
-{
-    // Make sure the value_sp object is allowed to contain
-    // values of the type passed in...
-    if (value_sp && (m_type_mask & value_sp->GetTypeAsMask()))
-    {
-        if (!can_replace)
-        {
-            collection::const_iterator pos = m_values.find (key);
-            if (pos != m_values.end())
-                return false;
-        }
-        m_values[key] = value_sp;
-        return true;
-    }
-    return false;
-}
-
-bool
-OptionValueDictionary::DeleteValueForKey (const ConstString &key)
-{
-    collection::iterator pos = m_values.find (key);
-    if (pos != m_values.end())
-    {
-        m_values.erase(pos);
-        return true;
-    }
-    return false;
-}
-
-
diff --git a/source/Interpreter/OptionGroupValueObjectDisplay.cpp b/source/Interpreter/OptionGroupValueObjectDisplay.cpp
index ced2c5c..bf58dd2 100644
--- a/source/Interpreter/OptionGroupValueObjectDisplay.cpp
+++ b/source/Interpreter/OptionGroupValueObjectDisplay.cpp
@@ -31,8 +31,7 @@
 static OptionDefinition
 g_option_table[] =
 {
-    { LLDB_OPT_SET_1, false, "dynamic-type",     'd', required_argument, TargetInstanceSettings::g_dynamic_value_types, 
-                                                                              0, eArgTypeNone,      "Show the object as its full dynamic type, not its static type, if available."},
+    { LLDB_OPT_SET_1, false, "dynamic-type",     'd', required_argument, g_dynamic_value_types, 0, eArgTypeNone,      "Show the object as its full dynamic type, not its static type, if available."},
     { LLDB_OPT_SET_1, false, "synthetic-type",   'S', required_argument, NULL, 0, eArgTypeBoolean,   "Show the object obeying its synthetic provider, if available."},
     { LLDB_OPT_SET_1, false, "depth",            'D', required_argument, NULL, 0, eArgTypeCount,     "Set the max recurse depth when dumping aggregate types (default is infinity)."},
     { LLDB_OPT_SET_1, false, "flat",             'F', no_argument,       NULL, 0, eArgTypeNone,      "Display results in a flat format that uses expression paths for each variable or member."},
@@ -73,7 +72,7 @@
         case 'd':
             {
                 int32_t result;
-                result = Args::StringToOptionEnum (option_arg, TargetInstanceSettings::g_dynamic_value_types, 2, error);
+                result = Args::StringToOptionEnum (option_arg, g_dynamic_value_types, 2, error);
                 if (error.Success())
                     use_dynamic = (lldb::DynamicValueType) result;
             }
diff --git a/source/Interpreter/OptionValue.cpp b/source/Interpreter/OptionValue.cpp
new file mode 100644
index 0000000..01ba65c
--- /dev/null
+++ b/source/Interpreter/OptionValue.cpp
@@ -0,0 +1,633 @@
+//===-- OptionValue.cpp -----------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/Interpreter/OptionValue.h"
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "lldb/Core/StringList.h"
+#include "lldb/Interpreter/OptionValues.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+
+//-------------------------------------------------------------------------
+// Get this value as a uint64_t value if it is encoded as a boolean,
+// uint64_t or int64_t. Other types will cause "fail_value" to be 
+// returned
+//-------------------------------------------------------------------------
+uint64_t
+OptionValue::GetUInt64Value (uint64_t fail_value, bool *success_ptr)
+{
+    if (success_ptr)
+        *success_ptr = true;
+    switch (GetType())
+    {
+    case OptionValue::eTypeBoolean: return static_cast<OptionValueBoolean *>(this)->GetCurrentValue();
+    case OptionValue::eTypeSInt64:  return static_cast<OptionValueSInt64 *>(this)->GetCurrentValue();
+    case OptionValue::eTypeUInt64:  return static_cast<OptionValueUInt64 *>(this)->GetCurrentValue();
+    default: 
+        break;
+    }
+    if (success_ptr)
+        *success_ptr = false;
+    return fail_value;
+}
+
+Error
+OptionValue::SetSubValue (const ExecutionContext *exe_ctx,
+                          VarSetOperationType op,
+                          const char *name,
+                          const char *value)
+{
+    Error error;
+    error.SetErrorStringWithFormat("SetSubValue is not supported");
+    return error;
+}
+
+
+OptionValueBoolean *
+OptionValue::GetAsBoolean ()
+{
+    if (GetType () == OptionValue::eTypeBoolean)
+        return static_cast<OptionValueBoolean *>(this);
+    return NULL;
+}
+
+const OptionValueBoolean *
+OptionValue::GetAsBoolean () const
+{
+    if (GetType () == OptionValue::eTypeBoolean)
+        return static_cast<const OptionValueBoolean *>(this);
+    return NULL;
+}
+
+
+OptionValueFileSpec *
+OptionValue::GetAsFileSpec ()
+{
+    if (GetType () == OptionValue::eTypeFileSpec)
+        return static_cast<OptionValueFileSpec *>(this);
+    return NULL;
+    
+}
+
+const OptionValueFileSpec *
+OptionValue::GetAsFileSpec () const
+{
+    if (GetType () == OptionValue::eTypeFileSpec)
+        return static_cast<const OptionValueFileSpec *>(this);
+    return NULL;
+    
+}
+
+OptionValueFileSpecList *
+OptionValue::GetAsFileSpecList ()
+{
+    if (GetType () == OptionValue::eTypeFileSpecList)
+        return static_cast<OptionValueFileSpecList *>(this);
+    return NULL;
+    
+}
+
+const OptionValueFileSpecList *
+OptionValue::GetAsFileSpecList () const
+{
+    if (GetType () == OptionValue::eTypeFileSpecList)
+        return static_cast<const OptionValueFileSpecList *>(this);
+    return NULL;
+    
+}
+
+OptionValueArch *
+OptionValue::GetAsArch ()
+{
+    if (GetType () == OptionValue::eTypeArch)
+        return static_cast<OptionValueArch *>(this);
+    return NULL;
+}
+
+
+const OptionValueArch *
+OptionValue::GetAsArch () const
+{
+    if (GetType () == OptionValue::eTypeArch)
+        return static_cast<const OptionValueArch *>(this);
+    return NULL;
+}
+
+OptionValueArray *
+OptionValue::GetAsArray ()
+{
+    if (GetType () == OptionValue::eTypeArray)
+        return static_cast<OptionValueArray *>(this);
+    return NULL;
+}
+
+
+const OptionValueArray *
+OptionValue::GetAsArray () const
+{
+    if (GetType () == OptionValue::eTypeArray)
+        return static_cast<const OptionValueArray *>(this);
+    return NULL;
+}
+
+OptionValueArgs *
+OptionValue::GetAsArgs ()
+{
+    if (GetType () == OptionValue::eTypeArgs)
+        return static_cast<OptionValueArgs *>(this);
+    return NULL;
+}
+
+
+const OptionValueArgs *
+OptionValue::GetAsArgs () const
+{
+    if (GetType () == OptionValue::eTypeArgs)
+        return static_cast<const OptionValueArgs *>(this);
+    return NULL;
+}
+
+OptionValueDictionary *
+OptionValue::GetAsDictionary ()
+{
+    if (GetType () == OptionValue::eTypeDictionary)
+        return static_cast<OptionValueDictionary *>(this);
+    return NULL;
+}
+
+const OptionValueDictionary *
+OptionValue::GetAsDictionary () const
+{
+    if (GetType () == OptionValue::eTypeDictionary)
+        return static_cast<const OptionValueDictionary *>(this);
+    return NULL;
+}
+
+OptionValueEnumeration *
+OptionValue::GetAsEnumeration ()
+{
+    if (GetType () == OptionValue::eTypeEnum)
+        return static_cast<OptionValueEnumeration *>(this);
+    return NULL;
+}
+
+const OptionValueEnumeration *
+OptionValue::GetAsEnumeration () const
+{
+    if (GetType () == OptionValue::eTypeEnum)
+        return static_cast<const OptionValueEnumeration *>(this);
+    return NULL;
+}
+
+OptionValueFormat *
+OptionValue::GetAsFormat ()
+{
+    if (GetType () == OptionValue::eTypeFormat)
+        return static_cast<OptionValueFormat *>(this);
+    return NULL;
+}
+
+const OptionValueFormat *
+OptionValue::GetAsFormat () const
+{
+    if (GetType () == OptionValue::eTypeFormat)
+        return static_cast<const OptionValueFormat *>(this);
+    return NULL;
+}
+
+OptionValuePathMappings *
+OptionValue::GetAsPathMappings ()
+{
+    if (GetType () == OptionValue::eTypePathMap)
+        return static_cast<OptionValuePathMappings *>(this);
+    return NULL;
+}
+
+const OptionValuePathMappings *
+OptionValue::GetAsPathMappings () const
+{
+    if (GetType () == OptionValue::eTypePathMap)
+        return static_cast<const OptionValuePathMappings *>(this);
+    return NULL;
+}
+
+OptionValueProperties *
+OptionValue::GetAsProperties ()
+{
+    if (GetType () == OptionValue::eTypeProperties)
+        return static_cast<OptionValueProperties *>(this);
+    return NULL;
+}
+
+const OptionValueProperties *
+OptionValue::GetAsProperties () const
+{
+    if (GetType () == OptionValue::eTypeProperties)
+        return static_cast<const OptionValueProperties *>(this);
+    return NULL;
+}
+
+OptionValueRegex *
+OptionValue::GetAsRegex ()
+{
+    if (GetType () == OptionValue::eTypeRegex)
+        return static_cast<OptionValueRegex *>(this);
+    return NULL;
+}
+
+const OptionValueRegex *
+OptionValue::GetAsRegex () const
+{
+    if (GetType () == OptionValue::eTypeRegex)
+        return static_cast<const OptionValueRegex *>(this);
+    return NULL;
+}
+
+OptionValueSInt64 *
+OptionValue::GetAsSInt64 ()
+{
+    if (GetType () == OptionValue::eTypeSInt64)
+        return static_cast<OptionValueSInt64 *>(this);
+    return NULL;
+}
+
+const OptionValueSInt64 *
+OptionValue::GetAsSInt64 () const
+{
+    if (GetType () == OptionValue::eTypeSInt64)
+        return static_cast<const OptionValueSInt64 *>(this);
+    return NULL;
+}
+
+OptionValueString *
+OptionValue::GetAsString ()
+{
+    if (GetType () == OptionValue::eTypeString)
+        return static_cast<OptionValueString *>(this);
+    return NULL;
+}
+
+const OptionValueString *
+OptionValue::GetAsString () const
+{
+    if (GetType () == OptionValue::eTypeString)
+        return static_cast<const OptionValueString *>(this);
+    return NULL;
+}
+
+OptionValueUInt64 *
+OptionValue::GetAsUInt64 ()
+{
+    if (GetType () == OptionValue::eTypeUInt64)
+        return static_cast<OptionValueUInt64 *>(this);
+    return NULL;
+}
+
+const OptionValueUInt64 *
+OptionValue::GetAsUInt64 () const
+{
+    if (GetType () == OptionValue::eTypeUInt64)
+        return static_cast<const OptionValueUInt64 *>(this);
+    return NULL;
+}
+
+OptionValueUUID *
+OptionValue::GetAsUUID ()
+{
+    if (GetType () == OptionValue::eTypeUUID)
+        return static_cast<OptionValueUUID *>(this);
+    return NULL;
+    
+}
+
+const OptionValueUUID *
+OptionValue::GetAsUUID () const
+{
+    if (GetType () == OptionValue::eTypeUUID)
+        return static_cast<const OptionValueUUID *>(this);
+    return NULL;
+    
+}
+
+bool
+OptionValue::GetBooleanValue (bool fail_value) const
+{
+    const OptionValueBoolean *option_value = GetAsBoolean ();
+    if (option_value)
+        return option_value->GetCurrentValue();
+    return fail_value;
+}
+
+bool
+OptionValue::SetBooleanValue (bool new_value)
+{
+    OptionValueBoolean *option_value = GetAsBoolean ();
+    if (option_value)
+    {
+        option_value->SetCurrentValue(new_value);
+        return true;
+    }
+    return false;
+}
+
+int64_t
+OptionValue::GetEnumerationValue (int64_t fail_value) const
+{
+    const OptionValueEnumeration *option_value = GetAsEnumeration();
+    if (option_value)
+        option_value->GetCurrentValue();
+    return fail_value;
+}
+
+bool
+OptionValue::SetEnumerationValue (int64_t value)
+{
+    OptionValueEnumeration *option_value = GetAsEnumeration();
+    if (option_value)
+    {
+        option_value->SetCurrentValue(value);
+        return true;
+    }
+    return false;
+}
+
+FileSpec
+OptionValue::GetFileSpecValue () const
+{
+    const OptionValueFileSpec *option_value = GetAsFileSpec ();
+    if (option_value)
+        return option_value->GetCurrentValue();
+    return FileSpec();
+}
+
+
+bool
+OptionValue::SetFileSpecValue (const FileSpec &file_spec)
+{
+    OptionValueFileSpec *option_value = GetAsFileSpec ();
+    if (option_value)
+    {
+        option_value->SetCurrentValue(file_spec);
+        return true;
+    }
+    return false;
+}
+
+FileSpecList
+OptionValue::GetFileSpecListValue () const
+{
+    const OptionValueFileSpecList *option_value = GetAsFileSpecList ();
+    if (option_value)
+        return option_value->GetCurrentValue();
+    return FileSpecList();
+}
+
+
+lldb::Format
+OptionValue::GetFormatValue (lldb::Format fail_value) const
+{
+    const OptionValueFormat *option_value = GetAsFormat ();
+    if (option_value)
+        return option_value->GetCurrentValue();
+    return fail_value;
+}
+
+bool
+OptionValue::SetFormatValue (lldb::Format new_value)
+{
+    OptionValueFormat *option_value = GetAsFormat ();
+    if (option_value)
+    {
+        option_value->SetCurrentValue(new_value);
+        return true;
+    }
+    return false;
+}
+
+const RegularExpression *
+OptionValue::GetRegexValue () const
+{
+    const OptionValueRegex *option_value = GetAsRegex ();
+    if (option_value)
+        return option_value->GetCurrentValue();
+    return NULL;
+}
+
+
+int64_t
+OptionValue::GetSInt64Value (int64_t fail_value) const
+{
+    const OptionValueSInt64 *option_value = GetAsSInt64 ();
+    if (option_value)
+        return option_value->GetCurrentValue();
+    return fail_value;
+}
+
+bool
+OptionValue::SetSInt64Value (int64_t new_value)
+{
+    OptionValueSInt64 *option_value = GetAsSInt64 ();
+    if (option_value)
+    {
+        option_value->SetCurrentValue(new_value);
+        return true;
+    }
+    return false;
+}
+
+const char *
+OptionValue::GetStringValue (const char *fail_value) const
+{
+    const OptionValueString *option_value = GetAsString ();
+    if (option_value)
+        return option_value->GetCurrentValue();
+    return fail_value;
+}
+
+bool
+OptionValue::SetStringValue (const char *new_value)
+{
+    OptionValueString *option_value = GetAsString ();
+    if (option_value)
+    {
+        option_value->SetCurrentValue(new_value);
+        return true;
+    }
+    return false;
+}
+
+uint64_t
+OptionValue::GetUInt64Value (uint64_t fail_value) const
+{
+    const OptionValueUInt64 *option_value = GetAsUInt64 ();
+    if (option_value)
+        return option_value->GetCurrentValue();
+    return fail_value;
+}
+
+bool
+OptionValue::SetUInt64Value (uint64_t new_value)
+{
+    OptionValueUInt64 *option_value = GetAsUInt64 ();
+    if (option_value)
+    {
+        option_value->SetCurrentValue(new_value);
+        return true;
+    }
+    return false;
+}
+
+UUID
+OptionValue::GetUUIDValue () const
+{
+    const OptionValueUUID *option_value = GetAsUUID();
+    if (option_value)
+        return option_value->GetCurrentValue();
+    return UUID();
+}
+
+bool
+OptionValue::SetUUIDValue (const UUID &uuid)
+{
+    OptionValueUUID *option_value = GetAsUUID();
+    if (option_value)
+    {
+        option_value->SetCurrentValue(uuid);
+        return true;
+    }
+    return false;
+}
+
+const char *
+OptionValue::GetBuiltinTypeAsCString (Type t)
+{
+    switch (t)
+    {
+        case eTypeInvalid:      return "invalid";
+        case eTypeArch:         return "arch";
+        case eTypeArgs:         return "arguments";
+        case eTypeArray:        return "array";
+        case eTypeBoolean:      return "boolean";
+        case eTypeDictionary:   return "dictionary";
+        case eTypeEnum:         return "enum";
+        case eTypeFileSpec:     return "file";
+        case eTypeFileSpecList: return "file-list";
+        case eTypeFormat:       return "format";
+        case eTypePathMap:      return "path-map";
+        case eTypeProperties:   return "properties";
+        case eTypeRegex:        return "regex";
+        case eTypeSInt64:       return "int";
+        case eTypeString:       return "string";
+        case eTypeUInt64:       return "unsigned";
+        case eTypeUUID:         return "uuid";
+    }
+    return NULL;
+}
+
+
+lldb::OptionValueSP
+OptionValue::CreateValueFromCStringForTypeMask (const char *value_cstr, uint32_t type_mask, Error &error)
+{
+    // If only 1 bit is set in the type mask for a dictionary or array
+    // then we know how to decode a value from a cstring
+    lldb::OptionValueSP value_sp;
+    switch (type_mask)
+    {
+    case 1u << eTypeArch:       value_sp.reset(new OptionValueArch()); break;
+    case 1u << eTypeBoolean:    value_sp.reset(new OptionValueBoolean(false)); break;
+    case 1u << eTypeFileSpec:   value_sp.reset(new OptionValueFileSpec()); break;
+    case 1u << eTypeFormat:     value_sp.reset(new OptionValueFormat(eFormatInvalid));    break;
+    case 1u << eTypeSInt64:     value_sp.reset(new OptionValueSInt64()); break;
+    case 1u << eTypeString:     value_sp.reset(new OptionValueString()); break;
+    case 1u << eTypeUInt64:     value_sp.reset(new OptionValueUInt64()); break;
+    case 1u << eTypeUUID:       value_sp.reset(new OptionValueUUID()); break;
+    }
+
+    if (value_sp)
+        error = value_sp->SetValueFromCString (value_cstr, eVarSetOperationAssign);
+    else
+        error.SetErrorString("unsupported type mask");
+    return value_sp;
+}
+
+bool
+OptionValue::DumpQualifiedName (Stream &strm) const
+{
+    bool dumped_something = false;
+    lldb::OptionValueSP m_parent_sp(m_parent_wp.lock());
+    if (m_parent_sp)
+    {
+        if (m_parent_sp->DumpQualifiedName(strm))
+            dumped_something = true;
+    }
+    ConstString name (GetName());
+    if (name)
+    {
+        if (dumped_something)
+            strm.PutChar('.');
+        else
+            dumped_something = true;
+        strm << name;
+    }
+    return dumped_something;
+}
+
+size_t
+OptionValue::AutoComplete (CommandInterpreter &interpreter,
+                           const char *s,
+                           int match_start_point,
+                           int max_return_elements,
+                           bool &word_complete,
+                           StringList &matches)
+{
+    word_complete = false;
+    matches.Clear();
+    return matches.GetSize();
+}
+
+Error
+OptionValue::SetValueFromCString (const char *value, VarSetOperationType op)
+{
+    Error error;
+    switch (op)
+    {
+    case eVarSetOperationReplace:
+        error.SetErrorStringWithFormat ("%s objects do not support the 'replace' operation", GetTypeAsCString());
+        break;
+    case eVarSetOperationInsertBefore:
+        error.SetErrorStringWithFormat ("%s objects do not support the 'insert-before' operation", GetTypeAsCString());
+        break;
+    case eVarSetOperationInsertAfter:
+        error.SetErrorStringWithFormat ("%s objects do not support the 'insert-after' operation", GetTypeAsCString());
+        break;
+    case eVarSetOperationRemove:
+        error.SetErrorStringWithFormat ("%s objects do not support the 'remove' operation", GetTypeAsCString());
+        break;
+    case eVarSetOperationAppend:
+        error.SetErrorStringWithFormat ("%s objects do not support the 'append' operation", GetTypeAsCString());
+        break;
+    case eVarSetOperationClear:
+        error.SetErrorStringWithFormat ("%s objects do not support the 'clear' operation", GetTypeAsCString());
+        break;
+    case eVarSetOperationAssign:
+        error.SetErrorStringWithFormat ("%s objects do not support the 'assign' operation", GetTypeAsCString());
+        break;
+    case eVarSetOperationInvalid:
+        error.SetErrorStringWithFormat ("invalid operation performed on a %s object", GetTypeAsCString());
+        break;
+    }
+    return error;
+}
+
diff --git a/source/Interpreter/OptionValueArch.cpp b/source/Interpreter/OptionValueArch.cpp
new file mode 100644
index 0000000..90ae775
--- /dev/null
+++ b/source/Interpreter/OptionValueArch.cpp
@@ -0,0 +1,109 @@
+//===-- OptionValueArch.cpp ---------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/Interpreter/OptionValueArch.h"
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "lldb/Core/FormatManager.h"
+#include "lldb/Core/State.h"
+#include "lldb/Interpreter/Args.h"
+#include "lldb/Interpreter/CommandCompletions.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+void
+OptionValueArch::DumpValue (const ExecutionContext *exe_ctx, Stream &strm, uint32_t dump_mask)
+{
+    if (dump_mask & eDumpOptionType)
+        strm.Printf ("(%s)", GetTypeAsCString ());
+    if (dump_mask & eDumpOptionValue)
+    {
+        if (dump_mask & eDumpOptionType)
+            strm.PutCString (" = ");
+
+        if (m_current_value.IsValid())
+        {
+            const char *arch_name = m_current_value.GetArchitectureName();
+            if (arch_name)
+                strm.PutCString (arch_name);
+        }
+    }
+}
+
+Error
+OptionValueArch::SetValueFromCString (const char *value_cstr, VarSetOperationType op)
+{
+    Error error;
+    switch (op)
+    {
+    case eVarSetOperationClear:
+        Clear();
+        break;
+        
+    case eVarSetOperationReplace:
+    case eVarSetOperationAssign:
+        if (value_cstr && value_cstr[0])
+        {
+            if (m_current_value.SetTriple (value_cstr))
+                m_value_was_set = true;
+            else
+                error.SetErrorStringWithFormat("unsupported architecture '%s'", value_cstr);
+        }
+        else
+        {
+            error.SetErrorString("invalid value string");
+        }
+        break;
+        
+    case eVarSetOperationInsertBefore:
+    case eVarSetOperationInsertAfter:
+    case eVarSetOperationRemove:
+    case eVarSetOperationAppend:
+    case eVarSetOperationInvalid:
+        error = OptionValue::SetValueFromCString (value_cstr, op);
+        break;
+    }
+    return error;
+}
+
+lldb::OptionValueSP
+OptionValueArch::DeepCopy () const
+{
+    return OptionValueSP(new OptionValueArch(*this));
+}
+
+
+size_t
+OptionValueArch::AutoComplete (CommandInterpreter &interpreter,
+                                   const char *s,
+                                   int match_start_point,
+                                   int max_return_elements,
+                                   bool &word_complete,
+                                   StringList &matches)
+{
+    word_complete = false;
+    matches.Clear();
+    CommandCompletions::InvokeCommonCompletionCallbacks (interpreter,
+                                                         CommandCompletions::eArchitectureCompletion,
+                                                         s,
+                                                         match_start_point,
+                                                         max_return_elements,
+                                                         NULL,
+                                                         word_complete,
+                                                         matches);
+    return matches.GetSize();
+}
+
+
+
+
diff --git a/source/Interpreter/OptionValueArgs.cpp b/source/Interpreter/OptionValueArgs.cpp
new file mode 100644
index 0000000..e28d884
--- /dev/null
+++ b/source/Interpreter/OptionValueArgs.cpp
@@ -0,0 +1,38 @@
+//===-- OptionValueArgs.cpp -------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/Interpreter/OptionValueArgs.h"
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "lldb/Interpreter/Args.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+size_t
+OptionValueArgs::GetArgs (Args &args)
+{
+    const uint32_t size = m_values.size();
+    std::vector<const char *> argv;
+    for (uint32_t i = 0; i<size; ++i)
+    {
+        const char *string_value = m_values[i]->GetStringValue ();
+        if (string_value)
+            argv.push_back(string_value);
+    }
+
+    if (argv.empty())
+        args.Clear();
+    else
+        args.SetArguments(argv.size(), &argv[0]);
+    return args.GetArgumentCount();
+}
diff --git a/source/Interpreter/OptionValueArray.cpp b/source/Interpreter/OptionValueArray.cpp
new file mode 100644
index 0000000..fbddd7b
--- /dev/null
+++ b/source/Interpreter/OptionValueArray.cpp
@@ -0,0 +1,350 @@
+//===-- OptionValueArray.cpp ------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/Interpreter/OptionValueArray.h"
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "lldb/Core/Stream.h"
+#include "lldb/Interpreter/Args.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+void
+OptionValueArray::DumpValue (const ExecutionContext *exe_ctx, Stream &strm, uint32_t dump_mask)
+{
+    const Type array_element_type = ConvertTypeMaskToType (m_type_mask);
+    if (dump_mask & eDumpOptionType)
+    {
+        if ((GetType() == eTypeArray) && (m_type_mask != eTypeInvalid))
+            strm.Printf ("(%s of %ss)", GetTypeAsCString(), GetBuiltinTypeAsCString(array_element_type));
+        else
+            strm.Printf ("(%s)", GetTypeAsCString());
+    }
+    if (dump_mask & eDumpOptionValue)
+    {
+        if (dump_mask & eDumpOptionType)
+            strm.Printf (" =%s", (m_values.size() > 0) ? "\n" : "");
+        strm.IndentMore();
+        const uint32_t size = m_values.size();
+        for (uint32_t i = 0; i<size; ++i)
+        {
+            strm.Indent();
+            strm.Printf("[%u]: ", i);
+            const uint32_t extra_dump_options = m_raw_value_dump ? eDumpOptionRaw : 0;
+            switch (array_element_type)
+            {
+                default:
+                case eTypeArray:
+                case eTypeDictionary:
+                case eTypeProperties:
+                case eTypeFileSpecList:
+                case eTypePathMap:
+                    m_values[i]->DumpValue(exe_ctx, strm, dump_mask | extra_dump_options);
+                    break;
+                    
+                case eTypeBoolean:
+                case eTypeEnum:
+                case eTypeFileSpec:
+                case eTypeFormat:
+                case eTypeSInt64:
+                case eTypeString:
+                case eTypeUInt64:
+                case eTypeUUID:
+                    // No need to show the type for dictionaries of simple items
+                    m_values[i]->DumpValue(exe_ctx, strm, (dump_mask & (~eDumpOptionType)) | extra_dump_options);
+                    break;
+            }
+            if (i < (size - 1))
+                strm.EOL();
+        }
+        strm.IndentLess();
+    }
+}
+
+Error
+OptionValueArray::SetValueFromCString (const char *value, VarSetOperationType op)
+{
+    Args args(value);
+    return SetArgs (args, op);
+}
+
+
+lldb::OptionValueSP
+OptionValueArray::GetSubValue (const ExecutionContext *exe_ctx,
+                               const char *name,
+                               bool will_modify,
+                               Error &error) const
+{
+    if (name && name[0] == '[')
+    {
+        const char *end_bracket = strchr (name+1, ']');
+        if (end_bracket)
+        {
+            const char *sub_value = NULL;
+            if (end_bracket[1])
+                sub_value = end_bracket + 1;
+            std::string index_str (name+1, end_bracket);
+            const size_t array_count = m_values.size();
+            int32_t idx = Args::StringToSInt32(index_str.c_str(), INT32_MAX, 0, NULL);
+            if (idx != INT32_MAX)
+            {
+                ;
+                uint32_t new_idx = UINT32_MAX;
+                if (idx < 0)
+                {
+                    // Access from the end of the array if the index is negative
+                    new_idx = array_count - idx;
+                }
+                else
+                {
+                    // Just a standard index
+                    new_idx = idx;
+                }
+
+                if (new_idx < array_count)
+                {
+                    if (m_values[new_idx])
+                    {
+                        if (sub_value)
+                            return m_values[new_idx]->GetSubValue (exe_ctx, sub_value, will_modify, error);
+                        else
+                            return m_values[new_idx];
+                    }
+                }
+                else
+                {
+                    if (array_count == 0)
+                        error.SetErrorStringWithFormat("index %i is not valid for an empty array", idx);
+                    else if (idx > 0)
+                        error.SetErrorStringWithFormat("index %i out of range, valid values are 0 through %zu", idx, array_count - 1);
+                    else
+                        error.SetErrorStringWithFormat("negative index %i out of range, valid values are -1 through -%zu", idx, array_count);
+                }
+            }
+        }
+    }
+    else
+    {
+        error.SetErrorStringWithFormat("invalid value path '%s', %s values only support '[<index>]' subvalues where <index> is a positive or negative array index", name, GetTypeAsCString());
+    }
+    return OptionValueSP();
+}
+
+
+size_t
+OptionValueArray::GetArgs (Args &args) const
+{
+    const uint32_t size = m_values.size();
+    std::vector<const char *> argv;
+    for (uint32_t i = 0; i<size; ++i)
+    {
+        const char *string_value = m_values[i]->GetStringValue ();
+        if (string_value)
+            argv.push_back(string_value);
+    }
+    
+    if (argv.empty())
+        args.Clear();
+    else
+        args.SetArguments(argv.size(), &argv[0]);
+    return args.GetArgumentCount();
+}
+
+Error
+OptionValueArray::SetArgs (const Args &args, VarSetOperationType op)
+{
+    Error error;
+    const size_t argc = args.GetArgumentCount();
+    switch (op)
+    {
+    case eVarSetOperationInvalid:
+        error.SetErrorString("unsupported operation");
+        break;
+        
+    case eVarSetOperationInsertBefore:
+    case eVarSetOperationInsertAfter:
+        if (argc > 1)
+        {
+            uint32_t idx = Args::StringToUInt32(args.GetArgumentAtIndex(0), UINT32_MAX);
+            const uint32_t count = GetSize();
+            if (idx > count)
+            {
+                error.SetErrorStringWithFormat("invalid insert array index %u, index must be 0 through %u", idx, count);
+            }
+            else
+            {
+                if (op == eVarSetOperationInsertAfter)
+                    ++idx;
+                for (size_t i=1; i<argc; ++i, ++idx)
+                {
+                    lldb::OptionValueSP value_sp (CreateValueFromCStringForTypeMask (args.GetArgumentAtIndex(i),
+                                                                                     m_type_mask,
+                                                                                     error));
+                    if (value_sp)
+                    {
+                        if (error.Fail())
+                            return error;
+                        if (idx >= m_values.size())
+                            m_values.push_back(value_sp);
+                        else
+                            m_values.insert(m_values.begin() + idx, value_sp);
+                    }
+                    else
+                    {
+                        error.SetErrorString("array of complex types must subclass OptionValueArray");
+                        return error;
+                    }
+                }
+            }
+        }
+        else
+        {
+            error.SetErrorString("insert operation takes an array index followed by one or more values");
+        }
+        break;
+        
+    case eVarSetOperationRemove:
+        if (argc > 0)
+        {
+            const uint32_t size = m_values.size();
+            std::vector<int> remove_indexes;
+            bool all_indexes_valid = true;
+            size_t i;
+            for (i=0; i<argc; ++i)
+            {
+                const int idx = Args::StringToSInt32(args.GetArgumentAtIndex(i), INT32_MAX);
+                if (idx >= size)
+                {
+                    all_indexes_valid = false;
+                    break;
+                }
+                else
+                    remove_indexes.push_back(idx);
+            }
+            
+            if (all_indexes_valid)
+            {
+                size_t num_remove_indexes = remove_indexes.size();
+                if (num_remove_indexes)
+                {
+                    // Sort and then erase in reverse so indexes are always valid
+                    if (num_remove_indexes > 1)
+                    {
+                        std::sort(remove_indexes.begin(), remove_indexes.end());
+                        for (std::vector<int>::const_reverse_iterator pos = remove_indexes.rbegin(), end = remove_indexes.rend(); pos != end; ++pos)
+                        {
+                            m_values.erase(m_values.begin() + *pos);
+                        }
+                    }
+                    else
+                    {
+                        // Only one index
+                        m_values.erase(m_values.begin() + remove_indexes.front());
+                    }
+                }
+            }
+            else
+            {
+                error.SetErrorStringWithFormat("invalid array index '%s', aborting remove operation", args.GetArgumentAtIndex(i));
+            }
+        }
+        else
+        {
+            error.SetErrorString("remove operation takes one or more array indices");
+        }
+        break;
+        
+    case eVarSetOperationClear:
+        Clear ();
+        break;
+        
+    case eVarSetOperationReplace:
+        if (argc > 1)
+        {
+            uint32_t idx = Args::StringToUInt32(args.GetArgumentAtIndex(0), UINT32_MAX);
+            const uint32_t count = GetSize();
+            if (idx > count)
+            {
+                error.SetErrorStringWithFormat("invalid replace array index %u, index must be 0 through %u", idx, count);
+            }
+            else
+            {
+                for (size_t i=1; i<argc; ++i, ++idx)
+                {
+                    lldb::OptionValueSP value_sp (CreateValueFromCStringForTypeMask (args.GetArgumentAtIndex(i),
+                                                                                     m_type_mask,
+                                                                                     error));
+                    if (value_sp)
+                    {
+                        if (error.Fail())
+                            return error;
+                        if (idx < count)
+                            m_values[idx] = value_sp;
+                        else
+                            m_values.push_back(value_sp);
+                    }
+                    else
+                    {
+                        error.SetErrorString("array of complex types must subclass OptionValueArray");
+                        return error;
+                    }
+                }
+            }
+        }
+        else
+        {
+            error.SetErrorString("replace operation takes an array index followed by one or more values");
+        }
+        break;
+        
+    case eVarSetOperationAssign:
+        m_values.clear();
+        // Fall through to append case
+    case eVarSetOperationAppend:
+        for (size_t i=0; i<argc; ++i)
+        {
+            lldb::OptionValueSP value_sp (CreateValueFromCStringForTypeMask (args.GetArgumentAtIndex(i),
+                                                                             m_type_mask,
+                                                                             error));
+            if (value_sp)
+            {
+                if (error.Fail())
+                    return error;
+                m_value_was_set = true;
+                AppendValue(value_sp);
+            }
+            else
+            {
+                error.SetErrorString("array of complex types must subclass OptionValueArray");
+            }
+        }
+        break;
+    }
+    return error;
+}
+
+lldb::OptionValueSP
+OptionValueArray::DeepCopy () const
+{
+    OptionValueArray *copied_array = new OptionValueArray (m_type_mask, m_raw_value_dump);
+    lldb::OptionValueSP copied_value_sp(copied_array);
+    const uint32_t size = m_values.size();
+    for (uint32_t i = 0; i<size; ++i)
+    {
+        copied_array->AppendValue (m_values[i]->DeepCopy());
+    }
+    return copied_value_sp;
+}
+
+
+
diff --git a/source/Interpreter/OptionValueBoolean.cpp b/source/Interpreter/OptionValueBoolean.cpp
new file mode 100644
index 0000000..4e6fd62
--- /dev/null
+++ b/source/Interpreter/OptionValueBoolean.cpp
@@ -0,0 +1,87 @@
+//===-- OptionValueBoolean.cpp ------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/Interpreter/OptionValueBoolean.h"
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "lldb/Core/Stream.h"
+#include "lldb/Interpreter/Args.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+void
+OptionValueBoolean::DumpValue (const ExecutionContext *exe_ctx, Stream &strm, uint32_t dump_mask)
+{
+    if (dump_mask & eDumpOptionType)
+        strm.Printf ("(%s)", GetTypeAsCString ());
+//    if (dump_mask & eDumpOptionName)
+//        DumpQualifiedName (strm);
+    if (dump_mask & eDumpOptionValue)
+    {
+        if (dump_mask & eDumpOptionType)
+            strm.PutCString (" = ");
+        strm.PutCString (m_current_value ? "true" : "false");
+    }
+}
+
+Error
+OptionValueBoolean::SetValueFromCString (const char *value_cstr,
+                                         VarSetOperationType op)
+{
+    Error error;
+    switch (op)
+    {
+    case eVarSetOperationClear:
+        Clear();
+        break;
+
+    case eVarSetOperationReplace:
+    case eVarSetOperationAssign:
+        {
+            bool success = false;
+            bool value = Args::StringToBoolean(value_cstr, false, &success);
+            if (success)
+            {
+                m_value_was_set = true;
+                m_current_value = value;
+            }
+            else
+            {
+                if (value_cstr == NULL)
+                    error.SetErrorString ("invalid boolean string value: NULL");
+                else if (value_cstr[0] == '\0')
+                    error.SetErrorString ("invalid boolean string value <empty>");
+                else
+                    error.SetErrorStringWithFormat ("invalid boolean string value: '%s'", value_cstr);
+            }
+        }
+        break;
+
+    case eVarSetOperationInsertBefore:
+    case eVarSetOperationInsertAfter:
+    case eVarSetOperationRemove:
+    case eVarSetOperationAppend:
+    case eVarSetOperationInvalid:
+        error = OptionValue::SetValueFromCString (value_cstr, op);
+        break;
+    }
+    return error;
+}
+
+lldb::OptionValueSP
+OptionValueBoolean::DeepCopy () const
+{
+    return OptionValueSP(new OptionValueBoolean(*this));
+}
+
+
diff --git a/source/Interpreter/OptionValueDictionary.cpp b/source/Interpreter/OptionValueDictionary.cpp
new file mode 100644
index 0000000..e291f7f
--- /dev/null
+++ b/source/Interpreter/OptionValueDictionary.cpp
@@ -0,0 +1,434 @@
+//===-- OptionValueDictionary.cpp -------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/Interpreter/OptionValueDictionary.h"
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+#include "llvm/ADT/StringRef.h"
+// Project includes
+#include "lldb/Core/FormatManager.h"
+#include "lldb/Core/State.h"
+#include "lldb/Interpreter/Args.h"
+#include "lldb/Interpreter/OptionValueString.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+void
+OptionValueDictionary::DumpValue (const ExecutionContext *exe_ctx, Stream &strm, uint32_t dump_mask)
+{
+    const Type dict_type = ConvertTypeMaskToType (m_type_mask);
+    if (dump_mask & eDumpOptionType)
+    {
+        if (m_type_mask != eTypeInvalid)
+            strm.Printf ("(%s of %ss)", GetTypeAsCString(), GetBuiltinTypeAsCString(dict_type));
+        else
+            strm.Printf ("(%s)", GetTypeAsCString());
+    }
+    if (dump_mask & eDumpOptionValue)
+    {
+        if (dump_mask & eDumpOptionType)
+            strm.PutCString (" =");
+
+        collection::iterator pos, end = m_values.end();
+
+        strm.IndentMore();
+        
+        for (pos = m_values.begin(); pos != end; ++pos)
+        {
+            OptionValue *option_value = pos->second.get();
+            strm.EOL();
+            strm.Indent(pos->first.GetCString());
+            
+            const uint32_t extra_dump_options = m_raw_value_dump ? eDumpOptionRaw : 0;
+            switch (dict_type)
+            {
+                default:
+                case eTypeArray:
+                case eTypeDictionary:
+                case eTypeProperties:
+                case eTypeFileSpecList:
+                case eTypePathMap:
+                    strm.PutChar (' ');
+                    option_value->DumpValue(exe_ctx, strm, dump_mask | extra_dump_options);
+                    break;
+
+                case eTypeBoolean:
+                case eTypeEnum:
+                case eTypeFileSpec:
+                case eTypeFormat:
+                case eTypeSInt64:
+                case eTypeString:
+                case eTypeUInt64:
+                case eTypeUUID:
+                    // No need to show the type for dictionaries of simple items
+                    strm.PutCString("=");
+                    option_value->DumpValue(exe_ctx, strm, (dump_mask & (~eDumpOptionType)) | extra_dump_options);
+                    break;
+            }
+        }
+        strm.IndentLess();
+    }
+
+}
+
+size_t
+OptionValueDictionary::GetArgs (Args &args) const
+{
+    args.Clear();
+    collection::const_iterator pos, end = m_values.end();
+    for (pos = m_values.begin(); pos != end; ++pos)
+    {
+        StreamString strm;
+        strm.Printf("%s=", pos->first.GetCString());
+        pos->second->DumpValue(NULL, strm, eDumpOptionValue|eDumpOptionRaw);
+        args.AppendArgument(strm.GetString().c_str());
+    }
+    return args.GetArgumentCount();
+}
+
+Error
+OptionValueDictionary::SetArgs (const Args &args, VarSetOperationType op)
+{
+    Error error;
+    const size_t argc = args.GetArgumentCount();
+    switch (op)
+    {
+    case eVarSetOperationClear:
+        Clear();
+        break;
+        
+    case eVarSetOperationAppend:
+    case eVarSetOperationReplace:
+    case eVarSetOperationAssign:
+        if (argc > 0)
+        {
+            for (size_t i=0; i<argc; ++i)
+            {
+                llvm::StringRef key_and_value(args.GetArgumentAtIndex(i));
+                if (!key_and_value.empty())
+                {
+                    std::pair<llvm::StringRef, llvm::StringRef> kvp(key_and_value.split('='));
+                    llvm::StringRef key = kvp.first;
+                    bool key_valid = false;
+                    if (!key.empty())
+                    {
+                        if (key.front() == '[')
+                        {
+                            // Key name starts with '[', so the the key value must be in single or double quotes like:
+                            // ['<key>']
+                            // ["<key>"]
+                            if ((key.size() > 2) && (key.back() == ']'))
+                            {
+                                // Strip leading '[' and trailing ']'
+                                key = key.substr(1, key.size()-2);
+                                const char quote_char = key.front();
+                                if ((quote_char == '\'') || (quote_char == '"'))
+                                {
+                                    if ((key.size() > 2) && (key.back() == quote_char))
+                                    {
+                                        // Strip the quotes
+                                        key = key.substr(1, key.size()-2);
+                                        key_valid = true;
+                                    }
+                                }
+                                else
+                                {
+                                    // square brackets, no quotes
+                                    key_valid = true;
+                                }
+                            }
+                        }
+                        else
+                        {
+                            // No square brackets or quotes
+                            key_valid = true;
+                        }
+                    }
+                    if (!key_valid)
+                    {
+                        error.SetErrorStringWithFormat("invalid key \"%s\", the key must be a bare string or surrounded by brackets with optional quotes: [<key>] or ['<key>'] or [\"<key>\"]", kvp.first.str().c_str());
+                        return error;
+                    }
+
+                    lldb::OptionValueSP value_sp (CreateValueFromCStringForTypeMask (kvp.second.data(),
+                                                                                     m_type_mask,
+                                                                                     error));
+                    if (value_sp)
+                    {
+                        if (error.Fail())
+                            return error;
+                        m_value_was_set = true;
+                        SetValueForKey (ConstString(key), value_sp, true);
+                    }
+                    else
+                    {
+                        error.SetErrorString("dictionaries that can contain multiple types must subclass OptionValueArray");
+                    }
+                }
+                else
+                {
+                    error.SetErrorString("empty argument");
+                }
+            }
+        }
+        else
+        {
+            error.SetErrorString("assign operation takes one or more key=value arguments");
+        }
+        break;
+        
+    case eVarSetOperationRemove:
+        if (argc > 0)
+        {
+            for (size_t i=0; i<argc; ++i)
+            {
+                ConstString key(args.GetArgumentAtIndex(i));
+                if (!DeleteValueForKey(key))
+                {
+                    error.SetErrorStringWithFormat("no value found named '%s', aborting remove operation", key.GetCString());
+                    break;
+                }
+            }
+        }
+        else
+        {
+            error.SetErrorString("remove operation takes one or more key arguments");
+        }
+        break;
+        
+    case eVarSetOperationInsertBefore:
+    case eVarSetOperationInsertAfter:
+    case eVarSetOperationInvalid:
+        error = OptionValue::SetValueFromCString (NULL, op);
+        break;
+    }
+    return error;
+}
+
+Error
+OptionValueDictionary::SetValueFromCString (const char *value_cstr, VarSetOperationType op)
+{
+    Args args(value_cstr);
+    return SetArgs (args, op);
+}
+
+lldb::OptionValueSP
+OptionValueDictionary::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 = NULL;
+        ConstString key;
+        const char *open_bracket = ::strchr (name, '[');
+
+        if (open_bracket)
+        {
+            const char *key_start = open_bracket + 1;
+            const char *key_end = NULL;
+            switch (open_bracket[1])
+            {
+                case '\'':
+                    ++key_start;
+                    key_end = strchr(key_start, '\'');
+                    if (key_end)
+                    {
+                        if (key_end[1] == ']')
+                        {
+                            if (key_end[2])
+                                sub_name = key_end + 2;
+                        }
+                        else
+                        {
+                            error.SetErrorStringWithFormat ("invalid value path '%s', single quoted key names must be formatted as ['<key>'] where <key> is a string that doesn't contain quotes", name);
+                            return value_sp;
+                        }
+                    }
+                    else
+                    {
+                        error.SetErrorString ("missing '] key name terminator, key name started with ['");
+                        return value_sp;
+                    }
+                    break;
+                case '"':
+                    ++key_start;
+                    key_end = strchr(key_start, '"');
+                    if (key_end)
+                    {
+                        if (key_end[1] == ']')
+                        {
+                            if (key_end[2])
+                                sub_name = key_end + 2;
+                            break;
+                        }
+                        error.SetErrorStringWithFormat ("invalid value path '%s', double quoted key names must be formatted as [\"<key>\"] where <key> is a string that doesn't contain quotes", name);
+                        return value_sp;
+                    }
+                    else
+                    {
+                        error.SetErrorString ("missing \"] key name terminator, key name started with [\"");
+                        return value_sp;
+                    }
+                    break;
+
+                default:
+                    key_end = strchr(key_start, ']');
+                    if (key_end)
+                    {
+                        if (key_end[1])
+                            sub_name = key_end + 1;
+                    }
+                    else
+                    {
+                        error.SetErrorString ("missing ] key name terminator, key name started with [");
+                        return value_sp;
+                    }
+                    break;
+            }
+            
+            if (key_start && key_end)
+            {
+                key.SetCStringWithLength (key_start, key_end - key_start);
+        
+                value_sp = GetValueForKey (key);
+                if (value_sp)
+                {
+                    if (sub_name)
+                        return value_sp->GetSubValue (exe_ctx, sub_name, will_modify, error);
+                }
+                else
+                {
+                    error.SetErrorStringWithFormat("dictionary does not contain a value for the key name '%s'", key.GetCString());
+                }
+            }
+        }
+        if (!value_sp && error.AsCString() == NULL)
+        {
+            error.SetErrorStringWithFormat ("invalid value path '%s', %s values only support '[<key>]' subvalues where <key> a string value optionally delimitted by single or double quotes",
+                                            name,
+                                            GetTypeAsCString());
+        }
+    }
+    return value_sp;
+}
+
+Error
+OptionValueDictionary::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->SetValueFromCString(value, op);
+    else
+    {
+        if (error.AsCString() == NULL)
+            error.SetErrorStringWithFormat("invalid value path '%s'", name);
+    }
+    return error;
+}
+
+
+lldb::OptionValueSP
+OptionValueDictionary::GetValueForKey (const ConstString &key) const
+{
+    lldb::OptionValueSP value_sp;
+    collection::const_iterator pos = m_values.find (key);
+    if (pos != m_values.end())
+        value_sp = pos->second;
+    return value_sp;
+}
+
+const char *
+OptionValueDictionary::GetStringValueForKey (const ConstString &key)
+{
+    collection::const_iterator pos = m_values.find (key);
+    if (pos != m_values.end())
+    {
+        OptionValueString *string_value = pos->second->GetAsString();
+        if (string_value)
+            return string_value->GetCurrentValue();
+    }
+    return NULL;
+}
+
+
+bool
+OptionValueDictionary::SetStringValueForKey (const ConstString &key, 
+                                             const char *value, 
+                                             bool can_replace)
+{
+    collection::const_iterator pos = m_values.find (key);
+    if (pos != m_values.end())
+    {
+        if (!can_replace)
+            return false;
+        if (pos->second->GetType() == OptionValue::eTypeString)
+        {
+            pos->second->SetValueFromCString(value);
+            return true;
+        }
+    }
+    m_values[key] = OptionValueSP (new OptionValueString (value));
+    return true;
+
+}
+
+bool
+OptionValueDictionary::SetValueForKey (const ConstString &key, 
+                                       const lldb::OptionValueSP &value_sp, 
+                                       bool can_replace)
+{
+    // Make sure the value_sp object is allowed to contain
+    // values of the type passed in...
+    if (value_sp && (m_type_mask & value_sp->GetTypeAsMask()))
+    {
+        if (!can_replace)
+        {
+            collection::const_iterator pos = m_values.find (key);
+            if (pos != m_values.end())
+                return false;
+        }
+        m_values[key] = value_sp;
+        return true;
+    }
+    return false;
+}
+
+bool
+OptionValueDictionary::DeleteValueForKey (const ConstString &key)
+{
+    collection::iterator pos = m_values.find (key);
+    if (pos != m_values.end())
+    {
+        m_values.erase(pos);
+        return true;
+    }
+    return false;
+}
+
+lldb::OptionValueSP
+OptionValueDictionary::DeepCopy () const
+{
+    OptionValueDictionary *copied_dict = new OptionValueDictionary (m_type_mask, m_raw_value_dump);
+    lldb::OptionValueSP copied_value_sp(copied_dict);
+    collection::const_iterator pos, end = m_values.end();
+    for (pos = m_values.begin(); pos != end; ++pos)
+    {
+        StreamString strm;
+        strm.Printf("%s=", pos->first.GetCString());
+        copied_dict->SetValueForKey (pos->first, pos->second->DeepCopy(), true);
+    }
+    return copied_value_sp;
+}
+
diff --git a/source/Interpreter/OptionValueEnumeration.cpp b/source/Interpreter/OptionValueEnumeration.cpp
new file mode 100644
index 0000000..61b184f
--- /dev/null
+++ b/source/Interpreter/OptionValueEnumeration.cpp
@@ -0,0 +1,131 @@
+//===-- OptionValueEnumeration.cpp ------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/Interpreter/OptionValueEnumeration.h"
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+
+using namespace lldb;
+using namespace lldb_private;
+
+OptionValueEnumeration::OptionValueEnumeration (const OptionEnumValueElement *enumerators,
+                                                enum_type value) :
+    OptionValue(),
+    m_current_value (value),
+    m_default_value (value),
+    m_enumerations ()
+{
+    SetEnumerations(enumerators);
+}
+
+OptionValueEnumeration::~OptionValueEnumeration()
+{
+}
+
+void
+OptionValueEnumeration::DumpValue (const ExecutionContext *exe_ctx, Stream &strm, uint32_t dump_mask)
+{
+    if (dump_mask & eDumpOptionType)
+        strm.Printf ("(%s)", GetTypeAsCString ());
+    if (dump_mask & eDumpOptionValue)
+    {
+        if (dump_mask & eDumpOptionType)
+            strm.PutCString (" = ");
+        const size_t count = m_enumerations.GetSize ();
+        for (size_t i=0; i<count; ++i)
+        {
+            if (m_enumerations.GetValueAtIndexUnchecked(i).value == m_current_value)
+            {
+                strm.PutCString(m_enumerations.GetCStringAtIndex(i));
+                return;
+            }
+        }
+        strm.Printf("%llu", (uint64_t)m_current_value);
+    }
+}
+
+Error
+OptionValueEnumeration::SetValueFromCString (const char *value, VarSetOperationType op)
+{
+    Error error;
+    switch (op)
+    {
+        case eVarSetOperationClear:
+            Clear ();
+            break;
+            
+        case eVarSetOperationReplace:
+        case eVarSetOperationAssign:
+            if (value && value[0])
+            {
+                ConstString const_enumerator_name(value);
+                const EnumerationMapEntry *enumerator_entry = m_enumerations.FindFirstValueForName (const_enumerator_name.GetCString());
+                if (enumerator_entry)
+                {
+                    m_current_value = enumerator_entry->value.value;
+                }
+                else
+                {
+                    StreamString error_strm;
+                    error_strm.Printf("invalid enumeration value '%s'", value);
+                    const size_t count = m_enumerations.GetSize ();
+                    if (count)
+                    {
+                        error_strm.Printf(", valid values are: %s", m_enumerations.GetCStringAtIndex(0));
+                        for (size_t i=1; i<count; ++i)
+                        {
+                            error_strm.Printf (", %s", m_enumerations.GetCStringAtIndex(i));
+                        }
+                    }
+                    error.SetErrorString(error_strm.GetData());
+                }
+            }
+            else
+            {
+                error.SetErrorString("invalid enumeration value");
+            }
+            break;
+            
+        case eVarSetOperationInsertBefore:
+        case eVarSetOperationInsertAfter:
+        case eVarSetOperationRemove:
+        case eVarSetOperationAppend:
+        case eVarSetOperationInvalid:
+            error = OptionValue::SetValueFromCString (value, op);
+            break;
+    }
+    return error;
+}
+
+void
+OptionValueEnumeration::SetEnumerations (const OptionEnumValueElement *enumerators)
+{
+    m_enumerations.Clear();
+    if (enumerators)
+    {
+        for (size_t i=0; enumerators[i].string_value != NULL; ++i)
+        {
+            ConstString const_enumerator_name(enumerators[i].string_value);
+            EnumeratorInfo enumerator_info = { enumerators[i].value, enumerators[i].usage };
+            m_enumerations.Append (const_enumerator_name.GetCString(), enumerator_info);
+        }
+        m_enumerations.Sort();
+    }
+}
+
+
+lldb::OptionValueSP
+OptionValueEnumeration::DeepCopy () const
+{
+    return OptionValueSP(new OptionValueEnumeration(*this));
+}
+
diff --git a/source/Interpreter/OptionValueFileSpec.cpp b/source/Interpreter/OptionValueFileSpec.cpp
new file mode 100644
index 0000000..20b0b04
--- /dev/null
+++ b/source/Interpreter/OptionValueFileSpec.cpp
@@ -0,0 +1,116 @@
+//===-- OptionValueFileSpec.cpp ---------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/Interpreter/OptionValueFileSpec.h"
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "lldb/Core/FormatManager.h"
+#include "lldb/Core/State.h"
+#include "lldb/Interpreter/Args.h"
+#include "lldb/Interpreter/CommandCompletions.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+void
+OptionValueFileSpec::DumpValue (const ExecutionContext *exe_ctx, Stream &strm, uint32_t dump_mask)
+{
+    if (dump_mask & eDumpOptionType)
+        strm.Printf ("(%s)", GetTypeAsCString ());
+    if (dump_mask & eDumpOptionValue)
+    {
+        if (dump_mask & eDumpOptionType)
+            strm.PutCString (" = ");
+
+        if (m_current_value)
+        {
+            if (m_current_value.GetDirectory())
+            {
+                strm << '"' << m_current_value.GetDirectory();
+                if (m_current_value.GetFilename())
+                    strm << '/' << m_current_value.GetFilename();
+                strm << '"';
+            }
+            else
+            {
+                strm << '"' << m_current_value.GetFilename() << '"';
+            }
+        }
+    }
+}
+
+Error
+OptionValueFileSpec::SetValueFromCString (const char *value_cstr,
+                                          VarSetOperationType op)
+{
+    Error error;
+    switch (op)
+    {
+    case eVarSetOperationClear:
+        Clear ();
+        break;
+        
+    case eVarSetOperationReplace:
+    case eVarSetOperationAssign:
+        if (value_cstr && value_cstr[0])
+        {
+            m_value_was_set = true;
+            m_current_value.SetFile(value_cstr, false);
+        }
+        else
+        {
+            error.SetErrorString("invalid value string");
+        }
+        break;
+        
+    case eVarSetOperationInsertBefore:
+    case eVarSetOperationInsertAfter:
+    case eVarSetOperationRemove:
+    case eVarSetOperationAppend:
+    case eVarSetOperationInvalid:
+        error = OptionValue::SetValueFromCString (value_cstr, op);
+        break;
+    }
+    return error;
+}
+
+lldb::OptionValueSP
+OptionValueFileSpec::DeepCopy () const
+{
+    return OptionValueSP(new OptionValueFileSpec(*this));
+}
+
+
+size_t
+OptionValueFileSpec::AutoComplete (CommandInterpreter &interpreter,
+                                   const char *s,
+                                   int match_start_point,
+                                   int max_return_elements,
+                                   bool &word_complete,
+                                   StringList &matches)
+{
+    word_complete = false;
+    matches.Clear();
+    CommandCompletions::InvokeCommonCompletionCallbacks (interpreter,
+                                                         CommandCompletions::eDiskFileCompletion,
+                                                         s,
+                                                         match_start_point,
+                                                         max_return_elements,
+                                                         NULL,
+                                                         word_complete,
+                                                         matches);
+    return matches.GetSize();
+}
+
+
+
+
diff --git a/source/Interpreter/OptionValueFileSpecLIst.cpp b/source/Interpreter/OptionValueFileSpecLIst.cpp
new file mode 100644
index 0000000..3328dc6
--- /dev/null
+++ b/source/Interpreter/OptionValueFileSpecLIst.cpp
@@ -0,0 +1,186 @@
+//===-- OptionValueFileSpecList.cpp -----------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/Interpreter/OptionValueFileSpecList.h"
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "lldb/Core/Stream.h"
+#include "lldb/Interpreter/Args.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+void
+OptionValueFileSpecList::DumpValue (const ExecutionContext *exe_ctx, Stream &strm, uint32_t dump_mask)
+{
+    if (dump_mask & eDumpOptionType)
+        strm.Printf ("(%s)", GetTypeAsCString ());
+    if (dump_mask & eDumpOptionValue)
+    {
+        if (dump_mask & eDumpOptionType)
+            strm.Printf (" =%s", m_current_value.GetSize() > 0 ? "\n" : "");
+        strm.IndentMore();
+        const uint32_t size = m_current_value.GetSize();
+        for (uint32_t i = 0; i<size; ++i)
+        {
+            strm.Indent();
+            strm.Printf("[%u]: ", i);
+            m_current_value.GetFileSpecAtIndex(i).Dump(&strm);
+        }
+        strm.IndentLess();
+    }
+}
+
+Error
+OptionValueFileSpecList::SetValueFromCString (const char *value, VarSetOperationType op)
+{
+    Error error;
+    Args args(value);
+    const size_t argc = args.GetArgumentCount();
+
+    switch (op)
+    {
+        case eVarSetOperationClear:
+            Clear ();
+            break;
+            
+        case eVarSetOperationReplace:
+            if (argc > 1)
+            {
+                uint32_t idx = Args::StringToUInt32(args.GetArgumentAtIndex(0), UINT32_MAX);
+                const uint32_t count = m_current_value.GetSize();
+                if (idx > count)
+                {
+                    error.SetErrorStringWithFormat("invalid file list index %u, index must be 0 through %u", idx, count);
+                }
+                else
+                {
+                    for (size_t i=1; i<argc; ++i, ++idx)
+                    {
+                        FileSpec file (args.GetArgumentAtIndex(i), false);
+                        if (idx < count)
+                            m_current_value.Replace(idx, file);
+                        else
+                            m_current_value.Append(file);
+                    }
+                }
+            }
+            else
+            {
+                error.SetErrorString("replace operation takes an array index followed by one or more values");
+            }
+            break;
+            
+            
+            
+        case eVarSetOperationAssign:
+            m_current_value.Clear();
+            // Fall through to append case
+        case eVarSetOperationAppend:
+            if (argc > 0)
+            {
+                m_value_was_set = true;
+                for (size_t i=0; i<argc; ++i)
+                {
+                    FileSpec file (args.GetArgumentAtIndex(i), false);
+                    m_current_value.Append(file);
+                }
+            }
+            else
+            {
+                error.SetErrorString("assign operation takes at least one file path argument");
+            }
+            break;
+            
+        case eVarSetOperationInsertBefore:
+        case eVarSetOperationInsertAfter:
+            if (argc > 1)
+            {
+                uint32_t idx = Args::StringToUInt32(args.GetArgumentAtIndex(0), UINT32_MAX);
+                const uint32_t count = m_current_value.GetSize();
+                if (idx > count)
+                {
+                    error.SetErrorStringWithFormat("invalid insert file list index %u, index must be 0 through %u", idx, count);
+                }
+                else
+                {
+                    if (op == eVarSetOperationInsertAfter)
+                        ++idx;
+                    for (size_t i=1; i<argc; ++i, ++idx)
+                    {
+                        FileSpec file (args.GetArgumentAtIndex(i), false);
+                        m_current_value.Insert (idx, file);
+                    }
+                }
+            }
+            else
+            {
+                error.SetErrorString("insert operation takes an array index followed by one or more values");
+            }
+            break;
+            
+        case eVarSetOperationRemove:
+            if (argc > 0)
+            {
+                std::vector<int> remove_indexes;
+                bool all_indexes_valid = true;
+                size_t i;
+                for (i=0; all_indexes_valid && i<argc; ++i)
+                {
+                    const int idx = Args::StringToSInt32(args.GetArgumentAtIndex(i), INT32_MAX);
+                    if (idx == INT32_MAX)
+                        all_indexes_valid = false;
+                    else
+                        remove_indexes.push_back(idx);
+                }
+                
+                if (all_indexes_valid)
+                {
+                    size_t num_remove_indexes = remove_indexes.size();
+                    if (num_remove_indexes)
+                    {
+                        // Sort and then erase in reverse so indexes are always valid
+                        std::sort(remove_indexes.begin(), remove_indexes.end());
+                        for (int i=num_remove_indexes-1; i<num_remove_indexes; ++i)
+                        {
+                            m_current_value.Remove (i);
+                        }
+                    }
+                }
+                else
+                {
+                    error.SetErrorStringWithFormat("invalid array index '%s', aborting remove operation", args.GetArgumentAtIndex(i));
+                }
+            }
+            else
+            {
+                error.SetErrorString("remove operation takes one or more array index");
+            }
+            break;
+
+        case eVarSetOperationInvalid:
+            error = OptionValue::SetValueFromCString (value, op);
+            break;
+    }
+    return error;
+
+    m_value_was_set = true;
+    return Error();
+}
+
+lldb::OptionValueSP
+OptionValueFileSpecList::DeepCopy () const
+{
+    return OptionValueSP(new OptionValueFileSpecList(*this));
+}
+
+
diff --git a/source/Interpreter/OptionValueFormat.cpp b/source/Interpreter/OptionValueFormat.cpp
new file mode 100644
index 0000000..7d09fb1
--- /dev/null
+++ b/source/Interpreter/OptionValueFormat.cpp
@@ -0,0 +1,76 @@
+//===-- OptionValueFormat.cpp -----------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/Interpreter/OptionValueFormat.h"
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "lldb/Core/FormatManager.h"
+#include "lldb/Core/Stream.h"
+#include "lldb/Interpreter/Args.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+void
+OptionValueFormat::DumpValue (const ExecutionContext *exe_ctx, Stream &strm, uint32_t dump_mask)
+{
+    if (dump_mask & eDumpOptionType)
+        strm.Printf ("(%s)", GetTypeAsCString ());
+    if (dump_mask & eDumpOptionValue)
+    {
+        if (dump_mask & eDumpOptionType)
+            strm.PutCString (" = ");
+        strm.PutCString (FormatManager::GetFormatAsCString (m_current_value));
+    }
+}
+
+Error
+OptionValueFormat::SetValueFromCString (const char *value_cstr, VarSetOperationType op)
+{
+    Error error;
+    switch (op)
+    {
+    case eVarSetOperationClear:
+        Clear();
+        break;
+        
+    case eVarSetOperationReplace:
+    case eVarSetOperationAssign:
+        {
+            Format new_format;
+            error = Args::StringToFormat (value_cstr, new_format, NULL);
+            if (error.Success())
+            {
+                m_value_was_set = true;
+                m_current_value = new_format;
+            }
+        }
+        break;
+        
+    case eVarSetOperationInsertBefore:
+    case eVarSetOperationInsertAfter:
+    case eVarSetOperationRemove:
+    case eVarSetOperationAppend:
+    case eVarSetOperationInvalid:
+        error = OptionValue::SetValueFromCString (value_cstr, op);
+        break;
+    }
+    return error;
+}
+
+
+lldb::OptionValueSP
+OptionValueFormat::DeepCopy () const
+{
+    return OptionValueSP(new OptionValueFormat(*this));
+}
+
diff --git a/source/Interpreter/OptionValuePathMappings.cpp b/source/Interpreter/OptionValuePathMappings.cpp
new file mode 100644
index 0000000..d507b14
--- /dev/null
+++ b/source/Interpreter/OptionValuePathMappings.cpp
@@ -0,0 +1,185 @@
+//===-- OptionValuePathMappings.cpp -----------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/Interpreter/OptionValuePathMappings.h"
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "lldb/Core/Stream.h"
+#include "lldb/Interpreter/Args.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+void
+OptionValuePathMappings::DumpValue (const ExecutionContext *exe_ctx, Stream &strm, uint32_t dump_mask)
+{
+    if (dump_mask & eDumpOptionType)
+        strm.Printf ("(%s)", GetTypeAsCString ());
+    if (dump_mask & eDumpOptionValue)
+    {
+        if (dump_mask & eDumpOptionType)
+            strm.Printf (" =%s", (m_path_mappings.GetSize() > 0) ? "\n" : "");
+        m_path_mappings.Dump(&strm);
+    }
+}
+
+Error
+OptionValuePathMappings::SetValueFromCString (const char *value, VarSetOperationType op)
+{
+    Error error;
+    Args args(value);
+    const size_t argc = args.GetArgumentCount();
+
+    switch (op)
+    {
+        case eVarSetOperationClear:
+            Clear ();
+            break;
+            
+        case eVarSetOperationReplace:
+            // Must be at least one index + 1 pair of paths, and the pair count must be even
+            if (argc >= 3 && (((argc - 1) & 1) == 0))
+            {
+                uint32_t idx = Args::StringToUInt32(args.GetArgumentAtIndex(0), UINT32_MAX);
+                const uint32_t count = m_path_mappings.GetSize();
+                if (idx > count)
+                {
+                    error.SetErrorStringWithFormat("invalid file list index %u, index must be 0 through %u", idx, count);
+                }
+                else
+                {
+                    for (size_t i=1; i<argc; i += 2, ++idx)
+                    {
+                        ConstString a(args.GetArgumentAtIndex(i));
+                        ConstString b(args.GetArgumentAtIndex(i+1));
+                        if (!m_path_mappings.Replace (a, b, idx, m_notify_changes))
+                            m_path_mappings.Append(a, b, m_notify_changes);
+                    }
+                }
+            }
+            else
+            {
+                error.SetErrorString("replace operation takes an array index followed by one or more path pairs");
+            }
+            break;
+            
+            
+            
+        case eVarSetOperationAssign:
+            if (argc < 2 || (argc & 1))
+            {
+                error.SetErrorString("assign operation takes one or more path pairs");
+                break;
+            }
+            m_path_mappings.Clear(m_notify_changes);
+            // Fall through to append case
+        case eVarSetOperationAppend:
+            if (argc < 2 || (argc & 1))
+            {
+                error.SetErrorString("append operation takes one or more path pairs");
+                break;
+            }
+            else
+            {
+                for (size_t i=0; i<argc; i += 2)
+                {
+                    ConstString a(args.GetArgumentAtIndex(i));
+                    ConstString b(args.GetArgumentAtIndex(i+1));
+                    m_path_mappings.Append(a, b, m_notify_changes);
+                    m_value_was_set = true;
+                }
+            }
+            break;
+            
+        case eVarSetOperationInsertBefore:
+        case eVarSetOperationInsertAfter:
+            // Must be at least one index + 1 pair of paths, and the pair count must be even
+            if (argc >= 3 && (((argc - 1) & 1) == 0))
+            {
+                uint32_t idx = Args::StringToUInt32(args.GetArgumentAtIndex(0), UINT32_MAX);
+                const uint32_t count = m_path_mappings.GetSize();
+                if (idx > count)
+                {
+                    error.SetErrorStringWithFormat("invalid file list index %u, index must be 0 through %u", idx, count);
+                }
+                else
+                {
+                    if (op == eVarSetOperationInsertAfter)
+                        ++idx;
+                    for (size_t i=1; i<argc; i += 2, ++idx)
+                    {
+                        ConstString a(args.GetArgumentAtIndex(i));
+                        ConstString b(args.GetArgumentAtIndex(i+1));
+                        m_path_mappings.Insert (a, b, idx, m_notify_changes);
+                    }
+                }
+            }
+            else
+            {
+                error.SetErrorString("insert operation takes an array index followed by one or more path pairs");
+            }
+            break;
+            
+        case eVarSetOperationRemove:
+            if (argc > 0)
+            {
+                std::vector<int> remove_indexes;
+                bool all_indexes_valid = true;
+                size_t i;
+                for (i=0; all_indexes_valid && i<argc; ++i)
+                {
+                    const int idx = Args::StringToSInt32(args.GetArgumentAtIndex(i), INT32_MAX);
+                    if (idx == INT32_MAX)
+                        all_indexes_valid = false;
+                    else
+                        remove_indexes.push_back(idx);
+                }
+                
+                if (all_indexes_valid)
+                {
+                    size_t num_remove_indexes = remove_indexes.size();
+                    if (num_remove_indexes)
+                    {
+                        // Sort and then erase in reverse so indexes are always valid
+                        std::sort(remove_indexes.begin(), remove_indexes.end());
+                        for (int i=num_remove_indexes-1; i<num_remove_indexes; ++i)
+                        {
+                            m_path_mappings.Remove (i, m_notify_changes);
+                        }
+                    }
+                }
+                else
+                {
+                    error.SetErrorStringWithFormat("invalid array index '%s', aborting remove operation", args.GetArgumentAtIndex(i));
+                }
+            }
+            else
+            {
+                error.SetErrorString("remove operation takes one or more array index");
+            }
+            break;
+
+        case eVarSetOperationInvalid:
+            error = OptionValue::SetValueFromCString (value, op);
+            break;
+    }
+    return error;
+
+    m_value_was_set = true;
+    return Error();
+}
+
+lldb::OptionValueSP
+OptionValuePathMappings::DeepCopy () const
+{
+    return OptionValueSP(new OptionValuePathMappings(*this));
+}
diff --git a/source/Interpreter/OptionValueProperties.cpp b/source/Interpreter/OptionValueProperties.cpp
new file mode 100644
index 0000000..ce31c15
--- /dev/null
+++ b/source/Interpreter/OptionValueProperties.cpp
@@ -0,0 +1,719 @@
+//===-- OptionValueProperties.cpp ---------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/Interpreter/OptionValueProperties.h"
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "lldb/Core/Flags.h"
+#include "lldb/Core/Stream.h"
+#include "lldb/Core/StringList.h"
+#include "lldb/Core/UserSettingsController.h"
+#include "lldb/Interpreter/Args.h"
+#include "lldb/Interpreter/OptionValues.h"
+#include "lldb/Interpreter/Property.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+
+OptionValueProperties::OptionValueProperties (const ConstString &name) :
+    m_name (name)
+{
+}
+
+OptionValueProperties::OptionValueProperties (const OptionValueProperties &global_properties) :
+    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 contructing 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();
+}
+
+
+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::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 dumped_something = false;
+////    lldb::OptionValuePropertiesSP parent_sp(GetParent ());
+////    if (parent_sp)
+////    {
+////        parent_sp->GetQualifiedName (strm);
+////        strm.PutChar('.');
+////        dumped_something = true;
+////    }
+//    if (m_name)
+//    {
+//        strm << m_name;
+//        dumped_something = true;
+//    }
+//    return dumped_something;
+//}
+//
+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;
+}
+
+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 = NULL;
+        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 '.':
+                return value_sp->GetSubValue (exe_ctx, sub_name + 1, will_modify, error);
+            
+            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 exectable 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;
+}
+
+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->SetValueFromCString(value, op);
+    else
+    {
+        if (error.AsCString() == NULL)
+            error.SetErrorStringWithFormat("invalid value path '%s'", name);
+    }
+    return error;
+}
+
+
+ConstString
+OptionValueProperties::GetPropertyNameAtIndex (uint32_t idx) const
+{
+    const Property *property = GetPropertyAtIndex(NULL, false, idx);
+    if (property)
+        return property->GetName();
+    return ConstString();
+    
+}
+
+const char *
+OptionValueProperties::GetPropertyDescriptionAtIndex (uint32_t idx) const
+{
+    const Property *property = GetPropertyAtIndex(NULL, false, idx);
+    if (property)
+        return property->GetDescription();
+    return NULL;
+}
+
+uint32_t
+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));
+}
+
+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();
+}
+
+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 NULL;
+}
+
+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 NULL;    
+}
+
+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 NULL;
+}
+
+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;
+}
+
+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;
+}
+
+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;
+        }
+    }
+    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 NULL;
+}
+
+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;
+}
+
+
+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;
+}
+
+const RegularExpression *
+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 NULL;
+}
+
+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 NULL;
+}
+
+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;
+}
+
+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::SetValueFromCString (const char *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::SetValueFromCString (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");
+}
+
+const Property *
+OptionValueProperties::GetPropertyAtPath (const ExecutionContext *exe_ctx,
+                                          bool will_modify,
+                                          const char *name) const
+{
+    const Property *property = NULL;
+    if (name && name[0])
+    {
+        const char *sub_name = NULL;
+        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 = NULL;
+        }
+    }
+    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);
+                }
+            }
+        }
+    }
+}
+
+
diff --git a/source/Interpreter/OptionValueRegex.cpp b/source/Interpreter/OptionValueRegex.cpp
new file mode 100644
index 0000000..f1ba0ed
--- /dev/null
+++ b/source/Interpreter/OptionValueRegex.cpp
@@ -0,0 +1,86 @@
+//===-- OptionValueRegex.cpp ------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/Interpreter/OptionValueRegex.h"
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "lldb/Core/Stream.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+void
+OptionValueRegex::DumpValue (const ExecutionContext *exe_ctx, Stream &strm, uint32_t dump_mask)
+{
+    if (dump_mask & eDumpOptionType)
+        strm.Printf ("(%s)", GetTypeAsCString ());
+    if (dump_mask & eDumpOptionValue)
+    {
+        if (dump_mask & eDumpOptionType)
+            strm.PutCString (" = ");
+        if (m_regex.IsValid())
+        {
+            const char *regex_text = m_regex.GetText();
+            if (regex_text && regex_text[0])
+                strm.Printf ("%s", regex_text);
+        }
+        else
+        {
+            
+        }
+    }
+}
+
+Error
+OptionValueRegex::SetValueFromCString (const char *value_cstr,
+                                        VarSetOperationType op)
+{
+    Error error;
+    switch (op)
+    {
+    case eVarSetOperationInvalid:
+    case eVarSetOperationInsertBefore:
+    case eVarSetOperationInsertAfter:
+    case eVarSetOperationRemove:
+    case eVarSetOperationAppend:
+        error = OptionValue::SetValueFromCString (value_cstr, op);
+        break;
+
+    case eVarSetOperationClear:
+        Clear();
+        break;
+
+    case eVarSetOperationReplace:
+    case eVarSetOperationAssign:
+        if (m_regex.Compile (value_cstr, m_regex.GetCompileFlags()))
+        {
+            m_value_was_set = true;
+        }
+        else
+        {
+            char regex_error[1024];
+            if (m_regex.GetErrorAsCString(regex_error, sizeof(regex_error)))
+                error.SetErrorString (regex_error);
+            else
+                error.SetErrorStringWithFormat ("regex error %u", m_regex.GetErrorCode());
+        }
+        break;
+    }
+    return error;
+}
+
+
+lldb::OptionValueSP
+OptionValueRegex::DeepCopy () const
+{
+    return OptionValueSP(new OptionValueRegex(m_regex.GetText(), m_regex.GetCompileFlags()));
+}
diff --git a/source/Interpreter/OptionValueSInt64.cpp b/source/Interpreter/OptionValueSInt64.cpp
new file mode 100644
index 0000000..9d7f4cc
--- /dev/null
+++ b/source/Interpreter/OptionValueSInt64.cpp
@@ -0,0 +1,89 @@
+//===-- OptionValueSInt64.cpp -----------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/Interpreter/OptionValueSInt64.h"
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "lldb/Core/Stream.h"
+#include "lldb/Interpreter/Args.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+void
+OptionValueSInt64::DumpValue (const ExecutionContext *exe_ctx, Stream &strm, uint32_t dump_mask)
+{
+    //printf ("%p: DumpValue (exe_ctx=%p, strm, mask) m_current_value = %lli\n", this, exe_ctx, m_current_value);
+    if (dump_mask & eDumpOptionType)
+        strm.Printf ("(%s)", GetTypeAsCString ());
+//    if (dump_mask & eDumpOptionName)
+//        DumpQualifiedName (strm);
+    if (dump_mask & eDumpOptionValue)
+    {
+        if (dump_mask & eDumpOptionType)
+            strm.PutCString (" = ");
+        strm.Printf ("%lli", m_current_value);
+    }
+}
+
+Error
+OptionValueSInt64::SetValueFromCString (const char *value_cstr, VarSetOperationType op)
+{
+    //printf ("%p: SetValueFromCString (s=\"%s\", op=%i)\n", this, value_cstr, op);
+    Error error;
+    switch (op)
+    {
+        case eVarSetOperationClear:
+            Clear();
+            break;
+            
+        case eVarSetOperationReplace:
+        case eVarSetOperationAssign:
+            {
+                bool success = false;
+                int64_t value = Args::StringToSInt64 (value_cstr, 0, 0, &success);
+                if (success)
+                {
+                    if (value >= m_min_value && value <= m_max_value)
+                    {
+                        m_value_was_set = true;
+                        m_current_value = value;
+                    }
+                    else
+                        error.SetErrorStringWithFormat ("%lli is out of range, valid values must be between %lli and %lli.",
+                                                        value,
+                                                        m_min_value,
+                                                        m_max_value);
+                }
+                else
+                {
+                    error.SetErrorStringWithFormat ("invalid int64_t string value: '%s'", value_cstr);
+                }
+            }
+            break;
+            
+        case eVarSetOperationInsertBefore:
+        case eVarSetOperationInsertAfter:
+        case eVarSetOperationRemove:
+        case eVarSetOperationAppend:
+        case eVarSetOperationInvalid:
+            error = OptionValue::SetValueFromCString (value_cstr, op);
+            break;
+    }
+    return error;
+}
+
+lldb::OptionValueSP
+OptionValueSInt64::DeepCopy () const
+{
+    return OptionValueSP(new OptionValueSInt64(*this));
+}
diff --git a/source/Interpreter/OptionValueString.cpp b/source/Interpreter/OptionValueString.cpp
new file mode 100644
index 0000000..35ab8c8
--- /dev/null
+++ b/source/Interpreter/OptionValueString.cpp
@@ -0,0 +1,77 @@
+//===-- OptionValueString.cpp ------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/Interpreter/OptionValueString.h"
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "lldb/Core/Stream.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+void
+OptionValueString::DumpValue (const ExecutionContext *exe_ctx, Stream &strm, uint32_t dump_mask)
+{
+    if (dump_mask & eDumpOptionType)
+        strm.Printf ("(%s)", GetTypeAsCString ());
+    if (dump_mask & eDumpOptionValue)
+    {
+        if (dump_mask & eDumpOptionType)
+            strm.PutCString (" = ");
+        if (!m_current_value.empty() || m_value_was_set)
+        {
+            if (dump_mask & eDumpOptionRaw)
+                strm.Printf ("%s", m_current_value.c_str());
+            else
+                strm.Printf ("\"%s\"", m_current_value.c_str());
+        }
+    }
+}
+
+Error
+OptionValueString::SetValueFromCString (const char *value_cstr,
+                                        VarSetOperationType op)
+{
+    Error error;
+    switch (op)
+    {
+    case eVarSetOperationInvalid:
+    case eVarSetOperationInsertBefore:
+    case eVarSetOperationInsertAfter:
+    case eVarSetOperationRemove:
+        error = OptionValue::SetValueFromCString (value_cstr, op);
+        break;
+
+    case eVarSetOperationAppend:
+        if (value_cstr && value_cstr[0])
+            m_current_value += value_cstr;
+        break;
+
+    case eVarSetOperationClear:
+        Clear ();
+        break;
+
+    case eVarSetOperationReplace:
+    case eVarSetOperationAssign:
+        m_value_was_set = true;
+        SetCurrentValue (value_cstr);
+        break;
+    }
+    return error;
+}
+
+
+lldb::OptionValueSP
+OptionValueString::DeepCopy () const
+{
+    return OptionValueSP(new OptionValueString(*this));
+}
diff --git a/source/Interpreter/OptionValueUInt64.cpp b/source/Interpreter/OptionValueUInt64.cpp
new file mode 100644
index 0000000..59f1e5f
--- /dev/null
+++ b/source/Interpreter/OptionValueUInt64.cpp
@@ -0,0 +1,89 @@
+//===-- OptionValueUInt64.cpp ------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/Interpreter/OptionValueUInt64.h"
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "lldb/Core/Stream.h"
+#include "lldb/Interpreter/Args.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+lldb::OptionValueSP
+OptionValueUInt64::Create (const char *value_cstr, Error &error)
+{
+    lldb::OptionValueSP value_sp (new OptionValueUInt64());
+    error = value_sp->SetValueFromCString (value_cstr);
+    if (error.Fail())
+        value_sp.reset();
+    return value_sp;
+}
+
+
+void
+OptionValueUInt64::DumpValue (const ExecutionContext *exe_ctx, Stream &strm, uint32_t dump_mask)
+{
+    if (dump_mask & eDumpOptionType)
+        strm.Printf ("(%s)", GetTypeAsCString ());
+    if (dump_mask & eDumpOptionValue)
+    {
+        if (dump_mask & eDumpOptionType)
+            strm.PutCString (" = ");
+        strm.Printf ("%llu", m_current_value);
+    }
+}
+
+Error
+OptionValueUInt64::SetValueFromCString (const char *value_cstr, VarSetOperationType op)
+{
+    Error error;
+    switch (op)
+    {
+        case eVarSetOperationClear:
+            Clear ();
+            break;
+            
+        case eVarSetOperationReplace:
+        case eVarSetOperationAssign:
+        {
+            bool success = false;
+            uint64_t value = Args::StringToUInt64 (value_cstr, 0, 0, &success);
+            if (success)
+            {
+                m_value_was_set = true;
+                m_current_value = value;
+            }
+            else
+            {
+                error.SetErrorStringWithFormat ("invalid uint64_t string value: '%s'", value_cstr);
+            }
+        }
+            break;
+            
+        case eVarSetOperationInsertBefore:
+        case eVarSetOperationInsertAfter:
+        case eVarSetOperationRemove:
+        case eVarSetOperationAppend:
+        case eVarSetOperationInvalid:
+            error = OptionValue::SetValueFromCString (value_cstr, op);
+            break;
+    }
+    return error;
+}
+
+lldb::OptionValueSP
+OptionValueUInt64::DeepCopy () const
+{
+    return OptionValueSP(new OptionValueUInt64(*this));
+}
+
diff --git a/source/Interpreter/OptionValueUUID.cpp b/source/Interpreter/OptionValueUUID.cpp
new file mode 100644
index 0000000..03a5684
--- /dev/null
+++ b/source/Interpreter/OptionValueUUID.cpp
@@ -0,0 +1,70 @@
+//===-- OptionValueUUID.cpp ------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/Interpreter/OptionValueUUID.h"
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "lldb/Core/Stream.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+void
+OptionValueUUID::DumpValue (const ExecutionContext *exe_ctx, Stream &strm, uint32_t dump_mask)
+{
+    if (dump_mask & eDumpOptionType)
+        strm.Printf ("(%s)", GetTypeAsCString ());
+    if (dump_mask & eDumpOptionValue)
+    {
+        if (dump_mask & eDumpOptionType)
+            strm.PutCString (" = ");
+        m_uuid.Dump (&strm);
+    }
+}
+
+Error
+OptionValueUUID::SetValueFromCString (const char *value_cstr,
+                                      VarSetOperationType op)
+{
+    Error error;
+    switch (op)
+    {
+        case eVarSetOperationClear:
+            Clear();
+            break;
+            
+        case eVarSetOperationReplace:
+        case eVarSetOperationAssign:
+            {
+                if (m_uuid.SetfromCString(value_cstr) == 0)
+                    error.SetErrorStringWithFormat ("invalid uuid string value '%s'", value_cstr);
+                else
+                    m_value_was_set = true;
+            }
+            break;
+            
+        case eVarSetOperationInsertBefore:
+        case eVarSetOperationInsertAfter:
+        case eVarSetOperationRemove:
+        case eVarSetOperationAppend:
+        case eVarSetOperationInvalid:
+            error = OptionValue::SetValueFromCString (value_cstr, op);
+            break;
+    }
+    return error;
+}
+
+lldb::OptionValueSP
+OptionValueUUID::DeepCopy () const
+{
+    return OptionValueSP(new OptionValueUUID(*this));
+}
diff --git a/source/Interpreter/Property.cpp b/source/Interpreter/Property.cpp
new file mode 100644
index 0000000..7e7dc01
--- /dev/null
+++ b/source/Interpreter/Property.cpp
@@ -0,0 +1,268 @@
+//===-- Property.cpp --------------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/Interpreter/Property.h"
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "lldb/Core/UserSettingsController.h"
+#include "lldb/Interpreter/Args.h"
+#include "lldb/Interpreter/CommandInterpreter.h"
+#include "lldb/Interpreter/OptionValues.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+Property::Property (const PropertyDefinition &definition) :
+    m_name (definition.name),
+    m_description (definition.description),
+    m_value_sp (),
+    m_is_global (definition.global)
+{
+    switch (definition.type)
+    {
+        case OptionValue::eTypeInvalid:
+        case OptionValue::eTypeProperties:
+            break;
+        case OptionValue::eTypeArch:
+            // "definition.default_uint_value" is not used
+            // "definition.default_cstr_value" as a string value that represents the default string value for the architecture/triple
+            m_value_sp.reset (new OptionValueArch(definition.default_cstr_value));
+            break;
+            
+        case OptionValue::eTypeArgs:
+            // "definition.default_uint_value" is always a OptionValue::Type
+            m_value_sp.reset (new OptionValueArgs());
+            break;
+            
+        case OptionValue::eTypeArray:
+            // "definition.default_uint_value" is always a OptionValue::Type
+            m_value_sp.reset (new OptionValueArray(OptionValue::ConvertTypeToMask((OptionValue::Type)definition.default_uint_value)));
+            break;
+            
+        case OptionValue::eTypeBoolean:
+            // "definition.default_uint_value" is the default boolean value if
+            // "definition.default_cstr_value" is NULL, otherwise interpret
+            // "definition.default_cstr_value" as a string value that represents the default
+            // value.
+            if (definition.default_cstr_value)
+                m_value_sp.reset (new OptionValueBoolean(Args::StringToBoolean (definition.default_cstr_value, false, NULL)));
+            else
+                m_value_sp.reset (new OptionValueBoolean(definition.default_uint_value != 0));
+            break;
+            
+        case OptionValue::eTypeDictionary:
+            // "definition.default_uint_value" is always a OptionValue::Type
+            m_value_sp.reset (new OptionValueDictionary(OptionValue::ConvertTypeToMask((OptionValue::Type)definition.default_uint_value)));
+            break;
+            
+        case OptionValue::eTypeEnum:
+            // "definition.default_uint_value" is the default enumeration value if
+            // "definition.default_cstr_value" is NULL, otherwise interpret
+            // "definition.default_cstr_value" as a string value that represents the default
+            // value.
+        {
+            OptionValueEnumeration *enum_value = new OptionValueEnumeration(definition.enum_values, definition.default_uint_value);
+            m_value_sp.reset (enum_value);
+            if (definition.default_cstr_value)
+            {
+                if (enum_value->SetValueFromCString(definition.default_cstr_value).Success())
+                {
+                    enum_value->SetDefaultValue(enum_value->GetCurrentValue());
+                    // Call Clear() since we don't want the value to appear as
+                    // having been set since we called SetValueFromCString() above.
+                    // Clear will set the current value to the default and clear
+                    // the boolean that says that the value has been set.
+                    enum_value->Clear();
+                }
+            }
+        }
+            break;
+            
+        case OptionValue::eTypeFileSpec:
+            // "definition.default_uint_value" represents if the "definition.default_cstr_value" should
+            // be resolved or not
+            m_value_sp.reset (new OptionValueFileSpec(FileSpec(definition.default_cstr_value, definition.default_uint_value != 0)));
+            break;
+            
+        case OptionValue::eTypeFileSpecList:
+            // "definition.default_uint_value" is not used for a OptionValue::eTypeFileSpecList
+            m_value_sp.reset (new OptionValueFileSpecList());
+            break;
+            
+        case OptionValue::eTypeFormat:
+            // "definition.default_uint_value" is the default format enumeration value if
+            // "definition.default_cstr_value" is NULL, otherwise interpret
+            // "definition.default_cstr_value" as a string value that represents the default
+            // value.
+        {
+            Format new_format = eFormatInvalid;
+            if (definition.default_cstr_value)
+                Args::StringToFormat (definition.default_cstr_value, new_format, NULL);
+            else
+                new_format = (Format)definition.default_uint_value;
+            m_value_sp.reset (new OptionValueFormat(new_format));
+        }
+            break;
+            
+        case OptionValue::eTypePathMap:
+            // "definition.default_uint_value" tells us if notifications should occur for
+            // path mappings
+            m_value_sp.reset (new OptionValuePathMappings(definition.default_uint_value != 0));
+            break;
+            
+        case OptionValue::eTypeRegex:
+            // "definition.default_uint_value" is used to the regular expression flags
+            // "definition.default_cstr_value" the default regular expression value
+            // value.
+            m_value_sp.reset (new OptionValueRegex(definition.default_cstr_value, definition.default_uint_value));
+            break;
+            
+        case OptionValue::eTypeSInt64:
+            // "definition.default_uint_value" is the default integer value if
+            // "definition.default_cstr_value" is NULL, otherwise interpret
+            // "definition.default_cstr_value" as a string value that represents the default
+            // value.
+            m_value_sp.reset (new OptionValueSInt64(definition.default_cstr_value ? Args::StringToSInt64 (definition.default_cstr_value) : definition.default_uint_value));
+            break;
+            
+        case OptionValue::eTypeUInt64:
+            // "definition.default_uint_value" is the default unsigned integer value if
+            // "definition.default_cstr_value" is NULL, otherwise interpret
+            // "definition.default_cstr_value" as a string value that represents the default
+            // value.
+            m_value_sp.reset (new OptionValueUInt64(definition.default_cstr_value ? Args::StringToUInt64 (definition.default_cstr_value) : definition.default_uint_value));
+            break;
+            
+        case OptionValue::eTypeUUID:
+            // "definition.default_uint_value" is not used for a OptionValue::eTypeUUID
+            // "definition.default_cstr_value" can contain a default UUID value
+        {
+            UUID uuid;
+            if (definition.default_cstr_value)
+                uuid.SetfromCString (definition.default_cstr_value);
+            m_value_sp.reset (new OptionValueUUID(uuid));
+        }
+            break;
+            
+        case OptionValue::eTypeString:
+            // "definition.default_uint_value" is not used for a OptionValueFileSpecList
+            // "definition.default_cstr_value" can contain a default string value
+            m_value_sp.reset (new OptionValueString(definition.default_cstr_value));
+            break;
+    }
+}
+
+Property::Property (const ConstString &name,
+                    const ConstString &desc,
+                    bool is_global,
+                    const lldb::OptionValueSP &value_sp) :
+    m_name (name),
+    m_description (desc),
+    m_value_sp (value_sp),
+    m_is_global (is_global)
+{
+}
+
+bool
+Property::DumpQualifiedName(Stream &strm) const
+{
+    if (m_name)
+    {
+        if (m_value_sp->DumpQualifiedName(strm))
+            strm.PutChar('.');
+        strm << m_name;
+        return true;
+    }
+    return false;
+}
+
+
+void
+Property::Dump (const ExecutionContext *exe_ctx, Stream &strm, uint32_t dump_mask) const
+{
+    if (m_value_sp)
+    {
+        const bool dump_desc = dump_mask & OptionValue::eDumpOptionDescription;
+        const bool transparent = m_value_sp->ValueIsTransparent ();
+        if (dump_desc || !transparent)
+        {
+            if ((dump_mask & OptionValue::eDumpOptionName) && m_name)
+            {
+                DumpQualifiedName(strm);
+                if (dump_mask & ~OptionValue::eDumpOptionName)
+                    strm.PutChar(' ');
+            }
+        }
+        if (dump_desc)
+        {
+            const char *desc = GetDescription();
+            if (desc)
+                strm.Printf ("-- %s", desc);
+            
+            if (transparent && (dump_mask == (OptionValue::eDumpOptionName | OptionValue::eDumpOptionDescription)))
+                strm.EOL();
+        }
+        m_value_sp->DumpValue(exe_ctx, strm, dump_mask);
+    }
+}
+
+
+void
+Property::DumpDescription (CommandInterpreter &interpreter,
+                           Stream &strm,
+                           uint32_t output_width,
+                           bool display_qualified_name) const
+{
+    if (m_value_sp)
+    {
+        const char *desc = GetDescription();
+
+        if (desc)
+        {
+            StreamString qualified_name;
+            const OptionValueProperties *sub_properties = m_value_sp->GetAsProperties();
+            if (sub_properties)
+            {
+                strm.EOL();
+                
+                if (m_value_sp->DumpQualifiedName(qualified_name))
+                    strm.Printf("'%s' variables:\n\n", qualified_name.GetString().c_str());
+                sub_properties->DumpAllDescriptions(interpreter, strm);
+            }
+            else
+            {
+                if (desc)
+                {
+                    if (display_qualified_name)
+                    {
+                        StreamString qualified_name;
+                        DumpQualifiedName(qualified_name);
+                        interpreter.OutputFormattedHelpText (strm,
+                                                             qualified_name.GetString().c_str(),
+                                                             "--",
+                                                             desc,
+                                                             output_width);
+                    }
+                    else
+                    {
+                        interpreter.OutputFormattedHelpText (strm,
+                                                             m_name.GetCString(),
+                                                             "--",
+                                                             desc,
+                                                             output_width);
+                    }
+                }
+            }
+        }
+    }
+}
+