+const char *
+_notmuch_message_get_subject (notmuch_message_t *message)
+{
+ if (! message->message_file) {
+ notmuch_message_file_t *message_file;
+ const char *filename;
+
+ filename = notmuch_message_get_filename (message);
+ if (unlikely (filename == NULL))
+ return NULL;
+
+ message_file = _notmuch_message_file_open_ctx (message, filename);
+ if (unlikely (message_file == NULL))
+ return NULL;
+
+ message->message_file = message_file;
+ }
+
+ return notmuch_message_file_get_header (message->message_file,
+ "subject");
+}
+
+const char *
+notmuch_message_get_thread_id (notmuch_message_t *message)
+{
+ Xapian::TermIterator i;
+
+ if (message->thread_id)
+ return message->thread_id;
+
+ i = message->doc.termlist_begin ();
+ i.skip_to (_find_prefix ("thread"));
+
+ if (i == message->doc.termlist_end ())
+ INTERNAL_ERROR ("Message with document ID of %d has no thread ID.\n",
+ message->doc_id);
+
+ message->thread_id = talloc_strdup (message, (*i).c_str () + 1);
+
+#if DEBUG_DATABASE_SANITY
+ i++;
+
+ if (i != message->doc.termlist_end () &&
+ strncmp ((*i).c_str (), _find_prefix ("thread"),
+ strlen (_find_prefix ("thread"))) == 0)
+ {
+ INTERNAL_ERROR ("Message with document ID of %d has duplicate thread IDs.\n",
+ message->doc_id);
+ }
+#endif
+
+ return message->thread_id;
+}
+