  };
  
  G_LOCK_DEFINE_STATIC (global_env);
-@@ -642,6 +645,12 @@
+@@ -246,6 +249,7 @@
+ 	status = do_create (bf, vcard, contact);
+ 	if (status == GNOME_Evolution_Addressbook_Success) {
+ 		e_book_backend_summary_add_contact (bf->priv->summary, *contact);
++		e_book_backend_file_index_add_contact (bf->priv->index, *contact);
+ 	}
+ 	return status;
+ }
+@@ -293,6 +297,7 @@
+ 	for (l = removed_cards; l; l = l->next) {
+ 		char *id = l->data;
+ 		e_book_backend_summary_remove_contact (bf->priv->summary, id);
++		e_book_backend_file_index_remove_contact (bf->priv->index, id);
+ 	}
+ 
+ 	return rv;
+@@ -345,6 +350,7 @@
+ 	g_free (vcard_with_rev);
+ 	
+ 	if (db_error == 0) {
++		e_book_backend_file_index_modify_contact (bf->priv->index, *contact);
+ 		return GNOME_Evolution_Addressbook_Success;
+ 	} else {
+ 		g_warning (G_STRLOC ": db->put failed with %s", db_strerror (db_error));
+@@ -642,7 +648,36 @@
  	d(printf ("signalling parent thread\n"));
  	e_flag_set (closure->running);
  
+-	if (e_book_backend_summary_is_summary_query (bf->priv->summary, query)) {
 +
 +	if (e_book_backend_file_index_is_usable (bf->priv->index, query))
 +	{
++		GPtrArray *ids = NULL;
++		int i;
++
++		ids = e_book_backend_file_index_query (bf->priv->index, query);
++
 +		g_debug ("Able to use EBookBackendFileIndex for %s", query);
-+	}
-+
- 	if (e_book_backend_summary_is_summary_query (bf->priv->summary, query)) {
++
++		for (i = 0; i < ids->len; i ++) {
++			char *id = g_ptr_array_index (ids, i);
++
++			if (!e_flag_is_set (closure->running))
++				break;
++
++			string_to_dbt (id, &id_dbt);
++			memset (&vcard_dbt, 0, sizeof (vcard_dbt));
++			vcard_dbt.flags = DB_DBT_MALLOC;
++
++			db_error = db->get (db, NULL, &id_dbt, &vcard_dbt, 0);
++
++			if (db_error == 0) {
++				e_data_book_view_notify_update_prefiltered_vcard (book_view, id, vcard_dbt.data);
++			}
++			else {
++				g_warning (G_STRLOC ": db->get failed with %s", db_strerror (db_error));
++			}
++		}
++	} else if (e_book_backend_summary_is_summary_query (bf->priv->summary, query)) {
  		/* do a summary query */
  		GPtrArray *ids = e_book_backend_summary_search (bf->priv->summary, e_data_book_view_get_card_query (book_view));
-@@ -1143,6 +1152,7 @@
+ 		int i;
+@@ -668,8 +703,7 @@
+ 		}
+ 
+ 		g_ptr_array_free (ids, TRUE);
+-	}
+-	else {
++	} else {
+ 		/* iterate over the db and do the query there */
+ 		DBC    *dbc;
+ 
+@@ -709,8 +743,6 @@
+ 				   bf->priv->filename);
+ 			abort ();
+ 		}
+-
+-
+ 	}
+ 
+ 	if (e_flag_is_set (closure->running))
+@@ -1143,6 +1175,7 @@
  	time_t db_mtime;
  	struct stat sb;
  	gchar *uri;

Index: git-foo/addressbook/backends/file/e-book-backend-file-index.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ git-foo/addressbook/backends/file/e-book-backend-file-index.c	2008-05-02 18:27:16.000000000 +0100
@@ -0,0 +1,702 @@
+#include "e-book-backend-file-index.h"
+#include "libedataserver/e-sexp.h"
+#include "libebook/e-contact.h"

+static ESExpResult *
+index_query (ESExp *sexp, gint argc, ESExpResult **argv, gpointer userdata)
+{
+  EBookBackendFileIndex *index = (EBookBackendFileIndex *)userdata;
+  EBookBackendFileIndexPrivate *priv = GET_PRIVATE (index);
+  
+  ESExpResult *result = NULL;
