[evolution-data-server/wip/mcrha/libical-glib] Split EBookBackend into EBookBackend and EBookBackendSync



commit 22e1ae35e918f79293a5b0e939fbf4bb62a3dbe3
Author: Milan Crha <mcrha redhat com>
Date:   Wed Apr 10 21:46:16 2019 +0200

    Split EBookBackend into EBookBackend and EBookBackendSync
    
    It includes also some API changes to avoid unnecessary conversions
    of strings into EContact, or GSList into GQueue and then back to GSList.

 CMakeLists.txt                                     |   2 +-
 .../evolution-data-server-docs.sgml.in             |   1 +
 .../backends/file/e-book-backend-file.c            | 189 +++---
 .../backends/file/e-book-backend-file.h            |   4 +-
 .../backends/ldap/e-book-backend-ldap.c            | 127 ++--
 src/addressbook/libedata-book/CMakeLists.txt       |  14 +-
 .../libedata-book/e-book-backend-sync.c            | 577 ++++++++++++++++++
 .../libedata-book/e-book-backend-sync.h            | 188 ++++++
 src/addressbook/libedata-book/e-book-backend.c     | 657 ++-------------------
 src/addressbook/libedata-book/e-book-backend.h     |  84 +--
 .../libedata-book/e-book-meta-backend.c            | 118 ++--
 .../libedata-book/e-book-meta-backend.h            |   6 +-
 src/addressbook/libedata-book/e-data-book.c        |  49 +-
 src/addressbook/libedata-book/e-data-book.h        |  16 +-
 src/addressbook/libedata-book/libedata-book.h      |   3 +-
 tests/libedata-book/test-book-meta-backend.c       | 227 +++----
 16 files changed, 1195 insertions(+), 1067 deletions(-)
---
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 42f4414d0..b341fabb4 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -72,7 +72,7 @@ set(LIBEBOOK_CONTACTS_CURRENT 2)
 set(LIBEBOOK_CONTACTS_REVISION 0)
 set(LIBEBOOK_CONTACTS_AGE 0)
 
-set(LIBEDATABOOK_CURRENT 25)
+set(LIBEDATABOOK_CURRENT 26)
 set(LIBEDATABOOK_REVISION 0)
 set(LIBEDATABOOK_AGE 0)
 
diff --git a/docs/reference/evolution-data-server/evolution-data-server-docs.sgml.in 
b/docs/reference/evolution-data-server/evolution-data-server-docs.sgml.in
index f3834222c..7742a7483 100644
--- a/docs/reference/evolution-data-server/evolution-data-server-docs.sgml.in
+++ b/docs/reference/evolution-data-server/evolution-data-server-docs.sgml.in
@@ -195,6 +195,7 @@
     <chapter>
       <title>Addressbook Backend Classes</title>
       <xi:include href="xml/e-book-backend.xml"/>
+      <xi:include href="xml/e-book-backend-sync.xml"/>
       <xi:include href="xml/e-book-backend-factory.xml"/>
       <xi:include href="xml/e-book-backend-sexp.xml"/>
       <xi:include href="xml/e-book-cache.xml"/>
diff --git a/src/addressbook/backends/file/e-book-backend-file.c 
b/src/addressbook/backends/file/e-book-backend-file.c
index a40d0146c..7467f2aaa 100644
--- a/src/addressbook/backends/file/e-book-backend-file.c
+++ b/src/addressbook/backends/file/e-book-backend-file.c
@@ -70,7 +70,7 @@ static void   e_book_backend_file_initable_init
 G_DEFINE_TYPE_WITH_CODE (
        EBookBackendFile,
        e_book_backend_file,
-       E_TYPE_BOOK_BACKEND,
+       E_TYPE_BOOK_BACKEND_SYNC,
        G_IMPLEMENT_INTERFACE (
                G_TYPE_INITABLE,
                e_book_backend_file_initable_init))
@@ -797,12 +797,11 @@ cursors_contact_removed (EBookBackendFile *bf,
 static gboolean
 do_create (EBookBackendFile *bf,
            const gchar * const *vcards,
-           GQueue *out_contacts,
+           GSList **out_contacts,
            GCancellable *cancellable,
            GError **error)
 {
        PhotoModifiedStatus status = STATUS_NORMAL;
-       GQueue queue = G_QUEUE_INIT;
        guint ii, length;
        GError *local_error = NULL;
 
@@ -831,7 +830,7 @@ do_create (EBookBackendFile *bf,
                if (status != STATUS_ERROR) {
 
                        /* Contact was added successfully. */
-                       g_queue_push_tail (&queue, contact);
+                       *out_contacts = g_slist_prepend (*out_contacts, contact);
                } else {
                        /* Contact could not be transformed */
                        g_warning (
@@ -846,16 +845,10 @@ do_create (EBookBackendFile *bf,
        }
 
        if (status != STATUS_ERROR) {
-               GList *tail, *link;
-               GSList *slist = NULL, *l;
-
-               /* EBookSqlite uses GSList. */
-               tail = g_queue_peek_tail_link (&queue);
-               for (link = tail; link != NULL; link = g_list_previous (link))
-                       slist = g_slist_prepend (slist, link->data);
+               GSList *link;
 
                if (!e_book_sqlite_add_contacts (bf->priv->sqlitedb,
-                                                slist, NULL, FALSE,
+                                                *out_contacts, NULL, FALSE,
                                                 cancellable,
                                                 &local_error)) {
 
@@ -876,19 +869,11 @@ do_create (EBookBackendFile *bf,
                }
 
                /* After adding any contacts, notify any cursors that the new contacts are added */
-               for (l = slist; l; l = l->next) {
-                       cursors_contact_added (bf, E_CONTACT (l->data));
+               for (link = *out_contacts; link; link = g_slist_next (link)) {
+                       cursors_contact_added (bf, link->data);
                }
-
-               g_slist_free (slist);
        }
 
-       if (status != STATUS_ERROR && out_contacts != NULL)
-               e_queue_transfer (&queue, out_contacts);
-
-       while (!g_queue_is_empty (&queue))
-               g_object_unref (g_queue_pop_head (&queue));
-
        return (status != STATUS_ERROR);
 }
 
@@ -1146,7 +1131,7 @@ book_backend_file_get_backend_property (EBookBackend *backend,
 }
 
 static gboolean
-book_backend_file_open_sync (EBookBackend *backend,
+book_backend_file_open_sync (EBookBackendSync *backend,
                              GCancellable *cancellable,
                              GError **error)
 {
@@ -1181,15 +1166,19 @@ book_backend_file_open_sync (EBookBackend *backend,
 }
 
 static gboolean
-book_backend_file_create_contacts_sync (EBookBackend *backend,
+book_backend_file_create_contacts_sync (EBookBackendSync *backend,
                                         const gchar * const *vcards,
-                                        GQueue *out_contacts,
+                                        GSList **out_contacts,
                                         GCancellable *cancellable,
                                         GError **error)
 {
        EBookBackendFile *bf = E_BOOK_BACKEND_FILE (backend);
        gboolean success = FALSE;
 
+       g_return_val_if_fail (out_contacts != NULL, FALSE);
+
+       *out_contacts = NULL;
+
        g_rw_lock_writer_lock (&(bf->priv->lock));
        if (!e_book_sqlite_lock (bf->priv->sqlitedb,
                                 EBSQL_LOCK_WRITE,
@@ -1200,6 +1189,13 @@ book_backend_file_create_contacts_sync (EBookBackend *backend,
 
        success = do_create (bf, vcards, out_contacts, cancellable, error);
 
+       if (success) {
+               *out_contacts = g_slist_reverse (*out_contacts);
+       } else {
+               g_slist_free_full (*out_contacts, g_object_unref);
+               *out_contacts = NULL;
+       }
+
        if (success)
                success = e_book_backend_file_bump_revision (bf, error);
 
@@ -1232,9 +1228,9 @@ book_backend_file_create_contacts_sync (EBookBackend *backend,
 }
 
 static gboolean
-book_backend_file_modify_contacts_sync (EBookBackend *backend,
+book_backend_file_modify_contacts_sync (EBookBackendSync *backend,
                                         const gchar * const *vcards,
-                                        GQueue *out_contacts,
+                                        GSList **out_contacts,
                                         GCancellable *cancellable,
                                         GError **error)
 {
@@ -1242,8 +1238,7 @@ book_backend_file_modify_contacts_sync (EBookBackend *backend,
        GSList           *ids = NULL;
        GError           *local_error = NULL;
        PhotoModifiedStatus status = STATUS_NORMAL;
-       GQueue old_contact_queue = G_QUEUE_INIT;
-       GQueue mod_contact_queue = G_QUEUE_INIT;
+       GSList *old_contacts = NULL;
        guint ii, length;
 
        length = g_strv_length ((gchar **) vcards);
@@ -1325,42 +1320,33 @@ book_backend_file_modify_contacts_sync (EBookBackend *backend,
                /* update the revision (modified time of contact) */
                set_revision (bf, mod_contact);
 
-               g_queue_push_tail (&old_contact_queue, old_contact);
-               g_queue_push_tail (&mod_contact_queue, mod_contact);
+               old_contacts = g_slist_prepend (old_contacts, old_contact);
+               *out_contacts = g_slist_prepend (*out_contacts, mod_contact);
 
                ids = g_slist_prepend (ids, id);
        }
 
        if (status != STATUS_ERROR) {
-               GList *old_link;
-               GList *mod_link;
-               GSList *slist = NULL;
+               GSList *old_link, *mod_link;
 
                /* Delete old photo file uris if need be (this will compare the new contact
                 * with the current copy in the BDB to extract the uris to delete) */
-               old_link = g_queue_peek_head_link (&old_contact_queue);
-               mod_link = g_queue_peek_head_link (&mod_contact_queue);
+               old_link = old_contacts;
+               mod_link = *out_contacts;
 
                while (old_link != NULL && mod_link != NULL) {
                        maybe_delete_unused_uris (
                                bf,
                                E_CONTACT (old_link->data),
                                E_CONTACT (mod_link->data));
-                       old_link = g_list_next (old_link);
-                       mod_link = g_list_next (mod_link);
-               }
-
-               /* EBookSqlite uses GSList. */
-               mod_link = g_queue_peek_tail_link (&mod_contact_queue);
-               while (mod_link != NULL) {
-                       slist = g_slist_prepend (slist, mod_link->data);
-                       mod_link = g_list_previous (mod_link);
+                       old_link = g_slist_next (old_link);
+                       mod_link = g_slist_next (mod_link);
                }
 
                /* Update summary as well */
                e_book_sqlite_add_contacts (
                        bf->priv->sqlitedb,
-                       slist, NULL, TRUE,
+                       *out_contacts, NULL, TRUE,
                        cancellable, &local_error);
 
                if (local_error != NULL) {
@@ -1372,8 +1358,6 @@ book_backend_file_modify_contacts_sync (EBookBackend *backend,
 
                        status = STATUS_ERROR;
                }
-
-               g_slist_free (slist);
        }
 
        /* Bump the revision atomically in the same transaction */
@@ -1409,43 +1393,41 @@ book_backend_file_modify_contacts_sync (EBookBackend *backend,
                }
        }
 
-       if (status != STATUS_ERROR)
-               e_queue_transfer (&mod_contact_queue, out_contacts);
+       if (status != STATUS_ERROR) {
+               *out_contacts = g_slist_reverse (*out_contacts);
+       } else {
+               g_slist_free_full (*out_contacts, g_object_unref);
+               *out_contacts = NULL;
+       }
 
        /* Now that we've modified the contact(s),
         * notify cursors of the changes. */
        if (status != STATUS_ERROR) {
-               GList *l;
+               GSList *link;
 
-               for (l = g_queue_peek_head_link (&old_contact_queue);
-                    l; l = l->next) {
-                       cursors_contact_removed (bf, E_CONTACT (l->data));
+               for (link = old_contacts; link; link = g_slist_next (link)) {
+                       cursors_contact_removed (bf, E_CONTACT (link->data));
                }
 
-               for (l = g_queue_peek_head_link (&mod_contact_queue);
-                    l; l = l->next) {
-                       cursors_contact_added (bf, E_CONTACT (l->data));
+               for (link = *out_contacts; link; link = g_slist_next (*out_contacts)) {
+                       cursors_contact_added (bf, E_CONTACT (link->data));
                }
        }
 
        g_rw_lock_writer_unlock (&(bf->priv->lock));
 
-       while (!g_queue_is_empty (&old_contact_queue))
-               g_object_unref (g_queue_pop_head (&old_contact_queue));
-
-       while (!g_queue_is_empty (&mod_contact_queue))
-               g_object_unref (g_queue_pop_head (&mod_contact_queue));
-
-       g_slist_free_full (ids, (GDestroyNotify) g_free);
+       g_slist_free_full (old_contacts, g_object_unref);
+       g_slist_free_full (ids, g_free);
 
        return (status != STATUS_ERROR);
 }
 
 static gboolean
-book_backend_file_remove_contacts_sync (EBookBackend *backend,
-                                        const gchar * const *uids,
-                                        GCancellable *cancellable,
-                                        GError **error)
+book_backend_file_remove_contacts_sync (EBookBackendSync *backend,
+                                       const gchar * const *uids,
+                                       GSList **out_removed_uids,
+                                       GCancellable *cancellable,
+                                       GError **error)
 {
        EBookBackendFile *bf = E_BOOK_BACKEND_FILE (backend);
        GSList           *removed_ids = NULL, *removed_contacts = NULL;
@@ -1454,6 +1436,8 @@ book_backend_file_remove_contacts_sync (EBookBackend *backend,
        gboolean success = TRUE;
        guint ii, length;
 
+       g_return_val_if_fail (out_removed_uids != NULL, FALSE);
+
        length = g_strv_length ((gchar **) uids);
 
        g_rw_lock_writer_lock (&(bf->priv->lock));
@@ -1540,16 +1524,17 @@ book_backend_file_remove_contacts_sync (EBookBackend *backend,
                }
        }
 
+       *out_removed_uids = removed_ids;
+
        g_rw_lock_writer_unlock (&(bf->priv->lock));
 
-       g_slist_free_full (removed_ids, (GDestroyNotify) g_free);
        g_slist_free_full (removed_contacts, (GDestroyNotify) g_object_unref);
 
        return success;
 }
 
 static EContact *
-book_backend_file_get_contact_sync (EBookBackend *backend,
+book_backend_file_get_contact_sync (EBookBackendSync *backend,
                                     const gchar *uid,
                                     GCancellable *cancellable,
                                     GError **error)
@@ -1583,9 +1568,9 @@ book_backend_file_get_contact_sync (EBookBackend *backend,
 }
 
 static gboolean
-book_backend_file_get_contact_list_sync (EBookBackend *backend,
+book_backend_file_get_contact_list_sync (EBookBackendSync *backend,
                                          const gchar *query,
-                                         GQueue *out_contacts,
+                                         GSList **out_contacts,
                                          GCancellable *cancellable,
                                          GError **error)
 {
@@ -1595,6 +1580,10 @@ book_backend_file_get_contact_list_sync (EBookBackend *backend,
        gboolean success = TRUE;
        GError *local_error = NULL;
 
+       g_return_val_if_fail (out_contacts != NULL, FALSE);
+
+       *out_contacts = NULL;
+
        d (printf ("book_backend_file_get_contact_list_sync (%s)\n", query));
 
        g_rw_lock_reader_lock (&(bf->priv->lock));
@@ -1656,29 +1645,31 @@ book_backend_file_get_contact_list_sync (EBookBackend *backend,
                EContact *contact;
 
                contact = e_contact_new_from_vcard (data->vcard);
-               g_queue_push_tail (out_contacts, contact);
+               link->data = contact;
+
+               e_book_sqlite_search_data_free (data);
        }
 
-       g_slist_free_full (
-               summary_list, (GDestroyNotify)
-               e_book_sqlite_search_data_free);
+       *out_contacts = summary_list;
 
        return success;
 }
 
 static gboolean
-book_backend_file_get_contact_list_uids_sync (EBookBackend *backend,
+book_backend_file_get_contact_list_uids_sync (EBookBackendSync *backend,
                                               const gchar *query,
-                                              GQueue *out_uids,
+                                              GSList **out_uids,
                                               GCancellable *cancellable,
                                               GError **error)
 {
        EBookBackendFile *bf = E_BOOK_BACKEND_FILE (backend);
-       GSList *uids = NULL;
-       GSList *link;
        gboolean success = TRUE;
        GError *local_error = NULL;
 
+       g_return_val_if_fail (out_uids != NULL, FALSE);
+
+       *out_uids = NULL;
+
        d (printf ("book_backend_file_get_contact_list_sync (%s)\n", query));
 
        g_rw_lock_reader_lock (&(bf->priv->lock));
@@ -1695,7 +1686,7 @@ book_backend_file_get_contact_list_uids_sync (EBookBackend *backend,
        success = e_book_sqlite_search_uids (
                bf->priv->sqlitedb,
                query,
-               &uids,
+               out_uids,
                cancellable,
                &local_error);
        e_book_sqlite_unlock (
@@ -1706,7 +1697,7 @@ book_backend_file_get_contact_list_uids_sync (EBookBackend *backend,
        g_rw_lock_reader_unlock (&(bf->priv->lock));
 
        if (!success) {
-               g_warn_if_fail (uids == NULL);
+               g_warn_if_fail (*out_uids == NULL);
 
                if (g_error_matches (local_error,
                                     E_BOOK_SQLITE_ERROR,
@@ -1734,12 +1725,6 @@ book_backend_file_get_contact_list_uids_sync (EBookBackend *backend,
                }
        }
 
-       /* Transfer UID strings to the GQueue. */
-       for (link = uids; link != NULL; link = g_slist_next (link))
-               g_queue_push_tail (out_uids, link->data);
-
-       g_slist_free (uids);
-
        return success;
 }
 
@@ -1825,16 +1810,6 @@ book_backend_file_configure_direct (EBookBackend *backend,
        priv->base_directory = g_strdup (config);
 }
 
-static void
-book_backend_file_sync (EBookBackend *backend)
-{
-       EBookBackendFile *bf = E_BOOK_BACKEND_FILE (backend);
-
-       g_return_if_fail (bf != NULL);
-
-       /* FIXME: Tell sqlite to dump NOW ! */
-}
-
 static void
 book_backend_file_vcard_changed (EbSqlChangeType change_type,
                                  const gchar *uid,
@@ -2143,6 +2118,7 @@ e_book_backend_file_class_init (EBookBackendFileClass *class)
 {
        GObjectClass *object_class;
        EBookBackendClass *backend_class;
+       EBookBackendSyncClass *backend_sync_class;
 
        g_type_class_add_private (class, sizeof (EBookBackendFilePrivate));
 
@@ -2150,20 +2126,21 @@ e_book_backend_file_class_init (EBookBackendFileClass *class)
        object_class->dispose = book_backend_file_dispose;
        object_class->finalize = book_backend_file_finalize;
 
+       backend_sync_class = E_BOOK_BACKEND_SYNC_CLASS (class);
+       backend_sync_class->open_sync = book_backend_file_open_sync;
+       backend_sync_class->create_contacts_sync = book_backend_file_create_contacts_sync;
+       backend_sync_class->modify_contacts_sync = book_backend_file_modify_contacts_sync;
+       backend_sync_class->remove_contacts_sync = book_backend_file_remove_contacts_sync;
+       backend_sync_class->get_contact_sync = book_backend_file_get_contact_sync;
+       backend_sync_class->get_contact_list_sync = book_backend_file_get_contact_list_sync;
+       backend_sync_class->get_contact_list_uids_sync = book_backend_file_get_contact_list_uids_sync;
+
        backend_class = E_BOOK_BACKEND_CLASS (class);
        backend_class->get_backend_property = book_backend_file_get_backend_property;
-       backend_class->open_sync = book_backend_file_open_sync;
-       backend_class->create_contacts_sync = book_backend_file_create_contacts_sync;
-       backend_class->modify_contacts_sync = book_backend_file_modify_contacts_sync;
-       backend_class->remove_contacts_sync = book_backend_file_remove_contacts_sync;
-       backend_class->get_contact_sync = book_backend_file_get_contact_sync;
-       backend_class->get_contact_list_sync = book_backend_file_get_contact_list_sync;
-       backend_class->get_contact_list_uids_sync = book_backend_file_get_contact_list_uids_sync;
        backend_class->start_view = book_backend_file_start_view;
        backend_class->stop_view = book_backend_file_stop_view;
        backend_class->get_direct_book = book_backend_file_get_direct_book;
        backend_class->configure_direct = book_backend_file_configure_direct;
-       backend_class->sync = book_backend_file_sync;
        backend_class->set_locale = book_backend_file_set_locale;
        backend_class->dup_locale = book_backend_file_dup_locale;
        backend_class->create_cursor = book_backend_file_create_cursor;
diff --git a/src/addressbook/backends/file/e-book-backend-file.h 
b/src/addressbook/backends/file/e-book-backend-file.h
index 8af35fe61..16760d573 100644
--- a/src/addressbook/backends/file/e-book-backend-file.h
+++ b/src/addressbook/backends/file/e-book-backend-file.h
@@ -54,12 +54,12 @@ typedef struct _EBookBackendFileClass EBookBackendFileClass;
 typedef struct _EBookBackendFilePrivate EBookBackendFilePrivate;
 
 struct _EBookBackendFile {
-       EBookBackend parent;
+       EBookBackendSync parent;
        EBookBackendFilePrivate *priv;
 };
 
 struct _EBookBackendFileClass {
-       EBookBackendClass parent_class;
+       EBookBackendSyncClass parent_class;
 };
 
 GType          e_book_backend_file_get_type    (void);
diff --git a/src/addressbook/backends/ldap/e-book-backend-ldap.c 
b/src/addressbook/backends/ldap/e-book-backend-ldap.c
index 5d6a0b72c..067a4aed5 100644
--- a/src/addressbook/backends/ldap/e-book-backend-ldap.c
+++ b/src/addressbook/backends/ldap/e-book-backend-ldap.c
@@ -2099,7 +2099,6 @@ get_contact_handler (LDAPOp *op,
        if (msg_type == LDAP_RES_SEARCH_ENTRY) {
                LDAPMessage *e;
                EContact *contact;
-               gchar *vcard;
 
                g_rec_mutex_lock (&eds_ldap_handler_lock);
                if (bl->priv->ldap)
@@ -2133,13 +2132,11 @@ get_contact_handler (LDAPOp *op,
                        return;
                }
 
-               vcard = e_vcard_to_string (E_VCARD (contact), EVC_FORMAT_VCARD_30);
                e_data_book_respond_get_contact (
                        op->book,
                        op->opid,
                        EDB_ERROR (SUCCESS),
-                       vcard);
-               g_free (vcard);
+                       contact);
                g_object_unref (contact);
                ldap_op_finished (op);
 
@@ -2245,18 +2242,18 @@ contact_list_handler (LDAPOp *op,
 
                while (NULL != e) {
                        EContact *contact;
-                       gchar *vcard;
 
                        contact = build_contact_from_entry (bl, e, NULL, NULL);
                        if (contact) {
-                               vcard = e_vcard_to_string (E_VCARD (contact), EVC_FORMAT_VCARD_30);
+                               if (enable_debug) {
+                                       gchar *vcard;
 
-                               if (enable_debug)
+                                       vcard = e_vcard_to_string (E_VCARD (contact), EVC_FORMAT_VCARD_30);
                                        printf ("vcard = %s\n", vcard);
+                                       g_free (vcard);
+                               }
 
-                               contact_list_op->contacts = g_slist_append (contact_list_op->contacts, vcard);
-
-                               g_object_unref (contact);
+                               contact_list_op->contacts = g_slist_append (contact_list_op->contacts, 
contact);
                        }
 
                        g_rec_mutex_lock (&eds_ldap_handler_lock);
@@ -2343,8 +2340,7 @@ contact_list_dtor (LDAPOp *op)
 {
        LDAPGetContactListOp *contact_list_op = (LDAPGetContactListOp *) op;
 
-       g_slist_foreach (contact_list_op->contacts, (GFunc) g_free, NULL);
-       g_slist_free (contact_list_op->contacts);
+       g_slist_free_full (contact_list_op->contacts, g_object_unref);
 
        g_free (contact_list_op);
 }
@@ -4631,13 +4627,8 @@ generate_cache_dtor (LDAPOp *op)
 {
        LDAPGetContactListOp *contact_list_op = (LDAPGetContactListOp *) op;
        EBookBackendLDAP *ldap_backend = E_BOOK_BACKEND_LDAP (op->backend);
-       GSList *l;
-
-       for (l = contact_list_op->contacts; l; l = g_slist_next (l)) {
-               g_object_unref (l->data);
-       }
 
-       g_slist_free (contact_list_op->contacts);
+       g_slist_free_full (contact_list_op->contacts, g_object_unref);
        g_free (contact_list_op);
 
        g_rec_mutex_lock (&eds_ldap_handler_lock);
@@ -4740,24 +4731,28 @@ generate_cache (EBookBackendLDAP *book_backend_ldap)
        }
 }
 
-static gboolean
-book_backend_ldap_refresh_sync (EBookBackend *backend,
-                               GCancellable *cancellable,
-                               GError **error)
+static void
+book_backend_ldap_refresh (EBookBackend *backend,
+                          EDataBook *book,
+                          guint32 opid,
+                          GCancellable *cancellable)
 {
-       EBookBackendLDAP *ldap_backend = E_BOOK_BACKEND_LDAP (backend);
+       EBookBackendLDAP *ldap_backend;
 
-       g_return_val_if_fail (ldap_backend != NULL, FALSE);
-       g_return_val_if_fail (ldap_backend->priv != NULL, FALSE);
+       g_return_if_fail (E_IS_BOOK_BACKEND_LDAP (backend));
+       g_return_if_fail (E_IS_DATA_BOOK (book));
 
-       if (!ldap_backend->priv->cache || !ldap_backend->priv->marked_for_offline ||
-           ldap_backend->priv->generate_cache_in_progress)
-               return TRUE;
+       ldap_backend = E_BOOK_BACKEND_LDAP (backend);
+       g_return_if_fail (ldap_backend != NULL);
+       g_return_if_fail (ldap_backend->priv != NULL);
 
-       e_book_backend_cache_set_time (ldap_backend->priv->cache, "");
-       generate_cache (ldap_backend);
+       if (ldap_backend->priv->cache && ldap_backend->priv->marked_for_offline &&
+           !ldap_backend->priv->generate_cache_in_progress) {
+               e_book_backend_cache_set_time (ldap_backend->priv->cache, "");
+               generate_cache (ldap_backend);
+       }
 
-       return TRUE;
+       e_data_book_respond_refresh (book, opid, NULL);
 }
 
 static void
@@ -5068,12 +5063,12 @@ book_backend_ldap_open (EBookBackend *backend,
 
 static void
 book_backend_ldap_create_contacts (EBookBackend *backend,
-                                   EDataBook *book,
-                                   guint32 opid,
-                                   GCancellable *cancellable,
-                                   const GSList *vcards)
+                                  EDataBook *book,
+                                  guint32 opid,
+                                  GCancellable *cancellable,
+                                  const gchar * const *vcards)
 {
-       LDAPCreateOp *create_op = g_new0 (LDAPCreateOp, 1);
+       LDAPCreateOp *create_op;
        EBookBackendLDAP *bl = E_BOOK_BACKEND_LDAP (backend);
        EDataBookView *book_view;
        gint create_contact_msgid;
@@ -5081,12 +5076,16 @@ book_backend_ldap_create_contacts (EBookBackend *backend,
        GPtrArray *mod_array;
        LDAPMod **ldap_mods;
        gchar *new_uid;
-       const gchar *vcard = (const gchar *) vcards->data;
+       const gchar *vcard;
        gboolean is_list;
 
+       g_return_if_fail (vcards != NULL);
+
+       vcard = vcards[0];
+
        /* We make the assumption that the vCard list we're passed is always exactly one element long, since 
we haven't specified "bulk-adds"
         * in our static capability list. This is because there is no clean way to roll back changes in case 
of an error. */
-       if (vcards->next != NULL) {
+       if (!vcards[0] || vcards[1]) {
                e_data_book_respond_create_contacts (
                        book, opid,
                        EDB_ERROR_EX (NOT_SUPPORTED,
@@ -5113,6 +5112,7 @@ book_backend_ldap_create_contacts (EBookBackend *backend,
        if (enable_debug)
                printf ("Create Contact: vcard = %s\n", vcard);
 
+       create_op = g_new0 (LDAPCreateOp, 1);
        create_op->new_contact = e_contact_new_from_vcard (vcard);
 
        new_uid = create_dn_from_contact (create_op->new_contact, bl->priv->ldap_rootdn);
@@ -5211,14 +5211,18 @@ book_backend_ldap_modify_contacts (EBookBackend *backend,
                                    EDataBook *book,
                                    guint32 opid,
                                    GCancellable *cancellable,
-                                   const GSList *vcards)
+                                   const gchar * const *vcards)
 {
-       LDAPModifyOp *modify_op = g_new0 (LDAPModifyOp, 1);
+       LDAPModifyOp *modify_op;
        EBookBackendLDAP *bl = E_BOOK_BACKEND_LDAP (backend);
        gint ldap_error;
        gint modify_contact_msgid;
        EDataBookView *book_view;
-       gchar *vcard = vcards->data;
+       const gchar *vcard;
+
+       g_return_if_fail (vcards != NULL);
+
+       vcard = vcards[0];
 
        if (!e_backend_get_online (E_BACKEND (backend))) {
                e_data_book_respond_modify_contacts (book, opid, EDB_ERROR (REPOSITORY_OFFLINE), NULL);
@@ -5227,7 +5231,7 @@ book_backend_ldap_modify_contacts (EBookBackend *backend,
 
        /* We make the assumption that the vCard list we're passed is always exactly one element long, since 
we haven't specified "bulk-modifies"
         * in our static capability list. This is because there is no clean way to roll back changes in case 
of an error. */
-       if (vcards->next != NULL) {
+       if (!vcards[0] || vcards[1]) {
                e_data_book_respond_modify_contacts (book, opid,
                                                     EDB_ERROR_EX (NOT_SUPPORTED,
                                                     _("The backend does not support bulk modifications")),
@@ -5239,7 +5243,6 @@ book_backend_ldap_modify_contacts (EBookBackend *backend,
        if (!bl->priv->ldap) {
                g_rec_mutex_unlock (&eds_ldap_handler_lock);
                e_data_book_respond_modify_contacts (book, opid, EDB_ERROR_NOT_CONNECTED (), NULL);
-               g_free (modify_op);
                return;
        }
        g_rec_mutex_unlock (&eds_ldap_handler_lock);
@@ -5248,6 +5251,7 @@ book_backend_ldap_modify_contacts (EBookBackend *backend,
 
        if (enable_debug)
                printf ("Modify Contact: vcard = %s\n", vcard);
+       modify_op = g_new0 (LDAPModifyOp, 1);
        modify_op->contact = e_contact_new_from_vcard (vcard);
        modify_op->id = e_contact_get_const (modify_op->contact, E_CONTACT_UID);
 
@@ -5289,17 +5293,18 @@ book_backend_ldap_remove_contacts (EBookBackend *backend,
                                    EDataBook *book,
                                    guint32 opid,
                                    GCancellable *cancellable,
-                                   const GSList *ids)
+                                   const gchar * const *uids)
 {
-       LDAPRemoveOp *remove_op = g_new (LDAPRemoveOp, 1);
+       LDAPRemoveOp *remove_op;
        EBookBackendLDAP *bl = E_BOOK_BACKEND_LDAP (backend);
        EDataBookView *book_view;
        gint remove_msgid;
        gint ldap_error;
 
+       g_return_if_fail (uids != NULL);
+
        if (!e_backend_get_online (E_BACKEND (backend))) {
                e_data_book_respond_remove_contacts (book, opid, EDB_ERROR (REPOSITORY_OFFLINE), NULL);
-               g_free (remove_op);
                return;
        }
 
@@ -5307,7 +5312,6 @@ book_backend_ldap_remove_contacts (EBookBackend *backend,
        if (!bl->priv->ldap) {
                g_rec_mutex_unlock (&eds_ldap_handler_lock);
                e_data_book_respond_remove_contacts (book, opid, EDB_ERROR_NOT_CONNECTED (), NULL);
-               g_free (remove_op);
                return;
        }
        g_rec_mutex_unlock (&eds_ldap_handler_lock);
@@ -5319,7 +5323,8 @@ book_backend_ldap_remove_contacts (EBookBackend *backend,
        ** capabilities, we should only get 1 length lists here, so
        ** the id we're deleting is the first and only id in the list.
        */
-       remove_op->id = g_strdup (ids->data);
+       remove_op = g_new (LDAPRemoveOp, 1);
+       remove_op->id = g_strdup (uids[0]);
 
        do {
                book_view_notify_status (bl, book_view, _("Removing contact from LDAP server..."));
@@ -5372,21 +5377,17 @@ book_backend_ldap_get_contact (EBookBackend *backend,
        if (!e_backend_get_online (E_BACKEND (backend))) {
                if (bl->priv->marked_for_offline && bl->priv->cache) {
                        EContact *contact = e_book_backend_cache_get_contact (bl->priv->cache, id);
-                       gchar *vcard_str;
 
                        if (!contact) {
                                e_data_book_respond_get_contact (book, opid, EDB_ERROR (CONTACT_NOT_FOUND), 
NULL);
                                return;
                        }
 
-                       vcard_str = e_vcard_to_string (E_VCARD (contact), EVC_FORMAT_VCARD_30);
-
                        e_data_book_respond_get_contact (
                                book,
                                opid,
                                EDB_ERROR (SUCCESS),
-                               vcard_str);
-                       g_free (vcard_str);
+                               contact);
                        g_object_unref (contact);
                        return;
                }
@@ -5478,23 +5479,20 @@ book_backend_ldap_get_contact_list (EBookBackend *backend,
        if (!e_backend_get_online (E_BACKEND (backend))) {
                if (bl->priv->marked_for_offline && bl->priv->cache) {
                        GList *contacts;
-                       GSList *vcard_strings = NULL;
+                       GSList *contacts_slist = NULL;
                        GList *l;
 
                        contacts = e_book_backend_cache_get_contacts (bl->priv->cache, query);
 
                        for (l = contacts; l; l = g_list_next (l)) {
                                EContact *contact = l->data;
-                               vcard_strings = g_slist_prepend (
-                                       vcard_strings, e_vcard_to_string (E_VCARD (contact),
-                                       EVC_FORMAT_VCARD_30));
-                               g_object_unref (contact);
+                               contacts_slist = g_slist_prepend (contacts_slist, contact);
                        }
 
-                       g_list_free (contacts);
-                       e_data_book_respond_get_contact_list (book, opid, EDB_ERROR (SUCCESS), vcard_strings);
-                       g_slist_foreach (vcard_strings, (GFunc) g_free, NULL);
-                       g_slist_free (vcard_strings);
+                       e_data_book_respond_get_contact_list (book, opid, EDB_ERROR (SUCCESS), 
contacts_slist);
+
+                       g_list_free_full (contacts, g_object_unref);
+                       g_slist_free (contacts_slist);
                        return;
                }
 
@@ -5600,8 +5598,7 @@ book_backend_ldap_get_contact_list_uids (EBookBackend *backend,
 
                        g_list_free (contacts);
                        e_data_book_respond_get_contact_list_uids (book, opid, EDB_ERROR (SUCCESS), uids);
-                       g_slist_foreach (uids, (GFunc) g_free, NULL);
-                       g_slist_free (uids);
+                       g_slist_free_full (uids, g_free);
                        return;
                }
 
@@ -5948,7 +5945,7 @@ e_book_backend_ldap_class_init (EBookBackendLDAPClass *class)
        book_backend_class->get_contact_list_uids = book_backend_ldap_get_contact_list_uids;
        book_backend_class->start_view = book_backend_ldap_start_view;
        book_backend_class->stop_view = book_backend_ldap_stop_view;
-       book_backend_class->refresh_sync = book_backend_ldap_refresh_sync;
+       book_backend_class->refresh = book_backend_ldap_refresh;
 
        /* Register our ESource extension. */
        E_TYPE_SOURCE_LDAP;
diff --git a/src/addressbook/libedata-book/CMakeLists.txt b/src/addressbook/libedata-book/CMakeLists.txt
index 8972c9bd5..15ac13a77 100644
--- a/src/addressbook/libedata-book/CMakeLists.txt
+++ b/src/addressbook/libedata-book/CMakeLists.txt
@@ -9,12 +9,13 @@ set(DEPENDENCIES
 )
 
 set(SOURCES
+       e-book-backend.c
+       e-book-backend-cache.c
        e-book-backend-factory.c
        e-book-backend-sexp.c
-       e-book-backend-summary.c
-       e-book-backend-cache.c
        e-book-backend-sqlitedb.c
-       e-book-backend.c
+       e-book-backend-summary.c
+       e-book-backend-sync.c
        e-book-cache.c
        e-book-meta-backend.c
        e-book-sqlite.c
@@ -32,10 +33,13 @@ set(SOURCES
 
 set(HEADERS
        libedata-book.h
+       e-book-backend.h
+       e-book-backend-cache.h
        e-book-backend-factory.h
        e-book-backend-sexp.h
+       e-book-backend-sqlitedb.h
        e-book-backend-summary.h
-       e-book-backend.h
+       e-book-backend-sync.h
        e-book-cache.h
        e-book-meta-backend.h
        e-book-sqlite.h
@@ -46,8 +50,6 @@ set(HEADERS
        e-data-book-cursor-cache.h
        e-data-book-cursor-sqlite.h
        e-data-book-direct.h
-       e-book-backend-cache.h
-       e-book-backend-sqlitedb.h
        e-subprocess-book-factory.h
        e-system-locale-watcher.h
 )
diff --git a/src/addressbook/libedata-book/e-book-backend-sync.c 
b/src/addressbook/libedata-book/e-book-backend-sync.c
new file mode 100644
index 000000000..a9d3e7079
--- /dev/null
+++ b/src/addressbook/libedata-book/e-book-backend-sync.c
@@ -0,0 +1,577 @@
+/*
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ * Copyright (C) 2012 Intel Corporation
+ *
+ * This library is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors: Nat Friedman (nat ximian com)
+ *          Tristan Van Berkom <tristanvb openismus com>
+ */
+
+/**
+ * SECTION: e-book-backend-sync
+ * @include: libedata-book/libedata-book.h
+ * @short_description: An abstract class for implementing synchronous addressbook backends
+ *
+ * This is a descendant of the #EBookBackend, providing synchronous variants
+ * of the main methods.
+ *
+ * Since: 3.36
+ **/
+
+#include "evolution-data-server-config.h"
+
+#include <glib.h>
+
+#include "e-data-book-view.h"
+#include "e-data-book.h"
+#include "e-book-backend.h"
+#include "e-book-backend-sync.h"
+
+struct _EBookBackendSyncPrivate {
+       guint dummy;
+};
+
+G_DEFINE_TYPE (EBookBackendSync, e_book_backend_sync, E_TYPE_BOOK_BACKEND)
+
+static void
+book_backend_sync_open (EBookBackend *backend,
+                       EDataBook *book,
+                       guint32 opid,
+                       GCancellable *cancellable,
+                       gboolean only_if_exists)
+{
+       GError *error = NULL;
+
+       g_return_if_fail (E_IS_BOOK_BACKEND_SYNC (backend));
+       g_return_if_fail (E_IS_DATA_BOOK (book));
+
+       e_book_backend_sync_open (E_BOOK_BACKEND_SYNC (backend), cancellable, &error);
+
+       e_data_book_respond_open (book, opid, error);
+}
+
+static void
+book_backend_sync_refresh (EBookBackend *backend,
+                          EDataBook *book,
+                          guint32 opid,
+                          GCancellable *cancellable)
+{
+       GError *error = NULL;
+
+       g_return_if_fail (E_IS_BOOK_BACKEND_SYNC (backend));
+       g_return_if_fail (E_IS_DATA_BOOK (book));
+
+       e_book_backend_sync_refresh (E_BOOK_BACKEND_SYNC (backend), cancellable, &error);
+
+       e_data_book_respond_refresh (book, opid, error);
+}
+
+static void
+book_backend_sync_create_contacts (EBookBackend *backend,
+                                  EDataBook *book,
+                                  guint32 opid,
+                                  GCancellable *cancellable,
+                                  const gchar * const *vcards)
+{
+       GSList *contacts = NULL;
+       GError *error = NULL;
+
+       g_return_if_fail (E_IS_BOOK_BACKEND_SYNC (backend));
+       g_return_if_fail (E_IS_DATA_BOOK (book));
+
+       e_book_backend_sync_create_contacts (E_BOOK_BACKEND_SYNC (backend), vcards, &contacts, cancellable, 
&error);
+
+       e_data_book_respond_create_contacts (book, opid, error, contacts);
+
+       g_slist_free_full (contacts, g_object_unref);
+}
+
+static void
+book_backend_sync_modify_contacts (EBookBackend *backend,
+                                  EDataBook *book,
+                                  guint32 opid,
+                                  GCancellable *cancellable,
+                                  const gchar * const *vcards)
+{
+       GSList *contacts = NULL;
+       GError *error = NULL;
+
+       g_return_if_fail (E_IS_BOOK_BACKEND_SYNC (backend));
+       g_return_if_fail (E_IS_DATA_BOOK (book));
+
+       e_book_backend_sync_modify_contacts (E_BOOK_BACKEND_SYNC (backend), vcards, &contacts, cancellable, 
&error);
+
+       e_data_book_respond_modify_contacts (book, opid, error, contacts);
+
+       g_slist_free_full (contacts, g_object_unref);
+}
+
+static void
+book_backend_sync_remove_contacts (EBookBackend *backend,
+                                  EDataBook *book,
+                                  guint32 opid,
+                                  GCancellable *cancellable,
+                                  const gchar * const *uids)
+{
+       GSList *removed_uids = NULL;
+       GError *error = NULL;
+
+       g_return_if_fail (E_IS_BOOK_BACKEND_SYNC (backend));
+       g_return_if_fail (E_IS_DATA_BOOK (book));
+
+       e_book_backend_sync_remove_contacts (E_BOOK_BACKEND_SYNC (backend), uids, &removed_uids, cancellable, 
&error);
+
+       e_data_book_respond_remove_contacts (book, opid, error, removed_uids);
+
+       g_slist_free_full (removed_uids, g_free);
+}
+
+static void
+book_backend_sync_get_contact (EBookBackend *backend,
+                              EDataBook *book,
+                              guint32 opid,
+                              GCancellable *cancellable,
+                              const gchar *uid)
+{
+       EContact *contact;
+       GError *error = NULL;
+
+       g_return_if_fail (E_IS_BOOK_BACKEND_SYNC (backend));
+       g_return_if_fail (E_IS_DATA_BOOK (book));
+
+       contact = e_book_backend_sync_get_contact (E_BOOK_BACKEND_SYNC (backend), uid, cancellable, &error);
+
+       e_data_book_respond_get_contact (book, opid, error, contact);
+
+       g_clear_object (&contact);
+}
+
+static void
+book_backend_sync_get_contact_list (EBookBackend *backend,
+                                   EDataBook *book,
+                                   guint32 opid,
+                                   GCancellable *cancellable,
+                                   const gchar *query)
+{
+       GSList *contacts = NULL;
+       GError *error = NULL;
+
+       g_return_if_fail (E_IS_BOOK_BACKEND_SYNC (backend));
+       g_return_if_fail (E_IS_DATA_BOOK (book));
+
+       e_book_backend_sync_get_contact_list (E_BOOK_BACKEND_SYNC (backend), query, &contacts, cancellable, 
&error);
+
+       e_data_book_respond_get_contact_list (book, opid, error, contacts);
+
+       g_slist_free_full (contacts, g_object_unref);
+}
+
+static void
+book_backend_sync_get_contact_list_uids (EBookBackend *backend,
+                                        EDataBook *book,
+                                        guint32 opid,
+                                        GCancellable *cancellable,
+                                        const gchar *query)
+{
+       GSList *uids = NULL;
+       GError *error = NULL;
+
+       g_return_if_fail (E_IS_BOOK_BACKEND_SYNC (backend));
+       g_return_if_fail (E_IS_DATA_BOOK (book));
+
+       e_book_backend_sync_get_contact_list_uids (E_BOOK_BACKEND_SYNC (backend), query, &uids, cancellable, 
&error);
+
+       e_data_book_respond_get_contact_list_uids (book, opid, error, uids);
+
+       g_slist_free_full (uids, g_free);
+}
+
+static gboolean
+book_backend_sync_get_contact_list_uids_sync (EBookBackendSync *backend,
+                                             const gchar *query,
+                                             GSList **out_uids,
+                                             GCancellable *cancellable,
+                                             GError **error)
+{
+       GSList *contacts = NULL;
+       gboolean success;
+
+       g_return_val_if_fail (E_IS_BOOK_BACKEND_SYNC (backend), FALSE);
+       g_return_val_if_fail (out_uids != NULL, FALSE);
+
+       *out_uids = NULL;
+
+       success = e_book_backend_sync_get_contact_list (backend, query, &contacts, cancellable, error);
+
+       if (success) {
+               GSList *link;
+
+               for (link = contacts; link; link = g_slist_next (link)) {
+                       EContact *contact = link->data;
+                       gchar *uid;
+
+                       uid = e_contact_get (contact, E_CONTACT_UID);
+                       *out_uids = g_slist_prepend (*out_uids, uid);
+               }
+       }
+
+       g_slist_free_full (contacts, g_object_unref);
+
+       return success;
+}
+
+static void
+e_book_backend_sync_class_init (EBookBackendSyncClass *klass)
+{
+       EBookBackendClass *book_backend_class;
+
+       g_type_class_add_private (klass, sizeof (EBookBackendSyncPrivate));
+
+       klass->get_contact_list_uids_sync = book_backend_sync_get_contact_list_uids_sync;
+
+       book_backend_class = E_BOOK_BACKEND_CLASS (klass);
+       book_backend_class->open = book_backend_sync_open;
+       book_backend_class->refresh = book_backend_sync_refresh;
+       book_backend_class->create_contacts = book_backend_sync_create_contacts;
+       book_backend_class->modify_contacts = book_backend_sync_modify_contacts;
+       book_backend_class->remove_contacts = book_backend_sync_remove_contacts;
+       book_backend_class->get_contact = book_backend_sync_get_contact;
+       book_backend_class->get_contact_list = book_backend_sync_get_contact_list;
+       book_backend_class->get_contact_list_uids = book_backend_sync_get_contact_list_uids;
+}
+
+static void
+e_book_backend_sync_init (EBookBackendSync *backend)
+{
+       backend->priv = G_TYPE_INSTANCE_GET_PRIVATE (backend, E_TYPE_BOOK_BACKEND_SYNC, 
EBookBackendSyncPrivate);
+}
+
+/**
+ * e_book_backend_sync_open:
+ * @backend: an #EBookBackendSync
+ * @cancellable: optional #GCancellable object, or %NULL
+ * @error: return location for a #GError, or %NULL
+ *
+ * "Opens" the @backend.  Opening a backend is something of an outdated
+ * concept, but the operation is hanging around for a little while longer.
+ * This usually involves some custom initialization logic, and testing of
+ * remote authentication if applicable.
+ *
+ * If an error occurs, the function will set @error and return %FALSE.
+ *
+ * Returns: %TRUE on success, %FALSE on failure
+ *
+ * Since: 3.36
+ **/
+gboolean
+e_book_backend_sync_open (EBookBackendSync *backend,
+                         GCancellable *cancellable,
+                         GError **error)
+{
+       EBookBackendSyncClass *klass;
+
+       g_return_val_if_fail (E_IS_BOOK_BACKEND_SYNC (backend), FALSE);
+
+       klass = E_BOOK_BACKEND_SYNC_GET_CLASS (backend);
+       g_return_val_if_fail (klass != NULL, FALSE);
+
+       if (klass->open_sync)
+               return klass->open_sync (backend, cancellable, error);
+
+       g_propagate_error (error, e_client_error_create (E_CLIENT_ERROR_NOT_SUPPORTED, NULL));
+
+       return FALSE;
+}
+
+/**
+ * e_book_backend_sync_refresh:
+ * @backend: an #EBookBackendSync
+ * @cancellable: optional #GCancellable object, or %NULL
+ * @error: return location for a #GError, or %NULL
+ *
+ * Initiates a refresh for @backend, if the @backend supports refreshing.
+ * The actual refresh operation completes on its own time.  This function
+ * merely initiates the operation.
+ *
+ * If an error occurs while initiating the refresh, the function will set
+ * @error and return %FALSE.  If the @backend does not support refreshing,
+ * the function will set an %E_CLIENT_ERROR_NOT_SUPPORTED error and return
+ * %FALSE.
+ *
+ * Returns: %TRUE on success, %FALSE on failure
+ *
+ * Since: 3.36
+ **/
+gboolean
+e_book_backend_sync_refresh (EBookBackendSync *backend,
+                            GCancellable *cancellable,
+                            GError **error)
+{
+       EBookBackendSyncClass *klass;
+
+       g_return_val_if_fail (E_IS_BOOK_BACKEND_SYNC (backend), FALSE);
+
+       klass = E_BOOK_BACKEND_SYNC_GET_CLASS (backend);
+       g_return_val_if_fail (klass != NULL, FALSE);
+
+       if (klass->refresh_sync)
+               return klass->refresh_sync (backend, cancellable, error);
+
+       g_propagate_error (error, e_client_error_create (E_CLIENT_ERROR_NOT_SUPPORTED, NULL));
+
+       return FALSE;
+}
+
+/**
+ * e_book_backend_sync_create_contacts:
+ * @backend: an #EBookBackendSync
+ * @vcards: a %NULL-terminated array of vCard strings
+ * @out_contacts: (out) (element-type EContact): a #GSList in which to deposit results
+ * @cancellable: optional #GCancellable object, or %NULL
+ * @error: return location for a #GError, or %NULL
+ *
+ * Creates one or more new contacts from @vcards, and deposits an #EContact
+ * instance for each newly-created contact in @out_contacts.
+ *
+ * The returned #EContact instances are referenced for thread-safety and
+ * must be unreferenced with g_object_unref() when finished with them.
+ *
+ * If an error occurs, the function will set @error and return %FALSE.
+ *
+ * Returns: %TRUE on success, %FALSE on failure
+ *
+ * Since: 3.36
+ **/
+gboolean
+e_book_backend_sync_create_contacts (EBookBackendSync *backend,
+                                    const gchar * const *vcards,
+                                    GSList **out_contacts,
+                                    GCancellable *cancellable,
+                                    GError **error)
+{
+       EBookBackendSyncClass *klass;
+
+       g_return_val_if_fail (E_IS_BOOK_BACKEND_SYNC (backend), FALSE);
+
+       klass = E_BOOK_BACKEND_SYNC_GET_CLASS (backend);
+       g_return_val_if_fail (klass != NULL, FALSE);
+
+       if (klass->create_contacts_sync)
+               return klass->create_contacts_sync (backend, vcards, out_contacts, cancellable, error);
+
+       g_propagate_error (error, e_client_error_create (E_CLIENT_ERROR_NOT_SUPPORTED, NULL));
+
+       return FALSE;
+}
+
+/**
+ * e_book_backend_sync_modify_contacts:
+ * @backend: an #EBookBackendSync
+ * @vcards: a %NULL-terminated array of vCard strings
+ * @out_contacts: (out) (element-type EContact): a #GSList to deposit the modified contacts to
+ * @cancellable: optional #GCancellable object, or %NULL
+ * @error: return location for a #GError, or %NULL
+ *
+ * Modifies one or more contacts according to @vcards.
+ *
+ * If an error occurs, the function will set @error and return %FALSE.
+ *
+ * Returns: %TRUE on success, %FALSE on failure
+ *
+ * Since: 3.36
+ **/
+gboolean
+e_book_backend_sync_modify_contacts (EBookBackendSync *backend,
+                                    const gchar * const *vcards,
+                                    GSList **out_contacts,
+                                    GCancellable *cancellable,
+                                    GError **error)
+{
+       EBookBackendSyncClass *klass;
+
+       g_return_val_if_fail (E_IS_BOOK_BACKEND_SYNC (backend), FALSE);
+
+       klass = E_BOOK_BACKEND_SYNC_GET_CLASS (backend);
+       g_return_val_if_fail (klass != NULL, FALSE);
+
+       if (klass->modify_contacts_sync)
+               return klass->modify_contacts_sync (backend, vcards, out_contacts, cancellable, error);
+
+       g_propagate_error (error, e_client_error_create (E_CLIENT_ERROR_NOT_SUPPORTED, NULL));
+
+       return FALSE;
+}
+
+/**
+ * e_book_backend_sync_remove_contacts:
+ * @backend: an #EBookBackendSync
+ * @uids: a %NULL-terminated array of contact ID strings
+ * @out_removed_uids: (out) (element-type utf8): a #GSList of removed UIDs
+ * @cancellable: optional #GCancellable object, or %NULL
+ * @error: return location for a #GError, or %NULL
+ *
+ * Removes one or more contacts according to @uids.
+ *
+ * If an error occurs, the function will set @error and return %FALSE.
+ *
+ * Returns: %TRUE on success, %FALSE on failure
+ *
+ * Since: 3.36
+ **/
+gboolean
+e_book_backend_sync_remove_contacts (EBookBackendSync *backend,
+                                    const gchar * const *uids,
+                                    GSList **out_removed_uids,
+                                    GCancellable *cancellable,
+                                    GError **error)
+{
+       EBookBackendSyncClass *klass;
+
+       g_return_val_if_fail (E_IS_BOOK_BACKEND_SYNC (backend), FALSE);
+
+       klass = E_BOOK_BACKEND_SYNC_GET_CLASS (backend);
+       g_return_val_if_fail (klass != NULL, FALSE);
+
+       if (klass->remove_contacts_sync)
+               return klass->remove_contacts_sync (backend, uids, out_removed_uids, cancellable, error);
+
+       g_propagate_error (error, e_client_error_create (E_CLIENT_ERROR_NOT_SUPPORTED, NULL));
+
+       return FALSE;
+}
+
+/**
+ * e_book_backend_sync_get_contact:
+ * @backend: an #EBookBackendSync
+ * @uid: a contact ID
+ * @cancellable: optional #GCancellable object, or %NULL
+ * @error: return location for a #GError, or %NULL
+ *
+ * Obtains an #EContact for @uid.
+ *
+ * The returned #EContact is referenced for thread-safety and must be
+ * unreferenced with g_object_unref() when finished with it.
+ *
+ * If an error occurs, the function will set @error and return %NULL.
+ *
+ * Returns: (transfer full): an #EContact, or %NULL
+ *
+ * Since: 3.36
+ **/
+EContact *
+e_book_backend_sync_get_contact (EBookBackendSync *backend,
+                                const gchar *uid,
+                                GCancellable *cancellable,
+                                GError **error)
+{
+       EBookBackendSyncClass *klass;
+
+       g_return_val_if_fail (E_IS_BOOK_BACKEND_SYNC (backend), FALSE);
+
+       klass = E_BOOK_BACKEND_SYNC_GET_CLASS (backend);
+       g_return_val_if_fail (klass != NULL, FALSE);
+
+       if (klass->get_contact_sync)
+               return klass->get_contact_sync (backend, uid, cancellable, error);
+
+       g_propagate_error (error, e_client_error_create (E_CLIENT_ERROR_NOT_SUPPORTED, NULL));
+
+       return FALSE;
+}
+
+/**
+ * e_book_backend_sync_get_contact_list:
+ * @backend: an #EBookBackendSync
+ * @query: a search query in S-expression format
+ * @out_contacts: (out) (element-type EContact): a #GSList in which to deposit results
+ * @cancellable: optional #GCancellable object, or %NULL
+ * @error: return location for a #GError, or %NULL
+ *
+ * Obtains a set of #EContact instances which satisfy the criteria specified
+ * in @query, and deposits them in @out_contacts.
+ *
+ * The returned #EContact instances are referenced for thread-safety and
+ * must be unreferenced with g_object_unref() when finished with them.
+ *
+ * If an error occurs, the function will set @error and return %FALSE.
+ * Note that an empty result set does not necessarily imply an error.
+ *
+ * Returns: %TRUE on success, %FALSE on failure
+ *
+ * Since: 3.36
+ **/
+gboolean
+e_book_backend_sync_get_contact_list (EBookBackendSync *backend,
+                                     const gchar *query,
+                                     GSList **out_contacts,
+                                     GCancellable *cancellable,
+                                     GError **error)
+{
+       EBookBackendSyncClass *klass;
+
+       g_return_val_if_fail (E_IS_BOOK_BACKEND_SYNC (backend), FALSE);
+
+       klass = E_BOOK_BACKEND_SYNC_GET_CLASS (backend);
+       g_return_val_if_fail (klass != NULL, FALSE);
+
+       if (klass->get_contact_list_sync)
+               return klass->get_contact_list_sync (backend, query, out_contacts, cancellable, error);
+
+       g_propagate_error (error, e_client_error_create (E_CLIENT_ERROR_NOT_SUPPORTED, NULL));
+
+       return FALSE;
+}
+
+/**
+ * e_book_backend_sync_get_contact_list_uids:
+ * @backend: an #EBookBackendSync
+ * @query: a search query in S-expression format
+ * @out_uids: a #GSList in which to deposit results
+ * @cancellable: optional #GCancellable object, or %NULL
+ * @error: return location for a #GError, or %NULL
+ *
+ * Obtains a set of ID strings for contacts which satisfy the criteria
+ * specified in @query, and deposits them in @out_uids.
+ *
+ * The returned ID strings must be freed with g_free() with finished
+ * with them.
+ *
+ * If an error occurs, the function will set @error and return %FALSE.
+ * Note that an empty result set does not necessarily imply an error.
+ *
+ * Returns: %TRUE on success, %FALSE on failure
+ *
+ * Since: 3.36
+ **/
+gboolean
+e_book_backend_sync_get_contact_list_uids (EBookBackendSync *backend,
+                                          const gchar *query,
+                                          GSList **out_uids,
+                                          GCancellable *cancellable,
+                                          GError **error)
+{
+       EBookBackendSyncClass *klass;
+
+       g_return_val_if_fail (E_IS_BOOK_BACKEND_SYNC (backend), FALSE);
+
+       klass = E_BOOK_BACKEND_SYNC_GET_CLASS (backend);
+       g_return_val_if_fail (klass != NULL, FALSE);
+
+       if (klass->get_contact_list_uids_sync)
+               return klass->get_contact_list_uids_sync (backend, query, out_uids, cancellable, error);
+
+       g_propagate_error (error, e_client_error_create (E_CLIENT_ERROR_NOT_SUPPORTED, NULL));
+
+       return FALSE;
+}
diff --git a/src/addressbook/libedata-book/e-book-backend-sync.h 
b/src/addressbook/libedata-book/e-book-backend-sync.h
new file mode 100644
index 000000000..5a7e89519
--- /dev/null
+++ b/src/addressbook/libedata-book/e-book-backend-sync.h
@@ -0,0 +1,188 @@
+/*
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ * Copyright (C) 2012 Intel Corporation
+ *
+ * This library is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors: Nat Friedman (nat ximian com)
+ *          Tristan Van Berkom <tristanvb openismus com>
+ */
+
+#if !defined (__LIBEDATA_BOOK_H_INSIDE__) && !defined (LIBEDATA_BOOK_COMPILATION)
+#error "Only <libedata-book/libedata-book.h> should be included directly."
+#endif
+
+#ifndef E_BOOK_BACKEND_SYNC_H
+#define E_BOOK_BACKEND_SYNC_H
+
+#include <libebook-contacts/libebook-contacts.h>
+#include <libebackend/libebackend.h>
+
+#include <libedata-book/e-book-backend.h>
+#include <libedata-book/e-data-book.h>
+#include <libedata-book/e-data-book-cursor.h>
+#include <libedata-book/e-data-book-direct.h>
+#include <libedata-book/e-data-book-view.h>
+
+/* Standard GObject macros */
+#define E_TYPE_BOOK_BACKEND_SYNC \
+       (e_book_backend_sync_get_type ())
+#define E_BOOK_BACKEND_SYNC(obj) \
+       (G_TYPE_CHECK_INSTANCE_CAST \
+       ((obj), E_TYPE_BOOK_BACKEND_SYNC, EBookBackendSync))
+#define E_BOOK_BACKEND_SYNC_CLASS(cls) \
+       (G_TYPE_CHECK_CLASS_CAST \
+       ((cls), E_TYPE_BOOK_BACKEND_SYNC, EBookBackendSyncClass))
+#define E_IS_BOOK_BACKEND_SYNC(obj) \
+       (G_TYPE_CHECK_INSTANCE_TYPE \
+       ((obj), E_TYPE_BOOK_BACKEND_SYNC))
+#define E_IS_BOOK_BACKEND_SYNC_CLASS(cls) \
+       (G_TYPE_CHECK_CLASS_TYPE \
+       ((cls), E_TYPE_BOOK_BACKEND_SYNC))
+#define E_BOOK_BACKEND_SYNC_GET_CLASS(obj) \
+       (G_TYPE_INSTANCE_GET_CLASS \
+       ((obj), E_TYPE_BOOK_BACKEND_SYNC, EBookBackendSyncClass))
+
+G_BEGIN_DECLS
+
+typedef struct _EBookBackendSync EBookBackendSync;
+typedef struct _EBookBackendSyncClass EBookBackendSyncClass;
+typedef struct _EBookBackendSyncPrivate EBookBackendSyncPrivate;
+
+/**
+ * EBookBackendSync:
+ *
+ * Contains only private data that should be read and manipulated using the
+ * functions below.
+ */
+struct _EBookBackendSync {
+       /*< private >*/
+       EBookBackend parent;
+       EBookBackendSyncPrivate *priv;
+};
+
+/**
+ * EBookBackendSyncClass:
+ * @open_sync: Open the backend
+ * @refresh_sync: Refresh the backend
+ * @create_contacts_sync: Add and store the passed vcards
+ * @modify_contacts_sync: Modify the existing contacts using the passed vcards
+ * @remove_contacts_sync: Remove the contacts specified by the passed UIDs
+ * @get_contact_sync: Fetch a contact by UID
+ * @get_contact_list_sync: Fetch a list of contacts based on a search expression
+ * @get_contact_list_uids_sync: Fetch a list of contact UIDs based on a search expression (optional)
+ *
+ * Class structure for the #EBookBackendSync class.
+ *
+ * These virtual methods must be implemented when writing
+ * an addressbook backend.
+ */
+struct _EBookBackendSyncClass {
+       /*< private >*/
+       EBookBackendClass parent_class;
+
+       /*< public >*/
+
+       gboolean        (*open_sync)            (EBookBackendSync *backend,
+                                                GCancellable *cancellable,
+                                                GError **error);
+       gboolean        (*refresh_sync)         (EBookBackendSync *backend,
+                                                GCancellable *cancellable,
+                                                GError **error);
+       gboolean        (*create_contacts_sync) (EBookBackendSync *backend,
+                                                const gchar * const *vcards,
+                                                GSList **out_contacts,
+                                                GCancellable *cancellable,
+                                                GError **error);
+       gboolean        (*modify_contacts_sync) (EBookBackendSync *backend,
+                                                const gchar * const *vcards,
+                                                GSList **out_contacts,
+                                                GCancellable *cancellable,
+                                                GError **error);
+       gboolean        (*remove_contacts_sync) (EBookBackendSync *backend,
+                                                const gchar * const *uids,
+                                                GSList **out_removed_uids,
+                                                GCancellable *cancellable,
+                                                GError **error);
+       EContact *      (*get_contact_sync)     (EBookBackendSync *backend,
+                                                const gchar *uid,
+                                                GCancellable *cancellable,
+                                                GError **error);
+       gboolean        (*get_contact_list_sync)
+                                               (EBookBackendSync *backend,
+                                                const gchar *query,
+                                                GSList **out_contacts,
+                                                GCancellable *cancellable,
+                                                GError **error);
+
+       /* This method is optional.  By default, it simply calls
+        * get_contact_list_sync() and extracts UID strings from
+        * the matched EContacts.  Backends may override this if
+        * they can implement it more efficiently. */
+       gboolean        (*get_contact_list_uids_sync)
+                                               (EBookBackendSync *backend,
+                                                const gchar *query,
+                                                GSList **out_uids,
+                                                GCancellable *cancellable,
+                                                GError **error);
+
+       /* Padding for future expansion */
+       gpointer reserved_padding[20];
+};
+
+GType          e_book_backend_sync_get_type    (void) G_GNUC_CONST;
+
+gboolean       e_book_backend_sync_open        (EBookBackendSync *backend,
+                                                GCancellable *cancellable,
+                                                GError **error);
+gboolean       e_book_backend_sync_refresh     (EBookBackendSync *backend,
+                                                GCancellable *cancellable,
+                                                GError **error);
+gboolean       e_book_backend_sync_create_contacts
+                                               (EBookBackendSync *backend,
+                                                const gchar * const *vcards,
+                                                GSList **out_contacts, /* EContact * */
+                                                GCancellable *cancellable,
+                                                GError **error);
+gboolean       e_book_backend_sync_modify_contacts
+                                               (EBookBackendSync *backend,
+                                                const gchar * const *vcards,
+                                                GSList **out_contacts, /* EContact * */
+                                                GCancellable *cancellable,
+                                                GError **error);
+gboolean       e_book_backend_sync_remove_contacts
+                                               (EBookBackendSync *backend,
+                                                const gchar * const *uids,
+                                                GSList **out_removed_uids, /* gchar * */
+                                                GCancellable *cancellable,
+                                                GError **error);
+EContact *     e_book_backend_sync_get_contact (EBookBackendSync *backend,
+                                                const gchar *uid,
+                                                GCancellable *cancellable,
+                                                GError **error);
+gboolean       e_book_backend_sync_get_contact_list
+                                               (EBookBackendSync *backend,
+                                                const gchar *query,
+                                                GSList **out_contacts, /* EContact * */
+                                                GCancellable *cancellable,
+                                                GError **error);
+gboolean       e_book_backend_sync_get_contact_list_uids
+                                               (EBookBackendSync *backend,
+                                                const gchar *query,
+                                                GSList **out_uids, /* gchar * */
+                                                GCancellable *cancellable,
+                                                GError **error);
+
+G_END_DECLS
+
+#endif /* E_BOOK_BACKEND_SYNC_H */
diff --git a/src/addressbook/libedata-book/e-book-backend.c b/src/addressbook/libedata-book/e-book-backend.c
index 18577618b..a769afc70 100644
--- a/src/addressbook/libedata-book/e-book-backend.c
+++ b/src/addressbook/libedata-book/e-book-backend.c
@@ -71,11 +71,6 @@ struct _EBookBackendPrivate {
 };
 
 struct _AsyncContext {
-
-       /* Indicates if we're using the old or new style API,
-        * as method results are stashed differently for each. */
-       gboolean old_style;
-
        /* Inputs */
        gchar *uid;
        gchar *query;
@@ -668,41 +663,6 @@ book_backend_get_backend_property (EBookBackend *backend,
        return prop_value;
 }
 
-static gboolean
-book_backend_get_contact_list_uids_sync (EBookBackend *backend,
-                                         const gchar *query,
-                                         GQueue *out_uids,
-                                         GCancellable *cancellable,
-                                         GError **error)
-{
-       EBookBackendClass *class;
-       GQueue queue = G_QUEUE_INIT;
-       gboolean success;
-
-       class = E_BOOK_BACKEND_GET_CLASS (backend);
-       g_return_val_if_fail (class != NULL, FALSE);
-       g_return_val_if_fail (class->get_contact_list_sync != NULL, FALSE);
-
-       success = class->get_contact_list_sync (
-               backend, query, &queue, cancellable, error);
-
-       if (success) {
-               while (!g_queue_is_empty (&queue)) {
-                       EContact *contact;
-                       gchar *uid;
-
-                       contact = g_queue_pop_head (&queue);
-                       uid = e_contact_get (contact, E_CONTACT_UID);
-                       g_queue_push_tail (out_uids, uid);
-                       g_object_unref (contact);
-               }
-       }
-
-       g_warn_if_fail (g_queue_is_empty (&queue));
-
-       return success;
-}
-
 static void
 book_backend_notify_update (EBookBackend *backend,
                             const EContact *contact)
@@ -752,7 +712,6 @@ e_book_backend_class_init (EBookBackendClass *class)
 
        class->use_serial_dispatch_queue = TRUE;
        class->get_backend_property = book_backend_get_backend_property;
-       class->get_contact_list_uids_sync = book_backend_get_contact_list_uids_sync;
        class->notify_update = book_backend_notify_update;
        class->shutdown = book_backend_shutdown;
 
@@ -1133,40 +1092,8 @@ e_book_backend_open_sync (EBookBackend *backend,
 /* Helper for e_book_backend_open() */
 static void
 book_backend_open_thread (GSimpleAsyncResult *simple,
-                          GObject *source_object,
-                          GCancellable *cancellable)
-{
-       EBookBackend *backend;
-       EBookBackendClass *class;
-
-       backend = E_BOOK_BACKEND (source_object);
-
-       class = E_BOOK_BACKEND_GET_CLASS (backend);
-       g_return_if_fail (class != NULL);
-       g_return_if_fail (class->open_sync != NULL);
-
-       if (!e_book_backend_is_opened (backend)) {
-               GError *error = NULL;
-
-               e_backend_ensure_online_state_updated (E_BACKEND (backend), cancellable);
-
-               class->open_sync (backend, cancellable, &error);
-
-               if (error != NULL)
-                       g_simple_async_result_take_error (simple, error);
-       }
-
-       /* XXX Once we get rid of the old-style API we can dispatch
-        *     methods using g_simple_async_result_run_in_thread(),
-        *     which completes the GSimpleAsyncResult for us. */
-       g_simple_async_result_complete_in_idle (simple);
-}
-
-/* Helper for e_book_backend_open() */
-static void
-book_backend_open_thread_old_style (GSimpleAsyncResult *simple,
-                                    GObject *source_object,
-                                    GCancellable *cancellable)
+                         GObject *source_object,
+                         GCancellable *cancellable)
 {
        EBookBackend *backend;
        EBookBackendClass *class;
@@ -1234,24 +1161,14 @@ e_book_backend_open (EBookBackend *backend,
 
        g_simple_async_result_set_check_cancellable (simple, cancellable);
 
-       if (class->open_sync != NULL) {
+       if (class->open != NULL) {
                book_backend_push_operation (
                        backend, simple, cancellable, TRUE,
                        book_backend_open_thread);
                book_backend_dispatch_next_operation (backend);
 
-       } else if (class->open != NULL) {
-               book_backend_push_operation (
-                       backend, simple, cancellable, TRUE,
-                       book_backend_open_thread_old_style);
-               book_backend_dispatch_next_operation (backend);
-
        } else {
-               g_simple_async_result_set_error (
-                       simple, E_CLIENT_ERROR,
-                       E_CLIENT_ERROR_NOT_SUPPORTED,
-                       "%s", e_client_error_to_string (
-                       E_CLIENT_ERROR_NOT_SUPPORTED));
+               g_simple_async_result_take_error (simple, e_client_error_create 
(E_CLIENT_ERROR_NOT_SUPPORTED, NULL));
                g_simple_async_result_complete_in_idle (simple);
        }
 
@@ -1344,45 +1261,8 @@ e_book_backend_refresh_sync (EBookBackend *backend,
 /* Helper for e_book_backend_refresh() */
 static void
 book_backend_refresh_thread (GSimpleAsyncResult *simple,
-                             GObject *source_object,
-                             GCancellable *cancellable)
-{
-       EBookBackend *backend;
-       EBookBackendClass *class;
-
-       backend = E_BOOK_BACKEND (source_object);
-
-       class = E_BOOK_BACKEND_GET_CLASS (backend);
-       g_return_if_fail (class != NULL);
-       g_return_if_fail (class->refresh_sync != NULL);
-
-       if (!e_book_backend_is_opened (backend)) {
-               g_simple_async_result_set_error (
-                       simple, E_CLIENT_ERROR,
-                       E_CLIENT_ERROR_NOT_OPENED,
-                       "%s", e_client_error_to_string (
-                       E_CLIENT_ERROR_NOT_OPENED));
-
-       } else {
-               GError *error = NULL;
-
-               class->refresh_sync (backend, cancellable, &error);
-
-               if (error != NULL)
-                       g_simple_async_result_take_error (simple, error);
-       }
-
-       /* XXX Once we get rid of the old-style API we can dispatch
-        *     methods using g_simple_async_result_run_in_thread(),
-        *     which completes the GSimpleAsyncResult for us. */
-       g_simple_async_result_complete_in_idle (simple);
-}
-
-/* Helper for e_book_backend_refresh() */
-static void
-book_backend_refresh_thread_old_style (GSimpleAsyncResult *simple,
-                                       GObject *source_object,
-                                       GCancellable *cancellable)
+                            GObject *source_object,
+                            GCancellable *cancellable)
 {
        EBookBackend *backend;
        EBookBackendClass *class;
@@ -1398,11 +1278,7 @@ book_backend_refresh_thread_old_style (GSimpleAsyncResult *simple,
        g_return_if_fail (data_book != NULL);
 
        if (!e_book_backend_is_opened (backend)) {
-               g_simple_async_result_set_error (
-                       simple, E_CLIENT_ERROR,
-                       E_CLIENT_ERROR_NOT_OPENED,
-                       "%s", e_client_error_to_string (
-                       E_CLIENT_ERROR_NOT_OPENED));
+               g_simple_async_result_take_error (simple, e_client_error_create (E_CLIENT_ERROR_NOT_OPENED, 
NULL));
                g_simple_async_result_complete_in_idle (simple);
 
        } else {
@@ -1453,24 +1329,14 @@ e_book_backend_refresh (EBookBackend *backend,
 
        g_simple_async_result_set_check_cancellable (simple, cancellable);
 
-       if (class->refresh_sync != NULL) {
+       if (class->refresh != NULL) {
                book_backend_push_operation (
                        backend, simple, cancellable, FALSE,
                        book_backend_refresh_thread);
                book_backend_dispatch_next_operation (backend);
 
-       } else if (class->refresh != NULL) {
-               book_backend_push_operation (
-                       backend, simple, cancellable, FALSE,
-                       book_backend_refresh_thread_old_style);
-               book_backend_dispatch_next_operation (backend);
-
        } else {
-               g_simple_async_result_set_error (
-                       simple, E_CLIENT_ERROR,
-                       E_CLIENT_ERROR_NOT_SUPPORTED,
-                       "%s", e_client_error_to_string (
-                       E_CLIENT_ERROR_NOT_SUPPORTED));
+               g_simple_async_result_take_error (simple, e_client_error_create 
(E_CLIENT_ERROR_NOT_SUPPORTED, NULL));
                g_simple_async_result_complete_in_idle (simple);
        }
 
@@ -1568,52 +1434,8 @@ e_book_backend_create_contacts_sync (EBookBackend *backend,
 /* Helper for e_book_backend_create_contacts() */
 static void
 book_backend_create_contacts_thread (GSimpleAsyncResult *simple,
-                                     GObject *source_object,
-                                     GCancellable *cancellable)
-{
-       EBookBackend *backend;
-       EBookBackendClass *class;
-       AsyncContext *async_context;
-
-       backend = E_BOOK_BACKEND (source_object);
-
-       class = E_BOOK_BACKEND_GET_CLASS (backend);
-       g_return_if_fail (class != NULL);
-       g_return_if_fail (class->create_contacts_sync != NULL);
-
-       async_context = g_simple_async_result_get_op_res_gpointer (simple);
-
-       if (!e_book_backend_is_opened (backend)) {
-               g_simple_async_result_set_error (
-                       simple, E_CLIENT_ERROR,
-                       E_CLIENT_ERROR_NOT_OPENED,
-                       "%s", e_client_error_to_string (
-                       E_CLIENT_ERROR_NOT_OPENED));
-
-       } else {
-               GError *error = NULL;
-
-               class->create_contacts_sync (
-                       backend,
-                       (const gchar * const *) async_context->strv,
-                       async_context->object_queue,
-                       cancellable, &error);
-
-               if (error != NULL)
-                       g_simple_async_result_take_error (simple, error);
-       }
-
-       /* XXX Once we get rid of the old-style API we can dispatch
-        *     methods using g_simple_async_result_run_in_thread(),
-        *     which completes the GSimpleAsyncResult for us. */
-       g_simple_async_result_complete_in_idle (simple);
-}
-
-/* Helper for e_book_backend_create_contacts() */
-static void
-book_backend_create_contacts_thread_old_style (GSimpleAsyncResult *simple,
-                                               GObject *source_object,
-                                               GCancellable *cancellable)
+                                    GObject *source_object,
+                                    GCancellable *cancellable)
 {
        EBookBackend *backend;
        EBookBackendClass *class;
@@ -1632,33 +1454,16 @@ book_backend_create_contacts_thread_old_style (GSimpleAsyncResult *simple,
        async_context = g_simple_async_result_get_op_res_gpointer (simple);
 
        if (!e_book_backend_is_opened (backend)) {
-               g_simple_async_result_set_error (
-                       simple, E_CLIENT_ERROR,
-                       E_CLIENT_ERROR_NOT_OPENED,
-                       "%s", e_client_error_to_string (
-                       E_CLIENT_ERROR_NOT_OPENED));
+               g_simple_async_result_take_error (simple, e_client_error_create (E_CLIENT_ERROR_NOT_OPENED, 
NULL));
                g_simple_async_result_complete_in_idle (simple);
 
        } else {
-               GSList *list = NULL;
                guint32 opid;
-               guint ii;
-
-               /* This is so the finish function knows which method
-                * was invoked and can gather results appropriately. */
-               async_context->old_style = TRUE;
 
                opid = book_backend_stash_operation (backend, simple);
 
-               /* The AsyncContext retains ownership of the strings. */
-               for (ii = 0; async_context->strv[ii] != NULL; ii++)
-                       list = g_slist_prepend (list, async_context->strv[ii]);
-               list = g_slist_reverse (list);
-
                class->create_contacts (
-                       backend, data_book, opid, cancellable, list);
-
-               g_slist_free (list);
+                       backend, data_book, opid, cancellable, (const gchar * const *) async_context->strv);
        }
 
        g_object_unref (data_book);
@@ -1710,24 +1515,14 @@ e_book_backend_create_contacts (EBookBackend *backend,
        g_simple_async_result_set_op_res_gpointer (
                simple, async_context, (GDestroyNotify) async_context_free);
 
-       if (class->create_contacts_sync != NULL) {
+       if (class->create_contacts != NULL) {
                book_backend_push_operation (
                        backend, simple, cancellable, FALSE,
                        book_backend_create_contacts_thread);
                book_backend_dispatch_next_operation (backend);
 
-       } else if (class->create_contacts != NULL) {
-               book_backend_push_operation (
-                       backend, simple, cancellable, FALSE,
-                       book_backend_create_contacts_thread_old_style);
-               book_backend_dispatch_next_operation (backend);
-
        } else {
-               g_simple_async_result_set_error (
-                       simple, E_CLIENT_ERROR,
-                       E_CLIENT_ERROR_NOT_SUPPORTED,
-                       "%s", e_client_error_to_string (
-                       E_CLIENT_ERROR_NOT_SUPPORTED));
+               g_simple_async_result_take_error (simple, e_client_error_create 
(E_CLIENT_ERROR_NOT_SUPPORTED, NULL));
                g_simple_async_result_complete_in_idle (simple);
        }
 
@@ -1835,52 +1630,8 @@ e_book_backend_modify_contacts_sync (EBookBackend *backend,
 /* Helper for e_book_backend_modify_contacts() */
 static void
 book_backend_modify_contacts_thread (GSimpleAsyncResult *simple,
-                                     GObject *source_object,
-                                     GCancellable *cancellable)
-{
-       EBookBackend *backend;
-       EBookBackendClass *class;
-       AsyncContext *async_context;
-
-       backend = E_BOOK_BACKEND (source_object);
-
-       class = E_BOOK_BACKEND_GET_CLASS (backend);
-       g_return_if_fail (class != NULL);
-       g_return_if_fail (class->modify_contacts_sync != NULL);
-
-       async_context = g_simple_async_result_get_op_res_gpointer (simple);
-
-       if (!e_book_backend_is_opened (backend)) {
-               g_simple_async_result_set_error (
-                       simple, E_CLIENT_ERROR,
-                       E_CLIENT_ERROR_NOT_OPENED,
-                       "%s", e_client_error_to_string (
-                       E_CLIENT_ERROR_NOT_OPENED));
-
-       } else {
-               GError *error = NULL;
-
-               class->modify_contacts_sync (
-                       backend,
-                       (const gchar * const *) async_context->strv,
-                       async_context->object_queue,
-                       cancellable, &error);
-
-               if (error != NULL)
-                       g_simple_async_result_take_error (simple, error);
-       }
-
-       /* XXX Once we get rid of the old-style API we can dispatch
-        *     methods using g_simple_async_result_run_in_thread(),
-        *     which completes the GSimpleAsyncResult for us. */
-       g_simple_async_result_complete_in_idle (simple);
-}
-
-/* Helper for e_book_backend_modify_contacts() */
-static void
-book_backend_modify_contacts_thread_old_style (GSimpleAsyncResult *simple,
-                                               GObject *source_object,
-                                               GCancellable *cancellable)
+                                    GObject *source_object,
+                                    GCancellable *cancellable)
 {
        EBookBackend *backend;
        EBookBackendClass *class;
@@ -1899,33 +1650,16 @@ book_backend_modify_contacts_thread_old_style (GSimpleAsyncResult *simple,
        async_context = g_simple_async_result_get_op_res_gpointer (simple);
 
        if (!e_book_backend_is_opened (backend)) {
-               g_simple_async_result_set_error (
-                       simple, E_CLIENT_ERROR,
-                       E_CLIENT_ERROR_NOT_OPENED,
-                       "%s", e_client_error_to_string (
-                       E_CLIENT_ERROR_NOT_OPENED));
+               g_simple_async_result_take_error (simple, e_client_error_create (E_CLIENT_ERROR_NOT_OPENED, 
NULL));
                g_simple_async_result_complete_in_idle (simple);
 
        } else {
-               GSList *list = NULL;
                guint32 opid;
-               guint ii;
-
-               /* This is so the finish function knows which method
-                * was invoked and can gather results appropriately. */
-               async_context->old_style = TRUE;
 
                opid = book_backend_stash_operation (backend, simple);
 
-               /* The AsyncContext retains ownership of the strings. */
-               for (ii = 0; async_context->strv[ii] != NULL; ii++)
-                       list = g_slist_prepend (list, async_context->strv[ii]);
-               list = g_slist_reverse (list);
-
                class->modify_contacts (
-                       backend, data_book, opid, cancellable, list);
-
-               g_slist_free (list);
+                       backend, data_book, opid, cancellable, (const gchar * const *) async_context->strv);
        }
 
        g_object_unref (data_book);
@@ -1977,24 +1711,14 @@ e_book_backend_modify_contacts (EBookBackend *backend,
        g_simple_async_result_set_op_res_gpointer (
                simple, async_context, (GDestroyNotify) async_context_free);
 
-       if (class->modify_contacts_sync != NULL) {
+       if (class->modify_contacts != NULL) {
                book_backend_push_operation (
                        backend, simple, cancellable, FALSE,
                        book_backend_modify_contacts_thread);
                book_backend_dispatch_next_operation (backend);
 
-       } else if (class->modify_contacts != NULL) {
-               book_backend_push_operation (
-                       backend, simple, cancellable, FALSE,
-                       book_backend_modify_contacts_thread_old_style);
-               book_backend_dispatch_next_operation (backend);
-
        } else {
-               g_simple_async_result_set_error (
-                       simple, E_CLIENT_ERROR,
-                       E_CLIENT_ERROR_NOT_SUPPORTED,
-                       "%s", e_client_error_to_string (
-                       E_CLIENT_ERROR_NOT_SUPPORTED));
+               g_simple_async_result_take_error (simple, e_client_error_create 
(E_CLIENT_ERROR_NOT_SUPPORTED, NULL));
                g_simple_async_result_complete_in_idle (simple);
        }
 
@@ -2096,51 +1820,8 @@ e_book_backend_remove_contacts_sync (EBookBackend *backend,
 /* Helper for e_book_backend_remove_contacts() */
 static void
 book_backend_remove_contacts_thread (GSimpleAsyncResult *simple,
-                                     GObject *source_object,
-                                     GCancellable *cancellable)
-{
-       EBookBackend *backend;
-       EBookBackendClass *class;
-       AsyncContext *async_context;
-
-       backend = E_BOOK_BACKEND (source_object);
-
-       class = E_BOOK_BACKEND_GET_CLASS (backend);
-       g_return_if_fail (class != NULL);
-       g_return_if_fail (class->remove_contacts_sync != NULL);
-
-       async_context = g_simple_async_result_get_op_res_gpointer (simple);
-
-       if (!e_book_backend_is_opened (backend)) {
-               g_simple_async_result_set_error (
-                       simple, E_CLIENT_ERROR,
-                       E_CLIENT_ERROR_NOT_OPENED,
-                       "%s", e_client_error_to_string (
-                       E_CLIENT_ERROR_NOT_OPENED));
-
-       } else {
-               GError *error = NULL;
-
-               class->remove_contacts_sync (
-                       backend,
-                       (const gchar * const *) async_context->strv,
-                       cancellable, &error);
-
-               if (error != NULL)
-                       g_simple_async_result_take_error (simple, error);
-       }
-
-       /* XXX Once we get rid of the old-style API we can dispatch
-        *     methods using g_simple_async_result_run_in_thread(),
-        *     which completes the GSimpleAsyncResult for us. */
-       g_simple_async_result_complete_in_idle (simple);
-}
-
-/* Helper for e_book_backend_remove_contacts() */
-static void
-book_backend_remove_contacts_thread_old_style (GSimpleAsyncResult *simple,
-                                               GObject *source_object,
-                                               GCancellable *cancellable)
+                                    GObject *source_object,
+                                    GCancellable *cancellable)
 {
        EBookBackend *backend;
        EBookBackendClass *class;
@@ -2159,33 +1840,16 @@ book_backend_remove_contacts_thread_old_style (GSimpleAsyncResult *simple,
        async_context = g_simple_async_result_get_op_res_gpointer (simple);
 
        if (!e_book_backend_is_opened (backend)) {
-               g_simple_async_result_set_error (
-                       simple, E_CLIENT_ERROR,
-                       E_CLIENT_ERROR_NOT_OPENED,
-                       "%s", e_client_error_to_string (
-                       E_CLIENT_ERROR_NOT_OPENED));
+               g_simple_async_result_take_error (simple, e_client_error_create (E_CLIENT_ERROR_NOT_OPENED, 
NULL));
                g_simple_async_result_complete_in_idle (simple);
 
        } else {
-               GSList *list = NULL;
                guint32 opid;
-               guint ii;
-
-               /* This is so the finish function knows which method
-                * was invoked and can gather results appropriately. */
-               async_context->old_style = TRUE;
 
                opid = book_backend_stash_operation (backend, simple);
 
-               /* The AsyncContext retains ownership of the strings. */
-               for (ii = 0; async_context->strv[ii] != NULL; ii++)
-                       list = g_slist_prepend (list, async_context->strv[ii]);
-               list = g_slist_reverse (list);
-
                class->remove_contacts (
-                       backend, data_book, opid, cancellable, list);
-
-               g_slist_free (list);
+                       backend, data_book, opid, cancellable, (const gchar * const *) async_context->strv);
        }
 
        g_object_unref (data_book);
@@ -2237,24 +1901,14 @@ e_book_backend_remove_contacts (EBookBackend *backend,
        g_simple_async_result_set_op_res_gpointer (
                simple, async_context, (GDestroyNotify) async_context_free);
 
-       if (class->remove_contacts_sync != NULL) {
+       if (class->remove_contacts != NULL) {
                book_backend_push_operation (
                        backend, simple, cancellable, FALSE,
                        book_backend_remove_contacts_thread);
                book_backend_dispatch_next_operation (backend);
 
-       } else if (class->remove_contacts != NULL) {
-               book_backend_push_operation (
-                       backend, simple, cancellable, FALSE,
-                       book_backend_remove_contacts_thread_old_style);
-               book_backend_dispatch_next_operation (backend);
-
        } else {
-               g_simple_async_result_set_error (
-                       simple, E_CLIENT_ERROR,
-                       E_CLIENT_ERROR_NOT_SUPPORTED,
-                       "%s", e_client_error_to_string (
-                       E_CLIENT_ERROR_NOT_SUPPORTED));
+               g_simple_async_result_take_error (simple, e_client_error_create 
(E_CLIENT_ERROR_NOT_SUPPORTED, NULL));
                g_simple_async_result_complete_in_idle (simple);
        }
 
@@ -2357,51 +2011,8 @@ e_book_backend_get_contact_sync (EBookBackend *backend,
 /* Helper for e_book_backend_get_contact() */
 static void
 book_backend_get_contact_thread (GSimpleAsyncResult *simple,
-                                 GObject *source_object,
-                                 GCancellable *cancellable)
-{
-       EBookBackend *backend;
-       EBookBackendClass *class;
-       AsyncContext *async_context;
-
-       backend = E_BOOK_BACKEND (source_object);
-
-       class = E_BOOK_BACKEND_GET_CLASS (backend);
-       g_return_if_fail (class != NULL);
-       g_return_if_fail (class->get_contact_sync != NULL);
-
-       async_context = g_simple_async_result_get_op_res_gpointer (simple);
-
-       if (!e_book_backend_is_opened (backend)) {
-               g_simple_async_result_set_error (
-                       simple, E_CLIENT_ERROR,
-                       E_CLIENT_ERROR_NOT_OPENED,
-                       "%s", e_client_error_to_string (
-                       E_CLIENT_ERROR_NOT_OPENED));
-
-       } else {
-               GError *error = NULL;
-
-               async_context->contact = class->get_contact_sync (
-                       backend,
-                       async_context->uid,
-                       cancellable, &error);
-
-               if (error != NULL)
-                       g_simple_async_result_take_error (simple, error);
-       }
-
-       /* XXX Once we get rid of the old-style API we can dispatch
-        *     methods using g_simple_async_result_run_in_thread(),
-        *     which completes the GSimpleAsyncResult for us. */
-       g_simple_async_result_complete_in_idle (simple);
-}
-
-/* Helper for e_book_backend_get_contact() */
-static void
-book_backend_get_contact_thread_old_style (GSimpleAsyncResult *simple,
-                                           GObject *source_object,
-                                           GCancellable *cancellable)
+                                GObject *source_object,
+                                GCancellable *cancellable)
 {
        EBookBackend *backend;
        EBookBackendClass *class;
@@ -2420,20 +2031,12 @@ book_backend_get_contact_thread_old_style (GSimpleAsyncResult *simple,
        async_context = g_simple_async_result_get_op_res_gpointer (simple);
 
        if (!e_book_backend_is_opened (backend)) {
-               g_simple_async_result_set_error (
-                       simple, E_CLIENT_ERROR,
-                       E_CLIENT_ERROR_NOT_OPENED,
-                       "%s", e_client_error_to_string (
-                       E_CLIENT_ERROR_NOT_OPENED));
+               g_simple_async_result_take_error (simple, e_client_error_create (E_CLIENT_ERROR_NOT_OPENED, 
NULL));
                g_simple_async_result_complete_in_idle (simple);
 
        } else {
                guint32 opid;
 
-               /* This is so the finish function knows which method
-                * was invoked and can gather results appropriately. */
-               async_context->old_style = TRUE;
-
                opid = book_backend_stash_operation (backend, simple);
 
                class->get_contact (
@@ -2490,24 +2093,14 @@ e_book_backend_get_contact (EBookBackend *backend,
        g_simple_async_result_set_op_res_gpointer (
                simple, async_context, (GDestroyNotify) async_context_free);
 
-       if (class->get_contact_sync != NULL) {
+       if (class->get_contact != NULL) {
                book_backend_push_operation (
                        backend, simple, cancellable, FALSE,
                        book_backend_get_contact_thread);
                book_backend_dispatch_next_operation (backend);
 
-       } else if (class->get_contact != NULL) {
-               book_backend_push_operation (
-                       backend, simple, cancellable, FALSE,
-                       book_backend_get_contact_thread_old_style);
-               book_backend_dispatch_next_operation (backend);
-
        } else {
-               g_simple_async_result_set_error (
-                       simple, E_CLIENT_ERROR,
-                       E_CLIENT_ERROR_NOT_SUPPORTED,
-                       "%s", e_client_error_to_string (
-                       E_CLIENT_ERROR_NOT_SUPPORTED));
+               g_simple_async_result_take_error (simple, e_client_error_create 
(E_CLIENT_ERROR_NOT_SUPPORTED, NULL));
                g_simple_async_result_complete_in_idle (simple);
        }
 
@@ -2537,6 +2130,7 @@ e_book_backend_get_contact_finish (EBookBackend *backend,
                                    GError **error)
 {
        GSimpleAsyncResult *simple;
+       GQueue *queue;
        AsyncContext *async_context;
 
        g_return_val_if_fail (
@@ -2554,12 +2148,10 @@ e_book_backend_get_contact_finish (EBookBackend *backend,
 
        /* XXX e_data_book_respond_get_contact() stuffs the
         *     resulting EContact into the object queue. */
-       if (async_context->old_style) {
-               GQueue *queue = async_context->object_queue;
-               g_warn_if_fail (async_context->contact == NULL);
-               async_context->contact = g_queue_pop_head (queue);
-               g_warn_if_fail (g_queue_is_empty (queue));
-       }
+       queue = async_context->object_queue;
+       g_warn_if_fail (async_context->contact == NULL);
+       async_context->contact = g_queue_pop_head (queue);
+       g_warn_if_fail (g_queue_is_empty (queue));
 
        g_return_val_if_fail (E_IS_CONTACT (async_context->contact), NULL);
 
@@ -2621,52 +2213,8 @@ e_book_backend_get_contact_list_sync (EBookBackend *backend,
 /* Helper for e_book_backend_get_contact_list() */
 static void
 book_backend_get_contact_list_thread (GSimpleAsyncResult *simple,
-                                      GObject *source_object,
-                                      GCancellable *cancellable)
-{
-       EBookBackend *backend;
-       EBookBackendClass *class;
-       AsyncContext *async_context;
-
-       backend = E_BOOK_BACKEND (source_object);
-
-       class = E_BOOK_BACKEND_GET_CLASS (backend);
-       g_return_if_fail (class != NULL);
-       g_return_if_fail (class->get_contact_list_sync != NULL);
-
-       async_context = g_simple_async_result_get_op_res_gpointer (simple);
-
-       if (!e_book_backend_is_opened (backend)) {
-               g_simple_async_result_set_error (
-                       simple, E_CLIENT_ERROR,
-                       E_CLIENT_ERROR_NOT_OPENED,
-                       "%s", e_client_error_to_string (
-                       E_CLIENT_ERROR_NOT_OPENED));
-
-       } else {
-               GError *error = NULL;
-
-               class->get_contact_list_sync (
-                       backend,
-                       async_context->query,
-                       async_context->object_queue,
-                       cancellable, &error);
-
-               if (error != NULL)
-                       g_simple_async_result_take_error (simple, error);
-       }
-
-       /* XXX Once we get rid of the old-style API we can dispatch
-        *     methods using g_simple_async_result_run_in_thread(),
-        *     which completes the GSimpleAsyncResult for us. */
-       g_simple_async_result_complete_in_idle (simple);
-}
-
-/* Helper for e_book_backend_get_contact_list() */
-static void
-book_backend_get_contact_list_thread_old_style (GSimpleAsyncResult *simple,
-                                                GObject *source_object,
-                                                GCancellable *cancellable)
+                                     GObject *source_object,
+                                     GCancellable *cancellable)
 {
        EBookBackend *backend;
        EBookBackendClass *class;
@@ -2685,20 +2233,12 @@ book_backend_get_contact_list_thread_old_style (GSimpleAsyncResult *simple,
        async_context = g_simple_async_result_get_op_res_gpointer (simple);
 
        if (!e_book_backend_is_opened (backend)) {
-               g_simple_async_result_set_error (
-                       simple, E_CLIENT_ERROR,
-                       E_CLIENT_ERROR_NOT_OPENED,
-                       "%s", e_client_error_to_string (
-                       E_CLIENT_ERROR_NOT_OPENED));
+               g_simple_async_result_take_error (simple, e_client_error_create (E_CLIENT_ERROR_NOT_OPENED, 
NULL));
                g_simple_async_result_complete_in_idle (simple);
 
        } else {
                guint32 opid;
 
-               /* This is so the finish function knows which method
-                * was invoked and can gather results appropriately. */
-               async_context->old_style = TRUE;
-
                opid = book_backend_stash_operation (backend, simple);
 
                class->get_contact_list (
@@ -2756,24 +2296,14 @@ e_book_backend_get_contact_list (EBookBackend *backend,
        g_simple_async_result_set_op_res_gpointer (
                simple, async_context, (GDestroyNotify) async_context_free);
 
-       if (class->get_contact_list_sync != NULL) {
+       if (class->get_contact_list != NULL) {
                book_backend_push_operation (
                        backend, simple, cancellable, FALSE,
                        book_backend_get_contact_list_thread);
                book_backend_dispatch_next_operation (backend);
 
-       } else if (class->get_contact_list != NULL) {
-               book_backend_push_operation (
-                       backend, simple, cancellable, FALSE,
-                       book_backend_get_contact_list_thread_old_style);
-               book_backend_dispatch_next_operation (backend);
-
        } else {
-               g_simple_async_result_set_error (
-                       simple, E_CLIENT_ERROR,
-                       E_CLIENT_ERROR_NOT_SUPPORTED,
-                       "%s", e_client_error_to_string (
-                       E_CLIENT_ERROR_NOT_SUPPORTED));
+               g_simple_async_result_take_error (simple, e_client_error_create 
(E_CLIENT_ERROR_NOT_SUPPORTED, NULL));
                g_simple_async_result_complete_in_idle (simple);
        }
 
@@ -2883,52 +2413,8 @@ e_book_backend_get_contact_list_uids_sync (EBookBackend *backend,
 /* Helper for e_book_backend_get_contact_list_uids() */
 static void
 book_backend_get_contact_list_uids_thread (GSimpleAsyncResult *simple,
-                                           GObject *source_object,
-                                           GCancellable *cancellable)
-{
-       EBookBackend *backend;
-       EBookBackendClass *class;
-       AsyncContext *async_context;
-
-       backend = E_BOOK_BACKEND (source_object);
-
-       class = E_BOOK_BACKEND_GET_CLASS (backend);
-       g_return_if_fail (class != NULL);
-       g_return_if_fail (class->get_contact_list_uids_sync != NULL);
-
-       async_context = g_simple_async_result_get_op_res_gpointer (simple);
-
-       if (!e_book_backend_is_opened (backend)) {
-               g_simple_async_result_set_error (
-                       simple, E_CLIENT_ERROR,
-                       E_CLIENT_ERROR_NOT_OPENED,
-                       "%s", e_client_error_to_string (
-                       E_CLIENT_ERROR_NOT_OPENED));
-
-       } else {
-               GError *error = NULL;
-
-               class->get_contact_list_uids_sync (
-                       backend,
-                       async_context->query,
-                       async_context->string_queue,
-                       cancellable, &error);
-
-               if (error != NULL)
-                       g_simple_async_result_take_error (simple, error);
-       }
-
-       /* XXX Once we get rid of the old-style API we can dispatch
-        *     methods using g_simple_async_result_run_in_thread(),
-        *     which completes the GSimpleAsyncResult for us. */
-       g_simple_async_result_complete_in_idle (simple);
-}
-
-/* Helper for e_book_backend_get_contact_list_uids() */
-static void
-book_backend_get_contact_list_uids_thread_old_style (GSimpleAsyncResult *simple,
-                                                     GObject *source_object,
-                                                     GCancellable *cancellable)
+                                          GObject *source_object,
+                                          GCancellable *cancellable)
 {
        EBookBackend *backend;
        EBookBackendClass *class;
@@ -2947,20 +2433,12 @@ book_backend_get_contact_list_uids_thread_old_style (GSimpleAsyncResult *simple,
        async_context = g_simple_async_result_get_op_res_gpointer (simple);
 
        if (!e_book_backend_is_opened (backend)) {
-               g_simple_async_result_set_error (
-                       simple, E_CLIENT_ERROR,
-                       E_CLIENT_ERROR_NOT_OPENED,
-                       "%s", e_client_error_to_string (
-                       E_CLIENT_ERROR_NOT_OPENED));
+               g_simple_async_result_take_error (simple, e_client_error_create (E_CLIENT_ERROR_NOT_OPENED, 
NULL));
                g_simple_async_result_complete_in_idle (simple);
 
        } else {
                guint32 opid;
 
-               /* This is so the finish function knows which method
-                * was invoked and can gather results appropriately. */
-               async_context->old_style = TRUE;
-
                opid = book_backend_stash_operation (backend, simple);
 
                class->get_contact_list_uids (
@@ -3018,24 +2496,14 @@ e_book_backend_get_contact_list_uids (EBookBackend *backend,
        g_simple_async_result_set_op_res_gpointer (
                simple, async_context, (GDestroyNotify) async_context_free);
 
-       if (class->get_contact_list_uids_sync != NULL) {
+       if (class->get_contact_list_uids != NULL) {
                book_backend_push_operation (
                        backend, simple, cancellable, FALSE,
                        book_backend_get_contact_list_uids_thread);
                book_backend_dispatch_next_operation (backend);
 
-       } else if (class->get_contact_list_uids != NULL) {
-               book_backend_push_operation (
-                       backend, simple, cancellable, FALSE,
-                       book_backend_get_contact_list_uids_thread_old_style);
-               book_backend_dispatch_next_operation (backend);
-
        } else {
-               g_simple_async_result_set_error (
-                       simple, E_CLIENT_ERROR,
-                       E_CLIENT_ERROR_NOT_SUPPORTED,
-                       "%s", e_client_error_to_string (
-                       E_CLIENT_ERROR_NOT_SUPPORTED));
+               g_simple_async_result_take_error (simple, e_client_error_create 
(E_CLIENT_ERROR_NOT_SUPPORTED, NULL));
                g_simple_async_result_complete_in_idle (simple);
        }
 
@@ -3359,35 +2827,6 @@ e_book_backend_configure_direct (EBookBackend *backend,
                class->configure_direct (backend, config);
 }
 
-/**
- * e_book_backend_sync:
- * @backend: an #EBookBackend
- *
- * Write all pending data to disk.  This is only required under special
- * circumstances (for example before a live backup) and should not be used in
- * normal use.
- *
- * Since: 1.12
- */
-void
-e_book_backend_sync (EBookBackend *backend)
-{
-       EBookBackendClass *class;
-
-       g_return_if_fail (E_IS_BOOK_BACKEND (backend));
-
-       class = E_BOOK_BACKEND_GET_CLASS (backend);
-       g_return_if_fail (class != NULL);
-
-       if (class->sync) {
-               g_object_ref (backend);
-
-               class->sync (backend);
-
-               g_object_unref (backend);
-       }
-}
-
 /**
  * e_book_backend_set_locale:
  * @backend: an #EBookBackend
@@ -3701,7 +3140,7 @@ e_book_backend_create_cursor (EBookBackend *backend,
                        error,
                        E_CLIENT_ERROR,
                        E_CLIENT_ERROR_NOT_SUPPORTED,
-                       "Addressbook backend does not support cursors");
+                       _("Addressbook backend does not support cursors"));
        }
 
        return cursor;
diff --git a/src/addressbook/libedata-book/e-book-backend.h b/src/addressbook/libedata-book/e-book-backend.h
index d53cf5e81..0e6d07ca7 100644
--- a/src/addressbook/libedata-book/e-book-backend.h
+++ b/src/addressbook/libedata-book/e-book-backend.h
@@ -77,14 +77,14 @@ struct _EBookBackend {
  * @use_serial_dispatch_queue: Whether a serial dispatch queue should
  *                             be used for this backend or not. The default is %TRUE.
  * @get_backend_property: Fetch a property value by name from the backend
- * @open_sync: Open the backend
- * @refresh_sync: Refresh the backend
- * @create_contacts_sync: Add and store the passed vcards
- * @modify_contacts_sync: Modify the existing contacts using the passed vcards
- * @remove_contacts_sync: Remove the contacts specified by the passed UIDs
- * @get_contact_sync: Fetch a contact by UID
- * @get_contact_list_sync: Fetch a list of contacts based on a search expression
- * @get_contact_list_uids_sync: Fetch a list of contact UIDs based on a search expression (optional)
+ * @open: Open the backend
+ * @refresh: Refresh the backend
+ * @create_contacts: Add and store the passed vcards
+ * @modify_contacts: Modify the existing contacts using the passed vcards
+ * @remove_contacts: Remove the contacts specified by the passed UIDs
+ * @get_contact: Fetch a contact by UID
+ * @get_contact_list: Fetch a list of contacts based on a search expression
+ * @get_contact_list_uids: Fetch a list of contact UIDs based on a search expression
  * @start_view: Start up the specified view
  * @stop_view: Stop the specified view
  * @notify_update: Notify changes which might have occured for a given contact
@@ -93,21 +93,12 @@ struct _EBookBackend {
  * @configure_direct: For addressbook backends which support Direct Read Access, configure a
  *                    backend instantiated on the client side for Direct Read Access, using data
  *                    reported from the server via the @get_direct_book method.
- * @sync: Sync the backend's persistance
  * @set_locale: Store & remember the passed locale setting
  * @dup_locale: Return the currently set locale setting (must be a string duplicate, for thread safety).
  * @create_cursor: Create an #EDataBookCursor
  * @delete_cursor: Delete an #EDataBookCursor previously created by this backend
  * @closed: A signal notifying that the backend was closed
  * @shutdown: A signal notifying that the backend is being shut down
- * @open: Deprecated method
- * @refresh: Deprecated method
- * @create_contacts: Deprecated method
- * @remove_contacts: Deprecated method
- * @modify_contacts: Deprecated method
- * @get_contact: Deprecated method
- * @get_contact_list: Deprecated method
- * @get_contact_list_uids: Deprecated method
  *
  * Class structure for the #EBookBackend class.
  *
@@ -130,50 +121,6 @@ struct _EBookBackendClass {
        gchar *         (*get_backend_property) (EBookBackend *backend,
                                                 const gchar *prop_name);
 
-       gboolean        (*open_sync)            (EBookBackend *backend,
-                                                GCancellable *cancellable,
-                                                GError **error);
-       gboolean        (*refresh_sync)         (EBookBackend *backend,
-                                                GCancellable *cancellable,
-                                                GError **error);
-       gboolean        (*create_contacts_sync) (EBookBackend *backend,
-                                                const gchar * const *vcards,
-                                                GQueue *out_contacts,
-                                                GCancellable *cancellable,
-                                                GError **error);
-       gboolean        (*modify_contacts_sync) (EBookBackend *backend,
-                                                const gchar * const *vcards,
-                                                GQueue *out_contacts,
-                                                GCancellable *cancellable,
-                                                GError **error);
-       gboolean        (*remove_contacts_sync) (EBookBackend *backend,
-                                                const gchar * const *uids,
-                                                GCancellable *cancellable,
-                                                GError **error);
-       EContact *      (*get_contact_sync)     (EBookBackend *backend,
-                                                const gchar *uid,
-                                                GCancellable *cancellable,
-                                                GError **error);
-       gboolean        (*get_contact_list_sync)
-                                               (EBookBackend *backend,
-                                                const gchar *query,
-                                                GQueue *out_contacts,
-                                                GCancellable *cancellable,
-                                                GError **error);
-
-       /* This method is optional.  By default, it simply calls
-        * get_contact_list_sync() and extracts UID strings from
-        * the matched EContacts.  Backends may override this if
-        * they can implement it more efficiently. */
-       gboolean        (*get_contact_list_uids_sync)
-                                               (EBookBackend *backend,
-                                                const gchar *query,
-                                                GQueue *out_uids,
-                                                GCancellable *cancellable,
-                                                GError **error);
-
-       /* These methods are deprecated and will be removed once all
-        * known subclasses are converted to the new methods above. */
        void            (*open)                 (EBookBackend *backend,
                                                 EDataBook *book,
                                                 guint32 opid,
@@ -187,17 +134,17 @@ struct _EBookBackendClass {
                                                 EDataBook *book,
                                                 guint32 opid,
                                                 GCancellable *cancellable,
-                                                const GSList *vcards);
-       void            (*remove_contacts)      (EBookBackend *backend,
+                                                const gchar * const *vcards);
+       void            (*modify_contacts)      (EBookBackend *backend,
                                                 EDataBook *book,
                                                 guint32 opid,
                                                 GCancellable *cancellable,
-                                                const GSList *id_list);
-       void            (*modify_contacts)      (EBookBackend *backend,
+                                                const gchar * const *vcards);
+       void            (*remove_contacts)      (EBookBackend *backend,
                                                 EDataBook *book,
                                                 guint32 opid,
                                                 GCancellable *cancellable,
-                                                const GSList *vcards);
+                                                const gchar * const *id_list);
        void            (*get_contact)          (EBookBackend *backend,
                                                 EDataBook *book,
                                                 guint32 opid,
@@ -228,8 +175,6 @@ struct _EBookBackendClass {
        void            (*configure_direct)     (EBookBackend *backend,
                                                 const gchar *config);
 
-       void            (*sync)                 (EBookBackend *backend);
-
        gboolean        (*set_locale)           (EBookBackend *backend,
                                                 const gchar *locale,
                                                 GCancellable *cancellable,
@@ -249,6 +194,9 @@ struct _EBookBackendClass {
        void            (*closed)               (EBookBackend *backend,
                                                 const gchar *sender);
        void            (*shutdown)             (EBookBackend *backend);
+
+       /* Padding for future expansion */
+       gpointer reserved_padding[20];
 };
 
 GType          e_book_backend_get_type         (void) G_GNUC_CONST;
diff --git a/src/addressbook/libedata-book/e-book-meta-backend.c 
b/src/addressbook/libedata-book/e-book-meta-backend.c
index 66027d42a..f1e430d94 100644
--- a/src/addressbook/libedata-book/e-book-meta-backend.c
+++ b/src/addressbook/libedata-book/e-book-meta-backend.c
@@ -107,7 +107,7 @@ enum {
 
 static guint signals[LAST_SIGNAL];
 
-G_DEFINE_ABSTRACT_TYPE (EBookMetaBackend, e_book_meta_backend, E_TYPE_BOOK_BACKEND)
+G_DEFINE_ABSTRACT_TYPE (EBookMetaBackend, e_book_meta_backend, E_TYPE_BOOK_BACKEND_SYNC)
 
 G_DEFINE_BOXED_TYPE (EBookMetaBackendInfo, e_book_meta_backend_info, e_book_meta_backend_info_copy, 
e_book_meta_backend_info_free)
 
@@ -1196,7 +1196,7 @@ ebmb_get_backend_property (EBookBackend *book_backend,
 }
 
 static gboolean
-ebmb_open_sync (EBookBackend *book_backend,
+ebmb_open_sync (EBookBackendSync *book_backend,
                GCancellable *cancellable,
                GError **error)
 {
@@ -1205,7 +1205,7 @@ ebmb_open_sync (EBookBackend *book_backend,
 
        g_return_val_if_fail (E_IS_BOOK_META_BACKEND (book_backend), FALSE);
 
-       if (e_book_backend_is_opened (book_backend))
+       if (e_book_backend_is_opened (E_BOOK_BACKEND (book_backend)))
                return TRUE;
 
        meta_backend = E_BOOK_META_BACKEND (book_backend);
@@ -1248,7 +1248,7 @@ ebmb_open_sync (EBookBackend *book_backend,
 }
 
 static gboolean
-ebmb_refresh_sync (EBookBackend *book_backend,
+ebmb_refresh_sync (EBookBackendSync *book_backend,
                   GCancellable *cancellable,
                   GError **error)
 {
@@ -1358,9 +1358,9 @@ ebmb_create_contact_sync (EBookMetaBackend *meta_backend,
 }
 
 static gboolean
-ebmb_create_contacts_sync (EBookBackend *book_backend,
+ebmb_create_contacts_sync (EBookBackendSync *book_backend,
                           const gchar * const *vcards,
-                          GQueue *out_contacts,
+                          GSList **out_contacts,
                           GCancellable *cancellable,
                           GError **error)
 {
@@ -1375,7 +1375,9 @@ ebmb_create_contacts_sync (EBookBackend *book_backend,
        g_return_val_if_fail (vcards != NULL, FALSE);
        g_return_val_if_fail (out_contacts != NULL, FALSE);
 
-       if (!e_book_backend_get_writable (book_backend)) {
+       *out_contacts = NULL;
+
+       if (!e_book_backend_get_writable (E_BOOK_BACKEND (book_backend))) {
                g_propagate_error (error, e_data_book_create_error (E_DATA_BOOK_STATUS_PERMISSION_DENIED, 
NULL));
                return FALSE;
        }
@@ -1405,7 +1407,7 @@ ebmb_create_contacts_sync (EBookBackend *book_backend,
                if (success) {
                        ebmb_foreach_cursor (meta_backend, new_contact, e_data_book_cursor_contact_added);
 
-                       g_queue_push_tail (out_contacts, new_contact);
+                       *out_contacts = g_slist_prepend (*out_contacts, new_contact);
                }
 
                g_object_unref (contact);
@@ -1413,9 +1415,11 @@ ebmb_create_contacts_sync (EBookBackend *book_backend,
 
        g_object_unref (book_cache);
 
-       if (!success) {
-               g_queue_foreach (out_contacts, (GFunc) g_object_unref, NULL);
-               g_queue_clear (out_contacts);
+       if (success) {
+               *out_contacts = g_slist_reverse (*out_contacts);
+       } else {
+               g_slist_free_full (*out_contacts, g_object_unref);
+               *out_contacts = NULL;
        }
 
        return success;
@@ -1494,9 +1498,9 @@ ebmb_modify_contact_sync (EBookMetaBackend *meta_backend,
 }
 
 static gboolean
-ebmb_modify_contacts_sync (EBookBackend *book_backend,
+ebmb_modify_contacts_sync (EBookBackendSync *book_backend,
                           const gchar * const *vcards,
-                          GQueue *out_contacts,
+                          GSList **out_contacts,
                           GCancellable *cancellable,
                           GError **error)
 {
@@ -1511,7 +1515,9 @@ ebmb_modify_contacts_sync (EBookBackend *book_backend,
        g_return_val_if_fail (vcards != NULL, FALSE);
        g_return_val_if_fail (out_contacts != NULL, FALSE);
 
-       if (!e_book_backend_get_writable (book_backend)) {
+       *out_contacts = NULL;
+
+       if (!e_book_backend_get_writable (E_BOOK_BACKEND (book_backend))) {
                g_propagate_error (error, e_data_book_create_error (E_DATA_BOOK_STATUS_PERMISSION_DENIED, 
NULL));
                return FALSE;
        }
@@ -1542,7 +1548,7 @@ ebmb_modify_contacts_sync (EBookBackend *book_backend,
                        ebmb_foreach_cursor (meta_backend, contact, e_data_book_cursor_contact_removed);
                        ebmb_foreach_cursor (meta_backend, new_contact, e_data_book_cursor_contact_added);
 
-                       g_queue_push_tail (out_contacts, g_object_ref (new_contact));
+                       *out_contacts = g_slist_prepend (*out_contacts, g_object_ref (new_contact));
                }
 
                g_clear_object (&new_contact);
@@ -1551,9 +1557,11 @@ ebmb_modify_contacts_sync (EBookBackend *book_backend,
 
        g_object_unref (book_cache);
 
-       if (!success) {
-               g_queue_foreach (out_contacts, (GFunc) g_object_unref, NULL);
-               g_queue_clear (out_contacts);
+       if (success) {
+               *out_contacts = g_slist_reverse (*out_contacts);
+       } else {
+               g_slist_free_full (*out_contacts, g_object_unref);
+               *out_contacts = NULL;
        }
 
        return success;
@@ -1625,8 +1633,9 @@ ebmb_remove_contact_sync (EBookMetaBackend *meta_backend,
 }
 
 static gboolean
-ebmb_remove_contacts_sync (EBookBackend *book_backend,
+ebmb_remove_contacts_sync (EBookBackendSync *book_backend,
                           const gchar * const *uids,
+                          GSList **out_removed_uids,
                           GCancellable *cancellable,
                           GError **error)
 {
@@ -1639,8 +1648,11 @@ ebmb_remove_contacts_sync (EBookBackend *book_backend,
 
        g_return_val_if_fail (E_IS_BOOK_META_BACKEND (book_backend), FALSE);
        g_return_val_if_fail (uids != NULL, FALSE);
+       g_return_val_if_fail (out_removed_uids != NULL, FALSE);
+
+       *out_removed_uids = NULL;
 
-       if (!e_book_backend_get_writable (book_backend)) {
+       if (!e_book_backend_get_writable (E_BOOK_BACKEND (book_backend))) {
                g_propagate_error (error, e_data_book_create_error (E_DATA_BOOK_STATUS_PERMISSION_DENIED, 
NULL));
                return FALSE;
        }
@@ -1664,15 +1676,19 @@ ebmb_remove_contacts_sync (EBookBackend *book_backend,
                }
 
                success = ebmb_remove_contact_sync (meta_backend, book_cache, &offline_flag, 
conflict_resolution, uid, cancellable, error);
+               if (success)
+                       *out_removed_uids = g_slist_prepend (*out_removed_uids, g_strdup (uid));
        }
 
        g_object_unref (book_cache);
 
+       *out_removed_uids = g_slist_reverse (*out_removed_uids);
+
        return success;
 }
 
 static EContact *
-ebmb_get_contact_sync (EBookBackend *book_backend,
+ebmb_get_contact_sync (EBookBackendSync *book_backend,
                       const gchar *uid,
                       GCancellable *cancellable,
                       GError **error)
@@ -1719,58 +1735,33 @@ ebmb_get_contact_sync (EBookBackend *book_backend,
 }
 
 static gboolean
-ebmb_get_contact_list_sync (EBookBackend *book_backend,
+ebmb_get_contact_list_sync (EBookBackendSync *book_backend,
                            const gchar *query,
-                           GQueue *out_contacts,
+                           GSList **out_contacts,
                            GCancellable *cancellable,
                            GError **error)
 {
-       GSList *contacts = NULL, *link;
-       gboolean success;
-
        g_return_val_if_fail (E_IS_BOOK_META_BACKEND (book_backend), FALSE);
        g_return_val_if_fail (out_contacts != NULL, FALSE);
 
-       success = e_book_meta_backend_search_sync (E_BOOK_META_BACKEND (book_backend), query, FALSE, 
&contacts, cancellable, error);
-       if (success) {
-               for (link = contacts; link; link = g_slist_next (link)) {
-                       EContact *contact = link->data;
-
-                       g_queue_push_tail (out_contacts, g_object_ref (contact));
-               }
-
-               g_slist_free_full (contacts, g_object_unref);
-       }
+       *out_contacts = NULL;
 
-       return success;
+       return e_book_meta_backend_search_sync (E_BOOK_META_BACKEND (book_backend), query, FALSE, 
out_contacts, cancellable, error);
 }
 
 static gboolean
-ebmb_get_contact_list_uids_sync (EBookBackend *book_backend,
+ebmb_get_contact_list_uids_sync (EBookBackendSync *book_backend,
                                 const gchar *query,
-                                GQueue *out_uids,
+                                GSList **out_uids,
                                 GCancellable *cancellable,
                                 GError **error)
 {
-       GSList *uids = NULL, *link;
-       gboolean success;
-
        g_return_val_if_fail (E_IS_BOOK_META_BACKEND (book_backend), FALSE);
        g_return_val_if_fail (out_uids != NULL, FALSE);
 
-       success = e_book_meta_backend_search_uids_sync (E_BOOK_META_BACKEND (book_backend), query, &uids, 
cancellable, error);
-       if (success) {
-               for (link = uids; link; link = g_slist_next (link)) {
-                       gchar *uid = link->data;
-
-                       g_queue_push_tail (out_uids, uid);
-                       link->data = NULL;
-               }
-
-               g_slist_free_full (uids, g_free);
-       }
+       *out_uids = NULL;
 
-       return success;
+       return e_book_meta_backend_search_uids_sync (E_BOOK_META_BACKEND (book_backend), query, out_uids, 
cancellable, error);
 }
 
 static void
@@ -2438,6 +2429,7 @@ e_book_meta_backend_class_init (EBookMetaBackendClass *klass)
        GObjectClass *object_class;
        EBackendClass *backend_class;
        EBookBackendClass *book_backend_class;
+       EBookBackendSyncClass *book_backend_sync_class;
 
        g_type_class_add_private (klass, sizeof (EBookMetaBackendPrivate));
 
@@ -2449,16 +2441,18 @@ e_book_meta_backend_class_init (EBookMetaBackendClass *klass)
        klass->requires_reconnect = ebmb_requires_reconnect;
        klass->get_ssl_error_details = ebmb_get_ssl_error_details;
 
+       book_backend_sync_class = E_BOOK_BACKEND_SYNC_CLASS (klass);
+       book_backend_sync_class->open_sync = ebmb_open_sync;
+       book_backend_sync_class->refresh_sync = ebmb_refresh_sync;
+       book_backend_sync_class->create_contacts_sync = ebmb_create_contacts_sync;
+       book_backend_sync_class->modify_contacts_sync = ebmb_modify_contacts_sync;
+       book_backend_sync_class->remove_contacts_sync = ebmb_remove_contacts_sync;
+       book_backend_sync_class->get_contact_sync = ebmb_get_contact_sync;
+       book_backend_sync_class->get_contact_list_sync = ebmb_get_contact_list_sync;
+       book_backend_sync_class->get_contact_list_uids_sync = ebmb_get_contact_list_uids_sync;
+
        book_backend_class = E_BOOK_BACKEND_CLASS (klass);
        book_backend_class->get_backend_property = ebmb_get_backend_property;
-       book_backend_class->open_sync = ebmb_open_sync;
-       book_backend_class->refresh_sync = ebmb_refresh_sync;
-       book_backend_class->create_contacts_sync = ebmb_create_contacts_sync;
-       book_backend_class->modify_contacts_sync = ebmb_modify_contacts_sync;
-       book_backend_class->remove_contacts_sync = ebmb_remove_contacts_sync;
-       book_backend_class->get_contact_sync = ebmb_get_contact_sync;
-       book_backend_class->get_contact_list_sync = ebmb_get_contact_list_sync;
-       book_backend_class->get_contact_list_uids_sync = ebmb_get_contact_list_uids_sync;
        book_backend_class->start_view = ebmb_start_view;
        book_backend_class->stop_view = ebmb_stop_view;
        book_backend_class->get_direct_book = ebmb_get_direct_book;
diff --git a/src/addressbook/libedata-book/e-book-meta-backend.h 
b/src/addressbook/libedata-book/e-book-meta-backend.h
index 6389f9f7e..cc9d9a3bd 100644
--- a/src/addressbook/libedata-book/e-book-meta-backend.h
+++ b/src/addressbook/libedata-book/e-book-meta-backend.h
@@ -23,7 +23,7 @@
 #define E_BOOK_META_BACKEND_H
 
 #include <libebackend/libebackend.h>
-#include <libedata-book/e-book-backend.h>
+#include <libedata-book/e-book-backend-sync.h>
 #include <libedata-book/e-book-cache.h>
 #include <libebook-contacts/libebook-contacts.h>
 
@@ -82,7 +82,7 @@ typedef struct _EBookMetaBackendPrivate EBookMetaBackendPrivate;
  **/
 struct _EBookMetaBackend {
        /*< private >*/
-       EBookBackend parent;
+       EBookBackendSync parent;
        EBookMetaBackendPrivate *priv;
 };
 
@@ -95,7 +95,7 @@ struct _EBookMetaBackend {
  */
 struct _EBookMetaBackendClass {
        /*< private >*/
-       EBookBackendClass parent_class;
+       EBookBackendSyncClass parent_class;
 
        /* For Direct Read Access */
        const gchar *backend_module_filename;
diff --git a/src/addressbook/libedata-book/e-data-book.c b/src/addressbook/libedata-book/e-data-book.c
index ac381ff7a..81199a81b 100644
--- a/src/addressbook/libedata-book/e-data-book.c
+++ b/src/addressbook/libedata-book/e-data-book.c
@@ -1469,16 +1469,16 @@ e_data_book_respond_refresh (EDataBook *book,
  * @book: An #EDataBook
  * @opid: An operation ID
  * @error: (nullable) (transfer full): Operation error, if any, automatically freed if passed it
- * @vcard: (nullable): the found vCard, as string, or %NULL, if it could not be found
+ * @contact: (nullable): the found #EContact, or %NULL, if it could not be found
  *
  * Notifies listeners of the completion of the get_contact method call.
- * Only one of @error and @vcard can be set.
+ * Only one of @error and @contact can be set.
  */
 void
 e_data_book_respond_get_contact (EDataBook *book,
                                  guint32 opid,
                                  GError *error,
-                                 const gchar *vcard)
+                                 const EContact *contact)
 {
        EBookBackend *backend;
        GSimpleAsyncResult *simple;
@@ -1497,11 +1497,7 @@ e_data_book_respond_get_contact (EDataBook *book,
        g_prefix_error (&error, "%s", _("Cannot get contact: "));
 
        if (error == NULL) {
-               EContact *contact;
-
-               contact = e_contact_new_from_vcard (vcard);
-               g_queue_push_tail (queue, g_object_ref (contact));
-               g_object_unref (contact);
+               g_queue_push_tail (queue, g_object_ref ((EContact *) contact));
        } else {
                g_simple_async_result_take_error (simple, error);
        }
@@ -1517,9 +1513,9 @@ e_data_book_respond_get_contact (EDataBook *book,
  * @book: An #EDataBook
  * @opid: An operation ID
  * @error: Operation error, if any, automatically freed if passed it
- * @cards: (allow-none) (element-type utf8): A list of vCard strings, or %NULL on error
+ * @contacts: (allow-none) (element-type EContact): A list of #EContact, or %NULL on error
  *
- * Finishes a call to get list of vCards which satisfy certain criteria.
+ * Finishes a call to get list of #EContact, which satisfy certain criteria.
  *
  * Since: 3.2
  **/
@@ -1527,7 +1523,7 @@ void
 e_data_book_respond_get_contact_list (EDataBook *book,
                                       guint32 opid,
                                       GError *error,
-                                      const GSList *cards)
+                                      const GSList *contacts)
 {
        EBookBackend *backend;
        GSimpleAsyncResult *simple;
@@ -1546,16 +1542,12 @@ e_data_book_respond_get_contact_list (EDataBook *book,
        g_prefix_error (&error, "%s", _("Cannot get contact list: "));
 
        if (error == NULL) {
-               GSList *list, *link;
+               GSList *link;
 
-               list = (GSList *) cards;
+               for (link = (GSList *) contacts; link; link = g_slist_next (link)) {
+                       EContact *contact = link->data;
 
-               for (link = list; link != NULL; link = g_slist_next (link)) {
-                       EContact *contact;
-
-                       contact = e_contact_new_from_vcard (link->data);
                        g_queue_push_tail (queue, g_object_ref (contact));
-                       g_object_unref (contact);
                }
 
        } else {
@@ -1653,12 +1645,10 @@ e_data_book_respond_create_contacts (EDataBook *book,
        g_prefix_error (&error, "%s", _("Cannot add contact: "));
 
        if (error == NULL) {
-               GSList *list, *link;
-
-               list = (GSList *) contacts;
+               GSList *link;
 
-               for (link = list; link != NULL; link = g_slist_next (link)) {
-                       EContact *contact = E_CONTACT (link->data);
+               for (link = (GSList *) contacts; link; link = g_slist_next (link)) {
+                       EContact *contact = link->data;
                        g_queue_push_tail (queue, g_object_ref (contact));
                }
 
@@ -1706,12 +1696,11 @@ e_data_book_respond_modify_contacts (EDataBook *book,
        g_prefix_error (&error, "%s", _("Cannot modify contacts: "));
 
        if (error == NULL) {
-               GSList *list, *link;
+               GSList *link;
 
-               list = (GSList *) contacts;
+               for (link = (GSList *) contacts; link; link = g_slist_next (link)) {
+                       EContact *contact = contacts->data;
 
-               for (link = list; link != NULL; link = g_slist_next (link)) {
-                       EContact *contact = E_CONTACT (contacts->data);
                        g_queue_push_tail (queue, g_object_ref (contact));
                }
 
@@ -1759,11 +1748,9 @@ e_data_book_respond_remove_contacts (EDataBook *book,
        g_prefix_error (&error, "%s", _("Cannot remove contacts: "));
 
        if (error == NULL) {
-               GSList *list, *link;
-
-               list = (GSList *) ids;
+               GSList *link;
 
-               for (link = list; link != NULL; link = g_slist_next (link))
+               for (link = (GSList *) ids; link; link = g_slist_next (link))
                        g_queue_push_tail (queue, g_strdup (link->data));
 
        } else {
diff --git a/src/addressbook/libedata-book/e-data-book.h b/src/addressbook/libedata-book/e-data-book.h
index 48e8a0bad..f91cfa758 100644
--- a/src/addressbook/libedata-book/e-data-book.h
+++ b/src/addressbook/libedata-book/e-data-book.h
@@ -105,31 +105,31 @@ void              e_data_book_respond_create_contacts
                                                (EDataBook *book,
                                                 guint32 opid,
                                                 GError *error,
-                                                const GSList *contacts);
-void           e_data_book_respond_remove_contacts
+                                                const GSList *contacts); /* EContact * */
+void           e_data_book_respond_modify_contacts
                                                (EDataBook *book,
                                                 guint32 opid,
                                                 GError *error,
-                                                const GSList *ids);
-void           e_data_book_respond_modify_contacts
+                                                const GSList *contacts); /* EContact * */
+void           e_data_book_respond_remove_contacts
                                                (EDataBook *book,
                                                 guint32 opid,
                                                 GError *error,
-                                                const GSList *contacts);
+                                                const GSList *ids); /* gchar * */
 void           e_data_book_respond_get_contact (EDataBook *book,
                                                 guint32 opid,
                                                 GError *error,
-                                                const gchar *vcard);
+                                                const EContact *contact);
 void           e_data_book_respond_get_contact_list
                                                (EDataBook *book,
                                                 guint32 opid,
                                                 GError *error,
-                                                const GSList *cards);
+                                                const GSList *contacts); /* EContact * */
 void           e_data_book_respond_get_contact_list_uids
                                                (EDataBook *book,
                                                 guint32 opid,
                                                 GError *error,
-                                                const GSList *uids);
+                                                const GSList *uids); /* gchar * */
 
 void           e_data_book_report_error        (EDataBook *book,
                                                 const gchar *message);
diff --git a/src/addressbook/libedata-book/libedata-book.h b/src/addressbook/libedata-book/libedata-book.h
index b5db50376..183147d62 100644
--- a/src/addressbook/libedata-book/libedata-book.h
+++ b/src/addressbook/libedata-book/libedata-book.h
@@ -23,12 +23,13 @@
 #include <libebook-contacts/libebook-contacts.h>
 #include <libebackend/libebackend.h>
 
+#include <libedata-book/e-book-backend.h>
 #include <libedata-book/e-book-backend-cache.h>
 #include <libedata-book/e-book-backend-factory.h>
 #include <libedata-book/e-book-backend-sexp.h>
 #include <libedata-book/e-book-backend-sqlitedb.h>
 #include <libedata-book/e-book-backend-summary.h>
-#include <libedata-book/e-book-backend.h>
+#include <libedata-book/e-book-backend-sync.h>
 #include <libedata-book/e-book-cache.h>
 #include <libedata-book/e-book-meta-backend.h>
 #include <libedata-book/e-book-sqlite.h>
diff --git a/tests/libedata-book/test-book-meta-backend.c b/tests/libedata-book/test-book-meta-backend.c
index e938b0d0b..2ea280ada 100644
--- a/tests/libedata-book/test-book-meta-backend.c
+++ b/tests/libedata-book/test-book-meta-backend.c
@@ -633,7 +633,7 @@ e_book_meta_backend_test_change_online (EBookMetaBackend *meta_backend,
 static void
 e_book_meta_backend_test_call_refresh (EBookMetaBackend *meta_backend)
 {
-       EBookBackendClass *backend_class;
+       EBookBackendSyncClass *backend_sync_class;
        EFlag *flag;
        gulong handler_id;
        gboolean success;
@@ -641,9 +641,9 @@ e_book_meta_backend_test_call_refresh (EBookMetaBackend *meta_backend)
 
        g_assert_nonnull (meta_backend);
 
-       backend_class = E_BOOK_BACKEND_GET_CLASS (meta_backend);
-       g_return_if_fail (backend_class != NULL);
-       g_return_if_fail (backend_class->refresh_sync != NULL);
+       backend_sync_class = E_BOOK_BACKEND_SYNC_GET_CLASS (meta_backend);
+       g_return_if_fail (backend_sync_class != NULL);
+       g_return_if_fail (backend_sync_class->refresh_sync != NULL);
 
        if (!e_backend_get_online (E_BACKEND (meta_backend)))
                return;
@@ -653,7 +653,7 @@ e_book_meta_backend_test_call_refresh (EBookMetaBackend *meta_backend)
        handler_id = g_signal_connect_swapped (meta_backend, "refresh-completed",
                G_CALLBACK (e_flag_set), flag);
 
-       success = backend_class->refresh_sync (E_BOOK_BACKEND (meta_backend), NULL, &error);
+       success = backend_sync_class->refresh_sync (E_BOOK_BACKEND_SYNC (meta_backend), NULL, &error);
        g_assert_no_error (error);
        g_assert (success);
 
@@ -837,19 +837,19 @@ static void
 test_create_contacts (EBookMetaBackend *meta_backend)
 {
        EBookMetaBackendTest *test_backend;
-       EBookBackendClass *backend_class;
+       EBookBackendSyncClass *backend_sync_class;
        EBookCache *book_cache;
        GSList *offline_changes;
        gchar *vcards[2] = { NULL, NULL }, *tmp;
-       GQueue new_contacts = G_QUEUE_INIT;
+       GSList *new_contacts = NULL;
        gboolean success;
        GError *error = NULL;
 
        g_assert_nonnull (meta_backend);
 
-       backend_class = E_BOOK_BACKEND_GET_CLASS (meta_backend);
-       g_return_if_fail (backend_class != NULL);
-       g_return_if_fail (backend_class->create_contacts_sync != NULL);
+       backend_sync_class = E_BOOK_BACKEND_SYNC_GET_CLASS (meta_backend);
+       g_return_if_fail (backend_sync_class != NULL);
+       g_return_if_fail (backend_sync_class->create_contacts_sync != NULL);
 
        test_backend = E_BOOK_META_BACKEND_TEST (meta_backend);
        book_cache = e_book_meta_backend_ref_cache (meta_backend);
@@ -860,11 +860,11 @@ test_create_contacts (EBookMetaBackend *meta_backend)
        /* Try to add existing contact, it should fail */
        vcards[0] = tcu_new_vcard_from_test_case ("custom-1");
 
-       success = backend_class->create_contacts_sync (E_BOOK_BACKEND (meta_backend),
+       success = backend_sync_class->create_contacts_sync (E_BOOK_BACKEND_SYNC (meta_backend),
                (const gchar * const *) vcards, &new_contacts, NULL, &error);
        g_assert_error (error, E_DATA_BOOK_ERROR, E_DATA_BOOK_STATUS_CONTACTID_ALREADY_EXISTS);
        g_assert (!success);
-       g_assert_cmpint (g_queue_get_length (&new_contacts), ==, 0);
+       g_assert_cmpint (g_slist_length (new_contacts), ==, 0);
        g_clear_error (&error);
        g_free (vcards[0]);
 
@@ -873,19 +873,19 @@ test_create_contacts (EBookMetaBackend *meta_backend)
        /* Try to add new contact */
        vcards[0] = tcu_new_vcard_from_test_case ("custom-7");
 
-       success = backend_class->create_contacts_sync (E_BOOK_BACKEND (meta_backend),
+       success = backend_sync_class->create_contacts_sync (E_BOOK_BACKEND_SYNC (meta_backend),
                (const gchar * const *) vcards, &new_contacts, NULL, &error);
        g_assert_no_error (error);
        g_assert (success);
-       g_assert_cmpint (g_queue_get_length (&new_contacts), ==, 1);
-       g_assert_cmpstr (e_contact_get_const (g_queue_peek_head (&new_contacts), E_CONTACT_UID), ==, 
"custom-7");
+       g_assert_cmpint (g_slist_length (new_contacts), ==, 1);
+       g_assert_cmpstr (e_contact_get_const (new_contacts->data, E_CONTACT_UID), ==, "custom-7");
        g_assert_cmpint (test_backend->connect_count, ==, 1);
        g_assert_cmpint (test_backend->list_count, ==, 0);
        g_assert_cmpint (test_backend->load_count, ==, 1);
        g_assert_cmpint (test_backend->save_count, ==, 1);
 
-       g_queue_foreach (&new_contacts, (GFunc) g_object_unref, NULL);
-       g_queue_clear (&new_contacts);
+       g_slist_free_full (new_contacts, g_object_unref);
+       new_contacts = NULL;
        g_free (vcards[0]);
 
        ebmb_test_cache_and_server_equal (book_cache, test_backend->contacts, E_CACHE_INCLUDE_DELETED);
@@ -898,11 +898,11 @@ test_create_contacts (EBookMetaBackend *meta_backend)
        /* Try to add existing contact, it should fail */
        vcards[0] = tcu_new_vcard_from_test_case ("custom-7");
 
-       success = backend_class->create_contacts_sync (E_BOOK_BACKEND (meta_backend),
+       success = backend_sync_class->create_contacts_sync (E_BOOK_BACKEND_SYNC (meta_backend),
                (const gchar * const *) vcards, &new_contacts, NULL, &error);
        g_assert_error (error, E_DATA_BOOK_ERROR, E_DATA_BOOK_STATUS_CONTACTID_ALREADY_EXISTS);
        g_assert (!success);
-       g_assert_cmpint (g_queue_get_length (&new_contacts), ==, 0);
+       g_assert_cmpint (g_slist_length (new_contacts), ==, 0);
        g_clear_error (&error);
        g_free (vcards[0]);
        g_assert_cmpint (test_backend->load_count, ==, 0);
@@ -911,18 +911,18 @@ test_create_contacts (EBookMetaBackend *meta_backend)
        /* Try to add new contact */
        vcards[0] = tcu_new_vcard_from_test_case ("custom-8");
 
-       success = backend_class->create_contacts_sync (E_BOOK_BACKEND (meta_backend),
+       success = backend_sync_class->create_contacts_sync (E_BOOK_BACKEND_SYNC (meta_backend),
                (const gchar * const *) vcards, &new_contacts, NULL, &error);
        g_assert_no_error (error);
        g_assert (success);
-       g_assert_cmpint (g_queue_get_length (&new_contacts), ==, 1);
-       g_assert_cmpstr (e_contact_get_const (g_queue_peek_head (&new_contacts), E_CONTACT_UID), ==, 
"custom-8");
+       g_assert_cmpint (g_slist_length (new_contacts), ==, 1);
+       g_assert_cmpstr (e_contact_get_const (new_contacts->data, E_CONTACT_UID), ==, "custom-8");
        g_assert_cmpint (test_backend->connect_count, ==, 0);
        g_assert_cmpint (test_backend->load_count, ==, 0);
        g_assert_cmpint (test_backend->save_count, ==, 0);
 
-       g_queue_foreach (&new_contacts, (GFunc) g_object_unref, NULL);
-       g_queue_clear (&new_contacts);
+       g_slist_free_full (new_contacts, g_object_unref);
+       new_contacts = NULL;
        g_free (vcards[0]);
 
        ebmb_test_hash_contains (test_backend->contacts, TRUE, FALSE,
@@ -950,25 +950,25 @@ test_create_contacts (EBookMetaBackend *meta_backend)
        g_assert_nonnull (tmp);
        memcpy (tmp, "X-TEST:*007*", 12);
 
-       success = backend_class->create_contacts_sync (E_BOOK_BACKEND (meta_backend),
+       success = backend_sync_class->create_contacts_sync (E_BOOK_BACKEND_SYNC (meta_backend),
                (const gchar * const *) vcards, &new_contacts, NULL, &error);
        g_assert_no_error (error);
        g_assert (success);
-       g_assert_cmpint (g_queue_get_length (&new_contacts), ==, 1);
-       g_assert_cmpstr (e_contact_get_const (g_queue_peek_head (&new_contacts), E_CONTACT_UID), !=, 
"custom-9");
+       g_assert_cmpint (g_slist_length (new_contacts), ==, 1);
+       g_assert_cmpstr (e_contact_get_const (new_contacts->data, E_CONTACT_UID), !=, "custom-9");
        g_assert_cmpint (test_backend->connect_count, ==, 1);
        g_assert_cmpint (test_backend->list_count, ==, 1);
        g_assert_cmpint (test_backend->load_count, ==, 2);
        g_assert_cmpint (test_backend->save_count, ==, 2);
 
-       tmp = e_vcard_to_string (E_VCARD (g_queue_peek_head (&new_contacts)), EVC_FORMAT_VCARD_30);
+       tmp = e_vcard_to_string (E_VCARD (new_contacts->data), EVC_FORMAT_VCARD_30);
        g_assert_nonnull (tmp);
        g_assert_nonnull (strstr (tmp, "X-TEST:*007*\r\n"));
-       g_assert_nonnull (strstr (tmp, e_contact_get_const (g_queue_peek_head (&new_contacts), 
E_CONTACT_UID)));
+       g_assert_nonnull (strstr (tmp, e_contact_get_const (new_contacts->data, E_CONTACT_UID)));
        g_free (tmp);
 
-       g_queue_foreach (&new_contacts, (GFunc) g_object_unref, NULL);
-       g_queue_clear (&new_contacts);
+       g_slist_free_full (new_contacts, g_object_unref);
+       new_contacts = NULL;
        g_free (vcards[0]);
 
        ebmb_test_cache_and_server_equal (book_cache, test_backend->contacts, E_CACHE_INCLUDE_DELETED);
@@ -1008,21 +1008,21 @@ static void
 test_modify_contacts (EBookMetaBackend *meta_backend)
 {
        EBookMetaBackendTest *test_backend;
-       EBookBackendClass *backend_class;
+       EBookBackendSyncClass *backend_sync_class;
        EBookCache *book_cache;
        EContact *contact;
        GSList *offline_changes;
        gchar *vcards[2] = { NULL, NULL }, *tmp;
-       GQueue new_contacts = G_QUEUE_INIT;
+       GSList *new_contacts = NULL;
        gint old_rev, new_rev;
        gboolean success;
        GError *error = NULL;
 
        g_assert_nonnull (meta_backend);
 
-       backend_class = E_BOOK_BACKEND_GET_CLASS (meta_backend);
-       g_return_if_fail (backend_class != NULL);
-       g_return_if_fail (backend_class->modify_contacts_sync != NULL);
+       backend_sync_class = E_BOOK_BACKEND_SYNC_GET_CLASS (meta_backend);
+       g_return_if_fail (backend_sync_class != NULL);
+       g_return_if_fail (backend_sync_class->modify_contacts_sync != NULL);
 
        test_backend = E_BOOK_META_BACKEND_TEST (meta_backend);
        book_cache = e_book_meta_backend_ref_cache (meta_backend);
@@ -1035,22 +1035,22 @@ test_modify_contacts (EBookMetaBackend *meta_backend)
        g_assert_nonnull (tmp);
        memcpy (tmp + 4, "unknown", 7);
 
-       success = backend_class->modify_contacts_sync (E_BOOK_BACKEND (meta_backend),
+       success = backend_sync_class->modify_contacts_sync (E_BOOK_BACKEND_SYNC (meta_backend),
                (const gchar * const *) vcards, &new_contacts, NULL, &error);
        g_assert_error (error, E_DATA_BOOK_ERROR, E_DATA_BOOK_STATUS_CONTACT_NOT_FOUND);
        g_assert (!success);
-       g_assert_cmpint (g_queue_get_length (&new_contacts), ==, 0);
+       g_assert_cmpint (g_slist_length (new_contacts), ==, 0);
        g_clear_error (&error);
        g_free (vcards[0]);
 
        /* Modify existing contact */
        vcards[0] = ebmb_test_modify_case ("custom-1");
 
-       success = backend_class->modify_contacts_sync (E_BOOK_BACKEND (meta_backend),
+       success = backend_sync_class->modify_contacts_sync (E_BOOK_BACKEND_SYNC (meta_backend),
                (const gchar * const *) vcards, &new_contacts, NULL, &error);
        g_assert_no_error (error);
        g_assert (success);
-       g_assert_cmpint (g_queue_get_length (&new_contacts), ==, 1);
+       g_assert_cmpint (g_slist_length (new_contacts), ==, 1);
        g_assert_cmpint (test_backend->load_count, ==, 1);
        g_assert_cmpint (test_backend->save_count, ==, 1);
 
@@ -1065,7 +1065,7 @@ test_modify_contacts (EBookMetaBackend *meta_backend)
 
        g_object_unref (contact);
 
-       contact = g_queue_peek_head (&new_contacts);
+       contact = new_contacts->data;
        g_assert_nonnull (contact);
        g_assert_nonnull (e_contact_get_const (contact, E_CONTACT_REV));
        g_assert_nonnull (e_contact_get_const (contact, E_CONTACT_FULL_NAME));
@@ -1075,8 +1075,8 @@ test_modify_contacts (EBookMetaBackend *meta_backend)
        g_assert_cmpstr (e_contact_get_const (contact, E_CONTACT_FULL_NAME), ==, MODIFIED_FN_STR);
        g_assert_cmpstr (e_contact_get_const (contact, E_CONTACT_UID), ==, "custom-1");
 
-       g_queue_foreach (&new_contacts, (GFunc) g_object_unref, NULL);
-       g_queue_clear (&new_contacts);
+       g_slist_free_full (new_contacts, g_object_unref);
+       new_contacts = NULL;
        g_free (vcards[0]);
 
        /* Going offline */
@@ -1087,11 +1087,11 @@ test_modify_contacts (EBookMetaBackend *meta_backend)
        /* Modify custom-2 */
        vcards[0] = ebmb_test_modify_case ("custom-2");
 
-       success = backend_class->modify_contacts_sync (E_BOOK_BACKEND (meta_backend),
+       success = backend_sync_class->modify_contacts_sync (E_BOOK_BACKEND_SYNC (meta_backend),
                (const gchar * const *) vcards, &new_contacts, NULL, &error);
        g_assert_no_error (error);
        g_assert (success);
-       g_assert_cmpint (g_queue_get_length (&new_contacts), ==, 1);
+       g_assert_cmpint (g_slist_length (new_contacts), ==, 1);
        g_assert_cmpint (test_backend->load_count, ==, 0);
        g_assert_cmpint (test_backend->save_count, ==, 0);
 
@@ -1106,7 +1106,7 @@ test_modify_contacts (EBookMetaBackend *meta_backend)
 
        g_object_unref (contact);
 
-       contact = g_queue_peek_head (&new_contacts);
+       contact = new_contacts->data;
        g_assert_nonnull (contact);
        g_assert_nonnull (e_contact_get_const (contact, E_CONTACT_REV));
        g_assert_nonnull (e_contact_get_const (contact, E_CONTACT_FULL_NAME));
@@ -1116,8 +1116,8 @@ test_modify_contacts (EBookMetaBackend *meta_backend)
        g_assert_cmpstr (e_contact_get_const (contact, E_CONTACT_FULL_NAME), ==, MODIFIED_FN_STR);
        g_assert_cmpstr (e_contact_get_const (contact, E_CONTACT_UID), ==, "custom-2");
 
-       g_queue_foreach (&new_contacts, (GFunc) g_object_unref, NULL);
-       g_queue_clear (&new_contacts);
+       g_slist_free_full (new_contacts, g_object_unref);
+       new_contacts = NULL;
        g_free (vcards[0]);
 
        /* Going online */
@@ -1139,18 +1139,19 @@ static void
 test_remove_contacts (EBookMetaBackend *meta_backend)
 {
        EBookMetaBackendTest *test_backend;
-       EBookBackendClass *backend_class;
+       EBookBackendSyncClass *backend_sync_class;
        EBookCache *book_cache;
        const gchar *uids[2] = { NULL, NULL };
        GSList *offline_changes;
+       GSList *removed_uids = NULL;
        gboolean success;
        GError *error = NULL;
 
        g_assert_nonnull (meta_backend);
 
-       backend_class = E_BOOK_BACKEND_GET_CLASS (meta_backend);
-       g_return_if_fail (backend_class != NULL);
-       g_return_if_fail (backend_class->remove_contacts_sync != NULL);
+       backend_sync_class = E_BOOK_BACKEND_SYNC_GET_CLASS (meta_backend);
+       g_return_if_fail (backend_sync_class != NULL);
+       g_return_if_fail (backend_sync_class->remove_contacts_sync != NULL);
 
        test_backend = E_BOOK_META_BACKEND_TEST (meta_backend);
        book_cache = e_book_meta_backend_ref_cache (meta_backend);
@@ -1159,22 +1160,27 @@ test_remove_contacts (EBookMetaBackend *meta_backend)
        /* Remove non-existing contact */
        uids[0] = "unknown-contact";
 
-       success = backend_class->remove_contacts_sync (E_BOOK_BACKEND (meta_backend),
-               (const gchar * const *) uids, NULL, &error);
+       success = backend_sync_class->remove_contacts_sync (E_BOOK_BACKEND_SYNC (meta_backend),
+               (const gchar * const *) uids, &removed_uids, NULL, &error);
        g_assert_error (error, E_DATA_BOOK_ERROR, E_DATA_BOOK_STATUS_CONTACT_NOT_FOUND);
        g_assert (!success);
+       g_assert_null (removed_uids);
        g_clear_error (&error);
 
        /* Remove existing contact */
        uids[0] = "custom-1";
 
-       success = backend_class->remove_contacts_sync (E_BOOK_BACKEND (meta_backend),
-               (const gchar * const *) uids, NULL, &error);
+       success = backend_sync_class->remove_contacts_sync (E_BOOK_BACKEND_SYNC (meta_backend),
+               (const gchar * const *) uids, &removed_uids, NULL, &error);
        g_assert_no_error (error);
        g_assert (success);
        g_assert_cmpint (test_backend->load_count, ==, 0);
        g_assert_cmpint (test_backend->save_count, ==, 0);
        g_assert_cmpint (test_backend->remove_count, ==, 1);
+       g_assert_cmpint (g_slist_length (removed_uids), ==, 1);
+       g_assert_cmpstr (removed_uids->data, ==, uids[0]);
+       g_slist_free_full (removed_uids, g_free);
+       removed_uids = NULL;
 
        ebmb_test_hash_contains (test_backend->contacts, TRUE, FALSE,
                "custom-1", NULL,
@@ -1188,13 +1194,17 @@ test_remove_contacts (EBookMetaBackend *meta_backend)
        /* Remove existing contact */
        uids[0] = "custom-3";
 
-       success = backend_class->remove_contacts_sync (E_BOOK_BACKEND (meta_backend),
-               (const gchar * const *) uids, NULL, &error);
+       success = backend_sync_class->remove_contacts_sync (E_BOOK_BACKEND_SYNC (meta_backend),
+               (const gchar * const *) uids, &removed_uids, NULL, &error);
        g_assert_no_error (error);
        g_assert (success);
        g_assert_cmpint (test_backend->load_count, ==, 0);
        g_assert_cmpint (test_backend->save_count, ==, 0);
        g_assert_cmpint (test_backend->remove_count, ==, 0);
+       g_assert_cmpint (g_slist_length (removed_uids), ==, 1);
+       g_assert_cmpstr (removed_uids->data, ==, uids[0]);
+       g_slist_free_full (removed_uids, g_free);
+       removed_uids = NULL;
 
        ebmb_test_hash_contains (test_backend->contacts, FALSE, FALSE,
                "custom-3", NULL,
@@ -1230,16 +1240,16 @@ static void
 test_get_contact (EBookMetaBackend *meta_backend)
 {
        EBookMetaBackendTest *test_backend;
-       EBookBackendClass *backend_class;
+       EBookBackendSyncClass *backend_sync_class;
        EBookCache *book_cache;
        EContact *contact;
        GError *error = NULL;
 
        g_assert_nonnull (meta_backend);
 
-       backend_class = E_BOOK_BACKEND_GET_CLASS (meta_backend);
-       g_return_if_fail (backend_class != NULL);
-       g_return_if_fail (backend_class->get_contact_sync != NULL);
+       backend_sync_class = E_BOOK_BACKEND_SYNC_GET_CLASS (meta_backend);
+       g_return_if_fail (backend_sync_class != NULL);
+       g_return_if_fail (backend_sync_class->get_contact_sync != NULL);
 
        test_backend = E_BOOK_META_BACKEND_TEST (meta_backend);
        book_cache = e_book_meta_backend_ref_cache (meta_backend);
@@ -1251,13 +1261,13 @@ test_get_contact (EBookMetaBackend *meta_backend)
        g_assert_no_error (error);
 
        /* Non-existing */
-       contact = backend_class->get_contact_sync (E_BOOK_BACKEND (meta_backend), "unknown-contact", NULL, 
&error);
+       contact = backend_sync_class->get_contact_sync (E_BOOK_BACKEND_SYNC (meta_backend), 
"unknown-contact", NULL, &error);
        g_assert_error (error, E_DATA_BOOK_ERROR, E_DATA_BOOK_STATUS_CONTACT_NOT_FOUND);
        g_assert_null (contact);
        g_clear_error (&error);
 
        /* Existing */
-       contact = backend_class->get_contact_sync (E_BOOK_BACKEND (meta_backend), "custom-1", NULL, &error);
+       contact = backend_sync_class->get_contact_sync (E_BOOK_BACKEND_SYNC (meta_backend), "custom-1", NULL, 
&error);
        g_assert_no_error (error);
        g_assert_nonnull (contact);
        g_assert_cmpstr (e_contact_get_const (contact, E_CONTACT_UID), ==, "custom-1");
@@ -1270,7 +1280,7 @@ test_get_contact (EBookMetaBackend *meta_backend)
 
        e_book_meta_backend_test_reset_counters (test_backend);
 
-       contact = backend_class->get_contact_sync (E_BOOK_BACKEND (meta_backend), "custom-5", NULL, &error);
+       contact = backend_sync_class->get_contact_sync (E_BOOK_BACKEND_SYNC (meta_backend), "custom-5", NULL, 
&error);
        g_assert_error (error, E_DATA_BOOK_ERROR, E_DATA_BOOK_STATUS_CONTACT_NOT_FOUND);
        g_assert_null (contact);
        g_clear_error (&error);
@@ -1291,7 +1301,7 @@ test_get_contact (EBookMetaBackend *meta_backend)
        e_book_meta_backend_test_reset_counters (test_backend);
        g_assert_cmpint (test_backend->connect_count, ==, 0);
 
-       contact = backend_class->get_contact_sync (E_BOOK_BACKEND (meta_backend), "custom-5", NULL, &error);
+       contact = backend_sync_class->get_contact_sync (E_BOOK_BACKEND_SYNC (meta_backend), "custom-5", NULL, 
&error);
        g_assert_no_error (error);
        g_assert_nonnull (contact);
        g_assert_cmpint (test_backend->connect_count, ==, 0);
@@ -1308,63 +1318,61 @@ test_get_contact (EBookMetaBackend *meta_backend)
 static void
 test_get_contact_list (EBookMetaBackend *meta_backend)
 {
-       EBookBackendClass *backend_class;
-       GQueue contacts = G_QUEUE_INIT;
+       EBookBackendSyncClass *backend_sync_class;
+       GSList *contacts = NULL;
        EContact *contact;
        gboolean success;
        GError *error = NULL;
 
        g_assert_nonnull (meta_backend);
 
-       backend_class = E_BOOK_BACKEND_GET_CLASS (meta_backend);
-       g_return_if_fail (backend_class != NULL);
-       g_return_if_fail (backend_class->get_contact_list_sync != NULL);
+       backend_sync_class = E_BOOK_BACKEND_SYNC_GET_CLASS (meta_backend);
+       g_return_if_fail (backend_sync_class != NULL);
+       g_return_if_fail (backend_sync_class->get_contact_list_sync != NULL);
 
-       success = backend_class->get_contact_list_sync (E_BOOK_BACKEND (meta_backend),
+       success = backend_sync_class->get_contact_list_sync (E_BOOK_BACKEND_SYNC (meta_backend),
                "(is \"uid\" \"unknown-contact\")", &contacts, NULL, &error);
        g_assert_no_error (error);
        g_assert (success);
-       g_assert_cmpint (g_queue_get_length (&contacts), ==, 0);
+       g_assert_cmpint (g_slist_length (contacts), ==, 0);
 
-       success = backend_class->get_contact_list_sync (E_BOOK_BACKEND (meta_backend),
+       success = backend_sync_class->get_contact_list_sync (E_BOOK_BACKEND_SYNC (meta_backend),
                "(is \"uid\" \"custom-3\")", &contacts, NULL, &error);
        g_assert_no_error (error);
-       g_assert_cmpint (g_queue_get_length (&contacts), ==, 1);
-       contact = g_queue_peek_head (&contacts);
+       g_assert_cmpint (g_slist_length (contacts), ==, 1);
+       contact = contacts->data;
        g_assert_nonnull (contact);
        g_assert_cmpstr (e_contact_get_const (contact, E_CONTACT_UID), ==, "custom-3");
-       g_queue_foreach (&contacts, (GFunc) g_object_unref, NULL);
-       g_queue_clear (&contacts);
+       g_slist_free_full (contacts, g_object_unref);
 }
 
 static void
 test_get_contact_list_uids (EBookMetaBackend *meta_backend)
 {
-       EBookBackendClass *backend_class;
-       GQueue uids = G_QUEUE_INIT;
+       EBookBackendSyncClass *backend_sync_class;
+       GSList *uids = NULL;
        gboolean success;
        GError *error = NULL;
 
        g_assert_nonnull (meta_backend);
 
-       backend_class = E_BOOK_BACKEND_GET_CLASS (meta_backend);
-       g_return_if_fail (backend_class != NULL);
-       g_return_if_fail (backend_class->get_contact_list_uids_sync != NULL);
+       backend_sync_class = E_BOOK_BACKEND_SYNC_GET_CLASS (meta_backend);
+       g_return_if_fail (backend_sync_class != NULL);
+       g_return_if_fail (backend_sync_class->get_contact_list_uids_sync != NULL);
 
-       success = backend_class->get_contact_list_uids_sync (E_BOOK_BACKEND (meta_backend),
+       success = backend_sync_class->get_contact_list_uids_sync (E_BOOK_BACKEND_SYNC (meta_backend),
                "(is \"uid\" \"unknown-contact\")", &uids, NULL, &error);
        g_assert_no_error (error);
        g_assert (success);
-       g_assert_cmpint (g_queue_get_length (&uids), ==, 0);
+       g_assert_cmpint (g_slist_length (uids), ==, 0);
 
-       success = backend_class->get_contact_list_uids_sync (E_BOOK_BACKEND (meta_backend),
+       success = backend_sync_class->get_contact_list_uids_sync (E_BOOK_BACKEND_SYNC (meta_backend),
                "(is \"uid\" \"custom-3\")", &uids, NULL, &error);
        g_assert_no_error (error);
-       g_assert_cmpint (g_queue_get_length (&uids), ==, 1);
-       g_assert_nonnull (g_queue_peek_head (&uids));
-       g_assert_cmpstr (g_queue_peek_head (&uids), ==, "custom-3");
-       g_queue_foreach (&uids, (GFunc) g_free, NULL);
-       g_queue_clear (&uids);
+       g_assert_cmpint (g_slist_length (uids), ==, 1);
+       g_assert_nonnull (uids->data);
+       g_assert_cmpstr (uids->data, ==, "custom-3");
+       g_slist_free_full (uids, g_free);
 }
 
 static void
@@ -1537,10 +1545,12 @@ static void
 test_cursor (EBookMetaBackend *meta_backend)
 {
        EBookBackendClass *backend_class;
+       EBookBackendSyncClass *backend_sync_class;
        EDataBookCursor *cursor;
        EContactField sort_fields[] = { E_CONTACT_FULL_NAME };
        EBookCursorSortType sort_types[] = { E_BOOK_CURSOR_SORT_ASCENDING };
-       GQueue contacts = G_QUEUE_INIT;
+       GSList *contacts = NULL;
+       GSList *removed_uids = NULL;
        gchar *vcards[2] = { NULL, NULL };
        const gchar *uids[2] = { NULL, NULL };
        gint traversed;
@@ -1553,9 +1563,12 @@ test_cursor (EBookMetaBackend *meta_backend)
        g_return_if_fail (backend_class != NULL);
        g_return_if_fail (backend_class->create_cursor != NULL);
        g_return_if_fail (backend_class->delete_cursor != NULL);
-       g_return_if_fail (backend_class->create_contacts_sync != NULL);
-       g_return_if_fail (backend_class->modify_contacts_sync != NULL);
-       g_return_if_fail (backend_class->remove_contacts_sync != NULL);
+
+       backend_sync_class = E_BOOK_BACKEND_SYNC_GET_CLASS (meta_backend);
+       g_return_if_fail (backend_sync_class != NULL);
+       g_return_if_fail (backend_sync_class->create_contacts_sync != NULL);
+       g_return_if_fail (backend_sync_class->modify_contacts_sync != NULL);
+       g_return_if_fail (backend_sync_class->remove_contacts_sync != NULL);
 
        /* Create the cursor */
        cursor = backend_class->create_cursor (E_BOOK_BACKEND (meta_backend),
@@ -1573,13 +1586,13 @@ test_cursor (EBookMetaBackend *meta_backend)
 
        /* Create */
        vcards[0] = tcu_new_vcard_from_test_case ("custom-7");
-       success = backend_class->create_contacts_sync (E_BOOK_BACKEND (meta_backend),
+       success = backend_sync_class->create_contacts_sync (E_BOOK_BACKEND_SYNC (meta_backend),
                (const gchar * const *) vcards, &contacts, NULL, &error);
        g_assert_no_error (error);
        g_assert (success);
-       g_assert_cmpint (g_queue_get_length (&contacts), ==, 1);
-       g_queue_foreach (&contacts, (GFunc) g_object_unref, NULL);
-       g_queue_clear (&contacts);
+       g_assert_cmpint (g_slist_length (contacts), ==, 1);
+       g_slist_free_full (contacts, g_object_unref);
+       contacts = NULL;
        g_free (vcards[0]);
 
        g_assert_cmpint (e_data_book_cursor_get_total (cursor), ==, 6);
@@ -1587,13 +1600,13 @@ test_cursor (EBookMetaBackend *meta_backend)
 
        /* Modify */
        vcards[0] = ebmb_test_modify_case ("custom-2");
-       success = backend_class->modify_contacts_sync (E_BOOK_BACKEND (meta_backend),
+       success = backend_sync_class->modify_contacts_sync (E_BOOK_BACKEND_SYNC (meta_backend),
                (const gchar * const *) vcards, &contacts, NULL, &error);
        g_assert_no_error (error);
        g_assert (success);
-       g_assert_cmpint (g_queue_get_length (&contacts), ==, 1);
-       g_queue_foreach (&contacts, (GFunc) g_object_unref, NULL);
-       g_queue_clear (&contacts);
+       g_assert_cmpint (g_slist_length (contacts), ==, 1);
+       g_slist_free_full (contacts, g_object_unref);
+       contacts = NULL;
        g_free (vcards[0]);
 
        g_assert_cmpint (e_data_book_cursor_get_total (cursor), ==, 6);
@@ -1601,10 +1614,14 @@ test_cursor (EBookMetaBackend *meta_backend)
 
        /* Remove */
        uids[0] = "custom-3";
-       success = backend_class->remove_contacts_sync (E_BOOK_BACKEND (meta_backend),
-               (const gchar * const *) uids, NULL, &error);
+       success = backend_sync_class->remove_contacts_sync (E_BOOK_BACKEND_SYNC (meta_backend),
+               (const gchar * const *) uids, &removed_uids, NULL, &error);
        g_assert_no_error (error);
        g_assert (success);
+       g_assert_cmpint (g_slist_length (removed_uids), ==, 1);
+       g_assert_cmpstr (removed_uids->data, ==, uids[0]);
+       g_slist_free_full (removed_uids, g_free);
+       removed_uids = NULL;
 
        g_assert_cmpint (e_data_book_cursor_get_total (cursor), ==, 5);
        g_assert_cmpint (e_data_book_cursor_get_position (cursor), ==, 2);



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]