+notmuch_sort_t
+notmuch_query_get_sort (const notmuch_query_t *query)
+{
+ return query->sort;
+}
+
+notmuch_status_t
+notmuch_query_add_tag_exclude (notmuch_query_t *query, const char *tag)
+{
+ notmuch_status_t status;
+ char *term;
+
+ status = _notmuch_query_ensure_parsed (query);
+ if (status)
+ return status;
+
+ term = talloc_asprintf (query, "%s%s", _find_prefix ("tag"), tag);
+ if (query->terms.count(term) != 0)
+ return NOTMUCH_STATUS_IGNORED;
+
+ _notmuch_string_list_append (query->exclude_terms, term);
+ return NOTMUCH_STATUS_SUCCESS;
+}
+
+/* We end up having to call the destructors explicitly because we had
+ * to use "placement new" in order to initialize C++ objects within a
+ * block that we allocated with talloc. So C++ is making talloc
+ * slightly less simple to use, (we wouldn't need
+ * talloc_set_destructor at all otherwise).
+ */
+static int
+_notmuch_messages_destructor (notmuch_mset_messages_t *messages)
+{
+ messages->iterator.~MSetIterator ();
+ messages->iterator_end.~MSetIterator ();
+
+ return 0;
+}
+
+/* Return a query that matches messages with the excluded tags
+ * registered with query. The caller of this function has to combine the returned
+ * query appropriately.*/
+static Xapian::Query
+_notmuch_exclude_tags (notmuch_query_t *query)
+{
+ Xapian::Query exclude_query = Xapian::Query::MatchNothing;
+
+ for (notmuch_string_node_t *term = query->exclude_terms->head; term;
+ term = term->next) {
+ exclude_query = Xapian::Query (Xapian::Query::OP_OR,
+ exclude_query, Xapian::Query (term->string));
+ }
+ return exclude_query;
+}
+
+
+notmuch_status_t
+notmuch_query_search_messages_st (notmuch_query_t *query,
+ notmuch_messages_t **out)
+{
+ return notmuch_query_search_messages (query, out);
+}
+
+notmuch_status_t