+Xapian::Document
+find_message (Xapian::Database db, const char *message_id)
+{
+ Xapian::PostingIterator i;
+ char *term;
+
+ term = g_strdup_printf ("%s%s", find_prefix ("msgid"), message_id);
+ i = db.postlist_begin (term);
+ if (i != db.postlist_end (term))
+ return db.get_document (*i);
+ else
+ return Xapian::Document ();
+}
+
+static char *
+find_thread_id (Xapian::Database db, GPtrArray *parents)
+{
+ Xapian::Document doc;
+ GHashTable *thread_ids;
+ GList *keys, *l;
+ GString *result = NULL;
+ unsigned int i;
+ string value_string;
+ const char *value;
+
+ thread_ids = g_hash_table_new (g_str_hash, g_str_equal);
+
+ for (i = 0; i < parents->len; i++) {
+ doc = find_message (db, (char *) g_ptr_array_index (parents, i));
+ value_string = doc.get_value (NOTMUCH_VALUE_THREAD);
+ value = value_string.c_str();
+ if (strlen (value))
+ g_hash_table_insert (thread_ids, strdup (value), NULL);
+ }
+
+ keys = g_hash_table_get_keys (thread_ids);
+ for (l = keys; l; l = l->next) {
+ char *id = (char *) l->data;
+ if (result == NULL) {
+ result = g_string_new (id);
+ } else {
+ g_string_append_printf (result, ",%s", id);
+ }
+ free (id);
+ }
+
+ if (result)
+ return g_string_free (result, FALSE);
+ else
+ return NULL;
+}
+
+/* Add a term for each message-id in the References header of the
+ * message. */
+static void
+parse_references (GPtrArray *array,
+ const char *refs)
+{
+ const char *end, *next;
+
+ if (refs == NULL)
+ return;
+
+ while (*refs) {
+ while (*refs && isspace (*refs))
+ refs++;
+ if (*refs == '<')
+ refs++;
+ end = refs;
+ while (*end && !isspace (*end))
+ end++;
+ next = end;
+ end--;
+ if (end > refs && *end == '>')
+ end--;
+ if (end > refs) {
+ g_ptr_array_add (array, g_strndup (refs, end - refs + 1));
+ }
+ refs = next;
+ }
+}
+