+ return (mset_messages->iterator != mset_messages->iterator_end);
+}
+
+static Xapian::docid
+_notmuch_mset_messages_get_doc_id (notmuch_messages_t *messages)
+{
+ notmuch_mset_messages_t *mset_messages;
+
+ mset_messages = (notmuch_mset_messages_t *) messages;
+
+ if (! _notmuch_mset_messages_valid (&mset_messages->base))
+ return 0;
+
+ return *mset_messages->iterator;
+}
+
+notmuch_message_t *
+_notmuch_mset_messages_get (notmuch_messages_t *messages)
+{
+ notmuch_message_t *message;
+ Xapian::docid doc_id;
+ notmuch_private_status_t status;
+ notmuch_mset_messages_t *mset_messages;
+
+ mset_messages = (notmuch_mset_messages_t *) messages;
+
+ if (! _notmuch_mset_messages_valid (&mset_messages->base))
+ return NULL;
+
+ doc_id = *mset_messages->iterator;
+
+ message = _notmuch_message_create (mset_messages,
+ mset_messages->notmuch, doc_id,
+ &status);
+
+ if (message == NULL &&
+ status == NOTMUCH_PRIVATE_STATUS_NO_DOCUMENT_FOUND)
+ {
+ INTERNAL_ERROR ("a messages iterator contains a non-existent document ID.\n");
+ }
+
+ if (messages->excluded_doc_ids &&
+ _notmuch_doc_id_set_contains (messages->excluded_doc_ids, doc_id))
+ notmuch_message_set_flag (message, NOTMUCH_MESSAGE_FLAG_EXCLUDED, TRUE);
+
+ return message;
+}
+
+void
+_notmuch_mset_messages_move_to_next (notmuch_messages_t *messages)
+{
+ notmuch_mset_messages_t *mset_messages;
+
+ mset_messages = (notmuch_mset_messages_t *) messages;
+
+ mset_messages->iterator++;
+}
+
+static notmuch_bool_t
+_notmuch_doc_id_set_init (void *ctx,
+ notmuch_doc_id_set_t *doc_ids,
+ GArray *arr)
+{
+ unsigned int max = 0;
+ unsigned char *bitmap;
+
+ for (unsigned int i = 0; i < arr->len; i++)
+ max = MAX(max, g_array_index (arr, unsigned int, i));
+ bitmap = talloc_zero_array (ctx, unsigned char, DOCIDSET_WORD(max) + 1);
+
+ if (bitmap == NULL)
+ return FALSE;
+
+ doc_ids->bitmap = bitmap;
+ doc_ids->bound = max + 1;
+
+ for (unsigned int i = 0; i < arr->len; i++) {
+ unsigned int doc_id = g_array_index (arr, unsigned int, i);
+ bitmap[DOCIDSET_WORD(doc_id)] |= 1 << DOCIDSET_BIT(doc_id);
+ }
+
+ return TRUE;
+}
+
+notmuch_bool_t
+_notmuch_doc_id_set_contains (notmuch_doc_id_set_t *doc_ids,
+ unsigned int doc_id)
+{
+ if (doc_id >= doc_ids->bound)
+ return FALSE;
+ return doc_ids->bitmap[DOCIDSET_WORD(doc_id)] & (1 << DOCIDSET_BIT(doc_id));
+}
+
+void
+_notmuch_doc_id_set_remove (notmuch_doc_id_set_t *doc_ids,
+ unsigned int doc_id)
+{
+ if (doc_id < doc_ids->bound)
+ doc_ids->bitmap[DOCIDSET_WORD(doc_id)] &= ~(1 << DOCIDSET_BIT(doc_id));