public function resolveIds(Horde_Imap_Client_Mailbox $mailbox,
                               Horde_Imap_Client_Ids $ids, $convert = 0)
    {
        $map = $this->_mailboxOb($mailbox)->map;

        if ($ids->special) {
            /* Optimization for ALL sequence searches. */
            if (!$convert && $ids->all && $ids->sequence) {
                $res = $this->status($mailbox, Horde_Imap_Client::STATUS_MESSAGES);
                return $this->getIdsOb($res['messages'] ? ('1:' . $res['messages']) : array(), true);
            }

            $convert = 2;
        } elseif (!$convert ||
                  (!$ids->sequence && ($convert == 1)) ||
                  $ids->isEmpty()) {
            return clone $ids;
        } else {
            /* Do an all or nothing: either we have all the numbers/UIDs in
             * memory and can return, or just send the whole ID query to the
             * server. Any advantage we would get by a partial search are
             * outweighed by the complexities needed to make the search and
             * then merge back into the original results. */
            $lookup = $map->lookup($ids);
            if (count($lookup) === count($ids)) {
                return $this->getIdsOb(array_values($lookup));
            }
        }

        $query = new Horde_Imap_Client_Search_Query();
        $query->ids($ids);

        $res = $this->search($mailbox, $query, array(
            'results' => array(
                Horde_Imap_Client::SEARCH_RESULTS_MATCH,
                Horde_Imap_Client::SEARCH_RESULTS_SAVE
            ),
            'sequence' => (!$convert && $ids->sequence),
            'sort' => array(Horde_Imap_Client::SORT_SEQUENCE)
        ));

        /* Update mapping. */
        if ($convert) {
            if ($ids->all) {
                $ids = $this->getIdsOb('1:' . count($res['match']));
            } elseif ($ids->special) {
                return $res['match'];
            }

            /* Sanity checking (Bug #12911). */
            $list1 = array_slice($ids->ids, 0, count($res['match']));
            $list2 = $res['match']->ids;
            if (!empty($list1) &&
                !empty($list2) &&
                (count($list1) === count($list2))) {
                $map->update(array_combine($list1, $list2));
            }
        }

        return $res['match'];
    }