///|
pub fn PEImage::imports(self : Self) -> Array[ImportLibrary] raise PeError {
  let directory = match self.directory(1) {
    Some(directory) if directory.virtual_address != 0UL && directory.size > 0 =>
      directory
    _ => return []
  }
  let descriptor_offset = self.rva_to_offset(directory.virtual_address)
  let directory_limit = if directory.size >= 20 {
    directory.size / 20
  } else {
    4096
  }
  let descriptor_limit = if directory_limit < 4096 {
    directory_limit
  } else {
    4096
  }
  let libraries = []
  for index in 0.. Array[ImportSymbol] raise PeError {
  if thunk_rva == 0UL {
    return []
  }
  let entry_size = if self.is_64_bit() { 8 } else { 4 }
  let symbols = []
  let mut index = 0
  while index < 65536 {
    let entry = if self.is_64_bit() {
      let offset = self.rva_to_offset(
        thunk_rva + (index * entry_size).to_uint64(),
      )
      read_u64(self.data, offset)
    } else {
      let offset = self.rva_to_offset(
        thunk_rva + (index * entry_size).to_uint64(),
      )
      read_u32(self.data, offset)
    }
    if entry == 0UL {
      break
    }
    let ordinal_mask = if self.is_64_bit() {
      0x8000000000000000UL
    } else {
      0x80000000UL
    }
    if entry.land(ordinal_mask) != 0UL {
      symbols.push({
        name: None,
        ordinal: Some(entry.land(0xffffUL).to_int()),
        hint: None,
      })
    } else {
      let name_rva = if self.is_64_bit() {
        entry.land(0x7fffffffffffffffUL)
      } else {
        entry.land(0x7fffffffUL)
      }
      let name_offset = self.rva_to_offset(name_rva)
      let hint = read_u16(self.data, name_offset)
      let name = read_ascii_z(self.data, name_offset + 2, 4096)
      symbols.push({ name: Some(name), ordinal: None, hint: Some(hint), })
    }
    index = index + 1
  }
  symbols
}