Index: examples/quest.cc
===================================================================
--- examples/quest.cc	(revision 7520)
+++ examples/quest.cc	(working copy)
@@ -20,9 +20,13 @@
 
 #include <config.h>
 
+// Maximum number of matches to consider for categories and counts.
+#define MATCH_LIMIT 1000000
+
 #include <xapian.h>
 
 #include <iostream>
+#include <map>
 
 #include "gnu_getopt.h"
 
@@ -53,6 +57,16 @@
 "  -v, --version       output version information and exit\n";
 }
 
+class Spy : public Xapian::MatchDecider {
+  public:
+    mutable map<string, size_t> categories;
+
+    int operator()(const Xapian::Document &doc) const {
+	++categories[doc.get_value(0)];
+	return true;
+    }
+};
+
 int
 main(int argc, char **argv)
 {
@@ -117,12 +131,26 @@
 	    exit(1);
 	}
 
-	Xapian::MSet mset = enquire.get_mset(0, msize);
+	Spy spy;
+	Xapian::MSet mset = enquire.get_mset(0, msize, MATCH_LIMIT, NULL, &spy);
+	if (mset.size() < (unsigned)msize) msize = mset.size();
 	for (Xapian::MSetIterator i = mset.begin(); i != mset.end(); i++) {
 	    Xapian::Document doc = i.get_document();
 	    string data = doc.get_data();
 	    cout << *i << " [" << i.get_percent() << "%]\n" << data << "\n";
+	    if (--msize == 0) break;
 	}
+
+	const char * lineend = ")\n";
+	if (mset.get_matches_upper_bound() == MATCH_LIMIT) {
+	    lineend = "+)\n";
+	}
+
+	map<string, size_t>::const_iterator i;
+	for (i = spy.categories.begin(); i != spy.categories.end(); ++i) {
+	    cout << "Category: " << i->first << " (" << i->second << lineend;
+	}
+
 	cout << flush;
     } catch (const Xapian::Error & err) {
 	cout << err.get_msg() << endl;
