Index: libedata-book-dbus/e-data-book-view.c
===================================================================
--- libedata-book-dbus/e-data-book-view.c	(revision 161)
+++ libedata-book-dbus/e-data-book-view.c	(revision 162)
@@ -320,6 +320,41 @@
 }
 
 void
+e_data_book_view_notify_update_vcard (EDataBookView *book_view, char *vcard)
+{
+  EDataBookViewPrivate *priv = E_DATA_BOOK_VIEW_GET_PRIVATE (book_view);
+  gboolean currently_in_view, want_in_view;
+  const char *id;
+  EContact *contact;
+
+  g_mutex_lock (priv->pending_mutex);
+
+  contact = e_contact_new_from_vcard (vcard);
+  id = e_contact_get_const (contact, E_CONTACT_UID);
+
+  currently_in_view =
+    g_hash_table_lookup (priv->ids, id) != NULL;
+  want_in_view =
+    e_book_backend_sexp_match_contact (priv->card_sexp, contact);
+
+  if (want_in_view) {
+    if (currently_in_view)
+      notify_change (priv, vcard);
+    else
+      notify_add (priv, id, vcard);
+  } else {
+    if (currently_in_view)
+      notify_remove (priv, id);
+    else
+      /* else nothing; we're removing a card that wasn't there */
+      free (vcard);
+  }
+
+  g_object_unref (contact);
+  g_mutex_unlock (priv->pending_mutex);
+}
+
+void
 e_data_book_view_notify_remove (EDataBookView *book_view, const char *id)
 {
   EDataBookViewPrivate *priv = E_DATA_BOOK_VIEW_GET_PRIVATE (book_view);
Index: libedata-book-dbus/e-data-book-view.h
===================================================================
--- libedata-book-dbus/e-data-book-view.h	(revision 161)
+++ libedata-book-dbus/e-data-book-view.h	(revision 162)
@@ -42,6 +42,8 @@
 #endif
 void         e_data_book_view_notify_update          (EDataBookView                *book_view,
                                                       EContact                     *contact);
+void         e_data_book_view_notify_update_vcard    (EDataBookView                *book_view,
+                                                      char                         *vcard);
 void         e_data_book_view_notify_remove          (EDataBookView                *book_view,
                                                       const char                   *id);
 void         e_data_book_view_notify_complete        (EDataBookView                *book_view, EDataBookStatus status);
Index: backends/file/e-book-backend-file.c
===================================================================
--- backends/file/e-book-backend-file.c	(revision 156)
+++ backends/file/e-book-backend-file.c	(working copy)
@@ -540,7 +540,7 @@
 
 		for (i = 0; i < ids->len; i ++) {
 			char *id = g_ptr_array_index (ids, i);
-			printf ("**** id %s\n", id);
+			d(printf ("**** id %s\n", id));
 			g_mutex_lock (closure->mutex);
 			stopped = closure->stopped;
 			g_mutex_unlock (closure->mutex);
@@ -555,13 +555,8 @@
 			db_error = db->get (db, NULL, &id_dbt, &vcard_dbt, 0);
 
 			if (db_error == 0) {
-				EContact *contact = create_contact (id_dbt.data, vcard_dbt.data);
 				/* notify_update will check if it matches for us */
-				e_data_book_view_notify_update (book_view, contact);
-				
-				g_object_unref (contact);
-
-				free (vcard_dbt.data);
+				e_data_book_view_notify_update_vcard (book_view, vcard_dbt.data);
 			}
 			else {
 				g_warning ("db->get returned %d", db_error);
@@ -576,6 +571,7 @@
 
 		memset (&id_dbt, 0, sizeof (id_dbt));
 		memset (&vcard_dbt, 0, sizeof (vcard_dbt));
+		vcard_dbt.flags = DB_DBT_MALLOC;
 
 		db_error = db->cursor (db, NULL, &dbc, 0);
 		if (db_error == 0) {
@@ -592,10 +588,8 @@
 
 				/* don't include the version in the list of cards */
 				if (strcmp (id_dbt.data, E_BOOK_BACKEND_FILE_VERSION_NAME)) {
-					EContact *contact = create_contact (id_dbt.data, vcard_dbt.data);
 					/* notify_update will check if it matches for us */
-					e_data_book_view_notify_update (book_view, contact);
-					g_object_unref (contact);
+					e_data_book_view_notify_update_vcard (book_view, vcard_dbt.data);
 				}
 
 				db_error = dbc->c_get(dbc, &id_dbt, &vcard_dbt, DB_NEXT);
