docs: def parse_resources_directory(self, rva, size=0, base_rva = None, level = 0, dirs=None):
          """Parse the resources directory.
          
          Given the RVA of the resources directory, it will process all
          its entries.
          
          The root will have the corresponding member of its structure,
          IMAGE_RESOURCE_DIRECTORY plus 'entries', a list of all the
          entries in the directory.
          
          Those entries will have, correspondingly, all the structure's
          members (IMAGE_RESOURCE_DIRECTORY_ENTRY) and an additional one,
          "directory", pointing to the IMAGE_RESOURCE_DIRECTORY structure
          representing upper layers of the tree. This one will also have
          an 'entries' attribute, pointing to the 3rd, and last, level.
          Another directory with more entries. Those last entries will
          have a new attribute (both 'leaf' or 'data_entry' can be used to
          access it). This structure finally points to the resource data.
          All the members of this structure, IMAGE_RESOURCE_DATA_ENTRY,
          are available as its attributes.
          """
          
          # OC Patch:
          if dirs is None:
              dirs = [rva]
          
          if base_rva is None:
              base_rva = rva
          
          resources_section = self.get_section_by_rva(rva)
          
          try:
              # If the RVA is invalid all would blow up. Some EXEs seem to be
              # specially nasty and have an invalid RVA.
              data = self.get_data(rva, Structure(self.__IMAGE_RESOURCE_DIRECTORY_format__).sizeof() )
          except PEFormatError, e:
              self.__warnings.append(
                  'Invalid resources directory. Can\'t read ' +
                  'directory data at RVA: 0x%x' % rva)
              return None
          
          # Get the resource directory structure, that is, the header
          # of the table preceding the actual entries
          #
          resource_dir = self.__unpack_data__(
              self.__IMAGE_RESOURCE_DIRECTORY_format__, data,
              file_offset = self.get_offset_from_rva(rva) )
          if resource_dir is None:
              # If can't parse resources directory then silently return.
              # This directory does not necessarily have to be valid to
              # still have a valid PE file
              self.__warnings.append(
                  'Invalid resources directory. Can\'t parse ' +
                  'directory data at RVA: 0x%x' % rva)
              return None
          
          dir_entries = []
          
          # Advance the RVA to the positon immediately following the directory
          # table header and pointing to the first entry in the table
          #
          rva += resource_dir.sizeof()
          
          number_of_entries = (
              resource_dir.NumberOfNamedEntries +
              resource_dir.NumberOfIdEntries )
          
          # Set a hard limit on the maximum resonable number of entries
          MAX_ALLOWED_ENTRIES = 4096
          if number_of_entries > MAX_ALLOWED_ENTRIES:
              self.__warnings.append(
                  'Error parsing the resources directory, '
                  'The directory contains %d entries (>%s)' %
                  (number_of_entries, MAX_ALLOWED_ENTRIES) )
              return None
          
          strings_to_postprocess = list()
          
          for idx in xrange(number_of_entries):
              
              
              res = self.parse_resource_entry(rva)
              if res is None:
                  self.__warnings.append(
                      'Error parsing the resources directory, '
                      'Entry %d is invalid, RVA = 0x%x. ' %
                      (idx, rva) )
                  break
              
              entry_name = None
              entry_id = None
              
              # If all named entries have been processed, only Id ones
              # remain
              
              if idx >= resource_dir.NumberOfNamedEntries:
                  entry_id = res.Name
              else:
                  ustr_offset = base_rva+res.NameOffset
                  try:
                      #entry_name = self.get_string_u_at_rva(ustr_offset, max_length=16)
                      entry_name = UnicodeStringWrapperPostProcessor(self, ustr_offset)
                      strings_to_postprocess.append(entry_name)
                  
                  except PEFormatError, excp:
                      self.__warnings.append(
                          'Error parsing the resources directory, '
                          'attempting to read entry name. '
                          'Can\'t read unicode string at offset 0x%x' %
                          (ustr_offset) )
                  
              
              if res.DataIsDirectory:
                  # OC Patch:
                  #
                  # One trick malware can do is to recursively reference
                  # the next directory. This causes hilarity to ensue when
                  # trying to parse everything correctly.
                  # If the original RVA given to this function is equal to
                  # the next one to parse, we assume that it's a trick.
                  # Instead of raising a PEFormatError this would skip some
                  # reasonable data so we just break.
                  #
                  # 9ee4d0a0caf095314fd7041a3e4404dc is the offending sample
                  if (base_rva + res.OffsetToDirectory) in dirs:
                      
                      break
                  
                  else:
                      entry_directory = self.parse_resources_directory(
                          base_rva+res.OffsetToDirectory,
                          size-(rva-base_rva), # size
                          base_rva=base_rva, level = level+1,
                          dirs=dirs + [base_rva + res.OffsetToDirectory])
                  
                  if not entry_directory:
                      break
                      
                  # Ange Albertini's code to process resources' strings
                  #
                  strings = None
                  if entry_id == RESOURCE_TYPE['RT_STRING']:
                      strings = dict()
                      for resource_id in entry_directory.entries:
                          if hasattr(resource_id, 'directory'):
                              for resource_lang in resource_id.directory.entries:
                                  
                                  resource_strings = dict()
                                  
                                  string_entry_rva = resource_lang.data.struct.OffsetToData
                                  string_entry_size = resource_lang.data.struct.Size
                                  string_entry_id = resource_id.id
                                  
                                  if resource_lang.data.struct.Size is None or resource_id.id is None:
                                      continue
                                      
                                  string_entry_data = self.get_data(string_entry_rva, string_entry_size)
                                  parse_strings( string_entry_data, (int(string_entry_id) - 1) * 16, resource_strings )
                                  strings.update(resource_strings)
                                  
                              resource_id.directory.strings = resource_strings
                                  
                  dir_entries.append(
                      ResourceDirEntryData(
                          struct = res,
                          name = entry_name,
                          id = entry_id,
                          directory = entry_directory))
              
              else:
                  struct = self.parse_resource_data_entry(
                      base_rva + res.OffsetToDirectory)
                  
                  if struct:
                      entry_data = ResourceDataEntryData(
                          struct = struct,
                          lang = res.Name & 0x3ff,
                          sublang = res.Name >> 10 )
                      
                      dir_entries.append(
                          ResourceDirEntryData(
                              struct = res,
                              name = entry_name,
                              id = entry_id,
                              data = entry_data))
                  
                  else:
                      break
                  
              
              
              # Check if this entry contains version information
              #
              if level == 0 and res.Id == RESOURCE_TYPE['RT_VERSION']:
                  if len(dir_entries)>0:
                      last_entry = dir_entries[-1]
                  
                  rt_version_struct = None
                  try:
                      rt_version_struct = last_entry.directory.entries[0].directory.entries[0].data.struct
                  except:
                      # Maybe a malformed directory structure...?
                      # Lets ignore it
                      pass
                  
                  if rt_version_struct is not None:
                      self.parse_version_information(rt_version_struct)
              
              rva += res.sizeof()
                      
          
          string_rvas = [s.get_rva() for s in strings_to_postprocess]
          string_rvas.sort()
          
          for idx, s in enumerate(strings_to_postprocess):
              s.render_pascal_16()
              
          
          resource_directory_data = ResourceDirData(
              struct = resource_dir,
              entries = dir_entries)
          
          return resource_directory_data