void imap_expunge_mailbox(struct ImapData *idata)
{
  struct Header *h = NULL;
  int cacheno;
  short old_sort;

#ifdef USE_HCACHE
  idata->hcache = imap_hcache_open(idata, NULL);
#endif

  old_sort = Sort;
  Sort = SORT_ORDER;
  mutt_sort_headers(idata->ctx, 0);

  for (int i = 0; i < idata->ctx->msgcount; i++)
  {
    h = idata->ctx->hdrs[i];

    if (h->index == INT_MAX)
    {
      mutt_debug(2, "Expunging message UID %u.\n", HEADER_DATA(h)->uid);

      h->active = false;
      idata->ctx->size -= h->content->length;

      imap_cache_del(idata, h);
#ifdef USE_HCACHE
      imap_hcache_del(idata, HEADER_DATA(h)->uid);
#endif

      /* free cached body from disk, if necessary */
      cacheno = HEADER_DATA(h)->uid % IMAP_CACHE_LEN;
      if (idata->cache[cacheno].uid == HEADER_DATA(h)->uid &&
          idata->cache[cacheno].path)
      {
        unlink(idata->cache[cacheno].path);
        FREE(&idata->cache[cacheno].path);
      }

      mutt_hash_int_delete(idata->uid_hash, HEADER_DATA(h)->uid, h);

      imap_free_header_data((struct ImapHeaderData **) &h->data);
    }
    else
    {
      h->index = i;
      /* NeoMutt has several places where it turns off h->active as a
       * hack.  For example to avoid FLAG updates, or to exclude from
       * imap_exec_msgset.
       *
       * Unfortunately, when a reopen is allowed and the IMAP_EXPUNGE_PENDING
       * flag becomes set (e.g. a flag update to a modified header),
       * this function will be called by imap_cmd_finish().
       *
       * The mx_update_tables() will free and remove these "inactive" headers,
       * despite that an EXPUNGE was not received for them.
       * This would result in memory leaks and segfaults due to dangling
       * pointers in the msn_index and uid_hash.
       *
       * So this is another hack to work around the hacks.  We don't want to
       * remove the messages, so make sure active is on.
       */
      h->active = true;
    }
  }

#ifdef USE_HCACHE
  imap_hcache_close(idata);
#endif

  /* We may be called on to expunge at any time. We can't rely on the caller
   * to always know to rethread */
  mx_update_tables(idata->ctx, false);
  Sort = old_sort;
  mutt_sort_headers(idata->ctx, 1);
}
void imap_expunge_mailbox(struct ImapData *idata)
{
  struct Header *h = NULL;
  int cacheno;
  short old_sort;

#ifdef USE_HCACHE
  idata->hcache = imap_hcache_open(idata, NULL);
#endif

  old_sort = Sort;
  Sort = SORT_ORDER;
  mutt_sort_headers(idata->ctx, 0);

  for (int i = 0; i < idata->ctx->msgcount; i++)
  {
    h = idata->ctx->hdrs[i];

    if (h->index == INT_MAX)
    {
      mutt_debug(2, "Expunging message UID %u.\n", HEADER_DATA(h)->uid);

      h->active = false;
      idata->ctx->size -= h->content->length;

      imap_cache_del(idata, h);
#ifdef USE_HCACHE
      imap_hcache_del(idata, HEADER_DATA(h)->uid);
#endif

       
      cacheno = HEADER_DATA(h)->uid % IMAP_CACHE_LEN;
      if (idata->cache[cacheno].uid == HEADER_DATA(h)->uid &&
          idata->cache[cacheno].path)
      {
        unlink(idata->cache[cacheno].path);
        FREE(&idata->cache[cacheno].path);
      }

      mutt_hash_int_delete(idata->uid_hash, HEADER_DATA(h)->uid, h);

      imap_free_header_data((struct ImapHeaderData **) &h->data);
    }
    else
    {
      h->index = i;
       
      h->active = true;
    }
  }

#ifdef USE_HCACHE
  imap_hcache_close(idata);
#endif

   
  mx_update_tables(idata->ctx, false);
  Sort = old_sort;
  mutt_sort_headers(idata->ctx, 1);
}