diff --git a/linux-ramdump-parser-v2/parsers/ipc_logging.py b/linux-ramdump-parser-v2/parsers/ipc_logging.py
index b360c163a41830cf8ae2f915c8ab89a2e39b6d4e..e67b14eb984c3cfdd6bab6f10eed03ffcfd636e8 100644
--- a/linux-ramdump-parser-v2/parsers/ipc_logging.py
+++ b/linux-ramdump-parser-v2/parsers/ipc_logging.py
@@ -49,59 +49,62 @@ NMAGIC = ctypes.c_uint32(~MAGIC).value
 CTX_MAGIC = 0x25874452
 CTX_NMAGIC = ctypes.c_uint32(~CTX_MAGIC).value
 
+
 def hex_to_str(chars, width, nLineLimit=None):
-	"""
-	Converts a binary string to a hex dump.
-
-	:param chars: The string to convert.
-	:param width: The width of the hex output.
-	:param nLineLimit: The maximum length of the hex output, in lines.
-
-	:return: The hex dump as a string.
-	"""
-	output = []
-	offset = 0
-	nLines = 0
-
-	while chars:
-		line = chars[:width]
-		chars = chars[width:]
-		strBlankHex = '   ' * (width - len(line))
-		strHex = ' '.join("%02x" % ord(c) for c in line) + strBlankHex
-		strOut = "%08x %s %s" % (offset, strHex, quotechars(line))
-		offset += width
-		output.append(strOut)
-		nLines += 1
-		if nLineLimit and nLines > nLineLimit:
-			output.append("...")
-			break
-
-	return '\n'.join(output) + '\n'
+    """
+    Converts a binary string to a hex dump.
+
+    :param chars: The string to convert.
+    :param width: The width of the hex output.
+    :param nLineLimit: The maximum length of the hex output, in lines.
+
+    :return: The hex dump as a string.
+    """
+    output = []
+    offset = 0
+    nLines = 0
+
+    while chars:
+        line = chars[:width]
+        chars = chars[width:]
+        strBlankHex = '   ' * (width - len(line))
+        strHex = ' '.join("%02x" % ord(c) for c in line) + strBlankHex
+        strOut = "%08x %s %s" % (offset, strHex, quotechars(line))
+        offset += width
+        output.append(strOut)
+        nLines += 1
+        if nLineLimit and nLines > nLineLimit:
+            output.append("...")
+            break
+
+    return '\n'.join(output) + '\n'
+
 
 def quotechars(chars):
-	return ''.join(['.', c][c.isalnum()] for c in chars)
+    return ''.join(['.', c][c.isalnum()] for c in chars)
+
 
 def str_to_hex(strHex):
-	"""
-	Converts a space-separated string of hex bytes into a binary string.
+    """
+    Converts a space-separated string of hex bytes into a binary string.
 
-	:param strHex: The space-separated string of hex bytes.
+    :param strHex: The space-separated string of hex bytes.
 
-	Example:
-		str_to_hex("01 02 0A 0B") ==> "\x01\x02\x0a\x0b"
+    Example:
+        str_to_hex("01 02 0A 0B") ==> "\x01\x02\x0a\x0b"
 
-	:return: The binary string.
-	"""
-	return ''.join([chr(int(x.strip(), 16)) for x in strHex.split()])
+    :return: The binary string.
+    """
+    return ''.join([chr(int(x.strip(), 16)) for x in strHex.split()])
 
 # Element types
-#enum {
-#	TSV_TYPE_INVALID,
-#	TSV_TYPE_TIMESTAMP,
-#	TSV_TYPE_POINTER,
-#	TSV_TYPE_INT32,
-#	TSV_TYPE_BYTE_ARRAY,
-#};
+# enum {
+#    TSV_TYPE_INVALID,
+#    TSV_TYPE_TIMESTAMP,
+#    TSV_TYPE_POINTER,
+#    TSV_TYPE_INT32,
+#    TSV_TYPE_BYTE_ARRAY,
+# };
 TSV_TYPE_INVALID = 0
 TSV_TYPE_TIMESTAMP = 1
 TSV_TYPE_POINTER = 2
@@ -109,12 +112,12 @@ TSV_TYPE_INT32 = 3
 TSV_TYPE_BYTE_ARRAY = 4
 
 # Message types
-#enum {
-#	TSV_TYPE_MSG_START = 1,
-#	TSV_TYPE_SKB = TSV_TYPE_MSG_START,
-#	TSV_TYPE_STRING,
-#	TSV_TYPE_MSG_END = TSV_TYPE_STRING,
-#};
+# enum {
+#    TSV_TYPE_MSG_START = 1,
+#    TSV_TYPE_SKB = TSV_TYPE_MSG_START,
+#    TSV_TYPE_STRING,
+#    TSV_TYPE_MSG_END = TSV_TYPE_STRING,
+# };
 TSV_TYPE_MSG_START = 1
 TSV_TYPE_SKB = TSV_TYPE_MSG_START
 TSV_TYPE_STRING = 2
@@ -122,10 +125,10 @@ TSV_TYPE_MSG_END = 2
 
 
 # TSV values
-#struct tsv_header {
-#	unsigned char type;
-#	unsigned char size; /* size of data field */
-#};
+# struct tsv_header {
+#    unsigned char type;
+#    unsigned char size; /* size of data field */
+# };
 V0_PAGE_HDR_SIZE = 4*4 + 2*2 + 2*4
 V1_PAGE_HDR_SIZE = 0x40
 V1_PAGE_HDR_SIZE_64 = 0x48
@@ -138,1581 +141,1614 @@ CTX_READ_SIZE = 64
 PAGE_HDR_SIZES = [V0_PAGE_HDR_SIZE, V1_PAGE_HDR_SIZE]
 PAGE_HDR_SIZES_64 = [V0_PAGE_HDR_SIZE, V1_PAGE_HDR_SIZE_64]
 
+
 class LogTSV(object):
-	"""Handles processing message/value headers"""
+    """Handles processing message/value headers"""
 
-	def __init__(self):
-		pass
+    def __init__(self):
+        pass
 
-	def unpack(self, data):
-		"""
-		Unpacks a TSV message. This is a wrapper around the
-		:func:`~struct.unpack()` function from the :mod:`struct` module.
+    def unpack(self, data):
+        """
+        Unpacks a TSV message. This is a wrapper around the
+        :func:`~struct.unpack()` function from the :mod:`struct` module.
 
-		:param data: The binary data to be unpacked.
+        :param data: The binary data to be unpacked.
 
-		:return: The TSV message with the header stripped off.
-		"""
-		assert len(data) >= 2, "Invalid message size %d" % (len(data))
-		self.msg_type, self.msg_size = struct.unpack('BB', data[0:2])
-		return data[2:]
+        :return: The TSV message with the header stripped off.
+        """
+        assert len(data) >= 2, "Invalid message size %d" % (len(data))
+        self.msg_type, self.msg_size = struct.unpack('BB', data[0:2])
+        return data[2:]
 
-	def pack(self, msg_type, msg_size):
-		"""
-		Packs a new TSV message structure. This is a wrapper around the
-		:func:`~struct.pack()` function from the :mod:`struct` module.
+    def pack(self, msg_type, msg_size):
+        """
+        Packs a new TSV message structure. This is a wrapper around the
+        :func:`~struct.pack()` function from the :mod:`struct` module.
 
-		:param msg_type: The TSV msg_type to be packed into the new \
-				TSV message structure.
-		:param msg_size: The TSV msg_size to be packed into the new \
-				TSV message structure.
+        :param msg_type: The TSV msg_type to be packed into the new
+                         TSV message structure.
+        :param msg_size: The TSV msg_size to be packed into the new
+                         TSV message structure.
+
+        :return: The TSV message structure packed into a binary string.
+        """
+        return struct.pack('BB', msg_type, msg_size)
 
-		:return: The TSV message structure packed into a binary string.
-		"""
-		return struct.pack('BB', msg_type, msg_size)
 
 class TsvTimestamp(object):
-	"""Handles processing TSV Timestamps"""
-
-	def unpack(self, data):
-		"""
-		Unpacks a TSV timestamp. This is a wrapper around the
-		:func:`~struct.unpack()` function from the :mod:`struct` module.
-
-		:return: The unpacked timestamp.
-
-		**Side Effects**: The unpacked timestamp is saved as an instance \
-				variable, ``self.fTimestamp``, which can be accessed as a \
-				string through the :meth:`__str__()` method of this class. \
-				This method is used by :class:`LogMessageString` to get \
-				the timestamp in order to dump it to the logs.
-		"""
-		tsv = LogTSV()
-		data = tsv.unpack(data)
-		assert tsv.msg_type == TSV_TYPE_TIMESTAMP, "timestamp"
-		assert tsv.msg_size == 8, "msg size"
-
-		# read 64-bit timestamp
-		timestamp_ns, = struct.unpack('<Q', data[0:8])
-		data = data[8:]
-		self.fTimestamp =  timestamp_ns * 1.0E-9
-		return data
-
-	def pack(self, fTimestamp):
-		"""
-		Packs a timestamp into a new TSV structure. This is a wrapper around the
-		:func:`~struct.pack()` function from the :mod:`struct` module.
-
-		:param fTimestamp: The TSV timestamp to be packed into a new TSV \
-				message structure.
-
-		:return: A TSV message structure with *fTimestamp* packed \
-				into the binary string.
-		"""
-		self.fTimestamp = fTimestamp
-		tsv = LogTSV()
-		data = tsv.pack(TSV_TYPE_TIMESTAMP, 8)
-		data += struct.pack('<Q', fTimestamp * 1.0E9)
-		return data
-
-	def __str__(self):
-		return '%16.9f' % (self.fTimestamp)
+    """Handles processing TSV Timestamps"""
+
+    def unpack(self, data):
+        """
+        Unpacks a TSV timestamp. This is a wrapper around the
+        :func:`~struct.unpack()` function from the :mod:`struct` module.
+
+        :return: The unpacked timestamp.
+
+        **Side Effects**: The unpacked timestamp is saved as an instance
+                variable, ``self.fTimestamp``, which can be accessed as a
+                string through the :meth:`__str__()` method of this class.
+                This method is used by :class:`LogMessageString` to get
+                the timestamp in order to dump it to the logs.
+        """
+        tsv = LogTSV()
+        data = tsv.unpack(data)
+        assert tsv.msg_type == TSV_TYPE_TIMESTAMP, "timestamp"
+        assert tsv.msg_size == 8, "msg size"
+
+        # read 64-bit timestamp
+        timestamp_ns, = struct.unpack('<Q', data[0:8])
+        data = data[8:]
+        self.fTimestamp = timestamp_ns * 1.0E-9
+        return data
+
+    def pack(self, fTimestamp):
+        """
+        Packs a timestamp into a new TSV structure. This is a wrapper around
+        the :func:`~struct.pack()` function from the :mod:`struct` module.
+
+        :param fTimestamp: The TSV timestamp to be packed into a new TSV
+                           message structure.
+
+        :return: A TSV message structure with *fTimestamp* packed
+                into the binary string.
+        """
+        self.fTimestamp = fTimestamp
+        tsv = LogTSV()
+        data = tsv.pack(TSV_TYPE_TIMESTAMP, 8)
+        data += struct.pack('<Q', fTimestamp * 1.0E9)
+        return data
+
+    def __str__(self):
+        return '%16.9f' % (self.fTimestamp)
+
 
 class TsvByteArray(object):
-	"""Handles processing TSV byte arrays."""
-
-	def unpack(self, data):
-		"""
-		Unpacks a TSV byte array. This is a wrapper around the
-		:func:`~struct.unpack()` function from the :mod:`struct` module.
-
-		:param data: The binary data to be unpacked.
-
-		:return: The header data of the TSV message.
-
-		**Side Effects**: The byte array data is saved as an instance \
-				variable, ``self.strByteArray``, which can be accessed as a \
-				string through the :meth:`__str__()` method of this class. \
-				This method is used by :class:`LogMessageString` to get \
-				the byte array data as a string in order to dump it to the logs.
-		"""
-		tsv = LogTSV()
-		data = tsv.unpack(data)
-		assert tsv.msg_type == TSV_TYPE_BYTE_ARRAY, \
-				"%d != %d" % (tsv.msg_type, TSV_TYPE_BYTE_ARRAY)
-
-		# read byte array
-		self.strByteArray = data[:tsv.msg_size]
-		data = data[tsv.msg_size:]
-		return data
-
-	def pack(self, data):
-		"""
-		Packs a new TSV message structure, using the TSV byte array in *data*.
-		This is a wrapper around the :func:`~struct.pack()` function from the
-		:mod:`struct` module.
-
-		:param data: The data to be packed into the new TSV message structure.
-
-		:return: The new structure as binary data, with *data* appended to the \
-				end.
-		"""
-		tsv = LogTSV()
-		lst = tsv.pack(TSV_TYPE_BYTE_ARRAY, len(data))
-		lst += data
-		return lst
-
-	def __str__(self):
-		return self.strByteArray
+    """Handles processing TSV byte arrays."""
+
+    def unpack(self, data):
+        """
+        Unpacks a TSV byte array. This is a wrapper around the
+        :func:`~struct.unpack()` function from the :mod:`struct` module.
+
+        :param data: The binary data to be unpacked.
+
+        :return: The header data of the TSV message.
+
+        **Side Effects**: The byte array data is saved as an instance
+                variable, ``self.strByteArray``, which can be accessed as a
+                string through the :meth:`__str__()` method of this class.
+                This method is used by :class:`LogMessageString` to get
+                the byte array data as a string in order to dump it to the
+                logs.
+        """
+        tsv = LogTSV()
+        data = tsv.unpack(data)
+        assert tsv.msg_type == TSV_TYPE_BYTE_ARRAY, \
+            "%d != %d" % (tsv.msg_type, TSV_TYPE_BYTE_ARRAY)
+
+        # read byte array
+        self.strByteArray = data[:tsv.msg_size]
+        data = data[tsv.msg_size:]
+        return data
+
+    def pack(self, data):
+        """
+        Packs a new TSV message structure, using the TSV byte array in *data*.
+        This is a wrapper around the :func:`~struct.pack()` function from the
+        :mod:`struct` module.
+
+        :param data: The data to be packed into the new TSV message structure.
+
+        :return: The new structure as binary data, with *data* appended to
+                the end.
+        """
+        tsv = LogTSV()
+        lst = tsv.pack(TSV_TYPE_BYTE_ARRAY, len(data))
+        lst += data
+        return lst
+
+    def __str__(self):
+        return self.strByteArray
+
 
 class LogMessageString(object):
-	"""Handles processing TSV message strings."""
-
-	def unpack(self, data, tsv):
-		"""
-		Unpacks a new TSV message string. To do this, it is first
-		necessary to unpack the timestamp using :meth:`TsvTimestamp.unpack()`,
-		and proceed to use unpack the byte array from the result using
-		:meth:`TsvByteArray.unpack()`. The result of this call is what is
-		returned.
-
-		:param data: The data containing the TSV string message to be unpacked
-		:param tsv: The :class:`LogTSV` object that was used to unpack *data*
-
-		:return: The TSV message string data
-
-		**Side Effects**: The timestamp and the message extracted from *data* \
-				are stored as instance variables, and can be printed using the \
-				:meth:`__str__` method of this class. This :meth:`__str__()` \
-				method is used to dump the logs in their \
-				'[timestamp] <message>' format.
-		"""
-		assert tsv.msg_type == TSV_TYPE_STRING, "invalid message type"
-
-		# TSV_TYPE_STRING - message type
-		# TSV_TYPE_TIMESTAMP
-		# TSV_TYPE_BYTE_ARRAY
-		self.timestamp = TsvTimestamp()
-		data = self.timestamp.unpack(data)
-
-		self.strMessage = TsvByteArray()
-		data = self.strMessage.unpack(data)
-		return data
-
-	def pack(self, fTimestamp, strMessage):
-		"""
-		Packs a new TSV LogMessageString structure.
-
-		:param fTimestamp: The timestamp to be packed into the structure
-		:param strMessage: The string message to be packed into the structure
-
-		:return: The packed TSV LogMessageString structure
-		"""
-		self.timestamp = TsvTimestamp()
-		data =self.timestamp.pack(fTimestamp)
-		data += TsvByteArray().pack(strMessage)
-
-		tsv = LogTSV()
-		data = tsv.pack(TSV_TYPE_STRING, len(data)) + data
-		self.strMessage = strMessage
-		return data
-
-	def __str__(self):
-		return '[%s] %s' % (self.timestamp, self.strMessage)
+    """Handles processing TSV message strings."""
+
+    def unpack(self, data, tsv):
+        """
+        Unpacks a new TSV message string. To do this, it is first
+        necessary to unpack the timestamp using :meth:`TsvTimestamp.unpack()`,
+        and proceed to use unpack the byte array from the result using
+        :meth:`TsvByteArray.unpack()`. The result of this call is what is
+        returned.
+
+        :param data: The data containing the TSV string message to be unpacked
+        :param tsv: The :class:`LogTSV` object that was used to unpack *data*
+
+        :return: The TSV message string data
+
+        **Side Effects**: The timestamp and the message extracted from *data*
+                are stored as instance variables, and can be printed using
+                the :meth:`__str__` method of this class. This
+                :meth:`__str__()` method is used to dump the logs in their
+                '[timestamp] <message>' format.
+        """
+        assert tsv.msg_type == TSV_TYPE_STRING, "invalid message type"
+
+        # TSV_TYPE_STRING - message type
+        # TSV_TYPE_TIMESTAMP
+        # TSV_TYPE_BYTE_ARRAY
+        self.timestamp = TsvTimestamp()
+        data = self.timestamp.unpack(data)
+
+        self.strMessage = TsvByteArray()
+        data = self.strMessage.unpack(data)
+        return data
+
+    def pack(self, fTimestamp, strMessage):
+        """
+        Packs a new TSV LogMessageString structure.
+
+        :param fTimestamp: The timestamp to be packed into the structure
+        :param strMessage: The string message to be packed into the structure
+
+        :return: The packed TSV LogMessageString structure
+        """
+        self.timestamp = TsvTimestamp()
+        data = self.timestamp.pack(fTimestamp)
+        data += TsvByteArray().pack(strMessage)
+
+        tsv = LogTSV()
+        data = tsv.pack(TSV_TYPE_STRING, len(data)) + data
+        self.strMessage = strMessage
+        return data
+
+    def __str__(self):
+        return '[%s] %s' % (self.timestamp, self.strMessage)
+
 
 class LogContext(object):
-	"""
-	A single context in a version 1 or greater IPC Logging log.
-
-	.. code-block:: c
-
-		struct ipc_log_context {
-			uint32_t magic;
-			uint32_t nmagic;
-			uint32_t version;
-			uint16_t user_version;
-			uint16_t header_size;
-			uint64_t log_id;
-
-			/* Local data structures below ... */
-		};
-
-	The purpose of the log context is to contain the above information about
-	the log. One log consists of one to several pages. Thus, pages and contexts
-	are associated by log ID, the one piece of information that is common
-	between them in their C structs.
-
-	"""
-
-	headerBinaryFormat = '<IIIHHQ20s'
-	headerBinaryFormatSize = struct.calcsize(headerBinaryFormat)
-
-	def __init__(self):
-		self.data = None
-
-	def unpack(self, data):
-		"""
-		Unpacks an ipc_log_context structure, and assigns the contents
-		into instance variables of this class. This is a wrapper around
-		the :func:`~struct.unpack()` function from the :mod:`struct` module.
-
-		:param data: The binary ipc_log_context structure to be unpacked.
-
-		:return: :const:`True` if the unpack completes successfully, \
-				:const:`False` if not.
-
-		**Side Effects**: If the unpack is successful, the contexts are \
-				assigned to instance variables. In this way, :meth:`unpack()` \
-				acts as a sort of constructor. This is common to all the \
-				unpack methods.
-		"""
-		self.data = data
-		self.magic, self.nmagic, self.version, self.user_version, \
-			self.header_size, self.log_id, self.name = \
-				struct.unpack(self.headerBinaryFormat,
-						self.data[0:self.headerBinaryFormatSize])
-		self.name = self.name.rstrip('\0')
-
-		if self.magic == CTX_MAGIC and self.nmagic == CTX_NMAGIC:
-			return True
-
-		return False
-
-	def pack(self, nVersion, nUserVersion, nHeaderSize, nLogId, nName):
-		"""
-		Packs a new ipc_log_context structure using the given elements. This
-		function is especially useful in unit testing, as it provides the
-		ability to create structures and then unpack them using the
-		:meth:`unpack()` method.
-
-		:param nVersion: The IPC Logging version
-		:param nUserVersion: The user version
-		:param nHeaderSize: The header size
-		:param nLogId: The log ID
-		:param nName: The context name
-
-		:return: The packed binary data.
-		"""
-		self.data = struct.pack(self.headerBinaryFormat, CTX_MAGIC, CTX_NMAGIC,
-				nVersion, nUserVersion, nHeaderSize, nLogId, nName)
-
-	def log_info(self):
-		"""
-		If DEBUG logging is turned on (command line parameter -v), logs the
-		instance variables of this LogContext to the output file. See the Python
-		:mod:`logging` module documentation and the IPC Logging main function
-		for more info on logging.
-
-		This method logs the ``version``, ``user_version``, ``log_id``,
-		``header_size``, and ``name`` variables to the logging output file.
-		"""
-		logging.debug("\tversion:      %d" % (self.version))
-		logging.debug("\tuser version: %d" % (self.user_version))
-		logging.debug("\tlog id:       %x" % (self.log_id))
-		logging.debug("\theader_size:  %x" % (self.header_size))
-		logging.debug("\tname:         %s" % (self.name))
+    """
+    A single context in a version 1 or greater IPC Logging log.
+
+    .. code-block:: c
+
+        struct ipc_log_context {
+            uint32_t magic;
+            uint32_t nmagic;
+            uint32_t version;
+            uint16_t user_version;
+            uint16_t header_size;
+            uint64_t log_id;
+
+            /* Local data structures below ... */
+        };
+
+    The purpose of the log context is to contain the above information about
+    the log. One log consists of one to several pages. Thus, pages and contexts
+    are associated by log ID, the one piece of information that is common
+    between them in their C structs.
+
+    """
+
+    headerBinaryFormat = '<IIIHHQ20s'
+    headerBinaryFormatSize = struct.calcsize(headerBinaryFormat)
+
+    def __init__(self):
+        self.data = None
+
+    def unpack(self, data):
+        """
+        Unpacks an ipc_log_context structure, and assigns the contents
+        into instance variables of this class. This is a wrapper around
+        the :func:`~struct.unpack()` function from the :mod:`struct` module.
+
+        :param data: The binary ipc_log_context structure to be unpacked.
+
+        :return: :const:`True` if the unpack completes successfully,
+                :const:`False` if not.
+
+        **Side Effects**: If the unpack is successful, the contexts are
+                assigned to instance variables. In this way, :meth:`unpack()`
+                acts as a sort of constructor. This is common to all the
+                unpack methods.
+        """
+        self.data = data
+        self.magic, self.nmagic, self.version, self.user_version, \
+            self.header_size, self.log_id, self.name = \
+            struct.unpack(self.headerBinaryFormat,
+                          self.data[0:self.headerBinaryFormatSize])
+        self.name = self.name.rstrip('\0')
+
+        if self.magic == CTX_MAGIC and self.nmagic == CTX_NMAGIC:
+            return True
+
+        return False
+
+    def pack(self, nVersion, nUserVersion, nHeaderSize, nLogId, nName):
+        """
+        Packs a new ipc_log_context structure using the given elements. This
+        function is especially useful in unit testing, as it provides the
+        ability to create structures and then unpack them using the
+        :meth:`unpack()` method.
+
+        :param nVersion: The IPC Logging version
+        :param nUserVersion: The user version
+        :param nHeaderSize: The header size
+        :param nLogId: The log ID
+        :param nName: The context name
+
+        :return: The packed binary data.
+        """
+        self.data = struct.pack(self.headerBinaryFormat, CTX_MAGIC, CTX_NMAGIC,
+                                nVersion, nUserVersion, nHeaderSize, nLogId,
+                                nName)
+
+    def log_info(self):
+        """
+        If DEBUG logging is turned on (command line parameter -v), logs the
+        instance variables of this LogContext to the output file. See the
+        Python :mod:`logging` module documentation and the IPC Logging main
+        function for more info on logging.
+
+        This method logs the ``version``, ``user_version``, ``log_id``,
+        ``header_size``, and ``name`` variables to the logging output file.
+        """
+        logging.debug("\tversion:      %d" % (self.version))
+        logging.debug("\tuser version: %d" % (self.user_version))
+        logging.debug("\tlog id:       %x" % (self.log_id))
+        logging.debug("\theader_size:  %x" % (self.header_size))
+        logging.debug("\tname:         %s" % (self.name))
+
 
 class LogPage(object):
-	"""
-	LogPage base class. New versions of IPC Logging will require new descendants
-	of this class, as their :meth:`~LogPage_v0.unpack()` methods will change,
-	among other things. In IPC Logging version 1, the children of
-	:class:`LogPage` include :class:`LogPage_v0` and :class:`LogPage_v1`. There
-	is another class, :class:`LogPageVersionUnknown`, which is not in this
-	inheritance hierarchy; this is because it does not use the methods or data
-	needed by the rest of the :class:`LogPage` classes.
-
-	Note that this is not an abstract class. The reason for this is to allow
-	new methods to be added here without forcing child classes to define them.
-	"""
-	def __init__(self):
-		self.data = None
-		self.previousPage = None
-		self.previousData = None
-		self.nextPage = None
-		self.nextData = None
-		self.iterated = False
-		self.page_header_size = V0_PAGE_HDR_SIZE
-		self.unknown_messages_data = None
-
-	def pack_continue(self, strPayload):
-		"""
-		Packs a new page structure.  The *strPayload* can be empty and
-		additional payload can be added using :meth:`pack_continue()`.
-
-		Returns: Overflow data (*strPayload* that didn't fit into the page) or
-		:const:`None` if all fit.
-		"""
-		self.data += strPayload
-
-		if len(self.data) > PAGE_SIZE:
-			overflowData = self.data[PAGE_SIZE:]
-			self.data = self.data[0:PAGE_SIZE]
-		else:
-			return None
-
-	def __iter__(self):
-		"""Message iterator"""
-		self.iterated = True
-		self.previousData = None
-
-		logging.debug("Iterating log id %d, page %d" % \
-				(self.log_id, self.page_num))
-		self.log_info()
-
-		if self.read_offset == FULL_PAGE_WRITE_OFFSET \
-				and self.write_offset == FULL_PAGE_WRITE_OFFSET:
-			# page is either empty or full, but only the page with
-			# valid read/write pointers knows if we have data
-			self.iter_data = self.data[self.page_header_size:]
-			logging.debug("\tfull/empty case")
-		elif self.write_offset == FULL_PAGE_WRITE_OFFSET:
-			# page is full
-			read_iter = self.read_offset + self.page_header_size
-			self.iter_data = self.data[read_iter:]
-			logging.debug("\tfull case")
-		elif self.read_offset == FULL_PAGE_WRITE_OFFSET:
-			# page hasn't been read, but has only been partially written
-			write_iter = self.write_offset + self.page_header_size
-			self.iter_data = self.data[self.page_header_size:write_iter]
-			logging.debug("\tpartial write, no read")
-		elif self.read_offset >= self.write_offset:
-			# almost full buffer
-			read_iter = self.read_offset + self.page_header_size
-			write_iter = self.write_offset + self.page_header_size
-			self.iter_data = self.data[read_iter:]
-			self.previousData = self.data[self.page_header_size:write_iter]
-
-			if self.page_num == 0 and self.read_offset == self.write_offset:
-				self.iter_data = self.data[self.page_header_size:]
-				self.previousData = None
-				logging.debug("\talmost full - first page offsets equal")
-
-			logging.debug("\talmost full")
-		else:
-			# almost empty buffer
-			read_iter = self.read_offset + self.page_header_size
-			write_iter = self.write_offset + self.page_header_size
-			self.iter_data = self.data[read_iter:write_iter]
-			logging.debug("\talmost empty")
-
-		# prepend data from previous page
-		if self.previousPage and self.previousPage.nextData:
-			logging.debug("Pulling previous data len")
-			logging.debug(hex_to_str(self.previousPage.nextData, 16, 10))
-			self.iter_data = self.previousPage.nextData + self.iter_data
-
-		return PageIterator(self)
-
-	def next(self):
-		# handles full-buffer condition where write pointer
-		# is behind the read pointer
-		if self.nextPage and self.nextPage.previousData:
-			self.iter_data += self.nextPage.previousData
-			self.nextPage.previousData = None
-
-		if len(self.iter_data) < 2:
-			# not enough data to retrieve message header
-			logging.debug("Pushing data to continue\n%s" % \
-					(hex_to_str(self.iter_data, 16, 10)))
-			self.nextData = self.iter_data
-			self.iter_data = None
-			raise StopIteration
-
-		while True:
-			try:
-				tsv = LogTSV()
-				data = tsv.unpack(self.iter_data)
-				if tsv.msg_size > len(data):
-					# not enough data left to extract entire message
-					logging.debug("Pushing data to continue\n%s" % \
-							(hex_to_str(self.iter_data, 16, 10)))
-					self.nextData = self.iter_data
-					self.iter_data = None
-					raise StopIteration
-
-				# TODO - this needs to be replaced with a dictionary for the
-				# message deserialization types for custom deserialization
-				# functions
-				if tsv.msg_type == 0:
-					# no more messages
-					raise StopIteration
-
-				if tsv.msg_type == TSV_TYPE_STRING:
-					self.iter_data = data
-					msg = LogMessageString()
-					self.iter_data = msg.unpack(self.iter_data, tsv)
-					return msg
-				else:
-					debug_str = "Unknown message type 0x%x\n%s" % \
-						(tsv.msg_type, hex_to_str(self.iter_data, 16, 10))
-
-					logging.debug(debug_str)
-					assert False, debug_str
-
-			except StopIteration:
-				raise
+    """
+    LogPage base class. New versions of IPC Logging will require new
+    descendants of this class, as their :meth:`~LogPage_v0.unpack()` methods
+    will change, among other things. In IPC Logging version 1, the children of
+    :class:`LogPage` include :class:`LogPage_v0` and :class:`LogPage_v1`. There
+    is another class, :class:`LogPageVersionUnknown`, which is not in this
+    inheritance hierarchy; this is because it does not use the methods or data
+    needed by the rest of the :class:`LogPage` classes.
+
+    Note that this is not an abstract class. The reason for this is to allow
+    new methods to be added here without forcing child classes to define them.
+    """
+    def __init__(self):
+        self.data = None
+        self.previousPage = None
+        self.previousData = None
+        self.nextPage = None
+        self.nextData = None
+        self.iterated = False
+        self.page_header_size = V0_PAGE_HDR_SIZE
+        self.unknown_messages_data = None
+
+    def pack_continue(self, strPayload):
+        """
+        Packs a new page structure.  The *strPayload* can be empty and
+        additional payload can be added using :meth:`pack_continue()`.
+
+        Returns: Overflow data (*strPayload* that didn't fit into the page) or
+        :const:`None` if all fit.
+        """
+        self.data += strPayload
+
+        if len(self.data) > PAGE_SIZE:
+            overflowData = self.data[PAGE_SIZE:]
+            self.data = self.data[0:PAGE_SIZE]
+            return overflowData
+        else:
+            return None
+
+    def __iter__(self):
+        """Message iterator"""
+        self.iterated = True
+        self.previousData = None
+
+        logging.debug("Iterating log id %d, page %d" %
+                      (self.log_id, self.page_num))
+        self.log_info()
+
+        if self.read_offset == FULL_PAGE_WRITE_OFFSET \
+                and self.write_offset == FULL_PAGE_WRITE_OFFSET:
+            # page is either empty or full, but only the page with
+            # valid read/write pointers knows if we have data
+            self.iter_data = self.data[self.page_header_size:]
+            logging.debug("\tfull/empty case")
+        elif self.write_offset == FULL_PAGE_WRITE_OFFSET:
+            # page is full
+            read_iter = self.read_offset + self.page_header_size
+            self.iter_data = self.data[read_iter:]
+            logging.debug("\tfull case")
+        elif self.read_offset == FULL_PAGE_WRITE_OFFSET:
+            # page hasn't been read, but has only been partially written
+            write_iter = self.write_offset + self.page_header_size
+            self.iter_data = self.data[self.page_header_size:write_iter]
+            logging.debug("\tpartial write, no read")
+        elif self.read_offset >= self.write_offset:
+            # almost full buffer
+            read_iter = self.read_offset + self.page_header_size
+            write_iter = self.write_offset + self.page_header_size
+            self.iter_data = self.data[read_iter:]
+            self.previousData = self.data[self.page_header_size:write_iter]
+
+            if self.page_num == 0 and self.read_offset == self.write_offset:
+                self.iter_data = self.data[self.page_header_size:]
+                self.previousData = None
+                logging.debug("\talmost full - first page offsets equal")
+
+            logging.debug("\talmost full")
+        else:
+            # almost empty buffer
+            read_iter = self.read_offset + self.page_header_size
+            write_iter = self.write_offset + self.page_header_size
+            self.iter_data = self.data[read_iter:write_iter]
+            logging.debug("\talmost empty")
+
+        # prepend data from previous page
+        if self.previousPage and self.previousPage.nextData:
+            logging.debug("Pulling previous data len")
+            logging.debug(hex_to_str(self.previousPage.nextData, 16, 10))
+            self.iter_data = self.previousPage.nextData + self.iter_data
+
+        return PageIterator(self)
+
+    def next(self):
+        # handles full-buffer condition where write pointer
+        # is behind the read pointer
+        if self.nextPage and self.nextPage.previousData:
+            self.iter_data += self.nextPage.previousData
+            self.nextPage.previousData = None
+
+        if len(self.iter_data) < 2:
+            # not enough data to retrieve message header
+            logging.debug("Pushing data to continue\n%s" %
+                          (hex_to_str(self.iter_data, 16, 10)))
+            self.nextData = self.iter_data
+            self.iter_data = None
+            raise StopIteration
+
+        while True:
+            try:
+                tsv = LogTSV()
+                data = tsv.unpack(self.iter_data)
+                if tsv.msg_size > len(data):
+                    # not enough data left to extract entire message
+                    logging.debug("Pushing data to continue\n%s" %
+                                  (hex_to_str(self.iter_data, 16, 10)))
+                    self.nextData = self.iter_data
+                    self.iter_data = None
+                    raise StopIteration
+
+                # TODO - this needs to be replaced with a dictionary for the
+                # message deserialization types for custom deserialization
+                # functions
+                if tsv.msg_type == 0:
+                    # no more messages
+                    raise StopIteration
+
+                if tsv.msg_type == TSV_TYPE_STRING:
+                    self.iter_data = data
+                    msg = LogMessageString()
+                    self.iter_data = msg.unpack(self.iter_data, tsv)
+                    return msg
+                else:
+                    debug_str = "Unknown message type 0x%x\n%s" % \
+                        (tsv.msg_type, hex_to_str(self.iter_data, 16, 10))
+
+                    logging.debug(debug_str)
+                    assert False, debug_str
+
+            except StopIteration:
+                raise
+
 
 class LogPageVersionUnknown(object):
-	"""
-	This class is used before the version of the log being parsed is known. It
-	only unpacks the magic numbers and the page number from the data that is
-	found by :func:`cmdParse()`, in order to determine the version.
-
-	This class can only be used to discover whether the log is a version 0 log
-	or a version 1 (or greater) log. See :meth:`isVersionOneOrGreater()` for
-	more details.
-	"""
-	def __init__(self):
-		self.data = None
-		self.version = None
-		self.headerMagicFormat = '<II'
-		self.headerMagicFormatSize = struct.calcsize(self.headerMagicFormat)
-		self.versionDataFormat = '<I'
-		self.versionDataFormatSize = struct.calcsize(self.versionDataFormat)
-
-	def unpack(self, data):
-		"""
-		Partially unpacks a page structure in order to inspect the magic number.
-		This is a wrapper around the :func:`~struct.unpack()` function from the
-		:mod:`struct` module.
-
-		:param data: The binary data to be unpacked.
-
-		:return: :const:`True` if the unpack is successful, :const:`False` if \
-				not.
-
-		**Side Effects**: The unpacked values are assigned to instance \
-				variables of this LogPageVersionUnknown instance.
-		"""
-		self.data=data
-
-		self.magic, self.nmagic = \
-				struct.unpack(self.headerMagicFormat,
-						self.data[0:self.headerMagicFormatSize])
-
-		if self.magic == MAGIC and self.nmagic == NMAGIC:
-			return True
-
-		return False
-
-	def isVersionOneOrGreater(self, data):
-		"""
-		This method determines whether the log is version 0, or version 1 or
-		greater. The top bit of ``self.version_data`` will be 1 if the log
-		version is at least 1, and 0 if not. Note that this function should
-		only be called after calling :meth:`unpack()`.
-
-		:return: :const:`True` if the version is 1 or greater, \
-				:const:`False` otherwise.
-
-		**Side Effects**: This method unpacks the version data and stores \
-				the result in an instance variable.
-		"""
-		self.data=data
-		endSize = self.headerMagicFormatSize + self.versionDataFormatSize
-		version_data = \
-				struct.unpack(self.versionDataFormat,
-						self.data[self.headerMagicFormatSize:endSize])
-		self.version_data = version_data[0]
-		mask = 0x80000000
-		result = (self.version_data & mask) >= 0x80000000
-		return result
+    """
+    This class is used before the version of the log being parsed is known. It
+    only unpacks the magic numbers and the page number from the data that is
+    found by :func:`cmdParse()`, in order to determine the version.
+
+    This class can only be used to discover whether the log is a version 0 log
+    or a version 1 (or greater) log. See :meth:`isVersionOneOrGreater()` for
+    more details.
+    """
+    def __init__(self):
+        self.data = None
+        self.version = None
+        self.headerMagicFormat = '<II'
+        self.headerMagicFormatSize = struct.calcsize(self.headerMagicFormat)
+        self.versionDataFormat = '<I'
+        self.versionDataFormatSize = struct.calcsize(self.versionDataFormat)
+
+    def unpack(self, data):
+        """
+        Partially unpacks a page structure in order to inspect the magic
+        number. This is a wrapper around the :func:`~struct.unpack()` function
+        from the :mod:`struct` module.
+
+        :param data: The binary data to be unpacked.
+
+        :return: :const:`True` if the unpack is successful, :const:`False` if
+                not.
+
+        **Side Effects**: The unpacked values are assigned to instance
+                variables of this LogPageVersionUnknown instance.
+        """
+        self.data = data
+
+        self.magic, self.nmagic = \
+            struct.unpack(self.headerMagicFormat,
+                          self.data[0:self.headerMagicFormatSize])
+
+        if self.magic == MAGIC and self.nmagic == NMAGIC:
+            return True
+
+        return False
+
+    def isVersionOneOrGreater(self, data):
+        """
+        This method determines whether the log is version 0, or version 1 or
+        greater. The top bit of ``self.version_data`` will be 1 if the log
+        version is at least 1, and 0 if not. Note that this function should
+        only be called after calling :meth:`unpack()`.
+
+        :return: :const:`True` if the version is 1 or greater,
+                :const:`False` otherwise.
+
+        **Side Effects**: This method unpacks the version data and stores
+                the result in an instance variable.
+        """
+        self.data = data
+        endSize = self.headerMagicFormatSize + self.versionDataFormatSize
+        version_data = \
+            struct.unpack(self.versionDataFormat,
+                          self.data[self.headerMagicFormatSize:endSize])
+        self.version_data = version_data[0]
+        mask = 0x80000000
+        result = (self.version_data & mask) >= 0x80000000
+        return result
+
 
 class LogPage_v0(LogPage):
-	"""
-	A single page in a version 0 IPC Logging log. This class is a descendant of
-	:class:`LogPage`.
-
-	.. code-block:: c
-
-		struct ipc_log_page_header {
-			uint32_t magic;
-			uint32_t nmagic; /* inverse of magic number */
-			uint32_t log_id; /* owner of log */
-			uint32_t page_num;
-			uint16_t read_offset;
-			uint16_t write_offset;
-			struct list_head list;
-		};
-	"""
-	def __init__(self):
-		# Call the parent constructor
-		super(self.__class__, self).__init__()
-		self.headerBinaryFormat = '<IIIIHH'
-		self.headerBinaryFormatSize = struct.calcsize(self.headerBinaryFormat)
-
-	def sortAndLink(self, lstPages, bSort):
-		"""
-		Given a list of pages in ascending page number order,
-		sort them chronologically and link the pages together.
-		This must be called before iterating over items in a page.
-
-		:param lstPages: The list of pages to be sorted
-		:param bSort: A boolean indicating whether the logs are full or \
-				partially full. If they are full, bSort is :const:`True`.
-
-		:return: The sorted and linked list of pages.
-
-		**Side Effects**: If the starting page cannot be found, this \
-				method will fail an assertion.
-		"""
-		# Convert lstPages deque to a regular Python list
-		lstPages = list(lstPages)
-
-		# Sort pages chronologically by finding the first active page.
-		# Since the pages are filled in order by page-id, the first
-		# non-full page is the last page written to.
-		if bSort:
-			for n in range(len(lstPages)):
-				if lstPages[0].write_offset != FULL_PAGE_WRITE_OFFSET:
-					break
-				lstPages.append(lstPages.pop(0))
-			assert lstPages[0].write_offset != FULL_PAGE_WRITE_OFFSET, \
-					"Unable to find starting page"
-
-		# link pages
-		numPages = len(lstPages)
-		nMaxPage = 0
-		for n in range(numPages):
-			page = lstPages[n]
-			nMaxPage = max(nMaxPage, page.page_num)
-			page.previousPage = lstPages[n - 1]
-			page.nextPage = lstPages[(n + 1) % numPages]
-			page.iterated = False
-		assert (nMaxPage + 1) == numPages, \
-				"Missing log pages: max page %d, num pages %d" % \
-					(nMaxPage, numPages)
-
-		return lstPages
-
-	def log_info(self):
-		"""
-		If DEBUG logging is turned on (command line parameter -v), logs the
-		instance variables of this LogPage_v0 to the output file. See the Python
-		:mod:`logging` module documentation and the IPC Logging main function
-		for more info on logging.
-
-		This method only logs the ``read_offset`` and
-		``write_offset`` variables as the others are logged elsewhere.
-		"""
-		logging.debug("\tread index:  %x" % (self.read_offset))
-		logging.debug("\twrite index: %x" % (self.write_offset))
-
-	def debug_save_log_pages(self, fIn, filename, data, options):
-		"""
-		Writes a binary file containing the data for the current page. This
-		is a helper to :func:`cmdParse`, and is particularly useful in
-		debugging.
-
-		:param fIn: The input file currently being processed by the caller
-		:param filename: The name of the input file currently being processed
-		:param data: The binary data for the current page
-		:param options: Configuration options containing options.output_dir for
-						the output directory
-
-		**Side Effects**: Writes an output file containing the binary data \
-				for the current page.
-		"""
-		# Get just the filename, instead of the whole path.
-		# Otherwise the file open call will fail.
-		filename = os.path.split(filename)[1]
-
-		strDebugFileName = 'log-%d-%d-%s-%u.bin' % (self.log_id, self.page_num,
-			filename, fIn.tell() - PAGE_SIZE)
-
-		if options.output_dir:
-			strDebugFileName = \
-					os.path.join(options.output_dir, strDebugFileName)
-
-		logging.info("Writing debug file '%s'\n", strDebugFileName)
-		fOut = open(strDebugFileName, 'wb')
-		fOut.write(data)
-		fOut.close()
-
-	def unpack(self, data):
-		"""
-		Unpacks an ipc_log_page version 0 structure, and assigns the contents
-		into instance variables of this class. This is a wrapper around
-		the :func:`~struct.unpack()` function from the :mod:`struct` module.
-
-		:param data: The binary ipc_log_context structure to be unpacked.
-
-		:return: :const:`True` if the unpack completes successfully, \
-				:const:`False` if not.
-
-		**Side Effects**: If the unpack is successful, the contexts are \
-				assigned to instance variables. In this way, :meth:`unpack()` \
-				acts as a sort of constructor. This is common to all the \
-				unpack methods.
-		"""
-		self.data = data
-		self.magic, self.nmagic, self.log_id, self.page_num, self.read_offset, \
-				self.write_offset = struct.unpack(self.headerBinaryFormat,
-					self.data[0:self.headerBinaryFormatSize])
-
-		# Mask off the top bit of page_num, which is used to indicate
-		# a version 1 or greater page
-		mask = 0x7FFFFFFF
-		self.page_num = self.page_num & mask
-
-		if self.magic == MAGIC and self.nmagic == NMAGIC:
-			return True
-
-		return False
-
-	def pack(self, nLogId, nPageNum, nReadOffset, nWriteOffset, strPayload):
-		"""
-		Packs a new version 0 page structure.  *strPayload* can be empty and
-		additional payload can be added using :meth:`~LogPage.pack_continue()`.
-
-		:param nLogId: The log ID to be packed into the new structure
-		:param nPageNum: The page number
-		:param nReadOffset: The read offset
-		:param nWriteOffset: The write offset
-		:param strPayload: The payload of the new structure
-
-		:return: Overflow data (*strPayload* that didn't fit into the page) or \
-				:const:`None` if all fit.
-		"""
-		data = struct.pack(self.headerBinaryFormat, MAGIC, NMAGIC,
-				nLogId, nPageNum, nReadOffset, nWriteOffset)
-
-		# add padding for list structures
-		data += '\0' * (self.page_header_size - len(data))
-
-		# append message payload
-		self.data = data + strPayload or ''
-
-		if len(self.data) > PAGE_SIZE:
-			data = self.data[PAGE_SIZE:]
-			self.data = self.data[0:PAGE_SIZE]
-			return data
-		else:
-			return None
+    """
+    A single page in a version 0 IPC Logging log. This class is a descendant of
+    :class:`LogPage`.
+
+    .. code-block:: c
+
+        struct ipc_log_page_header {
+            uint32_t magic;
+            uint32_t nmagic; /* inverse of magic number */
+            uint32_t log_id; /* owner of log */
+            uint32_t page_num;
+            uint16_t read_offset;
+            uint16_t write_offset;
+            struct list_head list;
+        };
+    """
+    def __init__(self):
+        # Call the parent constructor
+        super(self.__class__, self).__init__()
+        self.headerBinaryFormat = '<IIIIHH'
+        self.headerBinaryFormatSize = struct.calcsize(self.headerBinaryFormat)
+
+    def sortAndLink(self, lstPages, bSort):
+        """
+        Given a list of pages in ascending page number order,
+        sort them chronologically and link the pages together.
+        This must be called before iterating over items in a page.
+
+        :param lstPages: The list of pages to be sorted
+        :param bSort: A boolean indicating whether the logs are full or
+                partially full. If they are full, bSort is :const:`True`.
+
+        :return: The sorted and linked list of pages.
+
+        **Side Effects**: If the starting page cannot be found, this
+                method will fail an assertion.
+        """
+        # Convert lstPages deque to a regular Python list
+        lstPages = list(lstPages)
+
+        # Sort pages chronologically by finding the first active page.
+        # Since the pages are filled in order by page-id, the first
+        # non-full page is the last page written to.
+        if bSort:
+            for n in range(len(lstPages)):
+                if lstPages[0].write_offset != FULL_PAGE_WRITE_OFFSET:
+                    break
+                lstPages.append(lstPages.pop(0))
+            assert lstPages[0].write_offset != FULL_PAGE_WRITE_OFFSET, \
+                "Unable to find starting page"
+
+        # link pages
+        numPages = len(lstPages)
+        nMaxPage = 0
+        for n in range(numPages):
+            page = lstPages[n]
+            nMaxPage = max(nMaxPage, page.page_num)
+            page.previousPage = lstPages[n - 1]
+            page.nextPage = lstPages[(n + 1) % numPages]
+            page.iterated = False
+        assert (nMaxPage + 1) == numPages, \
+            "Missing log pages: max page %d, num pages %d" % \
+            (nMaxPage, numPages)
+
+        return lstPages
+
+    def log_info(self):
+        """
+        If DEBUG logging is turned on (command line parameter -v), logs the
+        instance variables of this LogPage_v0 to the output file. See the
+        Python :mod:`logging` module documentation and the IPC Logging main
+        function for more info on logging.
+
+        This method only logs the ``read_offset`` and
+        ``write_offset`` variables as the others are logged elsewhere.
+        """
+        logging.debug("\tread index:  %x" % (self.read_offset))
+        logging.debug("\twrite index: %x" % (self.write_offset))
+
+    def debug_save_log_pages(self, fIn, filename, data, options):
+        """
+        Writes a binary file containing the data for the current page. This
+        is a helper to :func:`cmdParse`, and is particularly useful in
+        debugging.
+
+        :param fIn: The input file currently being processed by the caller
+        :param filename: The name of the input file currently being processed
+        :param data: The binary data for the current page
+        :param options: Configuration options containing options.output_dir for
+                        the output directory
+
+        **Side Effects**: Writes an output file containing the binary data
+                for the current page.
+        """
+        # Get just the filename, instead of the whole path.
+        # Otherwise the file open call will fail.
+        filename = os.path.split(filename)[1]
+
+        strDebugFileName = 'log-%d-%d-%s-%u.bin' % (self.log_id, self.page_num,
+                                                    filename, fIn.tell() -
+                                                    PAGE_SIZE)
+
+        if options.output_dir:
+            strDebugFileName = \
+                os.path.join(options.output_dir, strDebugFileName)
+
+        logging.info("Writing debug file '%s'\n", strDebugFileName)
+        fOut = open(strDebugFileName, 'wb')
+        fOut.write(data)
+        fOut.close()
+
+    def unpack(self, data):
+        """
+        Unpacks an ipc_log_page version 0 structure, and assigns the contents
+        into instance variables of this class. This is a wrapper around
+        the :func:`~struct.unpack()` function from the :mod:`struct` module.
+
+        :param data: The binary ipc_log_context structure to be unpacked.
+
+        :return: :const:`True` if the unpack completes successfully,
+                :const:`False` if not.
+
+        **Side Effects**: If the unpack is successful, the contexts are
+                assigned to instance variables. In this way, :meth:`unpack()`
+                acts as a sort of constructor. This is common to all the
+                unpack methods.
+        """
+        self.data = data
+        self.magic, self.nmagic, self.log_id, self.page_num, \
+            self.read_offset, self.write_offset = \
+            struct.unpack(self.headerBinaryFormat,
+                          self.data[0:self.headerBinaryFormatSize])
+
+        # Mask off the top bit of page_num, which is used to indicate
+        # a version 1 or greater page
+        mask = 0x7FFFFFFF
+        self.page_num = self.page_num & mask
+
+        if self.magic == MAGIC and self.nmagic == NMAGIC:
+            return True
+
+        return False
+
+    def pack(self, nLogId, nPageNum, nReadOffset, nWriteOffset, strPayload):
+        """
+        Packs a new version 0 page structure.  *strPayload* can be empty and
+        additional payload can be added using :meth:`~LogPage.pack_continue()`.
+
+        :param nLogId: The log ID to be packed into the new structure
+        :param nPageNum: The page number
+        :param nReadOffset: The read offset
+        :param nWriteOffset: The write offset
+        :param strPayload: The payload of the new structure
+
+        :return: Overflow data (*strPayload* that didn't fit into the page)
+              or :const:`None` if all fit.
+        """
+        data = struct.pack(self.headerBinaryFormat, MAGIC, NMAGIC,
+                           nLogId, nPageNum, nReadOffset, nWriteOffset)
+
+        # add padding for list structures
+        data += '\0' * (self.page_header_size - len(data))
+
+        # append message payload
+        self.data = data + strPayload or ''
+
+        if len(self.data) > PAGE_SIZE:
+            data = self.data[PAGE_SIZE:]
+            self.data = self.data[0:PAGE_SIZE]
+            return data
+        else:
+            return None
+
 
 class LogPage_v1(LogPage):
-	"""
-	A single page in a version 0 IPC Logging log. This class is a descendant of
-	:class:`LogPage`.
-
-	.. code-block:: c
-
-		struct ipc_log_page_header {
-			uint32_t magic;
-			uint32_t nmagic;
-			uint32_t page_num;
-			uint16_t read_offset;
-			uint16_t write_offset;
-			uint64_t log_id;
-			uint64_t start_time;
-			uint64_t end_time;
-			int64_t context_offset;
-
-			/* add local data structures after this point */
-			struct list_head list;
-			uint16_t nd_read_offset;
-		};
-	"""
-	def __init__(self):
-		# Call the parent constructor
-		super(self.__class__, self).__init__()
-		self.headerBinaryFormat = '<IIIHHQQQq'
-		self.headerBinaryFormatSize = struct.calcsize(self.headerBinaryFormat)
-		self.context = LogContext()
-		self.context.header_size = V1_PAGE_HDR_SIZE
-		self.page_header_size = self.context.header_size
-
-	def sortAndLink(self, lstPages, bSort):
-		"""
-		Given a list of pages in ascending page number order,
-		sort them chronologically and link the pages together.
-		This must be called before iterating over items in a page.
-
-		:param lstPages: The list of pages to be sorted
-		:param bSort: A boolean indicating whether the logs are full or \
-				partially full. If they are full, bSort is :const:`True`.
-
-		:return: The sorted and linked list of pages.
-
-		**Side Effects**: If the starting page cannot be found, this \
-				method will fail an assertion.
-		"""
-		# Sort pages chronologically by finding the first active page.
-		# Since the pages are filled in order by page-id, the first
-		# non-full page is the last page written to.
-		if bSort:
-			# Rotate to lowest non-zero end time
-			min_end_time = None
-			min_start_time = None
-			min_end_position = 0
-			min_start_position = 0
-			for n in range(len(lstPages)):
-				cur_end_time = lstPages[n].get_end_time()
-				if cur_end_time == 0:
-					continue
-
-				if not min_end_time:
-					min_end_time = cur_end_time
-					min_end_position = n
-					continue
-
-				if cur_end_time > 0 and cur_end_time < min_end_time:
-					min_end_time = cur_end_time
-					min_end_position = n
-
-			min_position = min_end_position
-			if lstPages[min_end_position].read_offset == 0:
-				for n in range(len(lstPages)):
-					cur_start_time = lstPages[n].get_start_time()
-					if cur_start_time == 0:
-						continue
-
-					if not min_start_time:
-						min_start_time = cur_start_time
-						min_start_position = n
-						continue
-
-					if cur_start_time > 0 and cur_start_time < min_start_time:
-						min_start_time = cur_start_time
-						min_start_position = n
-
-				if lstPages[min_start_position].read_offset != 0:
-					min_position = min_start_position
-
-			lstPages.rotate(-min_position)
-			lstPages = list(lstPages)
-
-		# link pages
-		numPages = len(lstPages)
-		nMaxPage = 0
-		for n in range(numPages):
-			page = lstPages[n]
-			nMaxPage = max(nMaxPage, page.page_num)
-			page.previousPage = lstPages[n - 1]
-			page.nextPage = lstPages[(n + 1) % numPages]
-		assert (nMaxPage + 1) == numPages, \
-				"Missing log pages: max page %d, num pages %d" % \
-					(nMaxPage, numPages)
-
-		return lstPages
-
-	def log_info(self):
-		"""
-		If DEBUG logging is turned on (command line parameter -v), logs the
-		instance variables of this LogPage_v1 to the output file. See the Python
-		:mod:`logging` module documentation and the IPC Logging main function
-		for more info on logging.
-
-		This method logs the ``read_offset``, ``write_offset``, ``start_time``,
-		``end_time``, and ``context_offset`` variables.
-		"""
-		logging.debug("\tread index:  %x" % (self.read_offset))
-		logging.debug("\twrite index: %x" % (self.write_offset))
-		logging.debug("\tstart_time (seconds): %f" % (self.start_time * math.pow(10, -9)))
-		logging.debug("\tend_time (seconds): %f" % (self.end_time * math.pow(10, -9)))
-		logging.debug("\tcontext_offset: %x" % (self.context_offset))
-
-	def debug_save_log_pages(self, fIn, filename, data, name, options):
-		"""
-		If DEBUG logging is turned on, writes a binary file containing the data
-		for the current page. This is a helper to :func:`cmdParse`.
-
-		:param fIn: The input file currently being processed by the caller
-		:param filename: The name of the input file currently being processed
-		:param data: The binary data for the current page
-		:param options: Configuration options containing options.output_dir for
-						the output directory
-
-		**Side Effects**: Writes an output file containing the binary data \
-				for the current page.
-		"""
-		# Get just the filename, instead of the whole path.
-		# Otherwise the file open call will fail.
-		filename = os.path.split(filename)[1]
-
-		strDebugFileName = 'log-%s-%d-%s-%u.bin' % (name, self.page_num,
-			filename, fIn.tell() - PAGE_SIZE)
-
-		if options.output_dir:
-			strDebugFileName = \
-					os.path.join(options.output_dir, strDebugFileName)
-
-		logging.info("Writing debug file '%s'\n", strDebugFileName)
-		fOut = open(strDebugFileName, 'wb')
-		fOut.write(data)
-		fOut.close()
-
-	def unpack(self, data):
-		"""
-		Unpacks an ipc_log_page version 1 structure, and assigns the contents
-		into instance variables of this class. This is a wrapper around
-		the :func:`~struct.unpack()` function from the :mod:`struct` module.
-
-		:param data: The binary ipc_log_context structure to be unpacked.
-
-		:return: :const:`True` if the unpack completes successfully, \
-				:const:`False` if not.
-
-		**Side Effects**: If the unpack is successful, the contexts are \
-				assigned to instance variables. In this way, :meth:`unpack()` \
-				acts as a sort of constructor. This is common to all the \
-				unpack methods.
-		"""
-		self.data=data
-		self.magic, self.nmagic, self.page_num, self.read_offset, \
-				self.write_offset, self.log_id, self.start_time, \
-				self.end_time, self.context_offset = \
-				struct.unpack(self.headerBinaryFormat,
-							self.data[0:self.headerBinaryFormatSize])
-
-		# Mask off the top bit of page_num, which is used to indicate
-		# a version 1 or greater page
-		mask = 0x7FFFFFFF
-		self.page_num = self.page_num & mask
-
-		if self.magic == MAGIC and self.nmagic == NMAGIC:
-			return True
-
-		return False
-
-	def pack(self, nPageNum, nReadOffset, nWriteOffset, nLogId,
-			nStartTime, nEndTime, nContextOffset, strPayload):
-		"""
-		Packs a new version 1 page structure.  *strPayload* can be empty and
-		additional payload can be added using :meth:`~LogPage.pack_continue()`.
-
-		:param nPageNum: The page number to be packed into the new structure
-		:param nReadOffset: The read offset
-		:param nWriteOffset: The write offset
-		:param nLogId: The log ID
-		:param nStartTime: The start time
-		:param nEndTime: The end time
-		:param nContextOffset: The context offset
-		:param strPayload: The payload of the new structure
-
-		:return: Overflow data (*strPayload* that didn't fit into the page) or \
-				:const:`None` if all fit.
-		"""
-
-		data = struct.pack(self.headerBinaryFormat, MAGIC, NMAGIC,
-				nPageNum, nReadOffset, nWriteOffset, nLogId, nStartTime,
-				nEndTime, nContextOffset)
-
-		# add padding for list structures
-		data += '\0' * (self.page_header_size - len(data))
-
-		# append message payload
-		self.data = data + strPayload or ''
-
-		if len(self.data) > PAGE_SIZE:
-			data = self.data[PAGE_SIZE:]
-			self.data = self.data[0:PAGE_SIZE]
-			return data
-		else:
-			return None
-
-	def setContext(self, context):
-		"""
-		Sets the ``context`` field of this log page to *context*, and sets the
-		``page_header_size`` field to the context header size
-		(``context.header_size``). This method should be used whenever a page's
-		context is changed in order to make sure the page's information about
-		its context is consistent.
-
-		:param context: The :class:`LogContext` object to be assigned to this \
-				page
-		"""
-		self.context = context
-		self.page_header_size = self.context.header_size
-
-	#@staticmethod
-	def get_end_time(self):
-		return self.end_time
-
-	#@staticmethod
-	def get_start_time(self):
-		return self.start_time
+    """
+    A single page in a version 0 IPC Logging log. This class is a descendant of
+    :class:`LogPage`.
+
+    .. code-block:: c
+
+        struct ipc_log_page_header {
+            uint32_t magic;
+            uint32_t nmagic;
+            uint32_t page_num;
+            uint16_t read_offset;
+            uint16_t write_offset;
+            uint64_t log_id;
+            uint64_t start_time;
+            uint64_t end_time;
+            int64_t context_offset;
+
+            /* add local data structures after this point */
+            struct list_head list;
+            uint16_t nd_read_offset;
+        };
+    """
+    def __init__(self):
+        # Call the parent constructor
+        super(self.__class__, self).__init__()
+        self.headerBinaryFormat = '<IIIHHQQQq'
+        self.headerBinaryFormatSize = struct.calcsize(self.headerBinaryFormat)
+        self.context = LogContext()
+        self.context.header_size = V1_PAGE_HDR_SIZE
+        self.page_header_size = self.context.header_size
+
+    def sortAndLink(self, lstPages, bSort):
+        """
+        Given a list of pages in ascending page number order,
+        sort them chronologically and link the pages together.
+        This must be called before iterating over items in a page.
+
+        :param lstPages: The list of pages to be sorted
+        :param bSort: A boolean indicating whether the logs are full or
+                partially full. If they are full, bSort is :const:`True`.
+
+        :return: The sorted and linked list of pages.
+
+        **Side Effects**: If the starting page cannot be found, this
+                method will fail an assertion.
+        """
+        # Sort pages chronologically by finding the first active page.
+        # Since the pages are filled in order by page-id, the first
+        # non-full page is the last page written to.
+        if bSort:
+            # Rotate to lowest non-zero end time
+            min_end_time = None
+            min_start_time = None
+            min_end_position = 0
+            min_start_position = 0
+            for n in range(len(lstPages)):
+                cur_end_time = lstPages[n].get_end_time()
+                if cur_end_time == 0:
+                    continue
+
+                if not min_end_time:
+                    min_end_time = cur_end_time
+                    min_end_position = n
+                    continue
+
+                if cur_end_time > 0 and cur_end_time < min_end_time:
+                    min_end_time = cur_end_time
+                    min_end_position = n
+
+            min_position = min_end_position
+            if lstPages[min_end_position].read_offset == 0:
+                for n in range(len(lstPages)):
+                    cur_start_time = lstPages[n].get_start_time()
+                    if cur_start_time == 0:
+                        continue
+
+                    if not min_start_time:
+                        min_start_time = cur_start_time
+                        min_start_position = n
+                        continue
+
+                    if cur_start_time > 0 and cur_start_time < min_start_time:
+                        min_start_time = cur_start_time
+                        min_start_position = n
+
+                if lstPages[min_start_position].read_offset != 0:
+                    min_position = min_start_position
+
+            lstPages.rotate(-min_position)
+            lstPages = list(lstPages)
+
+        # link pages
+        numPages = len(lstPages)
+        nMaxPage = 0
+        for n in range(numPages):
+            page = lstPages[n]
+            nMaxPage = max(nMaxPage, page.page_num)
+            page.previousPage = lstPages[n - 1]
+            page.nextPage = lstPages[(n + 1) % numPages]
+        assert (nMaxPage + 1) == numPages, \
+            "Missing log pages: max page %d, num pages %d" % \
+            (nMaxPage, numPages)
+
+        return lstPages
+
+    def log_info(self):
+        """
+        If DEBUG logging is turned on (command line parameter -v), logs the
+        instance variables of this LogPage_v1 to the output file. See the
+        Python :mod:`logging` module documentation and the IPC Logging main
+        function for more info on logging.
+
+        This method logs the ``read_offset``, ``write_offset``, ``start_time``,
+        ``end_time``, and ``context_offset`` variables.
+        """
+        logging.debug("\tread index:  %x" % (self.read_offset))
+        logging.debug("\twrite index: %x" % (self.write_offset))
+        logging.debug("\tstart_time (seconds): %f" %
+                      (self.start_time * math.pow(10, -9)))
+        logging.debug("\tend_time (seconds): %f" %
+                      (self.end_time * math.pow(10, -9)))
+        logging.debug("\tcontext_offset: %x" % (self.context_offset))
+
+    def debug_save_log_pages(self, fIn, filename, data, name, options):
+        """
+        If DEBUG logging is turned on, writes a binary file containing the data
+        for the current page. This is a helper to :func:`cmdParse`.
+
+        :param fIn: The input file currently being processed by the caller
+        :param filename: The name of the input file currently being processed
+        :param data: The binary data for the current page
+        :param options: Configuration options containing options.output_dir for
+                        the output directory
+
+        **Side Effects**: Writes an output file containing the binary data
+                for the current page.
+        """
+        # Get just the filename, instead of the whole path.
+        # Otherwise the file open call will fail.
+        filename = os.path.split(filename)[1]
+
+        strDebugFileName = 'log-%s-%d-%s-%u.bin' % (name, self.page_num,
+                                                    filename,
+                                                    fIn.tell() - PAGE_SIZE)
+
+        if options.output_dir:
+            strDebugFileName = \
+                os.path.join(options.output_dir, strDebugFileName)
+
+        logging.info("Writing debug file '%s'\n", strDebugFileName)
+        fOut = open(strDebugFileName, 'wb')
+        fOut.write(data)
+        fOut.close()
+
+    def unpack(self, data):
+        """
+        Unpacks an ipc_log_page version 1 structure, and assigns the contents
+        into instance variables of this class. This is a wrapper around
+        the :func:`~struct.unpack()` function from the :mod:`struct` module.
+
+        :param data: The binary ipc_log_context structure to be unpacked.
+
+        :return: :const:`True` if the unpack completes successfully,
+                :const:`False` if not.
+
+        **Side Effects**: If the unpack is successful, the contexts are
+                assigned to instance variables. In this way, :meth:`unpack()`
+                acts as a sort of constructor. This is common to all the
+                unpack methods.
+        """
+        self.data = data
+        self.magic, self.nmagic, self.page_num, self.read_offset, \
+            self.write_offset, self.log_id, self.start_time, \
+            self.end_time, self.context_offset = \
+            struct.unpack(self.headerBinaryFormat,
+                          self.data[0:self.headerBinaryFormatSize])
+
+        # Mask off the top bit of page_num, which is used to indicate
+        # a version 1 or greater page
+        mask = 0x7FFFFFFF
+        self.page_num = self.page_num & mask
+
+        if self.magic == MAGIC and self.nmagic == NMAGIC:
+            return True
+
+        return False
+
+    def pack(self, nPageNum, nReadOffset, nWriteOffset, nLogId,
+             nStartTime, nEndTime, nContextOffset, strPayload):
+        """
+        Packs a new version 1 page structure.  *strPayload* can be empty and
+        additional payload can be added using :meth:`~LogPage.pack_continue()`.
+
+        :param nPageNum: The page number to be packed into the new structure
+        :param nReadOffset: The read offset
+        :param nWriteOffset: The write offset
+        :param nLogId: The log ID
+        :param nStartTime: The start time
+        :param nEndTime: The end time
+        :param nContextOffset: The context offset
+        :param strPayload: The payload of the new structure
+
+        :return: Overflow data (*strPayload* that didn't fit into the page)
+              or :const:`None` if all fit.
+        """
+
+        data = struct.pack(self.headerBinaryFormat, MAGIC, NMAGIC,
+                           nPageNum, nReadOffset, nWriteOffset, nLogId,
+                           nStartTime, nEndTime, nContextOffset)
+
+        # add padding for list structures
+        data += '\0' * (self.page_header_size - len(data))
+
+        # append message payload
+        self.data = data + strPayload or ''
+
+        if len(self.data) > PAGE_SIZE:
+            data = self.data[PAGE_SIZE:]
+            self.data = self.data[0:PAGE_SIZE]
+            return data
+        else:
+            return None
+
+    def setContext(self, context):
+        """
+        Sets the ``context`` field of this log page to *context*, and sets the
+        ``page_header_size`` field to the context header size
+        (``context.header_size``). This method should be used whenever a page's
+        context is changed in order to make sure the page's information about
+        its context is consistent.
+
+        :param context: The :class:`LogContext` object to be assigned to this
+                page
+        """
+        self.context = context
+        self.page_header_size = self.context.header_size
+
+    def get_end_time(self):
+        return self.end_time
+
+    def get_start_time(self):
+        return self.start_time
+
 
 class PageIterator(object):
-	"""
-	An iterator object for use by the :class:`LogPage` iterator method.
-	"""
-
-	def __init__(self, page):
-		self.page = page
-
-	def __iter__(self):
-		# TODO - clear all iteration flags
-		logging.debug("Starting iteration through page %d" % \
-				(self.page.page_num))
-
-	def next(self):
-		while True:
-			try:
-				return self.page.next()
-			except StopIteration:
-				logging.debug("Trying next page")
-				self.page = self.page.nextPage
-				if self.page.iterated:
-					logging.debug("Page %d already iterated" % \
-							(self.page.page_num))
-					raise
-				logging.debug("Iterating through page %d" % \
-						(self.page.page_num))
-
-				# This isn't right.  The page iterator is just discarded
-				# and then we are calling the .next.
-				self.page.__iter__()
+    """
+    An iterator object for use by the :class:`LogPage` iterator method.
+    """
+
+    def __init__(self, page):
+        self.page = page
+
+    def __iter__(self):
+        # TODO - clear all iteration flags
+        logging.debug("Starting iteration through page %d" %
+                      (self.page.page_num))
+
+    def next(self):
+        while True:
+            try:
+                return self.page.next()
+            except StopIteration:
+                logging.debug("Trying next page")
+                self.page = self.page.nextPage
+                if self.page.iterated:
+                    logging.debug("Page %d already iterated" %
+                                  (self.page.page_num))
+                    raise
+                logging.debug("Iterating through page %d" %
+                              (self.page.page_num))
+
+                # This isn't right.  The page iterator is just discarded
+                # and then we are calling the .next.
+                self.page.__iter__()
+
 
 def dumpLogHelper(fout, pages, numPages, bSort):
-	"""
-	Handles iterating through the TSV messages in each :class:`LogPage` object
-	and dumping them to the output file for the current log ID. This function
-	is called by :func:`dumpLogWithRetry()`.
-
-	:param fout: The output file for the log currently being processed by \
-			:func:`dumpLogWithRetry()`.
-	:param pages: A list containing the :class:`LogPage` objects for the log \
-			currently being processed.
-	:param numPages: The number of pages in *pages*.
-	:param bSort: A boolean indicating whether all pages in the log are \
-			completely filled, or if some are partially full. If they are \
-			full, bSort is :const:`True`.
-
-	:return: :const:`True` if the messages are processed with no errors, \
-			:const:`False` if errors are encountered during iteration or \
-			during parsing of the TSV messages within the :class:`LogPage` \
-			objects.
-	"""
-	# sort pages chronologically
-	try:
-		lstPages = collections.deque()
-		presentKey = None
-
-		for key in pages.keys():
-			if not presentKey:
-				presentKey = key
-			lstPages.append(pages[key])
-
-		lstPages = pages[presentKey].sortAndLink(lstPages, bSort)
-	except AssertionError as e:
-		strMsg = "Exception: %s" % (str(e))
-		logging.error(strMsg)
-		fout.write(strMsg + '\n')
-		return False
-
-	# dump data in pages
-	try:
-		page = lstPages[0]
-		logging.debug("Extracting messages from %d" % (page.page_num))
-		last_unknown_data = ''
-		for x in page:
-			if page.unknown_messages_data and \
-					page.unknown_messages_data != last_unknown_data:
-				fout.write(str(page.unknown_messages_data) + "\n")
-				last_unknown_data = page.unknown_messages_data
-
-			fout.write("\n" + str(x).strip())
-
-	except AssertionError as e:
-		strMsg = "Exception: %s" % (str(e))
-		logging.debug(strMsg)
-		fout.write(strMsg + '\n')
-		return False
-
-	return True
+    """
+    Handles iterating through the TSV messages in each :class:`LogPage` object
+    and dumping them to the output file for the current log ID. This function
+    is called by :func:`dumpLogWithRetry()`.
+
+    :param fout: The output file for the log currently being processed by
+            :func:`dumpLogWithRetry()`.
+    :param pages: A list containing the :class:`LogPage` objects for the log
+            currently being processed.
+    :param numPages: The number of pages in *pages*.
+    :param bSort: A boolean indicating whether all pages in the log are
+            completely filled, or if some are partially full. If they are
+            full, bSort is :const:`True`.
+
+    :return: :const:`True` if the messages are processed with no errors,
+            :const:`False` if errors are encountered during iteration or
+            during parsing of the TSV messages within the :class:`LogPage`
+            objects.
+    """
+    # sort pages chronologically
+    try:
+        lstPages = collections.deque()
+        presentKey = None
+
+        for key in pages.keys():
+            if not presentKey:
+                presentKey = key
+            lstPages.append(pages[key])
+
+        lstPages = pages[presentKey].sortAndLink(lstPages, bSort)
+    except AssertionError as e:
+        strMsg = "Exception: %s" % (str(e))
+        logging.error(strMsg)
+        fout.write(strMsg + '\n')
+        return False
+
+    # dump data in pages
+    try:
+        page = lstPages[0]
+        logging.debug("Extracting messages from %d" % (page.page_num))
+        last_unknown_data = ''
+        for x in page:
+            if page.unknown_messages_data and \
+                    page.unknown_messages_data != last_unknown_data:
+                fout.write(str(page.unknown_messages_data) + "\n")
+                last_unknown_data = page.unknown_messages_data
+
+            fout.write("\n" + str(x).strip())
+
+    except AssertionError as e:
+        strMsg = "Exception: %s" % (str(e))
+        logging.debug(strMsg)
+        fout.write(strMsg + '\n')
+        return False
+
+    return True
+
 
 def dumpLogWithRetry(logId, name, version, pages, numPages, test, options):
-	"""
-	This function is called by :func:`dumpLogs()` and :func:`cmdTest()`. It
-	handles creating output files for the parsed logs and writing data to them.
-	A significant part of this work is delegated to :func:`dumpLogHelper()`.
-
-	:param logId: The log ID currently being processed
-	:param name: The name of the log context
-	:param version: The version of the log
-	:param pages: List of pages to process and dump to the output file
-	:param numPages: The number of pages in the current log
-	:param test: True if this function was called by cmdTest
-	:param options: Configuration options containing options.output_dir for the
-					output directory
-	"""
-	if version >= 1:
-		strFileName = "ipc-log-%s.txt" % (str(name))
-		titleStr = "Log name: %s (%d pages)\n" % (str(name), numPages)
-	else:
-		strFileName = "ipc-log-%s.txt" % (str(logId))
-		titleStr = "Log id %s (%d pages)\n" % (str(logId), numPages)
-
-	if test:
-		strFileName = "ipc-log-%s.txt" % (str(name))
-
-	if options.output_dir:
-		strFileName = \
-				os.path.join(options.output_dir, strFileName)
-
-	fout = open(strFileName, 'w')
-	logging.info("Writing log file '%s'" % (strFileName))
-
-	fout.write('-'*70 + "\n")
-	fout.write(titleStr)
-	fout.write('-'*70 + "\n")
-
-	# Parse logs assuming they have wrapped (are full)
-	fout.write("Parsing as a full log\n")
-	bSuccess = dumpLogHelper(fout, pages, numPages, True)
-	if not bSuccess:
-		# If that fails, try assuming that they are partially-full
-		strMsg = "Unable to parse as full log, retrying as partial log"
-		logging.info(strMsg)
-		fout.write(strMsg + '\n')
-		bSuccess = dumpLogHelper(fout, pages, numPages, False)
-
-
-	if bSuccess:
-		strMsg = "Log extracted successfully"
-		logging.info(strMsg)
-		fout.write('\n' + strMsg + '\n')
-	else:
-		strMsg = "Could not extract log successfully. See %s for details." % \
-				(strFileName)
-		if version == 0:
-			v0_expl_str = \
-"""
-You are parsing a v0 log. If you collected logs using debugfs before the system
-crashed, it may have adversely affected the RAM dumps. Collect the logs again
-without using debugfs, or use the newest version of IPC Logging if possible.
-This issue has been resolved in v1 and above.
-"""
-			fout.write(v0_expl_str)
-		logging.info(strMsg)
+    """
+    This function is called by :func:`dumpLogs()` and :func:`cmdTest()`. It
+    handles creating output files for the parsed logs and writing data to them.
+    A significant part of this work is delegated to :func:`dumpLogHelper()`.
+
+    :param logId: The log ID currently being processed
+    :param name: The name of the log context
+    :param version: The version of the log
+    :param pages: List of pages to process and dump to the output file
+    :param numPages: The number of pages in the current log
+    :param test: True if this function was called by cmdTest
+    :param options: Configuration options containing options.output_dir for the
+                    output directory
+    """
+    if version >= 1:
+        strFileName = "ipc-log-%s.txt" % (str(name))
+        titleStr = "Log name: %s (%d pages)\n" % (str(name), numPages)
+    else:
+        strFileName = "ipc-log-%s.txt" % (str(logId))
+        titleStr = "Log id %s (%d pages)\n" % (str(logId), numPages)
+
+    if test:
+        strFileName = "ipc-log-%s.txt" % (str(name))
+
+    if options.output_dir:
+        strFileName = \
+            os.path.join(options.output_dir, strFileName)
+
+    fout = open(strFileName, 'w')
+    logging.info("Writing log file '%s'" % (strFileName))
+
+    fout.write('-'*70 + "\n")
+    fout.write(titleStr)
+    fout.write('-'*70 + "\n")
+
+    # Parse logs assuming they have wrapped (are full)
+    fout.write("Parsing as a full log\n")
+    bSuccess = dumpLogHelper(fout, pages, numPages, True)
+    if not bSuccess:
+        # If that fails, try assuming that they are partially-full
+        strMsg = "Unable to parse as full log, retrying as partial log"
+        logging.info(strMsg)
+        fout.write(strMsg + '\n')
+        bSuccess = dumpLogHelper(fout, pages, numPages, False)
+
+    if bSuccess:
+        strMsg = "Log extracted successfully"
+        logging.info(strMsg)
+        fout.write('\n' + strMsg + '\n')
+    else:
+        strMsg = "Could not extract log successfully. See %s for details." % \
+                 (strFileName)
+        if version == 0:
+            v0_expl_str = \
+                """
+                You are parsing a v0 log. If you collected logs using debugfs
+                before the system crashed, it may have adversely affected the
+                RAM dumps. Collect the logs again without using debugfs, or
+                use the newest version of IPC Logging if possible. This issue
+                has been resolved in v1 and above.
+                """
+            fout.write(v0_expl_str)
+        logging.info(strMsg)
+
+    # Add a newline to stdout output
+    logging.info("")
+    fout.close()
 
-	# Add a newline to stdout output
-	logging.info("")
-	fout.close()
 
 def get_context(start_of_page, fIn, page, dictContexts, lstFiles, fileCount):
-	'''
-	Called by :func:`cmdParse()` in order the find and read the context for
-	the log page currently being processed. The context is found by reading
-	*page.context_offset* and using it to find the position of the context in
-	the "logical file" created by :func:`get_files_info()`. Once the input file
-	and position where the context resides have been calculated, the context can
-	be read, assigned to the *page.context* field, and added to the log ID-to-
-	context dictionary *dictContexts* using the :func:`read_context()` function.
-
-	:param start_of_page: The starting position in the current file of the \
-			page currently being processed
-	:param fIn: The input file
-	:param page: The page currently being processed
-	:param dictContexts: The dictionary that maintains the \
-			log ID-to-:class:`LogContext` mapping.
-	:param lstFiles: The "logical file" data structure, a list of dictionaries \
-			containing the name, starting position, and ending position of \
-			each input file.
-	:param fileCount: An index into *lstFiles*, which indicates the file \
-			currently being processed. For example, if *lstFiles* contains \
-			three input files and we are processing the second one, fileCount \
-			is 1.
-
-	:return: A :class:`LogContext` object containing the context that was \
-			found. If no context is found, returns :const:`None`.
-
-	**Side Effects**: There are some performance side effects in this \
-			function, as :meth:`file.seek()`, :meth:`file.read()`, and \
-			:meth:`file.tell()` are performed several times in order to \
-			extract the context based on *page.context_offset*. Since there \
-			may be multiple files and the context may not be in the current \
-			file, the other files may need to be opened and closed in order \
-			to find the context. \
-	'''
-	context = LogContext()
-	start_of_file = lstFiles[fileCount]['start']
-	end_of_file = lstFiles[fileCount]['end']
-	file_position = start_of_file + start_of_page + page.context_offset
-	data = None
-
-	logging.debug("start of file: 0x%x, end of file: 0x%x, " + \
-			"start of page: 0x%x, context offset: 0x%x, file position: 0x%x,",
-			start_of_file, end_of_file, start_of_page, page.context_offset,
-			file_position)
-
-	for inFile in lstFiles:
-		if inFile['start'] <= file_position <= inFile['end']:
-			# If the position is in the current file, don't open and close a
-			# temporary file - use fIn
-			if inFile['start'] == start_of_file:
-				saved_position = fIn.tell()
-				fIn.seek(file_position - start_of_file)
-				data = fIn.read(CTX_READ_SIZE)
-				fIn.seek(saved_position)
-			else:
-				tempIn = open(inFile['name'], 'rb')
-				tempIn.seek(file_position - inFile['start'])
-				data = tempIn.read(CTX_READ_SIZE)
-				tempIn.close()
-			break
-
-	assert data is not None, "Context not found"
-
-	context = read_context(page, data, dictContexts)
-	return context
+    """
+    Called by :func:`cmdParse()` in order the find and read the context for
+    the log page currently being processed. The context is found by reading
+    *page.context_offset* and using it to find the position of the context in
+    the "logical file" created by :func:`get_files_info()`. Once the input file
+    and position where the context resides have been calculated, the context
+    can be read, assigned to the *page.context* field, and added to the log
+    ID-to-context dictionary *dictContexts* using the :func:`read_context()`
+    function.
+
+    :param start_of_page: The starting position in the current file of the
+            page currently being processed
+    :param fIn: The input file
+    :param page: The page currently being processed
+    :param dictContexts: The dictionary that maintains the
+            log ID-to-:class:`LogContext` mapping.
+    :param lstFiles: The "logical file" data structure, a list of dictionaries
+            containing the name, starting position, and ending position of
+            each input file.
+    :param fileCount: An index into *lstFiles*, which indicates the file
+            currently being processed. For example, if *lstFiles* contains
+            three input files and we are processing the second one, fileCount
+            is 1.
+
+    :return: A :class:`LogContext` object containing the context that was
+            found. If no context is found, returns :const:`None`.
+
+    **Side Effects**: There are some performance side effects in this
+            function, as :meth:`file.seek()`, :meth:`file.read()`, and
+            :meth:`file.tell()` are performed several times in order to
+            extract the context based on *page.context_offset*. Since there
+            may be multiple files and the context may not be in the current
+            file, the other files may need to be opened and closed in order
+            to find the context.
+    """
+    context = LogContext()
+    start_of_file = lstFiles[fileCount]['start']
+    end_of_file = lstFiles[fileCount]['end']
+    file_position = start_of_file + start_of_page + page.context_offset
+    data = None
+
+    logging.debug("start of file: 0x%x, end of file: 0x%x, " +
+                  "start of page: 0x%x, context offset: 0x%x, " +
+                  "file position: 0x%x,",
+                  start_of_file, end_of_file, start_of_page,
+                  page.context_offset, file_position)
+
+    for inFile in lstFiles:
+        if inFile['start'] <= file_position <= inFile['end']:
+            # If the position is in the current file, don't open and close a
+            # temporary file - use fIn
+            if inFile['start'] == start_of_file:
+                saved_position = fIn.tell()
+                fIn.seek(file_position - start_of_file)
+                data = fIn.read(CTX_READ_SIZE)
+                fIn.seek(saved_position)
+            else:
+                tempIn = open(inFile['name'], 'rb')
+                tempIn.seek(file_position - inFile['start'])
+                data = tempIn.read(CTX_READ_SIZE)
+                tempIn.close()
+            break
+
+    assert data is not None, "Context not found"
+
+    context = read_context(page, data, dictContexts)
+    return context
+
 
 def read_context(page, data, dictContexts):
-	'''
-	Read a context from *data* and make it the context of *page* using
-	:meth:`LogPage_v1.setContext()`. Then update the log ID-to-context
-	dictionary (*dictContexts*), and return the context. In short, find
-	a log context in *data*, perform some bookkeeping, and return the context.
-	This is a helper function to :func:`get_context()`, which is a helper to
-	:func:`cmdParse()`.
-
-	:param page: The page to which the found context will be assigned
-	:param data: The data to be read
-	:param dictContexts: The dictionary where the context will be placed, if \
-			a new context is read
-
-	:return: The new context if successful, None if not.
-	'''
-	context = LogContext()
-
-	if data and len(data) >= CTX_READ_SIZE and context.unpack(data):
-		page.setContext(context)
-
-		if not context.log_id in dictContexts:
-			logging.info("Found log context: %s" % (context.name))
-			context.log_info()
-
-			# Log a single newline to the output
-			logging.info("")
-			dictContexts[page.log_id] = context
-
-		return context
-	else:
-		return None
+    """
+    Read a context from *data* and make it the context of *page* using
+    :meth:`LogPage_v1.setContext()`. Then update the log ID-to-context
+    dictionary (*dictContexts*), and return the context. In short, find
+    a log context in *data*, perform some bookkeeping, and return the context.
+    This is a helper function to :func:`get_context()`, which is a helper to
+    :func:`cmdParse()`.
+
+    :param page: The page to which the found context will be assigned
+    :param data: The data to be read
+    :param dictContexts: The dictionary where the context will be placed, if
+            a new context is read
+
+    :return: The new context if successful, None if not.
+    """
+    context = LogContext()
+
+    if data and len(data) >= CTX_READ_SIZE and context.unpack(data):
+        page.setContext(context)
+
+        if context.log_id not in dictContexts:
+            logging.info("Found log context: %s" % (context.name))
+            context.log_info()
+
+            # Log a single newline to the output
+            logging.info("")
+            dictContexts[page.log_id] = context
+
+        return context
+    else:
+        return None
+
 
 def check_log_consistency(dictLogs, dictContexts):
-	'''
-	Creates two sets:
-
-	* The set of log IDs gained from reading each page
-
-	* The set of log IDs gained from reading each context
-
-	Takes the intersection and makes sure that the intersection
-	equals both sets, i.e. that all log IDs found from reading pages
-	were found reading contexts, and vice-versa.
-
-	:param dictLogs: The dictionary of log IDs to :class:`LogPage` objects
-	:param dictContext: The dictionary of log IDs to :class:`LogContext` objects
-
-	:return: The difference of the two sets, contained in a :class:`set`.
-	'''
-	diff = None
-	context_log_ids = set(dictContexts.keys())
-	page_log_ids = set(dictLogs.keys())
-	intersection = context_log_ids.intersection(page_log_ids)
-	if intersection == page_log_ids == context_log_ids:
-		logging.debug("Logs are consistent - the same log IDs are " + \
-				"found in pages and contexts.")
-	else:
-		logging.error("Logs inconsistent.")
-		logging.error("Logs from contexts: %s",
-				str([hex(n) for n in context_log_ids]))
-		logging.error("Logs from pages: %s",
-				str([hex(n) for n in page_log_ids]))
-
-		if len(page_log_ids) > len(context_log_ids):
-			diff = page_log_ids - context_log_ids
-			logging.error("IDs from pages, but not contexts: %s",
-					str([hex(n) for n in diff]))
-		else:
-			diff = context_log_ids - page_log_ids
-			logging.error("IDs from contexts, but not pages: %s",
-					str([hex(n) for n in diff]))
-	return diff
+    """
+    Creates two sets:
+
+    * The set of log IDs gained from reading each page
+
+    * The set of log IDs gained from reading each context
+
+    Takes the intersection and makes sure that the intersection
+    equals both sets, i.e. that all log IDs found from reading pages
+    were found reading contexts, and vice-versa.
+
+    :param dictLogs: The dictionary of log IDs to :class:`LogPage` objects
+    :param dictContext: The dictionary of log IDs to :class:`LogContext`
+                        objects
+
+    :return: The difference of the two sets, contained in a :class:`set`.
+    """
+    diff = None
+    context_log_ids = set(dictContexts.keys())
+    page_log_ids = set(dictLogs.keys())
+    intersection = context_log_ids.intersection(page_log_ids)
+    if intersection == page_log_ids == context_log_ids:
+        logging.debug("Logs are consistent - the same log IDs are " +
+                      "found in pages and contexts.")
+    else:
+        logging.error("Logs inconsistent.")
+        logging.error("Logs from contexts: %s",
+                      str([hex(n) for n in context_log_ids]))
+        logging.error("Logs from pages: %s",
+                      str([hex(n) for n in page_log_ids]))
+
+        if len(page_log_ids) > len(context_log_ids):
+            diff = page_log_ids - context_log_ids
+            logging.error("IDs from pages, but not contexts: %s",
+                          str([hex(n) for n in diff]))
+        else:
+            diff = context_log_ids - page_log_ids
+            logging.error("IDs from contexts, but not pages: %s",
+                          str([hex(n) for n in diff]))
+    return diff
+
 
 def calc_file_size(fIn):
-	"""
-	Calculates the size of an input file.
-
-	:param fIn: The input file
-
-	:return: The file size, which is also the ending position relative to the \
-			start of the input file.
-
-	**Side Effects**: This function uses :meth:`file.seek()` and \
-			:meth:`file.tell()` to calculate the file size, which can have \
-			performance considerations. The original seek position of the file \
-			is saved at the beginning of the function and is restored before \
-			returning.
-	"""
-	saved_file_position = fIn.tell()
-	fIn.seek(0, 2)
-	file_size = fIn.tell()
-	fIn.seek(saved_file_position)
-	return file_size
+    """
+    Calculates the size of an input file.
+
+    :param fIn: The input file
+
+    :return: The file size, which is also the ending position relative to the
+             start of the input file.
+
+    **Side Effects**: This function uses :meth:`file.seek()` and
+            :meth:`file.tell()` to calculate the file size, which can have
+            performance considerations. The original seek position of the file
+            is saved at the beginning of the function and is restored before
+            returning.
+    """
+    saved_file_position = fIn.tell()
+    fIn.seek(0, 2)
+    file_size = fIn.tell()
+    fIn.seek(saved_file_position)
+    return file_size
+
 
 def get_files_info(files):
-	"""
-	Calculates the size of each input file and uses this information to build
-	a "logical file" data structure, which is a list of dictionaries, with one
-	dictionary per input file. Each dictionary contains the name of the file,
-	the starting position of the file, the ending position of the file, and
-	the size of the file. The starting position of the second file in the list
-	is the ending position of the first file in the list, and so on. Once the
-	structure is completely built, it can be used to index any position in any
-	of the input files as if they were one big file, without reading this big
-	file into memory. This allows the retrieval of contexts located in a
-	different file than their pages.
-
-	The file size calculation is done using the :func:`calc_file_size()`
-	function.
-
-	:param files: The list of input files
-
-	:return: The "logical file" data structure, a list of dictionaries \
-			containing information about each of the input files
-	"""
-	lstFiles = []
-	fileCount = 0
-	for strFile in files:
-		fileStart = 0
-
-		if fileCount > 0:
-			fileStart = (lstFiles[fileCount-1]['end'])
-
-		strFileSplit = strFile.split(':', 1)
-		fileName = strFileSplit[0]
-		if len(strFileSplit) > 1:
-			fileStart = int(strFileSplit[1], 16)
-
-		lstFiles.append(\
-				{'name': fileName, 'start': fileStart, 'end': 0, 'size': 0})
-		fIn = open(fileName, 'rb')
-		file_size = calc_file_size(fIn)
-
-		lstFiles[fileCount]['end'] = fileStart + file_size
-		lstFiles[fileCount]['size'] = file_size
-
-		fileCount += 1
-
-	return lstFiles
+    """
+    Calculates the size of each input file and uses this information to build
+    a "logical file" data structure, which is a list of dictionaries, with one
+    dictionary per input file. Each dictionary contains the name of the file,
+    the starting position of the file, the ending position of the file, and
+    the size of the file. The starting position of the second file in the list
+    is the ending position of the first file in the list, and so on. Once the
+    structure is completely built, it can be used to index any position in any
+    of the input files as if they were one big file, without reading this big
+    file into memory. This allows the retrieval of contexts located in a
+    different file than their pages.
+
+    The file size calculation is done using the :func:`calc_file_size()`
+    function.
+
+    :param files: The list of input files
+
+    :return: The "logical file" data structure, a list of dictionaries
+            containing information about each of the input files
+    """
+    lstFiles = []
+    fileCount = 0
+    for strFile in files:
+        fileStart = 0
+
+        if fileCount > 0:
+            fileStart = (lstFiles[fileCount-1]['end'])
+
+        strFileSplit = strFile.split(':', 1)
+        fileName = strFileSplit[0]
+        if len(strFileSplit) > 1:
+            fileStart = int(strFileSplit[1], 16)
+
+        lstFiles.append(
+            {'name': fileName, 'start': fileStart, 'end': 0, 'size': 0})
+        fIn = open(fileName, 'rb')
+        file_size = calc_file_size(fIn)
+
+        lstFiles[fileCount]['end'] = fileStart + file_size
+        lstFiles[fileCount]['size'] = file_size
+
+        fileCount += 1
+
+    return lstFiles
+
 
 def cmdParse(options):
-	"""
-	The top-level function, which is called from the main entry point to the
-	program if the ``parse`` command-line option is given. This function creates
-	two dictionaries, ``dictLogs`` and ``dictContexts``, which have log IDs as
-	keys and :class:`LogPage` and :class:`LogContext` objects as values,
-	respectively. It then populates these dictionaries by going through
-	each input file and reading data page-by-page. After all data has been read,
-	this function calls :func:`dumpLogs()` to dump the parsed logs to output
-	files.
-
-	:param options: Configuration options containing options.output_dir for the
-					output directory, options.debug_enabled, a flag for
-					discerning whether the extraction script is running in debug
-					mode, and options.args, the list of input files. All
-					configuration options are passed through to helper
-					functions.
-	"""
-	dictLogs = {}
-	dictContexts = {}
-	fileCount = 0
-	version = 0
-	versionIsOneOrGreater = False
-	lstFiles = get_files_info(options.args)
-
-	# scan files for log pages
-	for strFile in options.args:
-		fileName = strFile.split(':', 1)[0]
-		fIn = open(fileName,'rb')
-
-		logging.info("Parsing '%s'" % (fileName))
-		logging.info("-" * 70)
-		sys.stdout.flush()
-		page = LogPageVersionUnknown()
-		context = LogContext()
-		file_size = lstFiles[fileCount]['size']
-
-		while True:
-			start_of_page = fIn.tell()
-			data = fIn.read(16)
-
-			# PAGE_SIZE - 16 = 4080
-			if not data or len(data) + 4080 < PAGE_SIZE:
-				break
-
-			if page.unpack(data):
-				data += fIn.read(PAGE_SIZE-16)
-
-				if page.isVersionOneOrGreater(data):
-					versionIsOneOrGreater = True
-					page = LogPage_v1()
-				else:
-					versionIsOneOrGreater = False
-					page = LogPage_v0()
-
-				if page.unpack(data):
-					if versionIsOneOrGreater:
-						if not page.log_id in dictContexts:
-							try:
-								context = get_context(start_of_page, fIn, page,
-										dictContexts, lstFiles, fileCount)
-							except:
-								msg = "Context not found - skipping page " + \
-										"and trying to " + \
-										"continue with unknown log page version"
-								logging.debug(msg)
-								page = LogPageVersionUnknown()
-								continue
-
-						else:
-							context = dictContexts[page.log_id]
-							page.setContext(context)
-
-						if context is None:
-							logging.debug("Context at 0x%x had no data, " + \
-									"skipping this page", page.context_offset)
-							if options.debug_enabled:
-								page.log_info()
-							page = LogPageVersionUnknown()
-							continue
-
-						version = context.version
-
-					if not page.log_id in dictLogs:
-						dictLogs[page.log_id] = {}
-
-					if dictLogs[page.log_id].has_key(page.page_num):
-						logging.error("Duplicate page found log id 0x%x," + \
-								"page %d", page.log_id, page.page_num)
-
-					dictLogs[page.log_id][page.page_num] = page
-
-					if versionIsOneOrGreater:
-						logging.info(\
-								"Found log page - context: %s, id: 0x%x, " + \
-								"page: %d", page.context.name, \
-								page.log_id, page.page_num)
-						page.log_info()
-						sys.stdout.flush()
-					else:
-						logging.info("Found log page: id 0x%x, page %d" % \
-								(page.log_id, page.page_num))
-						page.log_info()
-						sys.stdout.flush()
-
-					# for debug mode, save the extracted log pages
-					if options.debug_enabled:
-						if version >= 1:
-							page.debug_save_log_pages(fIn, fileName, data,
-									context.name, options)
-						else:
-							page.debug_save_log_pages(fIn, fileName, data,
-									options)
-
-					page = LogPageVersionUnknown()
-
-		fIn.close()
-		fileCount += 1
-
-	# Check that log_ids received from contexts and from pages match
-	if versionIsOneOrGreater:
-		check_log_consistency(dictLogs, dictContexts)
-		dumpLogs(dictLogs, version, options)
-	else:
-		dumpLogs(dictLogs, 0, options)
-
-	logging.debug("lstFiles: " + str(lstFiles))
+    """
+    The top-level function, which is called from the main entry point to the
+    program if the ``parse`` command-line option is given. This function
+    creates two dictionaries, ``dictLogs`` and ``dictContexts``, which have log
+    IDs as keys and :class:`LogPage` and :class:`LogContext` objects as values,
+    respectively. It then populates these dictionaries by going through each
+    input file and reading data page-by-page. After all data has been read,
+    this function calls :func:`dumpLogs()` to dump the parsed logs to output
+    files.
+
+    :param options: Configuration options containing options.output_dir for the
+                    output directory, options.debug_enabled, a flag for
+                    discerning whether the extraction script is running in
+                    debug mode, and options.args, the list of input files. All
+                    configuration options are passed through to helper
+                    functions.
+    """
+    dictLogs = {}
+    dictContexts = {}
+    fileCount = 0
+    version = 0
+    versionIsOneOrGreater = False
+    lstFiles = get_files_info(options.args)
+
+    # scan files for log pages
+    for strFile in options.args:
+        fileName = strFile.split(':', 1)[0]
+        fIn = open(fileName, 'rb')
+
+        logging.info("Parsing '%s'" % (fileName))
+        logging.info("-" * 70)
+        sys.stdout.flush()
+        page = LogPageVersionUnknown()
+        context = LogContext()
+
+        while True:
+            start_of_page = fIn.tell()
+            data = fIn.read(16)
+
+            # PAGE_SIZE - 16 = 4080
+            if not data or len(data) + 4080 < PAGE_SIZE:
+                break
+
+            if page.unpack(data):
+                data += fIn.read(PAGE_SIZE-16)
+
+                if page.isVersionOneOrGreater(data):
+                    versionIsOneOrGreater = True
+                    page = LogPage_v1()
+                else:
+                    versionIsOneOrGreater = False
+                    page = LogPage_v0()
+
+                if page.unpack(data):
+                    if versionIsOneOrGreater:
+                        if page.log_id not in dictContexts:
+                            try:
+                                context = get_context(start_of_page, fIn, page,
+                                                      dictContexts, lstFiles,
+                                                      fileCount)
+                            except:
+                                msg = "Context not found - skipping page " + \
+                                      "and trying to continue with " + \
+                                      "unknown log page version"
+                                logging.debug(msg)
+                                page = LogPageVersionUnknown()
+                                continue
+
+                        else:
+                            context = dictContexts[page.log_id]
+                            page.setContext(context)
+
+                        if context is None:
+                            logging.debug("Context at 0x%x had no data, " +
+                                          "skipping this page",
+                                          page.context_offset)
+                            if options.debug_enabled:
+                                page.log_info()
+                            page = LogPageVersionUnknown()
+                            continue
+
+                        version = context.version
+
+                    if page.log_id not in dictLogs:
+                        dictLogs[page.log_id] = {}
+
+                    if page.page_num in dictLogs[page.log_id]:
+                        logging.error("Duplicate page found log id 0x%x," +
+                                      "page %d", page.log_id, page.page_num)
+
+                    dictLogs[page.log_id][page.page_num] = page
+
+                    if versionIsOneOrGreater:
+                        logging.info(
+                            "Found log page - context: %s, id: 0x%x, " +
+                            "page: %d", page.context.name,
+                            page.log_id, page.page_num)
+                        page.log_info()
+                        sys.stdout.flush()
+                    else:
+                        logging.info("Found log page: id 0x%x, page %d" %
+                                     (page.log_id, page.page_num))
+                        page.log_info()
+                        sys.stdout.flush()
+
+                    # for debug mode, save the extracted log pages
+                    if options.debug_enabled:
+                        if version >= 1:
+                            page.debug_save_log_pages(fIn, fileName, data,
+                                                      context.name, options)
+                        else:
+                            page.debug_save_log_pages(fIn, fileName, data,
+                                                      options)
+
+                    page = LogPageVersionUnknown()
+
+        fIn.close()
+        fileCount += 1
+
+    # Check that log_ids received from contexts and from pages match
+    if versionIsOneOrGreater:
+        check_log_consistency(dictLogs, dictContexts)
+        dumpLogs(dictLogs, version, options)
+    else:
+        dumpLogs(dictLogs, 0, options)
+
+    logging.debug("lstFiles: " + str(lstFiles))
+
 
 def dumpLogs(dictLogs, version, options):
-	"""
-	Dump logs from the dictionary of log IDs to logs built by
-	:func:`cmdParse()`. This is called at the end of :func:`cmdParse()`,
-	after all files have been processed and the dictionary has been built.
-
-	:param dictLogs: The dictionary built by :func:`cmdParse()`.
-	:param version: The IPC Logging version.
-	:param options: Configuration options passed through to helper functions
-
-	**Side Effects**: The :func:`dumpLogWithRetry()` function is called, \
-			which dumps the parsed logs to output files.
-	"""
-	# dump the logs
-	logs = dictLogs.keys()
-	logs.sort()
-	logging.debug("Logs: %s", logs)
-	for key in logs:
-		pages = dictLogs[key]
-		numPages = len(pages.keys())
-
-		if version >= 1:
-			first_page_in_log = dictLogs[key].keys()[0]
-			name = dictLogs[key][first_page_in_log].context.name
-		else:
-			name = None
-
-		dumpLogWithRetry(key, name, version, pages, numPages, False, options)
+    """
+    Dump logs from the dictionary of log IDs to logs built by
+    :func:`cmdParse()`. This is called at the end of :func:`cmdParse()`,
+    after all files have been processed and the dictionary has been built.
+
+    :param dictLogs: The dictionary built by :func:`cmdParse()`.
+    :param version: The IPC Logging version.
+    :param options: Configuration options passed through to helper functions
+
+    **Side Effects**: The :func:`dumpLogWithRetry()` function is called,
+            which dumps the parsed logs to output files.
+    """
+    # dump the logs
+    logs = dictLogs.keys()
+    logs.sort()
+    logging.debug("Logs: %s", logs)
+    for key in logs:
+        pages = dictLogs[key]
+        numPages = len(pages.keys())
+
+        if version >= 1:
+            first_page_in_log = dictLogs[key].keys()[0]
+            name = dictLogs[key][first_page_in_log].context.name
+        else:
+            name = None
+
+        dumpLogWithRetry(key, name, version, pages, numPages, False, options)
+
 
 def cmdTest(options):
-	"""
-	Parses the provided log page files in order and extracts the logs. This is
-	useful for testing and for dealing with failure cases (such as duplicate
-	logs due to left-over log pages from previous boot cycles).
-
-	:param options: Configuration options containing options.output_dir for
-					the output directory, and options.args, the list of input
-					files, and options.arch_64, the flag indicating if the log
-					pages should be interpreted as 64-bit dumps or not. All
-					configuration options are passed through to helper
-					functions.
-	"""
-	dictPages = {}
-	version = 0
-	numPages = 0
-
-	# load existing files
-	lstFiles = options.args
-
-	try:
-		version = int(lstFiles.pop())
-	except ValueError as e:
-		strMsg = "Version must be provided! Exiting..."
-		logging.error("Exception: %s\n%s\n" % (str(e), strMsg))
-		raise
-
-	for f in lstFiles:
-		data = open(f, 'rb').read()
-
-		page = LogPageVersionUnknown()
-		assert page.unpack(data) == True, "Unable to open file '%s'" % (f)
-
-		if page.isVersionOneOrGreater(data):
-			page = LogPage_v1()
-			page.unpack(data)
-		else:
-			page = LogPage_v0()
-			page.unpack(data)
-
-		numPages += 1
-		dictPages[page.page_num] = page
-		logging.info("Loaded '%s' log id %d, page %d" % \
-				(f, page.log_id, page.page_num))
-		page.log_info()
-
-		try:
-			if options.arch_64:
-				page.page_header_size = PAGE_HDR_SIZES_64[version]
-			else:
-				page.page_header_size = PAGE_HDR_SIZES[version]
-		except IndexError as e:
-			strMsg = "Invalid version! Exiting..."
-			logging.error("Exception: %s\n%s\n" % (str(e), strMsg))
-			raise
-
-	# Use only the last pathname component, as the rest of the path is
-	# added in dumpLogWithRetry()
-	if options.output_dir:
-		filename = os.path.split(lstFiles[0])[1]
-	else:
-		filename = lstFiles[0]
-
-	# dump the logs (in the same order provided)
-	dumpLogWithRetry(page.log_id, 'test-log-%s' % (filename),
-			version, dictPages, numPages, True, options)
+    """
+    Parses the provided log page files in order and extracts the logs. This is
+    useful for testing and for dealing with failure cases (such as duplicate
+    logs due to left-over log pages from previous boot cycles).
+
+    :param options: Configuration options containing options.output_dir for
+                    the output directory, and options.args, the list of input
+                    files, and options.arch_64, the flag indicating if the log
+                    pages should be interpreted as 64-bit dumps or not. All
+                    configuration options are passed through to helper
+                    functions.
+    """
+    dictPages = {}
+    version = 0
+    numPages = 0
+
+    # load existing files
+    lstFiles = options.args
+
+    try:
+        version = int(lstFiles.pop())
+    except ValueError as e:
+        strMsg = "Version must be provided! Exiting..."
+        logging.error("Exception: %s\n%s\n" % (str(e), strMsg))
+        raise
+
+    for f in lstFiles:
+        data = open(f, 'rb').read()
+
+        page = LogPageVersionUnknown()
+        assert page.unpack(data) is True, "Unable to open file '%s'" % (f)
+
+        if page.isVersionOneOrGreater(data):
+            page = LogPage_v1()
+            page.unpack(data)
+        else:
+            page = LogPage_v0()
+            page.unpack(data)
+
+        numPages += 1
+        dictPages[page.page_num] = page
+        logging.info("Loaded '%s' log id %d, page %d" %
+                     (f, page.log_id, page.page_num))
+        page.log_info()
+
+        try:
+            if options.arch_64:
+                page.page_header_size = PAGE_HDR_SIZES_64[version]
+            else:
+                page.page_header_size = PAGE_HDR_SIZES[version]
+        except IndexError as e:
+            strMsg = "Invalid version! Exiting..."
+            logging.error("Exception: %s\n%s\n" % (str(e), strMsg))
+            raise
+
+    # Use only the last pathname component, as the rest of the path is
+    # added in dumpLogWithRetry()
+    if options.output_dir:
+        filename = os.path.split(lstFiles[0])[1]
+    else:
+        filename = lstFiles[0]
+
+    # dump the logs (in the same order provided)
+    dumpLogWithRetry(page.log_id, 'test-log-%s' % (filename),
+                     version, dictPages, numPages, True, options)
+
 
 class LoggingFormatter(logging.Formatter):
-	"""
-	Custom logging formatter that prints all INFO messages without formatting
-	and all other messages with the appropriate level name.
+    """
+    Custom logging formatter that prints all INFO messages without formatting
+    and all other messages with the appropriate level name.
+
+    See :mod:`logging` documentation for more info on Python logging.
+    """
+    infoFormat = '%(message)s'
+    defaultFormat = '%(levelname)s %(module)s:%(lineno)d: %(message)s'
 
-	See :mod:`logging` documentation for more info on Python logging.
-	"""
-	infoFormat = '%(message)s'
-	defaultFormat = '%(levelname)s %(module)s:%(lineno)d: %(message)s'
+    def __init__(self, fmt=defaultFormat):
+        logging.Formatter.__init__(self, fmt)
 
-	def __init__(self, fmt=defaultFormat):
-		logging.Formatter.__init__(self, fmt)
+    def format(self, record):
+        if record.levelno == logging.INFO:
+            self._fmt = self.infoFormat
+        else:
+            self._fmt = self.defaultFormat
+        return logging.Formatter.format(self, record)
 
-	def format(self, record):
-		if record.levelno == logging.INFO:
-			self._fmt = self.infoFormat
-		else:
-			self._fmt = self.defaultFormat
-		return logging.Formatter.format(self, record)
 
 def configure_logging(options, stdout):
-	"""
-	Configure the logging options.
-
-	:param options: The options object, which contains options.verbosity for
-					the logging verbosity and options.debug_enabled to indicate
-					whether the extraction script is running in debug mode.
-	:param stdout:	Whether or not to create a logging handler for stdout
-	"""
-
-	if stdout:
-		loggingHandler = logging.StreamHandler(sys.stdout)
-		loggingHandler.setFormatter(LoggingFormatter())
-		logging.root.addHandler(loggingHandler)
-
-	# Set Log level
-	LOG_LEVELS = {	3: logging.DEBUG,
-					2: logging.INFO,
-					1: logging.WARNING,
-					0: logging.ERROR,
-				  }
-	assert LOG_LEVELS.has_key(options.verbosity), "Unknown log level %d" % \
-			(options.verbosity)
-	logging.root.setLevel(LOG_LEVELS[options.verbosity])
-
-	if logging.root.getEffectiveLevel >= 2 and options.quiet:
-		logging.root.setLevel(LOG_LEVELS[1])
-
-	options.debug_enabled = False
-	if options.verbosity >= 3:
-		options.debug_enabled = True
+    """
+    Configure the logging options.
+
+    :param options: The options object, which contains options.verbosity for
+                    the logging verbosity and options.debug_enabled to indicate
+                    whether the extraction script is running in debug mode.
+    :param stdout:  Whether or not to create a logging handler for stdout
+    """
+
+    if stdout:
+        loggingHandler = logging.StreamHandler(sys.stdout)
+        loggingHandler.setFormatter(LoggingFormatter())
+        logging.root.addHandler(loggingHandler)
+
+    # Set Log level
+    LOG_LEVELS = {3: logging.DEBUG,
+                  2: logging.INFO,
+                  1: logging.WARNING,
+                  0: logging.ERROR}
+
+    assert options.verbosity in LOG_LEVELS, "Unknown log level %d" % \
+        (options.verbosity)
+    logging.root.setLevel(LOG_LEVELS[options.verbosity])
+
+    if logging.root.getEffectiveLevel >= 2 and options.quiet:
+        logging.root.setLevel(LOG_LEVELS[1])
+
+    options.debug_enabled = False
+    if options.verbosity >= 3:
+        options.debug_enabled = True
+
 
 def set_output_directory(options):
-	"""
-	Set up the output directory.
+    """
+    Set up the output directory.
 
-	:param options: Configuration options containing options.output_dir for the
-					output directory
+    :param options: Configuration options containing options.output_dir for the
+                    output directory
 
-	:return: The output logging handler object, or None if no output directory
-			was provided by the user.
-	"""
-	if not options.output_dir:
-		return None
+    :return: The output logging handler object, or None if no output directory
+            was provided by the user.
+    """
+    if not options.output_dir:
+        return None
 
-	options.output_dir = \
-			os.path.abspath(os.path.expanduser(options.output_dir))
+    options.output_dir = \
+        os.path.abspath(os.path.expanduser(options.output_dir))
 
-	# Create output directory if it does not exist
-	if not os.path.isdir(options.output_dir):
-		os.makedirs(options.output_dir)
+    # Create output directory if it does not exist
+    if not os.path.isdir(options.output_dir):
+        os.makedirs(options.output_dir)
 
-	# Create logging handler to take output in this directory
-	output_logging_handler = \
-			logging.FileHandler(\
-			os.path.join(options.output_dir, "ipc_extraction_report.txt"),
-			"w")
-	output_logging_handler.setFormatter(LoggingFormatter())
-	logging.root.addHandler(output_logging_handler)
+    # Create logging handler to take output in this directory
+    output_logging_handler = \
+        logging.FileHandler(
+            os.path.join(options.output_dir, "ipc_extraction_report.txt"),
+            "w")
+    output_logging_handler.setFormatter(LoggingFormatter())
+    logging.root.addHandler(output_logging_handler)
 
-	logging.info("Output path: " + options.output_dir)
-	return output_logging_handler
+    logging.info("Output path: " + options.output_dir)
+    return output_logging_handler
 
-#------------------------------------------------------------------------
+# ------------------------------------------------------------------------
 # Main Program Entry Point
-#------------------------------------------------------------------------
+# ------------------------------------------------------------------------
 if __name__ == '__main__':
-	# Parse command line
-	strUsage = """\
+    # Parse command line
+    strUsage = """\
 %prog CMD [OPTIONS]
 
 parse
@@ -1726,13 +1762,12 @@ Examples:
 \t%prog parse DDRCS0.BIN DDRCS1.BIN
 \t%prog parse DDRCS0_0.BIN DDRCS0_1.BIN DDRCS1_0.BIN DDRCS1_1.BIN
 \t%prog parse DDRCS0_0.BIN DDRCS0_1.BIN DDRCS1_0.BIN:0x80000000 DDRCS1_1.BIN
-\t%prog parse DDRCS0_0.BIN:0x00000000 DDRCS0_1.BIN:0x30000000 DDRCS1_0.BIN:0x80000000 DDRCS1_1.BIN:0xb0000000
 
 It is only necessary to provide the starting address of a memory dump file if
-the dumps are not contiguous in memory. Whether or not the dumps are contiguous,
-along with their starting addresses, can be found in the file load.cmm which
-is usually included in crash dumps. Starting addresses must be provided in
-hexadecimal.
+the dumps are not contiguous in memory. Whether or not the dumps are
+contiguous, along with their starting addresses, can be found in the file
+load.cmm which is usually included in crash dumps. Starting addresses must be
+provided in hexadecimal.
 
 test
 ----
@@ -1764,8 +1799,8 @@ Verbosity
 Debug logging can be enabled using the count -v or --verbose option.  The
 log level based upon the number of occurrences of the -v option will be one of
 the following:
-	ERROR/WARNING/INFO	Default
-	DEBUG			(-v)
+    ERROR/WARNING/INFO  Default
+    DEBUG           (-v)
 
 Quiet
 -----
@@ -1793,58 +1828,57 @@ Examples:
 \t%prog parse -o ~/test_output DDRCS0.BIN DDRCS1.BIN
 \t%prog test -v -o ~/test_output LOG_PAGE_FILE(s)
 """
-	parser = OptionParser(usage=strUsage)
-	if len(sys.argv) < 2:
-		parser.error('Command required')
+    parser = OptionParser(usage=strUsage)
+    if len(sys.argv) < 2:
+        parser.error('Command required')
 
-	strCmd = (sys.argv[1]).lower()
+    strCmd = (sys.argv[1]).lower()
 
-	parser.add_option("-v", "--verbose",
-	  action="count", dest="verbosity", default=2,
-	  help="Log program status to stdout (-v = debug)"
-	)
+    parser.add_option("-v", "--verbose",
+                      action="count", dest="verbosity", default=2,
+                      help="Log program status to stdout (-v = debug)")
 
-	parser.add_option("-q", "--quiet",
-	  action="count", dest="quiet", default=False,
-	  help="Log no program status to stdout (-q = quiet)"
-	)
+    parser.add_option("-q", "--quiet",
+                      action="count", dest="quiet", default=False,
+                      help="Log no program status to stdout (-q = quiet)")
 
-	parser.add_option("-o", "--output",
-			action="store", type="string", dest="output_dir",
-			help="If the current directory can't be written to, specify \
-					a path for an output directory. The path is \
-					OS-independent, and can be absolute or relative.")
+    parser.add_option("-o", "--output",
+                      action="store", type="string", dest="output_dir",
+                      help="If the current directory can't be written to, \
+                            specify a path for an output directory. The path \
+                            is OS-independent, and can be absolute or \
+                            relative.")
 
-	parser.add_option("", "--64-bit",
-			action="store_true", dest="arch_64",
-			help="For use with the test command. Interpret the log pages as \
-			64-bit dumps.")
+    parser.add_option("", "--64-bit",
+                      action="store_true", dest="arch_64",
+                      help="For use with the test command. Interpret the log \
+                            pages as 64-bit dumps.")
 
-	(options, args) = parser.parse_args(sys.argv[2:])
-	options.cmd = strCmd
+    (options, args) = parser.parse_args(sys.argv[2:])
+    options.cmd = strCmd
 
-	if args:
-		# extract positions args (args not associated with flags)
-		options.args = args
+    if args:
+        # extract positions args (args not associated with flags)
+        options.args = args
 
-	# Configure logging format
-	configure_logging(options, True)
+    # Configure logging format
+    configure_logging(options, True)
 
-	if not options.cmd or options.cmd == "help":
-			parser.error('No command/help specified')
-			exit(1)
+    if not options.cmd or options.cmd == "help":
+            parser.error('No command/help specified')
+            exit(1)
 
-	output_logging_handler = set_output_directory(options)
+    output_logging_handler = set_output_directory(options)
 
-	dictCmds = {'parse': cmdParse,
-				'test': cmdTest,
-				}
+    dictCmds = {'parse': cmdParse,
+                'test': cmdTest,
+                }
 
-	# run the requested command
-	if not dictCmds.has_key(options.cmd):
-			parser.error("Unknown command '%s'" % (options.cmd))
+    # run the requested command
+    if options.cmd not in dictCmds:
+            parser.error("Unknown command '%s'" % (options.cmd))
 
-	dictCmds[options.cmd](options)
+    dictCmds[options.cmd](options)
 
-	if options.output_dir:
-		output_logging_handler.close()
+    if options.output_dir:
+        output_logging_handler.close()