docs: def dump_info(self, dump=None):
          """Dump all the PE header information into human readable string."""
          
          
          if dump is None:
              dump = Dump()
          
          warnings = self.get_warnings()
          if warnings:
              dump.add_header('Parsing Warnings')
              for warning in warnings:
                  dump.add_line(warning)
                  dump.add_newline()
          
          
          dump.add_header('DOS_HEADER')
          dump.add_lines(self.DOS_HEADER.dump())
          dump.add_newline()
          
          dump.add_header('NT_HEADERS')
          dump.add_lines(self.NT_HEADERS.dump())
          dump.add_newline()
          
          dump.add_header('FILE_HEADER')
          dump.add_lines(self.FILE_HEADER.dump())
          
          image_flags = retrieve_flags(IMAGE_CHARACTERISTICS, 'IMAGE_FILE_')
          
          dump.add('Flags: ')
          flags = []
          for flag in image_flags:
              if getattr(self.FILE_HEADER, flag[0]):
                  flags.append(flag[0])
          dump.add_line(', '.join(flags))
          dump.add_newline()
          
          if hasattr(self, 'OPTIONAL_HEADER') and self.OPTIONAL_HEADER is not None:
              dump.add_header('OPTIONAL_HEADER')
              dump.add_lines(self.OPTIONAL_HEADER.dump())
          
          dll_characteristics_flags = retrieve_flags(DLL_CHARACTERISTICS, 'IMAGE_DLL_CHARACTERISTICS_')
          
          dump.add('DllCharacteristics: ')
          flags = []
          for flag in dll_characteristics_flags:
              if getattr(self.OPTIONAL_HEADER, flag[0]):
                  flags.append(flag[0])
          dump.add_line(', '.join(flags))
          dump.add_newline()
          
          
          dump.add_header('PE Sections')
          
          section_flags = retrieve_flags(SECTION_CHARACTERISTICS, 'IMAGE_SCN_')
          
          for section in self.sections:
              dump.add_lines(section.dump())
              dump.add('Flags: ')
              flags = []
              for flag in section_flags:
                  if getattr(section, flag[0]):
                      flags.append(flag[0])
              dump.add_line(', '.join(flags))
              dump.add_line('Entropy: %f (Min=0.0, Max=8.0)' % section.get_entropy() )
              if md5 is not None:
                  dump.add_line('MD5     hash: %s' % section.get_hash_md5() )
              if sha1 is not None:
                  dump.add_line('SHA-1   hash: %s' % section.get_hash_sha1() )
              if sha256 is not None:
                  dump.add_line('SHA-256 hash: %s' % section.get_hash_sha256() )
              if sha512 is not None:
                  dump.add_line('SHA-512 hash: %s' % section.get_hash_sha512() )
              dump.add_newline()
              
          
          
          if (hasattr(self, 'OPTIONAL_HEADER') and
              hasattr(self.OPTIONAL_HEADER, 'DATA_DIRECTORY') ):
              
              dump.add_header('Directories')
              for idx in xrange(len(self.OPTIONAL_HEADER.DATA_DIRECTORY)):
                  directory = self.OPTIONAL_HEADER.DATA_DIRECTORY[idx]
                  dump.add_lines(directory.dump())
              dump.add_newline()
              
          
          def convert_char(char):
              if char in string.ascii_letters or char in string.digits or char in string.punctuation or char in string.whitespace:
                  return char
              else:
                  return r'\x%02x' % ord(char)
                  
          def convert_to_printable(s):
              return ''.join([convert_char(c) for c in s])
          
          if hasattr(self, 'VS_VERSIONINFO'):
              dump.add_header('Version Information')
              dump.add_lines(self.VS_VERSIONINFO.dump())
              dump.add_newline()
              
              if hasattr(self, 'VS_FIXEDFILEINFO'):
                  dump.add_lines(self.VS_FIXEDFILEINFO.dump())
                  dump.add_newline()
              
              if hasattr(self, 'FileInfo'):
                  for entry in self.FileInfo:
                      dump.add_lines(entry.dump())
                      dump.add_newline()
                      
                      if hasattr(entry, 'StringTable'):
                          for st_entry in entry.StringTable:
                              [dump.add_line('  '+line) for line in st_entry.dump()]
                              dump.add_line('  LangID: '+st_entry.LangID)
                              dump.add_newline()
                              for str_entry in st_entry.entries.items():
                                  dump.add_line( '    ' +
                                      convert_to_printable(str_entry[0]) + ': ' +
                                      convert_to_printable(str_entry[1]) )
                          dump.add_newline()
                      
                      elif hasattr(entry, 'Var'):
                          for var_entry in entry.Var:
                              if hasattr(var_entry, 'entry'):
                                  [dump.add_line('  '+line) for line in var_entry.dump()]
                                  dump.add_line(
                                      '    ' + 
                                      convert_to_printable(var_entry.entry.keys()[0]) +
                                      ': ' + var_entry.entry.values()[0])
                          
                          dump.add_newline()
  
              
          
          if hasattr(self, 'DIRECTORY_ENTRY_EXPORT'):
              dump.add_header('Exported symbols')
              dump.add_lines(self.DIRECTORY_ENTRY_EXPORT.struct.dump())
              dump.add_newline()
              dump.add_line('%-10s   %-10s  %s' % ('Ordinal', 'RVA', 'Name'))
              for export in self.DIRECTORY_ENTRY_EXPORT.symbols:
                  if export.address is not None:
                      dump.add('%-10d 0x%08Xh    %s' % (
                          export.ordinal, export.address, export.name))
                      if export.forwarder:
                          dump.add_line(' forwarder: %s' % export.forwarder)
                      else:
                          dump.add_newline()
              
              dump.add_newline()
          
          if hasattr(self, 'DIRECTORY_ENTRY_IMPORT'):
              dump.add_header('Imported symbols')
              for module in self.DIRECTORY_ENTRY_IMPORT:
                  dump.add_lines(module.struct.dump())
                  dump.add_newline()
                  for symbol in module.imports:
                      
                      if symbol.import_by_ordinal is True:
                          dump.add('%s Ordinal[%s] (Imported by Ordinal)' % (
                              module.dll, str(symbol.ordinal)))
                      else:
                          dump.add('%s.%s Hint[%s]' % (
                              module.dll, symbol.name, str(symbol.hint)))
                      
                      if symbol.bound:
                          dump.add_line(' Bound: 0x%08X' % (symbol.bound))
                      else:
                          dump.add_newline()
                  dump.add_newline()
          
          
          if hasattr(self, 'DIRECTORY_ENTRY_BOUND_IMPORT'):
              dump.add_header('Bound imports')
              for bound_imp_desc in self.DIRECTORY_ENTRY_BOUND_IMPORT:
                  
                  dump.add_lines(bound_imp_desc.struct.dump())
                  dump.add_line('DLL: %s' % bound_imp_desc.name)
                  dump.add_newline()
                  
                  for bound_imp_ref in bound_imp_desc.entries:
                      dump.add_lines(bound_imp_ref.struct.dump(), 4)
                      dump.add_line('DLL: %s' % bound_imp_ref.name, 4)
                      dump.add_newline()
  
          
          if hasattr(self, 'DIRECTORY_ENTRY_DELAY_IMPORT'):
              dump.add_header('Delay Imported symbols')
              for module in self.DIRECTORY_ENTRY_DELAY_IMPORT:
                  
                  dump.add_lines(module.struct.dump())
                  dump.add_newline()
                  
                  for symbol in module.imports:
                      if symbol.import_by_ordinal is True:
                          dump.add('%s Ordinal[%s] (Imported by Ordinal)' % (
                              module.dll, str(symbol.ordinal)))
                      else:
                          dump.add('%s.%s Hint[%s]' % (
                              module.dll, symbol.name, str(symbol.hint)))
                      
                      if symbol.bound:
                          dump.add_line(' Bound: 0x%08X' % (symbol.bound))
                      else:
                          dump.add_newline()
                  dump.add_newline()
          
          
          if hasattr(self, 'DIRECTORY_ENTRY_RESOURCE'):
              dump.add_header('Resource directory')
              
              dump.add_lines(self.DIRECTORY_ENTRY_RESOURCE.struct.dump())
              
              for resource_type in self.DIRECTORY_ENTRY_RESOURCE.entries:
                  
                  if resource_type.name is not None:
                      dump.add_line('Name: [%s]' % resource_type.name, 2)
                  else:
                      dump.add_line('Id: [0x%X] (%s)' % (
                          resource_type.struct.Id, RESOURCE_TYPE.get(
                              resource_type.struct.Id, '-')),
                          2)
                  
                  dump.add_lines(resource_type.struct.dump(), 2)
                  
                  if hasattr(resource_type, 'directory'):
                      
                      dump.add_lines(resource_type.directory.struct.dump(), 4)
                      
                      for resource_id in resource_type.directory.entries:
                          
                          if resource_id.name is not None:
                              dump.add_line('Name: [%s]' % resource_id.name, 6)
                          else:
                              dump.add_line('Id: [0x%X]' % resource_id.struct.Id, 6)
                          
                          dump.add_lines(resource_id.struct.dump(), 6)
                          
                          if hasattr(resource_id, 'directory'):
                              dump.add_lines(resource_id.directory.struct.dump(), 8)
                              
                              for resource_lang in resource_id.directory.entries:
                                  if hasattr(resource_lang, 'data'):
                                      dump.add_line('\\--- LANG [%d,%d][%s,%s]' % (
                                          resource_lang.data.lang,
                                          resource_lang.data.sublang,
                                          LANG.get(resource_lang.data.lang, '*unknown*'), 
                                          get_sublang_name_for_lang( resource_lang.data.lang, resource_lang.data.sublang ) ), 8)
                                      dump.add_lines(resource_lang.struct.dump(), 10)
                                      dump.add_lines(resource_lang.data.struct.dump(), 12)
                              if hasattr(resource_id.directory, 'strings') and resource_id.directory.strings:
                                  dump.add_line( '[STRINGS]' , 10 )
                                  for idx, res_string in resource_id.directory.strings.items():
                                      dump.add_line( '%6d: %s' % (idx, convert_to_printable(res_string) ), 12 )
                                          
                  dump.add_newline()
              
              dump.add_newline()
          
          
          if ( hasattr(self, 'DIRECTORY_ENTRY_TLS') and
               self.DIRECTORY_ENTRY_TLS and
               self.DIRECTORY_ENTRY_TLS.struct ):
              
              dump.add_header('TLS')
              dump.add_lines(self.DIRECTORY_ENTRY_TLS.struct.dump())
              dump.add_newline()
          
          
          if ( hasattr(self, 'DIRECTORY_ENTRY_LOAD_CONFIG') and
               self.DIRECTORY_ENTRY_LOAD_CONFIG and
               self.DIRECTORY_ENTRY_LOAD_CONFIG.struct ):
               
              dump.add_header('LOAD_CONFIG')
              dump.add_lines(self.DIRECTORY_ENTRY_LOAD_CONFIG.struct.dump())
              dump.add_newline()
          
          
          if hasattr(self, 'DIRECTORY_ENTRY_DEBUG'):
              dump.add_header('Debug information')
              for dbg in self.DIRECTORY_ENTRY_DEBUG:
                  dump.add_lines(dbg.struct.dump())
                  try:
                      dump.add_line('Type: '+DEBUG_TYPE[dbg.struct.Type])
                  except KeyError:
                      dump.add_line('Type: 0x%x(Unknown)' % dbg.struct.Type)
                  dump.add_newline()
          
          
          if hasattr(self, 'DIRECTORY_ENTRY_BASERELOC'):
              dump.add_header('Base relocations')
              for base_reloc in self.DIRECTORY_ENTRY_BASERELOC:
                  dump.add_lines(base_reloc.struct.dump())
                  for reloc in base_reloc.entries:
                      try:
                          dump.add_line('%08Xh %s' % (
                              reloc.rva, RELOCATION_TYPE[reloc.type][16:]), 4)
                      except KeyError:
                          dump.add_line('0x%08X 0x%x(Unknown)' % (
                              reloc.rva, reloc.type), 4)
                  dump.add_newline()
  
          
          return dump.get_text()