The formatters for std::shared_ptr, std::weak_ptr, std::list, std::vector and std::map as provided by libc++ are now written in C++ instead of Python
std::deque is still in Python but is much less commonly used



git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@177454 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/include/lldb/DataFormatters/CXXFormatterFunctions.h b/include/lldb/DataFormatters/CXXFormatterFunctions.h
index 1b3360e..f3b5ec8 100644
--- a/include/lldb/DataFormatters/CXXFormatterFunctions.h
+++ b/include/lldb/DataFormatters/CXXFormatterFunctions.h
@@ -11,6 +11,8 @@
 #define liblldb_CXXFormatterFunctions_h_
 
 #include <stdint.h>
+#include <time.h>
+
 #include "lldb/lldb-forward.h"
 
 #include "lldb/Core/ConstString.h"
@@ -49,6 +51,9 @@
         size_t
         ExtractIndexFromString (const char* item_name);
         
+        time_t
+        GetOSXEpoch ();
+        
         bool
         Char16StringSummaryProvider (ValueObject& valobj, Stream& stream); // char16_t* and unichar*
         
@@ -684,6 +689,150 @@
         
         SyntheticChildrenFrontEnd* LibStdcppVectorIteratorSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP);
         
+        class LibcxxSharedPtrSyntheticFrontEnd : public SyntheticChildrenFrontEnd
+        {
+        public:
+            LibcxxSharedPtrSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp);
+            
+            virtual size_t
+            CalculateNumChildren ();
+            
+            virtual lldb::ValueObjectSP
+            GetChildAtIndex (size_t idx);
+            
+            virtual bool
+            Update();
+            
+            virtual bool
+            MightHaveChildren ();
+            
+            virtual size_t
+            GetIndexOfChildWithName (const ConstString &name);
+            
+            virtual
+            ~LibcxxSharedPtrSyntheticFrontEnd ();
+        private:
+            ValueObject* m_cntrl;
+            lldb::ValueObjectSP m_count_sp;
+            lldb::ValueObjectSP m_weak_count_sp;
+            uint8_t m_ptr_size;
+            lldb::ByteOrder m_byte_order;
+        };
+        
+        SyntheticChildrenFrontEnd* LibcxxSharedPtrSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP);
+        
+        class LibcxxStdVectorSyntheticFrontEnd : public SyntheticChildrenFrontEnd
+        {
+        public:
+            LibcxxStdVectorSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp);
+            
+            virtual size_t
+            CalculateNumChildren ();
+            
+            virtual lldb::ValueObjectSP
+            GetChildAtIndex (size_t idx);
+            
+            virtual bool
+            Update();
+            
+            virtual bool
+            MightHaveChildren ();
+            
+            virtual size_t
+            GetIndexOfChildWithName (const ConstString &name);
+            
+            virtual
+            ~LibcxxStdVectorSyntheticFrontEnd ();
+        private:
+            ValueObject* m_start;
+            ValueObject* m_finish;
+            ClangASTType m_element_type;
+            uint32_t m_element_size;
+            std::map<size_t,lldb::ValueObjectSP> m_children;
+        };
+        
+        SyntheticChildrenFrontEnd* LibcxxStdVectorSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP);
+        
+        class LibcxxStdListSyntheticFrontEnd : public SyntheticChildrenFrontEnd
+        {
+        public:
+            LibcxxStdListSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp);
+            
+            virtual size_t
+            CalculateNumChildren ();
+            
+            virtual lldb::ValueObjectSP
+            GetChildAtIndex (size_t idx);
+            
+            virtual bool
+            Update();
+            
+            virtual bool
+            MightHaveChildren ();
+            
+            virtual size_t
+            GetIndexOfChildWithName (const ConstString &name);
+            
+            virtual
+            ~LibcxxStdListSyntheticFrontEnd ();
+        private:
+            bool
+            HasLoop();
+            
+            static const size_t g_list_capping_size = 255;
+            static const bool g_use_loop_detect = true;
+            lldb::addr_t m_node_address;
+            ValueObject* m_head;
+            ValueObject* m_tail;
+            ClangASTType m_element_type;
+            uint32_t m_element_size;
+            size_t m_count;
+            std::map<size_t,lldb::ValueObjectSP> m_children;
+        };
+        
+        SyntheticChildrenFrontEnd* LibcxxStdListSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP);
+        
+        class LibcxxStdMapSyntheticFrontEnd : public SyntheticChildrenFrontEnd
+        {
+        public:
+            LibcxxStdMapSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp);
+            
+            virtual size_t
+            CalculateNumChildren ();
+            
+            virtual lldb::ValueObjectSP
+            GetChildAtIndex (size_t idx);
+            
+            virtual bool
+            Update();
+            
+            virtual bool
+            MightHaveChildren ();
+            
+            virtual size_t
+            GetIndexOfChildWithName (const ConstString &name);
+            
+            virtual
+            ~LibcxxStdMapSyntheticFrontEnd ();
+        private:
+            bool
+            GetDataType();
+            
+            void
+            GetValueOffset (const lldb::ValueObjectSP& node);
+            
+            static const size_t g_map_capping_size = 255;
+            ValueObject* m_tree;
+            ValueObject* m_root_node;
+            ClangASTType m_element_type;
+            uint32_t m_element_size;
+            uint32_t m_skip_size;
+            size_t m_count;
+            std::map<size_t,lldb::ValueObjectSP> m_children;
+        };
+        
+        SyntheticChildrenFrontEnd* LibcxxStdMapSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP);
+        
     } // namespace formatters
 } // namespace lldb_private
 
diff --git a/include/lldb/Symbol/ClangASTContext.h b/include/lldb/Symbol/ClangASTContext.h
index 7498bee..14402df 100644
--- a/include/lldb/Symbol/ClangASTContext.h
+++ b/include/lldb/Symbol/ClangASTContext.h
@@ -615,6 +615,15 @@
                      uint64_t *bit_offset_ptr,
                      uint32_t *bitfield_bit_size_ptr,
                      bool *is_bitfield_ptr);
+    
+    static size_t
+    GetIndexOfFieldWithName (clang::ASTContext *ast,
+                             lldb::clang_type_t clang_type,
+                             const char* name,
+                             lldb::clang_type_t* field_clang_type = NULL,
+                             uint64_t *bit_offset_ptr = NULL,
+                             uint32_t *bitfield_bit_size_ptr = NULL,
+                             bool *is_bitfield_ptr = NULL);
 
     static uint32_t
     GetNumPointeeChildren (lldb::clang_type_t clang_type);
diff --git a/lldb.xcodeproj/project.pbxproj b/lldb.xcodeproj/project.pbxproj
index 3ec29d8..3345e7e 100644
--- a/lldb.xcodeproj/project.pbxproj
+++ b/lldb.xcodeproj/project.pbxproj
@@ -549,6 +549,10 @@
 		94CB257116B0A4270059775D /* TypeSummary.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94CB256E16B0A4260059775D /* TypeSummary.cpp */; };
 		94CB257216B0A4270059775D /* TypeSynthetic.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94CB256F16B0A4270059775D /* TypeSynthetic.cpp */; };
 		94CB257416B1D3880059775D /* FormatCache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94CB257316B1D3870059775D /* FormatCache.cpp */; };
+		94CD704D16F8DDEA00CF1E42 /* CF.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94CD704B16F8DDEA00CF1E42 /* CF.cpp */; };
+		94CD704E16F8DDEA00CF1E42 /* Cocoa.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94CD704C16F8DDEA00CF1E42 /* Cocoa.cpp */; };
+		94CD705016F8DF1C00CF1E42 /* LibCxxList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94CD704F16F8DF1C00CF1E42 /* LibCxxList.cpp */; };
+		94CD705216F8F5BC00CF1E42 /* LibCxxMap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94CD705116F8F5BC00CF1E42 /* LibCxxMap.cpp */; };
 		94D0B10C16D5535900EA9C70 /* LibCxx.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94D0B10A16D5535900EA9C70 /* LibCxx.cpp */; };
 		94D0B10D16D5535900EA9C70 /* LibStdcpp.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94D0B10B16D5535900EA9C70 /* LibStdcpp.cpp */; };
 		94D6A0AA16CEB55F00833B6E /* NSArray.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94D6A0A716CEB55F00833B6E /* NSArray.cpp */; };
@@ -1603,6 +1607,10 @@
 		94CB256F16B0A4270059775D /* TypeSynthetic.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = TypeSynthetic.cpp; path = source/DataFormatters/TypeSynthetic.cpp; sourceTree = "<group>"; };
 		94CB257316B1D3870059775D /* FormatCache.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = FormatCache.cpp; path = source/DataFormatters/FormatCache.cpp; sourceTree = "<group>"; };
 		94CB257516B1D3910059775D /* FormatCache.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = FormatCache.h; path = include/lldb/DataFormatters/FormatCache.h; sourceTree = "<group>"; };
+		94CD704B16F8DDEA00CF1E42 /* CF.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CF.cpp; path = source/DataFormatters/CF.cpp; sourceTree = "<group>"; };
+		94CD704C16F8DDEA00CF1E42 /* Cocoa.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Cocoa.cpp; path = source/DataFormatters/Cocoa.cpp; sourceTree = "<group>"; };
+		94CD704F16F8DF1C00CF1E42 /* LibCxxList.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LibCxxList.cpp; path = source/DataFormatters/LibCxxList.cpp; sourceTree = "<group>"; };
+		94CD705116F8F5BC00CF1E42 /* LibCxxMap.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LibCxxMap.cpp; path = source/DataFormatters/LibCxxMap.cpp; sourceTree = "<group>"; };
 		94D0B10A16D5535900EA9C70 /* LibCxx.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LibCxx.cpp; path = source/DataFormatters/LibCxx.cpp; sourceTree = "<group>"; };
 		94D0B10B16D5535900EA9C70 /* LibStdcpp.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LibStdcpp.cpp; path = source/DataFormatters/LibStdcpp.cpp; sourceTree = "<group>"; };
 		94D6A0A716CEB55F00833B6E /* NSArray.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = NSArray.cpp; path = source/DataFormatters/NSArray.cpp; sourceTree = "<group>"; };
@@ -3422,6 +3430,8 @@
 		94CB255616B0683B0059775D /* DataFormatters */ = {
 			isa = PBXGroup;
 			children = (
+				94CD704B16F8DDEA00CF1E42 /* CF.cpp */,
+				94CD704C16F8DDEA00CF1E42 /* Cocoa.cpp */,
 				94CB255F16B069800059775D /* CXXFormatterFunctions.h */,
 				94CB255716B069770059775D /* CXXFormatterFunctions.cpp */,
 				94CB256016B069800059775D /* DataVisualization.h */,
@@ -3434,6 +3444,8 @@
 				94CB255A16B069770059775D /* FormatManager.cpp */,
 				94CB256316B069800059775D /* FormatNavigator.h */,
 				94D0B10A16D5535900EA9C70 /* LibCxx.cpp */,
+				94CD704F16F8DF1C00CF1E42 /* LibCxxList.cpp */,
+				94CD705116F8F5BC00CF1E42 /* LibCxxMap.cpp */,
 				94D0B10B16D5535900EA9C70 /* LibStdcpp.cpp */,
 				94D6A0A716CEB55F00833B6E /* NSArray.cpp */,
 				94D6A0A816CEB55F00833B6E /* NSDictionary.cpp */,
@@ -3939,6 +3951,7 @@
 				2689FFF113353DB600698AC0 /* BreakpointID.cpp in Sources */,
 				2689FFF313353DB600698AC0 /* BreakpointIDList.cpp in Sources */,
 				2689FFF513353DB600698AC0 /* BreakpointList.cpp in Sources */,
+				94CD704D16F8DDEA00CF1E42 /* CF.cpp in Sources */,
 				2689FFF713353DB600698AC0 /* BreakpointLocation.cpp in Sources */,
 				2689FFF913353DB600698AC0 /* BreakpointLocationCollection.cpp in Sources */,
 				2689FFFB13353DB600698AC0 /* BreakpointLocationList.cpp in Sources */,
@@ -3946,6 +3959,7 @@
 				2689FFFF13353DB600698AC0 /* BreakpointResolver.cpp in Sources */,
 				2689000113353DB600698AC0 /* BreakpointResolverAddress.cpp in Sources */,
 				2689000313353DB600698AC0 /* BreakpointResolverFileLine.cpp in Sources */,
+				94CD705216F8F5BC00CF1E42 /* LibCxxMap.cpp in Sources */,
 				2689000513353DB600698AC0 /* BreakpointResolverName.cpp in Sources */,
 				2689000713353DB600698AC0 /* BreakpointSite.cpp in Sources */,
 				2689000913353DB600698AC0 /* BreakpointSiteList.cpp in Sources */,
@@ -4292,12 +4306,14 @@
 				2697A39315E404B1003E682C /* OptionValueArch.cpp in Sources */,
 				94EA1D5C15E6C9B400D4171A /* PythonDataObjects.cpp in Sources */,
 				94D6A0AC16CEB55F00833B6E /* NSSet.cpp in Sources */,
+				94CD704E16F8DDEA00CF1E42 /* Cocoa.cpp in Sources */,
 				2698699B15E6CBD0002415FF /* OperatingSystemPython.cpp in Sources */,
 				947A1D641616476B0017C8D1 /* CommandObjectPlugin.cpp in Sources */,
 				262ED0081631FA3A00879631 /* OptionGroupString.cpp in Sources */,
 				94094C6B163B6F840083A547 /* ValueObjectCast.cpp in Sources */,
 				94CB255B16B069770059775D /* CXXFormatterFunctions.cpp in Sources */,
 				94CB255C16B069770059775D /* DataVisualization.cpp in Sources */,
+				94CD705016F8DF1C00CF1E42 /* LibCxxList.cpp in Sources */,
 				94CB255D16B069770059775D /* FormatClasses.cpp in Sources */,
 				94CB255E16B069770059775D /* FormatManager.cpp in Sources */,
 				94CB256616B096F10059775D /* TypeCategory.cpp in Sources */,
diff --git a/source/DataFormatters/CF.cpp b/source/DataFormatters/CF.cpp
new file mode 100644
index 0000000..8debc0e
--- /dev/null
+++ b/source/DataFormatters/CF.cpp
@@ -0,0 +1,299 @@
+//===-- CF.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/DataFormatters/CXXFormatterFunctions.h"
+
+#include "lldb/Core/DataBufferHeap.h"
+#include "lldb/Core/Error.h"
+#include "lldb/Core/Stream.h"
+#include "lldb/Core/ValueObject.h"
+#include "lldb/Core/ValueObjectConstResult.h"
+#include "lldb/Host/Endian.h"
+#include "lldb/Symbol/ClangASTContext.h"
+#include "lldb/Target/ObjCLanguageRuntime.h"
+#include "lldb/Target/Target.h"
+
+using namespace lldb;
+using namespace lldb_private;
+using namespace lldb_private::formatters;
+
+bool
+lldb_private::formatters::CFAbsoluteTimeSummaryProvider (ValueObject& valobj, Stream& stream)
+{
+    time_t epoch = GetOSXEpoch();
+    epoch = epoch + (time_t)valobj.GetValueAsUnsigned(0);
+    tm *tm_date = localtime(&epoch);
+    if (!tm_date)
+        return false;
+    std::string buffer(1024,0);
+    if (strftime (&buffer[0], 1023, "%Z", tm_date) == 0)
+        return false;
+    stream.Printf("%04d-%02d-%02d %02d:%02d:%02d %s", tm_date->tm_year+1900, tm_date->tm_mon+1, tm_date->tm_mday, tm_date->tm_hour, tm_date->tm_min, tm_date->tm_sec, buffer.c_str());
+    return true;
+}
+
+bool
+lldb_private::formatters::CFBagSummaryProvider (ValueObject& valobj, Stream& stream)
+{
+    ProcessSP process_sp = valobj.GetProcessSP();
+    if (!process_sp)
+        return false;
+    
+    ObjCLanguageRuntime* runtime = (ObjCLanguageRuntime*)process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC);
+    
+    if (!runtime)
+        return false;
+    
+    ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptor(valobj));
+    
+    if (!descriptor.get() || !descriptor->IsValid())
+        return false;
+    
+    uint32_t ptr_size = process_sp->GetAddressByteSize();
+    
+    lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0);
+    
+    if (!valobj_addr)
+        return false;
+    
+    uint32_t count = 0;
+    
+    bool is_type_ok = false; // check to see if this is a CFBag we know about
+    if (descriptor->IsCFType())
+    {
+        ConstString type_name(valobj.GetTypeName());
+        if (type_name == ConstString("__CFBag") || type_name == ConstString("const struct __CFBag"))
+        {
+            if (valobj.IsPointerType())
+                is_type_ok = true;
+        }
+    }
+    
+    if (is_type_ok == false)
+    {
+        StackFrameSP frame_sp(valobj.GetFrameSP());
+        if (!frame_sp)
+            return false;
+        ValueObjectSP count_sp;
+        StreamString expr;
+        expr.Printf("(int)CFBagGetCount((void*)0x%" PRIx64 ")",valobj.GetPointerValue());
+        if (process_sp->GetTarget().EvaluateExpression(expr.GetData(), frame_sp.get(), count_sp) != eExecutionCompleted)
+            return false;
+        if (!count_sp)
+            return false;
+        count = count_sp->GetValueAsUnsigned(0);
+    }
+    else
+    {
+        uint32_t offset = 2*ptr_size+4 + valobj_addr;
+        Error error;
+        count = process_sp->ReadUnsignedIntegerFromMemory(offset, 4, 0, error);
+        if (error.Fail())
+            return false;
+    }
+    stream.Printf("@\"%u value%s\"",
+                  count,(count == 1 ? "" : "s"));
+    return true;
+}
+
+bool
+lldb_private::formatters::CFBitVectorSummaryProvider (ValueObject& valobj, Stream& stream)
+{
+    ProcessSP process_sp = valobj.GetProcessSP();
+    if (!process_sp)
+        return false;
+    
+    ObjCLanguageRuntime* runtime = (ObjCLanguageRuntime*)process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC);
+    
+    if (!runtime)
+        return false;
+    
+    ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptor(valobj));
+    
+    if (!descriptor.get() || !descriptor->IsValid())
+        return false;
+    
+    uint32_t ptr_size = process_sp->GetAddressByteSize();
+    
+    lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0);
+    
+    if (!valobj_addr)
+        return false;
+    
+    uint32_t count = 0;
+    
+    bool is_type_ok = false; // check to see if this is a CFBag we know about
+    if (descriptor->IsCFType())
+    {
+        ConstString type_name(valobj.GetTypeName());
+        if (type_name == ConstString("__CFMutableBitVector") || type_name == ConstString("__CFBitVector") || type_name == ConstString("CFMutableBitVectorRef") || type_name == ConstString("CFBitVectorRef"))
+        {
+            if (valobj.IsPointerType())
+                is_type_ok = true;
+        }
+    }
+    
+    if (is_type_ok == false)
+        return false;
+    
+    Error error;
+    count = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr+2*ptr_size, ptr_size, 0, error);
+    if (error.Fail())
+        return false;
+    uint64_t num_bytes = count / 8 + ((count & 7) ? 1 : 0);
+    addr_t data_ptr = process_sp->ReadPointerFromMemory(valobj_addr+2*ptr_size+2*ptr_size, error);
+    if (error.Fail())
+        return false;
+    // make sure we do not try to read huge amounts of data
+    if (num_bytes > 1024)
+        num_bytes = 1024;
+    DataBufferSP buffer_sp(new DataBufferHeap(num_bytes,0));
+    num_bytes = process_sp->ReadMemory(data_ptr, buffer_sp->GetBytes(), num_bytes, error);
+    if (error.Fail())
+        return false;
+    for (int byte_idx = 0; byte_idx < num_bytes-1; byte_idx++)
+    {
+        uint8_t byte = buffer_sp->GetBytes()[byte_idx];
+        bool bit0 = (byte & 1) == 1;
+        bool bit1 = (byte & 2) == 2;
+        bool bit2 = (byte & 4) == 4;
+        bool bit3 = (byte & 8) == 8;
+        bool bit4 = (byte & 16) == 16;
+        bool bit5 = (byte & 32) == 32;
+        bool bit6 = (byte & 64) == 64;
+        bool bit7 = (byte & 128) == 128;
+        stream.Printf("%c%c%c%c %c%c%c%c ",
+                      (bit7 ? '1' : '0'),
+                      (bit6 ? '1' : '0'),
+                      (bit5 ? '1' : '0'),
+                      (bit4 ? '1' : '0'),
+                      (bit3 ? '1' : '0'),
+                      (bit2 ? '1' : '0'),
+                      (bit1 ? '1' : '0'),
+                      (bit0 ? '1' : '0'));
+        count -= 8;
+    }
+    {
+        // print the last byte ensuring we do not print spurious bits
+        uint8_t byte = buffer_sp->GetBytes()[num_bytes-1];
+        bool bit0 = (byte & 1) == 1;
+        bool bit1 = (byte & 2) == 2;
+        bool bit2 = (byte & 4) == 4;
+        bool bit3 = (byte & 8) == 8;
+        bool bit4 = (byte & 16) == 16;
+        bool bit5 = (byte & 32) == 32;
+        bool bit6 = (byte & 64) == 64;
+        bool bit7 = (byte & 128) == 128;
+        if (count)
+        {
+            stream.Printf("%c",bit7 ? '1' : '0');
+            count -= 1;
+        }
+        if (count)
+        {
+            stream.Printf("%c",bit6 ? '1' : '0');
+            count -= 1;
+        }
+        if (count)
+        {
+            stream.Printf("%c",bit5 ? '1' : '0');
+            count -= 1;
+        }
+        if (count)
+        {
+            stream.Printf("%c",bit4 ? '1' : '0');
+            count -= 1;
+        }
+        if (count)
+        {
+            stream.Printf("%c",bit3 ? '1' : '0');
+            count -= 1;
+        }
+        if (count)
+        {
+            stream.Printf("%c",bit2 ? '1' : '0');
+            count -= 1;
+        }
+        if (count)
+        {
+            stream.Printf("%c",bit1 ? '1' : '0');
+            count -= 1;
+        }
+        if (count)
+        {
+            stream.Printf("%c",bit0 ? '1' : '0');
+            count -= 1;
+        }
+    }
+    return true;
+}
+
+bool
+lldb_private::formatters::CFBinaryHeapSummaryProvider (ValueObject& valobj, Stream& stream)
+{
+    ProcessSP process_sp = valobj.GetProcessSP();
+    if (!process_sp)
+        return false;
+    
+    ObjCLanguageRuntime* runtime = (ObjCLanguageRuntime*)process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC);
+    
+    if (!runtime)
+        return false;
+    
+    ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptor(valobj));
+    
+    if (!descriptor.get() || !descriptor->IsValid())
+        return false;
+    
+    uint32_t ptr_size = process_sp->GetAddressByteSize();
+    
+    lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0);
+    
+    if (!valobj_addr)
+        return false;
+    
+    uint32_t count = 0;
+    
+    bool is_type_ok = false; // check to see if this is a CFBinaryHeap we know about
+    if (descriptor->IsCFType())
+    {
+        ConstString type_name(valobj.GetTypeName());
+        if (type_name == ConstString("__CFBinaryHeap") || type_name == ConstString("const struct __CFBinaryHeap"))
+        {
+            if (valobj.IsPointerType())
+                is_type_ok = true;
+        }
+    }
+    
+    if (is_type_ok == false)
+    {
+        StackFrameSP frame_sp(valobj.GetFrameSP());
+        if (!frame_sp)
+            return false;
+        ValueObjectSP count_sp;
+        StreamString expr;
+        expr.Printf("(int)CFBinaryHeapGetCount((void*)0x%" PRIx64 ")",valobj.GetPointerValue());
+        if (process_sp->GetTarget().EvaluateExpression(expr.GetData(), frame_sp.get(), count_sp) != eExecutionCompleted)
+            return false;
+        if (!count_sp)
+            return false;
+        count = count_sp->GetValueAsUnsigned(0);
+    }
+    else
+    {
+        uint32_t offset = 2*ptr_size;
+        Error error;
+        count = process_sp->ReadUnsignedIntegerFromMemory(offset, 4, 0, error);
+        if (error.Fail())
+            return false;
+    }
+    stream.Printf("@\"%u item%s\"",
+                  count,(count == 1 ? "" : "s"));
+    return true;
+}
diff --git a/source/DataFormatters/CXXFormatterFunctions.cpp b/source/DataFormatters/CXXFormatterFunctions.cpp
index 2df6524..20000a7 100644
--- a/source/DataFormatters/CXXFormatterFunctions.cpp
+++ b/source/DataFormatters/CXXFormatterFunctions.cpp
@@ -9,8 +9,6 @@
 
 #include "lldb/lldb-python.h"
 
-#include <time.h>
-
 #include "lldb/DataFormatters/CXXFormatterFunctions.h"
 
 #include "llvm/Support/ConvertUTF.h"
@@ -642,656 +640,6 @@
     return true;
 }
 
-bool
-lldb_private::formatters::NSBundleSummaryProvider (ValueObject& valobj, Stream& stream)
-{
-    ProcessSP process_sp = valobj.GetProcessSP();
-    if (!process_sp)
-        return false;
-    
-    ObjCLanguageRuntime* runtime = (ObjCLanguageRuntime*)process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC);
-    
-    if (!runtime)
-        return false;
-    
-    ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptor(valobj));
-    
-    if (!descriptor.get() || !descriptor->IsValid())
-        return false;
-    
-    uint32_t ptr_size = process_sp->GetAddressByteSize();
-    
-    lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0);
-    
-    if (!valobj_addr)
-        return false;
-    
-    const char* class_name = descriptor->GetClassName().GetCString();
-    
-    if (!class_name || !*class_name)
-        return false;
-    
-    if (!strcmp(class_name,"NSBundle"))
-    {
-        uint64_t offset = 5 * ptr_size;
-        ClangASTType type(valobj.GetClangAST(),valobj.GetClangType());
-        ValueObjectSP text(valobj.GetSyntheticChildAtOffset(offset, type, true));
-        StreamString summary_stream;
-        bool was_nsstring_ok = NSStringSummaryProvider(*text.get(), summary_stream);
-        if (was_nsstring_ok && summary_stream.GetSize() > 0)
-        {
-            stream.Printf("%s",summary_stream.GetData());
-            return true;
-        }
-    }
-    // this is either an unknown subclass or an NSBundle that comes from [NSBundle mainBundle]
-    // which is encoded differently and needs to be handled by running code
-    return ExtractSummaryFromObjCExpression(valobj, "NSString*", "bundlePath", stream);
-}
-
-bool
-lldb_private::formatters::NSTimeZoneSummaryProvider (ValueObject& valobj, Stream& stream)
-{
-    ProcessSP process_sp = valobj.GetProcessSP();
-    if (!process_sp)
-        return false;
-    
-    ObjCLanguageRuntime* runtime = (ObjCLanguageRuntime*)process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC);
-    
-    if (!runtime)
-        return false;
-    
-    ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptor(valobj));
-    
-    if (!descriptor.get() || !descriptor->IsValid())
-        return false;
-    
-    uint32_t ptr_size = process_sp->GetAddressByteSize();
-    
-    lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0);
-    
-    if (!valobj_addr)
-        return false;
-    
-    const char* class_name = descriptor->GetClassName().GetCString();
-    
-    if (!class_name || !*class_name)
-        return false;
-    
-    if (!strcmp(class_name,"__NSTimeZone"))
-    {
-        uint64_t offset = ptr_size;
-        ClangASTType type(valobj.GetClangAST(),valobj.GetClangType());
-        ValueObjectSP text(valobj.GetSyntheticChildAtOffset(offset, type, true));
-        StreamString summary_stream;
-        bool was_nsstring_ok = NSStringSummaryProvider(*text.get(), summary_stream);
-        if (was_nsstring_ok && summary_stream.GetSize() > 0)
-        {
-            stream.Printf("%s",summary_stream.GetData());
-            return true;
-        }
-    }
-    return ExtractSummaryFromObjCExpression(valobj, "NSString*", "name", stream);
-}
-
-bool
-lldb_private::formatters::NSNotificationSummaryProvider (ValueObject& valobj, Stream& stream)
-{
-    ProcessSP process_sp = valobj.GetProcessSP();
-    if (!process_sp)
-        return false;
-    
-    ObjCLanguageRuntime* runtime = (ObjCLanguageRuntime*)process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC);
-    
-    if (!runtime)
-        return false;
-    
-    ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptor(valobj));
-    
-    if (!descriptor.get() || !descriptor->IsValid())
-        return false;
-    
-    uint32_t ptr_size = process_sp->GetAddressByteSize();
-    
-    lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0);
-    
-    if (!valobj_addr)
-        return false;
-    
-    const char* class_name = descriptor->GetClassName().GetCString();
-    
-    if (!class_name || !*class_name)
-        return false;
-    
-    if (!strcmp(class_name,"NSConcreteNotification"))
-    {
-        uint64_t offset = ptr_size;
-        ClangASTType type(valobj.GetClangAST(),valobj.GetClangType());
-        ValueObjectSP text(valobj.GetSyntheticChildAtOffset(offset, type, true));
-        StreamString summary_stream;
-        bool was_nsstring_ok = NSStringSummaryProvider(*text.get(), summary_stream);
-        if (was_nsstring_ok && summary_stream.GetSize() > 0)
-        {
-            stream.Printf("%s",summary_stream.GetData());
-            return true;
-        }
-    }
-    // this is either an unknown subclass or an NSBundle that comes from [NSBundle mainBundle]
-    // which is encoded differently and needs to be handled by running code
-    return ExtractSummaryFromObjCExpression(valobj, "NSString*", "name", stream);
-}
-
-bool
-lldb_private::formatters::NSMachPortSummaryProvider (ValueObject& valobj, Stream& stream)
-{
-    ProcessSP process_sp = valobj.GetProcessSP();
-    if (!process_sp)
-        return false;
-    
-    ObjCLanguageRuntime* runtime = (ObjCLanguageRuntime*)process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC);
-    
-    if (!runtime)
-        return false;
-    
-    ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptor(valobj));
-    
-    if (!descriptor.get() || !descriptor->IsValid())
-        return false;
-    
-    uint32_t ptr_size = process_sp->GetAddressByteSize();
-    
-    lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0);
-    
-    if (!valobj_addr)
-        return false;
-    
-    const char* class_name = descriptor->GetClassName().GetCString();
-    
-    if (!class_name || !*class_name)
-        return false;
-    
-    uint64_t port_number = 0;
-    
-    do
-    {
-        if (!strcmp(class_name,"NSMachPort"))
-        {
-            uint64_t offset = (ptr_size == 4 ? 12 : 20);
-            Error error;
-            port_number = process_sp->ReadUnsignedIntegerFromMemory(offset+valobj_addr, 4, 0, error);
-            if (error.Success())
-                break;
-        }
-        if (!ExtractValueFromObjCExpression(valobj, "int", "machPort", port_number))
-            return false;
-    } while (false);
-    
-    stream.Printf("mach port: %u",(uint32_t)(port_number & 0x00000000FFFFFFFF));
-    return true;
-}
-
-bool
-lldb_private::formatters::CFBagSummaryProvider (ValueObject& valobj, Stream& stream)
-{
-    ProcessSP process_sp = valobj.GetProcessSP();
-    if (!process_sp)
-        return false;
-    
-    ObjCLanguageRuntime* runtime = (ObjCLanguageRuntime*)process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC);
-    
-    if (!runtime)
-        return false;
-    
-    ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptor(valobj));
-    
-    if (!descriptor.get() || !descriptor->IsValid())
-        return false;
-    
-    uint32_t ptr_size = process_sp->GetAddressByteSize();
-    
-    lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0);
-    
-    if (!valobj_addr)
-        return false;
-    
-    uint32_t count = 0;
-
-    bool is_type_ok = false; // check to see if this is a CFBag we know about
-    if (descriptor->IsCFType())
-    {
-        ConstString type_name(valobj.GetTypeName());
-        if (type_name == ConstString("__CFBag") || type_name == ConstString("const struct __CFBag"))
-        {
-            if (valobj.IsPointerType())
-                is_type_ok = true;
-        }
-    }
-    
-    if (is_type_ok == false)
-    {
-        StackFrameSP frame_sp(valobj.GetFrameSP());
-        if (!frame_sp)
-            return false;
-        ValueObjectSP count_sp;
-        StreamString expr;
-        expr.Printf("(int)CFBagGetCount((void*)0x%" PRIx64 ")",valobj.GetPointerValue());
-        if (process_sp->GetTarget().EvaluateExpression(expr.GetData(), frame_sp.get(), count_sp) != eExecutionCompleted)
-            return false;
-        if (!count_sp)
-            return false;
-        count = count_sp->GetValueAsUnsigned(0);
-    }
-    else
-    {
-        uint32_t offset = 2*ptr_size+4 + valobj_addr;
-        Error error;
-        count = process_sp->ReadUnsignedIntegerFromMemory(offset, 4, 0, error);
-        if (error.Fail())
-            return false;
-    }
-    stream.Printf("@\"%u value%s\"",
-                  count,(count == 1 ? "" : "s"));
-    return true;
-}
-
-bool
-lldb_private::formatters::CFBitVectorSummaryProvider (ValueObject& valobj, Stream& stream)
-{
-    ProcessSP process_sp = valobj.GetProcessSP();
-    if (!process_sp)
-        return false;
-    
-    ObjCLanguageRuntime* runtime = (ObjCLanguageRuntime*)process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC);
-    
-    if (!runtime)
-        return false;
-    
-    ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptor(valobj));
-    
-    if (!descriptor.get() || !descriptor->IsValid())
-        return false;
-    
-    uint32_t ptr_size = process_sp->GetAddressByteSize();
-    
-    lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0);
-    
-    if (!valobj_addr)
-        return false;
-    
-    uint32_t count = 0;
-    
-    bool is_type_ok = false; // check to see if this is a CFBag we know about
-    if (descriptor->IsCFType())
-    {
-        ConstString type_name(valobj.GetTypeName());
-        if (type_name == ConstString("__CFMutableBitVector") || type_name == ConstString("__CFBitVector") || type_name == ConstString("CFMutableBitVectorRef") || type_name == ConstString("CFBitVectorRef"))
-        {
-            if (valobj.IsPointerType())
-                is_type_ok = true;
-        }
-    }
-    
-    if (is_type_ok == false)
-        return false;
-    
-    Error error;
-    count = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr+2*ptr_size, ptr_size, 0, error);
-    if (error.Fail())
-        return false;
-    uint64_t num_bytes = count / 8 + ((count & 7) ? 1 : 0);
-    addr_t data_ptr = process_sp->ReadPointerFromMemory(valobj_addr+2*ptr_size+2*ptr_size, error);
-    if (error.Fail())
-        return false;
-    // make sure we do not try to read huge amounts of data
-    if (num_bytes > 1024)
-        num_bytes = 1024;
-    DataBufferSP buffer_sp(new DataBufferHeap(num_bytes,0));
-    num_bytes = process_sp->ReadMemory(data_ptr, buffer_sp->GetBytes(), num_bytes, error);
-    if (error.Fail())
-        return false;
-    for (int byte_idx = 0; byte_idx < num_bytes-1; byte_idx++)
-    {
-        uint8_t byte = buffer_sp->GetBytes()[byte_idx];
-        bool bit0 = (byte & 1) == 1;
-        bool bit1 = (byte & 2) == 2;
-        bool bit2 = (byte & 4) == 4;
-        bool bit3 = (byte & 8) == 8;
-        bool bit4 = (byte & 16) == 16;
-        bool bit5 = (byte & 32) == 32;
-        bool bit6 = (byte & 64) == 64;
-        bool bit7 = (byte & 128) == 128;
-        stream.Printf("%c%c%c%c %c%c%c%c ",
-                      (bit7 ? '1' : '0'),
-                      (bit6 ? '1' : '0'),
-                      (bit5 ? '1' : '0'),
-                      (bit4 ? '1' : '0'),
-                      (bit3 ? '1' : '0'),
-                      (bit2 ? '1' : '0'),
-                      (bit1 ? '1' : '0'),
-                      (bit0 ? '1' : '0'));
-        count -= 8;
-    }
-    {
-        // print the last byte ensuring we do not print spurious bits
-        uint8_t byte = buffer_sp->GetBytes()[num_bytes-1];
-        bool bit0 = (byte & 1) == 1;
-        bool bit1 = (byte & 2) == 2;
-        bool bit2 = (byte & 4) == 4;
-        bool bit3 = (byte & 8) == 8;
-        bool bit4 = (byte & 16) == 16;
-        bool bit5 = (byte & 32) == 32;
-        bool bit6 = (byte & 64) == 64;
-        bool bit7 = (byte & 128) == 128;
-        if (count)
-        {
-            stream.Printf("%c",bit7 ? '1' : '0');
-            count -= 1;
-        }
-        if (count)
-        {
-            stream.Printf("%c",bit6 ? '1' : '0');
-            count -= 1;
-        }
-        if (count)
-        {
-            stream.Printf("%c",bit5 ? '1' : '0');
-            count -= 1;
-        }
-        if (count)
-        {
-            stream.Printf("%c",bit4 ? '1' : '0');
-            count -= 1;
-        }
-        if (count)
-        {
-            stream.Printf("%c",bit3 ? '1' : '0');
-            count -= 1;
-        }
-        if (count)
-        {
-            stream.Printf("%c",bit2 ? '1' : '0');
-            count -= 1;
-        }
-        if (count)
-        {
-            stream.Printf("%c",bit1 ? '1' : '0');
-            count -= 1;
-        }
-        if (count)
-        {
-            stream.Printf("%c",bit0 ? '1' : '0');
-            count -= 1;
-        }
-    }
-    return true;
-}
-
-bool
-lldb_private::formatters::CFBinaryHeapSummaryProvider (ValueObject& valobj, Stream& stream)
-{
-    ProcessSP process_sp = valobj.GetProcessSP();
-    if (!process_sp)
-        return false;
-    
-    ObjCLanguageRuntime* runtime = (ObjCLanguageRuntime*)process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC);
-    
-    if (!runtime)
-        return false;
-    
-    ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptor(valobj));
-    
-    if (!descriptor.get() || !descriptor->IsValid())
-        return false;
-    
-    uint32_t ptr_size = process_sp->GetAddressByteSize();
-    
-    lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0);
-    
-    if (!valobj_addr)
-        return false;
-    
-    uint32_t count = 0;
-    
-    bool is_type_ok = false; // check to see if this is a CFBinaryHeap we know about
-    if (descriptor->IsCFType())
-    {
-        ConstString type_name(valobj.GetTypeName());
-        if (type_name == ConstString("__CFBinaryHeap") || type_name == ConstString("const struct __CFBinaryHeap"))
-        {
-            if (valobj.IsPointerType())
-                is_type_ok = true;
-        }
-    }
-    
-    if (is_type_ok == false)
-    {
-        StackFrameSP frame_sp(valobj.GetFrameSP());
-        if (!frame_sp)
-            return false;
-        ValueObjectSP count_sp;
-        StreamString expr;
-        expr.Printf("(int)CFBinaryHeapGetCount((void*)0x%" PRIx64 ")",valobj.GetPointerValue());
-        if (process_sp->GetTarget().EvaluateExpression(expr.GetData(), frame_sp.get(), count_sp) != eExecutionCompleted)
-            return false;
-        if (!count_sp)
-            return false;
-        count = count_sp->GetValueAsUnsigned(0);
-    }
-    else
-    {
-        uint32_t offset = 2*ptr_size;
-        Error error;
-        count = process_sp->ReadUnsignedIntegerFromMemory(offset, 4, 0, error);
-        if (error.Fail())
-            return false;
-    }
-    stream.Printf("@\"%u item%s\"",
-                  count,(count == 1 ? "" : "s"));
-    return true;
-}
-
-bool
-lldb_private::formatters::NSIndexSetSummaryProvider (ValueObject& valobj, Stream& stream)
-{
-    ProcessSP process_sp = valobj.GetProcessSP();
-    if (!process_sp)
-        return false;
-    
-    ObjCLanguageRuntime* runtime = (ObjCLanguageRuntime*)process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC);
-    
-    if (!runtime)
-        return false;
-    
-    ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptor(valobj));
-    
-    if (!descriptor.get() || !descriptor->IsValid())
-        return false;
-    
-    uint32_t ptr_size = process_sp->GetAddressByteSize();
-    
-    lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0);
-    
-    if (!valobj_addr)
-        return false;
-    
-    const char* class_name = descriptor->GetClassName().GetCString();
-    
-    if (!class_name || !*class_name)
-        return false;
-    
-    uint64_t count = 0;
-    
-    do {
-        if (!strcmp(class_name,"NSIndexSet") || !strcmp(class_name,"NSMutableIndexSet"))
-        {
-            Error error;
-            uint32_t mode = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr+ptr_size, 4, 0, error);
-            if (error.Fail())
-                return false;
-            // this means the set is empty - count = 0
-            if ((mode & 1) == 1)
-            {
-                count = 0;
-                break;
-            }
-            if ((mode & 2) == 2)
-                mode = 1; // this means the set only has one range
-            else
-                mode = 2; // this means the set has multiple ranges
-            if (mode == 1)
-            {
-                count = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr+3*ptr_size, ptr_size, 0, error);
-                if (error.Fail())
-                    return false;
-            }
-            else
-            {
-                // read a pointer to the data at 2*ptr_size
-                count = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr+2*ptr_size, ptr_size, 0, error);
-                if (error.Fail())
-                    return false;
-                // read the data at 2*ptr_size from the first location
-                count = process_sp->ReadUnsignedIntegerFromMemory(count+2*ptr_size, ptr_size, 0, error);
-                if (error.Fail())
-                    return false;
-            }
-        }
-        else
-        {
-            if (!ExtractValueFromObjCExpression(valobj, "unsigned long long int", "count", count))
-                return false;
-        }
-    }  while (false);
-    stream.Printf("%llu index%s",
-                  count,
-                  (count == 1 ? "" : "es"));
-    return true;
-}
-
-bool
-lldb_private::formatters::NSNumberSummaryProvider (ValueObject& valobj, Stream& stream)
-{
-    ProcessSP process_sp = valobj.GetProcessSP();
-    if (!process_sp)
-        return false;
-    
-    ObjCLanguageRuntime* runtime = (ObjCLanguageRuntime*)process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC);
-    
-    if (!runtime)
-        return false;
-    
-    ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptor(valobj));
-    
-    if (!descriptor.get() || !descriptor->IsValid())
-        return false;
-    
-    uint32_t ptr_size = process_sp->GetAddressByteSize();
-    
-    lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0);
-    
-    if (!valobj_addr)
-        return false;
-    
-    const char* class_name = descriptor->GetClassName().GetCString();
-    
-    if (!class_name || !*class_name)
-        return false;
-    
-    if (!strcmp(class_name,"NSNumber") || !strcmp(class_name,"__NSCFNumber"))
-    {
-        if (descriptor->IsTagged())
-        {
-            // we have a call to get info and value bits in the tagged descriptor. but we prefer not to cast and replicate them
-            int64_t value = (valobj_addr & ~0x0000000000000000FFL) >> 8;
-            uint64_t i_bits = (valobj_addr & 0xF0) >> 4;
-            
-            switch (i_bits)
-            {
-                case 0:
-                    stream.Printf("(char)%hhd",(char)value);
-                    break;
-                case 4:
-                    stream.Printf("(short)%hd",(short)value);
-                    break;
-                case 8:
-                    stream.Printf("(int)%d",(int)value);
-                    break;
-                case 12:
-                    stream.Printf("(long)%" PRId64,value);
-                    break;
-                default:
-                    stream.Printf("unexpected value:(info=%" PRIu64 ", value=%" PRIu64,i_bits,value);
-                    break;
-            }
-            return true;
-        }
-        else
-        {
-            Error error;
-            uint8_t data_type = (process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + ptr_size, 1, 0, error) & 0x1F);
-            uint64_t data_location = valobj_addr + 2*ptr_size;
-            uint64_t value = 0;
-            if (error.Fail())
-                return false;
-            switch (data_type)
-            {
-                case 1: // 0B00001
-                    value = process_sp->ReadUnsignedIntegerFromMemory(data_location, 1, 0, error);
-                    if (error.Fail())
-                        return false;
-                    stream.Printf("(char)%hhd",(char)value);
-                    break;
-                case 2: // 0B0010
-                    value = process_sp->ReadUnsignedIntegerFromMemory(data_location, 2, 0, error);
-                    if (error.Fail())
-                        return false;
-                    stream.Printf("(short)%hd",(short)value);
-                    break;
-                case 3: // 0B0011
-                    value = process_sp->ReadUnsignedIntegerFromMemory(data_location, 4, 0, error);
-                    if (error.Fail())
-                        return false;
-                    stream.Printf("(int)%d",(int)value);
-                    break;
-                case 17: // 0B10001
-                    data_location += 8;
-                case 4: // 0B0100
-                    value = process_sp->ReadUnsignedIntegerFromMemory(data_location, 8, 0, error);
-                    if (error.Fail())
-                        return false;
-                    stream.Printf("(long)%" PRId64,value);
-                    break;
-                case 5: // 0B0101
-                {
-                    uint32_t flt_as_int = process_sp->ReadUnsignedIntegerFromMemory(data_location, 4, 0, error);
-                    if (error.Fail())
-                        return false;
-                    float flt_value = *((float*)&flt_as_int);
-                    stream.Printf("(float)%f",flt_value);
-                    break;
-                }
-                case 6: // 0B0110
-                {
-                    uint64_t dbl_as_lng = process_sp->ReadUnsignedIntegerFromMemory(data_location, 8, 0, error);
-                    if (error.Fail())
-                        return false;
-                    double dbl_value = *((double*)&dbl_as_lng);
-                    stream.Printf("(double)%g",dbl_value);
-                    break;
-                }
-                default:
-                    stream.Printf("absurd: dt=%d",data_type);
-                    break;
-            }
-            return true;
-        }
-    }
-    else
-    {
-        return ExtractSummaryFromObjCExpression(valobj, "NSString*", "stringValue", stream);
-    }
-}
-
 static bool
 ReadAsciiBufferAndDumpToStream (lldb::addr_t location,
                                 lldb::ProcessSP& process_sp,
@@ -1488,71 +836,6 @@
 }
 
 bool
-lldb_private::formatters::NSURLSummaryProvider (ValueObject& valobj, Stream& stream)
-{
-    ProcessSP process_sp = valobj.GetProcessSP();
-    if (!process_sp)
-        return false;
-    
-    ObjCLanguageRuntime* runtime = (ObjCLanguageRuntime*)process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC);
-    
-    if (!runtime)
-        return false;
-    
-    ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptor(valobj));
-    
-    if (!descriptor.get() || !descriptor->IsValid())
-        return false;
-    
-    uint32_t ptr_size = process_sp->GetAddressByteSize();
-    
-    lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0);
-    
-    if (!valobj_addr)
-        return false;
-    
-    const char* class_name = descriptor->GetClassName().GetCString();
-    
-    if (!class_name || !*class_name)
-        return false;
-    
-    if (strcmp(class_name, "NSURL") == 0)
-    {
-        uint64_t offset_text = ptr_size + ptr_size + 8; // ISA + pointer + 8 bytes of data (even on 32bit)
-        uint64_t offset_base = offset_text + ptr_size;
-        ClangASTType type(valobj.GetClangAST(),valobj.GetClangType());
-        ValueObjectSP text(valobj.GetSyntheticChildAtOffset(offset_text, type, true));
-        ValueObjectSP base(valobj.GetSyntheticChildAtOffset(offset_base, type, true));
-        if (!text)
-            return false;
-        if (text->GetValueAsUnsigned(0) == 0)
-            return false;
-        StreamString summary;
-        if (!NSStringSummaryProvider(*text, summary))
-            return false;
-        if (base && base->GetValueAsUnsigned(0))
-        {
-            if (summary.GetSize() > 0)
-                summary.GetString().resize(summary.GetSize()-1);
-            summary.Printf(" -- ");
-            StreamString base_summary;
-            if (NSURLSummaryProvider(*base, base_summary) && base_summary.GetSize() > 0)
-                summary.Printf("%s",base_summary.GetSize() > 2 ? base_summary.GetData() + 2 : base_summary.GetData());
-        }
-        if (summary.GetSize())
-        {
-            stream.Printf("%s",summary.GetData());
-            return true;
-        }
-    }
-    else
-    {
-        return ExtractSummaryFromObjCExpression(valobj, "NSString*", "description", stream);
-    }
-    return false;
-}
-
-bool
 lldb_private::formatters::ObjCBOOLSummaryProvider (ValueObject& valobj, Stream& stream)
 {
     const uint32_t type_info = ClangASTContext::GetTypeInfo(valobj.GetClangType(),
@@ -1623,7 +906,7 @@
 // POSIX has an epoch on Jan-1-1970, but Cocoa prefers Jan-1-2001
 // this call gives the POSIX equivalent of the Cocoa epoch
 time_t
-GetOSXEpoch ()
+lldb_private::formatters::GetOSXEpoch ()
 {
     static time_t epoch = 0;
     if (!epoch)
@@ -1644,107 +927,6 @@
     return epoch;
 }
 
-bool
-lldb_private::formatters::NSDateSummaryProvider (ValueObject& valobj, Stream& stream)
-{
-    ProcessSP process_sp = valobj.GetProcessSP();
-    if (!process_sp)
-        return false;
-    
-    ObjCLanguageRuntime* runtime = (ObjCLanguageRuntime*)process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC);
-    
-    if (!runtime)
-        return false;
-    
-    ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptor(valobj));
-    
-    if (!descriptor.get() || !descriptor->IsValid())
-        return false;
-    
-    uint32_t ptr_size = process_sp->GetAddressByteSize();
-    
-    lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0);
-    
-    if (!valobj_addr)
-        return false;
-
-    uint64_t date_value_bits = 0;
-    double date_value = 0.0;
-    
-    const char* class_name = descriptor->GetClassName().GetCString();
-    
-    if (!class_name || !*class_name)
-        return false;
-    
-    if (strcmp(class_name,"NSDate") == 0 ||
-        strcmp(class_name,"__NSDate") == 0 ||
-        strcmp(class_name,"__NSTaggedDate") == 0)
-    {
-        if (descriptor->IsTagged())
-        {
-            uint64_t info_bits = (valobj_addr & 0xF0ULL) >> 4;
-            uint64_t value_bits = (valobj_addr & ~0x0000000000000000FFULL) >> 8;
-            date_value_bits = ((value_bits << 8) | (info_bits << 4));
-            date_value = *((double*)&date_value_bits);
-        }
-        else
-        {
-            Error error;
-            date_value_bits = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr+ptr_size, 8, 0, error);
-            date_value = *((double*)&date_value_bits);
-            if (error.Fail())
-                return false;
-        }
-    }
-    else if (!strcmp(class_name,"NSCalendarDate"))
-    {
-        Error error;
-        date_value_bits = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr+2*ptr_size, 8, 0, error);
-        date_value = *((double*)&date_value_bits);
-        if (error.Fail())
-            return false;
-    }
-    else
-    {
-        if (ExtractValueFromObjCExpression(valobj, "NSTimeInterval", "ExtractValueFromObjCExpression", date_value_bits) == false)
-            return false;
-        date_value = *((double*)&date_value_bits);
-    }
-    if (date_value == -63114076800)
-    {
-        stream.Printf("0001-12-30 00:00:00 +0000");
-        return true;
-    }
-    // this snippet of code assumes that time_t == seconds since Jan-1-1970
-    // this is generally true and POSIXly happy, but might break if a library
-    // vendor decides to get creative
-    time_t epoch = GetOSXEpoch();
-    epoch = epoch + (time_t)date_value;
-    tm *tm_date = localtime(&epoch);
-    if (!tm_date)
-        return false;
-    std::string buffer(1024,0);
-    if (strftime (&buffer[0], 1023, "%Z", tm_date) == 0)
-        return false;
-    stream.Printf("%04d-%02d-%02d %02d:%02d:%02d %s", tm_date->tm_year+1900, tm_date->tm_mon+1, tm_date->tm_mday, tm_date->tm_hour, tm_date->tm_min, tm_date->tm_sec, buffer.c_str());
-    return true;
-}
-
-bool
-lldb_private::formatters::CFAbsoluteTimeSummaryProvider (ValueObject& valobj, Stream& stream)
-{
-    time_t epoch = GetOSXEpoch();
-    epoch = epoch + (time_t)valobj.GetValueAsUnsigned(0);
-    tm *tm_date = localtime(&epoch);
-    if (!tm_date)
-        return false;
-    std::string buffer(1024,0);
-    if (strftime (&buffer[0], 1023, "%Z", tm_date) == 0)
-        return false;
-    stream.Printf("%04d-%02d-%02d %02d:%02d:%02d %s", tm_date->tm_year+1900, tm_date->tm_mon+1, tm_date->tm_mday, tm_date->tm_hour, tm_date->tm_min, tm_date->tm_sec, buffer.c_str());
-    return true;
-}
-
 size_t
 lldb_private::formatters::ExtractIndexFromString (const char* item_name)
 {
diff --git a/source/DataFormatters/Cocoa.cpp b/source/DataFormatters/Cocoa.cpp
new file mode 100644
index 0000000..2ae7ee0
--- /dev/null
+++ b/source/DataFormatters/Cocoa.cpp
@@ -0,0 +1,565 @@
+//===-- Cocoa.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/DataFormatters/CXXFormatterFunctions.h"
+
+#include "lldb/Core/DataBufferHeap.h"
+#include "lldb/Core/Error.h"
+#include "lldb/Core/Stream.h"
+#include "lldb/Core/ValueObject.h"
+#include "lldb/Core/ValueObjectConstResult.h"
+#include "lldb/Host/Endian.h"
+#include "lldb/Symbol/ClangASTContext.h"
+#include "lldb/Target/ObjCLanguageRuntime.h"
+#include "lldb/Target/Target.h"
+
+using namespace lldb;
+using namespace lldb_private;
+using namespace lldb_private::formatters;
+
+bool
+lldb_private::formatters::NSBundleSummaryProvider (ValueObject& valobj, Stream& stream)
+{
+    ProcessSP process_sp = valobj.GetProcessSP();
+    if (!process_sp)
+        return false;
+    
+    ObjCLanguageRuntime* runtime = (ObjCLanguageRuntime*)process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC);
+    
+    if (!runtime)
+        return false;
+    
+    ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptor(valobj));
+    
+    if (!descriptor.get() || !descriptor->IsValid())
+        return false;
+    
+    uint32_t ptr_size = process_sp->GetAddressByteSize();
+    
+    lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0);
+    
+    if (!valobj_addr)
+        return false;
+    
+    const char* class_name = descriptor->GetClassName().GetCString();
+    
+    if (!class_name || !*class_name)
+        return false;
+    
+    if (!strcmp(class_name,"NSBundle"))
+    {
+        uint64_t offset = 5 * ptr_size;
+        ClangASTType type(valobj.GetClangAST(),valobj.GetClangType());
+        ValueObjectSP text(valobj.GetSyntheticChildAtOffset(offset, type, true));
+        StreamString summary_stream;
+        bool was_nsstring_ok = NSStringSummaryProvider(*text.get(), summary_stream);
+        if (was_nsstring_ok && summary_stream.GetSize() > 0)
+        {
+            stream.Printf("%s",summary_stream.GetData());
+            return true;
+        }
+    }
+    // this is either an unknown subclass or an NSBundle that comes from [NSBundle mainBundle]
+    // which is encoded differently and needs to be handled by running code
+    return ExtractSummaryFromObjCExpression(valobj, "NSString*", "bundlePath", stream);
+}
+
+bool
+lldb_private::formatters::NSTimeZoneSummaryProvider (ValueObject& valobj, Stream& stream)
+{
+    ProcessSP process_sp = valobj.GetProcessSP();
+    if (!process_sp)
+        return false;
+    
+    ObjCLanguageRuntime* runtime = (ObjCLanguageRuntime*)process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC);
+    
+    if (!runtime)
+        return false;
+    
+    ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptor(valobj));
+    
+    if (!descriptor.get() || !descriptor->IsValid())
+        return false;
+    
+    uint32_t ptr_size = process_sp->GetAddressByteSize();
+    
+    lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0);
+    
+    if (!valobj_addr)
+        return false;
+    
+    const char* class_name = descriptor->GetClassName().GetCString();
+    
+    if (!class_name || !*class_name)
+        return false;
+    
+    if (!strcmp(class_name,"__NSTimeZone"))
+    {
+        uint64_t offset = ptr_size;
+        ClangASTType type(valobj.GetClangAST(),valobj.GetClangType());
+        ValueObjectSP text(valobj.GetSyntheticChildAtOffset(offset, type, true));
+        StreamString summary_stream;
+        bool was_nsstring_ok = NSStringSummaryProvider(*text.get(), summary_stream);
+        if (was_nsstring_ok && summary_stream.GetSize() > 0)
+        {
+            stream.Printf("%s",summary_stream.GetData());
+            return true;
+        }
+    }
+    return ExtractSummaryFromObjCExpression(valobj, "NSString*", "name", stream);
+}
+
+bool
+lldb_private::formatters::NSNotificationSummaryProvider (ValueObject& valobj, Stream& stream)
+{
+    ProcessSP process_sp = valobj.GetProcessSP();
+    if (!process_sp)
+        return false;
+    
+    ObjCLanguageRuntime* runtime = (ObjCLanguageRuntime*)process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC);
+    
+    if (!runtime)
+        return false;
+    
+    ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptor(valobj));
+    
+    if (!descriptor.get() || !descriptor->IsValid())
+        return false;
+    
+    uint32_t ptr_size = process_sp->GetAddressByteSize();
+    
+    lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0);
+    
+    if (!valobj_addr)
+        return false;
+    
+    const char* class_name = descriptor->GetClassName().GetCString();
+    
+    if (!class_name || !*class_name)
+        return false;
+    
+    if (!strcmp(class_name,"NSConcreteNotification"))
+    {
+        uint64_t offset = ptr_size;
+        ClangASTType type(valobj.GetClangAST(),valobj.GetClangType());
+        ValueObjectSP text(valobj.GetSyntheticChildAtOffset(offset, type, true));
+        StreamString summary_stream;
+        bool was_nsstring_ok = NSStringSummaryProvider(*text.get(), summary_stream);
+        if (was_nsstring_ok && summary_stream.GetSize() > 0)
+        {
+            stream.Printf("%s",summary_stream.GetData());
+            return true;
+        }
+    }
+    // this is either an unknown subclass or an NSBundle that comes from [NSBundle mainBundle]
+    // which is encoded differently and needs to be handled by running code
+    return ExtractSummaryFromObjCExpression(valobj, "NSString*", "name", stream);
+}
+
+bool
+lldb_private::formatters::NSMachPortSummaryProvider (ValueObject& valobj, Stream& stream)
+{
+    ProcessSP process_sp = valobj.GetProcessSP();
+    if (!process_sp)
+        return false;
+    
+    ObjCLanguageRuntime* runtime = (ObjCLanguageRuntime*)process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC);
+    
+    if (!runtime)
+        return false;
+    
+    ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptor(valobj));
+    
+    if (!descriptor.get() || !descriptor->IsValid())
+        return false;
+    
+    uint32_t ptr_size = process_sp->GetAddressByteSize();
+    
+    lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0);
+    
+    if (!valobj_addr)
+        return false;
+    
+    const char* class_name = descriptor->GetClassName().GetCString();
+    
+    if (!class_name || !*class_name)
+        return false;
+    
+    uint64_t port_number = 0;
+    
+    do
+    {
+        if (!strcmp(class_name,"NSMachPort"))
+        {
+            uint64_t offset = (ptr_size == 4 ? 12 : 20);
+            Error error;
+            port_number = process_sp->ReadUnsignedIntegerFromMemory(offset+valobj_addr, 4, 0, error);
+            if (error.Success())
+                break;
+        }
+        if (!ExtractValueFromObjCExpression(valobj, "int", "machPort", port_number))
+            return false;
+    } while (false);
+    
+    stream.Printf("mach port: %u",(uint32_t)(port_number & 0x00000000FFFFFFFF));
+    return true;
+}
+
+bool
+lldb_private::formatters::NSIndexSetSummaryProvider (ValueObject& valobj, Stream& stream)
+{
+    ProcessSP process_sp = valobj.GetProcessSP();
+    if (!process_sp)
+        return false;
+    
+    ObjCLanguageRuntime* runtime = (ObjCLanguageRuntime*)process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC);
+    
+    if (!runtime)
+        return false;
+    
+    ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptor(valobj));
+    
+    if (!descriptor.get() || !descriptor->IsValid())
+        return false;
+    
+    uint32_t ptr_size = process_sp->GetAddressByteSize();
+    
+    lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0);
+    
+    if (!valobj_addr)
+        return false;
+    
+    const char* class_name = descriptor->GetClassName().GetCString();
+    
+    if (!class_name || !*class_name)
+        return false;
+    
+    uint64_t count = 0;
+    
+    do {
+        if (!strcmp(class_name,"NSIndexSet") || !strcmp(class_name,"NSMutableIndexSet"))
+        {
+            Error error;
+            uint32_t mode = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr+ptr_size, 4, 0, error);
+            if (error.Fail())
+                return false;
+            // this means the set is empty - count = 0
+            if ((mode & 1) == 1)
+            {
+                count = 0;
+                break;
+            }
+            if ((mode & 2) == 2)
+                mode = 1; // this means the set only has one range
+            else
+                mode = 2; // this means the set has multiple ranges
+            if (mode == 1)
+            {
+                count = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr+3*ptr_size, ptr_size, 0, error);
+                if (error.Fail())
+                    return false;
+            }
+            else
+            {
+                // read a pointer to the data at 2*ptr_size
+                count = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr+2*ptr_size, ptr_size, 0, error);
+                if (error.Fail())
+                    return false;
+                // read the data at 2*ptr_size from the first location
+                count = process_sp->ReadUnsignedIntegerFromMemory(count+2*ptr_size, ptr_size, 0, error);
+                if (error.Fail())
+                    return false;
+            }
+        }
+        else
+        {
+            if (!ExtractValueFromObjCExpression(valobj, "unsigned long long int", "count", count))
+                return false;
+        }
+    }  while (false);
+    stream.Printf("%llu index%s",
+                  count,
+                  (count == 1 ? "" : "es"));
+    return true;
+}
+
+bool
+lldb_private::formatters::NSNumberSummaryProvider (ValueObject& valobj, Stream& stream)
+{
+    ProcessSP process_sp = valobj.GetProcessSP();
+    if (!process_sp)
+        return false;
+    
+    ObjCLanguageRuntime* runtime = (ObjCLanguageRuntime*)process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC);
+    
+    if (!runtime)
+        return false;
+    
+    ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptor(valobj));
+    
+    if (!descriptor.get() || !descriptor->IsValid())
+        return false;
+    
+    uint32_t ptr_size = process_sp->GetAddressByteSize();
+    
+    lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0);
+    
+    if (!valobj_addr)
+        return false;
+    
+    const char* class_name = descriptor->GetClassName().GetCString();
+    
+    if (!class_name || !*class_name)
+        return false;
+    
+    if (!strcmp(class_name,"NSNumber") || !strcmp(class_name,"__NSCFNumber"))
+    {
+        if (descriptor->IsTagged())
+        {
+            // we have a call to get info and value bits in the tagged descriptor. but we prefer not to cast and replicate them
+            int64_t value = (valobj_addr & ~0x0000000000000000FFL) >> 8;
+            uint64_t i_bits = (valobj_addr & 0xF0) >> 4;
+            
+            switch (i_bits)
+            {
+                case 0:
+                    stream.Printf("(char)%hhd",(char)value);
+                    break;
+                case 4:
+                    stream.Printf("(short)%hd",(short)value);
+                    break;
+                case 8:
+                    stream.Printf("(int)%d",(int)value);
+                    break;
+                case 12:
+                    stream.Printf("(long)%" PRId64,value);
+                    break;
+                default:
+                    stream.Printf("unexpected value:(info=%" PRIu64 ", value=%" PRIu64,i_bits,value);
+                    break;
+            }
+            return true;
+        }
+        else
+        {
+            Error error;
+            uint8_t data_type = (process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + ptr_size, 1, 0, error) & 0x1F);
+            uint64_t data_location = valobj_addr + 2*ptr_size;
+            uint64_t value = 0;
+            if (error.Fail())
+                return false;
+            switch (data_type)
+            {
+                case 1: // 0B00001
+                    value = process_sp->ReadUnsignedIntegerFromMemory(data_location, 1, 0, error);
+                    if (error.Fail())
+                        return false;
+                    stream.Printf("(char)%hhd",(char)value);
+                    break;
+                case 2: // 0B0010
+                    value = process_sp->ReadUnsignedIntegerFromMemory(data_location, 2, 0, error);
+                    if (error.Fail())
+                        return false;
+                    stream.Printf("(short)%hd",(short)value);
+                    break;
+                case 3: // 0B0011
+                    value = process_sp->ReadUnsignedIntegerFromMemory(data_location, 4, 0, error);
+                    if (error.Fail())
+                        return false;
+                    stream.Printf("(int)%d",(int)value);
+                    break;
+                case 17: // 0B10001
+                    data_location += 8;
+                case 4: // 0B0100
+                    value = process_sp->ReadUnsignedIntegerFromMemory(data_location, 8, 0, error);
+                    if (error.Fail())
+                        return false;
+                    stream.Printf("(long)%" PRId64,value);
+                    break;
+                case 5: // 0B0101
+                {
+                    uint32_t flt_as_int = process_sp->ReadUnsignedIntegerFromMemory(data_location, 4, 0, error);
+                    if (error.Fail())
+                        return false;
+                    float flt_value = *((float*)&flt_as_int);
+                    stream.Printf("(float)%f",flt_value);
+                    break;
+                }
+                case 6: // 0B0110
+                {
+                    uint64_t dbl_as_lng = process_sp->ReadUnsignedIntegerFromMemory(data_location, 8, 0, error);
+                    if (error.Fail())
+                        return false;
+                    double dbl_value = *((double*)&dbl_as_lng);
+                    stream.Printf("(double)%g",dbl_value);
+                    break;
+                }
+                default:
+                    stream.Printf("absurd: dt=%d",data_type);
+                    break;
+            }
+            return true;
+        }
+    }
+    else
+    {
+        return ExtractSummaryFromObjCExpression(valobj, "NSString*", "stringValue", stream);
+    }
+}
+
+bool
+lldb_private::formatters::NSURLSummaryProvider (ValueObject& valobj, Stream& stream)
+{
+    ProcessSP process_sp = valobj.GetProcessSP();
+    if (!process_sp)
+        return false;
+    
+    ObjCLanguageRuntime* runtime = (ObjCLanguageRuntime*)process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC);
+    
+    if (!runtime)
+        return false;
+    
+    ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptor(valobj));
+    
+    if (!descriptor.get() || !descriptor->IsValid())
+        return false;
+    
+    uint32_t ptr_size = process_sp->GetAddressByteSize();
+    
+    lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0);
+    
+    if (!valobj_addr)
+        return false;
+    
+    const char* class_name = descriptor->GetClassName().GetCString();
+    
+    if (!class_name || !*class_name)
+        return false;
+    
+    if (strcmp(class_name, "NSURL") == 0)
+    {
+        uint64_t offset_text = ptr_size + ptr_size + 8; // ISA + pointer + 8 bytes of data (even on 32bit)
+        uint64_t offset_base = offset_text + ptr_size;
+        ClangASTType type(valobj.GetClangAST(),valobj.GetClangType());
+        ValueObjectSP text(valobj.GetSyntheticChildAtOffset(offset_text, type, true));
+        ValueObjectSP base(valobj.GetSyntheticChildAtOffset(offset_base, type, true));
+        if (!text)
+            return false;
+        if (text->GetValueAsUnsigned(0) == 0)
+            return false;
+        StreamString summary;
+        if (!NSStringSummaryProvider(*text, summary))
+            return false;
+        if (base && base->GetValueAsUnsigned(0))
+        {
+            if (summary.GetSize() > 0)
+                summary.GetString().resize(summary.GetSize()-1);
+            summary.Printf(" -- ");
+            StreamString base_summary;
+            if (NSURLSummaryProvider(*base, base_summary) && base_summary.GetSize() > 0)
+                summary.Printf("%s",base_summary.GetSize() > 2 ? base_summary.GetData() + 2 : base_summary.GetData());
+        }
+        if (summary.GetSize())
+        {
+            stream.Printf("%s",summary.GetData());
+            return true;
+        }
+    }
+    else
+    {
+        return ExtractSummaryFromObjCExpression(valobj, "NSString*", "description", stream);
+    }
+    return false;
+}
+
+bool
+lldb_private::formatters::NSDateSummaryProvider (ValueObject& valobj, Stream& stream)
+{
+    ProcessSP process_sp = valobj.GetProcessSP();
+    if (!process_sp)
+        return false;
+    
+    ObjCLanguageRuntime* runtime = (ObjCLanguageRuntime*)process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC);
+    
+    if (!runtime)
+        return false;
+    
+    ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptor(valobj));
+    
+    if (!descriptor.get() || !descriptor->IsValid())
+        return false;
+    
+    uint32_t ptr_size = process_sp->GetAddressByteSize();
+    
+    lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0);
+    
+    if (!valobj_addr)
+        return false;
+    
+    uint64_t date_value_bits = 0;
+    double date_value = 0.0;
+    
+    const char* class_name = descriptor->GetClassName().GetCString();
+    
+    if (!class_name || !*class_name)
+        return false;
+    
+    if (strcmp(class_name,"NSDate") == 0 ||
+        strcmp(class_name,"__NSDate") == 0 ||
+        strcmp(class_name,"__NSTaggedDate") == 0)
+    {
+        if (descriptor->IsTagged())
+        {
+            uint64_t info_bits = (valobj_addr & 0xF0ULL) >> 4;
+            uint64_t value_bits = (valobj_addr & ~0x0000000000000000FFULL) >> 8;
+            date_value_bits = ((value_bits << 8) | (info_bits << 4));
+            date_value = *((double*)&date_value_bits);
+        }
+        else
+        {
+            Error error;
+            date_value_bits = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr+ptr_size, 8, 0, error);
+            date_value = *((double*)&date_value_bits);
+            if (error.Fail())
+                return false;
+        }
+    }
+    else if (!strcmp(class_name,"NSCalendarDate"))
+    {
+        Error error;
+        date_value_bits = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr+2*ptr_size, 8, 0, error);
+        date_value = *((double*)&date_value_bits);
+        if (error.Fail())
+            return false;
+    }
+    else
+    {
+        if (ExtractValueFromObjCExpression(valobj, "NSTimeInterval", "ExtractValueFromObjCExpression", date_value_bits) == false)
+            return false;
+        date_value = *((double*)&date_value_bits);
+    }
+    if (date_value == -63114076800)
+    {
+        stream.Printf("0001-12-30 00:00:00 +0000");
+        return true;
+    }
+    // this snippet of code assumes that time_t == seconds since Jan-1-1970
+    // this is generally true and POSIXly happy, but might break if a library
+    // vendor decides to get creative
+    time_t epoch = GetOSXEpoch();
+    epoch = epoch + (time_t)date_value;
+    tm *tm_date = localtime(&epoch);
+    if (!tm_date)
+        return false;
+    std::string buffer(1024,0);
+    if (strftime (&buffer[0], 1023, "%Z", tm_date) == 0)
+        return false;
+    stream.Printf("%04d-%02d-%02d %02d:%02d:%02d %s", tm_date->tm_year+1900, tm_date->tm_mon+1, tm_date->tm_mday, tm_date->tm_hour, tm_date->tm_min, tm_date->tm_sec, buffer.c_str());
+    return true;
+}
diff --git a/source/DataFormatters/FormatManager.cpp b/source/DataFormatters/FormatManager.cpp
index e4937ce..fa9ce49 100644
--- a/source/DataFormatters/FormatManager.cpp
+++ b/source/DataFormatters/FormatManager.cpp
@@ -623,24 +623,16 @@
     SyntheticChildren::Flags stl_synth_flags;
     stl_synth_flags.SetCascades(true).SetSkipPointers(false).SetSkipReferences(false);
     
-    libcxx_category_sp->GetRegexSyntheticNavigator()->Add(RegularExpressionSP(new RegularExpression("^std::__1::vector<.+>(( )?&)?$")),
-                                                       SyntheticChildrenSP(new ScriptedSyntheticChildren(stl_synth_flags,
-                                                                                                 "lldb.formatters.cpp.libcxx.stdvector_SynthProvider")));
-    libcxx_category_sp->GetRegexSyntheticNavigator()->Add(RegularExpressionSP(new RegularExpression("^std::__1::list<.+>(( )?&)?$")),
-                                                       SyntheticChildrenSP(new ScriptedSyntheticChildren(stl_synth_flags,
-                                                                                                 "lldb.formatters.cpp.libcxx.stdlist_SynthProvider")));
-    libcxx_category_sp->GetRegexSyntheticNavigator()->Add(RegularExpressionSP(new RegularExpression("^std::__1::map<.+> >(( )?&)?$")),
-                                                       SyntheticChildrenSP(new ScriptedSyntheticChildren(stl_synth_flags,
-                                                                                                 "lldb.formatters.cpp.libcxx.stdmap_SynthProvider")));
+    AddCXXSynthetic(libcxx_category_sp, lldb_private::formatters::LibcxxStdVectorSyntheticFrontEndCreator, "libc++ std::vector synthetic children", ConstString("^std::__1::vector<.+>(( )?&)?$"), stl_synth_flags, true);
+    AddCXXSynthetic(libcxx_category_sp, lldb_private::formatters::LibcxxStdListSyntheticFrontEndCreator, "libc++ std::list synthetic children", ConstString("^std::__1::list<.+>(( )?&)?$"), stl_synth_flags, true);
+    AddCXXSynthetic(libcxx_category_sp, lldb_private::formatters::LibcxxStdMapSyntheticFrontEndCreator, "libc++ std::map synthetic children", ConstString("^std::__1::map<.+> >(( )?&)?$"), stl_synth_flags, true);
+
     libcxx_category_sp->GetRegexSyntheticNavigator()->Add(RegularExpressionSP(new RegularExpression("^(std::__1::)deque<.+>(( )?&)?$")),
                                                           SyntheticChildrenSP(new ScriptedSyntheticChildren(stl_synth_flags,
                                                                                                     "lldb.formatters.cpp.libcxx.stddeque_SynthProvider")));
-    libcxx_category_sp->GetRegexSyntheticNavigator()->Add(RegularExpressionSP(new RegularExpression("^(std::__1::)shared_ptr<.+>(( )?&)?$")),
-                                                          SyntheticChildrenSP(new ScriptedSyntheticChildren(stl_synth_flags,
-                                                                                                    "lldb.formatters.cpp.libcxx.stdsharedptr_SynthProvider")));
-    libcxx_category_sp->GetRegexSyntheticNavigator()->Add(RegularExpressionSP(new RegularExpression("^(std::__1::)weak_ptr<.+>(( )?&)?$")),
-                                                          SyntheticChildrenSP(new ScriptedSyntheticChildren(stl_synth_flags,
-                                                                                                    "lldb.formatters.cpp.libcxx.stdsharedptr_SynthProvider")));
+    
+    AddCXXSynthetic(libcxx_category_sp, lldb_private::formatters::LibcxxSharedPtrSyntheticFrontEndCreator, "shared_ptr synthetic children", ConstString("^(std::__1::)shared_ptr<.+>(( )?&)?$"), stl_synth_flags, true);
+    AddCXXSynthetic(libcxx_category_sp, lldb_private::formatters::LibcxxSharedPtrSyntheticFrontEndCreator, "weak_ptr synthetic children", ConstString("^(std::__1::)weak_ptr<.+>(( )?&)?$"), stl_synth_flags, true);
     
     stl_summary_flags.SetDontShowChildren(false);stl_summary_flags.SetSkipPointers(true);
     libcxx_category_sp->GetRegexSummaryNavigator()->Add(RegularExpressionSP(new RegularExpression("^std::__1::vector<.+>(( )?&)?$")),
diff --git a/source/DataFormatters/LibCxx.cpp b/source/DataFormatters/LibCxx.cpp
index 5074d17..28e596a 100644
--- a/source/DataFormatters/LibCxx.cpp
+++ b/source/DataFormatters/LibCxx.cpp
@@ -136,7 +136,7 @@
         m_count = 0;
         return false;
     }
-    return true;
+    return false;
 }
 
 bool
@@ -219,7 +219,7 @@
                                                      ValueObject::GetValueForExpressionPathOptions().DontCheckDotVsArrowSyntax().DontAllowSyntheticChildren(),
                                                      NULL).get();
     
-    return (m_pair_ptr != NULL);
+    return false;
 }
 
 size_t
@@ -285,3 +285,218 @@
         return NULL;
     return (new VectorIteratorSyntheticFrontEnd(valobj_sp,g_item_name));
 }
+
+lldb_private::formatters::LibcxxSharedPtrSyntheticFrontEnd::LibcxxSharedPtrSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) :
+SyntheticChildrenFrontEnd(*valobj_sp.get()),
+m_cntrl(NULL),
+m_count_sp(),
+m_weak_count_sp(),
+m_ptr_size(0),
+m_byte_order(lldb::eByteOrderInvalid)
+{
+    if (valobj_sp)
+        Update();
+}
+
+size_t
+lldb_private::formatters::LibcxxSharedPtrSyntheticFrontEnd::CalculateNumChildren ()
+{
+    return (m_cntrl ? 1 : 0);
+}
+
+lldb::ValueObjectSP
+lldb_private::formatters::LibcxxSharedPtrSyntheticFrontEnd::GetChildAtIndex (size_t idx)
+{
+    if (!m_cntrl)
+        return lldb::ValueObjectSP();
+
+    ValueObjectSP valobj_sp = m_backend.GetSP();
+    if (!valobj_sp)
+        return lldb::ValueObjectSP();
+
+    if (idx == 0)
+        return valobj_sp->GetChildMemberWithName(ConstString("__ptr_"), true);
+
+    if (idx > 2)
+        return lldb::ValueObjectSP();
+
+    if (idx == 1)
+    {
+        if (!m_count_sp)
+        {
+            ValueObjectSP shared_owners_sp(m_cntrl->GetChildMemberWithName(ConstString("__shared_owners_"),true));
+            if (!shared_owners_sp)
+                return lldb::ValueObjectSP();
+            uint64_t count = 1 + shared_owners_sp->GetValueAsUnsigned(0);
+            DataExtractor data(&count, 8, m_byte_order, m_ptr_size);
+            m_count_sp = ValueObject::CreateValueObjectFromData("count", data, valobj_sp->GetExecutionContextRef(), ClangASTType(shared_owners_sp->GetClangAST(), shared_owners_sp->GetClangType()));
+        }
+        return m_count_sp;
+    }
+    else /* if (idx == 2) */
+    {
+        if (!m_weak_count_sp)
+        {
+            ValueObjectSP shared_weak_owners_sp(m_cntrl->GetChildMemberWithName(ConstString("__shared_weak_owners_"),true));
+            if (!shared_weak_owners_sp)
+                return lldb::ValueObjectSP();
+            uint64_t count = 1 + shared_weak_owners_sp->GetValueAsUnsigned(0);
+            DataExtractor data(&count, 8, m_byte_order, m_ptr_size);
+            m_weak_count_sp = ValueObject::CreateValueObjectFromData("count", data, valobj_sp->GetExecutionContextRef(), ClangASTType(shared_weak_owners_sp->GetClangAST(), shared_weak_owners_sp->GetClangType()));
+        }
+        return m_weak_count_sp;
+    }
+}
+
+bool
+lldb_private::formatters::LibcxxSharedPtrSyntheticFrontEnd::Update()
+{
+    m_count_sp.reset();
+    m_weak_count_sp.reset();
+    m_cntrl = NULL;
+    
+    ValueObjectSP valobj_sp = m_backend.GetSP();
+    if (!valobj_sp)
+        return false;
+    
+    TargetSP target_sp(valobj_sp->GetTargetSP());
+    if (!target_sp)
+        return false;
+    
+    m_byte_order = target_sp->GetArchitecture().GetByteOrder();
+    m_ptr_size = target_sp->GetArchitecture().GetAddressByteSize();
+    
+    lldb::ValueObjectSP cntrl_sp(valobj_sp->GetChildMemberWithName(ConstString("__cntrl_"),true));
+    
+    m_cntrl = cntrl_sp.get(); // need to store the raw pointer to avoid a circular dependency
+    return false;
+}
+
+bool
+lldb_private::formatters::LibcxxSharedPtrSyntheticFrontEnd::MightHaveChildren ()
+{
+    return true;
+}
+
+size_t
+lldb_private::formatters::LibcxxSharedPtrSyntheticFrontEnd::GetIndexOfChildWithName (const ConstString &name)
+{
+    if (name == ConstString("__ptr_"))
+        return 0;
+    if (name == ConstString("count"))
+        return 1;
+    if (name == ConstString("weak_count"))
+        return 2;
+    return UINT32_MAX;
+}
+
+lldb_private::formatters::LibcxxSharedPtrSyntheticFrontEnd::~LibcxxSharedPtrSyntheticFrontEnd ()
+{}
+
+SyntheticChildrenFrontEnd*
+lldb_private::formatters::LibcxxSharedPtrSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP valobj_sp)
+{
+    if (!valobj_sp)
+        return NULL;
+    return (new LibcxxSharedPtrSyntheticFrontEnd(valobj_sp));
+}
+
+lldb_private::formatters::LibcxxStdVectorSyntheticFrontEnd::LibcxxStdVectorSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) :
+SyntheticChildrenFrontEnd(*valobj_sp.get()),
+m_start(NULL),
+m_finish(NULL),
+m_element_type(),
+m_element_size(0),
+m_children()
+{
+    if (valobj_sp)
+        Update();
+}
+
+size_t
+lldb_private::formatters::LibcxxStdVectorSyntheticFrontEnd::CalculateNumChildren ()
+{
+    if (!m_start || !m_finish)
+        return 0;
+    uint64_t start_val = m_start->GetValueAsUnsigned(0);
+    uint64_t finish_val = m_finish->GetValueAsUnsigned(0);
+
+    if (start_val == 0 || finish_val == 0)
+        return 0;
+    
+    if (start_val >= finish_val)
+        return 0;
+    
+    size_t num_children = (finish_val - start_val);
+    if (num_children % m_element_size)
+        return 0;
+    return num_children/m_element_size;
+}
+
+lldb::ValueObjectSP
+lldb_private::formatters::LibcxxStdVectorSyntheticFrontEnd::GetChildAtIndex (size_t idx)
+{
+    if (!m_start || !m_finish)
+        return lldb::ValueObjectSP();
+    
+    auto cached = m_children.find(idx);
+    if (cached != m_children.end())
+        return cached->second;
+    
+    uint64_t offset = idx * m_element_size;
+    offset = offset + m_start->GetValueAsUnsigned(0);
+    StreamString name;
+    name.Printf("[%zu]",idx);
+    ValueObjectSP child_sp = ValueObject::CreateValueObjectFromAddress(name.GetData(), offset, m_backend.GetExecutionContextRef(), m_element_type);
+    m_children[idx] = child_sp;
+    return child_sp;
+}
+
+bool
+lldb_private::formatters::LibcxxStdVectorSyntheticFrontEnd::Update()
+{
+    m_start = m_finish = NULL;
+    m_children.clear();
+    ValueObjectSP data_type_finder_sp(m_backend.GetChildMemberWithName(ConstString("__end_cap_"),true));
+    if (!data_type_finder_sp)
+        return false;
+    data_type_finder_sp = data_type_finder_sp->GetChildMemberWithName(ConstString("__first_"),true);
+    if (!data_type_finder_sp)
+        return false;
+    m_element_type = ClangASTType(data_type_finder_sp->GetClangAST(),data_type_finder_sp->GetClangType());
+    m_element_type.SetClangType(m_element_type.GetASTContext(), m_element_type.GetPointeeType());
+    m_element_size = m_element_type.GetTypeByteSize();
+    // store raw pointers or end up with a circular dependency
+    m_start = m_backend.GetChildMemberWithName(ConstString("__begin_"),true).get();
+    m_finish = m_backend.GetChildMemberWithName(ConstString("__end_"),true).get();
+    return false;
+}
+
+bool
+lldb_private::formatters::LibcxxStdVectorSyntheticFrontEnd::MightHaveChildren ()
+{
+    return true;
+}
+
+size_t
+lldb_private::formatters::LibcxxStdVectorSyntheticFrontEnd::GetIndexOfChildWithName (const ConstString &name)
+{
+    if (!m_start || !m_finish)
+        return UINT32_MAX;
+    return ExtractIndexFromString(name.GetCString());
+}
+
+lldb_private::formatters::LibcxxStdVectorSyntheticFrontEnd::~LibcxxStdVectorSyntheticFrontEnd ()
+{
+    // these need to stay around because they are child objects who will follow their parent's life cycle
+    // delete m_start;
+    // delete m_finish;
+}
+
+SyntheticChildrenFrontEnd*
+lldb_private::formatters::LibcxxStdVectorSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP valobj_sp)
+{
+    if (!valobj_sp)
+        return NULL;
+    return (new LibcxxStdVectorSyntheticFrontEnd(valobj_sp));
+}
diff --git a/source/DataFormatters/LibCxxList.cpp b/source/DataFormatters/LibCxxList.cpp
new file mode 100644
index 0000000..7bedd8f
--- /dev/null
+++ b/source/DataFormatters/LibCxxList.cpp
@@ -0,0 +1,288 @@
+//===-- LibCxxList.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/DataFormatters/CXXFormatterFunctions.h"
+
+#include "lldb/Core/DataBufferHeap.h"
+#include "lldb/Core/Error.h"
+#include "lldb/Core/Stream.h"
+#include "lldb/Core/ValueObject.h"
+#include "lldb/Core/ValueObjectConstResult.h"
+#include "lldb/Host/Endian.h"
+#include "lldb/Symbol/ClangASTContext.h"
+#include "lldb/Target/ObjCLanguageRuntime.h"
+#include "lldb/Target/Target.h"
+
+using namespace lldb;
+using namespace lldb_private;
+using namespace lldb_private::formatters;
+
+class ListEntry
+{
+public:
+    ListEntry () {}
+    ListEntry (ValueObjectSP entry_sp) : m_entry_sp(entry_sp) {}
+    ListEntry (const ListEntry& rhs) : m_entry_sp(rhs.m_entry_sp) {}
+    ListEntry (ValueObject* entry) : m_entry_sp(entry ? entry->GetSP() : ValueObjectSP()) {}
+    
+    ValueObjectSP
+    next ()
+    {
+        if (!m_entry_sp)
+            return m_entry_sp;
+        return m_entry_sp->GetChildMemberWithName(ConstString("__next_"), true);
+    }
+    
+    ValueObjectSP
+    prev ()
+    {
+        if (!m_entry_sp)
+            return m_entry_sp;
+        return m_entry_sp->GetChildMemberWithName(ConstString("__prev_"), true);
+    }
+    
+    uint64_t
+    value ()
+    {
+        if (!m_entry_sp)
+            return 0;
+        return m_entry_sp->GetValueAsUnsigned(0);
+    }
+
+    bool
+    null()
+    {
+        return (value() == 0);
+    }
+    
+    ValueObjectSP
+    GetEntry ()
+    {
+        return m_entry_sp;
+    }
+    
+    void
+    SetEntry (ValueObjectSP entry)
+    {
+        m_entry_sp = entry;
+    }
+    
+    bool
+    operator == (const ListEntry& rhs) const
+    {
+        return (rhs.m_entry_sp.get() == m_entry_sp.get());
+    }
+    
+private:
+    ValueObjectSP m_entry_sp;
+};
+
+class ListIterator
+{
+public:
+    ListIterator () {}
+    ListIterator (ListEntry entry) : m_entry(entry) {}
+    ListIterator (ValueObjectSP entry) : m_entry(entry) {}
+    ListIterator (const ListIterator& rhs) : m_entry(rhs.m_entry) {}
+    ListIterator (ValueObject* entry) : m_entry(entry) {}
+
+    ValueObjectSP
+    value ()
+    {
+        return m_entry.GetEntry();
+    }
+    
+    ValueObjectSP
+    advance (size_t count)
+    {
+        if (count == 0)
+            return m_entry.GetEntry();
+        if (count == 1)
+        {
+            next ();
+            return m_entry.GetEntry();
+        }
+        while (count > 0)
+        {
+            next ();
+            count--;
+            if (m_entry.null())
+                return lldb::ValueObjectSP();
+        }
+        return m_entry.GetEntry();
+    }
+    
+    bool
+    operator == (const ListIterator& rhs) const
+    {
+        return (rhs.m_entry == m_entry);
+    }
+    
+protected:
+    void
+    next ()
+    {
+        m_entry.SetEntry(m_entry.next());
+    }
+    
+    void
+    prev ()
+    {
+        m_entry.SetEntry(m_entry.prev());
+    }
+private:
+    ListEntry m_entry;
+};
+
+lldb_private::formatters::LibcxxStdListSyntheticFrontEnd::LibcxxStdListSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) :
+SyntheticChildrenFrontEnd(*valobj_sp.get()),
+m_node_address(),
+m_head(NULL),
+m_tail(NULL),
+m_element_type(),
+m_element_size(0),
+m_count(UINT32_MAX),
+m_children()
+{
+    if (valobj_sp)
+        Update();
+}
+
+bool
+lldb_private::formatters::LibcxxStdListSyntheticFrontEnd::HasLoop()
+{
+    if (g_use_loop_detect == false)
+        return false;
+    ListEntry slow(m_head);
+    ListEntry fast1(m_head);
+    ListEntry fast2(m_head);
+    while (slow.next() && slow.next()->GetValueAsUnsigned(0) != m_node_address)
+    {
+        auto slow_value = slow.value();
+        fast1.SetEntry(fast2.next());
+        fast2.SetEntry(fast1.next());
+        if (fast1.value() == slow_value || fast2.value() == slow_value)
+            return true;
+        slow.SetEntry(slow.next());
+    }
+    return false;
+}
+
+size_t
+lldb_private::formatters::LibcxxStdListSyntheticFrontEnd::CalculateNumChildren ()
+{
+    if (m_count != UINT32_MAX)
+        return m_count;
+    if (!m_head || !m_tail || m_node_address == 0)
+        return 0;
+    uint64_t next_val = m_head->GetValueAsUnsigned(0);
+    uint64_t prev_val = m_tail->GetValueAsUnsigned(0);
+    if (next_val == 0 || prev_val == 0)
+        return 0;
+    if (next_val == m_node_address)
+        return 0;
+    if (next_val == prev_val)
+        return 1;
+    if (HasLoop())
+        return 0;
+    uint64_t size = 2;
+    ListEntry current(m_head);
+    while (current.next() && current.next()->GetValueAsUnsigned(0) != m_node_address)
+    {
+        size++;
+        current.SetEntry(current.next());
+        if (size > g_list_capping_size)
+            break;
+    }
+    return m_count = (size-1);
+}
+
+lldb::ValueObjectSP
+lldb_private::formatters::LibcxxStdListSyntheticFrontEnd::GetChildAtIndex (size_t idx)
+{
+    if (idx >= CalculateNumChildren())
+        return lldb::ValueObjectSP();
+    
+    if (!m_head || !m_tail || m_node_address == 0)
+        return lldb::ValueObjectSP();
+    
+    auto cached = m_children.find(idx);
+    if (cached != m_children.end())
+        return cached->second;
+    
+    ListIterator current(m_head);
+    ValueObjectSP current_sp(current.advance(idx));
+    if (!current_sp)
+        return lldb::ValueObjectSP();
+    current_sp = current_sp->GetChildMemberWithName(ConstString("__value_"), true);
+    if (!current_sp)
+        return lldb::ValueObjectSP();
+    // we need to copy current_sp into a new object otherwise we will end up with all items named __value_
+    DataExtractor data;
+    current_sp->GetData(data);
+    StreamString name;
+    name.Printf("[%zu]",idx);
+    return (m_children[idx] = ValueObject::CreateValueObjectFromData(name.GetData(), data, m_backend.GetExecutionContextRef(), m_element_type));
+}
+
+bool
+lldb_private::formatters::LibcxxStdListSyntheticFrontEnd::Update()
+{
+    m_head = m_tail = NULL;
+    m_node_address = 0;
+    m_count = UINT32_MAX;
+    Error err;
+    ValueObjectSP backend_addr(m_backend.AddressOf(err));
+    if (err.Fail() || backend_addr.get() == NULL)
+        return false;
+    m_node_address = backend_addr->GetValueAsUnsigned(0);
+    if (!m_node_address || m_node_address == LLDB_INVALID_ADDRESS)
+        return false;
+    ValueObjectSP impl_sp(m_backend.GetChildMemberWithName(ConstString("__end_"),true));
+    if (!impl_sp)
+        return false;
+    auto list_type = m_backend.GetClangType();
+    if (ClangASTContext::IsReferenceType(list_type))
+    {
+        clang::QualType qt = clang::QualType::getFromOpaquePtr(list_type);
+        list_type = qt.getNonReferenceType().getAsOpaquePtr();
+    }
+    if (ClangASTContext::GetNumTemplateArguments(m_backend.GetClangAST(), list_type) == 0)
+        return false;
+    lldb::TemplateArgumentKind kind;
+    m_element_type = ClangASTType(m_backend.GetClangAST(), ClangASTContext::GetTemplateArgument(m_backend.GetClangAST(), list_type, 0, kind));
+    m_element_size = m_element_type.GetTypeByteSize();
+    m_head = impl_sp->GetChildMemberWithName(ConstString("__next_"), true).get();
+    m_tail = impl_sp->GetChildMemberWithName(ConstString("__prev_"), true).get();
+    return false;
+}
+
+bool
+lldb_private::formatters::LibcxxStdListSyntheticFrontEnd::MightHaveChildren ()
+{
+    return true;
+}
+
+size_t
+lldb_private::formatters::LibcxxStdListSyntheticFrontEnd::GetIndexOfChildWithName (const ConstString &name)
+{
+    return ExtractIndexFromString(name.GetCString());
+}
+
+lldb_private::formatters::LibcxxStdListSyntheticFrontEnd::~LibcxxStdListSyntheticFrontEnd ()
+{}
+
+SyntheticChildrenFrontEnd*
+lldb_private::formatters::LibcxxStdListSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP valobj_sp)
+{
+    if (!valobj_sp)
+        return NULL;
+    return (new LibcxxStdListSyntheticFrontEnd(valobj_sp));
+}
+
diff --git a/source/DataFormatters/LibCxxMap.cpp b/source/DataFormatters/LibCxxMap.cpp
new file mode 100644
index 0000000..2ffeb4b
--- /dev/null
+++ b/source/DataFormatters/LibCxxMap.cpp
@@ -0,0 +1,384 @@
+//===-- LibCxxList.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/DataFormatters/CXXFormatterFunctions.h"
+
+#include "lldb/Core/DataBufferHeap.h"
+#include "lldb/Core/Error.h"
+#include "lldb/Core/Stream.h"
+#include "lldb/Core/ValueObject.h"
+#include "lldb/Core/ValueObjectConstResult.h"
+#include "lldb/Host/Endian.h"
+#include "lldb/Symbol/ClangASTContext.h"
+#include "lldb/Target/ObjCLanguageRuntime.h"
+#include "lldb/Target/Target.h"
+
+using namespace lldb;
+using namespace lldb_private;
+using namespace lldb_private::formatters;
+
+class MapEntry
+{
+public:
+    MapEntry () {}
+    MapEntry (ValueObjectSP entry_sp) : m_entry_sp(entry_sp) {}
+    MapEntry (const MapEntry& rhs) : m_entry_sp(rhs.m_entry_sp) {}
+    MapEntry (ValueObject* entry) : m_entry_sp(entry ? entry->GetSP() : ValueObjectSP()) {}
+    
+    ValueObjectSP
+    left ()
+    {
+        if (!m_entry_sp)
+            return m_entry_sp;
+        return m_entry_sp->GetChildMemberWithName(ConstString("__left_"), true);
+    }
+    
+    ValueObjectSP
+    right ()
+    {
+        if (!m_entry_sp)
+            return m_entry_sp;
+        return m_entry_sp->GetChildMemberWithName(ConstString("__right_"), true);
+    }
+    
+    ValueObjectSP
+    parent ()
+    {
+        if (!m_entry_sp)
+            return m_entry_sp;
+        return m_entry_sp->GetChildMemberWithName(ConstString("__parent_"), true);
+    }
+    
+    uint64_t
+    value ()
+    {
+        if (!m_entry_sp)
+            return 0;
+        return m_entry_sp->GetValueAsUnsigned(0);
+    }
+    
+    bool
+    null()
+    {
+        return (value() == 0);
+    }
+    
+    ValueObjectSP
+    GetEntry ()
+    {
+        return m_entry_sp;
+    }
+    
+    void
+    SetEntry (ValueObjectSP entry)
+    {
+        m_entry_sp = entry;
+    }
+    
+    bool
+    operator == (const MapEntry& rhs) const
+    {
+        return (rhs.m_entry_sp.get() == m_entry_sp.get());
+    }
+    
+private:
+    ValueObjectSP m_entry_sp;
+};
+
+class MapIterator
+{
+public:
+    MapIterator () {}
+    MapIterator (MapEntry entry, size_t depth = 0) : m_entry(entry), m_max_depth(depth) {}
+    MapIterator (ValueObjectSP entry, size_t depth = 0) : m_entry(entry), m_max_depth(depth) {}
+    MapIterator (const MapIterator& rhs) : m_entry(rhs.m_entry),m_max_depth(rhs.m_max_depth) {}
+    MapIterator (ValueObject* entry, size_t depth = 0) : m_entry(entry), m_max_depth(depth) {}
+    
+    ValueObjectSP
+    value ()
+    {
+        return m_entry.GetEntry();
+    }
+    
+    ValueObjectSP
+    advance (size_t count)
+    {
+        if (count == 0)
+            return m_entry.GetEntry();
+        if (count == 1)
+        {
+            next ();
+            return m_entry.GetEntry();
+        }
+        size_t steps = 0;
+        while (count > 0)
+        {
+            next ();
+            count--;
+            if (m_entry.null())
+                return lldb::ValueObjectSP();
+            steps++;
+            if (steps > m_max_depth)
+                return lldb::ValueObjectSP();
+        }
+        return m_entry.GetEntry();
+    }
+protected:
+    void
+    next ()
+    {
+        m_entry.SetEntry(increment(m_entry.GetEntry()));
+    }
+
+private:
+    ValueObjectSP
+    tree_min (ValueObjectSP x_sp)
+    {
+        MapEntry x(x_sp);
+        if (x.null())
+            return ValueObjectSP();
+        MapEntry left(x.left());
+        size_t steps = 0;
+        while (left.null() == false)
+        {
+            x.SetEntry(left.GetEntry());
+            left.SetEntry(x.left());
+            steps++;
+            if (steps > m_max_depth)
+                return lldb::ValueObjectSP();
+        }
+        return x.GetEntry();
+    }
+    
+    ValueObjectSP
+    tree_max (ValueObjectSP x_sp)
+    {
+        MapEntry x(x_sp);
+        if (x.null())
+            return ValueObjectSP();
+        MapEntry right(x.right());
+        size_t steps = 0;
+        while (right.null() == false)
+        {
+            x.SetEntry(right.GetEntry());
+            right.SetEntry(x.right());
+            steps++;
+            if (steps > m_max_depth)
+                return lldb::ValueObjectSP();
+        }
+        return x.GetEntry();
+    }
+    
+    bool
+    is_left_child (ValueObjectSP x_sp)
+    {
+        MapEntry x(x_sp);
+        if (x.null())
+            return false;
+        MapEntry rhs(x.parent());
+        rhs.SetEntry(rhs.left());
+        return x.value() == rhs.value();
+    }
+    
+    ValueObjectSP
+    increment (ValueObjectSP x_sp)
+    {
+        MapEntry node(x_sp);
+        if (node.null())
+            return ValueObjectSP();
+        MapEntry right(node.right());
+        if (right.null() == false)
+            return tree_min(right.GetEntry());
+        size_t steps = 0;
+        while (!is_left_child(node.GetEntry()))
+        {
+            node.SetEntry(node.parent());
+            steps++;
+            if (steps > m_max_depth)
+                return lldb::ValueObjectSP();
+        }
+        return node.parent();
+    }
+        
+    MapEntry m_entry;
+    size_t m_max_depth;
+};
+
+lldb_private::formatters::LibcxxStdMapSyntheticFrontEnd::LibcxxStdMapSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) :
+SyntheticChildrenFrontEnd(*valobj_sp.get()),
+m_tree(NULL),
+m_root_node(NULL),
+m_element_type(),
+m_element_size(0),
+m_skip_size(UINT32_MAX),
+m_count(UINT32_MAX),
+m_children()
+{
+    if (valobj_sp)
+        Update();
+}
+
+size_t
+lldb_private::formatters::LibcxxStdMapSyntheticFrontEnd::CalculateNumChildren ()
+{
+    if (m_count != UINT32_MAX)
+        return m_count;
+    if (m_tree == NULL)
+        return 0;
+    ValueObjectSP m_item(m_tree->GetChildMemberWithName(ConstString("__pair3_"), true));
+    if (!m_item)
+        return 0;
+    m_item = m_item->GetChildMemberWithName(ConstString("__first_"), true);
+    if (!m_item)
+        return 0;
+    m_count = m_item->GetValueAsUnsigned(0);
+    return m_count;
+}
+
+bool
+lldb_private::formatters::LibcxxStdMapSyntheticFrontEnd::GetDataType()
+{
+    if (m_element_type.GetOpaqueQualType() && m_element_type.GetASTContext())
+        return true;
+    m_element_type.Clear();
+    ValueObjectSP deref;
+    Error error;
+    deref = m_root_node->Dereference(error);
+    if (!deref || error.Fail())
+        return false;
+    deref = deref->GetChildMemberWithName(ConstString("__value_"), true);
+    if (!deref)
+        return false;
+    m_element_type.SetClangType(deref->GetClangAST(), deref->GetClangType());
+    m_element_size = m_element_type.GetTypeByteSize();
+    return true;
+}
+
+void
+lldb_private::formatters::LibcxxStdMapSyntheticFrontEnd::GetValueOffset (const lldb::ValueObjectSP& node)
+{
+    if (m_skip_size != UINT32_MAX)
+        return;
+    if (!node)
+        return;
+    ClangASTType node_type(node->GetClangAST(),node->GetClangType());
+    uint64_t bit_offset;
+    if (ClangASTContext::GetIndexOfFieldWithName(node->GetClangAST(),node->GetClangType(),"__value_",NULL,&bit_offset) == UINT32_MAX)
+        return;
+    m_skip_size = bit_offset / 8u;
+}
+
+lldb::ValueObjectSP
+lldb_private::formatters::LibcxxStdMapSyntheticFrontEnd::GetChildAtIndex (size_t idx)
+{
+    if (idx >= CalculateNumChildren())
+        return lldb::ValueObjectSP();
+    if (m_tree == NULL || m_root_node == NULL)
+        return lldb::ValueObjectSP();
+    
+    auto cached = m_children.find(idx);
+    if (cached != m_children.end())
+        return cached->second;
+    
+    bool need_to_skip = (idx > 0);
+    MapIterator iterator(m_root_node, CalculateNumChildren());
+    ValueObjectSP iterated_sp(iterator.advance(idx));
+    if (iterated_sp.get() == NULL)
+    {
+        // this tree is garbage - stop
+        m_tree = NULL; // this will stop all future searches until an Update() happens
+        return iterated_sp;
+    }
+    if (GetDataType())
+    {
+        if (!need_to_skip)
+        {
+            Error error;
+            iterated_sp = iterated_sp->Dereference(error);
+            if (!iterated_sp || error.Fail())
+            {
+                m_tree = NULL;
+                return lldb::ValueObjectSP();
+            }
+            GetValueOffset(iterated_sp);
+            iterated_sp = iterated_sp->GetChildMemberWithName(ConstString("__value_"), true);
+            if (!iterated_sp)
+            {
+                m_tree = NULL;
+                return lldb::ValueObjectSP();
+            }
+        }
+        else
+        {
+            // because of the way our debug info is made, we need to read item 0 first
+            // so that we can cache information used to generate other elements
+            if (m_skip_size == UINT32_MAX)
+                GetChildAtIndex(0);
+            if (m_skip_size == UINT32_MAX)
+            {
+                m_tree = NULL;
+                return lldb::ValueObjectSP();
+            }
+            iterated_sp = iterated_sp->GetSyntheticChildAtOffset(m_skip_size, m_element_type, true);
+            if (!iterated_sp)
+            {
+                m_tree = NULL;
+                return lldb::ValueObjectSP();
+            }
+        }
+    }
+    else
+    {
+        m_tree = NULL;
+        return lldb::ValueObjectSP();
+    }
+    // at this point we have a valid 
+    // we need to copy current_sp into a new object otherwise we will end up with all items named __value_
+    DataExtractor data;
+    iterated_sp->GetData(data);
+    StreamString name;
+    name.Printf("[%zu]",idx);
+    return (m_children[idx] = ValueObject::CreateValueObjectFromData(name.GetData(), data, m_backend.GetExecutionContextRef(), m_element_type));
+}
+
+bool
+lldb_private::formatters::LibcxxStdMapSyntheticFrontEnd::Update()
+{
+    m_count = UINT32_MAX;
+    m_tree = m_root_node = NULL;
+    m_children.clear();
+    m_tree = m_backend.GetChildMemberWithName(ConstString("__tree_"), true).get();
+    if (!m_tree)
+        return NULL;
+    m_root_node = m_tree->GetChildMemberWithName(ConstString("__begin_node_"), true).get();
+    return false;
+}
+
+bool
+lldb_private::formatters::LibcxxStdMapSyntheticFrontEnd::MightHaveChildren ()
+{
+    return true;
+}
+
+size_t
+lldb_private::formatters::LibcxxStdMapSyntheticFrontEnd::GetIndexOfChildWithName (const ConstString &name)
+{
+    return ExtractIndexFromString(name.GetCString());
+}
+
+lldb_private::formatters::LibcxxStdMapSyntheticFrontEnd::~LibcxxStdMapSyntheticFrontEnd ()
+{}
+
+SyntheticChildrenFrontEnd*
+lldb_private::formatters::LibcxxStdMapSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP valobj_sp)
+{
+    if (!valobj_sp)
+        return NULL;
+    return (new LibcxxStdMapSyntheticFrontEnd(valobj_sp));
+}
diff --git a/source/DataFormatters/TypeSynthetic.cpp b/source/DataFormatters/TypeSynthetic.cpp
index b0d4cda..d8e94a5 100644
--- a/source/DataFormatters/TypeSynthetic.cpp
+++ b/source/DataFormatters/TypeSynthetic.cpp
@@ -53,7 +53,7 @@
 CXXSyntheticChildren::GetDescription()
 {
     StreamString sstr;
-    sstr.Printf("%s%s%s Generator at %p - %s\n",
+    sstr.Printf("%s%s%s Generator at %p - %s",
                 Cascades() ? "" : " (not cascading)",
                 SkipsPointers() ? " (skip pointers)" : "",
                 SkipsReferences() ? " (skip references)" : "",
diff --git a/source/Symbol/ClangASTContext.cpp b/source/Symbol/ClangASTContext.cpp
index 28679b9..69e22c3 100644
--- a/source/Symbol/ClangASTContext.cpp
+++ b/source/Symbol/ClangASTContext.cpp
@@ -3673,6 +3673,31 @@
     return NULL;
 }
 
+size_t
+ClangASTContext::GetIndexOfFieldWithName (clang::ASTContext *ast,
+                                          lldb::clang_type_t clang_type,
+                                          const char* name,
+                                          lldb::clang_type_t* field_clang_type,
+                                          uint64_t *bit_offset_ptr,
+                                          uint32_t *bitfield_bit_size_ptr,
+                                          bool *is_bitfield_ptr)
+{
+    auto count = ClangASTContext::GetNumFields(ast, clang_type);
+    lldb::clang_type_t field_clang_type_internal;
+    std::string field_name;
+    for (auto index = 0; index < count; index++)
+    {
+        field_clang_type_internal = ClangASTContext::GetFieldAtIndex(ast, clang_type, index, field_name, bit_offset_ptr, bitfield_bit_size_ptr, is_bitfield_ptr);
+        if ( strcmp(field_name.c_str(), name) == 0 )
+        {
+            if (field_clang_type)
+                *field_clang_type = field_clang_type_internal;
+            return index;
+        }
+    }
+    return UINT32_MAX;
+}
+
 lldb::BasicType
 ClangASTContext::GetLLDBBasicTypeEnumeration (clang_type_t clang_type)
 {