diff --git a/lldb/examples/summaries/cocoa/CFArray.py b/lldb/examples/summaries/cocoa/CFArray.py
index 5068875..6fc9708 100644
--- a/lldb/examples/summaries/cocoa/CFArray.py
+++ b/lldb/examples/summaries/cocoa/CFArray.py
@@ -22,183 +22,212 @@
 # much less functional than the other two cases below
 # just runs code to get to the count and then returns
 # no children
+
+
 class NSArrayKVC_SynthProvider:
 
-	def adjust_for_architecture(self):
-		pass
+    def adjust_for_architecture(self):
+        pass
 
-	def __init__(self, valobj, dict, params):
-		logger = lldb.formatters.Logger.Logger()
-		self.valobj = valobj;
-		self.update()
+    def __init__(self, valobj, dict, params):
+        logger = lldb.formatters.Logger.Logger()
+        self.valobj = valobj
+        self.update()
 
-	def update(self):
-		logger = lldb.formatters.Logger.Logger()
-		self.adjust_for_architecture();
+    def update(self):
+        logger = lldb.formatters.Logger.Logger()
+        self.adjust_for_architecture()
 
-	def num_children(self):
-		logger = lldb.formatters.Logger.Logger()
-		stream = lldb.SBStream()
-		self.valobj.GetExpressionPath(stream)
-		num_children_vo = self.valobj.CreateValueFromExpression("count","(int)[" + stream.GetData() + " count]");
-		if num_children_vo.IsValid():
-			return num_children_vo.GetValueAsUnsigned(0)
-		return "<variable is not NSArray>"
+    def num_children(self):
+        logger = lldb.formatters.Logger.Logger()
+        stream = lldb.SBStream()
+        self.valobj.GetExpressionPath(stream)
+        num_children_vo = self.valobj.CreateValueFromExpression(
+            "count", "(int)[" + stream.GetData() + " count]")
+        if num_children_vo.IsValid():
+            return num_children_vo.GetValueAsUnsigned(0)
+        return "<variable is not NSArray>"
 
 # much less functional than the other two cases below
 # just runs code to get to the count and then returns
 # no children
+
+
 class NSArrayCF_SynthProvider:
 
-	def adjust_for_architecture(self):
-		pass
+    def adjust_for_architecture(self):
+        pass
 
-	def __init__(self, valobj, dict, params):
-		logger = lldb.formatters.Logger.Logger()
-		self.valobj = valobj;
-		self.sys_params = params
-		if not (self.sys_params.types_cache.ulong):
-			self.sys_params.types_cache.ulong = self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedLong)
-		self.update()
+    def __init__(self, valobj, dict, params):
+        logger = lldb.formatters.Logger.Logger()
+        self.valobj = valobj
+        self.sys_params = params
+        if not (self.sys_params.types_cache.ulong):
+            self.sys_params.types_cache.ulong = self.valobj.GetType(
+            ).GetBasicType(lldb.eBasicTypeUnsignedLong)
+        self.update()
 
-	def update(self):
-		logger = lldb.formatters.Logger.Logger()
-		self.adjust_for_architecture();
+    def update(self):
+        logger = lldb.formatters.Logger.Logger()
+        self.adjust_for_architecture()
 
-	def num_children(self):
-		logger = lldb.formatters.Logger.Logger()
-		num_children_vo = self.valobj.CreateChildAtOffset("count",
-							self.sys_params.cfruntime_size,
-							self.sys_params.types_cache.ulong)
-		return num_children_vo.GetValueAsUnsigned(0)
+    def num_children(self):
+        logger = lldb.formatters.Logger.Logger()
+        num_children_vo = self.valobj.CreateChildAtOffset(
+            "count", self.sys_params.cfruntime_size, self.sys_params.types_cache.ulong)
+        return num_children_vo.GetValueAsUnsigned(0)
+
 
 class NSArrayI_SynthProvider:
-	def adjust_for_architecture(self):
-		pass
 
-	def __init__(self, valobj, dict, params):
-		logger = lldb.formatters.Logger.Logger()
-		self.valobj = valobj;
-		self.sys_params = params
-		if not(self.sys_params.types_cache.long):
-			self.sys_params.types_cache.long = self.valobj.GetType().GetBasicType(lldb.eBasicTypeLong)
-		self.update()
+    def adjust_for_architecture(self):
+        pass
 
-	def update(self):
-		logger = lldb.formatters.Logger.Logger()
-		self.adjust_for_architecture();
+    def __init__(self, valobj, dict, params):
+        logger = lldb.formatters.Logger.Logger()
+        self.valobj = valobj
+        self.sys_params = params
+        if not(self.sys_params.types_cache.long):
+            self.sys_params.types_cache.long = self.valobj.GetType(
+            ).GetBasicType(lldb.eBasicTypeLong)
+        self.update()
 
-	# skip the isa pointer and get at the size
-	def num_children(self):
-		logger = lldb.formatters.Logger.Logger()
-		count = self.valobj.CreateChildAtOffset("count",
-				self.sys_params.pointer_size,
-				self.sys_params.types_cache.long);
-		return count.GetValueAsUnsigned(0)
+    def update(self):
+        logger = lldb.formatters.Logger.Logger()
+        self.adjust_for_architecture()
+
+    # skip the isa pointer and get at the size
+    def num_children(self):
+        logger = lldb.formatters.Logger.Logger()
+        count = self.valobj.CreateChildAtOffset(
+            "count",
+            self.sys_params.pointer_size,
+            self.sys_params.types_cache.long)
+        return count.GetValueAsUnsigned(0)
+
 
 class NSArrayM_SynthProvider:
-	def adjust_for_architecture(self):
-		pass
 
-	def __init__(self, valobj, dict, params):
-		logger = lldb.formatters.Logger.Logger()
-		self.valobj = valobj;
-		self.sys_params = params
-		if not(self.sys_params.types_cache.long):
-			self.sys_params.types_cache.long = self.valobj.GetType().GetBasicType(lldb.eBasicTypeLong)
-		self.update()
+    def adjust_for_architecture(self):
+        pass
 
-	def update(self):
-		logger = lldb.formatters.Logger.Logger()
-		self.adjust_for_architecture();
+    def __init__(self, valobj, dict, params):
+        logger = lldb.formatters.Logger.Logger()
+        self.valobj = valobj
+        self.sys_params = params
+        if not(self.sys_params.types_cache.long):
+            self.sys_params.types_cache.long = self.valobj.GetType(
+            ).GetBasicType(lldb.eBasicTypeLong)
+        self.update()
 
-	# skip the isa pointer and get at the size
-	def num_children(self):
-		logger = lldb.formatters.Logger.Logger()
-		count = self.valobj.CreateChildAtOffset("count",
-				self.sys_params.pointer_size,
-				self.sys_params.types_cache.long);
-		return count.GetValueAsUnsigned(0)
+    def update(self):
+        logger = lldb.formatters.Logger.Logger()
+        self.adjust_for_architecture()
+
+    # skip the isa pointer and get at the size
+    def num_children(self):
+        logger = lldb.formatters.Logger.Logger()
+        count = self.valobj.CreateChildAtOffset(
+            "count",
+            self.sys_params.pointer_size,
+            self.sys_params.types_cache.long)
+        return count.GetValueAsUnsigned(0)
 
 # this is the actual synth provider, but is just a wrapper that checks
 # whether valobj is an instance of __NSArrayI or __NSArrayM and sets up an
-# appropriate backend layer to do the computations 
+# appropriate backend layer to do the computations
+
+
 class NSArray_SynthProvider:
-	def adjust_for_architecture(self):
-		pass
 
-	def __init__(self, valobj, dict):
-		logger = lldb.formatters.Logger.Logger()
-		self.valobj = valobj;
-		self.adjust_for_architecture()
-		self.error = False
-		self.wrapper = self.make_wrapper()
-		self.invalid = (self.wrapper == None)
+    def adjust_for_architecture(self):
+        pass
 
-	def num_children(self):
-		logger = lldb.formatters.Logger.Logger()
-		if self.wrapper == None:
-			return 0;
-		return self.wrapper.num_children()
+    def __init__(self, valobj, dict):
+        logger = lldb.formatters.Logger.Logger()
+        self.valobj = valobj
+        self.adjust_for_architecture()
+        self.error = False
+        self.wrapper = self.make_wrapper()
+        self.invalid = (self.wrapper is None)
 
-	def update(self):
-		logger = lldb.formatters.Logger.Logger()
-		if self.wrapper == None:
-			return
-		self.wrapper.update()
+    def num_children(self):
+        logger = lldb.formatters.Logger.Logger()
+        if self.wrapper is None:
+            return 0
+        return self.wrapper.num_children()
 
-	# this code acts as our defense against NULL and uninitialized
-	# NSArray pointers, which makes it much longer than it would be otherwise
-	def make_wrapper(self):
-		logger = lldb.formatters.Logger.Logger()
-		if self.valobj.GetValueAsUnsigned() == 0:
-			self.error = True
-			return lldb.runtime.objc.objc_runtime.InvalidPointer_Description(True)
-		else:
-			global statistics
-			class_data,wrapper =lldb.runtime.objc.objc_runtime.Utilities.prepare_class_detection(self.valobj,statistics)
-			if wrapper:
-				self.error = True
-				return wrapper
-		
-		name_string = class_data.class_name()
-		
-		logger >> "Class name is " + str(name_string)
-		
-		if name_string == '__NSArrayI':
-			wrapper = NSArrayI_SynthProvider(self.valobj, dict, class_data.sys_params)
-			statistics.metric_hit('code_notrun',self.valobj.GetName())
-		elif name_string == '__NSArrayM':
-			wrapper = NSArrayM_SynthProvider(self.valobj, dict, class_data.sys_params)
-			statistics.metric_hit('code_notrun',self.valobj.GetName())
-		elif name_string == '__NSCFArray':
-			wrapper = NSArrayCF_SynthProvider(self.valobj, dict, class_data.sys_params)
-			statistics.metric_hit('code_notrun',self.valobj.GetName())
-		else:
-			wrapper = NSArrayKVC_SynthProvider(self.valobj, dict, class_data.sys_params)
-			statistics.metric_hit('unknown_class',str(self.valobj.GetName()) + " seen as " + name_string)
-		return wrapper;
+    def update(self):
+        logger = lldb.formatters.Logger.Logger()
+        if self.wrapper is None:
+            return
+        self.wrapper.update()
 
-def CFArray_SummaryProvider (valobj,dict):
-	logger = lldb.formatters.Logger.Logger()
-	provider = NSArray_SynthProvider(valobj,dict);
-	if provider.invalid == False:
-		if provider.error == True:
-			return provider.wrapper.message()
-		try:
-			summary = int(provider.num_children());
-		except:
-			summary = None
-		logger >> "provider gave me " + str(summary)
-		if summary == None:
-			summary = '<variable is not NSArray>'
-		elif isinstance(summary,basestring):
-			pass
-		else:
-			# we format it like it were a CFString to make it look the same as the summary from Xcode
-			summary = '@"' + str(summary) + (" objects" if summary != 1 else " object") + '"'
-		return summary
-	return 'Summary Unavailable'
+    # this code acts as our defense against NULL and uninitialized
+    # NSArray pointers, which makes it much longer than it would be otherwise
+    def make_wrapper(self):
+        logger = lldb.formatters.Logger.Logger()
+        if self.valobj.GetValueAsUnsigned() == 0:
+            self.error = True
+            return lldb.runtime.objc.objc_runtime.InvalidPointer_Description(
+                True)
+        else:
+            global statistics
+            class_data, wrapper = lldb.runtime.objc.objc_runtime.Utilities.prepare_class_detection(
+                self.valobj, statistics)
+            if wrapper:
+                self.error = True
+                return wrapper
 
-def __lldb_init_module(debugger,dict):
-	debugger.HandleCommand("type summary add -F CFArray.CFArray_SummaryProvider NSArray CFArrayRef CFMutableArrayRef")
+        name_string = class_data.class_name()
+
+        logger >> "Class name is " + str(name_string)
+
+        if name_string == '__NSArrayI':
+            wrapper = NSArrayI_SynthProvider(
+                self.valobj, dict, class_data.sys_params)
+            statistics.metric_hit('code_notrun', self.valobj.GetName())
+        elif name_string == '__NSArrayM':
+            wrapper = NSArrayM_SynthProvider(
+                self.valobj, dict, class_data.sys_params)
+            statistics.metric_hit('code_notrun', self.valobj.GetName())
+        elif name_string == '__NSCFArray':
+            wrapper = NSArrayCF_SynthProvider(
+                self.valobj, dict, class_data.sys_params)
+            statistics.metric_hit('code_notrun', self.valobj.GetName())
+        else:
+            wrapper = NSArrayKVC_SynthProvider(
+                self.valobj, dict, class_data.sys_params)
+            statistics.metric_hit(
+                'unknown_class', str(
+                    self.valobj.GetName()) + " seen as " + name_string)
+        return wrapper
+
+
+def CFArray_SummaryProvider(valobj, dict):
+    logger = lldb.formatters.Logger.Logger()
+    provider = NSArray_SynthProvider(valobj, dict)
+    if not provider.invalid:
+        if provider.error:
+            return provider.wrapper.message()
+        try:
+            summary = int(provider.num_children())
+        except:
+            summary = None
+        logger >> "provider gave me " + str(summary)
+        if summary is None:
+            summary = '<variable is not NSArray>'
+        elif isinstance(summary, basestring):
+            pass
+        else:
+            # we format it like it were a CFString to make it look the same as
+            # the summary from Xcode
+            summary = '@"' + str(summary) + \
+                (" objects" if summary != 1 else " object") + '"'
+        return summary
+    return 'Summary Unavailable'
+
+
+def __lldb_init_module(debugger, dict):
+    debugger.HandleCommand(
+        "type summary add -F CFArray.CFArray_SummaryProvider NSArray CFArrayRef CFMutableArrayRef")
