void
MEMRemoveListObject(MemoryList *list, void *object)
{
   void *head = nullptr;

   if (!object) {
      return;
   }

   if (list->head == object && list->tail == object) {
      // Clear list
      list->head = nullptr;
      list->tail = nullptr;
      list->count = 0;
      return;
   }

   if (list->head == object) {
      // Remove from head
      list->head = MEMGetNextListObject(list, list->head);
      getLink(list, list->tail)->prev = nullptr;
      list->count--;
      return;
   }

   if (list->tail == object) {
      // Remove from tail
      list->tail = MEMGetPrevListObject(list, list->tail);
      getLink(list, list->tail)->next = nullptr;
      list->count--;
      return;
   }

   do {
      head = MEMGetNextListObject(list, head);
   } while (head && head != object);

   if (head == object) {
      // Remove from middle of list
      auto link = getLink(list, object);
      auto next = link->next;
      auto prev = link->prev;
      getLink(list, prev)->next = next;
      getLink(list, next)->prev = prev;
      list->count--;
   }
}
void
MEMRemoveListObject(MemoryList *list, void *object)
{
    void *head = nullptr;

    if (!object) {
        return;
    }

    if (list->head == object && list->tail == object) {
        // Clear list
        list->head = nullptr;
        list->tail = nullptr;
        list->count = 0;
        return;
    }

    if (list->head == object) {
        // Remove from head
        list->head = MEMGetNextListObject(list, list->head);
        list->count--;
        return;
    }

    if (list->tail == object) {
        // Remove from tail
        list->tail = MEMGetPrevListObject(list, list->tail);
        list->count--;
        return;
    }

    do {
        MEMGetNextListObject(list, head);
    } while (head && head != object);

    if (head == object) {
        // Remove from middle of list
        auto link = getLink(list, object);
        auto before = link->next;
        auto after = link->prev;
        getLink(list, before)->next = after;
        getLink(list, after)->prev = before;
        list->count--;
    }
}
void *
MEMGetNthListObject(MemoryList *list, uint16_t n)
{
   void *head = nullptr;

   for (auto i = 0u; i < n && head; ++i) {
      head = MEMGetNextListObject(list, head);
   }

   return head;
}
void *
MEMGetNthListObject(MemoryList *list, uint16_t n)
{
    void *head = nullptr;

    do {
        MEMGetNextListObject(list, head);
        --n;
    } while (head && n >= 0);

    return head;
}
static CommonHeap *
findHeapContainingBlock(MemoryList *list, void *block)
{
   CommonHeap *heap = nullptr;
   uint32_t addr = gMemory.untranslate(block);

   while (heap = reinterpret_cast<CommonHeap*>(MEMGetNextListObject(list, heap))) {
      if (addr >= heap->dataStart && addr < heap->dataEnd) {
         auto child = findHeapContainingBlock(&heap->list, block);
         return child ? child : heap;
      }
   }

   return nullptr;
}