[evolution-data-server/openismus-work-master: 5/11] EBookClient, EDataBook: Added direct access APIs



commit a93dbd6e620d83e620feb5e5d8af82f780bf9c83
Author: Tristan Van Berkom <tristanvb openismus com>
Date:   Fri Nov 2 20:37:34 2012 +0900

    EBookClient, EDataBook: Added direct access APIs
    
    With direct access enabled, an EDataBook is created locally by
    the client and used for read access directly instead of going over
    the D-Bus.
    
    EDataBook has been extended with APIs for reading the addressbook
    directly (with sync and async variants that dont go over any IPC
    but still need async/sync variants to wait for thread operations
    to complete).
    
    EDataBookDirect has been added to advertize some information over
    the bus needed for setting up a direct connection to the addressbook,
    backends supporting direct access are expected to implement the new
    EBookBackend method ->get_direct_book() in order to advertize that
    it supports direct access, backends can also optionally implement
    ->configure_direct().
    
    This commit also splits up libebook into 2 libraries, lower level data types
    such as EContact are split out into a libebook-contacts shared library
    (This is important since now libebook depends on libedata-book in order
    to instanciate an EDataBook directly)

 addressbook/Makefile.am                            |    2 +-
 addressbook/backends/file/Makefile.am              |    1 +
 addressbook/backends/google/Makefile.am            |    1 +
 addressbook/backends/google/e-book-google-utils.c  |    2 +-
 addressbook/backends/google/tests/phone-numbers.c  |    2 +-
 addressbook/backends/ldap/Makefile.am              |    1 +
 addressbook/backends/webdav/Makefile.am            |    1 +
 addressbook/libebook-contacts/Makefile.am          |  141 ++
 .../e-address-western.c                            |    0
 .../e-address-western.h                            |    4 +-
 .../e-book-contacts-enumtypes.c.template           |   38 +
 .../e-book-contacts-enumtypes.h.template           |   27 +
 .../libebook-contacts/e-book-contacts-marshal.list |    6 +
 .../libebook-contacts/e-book-contacts-types.h      |  112 ++
 .../{libebook => libebook-contacts}/e-book-query.c |    0
 .../{libebook => libebook-contacts}/e-book-query.h |    6 +-
 .../{libebook => libebook-contacts}/e-contact.c    |    1 -
 .../{libebook => libebook-contacts}/e-contact.h    |    6 +-
 .../e-name-western-tables.h                        |    0
 .../e-name-western-tables.h.in                     |    0
 .../e-name-western.c                               |    0
 .../e-name-western.h                               |    4 +-
 .../e-source-backend-summary-setup.c               |    6 +-
 .../e-source-backend-summary-setup.h               |    8 +-
 .../{libebook => libebook-contacts}/e-vcard.c      |    0
 .../{libebook => libebook-contacts}/e-vcard.h      |    4 +-
 .../gen-western-table.py                           |    0
 addressbook/libebook-contacts/libebook-contacts.h  |   38 +
 .../libebook-contacts/libebook-contacts.pc.in      |   16 +
 addressbook/libebook/Makefile.am                   |   36 +-
 addressbook/libebook/e-book-client-view.h          |   18 -
 addressbook/libebook/e-book-client.c               |  279 ++++-
 addressbook/libebook/e-book-client.h               |    5 +-
 addressbook/libebook/e-book-types.h                |   75 +--
 addressbook/libebook/e-book.c                      |    2 -
 addressbook/libebook/e-book.h                      |    3 +-
 addressbook/libebook/e-destination.h               |    2 +-
 addressbook/libebook/libebook.h                    |    7 +-
 addressbook/libebook/libebook.pc.in                |    2 +-
 addressbook/libedata-book/Makefile.am              |    4 +-
 addressbook/libedata-book/e-book-backend-cache.h   |    2 +-
 .../libedata-book/e-book-backend-db-cache.h        |    2 +-
 addressbook/libedata-book/e-book-backend-sexp.h    |    2 +-
 .../libedata-book/e-book-backend-sqlitedb-test.c   |    2 +-
 .../libedata-book/e-book-backend-sqlitedb.c        |    4 +
 .../libedata-book/e-book-backend-sqlitedb.h        |    2 +-
 addressbook/libedata-book/e-book-backend-summary.h |    2 +-
 addressbook/libedata-book/e-book-backend.c         |   48 +
 addressbook/libedata-book/e-book-backend.h         |   12 +-
 addressbook/libedata-book/e-data-book-direct.c     |  132 ++
 addressbook/libedata-book/e-data-book-direct.h     |   64 +
 addressbook/libedata-book/e-data-book-view.h       |    2 +-
 addressbook/libedata-book/e-data-book.c            |  902 ++++++++++++-
 addressbook/libedata-book/e-data-book.h            |   27 +
 addressbook/libedata-book/libedata-book.h          |    3 +-
 addressbook/libegdbus/Makefile.am                  |    7 +-
 addressbook/libegdbus/e-gdbus-book-direct.c        | 1359 ++++++++++++++++++++
 addressbook/libegdbus/e-gdbus-book-direct.h        |  173 +++
 calendar/backends/contacts/Makefile.am             |    1 +
 configure.ac                                       |    9 +
 docs/reference/addressbook/libebook/Makefile.am    |    1 +
 .../addressbook/libedata-book/Makefile.am          |    1 +
 tests/libebook/Makefile.am                         |    3 +-
 tests/libebook/client/Makefile.am                  |    1 +
 tests/libebook/vcard/Makefile.am                   |    1 +
 vala/EBook-1.2.metadata                            |   23 -
 vala/EBookContacts-1.2.metadata                    |   23 +
 vala/Makefile.am                                   |   39 +-
 vala/libebook-1.2.deps                             |    2 +-
 ...stom.vala => libebook-contacts-1.2-custom.vala} |    0
 vala/libebook-contacts-1.2.deps                    |    3 +
 71 files changed, 3437 insertions(+), 275 deletions(-)
---
diff --git a/addressbook/Makefile.am b/addressbook/Makefile.am
index f61358d..62414f6 100644
--- a/addressbook/Makefile.am
+++ b/addressbook/Makefile.am
@@ -1,3 +1,3 @@
-SUBDIRS = libegdbus libebook libedata-book backends
+SUBDIRS = libegdbus libebook-contacts libedata-book libebook backends
 
 -include $(top_srcdir)/git.mk
diff --git a/addressbook/backends/file/Makefile.am b/addressbook/backends/file/Makefile.am
index 92ca13d..de53c5d 100644
--- a/addressbook/backends/file/Makefile.am
+++ b/addressbook/backends/file/Makefile.am
@@ -21,6 +21,7 @@ libebookbackendfile_la_SOURCES =			\
 	e-book-backend-file-factory.c
 
 libebookbackendfile_la_LIBADD =						\
+	$(top_builddir)/addressbook/libebook-contacts/libebook-contacts-1.2.la		\
 	$(top_builddir)/addressbook/libebook/libebook-1.2.la		\
 	$(top_builddir)/addressbook/libedata-book/libedata-book-1.2.la	\
 	$(top_builddir)/libedataserver/libedataserver-1.2.la		\
diff --git a/addressbook/backends/google/Makefile.am b/addressbook/backends/google/Makefile.am
index 5da07b1..6238c4e 100644
--- a/addressbook/backends/google/Makefile.am
+++ b/addressbook/backends/google/Makefile.am
@@ -34,6 +34,7 @@ libebookbackendgoogle_la_SOURCES = \
 	$(GOA_SOURCES)
 
 libebookbackendgoogle_la_LIBADD = \
+	$(top_builddir)/addressbook/libebook-contacts/libebook-contacts-1.2.la		\
 	$(top_builddir)/addressbook/libedata-book/libedata-book-1.2.la \
 	$(top_builddir)/addressbook/libebook/libebook-1.2.la \
 	$(top_builddir)/libedataserver/libedataserver-1.2.la \
diff --git a/addressbook/backends/google/e-book-google-utils.c b/addressbook/backends/google/e-book-google-utils.c
index db4d292..604bc6b 100644
--- a/addressbook/backends/google/e-book-google-utils.c
+++ b/addressbook/backends/google/e-book-google-utils.c
@@ -26,7 +26,7 @@
 #include <errno.h>
 
 #include <glib/gi18n-lib.h>
-#include <libebook/libebook.h>
+#include <libebook-contacts/libebook-contacts.h>
 #include <gdata/gdata.h>
 
 #include "e-book-google-utils.h"
diff --git a/addressbook/backends/google/tests/phone-numbers.c b/addressbook/backends/google/tests/phone-numbers.c
index b67fb66..a37f212 100644
--- a/addressbook/backends/google/tests/phone-numbers.c
+++ b/addressbook/backends/google/tests/phone-numbers.c
@@ -19,7 +19,7 @@
  * Author: Philip Withnall <philip tecnocode co uk>
  */
 
-#include <libebook/libebook.h>
+#include <libebook-contacts/libebook-contacts.h>
 #include <gdata/gdata.h>
 
 #include "e-book-google-utils.h"
diff --git a/addressbook/backends/ldap/Makefile.am b/addressbook/backends/ldap/Makefile.am
index 5effe35..c0d9c7a 100644
--- a/addressbook/backends/ldap/Makefile.am
+++ b/addressbook/backends/ldap/Makefile.am
@@ -21,6 +21,7 @@ libebookbackendldap_la_SOURCES =			\
 	e-source-ldap.h
 
 libebookbackendldap_la_LIBADD =						\
+	$(top_builddir)/addressbook/libebook-contacts/libebook-contacts-1.2.la		\
 	$(top_builddir)/addressbook/libebook/libebook-1.2.la		\
 	$(top_builddir)/addressbook/libedata-book/libedata-book-1.2.la	\
 	$(top_builddir)/libedataserver/libedataserver-1.2.la		\
diff --git a/addressbook/backends/webdav/Makefile.am b/addressbook/backends/webdav/Makefile.am
index 4c6d554..58ded89 100644
--- a/addressbook/backends/webdav/Makefile.am
+++ b/addressbook/backends/webdav/Makefile.am
@@ -19,6 +19,7 @@ libebookbackendwebdav_la_SOURCES = \
 	e-book-backend-webdav.c
 
 libebookbackendwebdav_la_LIBADD = \
+	$(top_builddir)/addressbook/libebook-contacts/libebook-contacts-1.2.la		\
 	$(top_builddir)/addressbook/libebook/libebook-1.2.la \
 	$(top_builddir)/addressbook/libedata-book/libedata-book-1.2.la \
 	$(top_builddir)/libedataserver/libedataserver-1.2.la \
diff --git a/addressbook/libebook-contacts/Makefile.am b/addressbook/libebook-contacts/Makefile.am
new file mode 100644
index 0000000..01c3d33
--- /dev/null
+++ b/addressbook/libebook-contacts/Makefile.am
@@ -0,0 +1,141 @@
+CLEANFILES=
+BUILT_SOURCES=
+
+ENUM_TYPES = e-book-contacts-types.h
+
+e-book-contacts-enumtypes.h: e-book-contacts-enumtypes.h.template $(ENUM_TYPES)
+	$(AM_V_GEN) (cd $(srcdir) && $(GLIB_MKENUMS) --template e-book-contacts-enumtypes.h.template $(ENUM_TYPES)) > $@
+
+e-book-contacts-enumtypes.c: e-book-contacts-enumtypes.c.template $(ENUM_TYPES)
+	$(AM_V_GEN) (cd $(srcdir) && $(GLIB_MKENUMS) --template e-book-contacts-enumtypes.c.template $(ENUM_TYPES)) > $@
+
+ENUM_GENERATED = e-book-contacts-enumtypes.h e-book-contacts-enumtypes.c
+
+# The marshallers
+MARSHAL_GENERATED = e-book-contacts-marshal.c e-book-contacts-marshal.h
+ EVO_MARSHAL_RULE@
+
+# The library
+lib_LTLIBRARIES = libebook-contacts-1.2.la
+
+libebook_contacts_1_2_la_CPPFLAGS = \
+	$(AM_CPPFLAGS)					\
+	-DLIBEBOOK_CONTACTS_COMPILATION			\
+	-DLOCALEDIR=\""$(localedir)"\"			\
+	-DG_LOG_DOMAIN=\"libebook-contacts\"		\
+	-I$(top_srcdir)					\
+	-I$(top_srcdir)/addressbook			\
+	-I$(top_builddir)				\
+	-I$(top_builddir)/addressbook			\
+	$(EVOLUTION_ADDRESSBOOK_CFLAGS)			\
+	$(CAMEL_CFLAGS)					\
+	$(CODE_COVERAGE_CFLAGS)				\
+	$(NULL)
+
+libebook_contacts_1_2_la_SOURCES =				\
+	$(ENUM_GENERATED)				\
+	$(MARSHAL_GENERATED)				\
+	e-address-western.c				\
+	e-name-western.c				\
+	e-name-western-tables.h                         \
+	e-book-query.c					\
+	e-contact.c					\
+	e-vcard.c					\
+	e-source-backend-summary-setup.c
+
+libebook_contacts_1_2_la_LIBADD =					\
+	$(top_builddir)/camel/libcamel-1.2.la			\
+	$(top_builddir)/libedataserver/libedataserver-1.2.la	\
+	$(EVOLUTION_ADDRESSBOOK_LIBS)				\
+	$(CAMEL_LIBS)
+
+libebook_contacts_1_2_la_LDFLAGS = 							\
+	-version-info $(LIBEBOOK_CONTACTS_CURRENT):$(LIBEBOOK_CONTACTS_REVISION):$(LIBEBOOK_CONTACTS_AGE) $(NO_UNDEFINED) \
+	$(CODE_COVERAGE_LDFLAGS) \
+	$(NULL)
+
+libebookcontactsincludedir = $(privincludedir)/libebook-contacts
+
+libebookcontactsinclude_HEADERS =			\
+	libebook-contacts.h				\
+	e-book-contacts-enumtypes.h			\
+	e-book-contacts-types.h				\
+	e-book-query.h					\
+	e-address-western.h				\
+	e-name-western.h				\
+	e-contact.h					\
+	e-vcard.h					\
+	e-source-backend-summary-setup.h
+
+%-$(API_VERSION).pc: %.pc
+	 cp $< $@
+
+e-name-western-tables.h: e-name-western-tables.h.in
+	$(AM_V_GEN) ($(PYTHON) ${srcdir}/gen-western-table.py < $< > $  tmp && mv $  tmp $@) || rm -f $  tmp
+
+BUILT_SOURCES += e-name-western-tables.h
+
+pkgconfigdir = $(libdir)/pkgconfig
+pkgconfig_DATA = libebook-contacts-$(API_VERSION).pc
+
+
+-include $(INTROSPECTION_MAKEFILE)
+INTROSPECTION_GIRS =
+INTROSPECTION_SCANNER_ARGS = --add-include-path=$(top_builddir)/libedataserver \
+	--add-include-path=$(srcdir) --identifier-prefix=E --pkg-export \
+	libebook-contacts-1.2 --c-include="libebook-contacts/libebook-contacts.h" --warn-all
+INTROSPECTION_COMPILER_ARGS = --includedir=$(top_builddir)/libedataserver \
+	--includedir=$(srcdir)
+
+if HAVE_INTROSPECTION
+introspection_sources = $(libebook_contacts_1_2_la_SOURCES)
+EBookContacts-1.2.gir: libebook-contacts-1.2.la
+
+EBookContacts_1_2_gir_INCLUDES = GObject-2.0 GLib-2.0 libxml2-2.0 \
+	Gio-2.0 \
+	$(NULL)
+libxml_include = `$(PKG_CONFIG) --cflags libxml-2.0`
+EBookContacts_1_2_gir_CFLAGS = $(INCLUDES) \
+		       $(libxml_include) \
+		       -I$(top_srcdir) \
+		       -I$(top_builddir) \
+		       -I$(top_srcdir)/addressbook/ \
+		       -I$(top_builddir)/addressbook/ \
+		       -I$(top_srcdir)/addressbook/libebook-contacts \
+		       -I$(top_builddir)/addressbook/libebook-contacts \
+			-DLIBEBOOK_CONTACTS_COMPILATION		\
+		       $(EVOLUTION_ADDRESSBOOK_CFLAGS) \
+		       $(CAMEL_CFLAGS) \
+			$(NULL)
+EBookContacts_1_2_gir_SCANNERFLAGS = --include-uninstalled=$(top_builddir)/libedataserver/EDataServer-1.2.gir
+EBookContacts_1_2_gir_LIBS = \
+	libebook-contacts-1.2.la $(top_builddir)/libedataserver/libedataserver-1.2.la
+EBookContacts_1_2_gir_FILES = $(libebook_contacts_1_2_la_SOURCES) $(libebookcontactsinclude_HEADERS)
+
+INTROSPECTION_GIRS += EBookContacts-1.2.gir
+
+girdir = $(datadir)/gir-1.0
+dist_gir_DATA = $(INTROSPECTION_GIRS)
+
+typelibdir = $(libdir)/girepository-1.0
+typelib_DATA = $(INTROSPECTION_GIRS:.gir=.typelib)
+
+CLEANFILES += $(dist_gir_DATA) $(typelib_DATA)
+endif
+
+BUILT_SOURCES += $(ENUM_GENERATED) $(MARSHAL_GENERATED)
+CLEANFILES    += $(BUILT_SOURCES)
+DISTCLEANFILES = $(pkgconfig_DATA)
+
+EXTRA_DIST = 						\
+	$(pkgconfig_DATA:-$(API_VERSION).pc=.pc.in)	\
+	e-book-contacts-enumtypes.h.template			\
+	e-book-contacts-enumtypes.c.template			\
+	e-book-contacts-marshal.list	\
+	e-name-western-tables.h.in                      \
+	gen-western-table.py
+
+dist-hook:
+	cd $(distdir); rm -f $(BUILT_SOURCES)
+
+-include $(top_srcdir)/git.mk
diff --git a/addressbook/libebook/e-address-western.c b/addressbook/libebook-contacts/e-address-western.c
similarity index 100%
rename from addressbook/libebook/e-address-western.c
rename to addressbook/libebook-contacts/e-address-western.c
diff --git a/addressbook/libebook/e-address-western.h b/addressbook/libebook-contacts/e-address-western.h
similarity index 76%
rename from addressbook/libebook/e-address-western.h
rename to addressbook/libebook-contacts/e-address-western.h
index aab4c00..a4dd8de 100644
--- a/addressbook/libebook/e-address-western.h
+++ b/addressbook/libebook-contacts/e-address-western.h
@@ -1,5 +1,5 @@
-#if !defined (__LIBEBOOK_H_INSIDE__) && !defined (LIBEBOOK_COMPILATION)
-#error "Only <libebook/libebook.h> should be included directly."
+#if !defined (__LIBEBOOK_CONTACTS_H_INSIDE__) && !defined (LIBEBOOK_CONTACTS_COMPILATION)
+#error "Only <libebook-contacts/libebook-contacts.h> should be included directly."
 #endif
 
 #ifndef __E_ADDRESS_WESTERN_H__
diff --git a/addressbook/libebook-contacts/e-book-contacts-enumtypes.c.template b/addressbook/libebook-contacts/e-book-contacts-enumtypes.c.template
new file mode 100644
index 0000000..127154b
--- /dev/null
+++ b/addressbook/libebook-contacts/e-book-contacts-enumtypes.c.template
@@ -0,0 +1,38 @@
+/*** BEGIN file-header ***/
+#include "e-book-contacts-enumtypes.h"
+
+/*** END file-header ***/
+
+/*** BEGIN file-production ***/
+/* enumerations from "@filename@" */
+#include "@filename@"
+
+/*** END file-production ***/
+
+/*** BEGIN value-header ***/
+GType
+ enum_name@_get_type (void)
+{
+	static GType the_type = 0;
+	
+	if (the_type == 0) {
+		static const G Type@Value values[] = {
+/*** END value-header ***/
+
+/*** BEGIN value-production ***/
+			{ @VALUENAME@,
+			  "@VALUENAME@",
+			  "@valuenick@" },
+/*** END value-production ***/
+
+/*** BEGIN value-tail ***/
+			{ 0, NULL, NULL }
+		};
+		the_type = g_ type@_register_static (
+			g_intern_static_string ("@EnumName@"),
+			values);
+	}
+	return the_type;
+}
+
+/*** END value-tail ***/
diff --git a/addressbook/libebook-contacts/e-book-contacts-enumtypes.h.template b/addressbook/libebook-contacts/e-book-contacts-enumtypes.h.template
new file mode 100644
index 0000000..69ff145
--- /dev/null
+++ b/addressbook/libebook-contacts/e-book-contacts-enumtypes.h.template
@@ -0,0 +1,27 @@
+/*** BEGIN file-header ***/
+#ifndef E_BOOK_CONTACTS_ENUMTYPES_H
+#define E_BOOK_CONTACTS_ENUMTYPES_H
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+/*** END file-header ***/
+
+/*** BEGIN file-production ***/
+/* Enumerations from "@filename@" */
+
+/*** END file-production ***/
+
+/*** BEGIN enumeration-production ***/
+#define E_TYPE_ ENUMSHORT@	(@enum_name _get_type())
+GType @enum_name _get_type	(void) G_GNUC_CONST;
+
+/*** END enumeration-production ***/
+
+/*** BEGIN file-tail ***/
+G_END_DECLS
+
+#endif /* E_BOOK_ENUMTYPES_H */
+/*** END file-tail ***/
+
diff --git a/addressbook/libebook-contacts/e-book-contacts-marshal.list b/addressbook/libebook-contacts/e-book-contacts-marshal.list
new file mode 100644
index 0000000..4f34146
--- /dev/null
+++ b/addressbook/libebook-contacts/e-book-contacts-marshal.list
@@ -0,0 +1,6 @@
+NONE:NONE
+NONE:BOOL
+NONE:POINTER
+NONE:STRING
+NONE:INT
+NONE:UINT,STRING
diff --git a/addressbook/libebook-contacts/e-book-contacts-types.h b/addressbook/libebook-contacts/e-book-contacts-types.h
new file mode 100644
index 0000000..0f2876d
--- /dev/null
+++ b/addressbook/libebook-contacts/e-book-contacts-types.h
@@ -0,0 +1,112 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * A client-side GObject which exposes the
+ * Evolution:BookListener interface.
+ *
+ * Author:
+ *   Nat Friedman (nat ximian com)
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ */
+
+#if !defined (__LIBEBOOK_CONTACTS_H_INSIDE__) && !defined (LIBEBOOK_CONTACTS_COMPILATION)
+#error "Only <libebook-contacts/libebook-contacts.h> should be included directly."
+#endif
+
+#ifndef __E_BOOK_CONTACTS_TYPES_H__
+#define __E_BOOK_CONTACTS_TYPES_H__
+
+#include <libebook-contacts/e-contact.h>
+
+G_BEGIN_DECLS
+
+/**
+ * EBookClientViewFlags:
+ * @E_BOOK_CLIENT_VIEW_FLAGS_NONE:
+ *   Symbolic value for no flags
+ * @E_BOOK_CLIENT_VIEW_FLAGS_NOTIFY_INITIAL:
+ *   If this flag is set then all contacts matching the view's query will
+ *   be sent as notifications when starting the view, otherwise only future
+ *   changes will be reported.  The default for a #EBookClientView is %TRUE.
+ *
+ * Flags that control the behaviour of an #EBookClientView.
+ *
+ * Since: 3.4
+ */
+typedef enum {
+	E_BOOK_CLIENT_VIEW_FLAGS_NONE           = 0,
+	E_BOOK_CLIENT_VIEW_FLAGS_NOTIFY_INITIAL = (1 << 0),
+} EBookClientViewFlags;
+
+/**
+ * EDataBookStatus:
+ *
+ * XXX Document me!
+ *
+ * Since: 3.6
+ **/
+typedef enum {
+	E_DATA_BOOK_STATUS_SUCCESS,
+	E_DATA_BOOK_STATUS_BUSY,
+	E_DATA_BOOK_STATUS_REPOSITORY_OFFLINE,
+	E_DATA_BOOK_STATUS_PERMISSION_DENIED,
+	E_DATA_BOOK_STATUS_CONTACT_NOT_FOUND,
+	E_DATA_BOOK_STATUS_CONTACTID_ALREADY_EXISTS,
+	E_DATA_BOOK_STATUS_AUTHENTICATION_FAILED,
+	E_DATA_BOOK_STATUS_AUTHENTICATION_REQUIRED,
+	E_DATA_BOOK_STATUS_UNSUPPORTED_FIELD,
+	E_DATA_BOOK_STATUS_UNSUPPORTED_AUTHENTICATION_METHOD,
+	E_DATA_BOOK_STATUS_TLS_NOT_AVAILABLE,
+	E_DATA_BOOK_STATUS_NO_SUCH_BOOK,
+	E_DATA_BOOK_STATUS_BOOK_REMOVED,
+	E_DATA_BOOK_STATUS_OFFLINE_UNAVAILABLE,
+	E_DATA_BOOK_STATUS_SEARCH_SIZE_LIMIT_EXCEEDED,
+	E_DATA_BOOK_STATUS_SEARCH_TIME_LIMIT_EXCEEDED,
+	E_DATA_BOOK_STATUS_INVALID_QUERY,
+	E_DATA_BOOK_STATUS_QUERY_REFUSED,
+	E_DATA_BOOK_STATUS_COULD_NOT_CANCEL,
+	E_DATA_BOOK_STATUS_OTHER_ERROR,
+	E_DATA_BOOK_STATUS_INVALID_SERVER_VERSION,
+	E_DATA_BOOK_STATUS_NO_SPACE,
+	E_DATA_BOOK_STATUS_INVALID_ARG,
+	E_DATA_BOOK_STATUS_NOT_SUPPORTED,
+	E_DATA_BOOK_STATUS_NOT_OPENED,
+	E_DATA_BOOK_STATUS_OUT_OF_SYNC
+} EDataBookStatus;
+
+typedef enum {
+	E_BOOK_VIEW_STATUS_OK,
+	E_BOOK_VIEW_STATUS_TIME_LIMIT_EXCEEDED,
+	E_BOOK_VIEW_STATUS_SIZE_LIMIT_EXCEEDED,
+	E_BOOK_VIEW_ERROR_INVALID_QUERY,
+	E_BOOK_VIEW_ERROR_QUERY_REFUSED,
+	E_BOOK_VIEW_ERROR_OTHER_ERROR
+} EBookViewStatus;
+
+typedef enum {
+	E_BOOK_CHANGE_CARD_ADDED,
+	E_BOOK_CHANGE_CARD_DELETED,
+	E_BOOK_CHANGE_CARD_MODIFIED
+} EBookChangeType;
+
+typedef struct {
+	EBookChangeType  change_type;
+	EContact        *contact;
+} EBookChange;
+
+
+/**
+ * EBookIndexType:
+ * @E_BOOK_INDEX_PREFIX: An index suitable for searching contacts with a prefix pattern
+ * @E_BOOK_INDEX_SUFFIX: An index suitable for searching contacts with a suffix pattern
+ *
+ * The type of index defined by e_source_backend_summary_setup_set_indexed_fields()
+ */
+typedef enum {
+	E_BOOK_INDEX_PREFIX = 0,
+	E_BOOK_INDEX_SUFFIX
+} EBookIndexType;
+
+G_END_DECLS
+
+#endif /* __E_BOOK_CONTACTS_TYPES_H__ */
diff --git a/addressbook/libebook/e-book-query.c b/addressbook/libebook-contacts/e-book-query.c
similarity index 100%
rename from addressbook/libebook/e-book-query.c
rename to addressbook/libebook-contacts/e-book-query.c
diff --git a/addressbook/libebook/e-book-query.h b/addressbook/libebook-contacts/e-book-query.h
similarity index 90%
rename from addressbook/libebook/e-book-query.h
rename to addressbook/libebook-contacts/e-book-query.h
index 59c8987..d5a842f 100644
--- a/addressbook/libebook/e-book-query.h
+++ b/addressbook/libebook-contacts/e-book-query.h
@@ -1,12 +1,12 @@
 
-#if !defined (__LIBEBOOK_H_INSIDE__) && !defined (LIBEBOOK_COMPILATION)
-#error "Only <libebook/libebook.h> should be included directly."
+#if !defined (__LIBEBOOK_CONTACTS_H_INSIDE__) && !defined (LIBEBOOK_CONTACTS_COMPILATION)
+#error "Only <libebook-contacts/libebook-contacts.h> should be included directly."
 #endif
 
 #ifndef __E_BOOK_QUERY_H__
 #define __E_BOOK_QUERY_H__
 
-#include <libebook/e-contact.h>
+#include <libebook-contacts/e-contact.h>
 
 G_BEGIN_DECLS
 
diff --git a/addressbook/libebook/e-contact.c b/addressbook/libebook-contacts/e-contact.c
similarity index 99%
rename from addressbook/libebook/e-contact.c
rename to addressbook/libebook-contacts/e-contact.c
index b918d57..3749b67 100644
--- a/addressbook/libebook/e-contact.c
+++ b/addressbook/libebook-contacts/e-contact.c
@@ -30,7 +30,6 @@
 #include <gio/gio.h>
 #include <glib/gi18n-lib.h>
 #include "e-contact.h"
-#include "e-book.h"
 #include "e-name-western.h"
 
 #ifdef G_OS_WIN32
diff --git a/addressbook/libebook/e-contact.h b/addressbook/libebook-contacts/e-contact.h
similarity index 98%
rename from addressbook/libebook/e-contact.h
rename to addressbook/libebook-contacts/e-contact.h
index 3e56547..e698aa6 100644
--- a/addressbook/libebook/e-contact.h
+++ b/addressbook/libebook-contacts/e-contact.h
@@ -6,8 +6,8 @@
  * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
  */
 
-#if !defined (__LIBEBOOK_H_INSIDE__) && !defined (LIBEBOOK_COMPILATION)
-#error "Only <libebook/libebook.h> should be included directly."
+#if !defined (__LIBEBOOK_CONTACTS_H_INSIDE__) && !defined (LIBEBOOK_CONTACTS_COMPILATION)
+#error "Only <libebook-contacts/libebook-contacts.h> should be included directly."
 #endif
 
 #ifndef E_CONTACT_H
@@ -15,7 +15,7 @@
 
 #include <time.h>
 #include <stdio.h>
-#include <libebook/e-vcard.h>
+#include <libebook-contacts/e-vcard.h>
 
 /* Standard GObject macros */
 #define E_TYPE_CONTACT \
diff --git a/addressbook/libebook/e-name-western-tables.h b/addressbook/libebook-contacts/e-name-western-tables.h
similarity index 100%
rename from addressbook/libebook/e-name-western-tables.h
rename to addressbook/libebook-contacts/e-name-western-tables.h
diff --git a/addressbook/libebook/e-name-western-tables.h.in b/addressbook/libebook-contacts/e-name-western-tables.h.in
similarity index 100%
rename from addressbook/libebook/e-name-western-tables.h.in
rename to addressbook/libebook-contacts/e-name-western-tables.h.in
diff --git a/addressbook/libebook/e-name-western.c b/addressbook/libebook-contacts/e-name-western.c
similarity index 100%
rename from addressbook/libebook/e-name-western.c
rename to addressbook/libebook-contacts/e-name-western.c
diff --git a/addressbook/libebook/e-name-western.h b/addressbook/libebook-contacts/e-name-western.h
similarity index 71%
rename from addressbook/libebook/e-name-western.h
rename to addressbook/libebook-contacts/e-name-western.h
index e2515bf..e1e6f1e 100644
--- a/addressbook/libebook/e-name-western.h
+++ b/addressbook/libebook-contacts/e-name-western.h
@@ -1,8 +1,8 @@
 #ifndef __E_NAME_WESTERN_H__
 #define __E_NAME_WESTERN_H__
 
-#if !defined (__LIBEBOOK_H_INSIDE__) && !defined (LIBEBOOK_COMPILATION)
-#error "Only <libebook/libebook.h> should be included directly."
+#if !defined (__LIBEBOOK_CONTACTS_H_INSIDE__) && !defined (LIBEBOOK_CONTACTS_COMPILATION)
+#error "Only <libebook-contacts/libebook-contacts.h> should be included directly."
 #endif
 
 #include <glib.h>
diff --git a/addressbook/libebook/e-source-backend-summary-setup.c b/addressbook/libebook-contacts/e-source-backend-summary-setup.c
similarity index 99%
rename from addressbook/libebook/e-source-backend-summary-setup.c
rename to addressbook/libebook-contacts/e-source-backend-summary-setup.c
index 018a941..fc134a9 100644
--- a/addressbook/libebook/e-source-backend-summary-setup.c
+++ b/addressbook/libebook-contacts/e-source-backend-summary-setup.c
@@ -22,7 +22,7 @@
 
 /**
  * SECTION: e-source-backend-summary-setup
- * @include: libebook/libebook.h
+ * @include: libebook-contacts/libebook-contacts.h
  * @short_description: #ESource extension to configure summary fields
  *
  * The #ESourceBackendSummarySetup extension configures which #EContactFields
@@ -32,7 +32,7 @@
  * Access the extension as follows:
  *
  * |[
- *   #include <libebook/libebook.h>
+ *   #include <libebook-contacts/libebook-contacts.h>
  *
  *   ESourceBackendSummarySetup *extension;
  *
@@ -46,7 +46,7 @@
  **/
 
 #include "e-source-backend-summary-setup.h"
-#include "e-book-enumtypes.h"
+#include "e-book-contacts-enumtypes.h"
 
 #define E_SOURCE_BACKEND_SUMMARY_GET_PRIVATE(obj)	\
 	(G_TYPE_INSTANCE_GET_PRIVATE			\
diff --git a/addressbook/libebook/e-source-backend-summary-setup.h b/addressbook/libebook-contacts/e-source-backend-summary-setup.h
similarity index 93%
rename from addressbook/libebook/e-source-backend-summary-setup.h
rename to addressbook/libebook-contacts/e-source-backend-summary-setup.h
index ecea646..8950a0e 100644
--- a/addressbook/libebook/e-source-backend-summary-setup.h
+++ b/addressbook/libebook-contacts/e-source-backend-summary-setup.h
@@ -20,16 +20,16 @@
  * Authors: Tristan Van Berkom <tristanvb openismus com>
  */
 
-#if !defined (__LIBEBOOK_H_INSIDE__) && !defined (LIBEBOOK_COMPILATION)
-#error "Only <libebook/libebook.h> should be included directly."
+#if !defined (__LIBEBOOK_CONTACTS_H_INSIDE__) && !defined (LIBEBOOK_CONTACTS_COMPILATION)
+#error "Only <libebook-contacts/libebook-contacts.h> should be included directly."
 #endif
 
 #ifndef E_SOURCE_BACKEND_SUMMARY_SETUP_H
 #define E_SOURCE_BACKEND_SUMMARY_SETUP_H
 
 #include <libedataserver/libedataserver.h>
-#include <libebook/e-contact.h>
-#include <libebook/e-book-types.h>
+#include <libebook-contacts/e-contact.h>
+#include <libebook-contacts/e-book-contacts-types.h>
 
 /* Standard GObject macros */
 #define E_TYPE_SOURCE_BACKEND_SUMMARY_SETUP \
diff --git a/addressbook/libebook/e-vcard.c b/addressbook/libebook-contacts/e-vcard.c
similarity index 100%
rename from addressbook/libebook/e-vcard.c
rename to addressbook/libebook-contacts/e-vcard.c
diff --git a/addressbook/libebook/e-vcard.h b/addressbook/libebook-contacts/e-vcard.h
similarity index 98%
rename from addressbook/libebook/e-vcard.h
rename to addressbook/libebook-contacts/e-vcard.h
index 5f4156c..9a39c0f 100644
--- a/addressbook/libebook/e-vcard.h
+++ b/addressbook/libebook-contacts/e-vcard.h
@@ -20,8 +20,8 @@
  * Author: Chris Toshok (toshok ximian com)
  */
 
-#if !defined (__LIBEBOOK_H_INSIDE__) && !defined (LIBEBOOK_COMPILATION)
-#error "Only <libebook/libebook.h> should be included directly."
+#if !defined (__LIBEBOOK_CONTACTS_H_INSIDE__) && !defined (LIBEBOOK_CONTACTS_COMPILATION)
+#error "Only <libebook-contacts/libebook-contacts.h> should be included directly."
 #endif
 
 #ifndef _EVCARD_H
diff --git a/addressbook/libebook/gen-western-table.py b/addressbook/libebook-contacts/gen-western-table.py
similarity index 100%
rename from addressbook/libebook/gen-western-table.py
rename to addressbook/libebook-contacts/gen-western-table.py
diff --git a/addressbook/libebook-contacts/libebook-contacts.h b/addressbook/libebook-contacts/libebook-contacts.h
new file mode 100644
index 0000000..92f95f3
--- /dev/null
+++ b/addressbook/libebook-contacts/libebook-contacts.h
@@ -0,0 +1,38 @@
+/*
+ * libebook-contacts.h
+ *
+ * This program 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; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program 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 the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+#ifndef LIBEBOOK_CONTACTS_H
+#define LIBEBOOK_CONTACTS_H
+
+#define __LIBEBOOK_CONTACTS_H_INSIDE__
+
+#include <libedataserver/libedataserver.h>
+
+#include <libebook-contacts/e-book-contacts-types.h>
+#include <libebook-contacts/e-book-query.h>
+#include <libebook-contacts/e-name-western.h>
+#include <libebook-contacts/e-address-western.h>
+#include <libebook-contacts/e-contact.h>
+#include <libebook-contacts/e-vcard.h>
+#include <libebook-contacts/e-book-contacts-enumtypes.h>
+#include <libebook-contacts/e-source-backend-summary-setup.h>
+
+#undef __LIBEBOOK_CONTACTS_H_INSIDE__
+
+#endif /* LIBEBOOK_CONTACTS_H */
+
diff --git a/addressbook/libebook-contacts/libebook-contacts.pc.in b/addressbook/libebook-contacts/libebook-contacts.pc.in
new file mode 100644
index 0000000..d1396fb
--- /dev/null
+++ b/addressbook/libebook-contacts/libebook-contacts.pc.in
@@ -0,0 +1,16 @@
+prefix= prefix@
+exec_prefix= exec_prefix@
+libdir= libdir@
+includedir= includedir@
+datarootdir= datarootdir@
+datadir= datadir@
+
+privincludedir= privincludedir@
+
+Name: libebook-contacts
+Description: Client library for evolution contacts and vcard structures
+Version: @VERSION@
+Requires: libedataserver-1.2
+Requires.private: camel-1.2
+Libs: -L${libdir} -lebook-contacts-1.2
+Cflags: -I${privincludedir}
diff --git a/addressbook/libebook/Makefile.am b/addressbook/libebook/Makefile.am
index 5e29354..e188256 100644
--- a/addressbook/libebook/Makefile.am
+++ b/addressbook/libebook/Makefile.am
@@ -38,25 +38,22 @@ libebook_1_2_la_CPPFLAGS = \
 libebook_1_2_la_SOURCES =				\
 	$(ENUM_GENERATED)				\
 	$(MARSHAL_GENERATED)				\
-	e-address-western.c				\
 	e-book-client.c					\
 	e-book-client-view.c				\
-	e-book-query.c					\
 	e-book-view-private.h				\
 	e-book-view.c					\
 	e-book.c					\
-	e-contact.c					\
 	e-destination.c					\
-	e-name-western.c				\
-	e-name-western-tables.h                         \
-	e-source-backend-summary-setup.c			\
-	e-vcard.c					\
 	e-error.h
 
 libebook_1_2_la_LIBADD =					\
+	$(top_builddir)/addressbook/libebook-contacts/libebook-contacts-1.2.la \
+	$(top_builddir)/addressbook/libedata-book/libedata-book-1.2.la \
 	$(top_builddir)/addressbook/libegdbus/libegdbus-book.la	\
 	$(top_builddir)/camel/libcamel-1.2.la			\
 	$(top_builddir)/libedataserver/libedataserver-1.2.la	\
+	$(top_builddir)/libebackend/libebackend-1.2.la \
+	$(top_builddir)/addressbook/libedata-book/libedata-book-1.2.la	\
 	$(EVOLUTION_ADDRESSBOOK_LIBS)				\
 	$(CAMEL_LIBS)
 
@@ -69,28 +66,16 @@ libebookincludedir = $(privincludedir)/libebook
 
 libebookinclude_HEADERS =				\
 	libebook.h					\
-	e-address-western.h				\
 	e-book-client.h					\
 	e-book-client-view.h				\
 	e-book-enumtypes.h				\
-	e-book-query.h					\
 	e-book-view.h					\
 	e-book-types.h					\
-	e-book.h					\
-	e-contact.h					\
-	e-destination.h					\
-	e-name-western.h				\
-	e-source-backend-summary-setup.h		\
-	e-vcard.h
+	e-book.h
 
 %-$(API_VERSION).pc: %.pc
 	 cp $< $@
 
-e-name-western-tables.h: e-name-western-tables.h.in
-	$(AM_V_GEN) ($(PYTHON) ${srcdir}/gen-western-table.py < $< > $  tmp && mv $  tmp $@) || rm -f $  tmp
-
-BUILT_SOURCES += e-name-western-tables.h
-
 pkgconfigdir = $(libdir)/pkgconfig
 pkgconfig_DATA = libebook-$(API_VERSION).pc
 
@@ -105,6 +90,7 @@ INTROSPECTION_SCANNER_ARGS = \
 	--c-include="libebook/libebook.h" \
 	$(NULL)
 INTROSPECTION_COMPILER_ARGS = \
+	--includedir=$(top_builddir)/addressbook/libebook-contacts \
 	--includedir=$(top_builddir)/libedataserver \
 	--includedir=$(srcdir) \
 	$(NULL)
@@ -130,15 +116,15 @@ EBook_1_2_gir_CFLAGS = \
 	$(NULL)
 EBook_1_2_gir_SCANNERFLAGS = \
 	--include-uninstalled=$(top_builddir)/libedataserver/EDataServer-1.2.gir \
+	--include-uninstalled=$(top_builddir)/addressbook/libebook-contacts/EBookContacts-1.2.gir \
 	$(NULL)
 EBook_1_2_gir_LIBS = \
-	libebook-1.2.la \
-	$(top_builddir)/libedataserver/libedataserver-1.2.la \
-	$(NULL)
+	$(top_builddir)/addressbook/libebook-contacts/libebook-contacts-1.2.la \
+	$(top_builddir)/addressbook/libedata-book/libedata-book-1.2.la \
+	libebook-1.2.la $(top_builddir)/libedataserver/libedataserver-1.2.la
 EBook_1_2_gir_FILES = \
 	$(libebook_1_2_la_SOURCES) \
-	$(libebookinclude_HEADERS) \
-	$(NULL)
+	$(libebookinclude_HEADERS)
 
 INTROSPECTION_GIRS += EBook-1.2.gir
 
diff --git a/addressbook/libebook/e-book-client-view.h b/addressbook/libebook/e-book-client-view.h
index 176df48..72a3344 100644
--- a/addressbook/libebook/e-book-client-view.h
+++ b/addressbook/libebook/e-book-client-view.h
@@ -55,24 +55,6 @@ typedef struct _EBookClientViewPrivate EBookClientViewPrivate;
 struct _EBookClient;
 
 /**
- * EBookClientViewFlags:
- * @E_BOOK_CLIENT_VIEW_FLAGS_NONE:
- *   Symbolic value for no flags
- * @E_BOOK_CLIENT_VIEW_FLAGS_NOTIFY_INITIAL:
- *   If this flag is set then all contacts matching the view's query will
- *   be sent as notifications when starting the view, otherwise only future
- *   changes will be reported.  The default for a #EBookClientView is %TRUE.
- *
- * Flags that control the behaviour of an #EBookClientView.
- *
- * Since: 3.4
- */
-typedef enum {
-	E_BOOK_CLIENT_VIEW_FLAGS_NONE           = 0,
-	E_BOOK_CLIENT_VIEW_FLAGS_NOTIFY_INITIAL = (1 << 0),
-} EBookClientViewFlags;
-
-/**
  * EBookClientView:
  *
  * Contains only private data the should be read and manipulated using the
diff --git a/addressbook/libebook/e-book-client.c b/addressbook/libebook/e-book-client.c
index af2d4d1..ef46dcc 100644
--- a/addressbook/libebook/e-book-client.c
+++ b/addressbook/libebook/e-book-client.c
@@ -29,12 +29,15 @@
 #include <libedataserver/libedataserver.h>
 #include <libedataserver/e-client-private.h>
 
+#include <libebackend/libebackend.h>
+#include <libedata-book/libedata-book.h>
+
 #include "e-book-client.h"
-#include "e-contact.h"
-#include "e-name-western.h"
 
 #include "e-gdbus-book.h"
 #include "e-gdbus-book-factory.h"
+#include "e-gdbus-book-view.h"
+#include "e-gdbus-book-direct.h"
 
 #define E_BOOK_CLIENT_GET_PRIVATE(obj) \
 	(G_TYPE_INSTANCE_GET_PRIVATE \
@@ -43,6 +46,8 @@
 struct _EBookClientPrivate {
 	GDBusProxy *dbus_proxy;
 	guint gone_signal_id;
+
+	EDataBook *direct_book;
 };
 
 G_DEFINE_TYPE (EBookClient, e_book_client, E_TYPE_CLIENT)
@@ -185,6 +190,71 @@ static GRecMutex book_factory_lock;
 
 static void gdbus_book_factory_closed_cb (GDBusConnection *connection, gboolean remote_peer_vanished, GError *error, gpointer user_data);
 
+
+typedef struct {
+	EBookClient         *client;
+	GAsyncReadyCallback  callback;
+	gpointer             user_data;
+	gpointer             source_tag;
+	GCancellable        *cancellable;    /* Cancellable and only-if-exists only used */
+	gboolean             only_if_exists; /* for chaining the async open call into 2 calls */
+} PropagateReadyData;
+
+static PropagateReadyData *
+propagate_ready_data_new (EBookClient         *client,
+			  GAsyncReadyCallback  callback,
+			  gpointer             user_data,
+			  gpointer             source_tag,
+			  GCancellable        *cancellable)
+{
+	PropagateReadyData *data = g_slice_new0 (PropagateReadyData);
+
+	data->client = g_object_ref (client);
+	data->callback = callback;
+	data->user_data = user_data;
+	data->source_tag = source_tag;
+
+	if (cancellable)
+		data->cancellable = g_object_ref (cancellable);
+
+	return data;
+}
+
+static void
+propagate_ready_data_free (PropagateReadyData *data)
+{
+	if (data) {
+		g_object_unref (data->client);
+
+		if (data->cancellable)
+			g_object_unref (data->cancellable);
+
+		g_slice_free (PropagateReadyData, data);
+	}
+}
+
+static void
+propagate_direct_book_async_ready (GObject *source_object,
+				   GAsyncResult *res,
+				   gpointer user_data)
+{
+  GSimpleAsyncResult *result;
+  PropagateReadyData *data = (PropagateReadyData *)user_data;
+
+  result = g_simple_async_result_new (G_OBJECT (data->client),
+				      data->callback,
+				      data->user_data,
+				      data->source_tag);
+
+  g_object_ref (res);
+  g_simple_async_result_set_op_res_gpointer (result, res, g_object_unref);
+
+  g_simple_async_result_complete (result);
+  g_object_unref (result);
+
+  propagate_ready_data_free (data);
+}
+
 static void
 gdbus_book_factory_disconnect (GDBusConnection *connection)
 {
@@ -478,13 +548,21 @@ static void
 book_client_dispose (GObject *object)
 {
 	EClient *client;
+	EBookClient *book_client;
 
 	client = E_CLIENT (object);
+	book_client = E_BOOK_CLIENT (object);
 
 	e_client_cancel_all (client);
 
 	gdbus_book_client_disconnect (E_BOOK_CLIENT (client));
 
+	if (book_client->priv->direct_book) {
+		e_data_book_close_sync (book_client->priv->direct_book, NULL, NULL);
+		g_object_unref (book_client->priv->direct_book);
+		book_client->priv->direct_book = NULL;
+	}
+
 	/* Chain up to parent's dispose() method. */
 	G_OBJECT_CLASS (e_book_client_parent_class)->dispose (object);
 }
@@ -713,6 +791,43 @@ book_client_set_backend_property_sync (EClient *client,
 	return res;
 }
 
+
+static void book_client_open (EClient *client,
+			      gboolean only_if_exists,
+			      GCancellable *cancellable,
+			      GAsyncReadyCallback callback,
+			      gpointer user_data);
+
+static void
+direct_book_async_opened (GObject *source_object,
+			  GAsyncResult *res,
+			  gpointer user_data)
+{
+	PropagateReadyData *data = (PropagateReadyData *)user_data;
+	GError *error = NULL;
+
+	if (e_data_book_open_finish (E_DATA_BOOK (source_object), res, &error)) {
+
+		/* Open direct book succeeded, now proceed to open the real book over D-Bus */
+		e_client_proxy_call_boolean (E_CLIENT (data->client), data->only_if_exists,
+					     data->cancellable, data->callback, data->user_data, book_client_open,
+					     e_gdbus_book_call_open, e_gdbus_book_call_open_finish,
+					     NULL, NULL, NULL, NULL);
+	} else {
+		/* Open failed, report error right away */
+		GSimpleAsyncResult *result;
+
+		result = g_simple_async_result_new_take_error (G_OBJECT (data->client),
+							       data->callback,
+							       data->user_data,
+							       error);
+		g_simple_async_result_complete (result);
+		g_object_unref (result);
+	}
+
+	propagate_ready_data_free (data);
+}
+
 static void
 book_client_open (EClient *client,
                   gboolean only_if_exists,
@@ -720,13 +835,35 @@ book_client_open (EClient *client,
                   GAsyncReadyCallback callback,
                   gpointer user_data)
 {
-	e_client_proxy_call_boolean (
-		client, only_if_exists,
-		cancellable, callback, user_data,
-		book_client_open,
-		e_gdbus_book_call_open,
-		e_gdbus_book_call_open_finish,
-		NULL, NULL, NULL, NULL);
+	EBookClient *book_client;
+	PropagateReadyData *data;
+
+	g_return_if_fail (E_IS_BOOK_CLIENT (client));
+
+	book_client = E_BOOK_CLIENT (client);
+
+	if (book_client->priv->direct_book) {
+		data = propagate_ready_data_new (book_client,
+						 callback,
+						 user_data,
+						 book_client_open,
+						 cancellable);
+		data->only_if_exists = only_if_exists;
+
+		e_data_book_open (book_client->priv->direct_book,
+				  only_if_exists,
+				  cancellable,
+				  direct_book_async_opened,
+				  data);
+	} else {
+		e_client_proxy_call_boolean (
+		        client, only_if_exists,
+			cancellable, callback, user_data,
+			book_client_open,
+			e_gdbus_book_call_open,
+			e_gdbus_book_call_open_finish,
+			NULL, NULL, NULL, NULL);
+	}
 }
 
 static gboolean
@@ -755,9 +892,14 @@ book_client_open_sync (EClient *client,
 		return FALSE;
 	}
 
+	if (book_client->priv->direct_book &&
+	    !e_data_book_open_sync (book_client->priv->direct_book,
+				    only_if_exists, cancellable, error))
+		return FALSE;
+
 	return e_client_proxy_call_sync_boolean__void (
-		client, only_if_exists, cancellable, error,
-		e_gdbus_book_call_open_sync);
+                client, only_if_exists, cancellable, error,
+                e_gdbus_book_call_open_sync);
 }
 
 static void
@@ -964,6 +1106,62 @@ e_book_client_new (ESource *source,
 	return client;
 }
 
+/**
+ * e_book_client_new_direct:
+ * @source: An #ESource pointer
+ * @error: A #GError pointer
+ *
+ * Like e_book_client_new(), except creates the book client for
+ * direct read access to the underlying addressbook.
+ *
+ * Returns: a new but unopened #EBookClient.
+ *
+ * Since: 3.8
+ **/
+EBookClient *
+e_book_client_new_direct (ESourceRegistry *registry,
+			  ESource         *source,
+			  GError         **error)
+{
+	EBookClient *client;
+	EGdbusBookDirect *direct_config;
+	const gchar *backend_name, *backend_path, *config;
+
+	client = e_book_client_new (source, error);
+
+	if (!client)
+		return NULL;
+
+	direct_config = 
+	        e_gdbus_book_direct_proxy_new_sync (
+		        g_dbus_proxy_get_connection (client->priv->dbus_proxy),
+			G_DBUS_PROXY_FLAGS_NONE,
+			ADDRESS_BOOK_DBUS_SERVICE_NAME,
+			g_dbus_proxy_get_object_path (client->priv->dbus_proxy),
+			NULL, NULL);
+
+	backend_path = e_gdbus_book_direct_get_backend_path (direct_config);
+	backend_name = e_gdbus_book_direct_get_backend_name (direct_config);
+	config = e_gdbus_book_direct_get_backend_config (direct_config);
+
+	if (backend_path && backend_path[0] &&
+	    backend_name && backend_name[0]) {
+		client->priv->direct_book =
+			e_data_book_new_direct (registry, source,
+						backend_path,
+						backend_name,
+						config);
+		if (!client->priv->direct_book)
+			g_warning ("Failed to open addressbook in direct read access mode, falling back to normal read access mode");
+
+	} else
+		g_warning ("Direct read access mode not supported by the given backend, falling back to normal read access mode");
+
+	g_object_unref (direct_config);
+
+	return client;
+}
+
 #define SELF_UID_PATH_ID "org.gnome.evolution-data-server.addressbook"
 #define SELF_UID_KEY "self-contact-uid"
 
@@ -2031,6 +2229,15 @@ e_book_client_get_contact (EBookClient *client,
 
 	g_return_if_fail (uid != NULL);
 
+	if (client->priv->direct_book) {
+		PropagateReadyData *data = propagate_ready_data_new (client, callback, user_data,
+								     e_book_client_get_contact, NULL);
+
+		e_data_book_get_contact (client->priv->direct_book, uid, cancellable,
+					 propagate_direct_book_async_ready, data);
+		return;
+	}
+
 	safe_uid = e_util_ensure_gdbus_string (uid, &gdbus_uid);
 	g_return_if_fail (safe_uid != NULL);
 
@@ -2072,6 +2279,12 @@ e_book_client_get_contact_finish (EBookClient *client,
 
 	g_return_val_if_fail (contact != NULL, FALSE);
 
+	if (client->priv->direct_book) {
+		GAsyncResult *res = g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (result));
+
+		return e_data_book_get_contact_finish (client->priv->direct_book, res, contact, error);
+	}
+
 	res = e_client_proxy_call_finish_string (
 		E_CLIENT (client),
 		result, &vcard, error,
@@ -2118,6 +2331,9 @@ e_book_client_get_contact_sync (EBookClient *client,
 	g_return_val_if_fail (uid != NULL, FALSE);
 	g_return_val_if_fail (contact != NULL, FALSE);
 
+	if (client->priv->direct_book)
+		return e_data_book_get_contact_sync (client->priv->direct_book, uid, contact, cancellable, error);
+
 	if (client->priv->dbus_proxy == NULL) {
 		set_proxy_gone_error (error);
 		return FALSE;
@@ -2170,6 +2386,15 @@ e_book_client_get_contacts (EBookClient *client,
 
 	g_return_if_fail (sexp != NULL);
 
+	if (client->priv->direct_book) {
+		PropagateReadyData *data = propagate_ready_data_new (client, callback, user_data,
+								     e_book_client_get_contacts, NULL);
+
+		e_data_book_get_contacts (client->priv->direct_book, sexp, cancellable, 
+					  propagate_direct_book_async_ready, data);
+		return;
+	}
+
 	e_client_proxy_call_string (
 		E_CLIENT (client),
 		e_util_ensure_gdbus_string (sexp, &gdbus_sexp),
@@ -2209,6 +2434,14 @@ e_book_client_get_contacts_finish (EBookClient *client,
 
 	g_return_val_if_fail (contacts != NULL, FALSE);
 
+	if (client->priv->direct_book) {
+		GAsyncResult *direct_res =
+			g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (result));
+
+		return e_data_book_get_contacts_finish (client->priv->direct_book,
+							direct_res, contacts, error);
+	}
+
 	res = e_client_proxy_call_finish_strv (
 		E_CLIENT (client),
 		result, &vcards, error,
@@ -2266,6 +2499,10 @@ e_book_client_get_contacts_sync (EBookClient *client,
 	g_return_val_if_fail (sexp != NULL, FALSE);
 	g_return_val_if_fail (contacts != NULL, FALSE);
 
+	if (client->priv->direct_book)
+		return e_data_book_get_contacts_sync (client->priv->direct_book,
+						      sexp, contacts, cancellable, error);
+
 	if (client->priv->dbus_proxy == NULL) {
 		set_proxy_gone_error (error);
 		return FALSE;
@@ -2324,6 +2561,15 @@ e_book_client_get_contacts_uids (EBookClient *client,
 
 	g_return_if_fail (sexp != NULL);
 
+	if (client->priv->direct_book) {
+		PropagateReadyData *data = propagate_ready_data_new (client, callback, user_data,
+								     e_book_client_get_contacts_uids, NULL);
+
+		e_data_book_get_contacts_uids (client->priv->direct_book, sexp, cancellable, 
+					       propagate_direct_book_async_ready, data);
+		return;
+	}
+
 	e_client_proxy_call_string (
 		E_CLIENT (client),
 		e_util_ensure_gdbus_string (sexp, &gdbus_sexp),
@@ -2363,6 +2609,14 @@ e_book_client_get_contacts_uids_finish (EBookClient *client,
 
 	g_return_val_if_fail (contacts_uids != NULL, FALSE);
 
+	if (client->priv->direct_book) {
+		GAsyncResult *direct_res =
+			g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (result));
+
+		return e_data_book_get_contacts_uids_finish (client->priv->direct_book,
+							     direct_res, contacts_uids, error);
+	}
+
 	res = e_client_proxy_call_finish_strv (
 		E_CLIENT (client),
 		result, &uids, error,
@@ -2420,6 +2674,9 @@ e_book_client_get_contacts_uids_sync (EBookClient *client,
 	g_return_val_if_fail (sexp != NULL, FALSE);
 	g_return_val_if_fail (contacts_uids != NULL, FALSE);
 
+	if (client->priv->direct_book)
+		return e_data_book_get_contacts_uids_sync (client->priv->direct_book, sexp, contacts_uids, cancellable, error);
+
 	if (client->priv->dbus_proxy == NULL) {
 		set_proxy_gone_error (error);
 		return FALSE;
diff --git a/addressbook/libebook/e-book-client.h b/addressbook/libebook/e-book-client.h
index 26da1d6..085fbf3 100644
--- a/addressbook/libebook/e-book-client.h
+++ b/addressbook/libebook/e-book-client.h
@@ -27,9 +27,9 @@
 #define E_BOOK_CLIENT_H
 
 #include <libedataserver/libedataserver.h>
+#include <libebook-contacts/libebook-contacts.h>
 
 #include <libebook/e-book-client-view.h>
-#include <libebook/e-contact.h>
 
 /* Standard GObject macros */
 #define E_TYPE_BOOK_CLIENT \
@@ -123,6 +123,9 @@ GError *	e_book_client_error_create	(EBookClientError code,
 GType		e_book_client_get_type		(void) G_GNUC_CONST;
 EBookClient *	e_book_client_new		(ESource *source,
 						 GError **error);
+EBookClient *   e_book_client_new_direct        (ESourceRegistry *registry,
+						 ESource *source,
+						 GError **error);
 gboolean	e_book_client_get_self		(ESourceRegistry *registry,
 						 EContact **contact,
 						 EBookClient **client,
diff --git a/addressbook/libebook/e-book-types.h b/addressbook/libebook/e-book-types.h
index f7d896f..0ba8067 100644
--- a/addressbook/libebook/e-book-types.h
+++ b/addressbook/libebook/e-book-types.h
@@ -16,7 +16,7 @@
 #ifndef __E_BOOK_TYPES_H__
 #define __E_BOOK_TYPES_H__
 
-#include <libebook/e-contact.h>
+#include <libebook-contacts/libebook-contacts.h>
 
 G_BEGIN_DECLS
 
@@ -52,80 +52,9 @@ typedef enum {
 	E_BOOK_ERROR_NOT_SUPPORTED
 } EBookStatus;
 
-/**
- * EDataBookStatus:
- *
- * XXX Document me!
- *
- * Since: 3.6
- **/
-typedef enum {
-	E_DATA_BOOK_STATUS_SUCCESS,
-	E_DATA_BOOK_STATUS_BUSY,
-	E_DATA_BOOK_STATUS_REPOSITORY_OFFLINE,
-	E_DATA_BOOK_STATUS_PERMISSION_DENIED,
-	E_DATA_BOOK_STATUS_CONTACT_NOT_FOUND,
-	E_DATA_BOOK_STATUS_CONTACTID_ALREADY_EXISTS,
-	E_DATA_BOOK_STATUS_AUTHENTICATION_FAILED,
-	E_DATA_BOOK_STATUS_AUTHENTICATION_REQUIRED,
-	E_DATA_BOOK_STATUS_UNSUPPORTED_FIELD,
-	E_DATA_BOOK_STATUS_UNSUPPORTED_AUTHENTICATION_METHOD,
-	E_DATA_BOOK_STATUS_TLS_NOT_AVAILABLE,
-	E_DATA_BOOK_STATUS_NO_SUCH_BOOK,
-	E_DATA_BOOK_STATUS_BOOK_REMOVED,
-	E_DATA_BOOK_STATUS_OFFLINE_UNAVAILABLE,
-	E_DATA_BOOK_STATUS_SEARCH_SIZE_LIMIT_EXCEEDED,
-	E_DATA_BOOK_STATUS_SEARCH_TIME_LIMIT_EXCEEDED,
-	E_DATA_BOOK_STATUS_INVALID_QUERY,
-	E_DATA_BOOK_STATUS_QUERY_REFUSED,
-	E_DATA_BOOK_STATUS_COULD_NOT_CANCEL,
-	E_DATA_BOOK_STATUS_OTHER_ERROR,
-	E_DATA_BOOK_STATUS_INVALID_SERVER_VERSION,
-	E_DATA_BOOK_STATUS_NO_SPACE,
-	E_DATA_BOOK_STATUS_INVALID_ARG,
-	E_DATA_BOOK_STATUS_NOT_SUPPORTED,
-	E_DATA_BOOK_STATUS_NOT_OPENED,
-	E_DATA_BOOK_STATUS_OUT_OF_SYNC
-} EDataBookStatus;
-
-#ifndef EDS_DISABLE_DEPRECATED
+#ifndef E_BOOK_DISABLE_DEPRECATED
 #define E_BOOK_ERROR_CORBA_EXCEPTION E_BOOK_ERROR_DBUS_EXCEPTION
 #endif
 
-typedef enum {
-	E_BOOK_VIEW_STATUS_OK,
-	E_BOOK_VIEW_STATUS_TIME_LIMIT_EXCEEDED,
-	E_BOOK_VIEW_STATUS_SIZE_LIMIT_EXCEEDED,
-	E_BOOK_VIEW_ERROR_INVALID_QUERY,
-	E_BOOK_VIEW_ERROR_QUERY_REFUSED,
-	E_BOOK_VIEW_ERROR_OTHER_ERROR
-} EBookViewStatus;
-
-typedef enum {
-	E_BOOK_CHANGE_CARD_ADDED,
-	E_BOOK_CHANGE_CARD_DELETED,
-	E_BOOK_CHANGE_CARD_MODIFIED
-} EBookChangeType;
-
-typedef struct {
-	EBookChangeType  change_type;
-	EContact        *contact;
-} EBookChange;
-
-/**
- * EBookIndexType:
- * @E_BOOK_INDEX_PREFIX: An index suitable for searching contacts with a prefix pattern
- * @E_BOOK_INDEX_SUFFIX: An index suitable for searching contacts with a suffix pattern
- *
- * The type of index defined for e_source_backend_summary_setup_set_indexed_fields()
- *
- * Since: 3.8
- */
-typedef enum {
-	E_BOOK_INDEX_PREFIX = 0,
-	E_BOOK_INDEX_SUFFIX
-} EBookIndexType;
-
-G_END_DECLS
 
 #endif /* __E_BOOK_TYPES_H__ */
diff --git a/addressbook/libebook/e-book.c b/addressbook/libebook/e-book.c
index 3f7af4a..8829778 100644
--- a/addressbook/libebook/e-book.c
+++ b/addressbook/libebook/e-book.c
@@ -40,8 +40,6 @@
 #include <glib/gi18n-lib.h>
 #include "e-book.h"
 #include "e-error.h"
-#include "e-contact.h"
-#include "e-name-western.h"
 #include "e-book-view-private.h"
 #include "e-book-marshal.h"
 
diff --git a/addressbook/libebook/e-book.h b/addressbook/libebook/e-book.h
index 91d12e8..868d07b 100644
--- a/addressbook/libebook/e-book.h
+++ b/addressbook/libebook/e-book.h
@@ -21,9 +21,8 @@
 #define __E_BOOK_H__
 
 #include <libedataserver/libedataserver.h>
+#include <libebook-contacts/libebook-contacts.h>
 
-#include <libebook/e-contact.h>
-#include <libebook/e-book-query.h>
 #include <libebook/e-book-view.h>
 #include <libebook/e-book-types.h>
 
diff --git a/addressbook/libebook/e-destination.h b/addressbook/libebook/e-destination.h
index 7cb65c5..7526037 100644
--- a/addressbook/libebook/e-destination.h
+++ b/addressbook/libebook/e-destination.h
@@ -32,8 +32,8 @@
 #ifndef __E_DESTINATION_H__
 #define __E_DESTINATION_H__
 
+#include <libebook-contacts/libebook-contacts.h>
 #include <libebook/e-book.h>
-#include <libebook/e-contact.h>
 #include <libebook/e-book-client.h>
 #include <libxml/tree.h>
 
diff --git a/addressbook/libebook/libebook.h b/addressbook/libebook/libebook.h
index b1ddffc..ae1ad0e 100644
--- a/addressbook/libebook/libebook.h
+++ b/addressbook/libebook/libebook.h
@@ -22,20 +22,15 @@
 #define __LIBEBOOK_H_INSIDE__
 
 #include <libedataserver/libedataserver.h>
+#include <libebook-contacts/libebook-contacts.h>
 
-#include <libebook/e-address-western.h>
 #include <libebook/e-book-client-view.h>
 #include <libebook/e-book-client.h>
 #include <libebook/e-book-enumtypes.h>
-#include <libebook/e-book-query.h>
 #include <libebook/e-book-types.h>
 #include <libebook/e-book-view.h>
 #include <libebook/e-book.h>
-#include <libebook/e-contact.h>
 #include <libebook/e-destination.h>
-#include <libebook/e-name-western.h>
-#include <libebook/e-source-backend-summary-setup.h>
-#include <libebook/e-vcard.h>
 
 #undef __LIBEBOOK_H_INSIDE__
 
diff --git a/addressbook/libebook/libebook.pc.in b/addressbook/libebook/libebook.pc.in
index 993870b..81b5afd 100644
--- a/addressbook/libebook/libebook.pc.in
+++ b/addressbook/libebook/libebook.pc.in
@@ -10,7 +10,7 @@ privincludedir= privincludedir@
 Name: libebook
 Description: Client library for evolution address books
 Version: @VERSION@
-Requires: libedataserver-1.2
+Requires: libedataserver-1.2 libebook-contacts-1.2
 Requires.private: camel-1.2
 Libs: -L${libdir} -lebook-1.2
 Cflags: -I${privincludedir}
diff --git a/addressbook/libedata-book/Makefile.am b/addressbook/libedata-book/Makefile.am
index 8c422b3..fa3ab00 100644
--- a/addressbook/libedata-book/Makefile.am
+++ b/addressbook/libedata-book/Makefile.am
@@ -30,10 +30,11 @@ libedata_book_1_2_la_SOURCES = \
 	e-data-book.c \
 	e-data-book-factory.c \
 	e-data-book-view.c \
+	e-data-book-direct.c \
 	ximian-vcard.h
 
 libedata_book_1_2_la_LIBADD = \
-	$(top_builddir)/addressbook/libebook/libebook-1.2.la \
+	$(top_builddir)/addressbook/libebook-contacts/libebook-contacts-1.2.la \
 	$(top_builddir)/addressbook/libegdbus/libegdbus-book.la \
 	$(top_builddir)/libedataserver/libedataserver-1.2.la \
 	$(top_builddir)/libebackend/libebackend-1.2.la \
@@ -58,6 +59,7 @@ libedata_bookinclude_HEADERS = \
 	e-book-backend.h \
 	e-data-book-factory.h \
 	e-data-book-view.h \
+	e-data-book-direct.h \
 	e-data-book.h \
 	e-book-backend-cache.h \
 	e-book-backend-sqlitedb.h \
diff --git a/addressbook/libedata-book/e-book-backend-cache.h b/addressbook/libedata-book/e-book-backend-cache.h
index 35b3d0f..ed0163a 100644
--- a/addressbook/libedata-book/e-book-backend-cache.h
+++ b/addressbook/libedata-book/e-book-backend-cache.h
@@ -27,7 +27,7 @@
 #ifndef E_BOOK_BACKEND_CACHE_H
 #define E_BOOK_BACKEND_CACHE_H
 
-#include <libebook/libebook.h>
+#include <libebook-contacts/libebook-contacts.h>
 #include <libebackend/libebackend.h>
 
 /* Standard GObject macros */
diff --git a/addressbook/libedata-book/e-book-backend-db-cache.h b/addressbook/libedata-book/e-book-backend-db-cache.h
index b26e5f1..41c47fb 100644
--- a/addressbook/libedata-book/e-book-backend-db-cache.h
+++ b/addressbook/libedata-book/e-book-backend-db-cache.h
@@ -26,7 +26,7 @@
 #ifndef E_BOOK_BACKEND_DB_CACHE_H
 #define E_BOOK_BACKEND_DB_CACHE_H
 
-#include <libebook/libebook.h>
+#include <libebook-contacts/libebook-contacts.h>
 
 G_BEGIN_DECLS
 
diff --git a/addressbook/libedata-book/e-book-backend-sexp.h b/addressbook/libedata-book/e-book-backend-sexp.h
index cf98bbf..9f58207 100644
--- a/addressbook/libedata-book/e-book-backend-sexp.h
+++ b/addressbook/libedata-book/e-book-backend-sexp.h
@@ -28,7 +28,7 @@
 #ifndef E_BOOK_BACKEND_SEXP_H
 #define E_BOOK_BACKEND_SEXP_H
 
-#include <libebook/libebook.h>
+#include <libebook-contacts/libebook-contacts.h>
 
 /* Standard GObject macros */
 #define E_TYPE_BOOK_BACKEND_SEXP \
diff --git a/addressbook/libedata-book/e-book-backend-sqlitedb-test.c b/addressbook/libedata-book/e-book-backend-sqlitedb-test.c
index 1d26528..68e3b19 100644
--- a/addressbook/libedata-book/e-book-backend-sqlitedb-test.c
+++ b/addressbook/libedata-book/e-book-backend-sqlitedb-test.c
@@ -20,7 +20,7 @@
  */
 
 #include <config.h>
-#include <libebook/libebook.h>
+#include <libebook-contacts/libebook-contacts.h>
 #include "e-book-backend-sqlitedb.h"
 
 static GMainLoop *main_loop;
diff --git a/addressbook/libedata-book/e-book-backend-sqlitedb.c b/addressbook/libedata-book/e-book-backend-sqlitedb.c
index 1382de6..0531c9d 100644
--- a/addressbook/libedata-book/e-book-backend-sqlitedb.c
+++ b/addressbook/libedata-book/e-book-backend-sqlitedb.c
@@ -991,6 +991,10 @@ book_backend_sqlitedb_load (EBookBackendSqliteDB *ebsdb,
 		ebsdb->priv->db,
 		"PRAGMA case_sensitive_like = ON",
 		NULL, NULL, NULL);
+	book_backend_sql_exec (
+		ebsdb->priv->db,
+	        "PRAGMA journal_mode = WAL",
+		NULL, NULL, NULL);
 
 	WRITER_UNLOCK (ebsdb);
 
diff --git a/addressbook/libedata-book/e-book-backend-sqlitedb.h b/addressbook/libedata-book/e-book-backend-sqlitedb.h
index cfc33e6..a451415 100644
--- a/addressbook/libedata-book/e-book-backend-sqlitedb.h
+++ b/addressbook/libedata-book/e-book-backend-sqlitedb.h
@@ -26,7 +26,7 @@
 #ifndef E_BOOK_BACKEND_SQLITEDB_H
 #define E_BOOK_BACKEND_SQLITEDB_H
 
-#include <libebook/libebook.h>
+#include <libebook-contacts/libebook-contacts.h>
 
 /* Standard GObject macros */
 #define E_TYPE_BOOK_BACKEND_SQLITEDB \
diff --git a/addressbook/libedata-book/e-book-backend-summary.h b/addressbook/libedata-book/e-book-backend-summary.h
index c914616..b229d19 100644
--- a/addressbook/libedata-book/e-book-backend-summary.h
+++ b/addressbook/libedata-book/e-book-backend-summary.h
@@ -28,7 +28,7 @@
 #ifndef E_BOOK_BACKEND_SUMMARY_H
 #define E_BOOK_BACKEND_SUMMARY_H
 
-#include <libebook/libebook.h>
+#include <libebook-contacts/libebook-contacts.h>
 
 /* Standard GObject macros */
 #define E_TYPE_BOOK_BACKEND_SUMMARY \
diff --git a/addressbook/libedata-book/e-book-backend.c b/addressbook/libedata-book/e-book-backend.c
index 5c6525f..5f8ca21 100644
--- a/addressbook/libedata-book/e-book-backend.c
+++ b/addressbook/libedata-book/e-book-backend.c
@@ -1056,6 +1056,54 @@ e_book_backend_set_is_removed (EBookBackend *backend,
 }
 
 /**
+ * e_book_backend_get_direct_book:
+ * @backend: an #EBookBackend
+ *
+ * Tries to create an #EDataBookDirect for @backend if
+ * backend supports direct read access.
+ *
+ * Returns: (transfer full): A new #EDataBookDirect object, or %NULL if @backend does not support direct access
+ *
+ * Since: 3.8
+ */
+EDataBookDirect *
+e_book_backend_get_direct_book (EBookBackend *backend)
+{
+	g_return_val_if_fail (E_IS_BOOK_BACKEND (backend), NULL);
+
+	if (E_BOOK_BACKEND_GET_CLASS (backend)->get_direct_book)
+		return E_BOOK_BACKEND_GET_CLASS (backend)->get_direct_book (backend);
+
+	return NULL;
+}
+
+/**
+ * e_book_backend_configure_direct:
+ * @backend: an #EBookBackend
+ * @config: The configuration string for the given backend
+ *
+ * This method is called on @backend in direct read access mode.
+ * The @config argument is the same configuration string which
+ * the same backend reported in the #EDataBookDirect returned
+ * by e_book_backend_get_direct_book().
+ *
+ * The configuration string is optional and is used to ensure
+ * that direct access backends are properly configured to
+ * interface with the same data as the running server side backend.
+ *
+ * Since: 3.8
+ */
+void
+e_book_backend_configure_direct (EBookBackend *backend,
+				 const gchar *config)
+{
+	g_return_if_fail (E_IS_BOOK_BACKEND (backend));
+
+	if (E_BOOK_BACKEND_GET_CLASS (backend)->configure_direct)
+		E_BOOK_BACKEND_GET_CLASS (backend)->configure_direct (backend, config);
+}
+
+/**
  * e_book_backend_sync:
  * @backend: an #EBookbackend
  *
diff --git a/addressbook/libedata-book/e-book-backend.h b/addressbook/libedata-book/e-book-backend.h
index cafa765..100c8c7 100644
--- a/addressbook/libedata-book/e-book-backend.h
+++ b/addressbook/libedata-book/e-book-backend.h
@@ -26,11 +26,12 @@
 #ifndef E_BOOK_BACKEND_H
 #define E_BOOK_BACKEND_H
 
-#include <libebook/libebook.h>
+#include <libebook-contacts/libebook-contacts.h>
 #include <libebackend/libebackend.h>
 
 #include <libedata-book/e-data-book.h>
 #include <libedata-book/e-data-book-view.h>
+#include <libedata-book/e-data-book-direct.h>
 
 /* Standard GObject macros */
 #define E_TYPE_BOOK_BACKEND \
@@ -211,6 +212,11 @@ struct _EBookBackendClass {
 	void		(*notify_update)	(EBookBackend *backend,
 						 const EContact *contact);
 
+
+	EDataBookDirect *
+	        (* get_direct_book)             (EBookBackend *backend);
+	void    (* configure_direct)            (EBookBackend *backend, const gchar *config);
+
 	/* Notification signals */
 	void		(*sync)			(EBookBackend *backend);
 };
@@ -317,6 +323,10 @@ void		e_book_backend_notify_property_changed
 						 const gchar *prop_name,
 						 const gchar *prop_value);
 
+EDataBookDirect *
+                e_book_backend_get_direct_book  (EBookBackend *backend);
+void            e_book_backend_configure_direct (EBookBackend *backend, const gchar *config);
+
 void		e_book_backend_sync		(EBookBackend *backend);
 
 /* protected functions for subclasses */
diff --git a/addressbook/libedata-book/e-data-book-direct.c b/addressbook/libedata-book/e-data-book-direct.c
new file mode 100644
index 0000000..dcedf86
--- /dev/null
+++ b/addressbook/libedata-book/e-data-book-direct.c
@@ -0,0 +1,132 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 2012 Intel Corporation
+ *
+ * This program 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; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program 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 the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ * Author: Tristan Van Berkom <tristanvb openismus com>
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <string.h>
+
+#include "e-data-book-direct.h"
+#include "e-gdbus-book-direct.h"
+
+#define E_DATA_BOOK_DIRECT_GET_PRIVATE(obj) \
+	(G_TYPE_INSTANCE_GET_PRIVATE \
+	((obj), E_TYPE_DATA_BOOK_DIRECT, EDataBookDirectPrivate))
+
+G_DEFINE_TYPE (EDataBookDirect, e_data_book_direct, G_TYPE_OBJECT);
+#define THRESHOLD_ITEMS   32	/* how many items can be hold in a cache, before propagated to UI */
+#define THRESHOLD_SECONDS  2	/* how long to wait until notifications are propagated to UI; in seconds */
+
+struct _EDataBookDirectPrivate {
+	EGdbusBookDirect *gdbus_object;
+};
+
+/* GObjectClass */
+static void
+e_data_book_direct_dispose (GObject *object)
+{
+	EDataBookDirect *direct = E_DATA_BOOK_DIRECT (object);
+
+	if (direct->priv->gdbus_object) {
+		g_dbus_interface_skeleton_unexport (G_DBUS_INTERFACE_SKELETON (direct->priv->gdbus_object));
+		g_object_unref (direct->priv->gdbus_object);
+		direct->priv->gdbus_object = NULL;
+	}
+
+	G_OBJECT_CLASS (e_data_book_direct_parent_class)->dispose (object);
+}
+
+static void
+e_data_book_direct_init (EDataBookDirect *direct)
+{
+	direct->priv = E_DATA_BOOK_DIRECT_GET_PRIVATE (direct);
+	direct->priv->gdbus_object = e_gdbus_book_direct_skeleton_new ();
+}
+
+static void
+e_data_book_direct_class_init (EDataBookDirectClass *class)
+{
+	GObjectClass *object_class = G_OBJECT_CLASS (class);
+
+	g_type_class_add_private (class, sizeof (EDataBookDirectPrivate));
+
+	object_class->dispose = e_data_book_direct_dispose;
+}
+
+/**
+ * e_data_book_direct_new:
+ * @backend_path: Full path to the installed backend shared library
+ * @backend_factory_name: Type name of the EBookBackendFactory implemented by the library
+ * @config: A backend specific configuration string
+ *
+ * Creates a #EDataBookDirect to report configuration data needed for direct
+ * read access.
+ *
+ * This is returned by e_book_backend_get_direct_book() for backends
+ * which support direct read access mode.
+ *
+ * Returns: (transfer full): A newly created #EDataBookDirect
+ *
+ * Since: 3.8
+ */
+EDataBookDirect *
+e_data_book_direct_new (const gchar *backend_path,
+			const gchar *backend_factory_name,
+			const gchar *config)
+{
+	EDataBookDirect *direct;
+
+	g_return_val_if_fail (backend_path && backend_path[0], NULL);
+	g_return_val_if_fail (backend_factory_name && backend_factory_name[0], NULL);
+
+	direct = g_object_new (E_TYPE_DATA_BOOK_DIRECT, NULL);
+
+	e_gdbus_book_direct_set_backend_path (direct->priv->gdbus_object, backend_path);
+	e_gdbus_book_direct_set_backend_name (direct->priv->gdbus_object, backend_factory_name);
+	e_gdbus_book_direct_set_backend_config (direct->priv->gdbus_object, config);
+
+	return direct;
+}
+
+/**
+ * e_data_book_direct_register_gdbus_object:
+ * @direct: An #EDataBookDirect
+ * @connection: The #GDBusConnection to register with
+ * @object_path: The object path to place the direct access configuration data
+ * @error: A location to store any error which might occur while registering
+ *
+ * Places @direct on the @connection at @object_path
+ *
+ * Since: 3.8
+ **/
+gboolean
+e_data_book_direct_register_gdbus_object (EDataBookDirect *direct,
+					  GDBusConnection *connection,
+					  const gchar *object_path,
+					  GError **error)
+{
+	g_return_val_if_fail (E_IS_DATA_BOOK_DIRECT (direct), FALSE);
+	g_return_val_if_fail (connection != NULL, FALSE);
+	g_return_val_if_fail (object_path != NULL, 0);
+
+	return g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (direct->priv->gdbus_object),
+						 connection, object_path, error);
+}
diff --git a/addressbook/libedata-book/e-data-book-direct.h b/addressbook/libedata-book/e-data-book-direct.h
new file mode 100644
index 0000000..11e3ee8
--- /dev/null
+++ b/addressbook/libedata-book/e-data-book-direct.h
@@ -0,0 +1,64 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 2012 Intel Corporation
+ *
+ * This program 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; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program 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 the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ * Author: 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_DATA_BOOK_DIRECT_H__
+#define __E_DATA_BOOK_DIRECT_H__
+
+#include <gio/gio.h>
+
+G_BEGIN_DECLS
+
+#define E_TYPE_DATA_BOOK_DIRECT        (e_data_book_direct_get_type ())
+#define E_DATA_BOOK_DIRECT(o)          (G_TYPE_CHECK_INSTANCE_CAST ((o), E_TYPE_DATA_BOOK_DIRECT, EDataBookDirect))
+#define E_DATA_BOOK_DIRECT_CLASS(k)    (G_TYPE_CHECK_CLASS_CAST((k), E_TYPE_DATA_BOOK_DIRECT, EDataBookDirectClass))
+#define E_IS_DATA_BOOK_DIRECT(o)       (G_TYPE_CHECK_INSTANCE_TYPE ((o), E_TYPE_DATA_BOOK_DIRECT))
+#define E_IS_DATA_BOOK_DIRECT_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), E_TYPE_DATA_BOOK_DIRECT))
+#define E_DATA_BOOK_DIRECT_GET_CLASS(k) (G_TYPE_INSTANCE_GET_CLASS ((obj), E_TYPE_DATA_BOOK_DIRECT, EDataBookDirect))
+
+typedef struct _EDataBookDirect EDataBookDirect;
+typedef struct _EDataBookDirectClass EDataBookDirectClass;
+typedef struct _EDataBookDirectPrivate EDataBookDirectPrivate;
+
+struct _EDataBookDirect {
+	GObject parent;
+	EDataBookDirectPrivate *priv;
+};
+
+struct _EDataBookDirectClass {
+	GObjectClass parent;
+};
+
+GType			e_data_book_direct_get_type		 (void);
+EDataBookDirect *	e_data_book_direct_new			 (const gchar *backend_path,
+								  const gchar *backend_factory_name,
+								  const gchar *config);
+
+gboolean                e_data_book_direct_register_gdbus_object (EDataBookDirect *direct,
+								  GDBusConnection *connection,
+								  const gchar *object_path,
+								  GError **error);
+
+G_END_DECLS
+
+#endif /* __E_DATA_BOOK_DIRECT_H__ */
diff --git a/addressbook/libedata-book/e-data-book-view.h b/addressbook/libedata-book/e-data-book-view.h
index 5cda7ca..fe626e5 100644
--- a/addressbook/libedata-book/e-data-book-view.h
+++ b/addressbook/libedata-book/e-data-book-view.h
@@ -28,7 +28,7 @@
 #ifndef E_DATA_BOOK_VIEW_H
 #define E_DATA_BOOK_VIEW_H
 
-#include <libebook/libebook.h>
+#include <libebook-contacts/libebook-contacts.h>
 
 #include <libedata-book/e-book-backend-sexp.h>
 
diff --git a/addressbook/libedata-book/e-data-book.c b/addressbook/libedata-book/e-data-book.c
index 3e517c3..708680f 100644
--- a/addressbook/libedata-book/e-data-book.c
+++ b/addressbook/libedata-book/e-data-book.c
@@ -25,12 +25,13 @@
 #include <glib/gi18n.h>
 #include <gio/gio.h>
 
-#include <libebook/libebook.h>
+#include <libebook-contacts/libebook-contacts.h>
 
 #include "e-data-book-factory.h"
 #include "e-data-book.h"
 #include "e-data-book-view.h"
 #include "e-book-backend.h"
+#include "e-book-backend-factory.h"
 #include "e-book-backend-sexp.h"
 
 #include "e-gdbus-book.h"
@@ -42,11 +43,15 @@
 struct _EDataBookPrivate {
 	GDBusConnection *connection;
 	EGdbusBook *dbus_interface;
+	EModule *direct_module;
+	EDataBookDirect *direct_book;
+
 	EBookBackend *backend;
 	gchar *object_path;
 
 	GRecMutex pending_ops_lock;
 	GHashTable *pending_ops; /* opid to GCancellable for still running operations */
+	GHashTable *direct_ops; /* opid to DirectOperationData for still running operations */
 };
 
 enum {
@@ -111,8 +116,41 @@ typedef struct {
 	} d;
 } OperationData;
 
+typedef struct {
+	GAsyncReadyCallback callback;
+	gpointer            user_data;
+	GCancellable       *cancellable;
+	GSimpleAsyncResult *result;
+
+	gboolean            is_sync_call;
+	gboolean            sync_call_complete;
+	GMutex              sync_result_mutex;
+	GCond               sync_result_condition;
+} DirectOperationData;
+
+/* EModule's can never be free'd, however the use count can change
+ * Here we ensure that there is only one ever created by way of
+ * static variables and locks
+ */
+static GHashTable *modules_table = NULL;
+G_LOCK_DEFINE (modules_table);
+
+
 /* Forward Declarations */
-static void	e_data_book_initable_init	(GInitableIface *interface);
+static void                 e_data_book_initable_init  (GInitableIface *interface);
+static DirectOperationData *direct_operation_data_push (EDataBook          *book,
+							OperationID         opid,
+							GAsyncReadyCallback callback,
+							gpointer            user_data,
+							GCancellable       *cancellable,
+							gpointer            source_tag,
+							gboolean            sync_call);
+static void                 direct_operation_data_free (DirectOperationData *data);
+static void                 direct_operation_complete  (DirectOperationData *data);
+static void                 direct_operation_wait      (DirectOperationData *data);
+static void                 e_data_book_respond_close  (EDataBook *book,
+							guint opid,
+							GError *error);
 
 G_DEFINE_TYPE_WITH_CODE (
 	EDataBook,
@@ -122,6 +160,108 @@ G_DEFINE_TYPE_WITH_CODE (
 		G_TYPE_INITABLE,
 		e_data_book_initable_init))
 
+static EModule *
+load_module (const gchar *module_path)
+{
+	EModule *module = NULL;
+
+	G_LOCK (modules_table);
+
+	if (!modules_table)
+		modules_table = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
+
+	module = g_hash_table_lookup (modules_table, module_path);
+
+	if (!module) {
+		module = e_module_new (module_path);
+		if (!module)
+			g_warning ("Failed to open EModule at path: %s", module_path);
+		else
+			g_hash_table_insert (modules_table, g_strdup (module_path), module);
+	}
+
+	G_UNLOCK (modules_table);
+
+	return module;
+}
+
+static DirectOperationData *
+direct_operation_data_push (EDataBook          *book,
+			    OperationID         opid,
+			    GAsyncReadyCallback callback,
+			    gpointer            user_data,
+			    GCancellable       *cancellable,
+			    gpointer            source_tag,
+			    gboolean            sync_call)
+{
+	DirectOperationData *data;
+
+	data = g_slice_new (DirectOperationData);
+	data->callback = callback;
+	data->user_data = user_data;
+	data->cancellable = g_object_ref (cancellable);
+	data->result = g_simple_async_result_new (G_OBJECT (book),
+						  data->callback,
+						  data->user_data,
+						  source_tag);
+	data->is_sync_call = sync_call;
+	data->sync_call_complete = FALSE;
+
+	if (data->is_sync_call) {
+		g_mutex_init (&data->sync_result_mutex);
+		g_cond_init (&data->sync_result_condition);
+	}
+
+	g_hash_table_insert (book->priv->direct_ops, GUINT_TO_POINTER (opid), data);
+
+	return data;
+}
+
+static void
+direct_operation_data_free (DirectOperationData *data)
+{
+	if (data) {
+		if (data->is_sync_call) {
+			g_mutex_clear (&data->sync_result_mutex);
+			g_cond_clear (&data->sync_result_condition);
+		}
+
+		g_object_unref (data->result);
+		g_object_unref (data->cancellable);
+		g_slice_free (DirectOperationData, data);
+	}
+}
+
+static void
+direct_operation_complete (DirectOperationData *data)
+{
+	/* If it was a sync call, we have the calling thread
+	 * waiting on the sync call condition, it's up to
+	 * the sync call to free the data with direct_operation_data_free().
+	 *
+	 * Otherwise for async calls we need to complete
+	 * in the calling thread.
+	 */
+	if (data->is_sync_call) {
+		g_mutex_lock (&data->sync_result_mutex);
+		data->sync_call_complete = TRUE;
+		g_cond_signal (&data->sync_result_condition);
+		g_mutex_unlock (&data->sync_result_mutex);
+	} else {
+		g_simple_async_result_complete_in_idle (data->result);
+		direct_operation_data_free (data);
+	}
+}
+
+static void
+direct_operation_wait (DirectOperationData *data)
+{
+	g_mutex_lock (&data->sync_result_mutex);
+	while (data->sync_call_complete == FALSE)
+		g_cond_wait (&data->sync_result_condition, &data->sync_result_mutex);
+	g_mutex_unlock (&data->sync_result_mutex);
+}
+
 static gchar *
 construct_bookview_path (void)
 {
@@ -257,6 +397,10 @@ operation_thread (gpointer data,
 	case OP_CLOSE:
 		/* close just cancels all pending ops and frees data book */
 		e_book_backend_remove_client (backend, op->book);
+
+		/* Let direct calls return, notify the direct callers that it's closed */
+		e_data_book_respond_close (op->book, op->id, NULL);
+
 	case OP_CANCEL_ALL:
 		g_rec_mutex_lock (&op->book->priv->pending_ops_lock);
 		g_hash_table_foreach (op->book->priv->pending_ops, cancel_ops_cb, NULL);
@@ -288,17 +432,59 @@ op_new (OperationID op,
 	return data;
 }
 
-static void
+static OperationData *
+op_direct_new (OperationID op,
+	       EDataBook *book,
+	       GCancellable *cancellable,
+	       GAsyncReadyCallback callback,
+	       gpointer user_data,
+	       gpointer source_tag,
+	       gboolean sync_call,
+	       DirectOperationData **ret_data)
+{
+	OperationData *data;
+	DirectOperationData *direct_data;
+
+	data = g_slice_new0 (OperationData);
+	data->op = op;
+	data->book = g_object_ref (book);
+	data->id = e_operation_pool_reserve_opid (ops_pool);
+
+	if (cancellable)
+		data->cancellable = g_object_ref (cancellable);
+	else
+		data->cancellable = g_cancellable_new ();
+
+	g_rec_mutex_lock (&book->priv->pending_ops_lock);
+	g_hash_table_insert (book->priv->pending_ops, GUINT_TO_POINTER (data->id), g_object_ref (data->cancellable));
+	direct_data = direct_operation_data_push (book, data->id, callback, user_data, data->cancellable, source_tag, sync_call);
+	g_rec_mutex_unlock (&book->priv->pending_ops_lock);
+
+	if (ret_data)
+		*ret_data = direct_data;
+
+	return data;
+}
+
+
+static DirectOperationData *
 op_complete (EDataBook *book,
              guint32 opid)
 {
-	g_return_if_fail (book != NULL);
+	DirectOperationData *direct_data;
+
+	g_return_val_if_fail (book != NULL, NULL);
 
 	e_operation_pool_release_opid (ops_pool, opid);
 
 	g_rec_mutex_lock (&book->priv->pending_ops_lock);
 	g_hash_table_remove (book->priv->pending_ops, GUINT_TO_POINTER (opid));
+	direct_data = g_hash_table_lookup (book->priv->direct_ops, GUINT_TO_POINTER (opid));
+	if (direct_data)
+		g_hash_table_steal (book->priv->direct_ops, GUINT_TO_POINTER (opid));
 	g_rec_mutex_unlock (&book->priv->pending_ops_lock);
+
+	return direct_data;
 }
 
 /**
@@ -793,12 +979,36 @@ e_data_book_respond_open (EDataBook *book,
                           guint opid,
                           GError *error)
 {
-	op_complete (book, opid);
+	DirectOperationData *data;
+
+	data = op_complete (book, opid);
 
 	/* Translators: This is prefix to a detailed error message */
 	g_prefix_error (&error, "%s", _("Cannot open book: "));
 
-	e_gdbus_book_emit_open_done (book->priv->dbus_interface, opid, error);
+	if (data) {
+		gboolean result = FALSE;
+
+		if (error)
+			g_simple_async_result_set_error (data->result,
+							 error->domain,
+							 error->code,
+							 "%s", error->message);
+
+		else {
+			g_simple_async_result_set_check_cancellable (data->result,
+								     data->cancellable);
+
+			if (!g_cancellable_is_cancelled (data->cancellable))
+				result = TRUE;
+		}
+
+		g_simple_async_result_set_op_res_gboolean (data->result, result);
+
+		/* Deliver the result to the caller */
+		direct_operation_complete (data);
+	} else
+		e_gdbus_book_emit_open_done (book->priv->dbus_interface, opid, error);
 
 	if (error)
 		g_error_free (error);
@@ -886,19 +1096,48 @@ e_data_book_respond_get_contact (EDataBook *book,
                                  GError *error,
                                  const gchar *vcard)
 {
-	gchar *gdbus_vcard = NULL;
+	DirectOperationData *data;
 
-	op_complete (book, opid);
+	data = op_complete (book, opid);
 
 	/* Translators: This is prefix to a detailed error message */
 	g_prefix_error (&error, "%s", _("Cannot get contact: "));
 
-	e_gdbus_book_emit_get_contact_done (book->priv->dbus_interface, opid, error, e_util_ensure_gdbus_string (vcard, &gdbus_vcard));
+	if (data) {
+
+		if (error) {
+			g_simple_async_result_set_error (data->result,
+							 error->domain,
+							 error->code,
+							 "%s", error->message);
+		} else {
+			g_simple_async_result_set_check_cancellable (data->result,
+								     data->cancellable);
+
+			if (!g_cancellable_is_cancelled (data->cancellable)) {
+				EContact *contact;
+
+				contact = e_contact_new_from_vcard (vcard);
+
+				/* Give it an EContact for the return value */
+				g_simple_async_result_set_op_res_gpointer (data->result, contact, g_object_unref);
+			}
+		}
+
+		/* Deliver the result to the caller */
+		direct_operation_complete (data);
+
+	} else {
+		gchar *gdbus_vcard = NULL;
+
+		e_gdbus_book_emit_get_contact_done (book->priv->dbus_interface, opid, error,
+						    e_util_ensure_gdbus_string (vcard, &gdbus_vcard));
+
+		g_free (gdbus_vcard);	
+	}
 
 	if (error)
 		g_error_free (error);
-
-	g_free (gdbus_vcard);
 }
 
 void
@@ -907,11 +1146,51 @@ e_data_book_respond_get_contact_list (EDataBook *book,
                                       GError *error,
                                       const GSList *cards)
 {
-	if (error) {
-		/* Translators: This is prefix to a detailed error message */
+	DirectOperationData *data;
+
+	/* Translators: This is prefix to a detailed error message */
+	if (error)
 		g_prefix_error (&error, "%s", _("Cannot get contact list: "));
+
+	data = op_complete (book, opid);
+
+	if (data) {
+
+		if (error) {
+			g_simple_async_result_set_error (data->result,
+							 error->domain,
+							 error->code,
+							 "%s", error->message);
+		} else {
+			g_simple_async_result_set_check_cancellable (data->result,
+								     data->cancellable);
+
+			if (!g_cancellable_is_cancelled (data->cancellable)) {
+				EContact *contact;
+				const GSList *l;
+				GSList *contacts = NULL;
+
+				for (l = cards; l; l = l->next) {
+					const gchar *vcard = l->data;
+
+					contact = e_contact_new_from_vcard (vcard);
+					contacts = g_slist_prepend (contacts, contact);
+				}
+
+				contacts = g_slist_reverse (contacts);
+
+				/* Give it an EContact for the return value */
+				g_simple_async_result_set_op_res_gpointer (data->result, contacts,
+									   (GDestroyNotify)e_util_free_object_slist);
+			}
+		}
+
+		/* Deliver the result to the caller */
+		direct_operation_complete (data);
+
+	} else if (error) {
+
 		e_gdbus_book_emit_get_contact_list_done (book->priv->dbus_interface, opid, error, NULL);
-		g_error_free (error);
 	} else {
 		gchar **array;
 		const GSList *l;
@@ -926,6 +1205,9 @@ e_data_book_respond_get_contact_list (EDataBook *book,
 
 		g_strfreev (array);
 	}
+
+	if (error)
+		g_error_free (error);
 }
 
 /**
@@ -941,11 +1223,41 @@ e_data_book_respond_get_contact_list_uids (EDataBook *book,
                                            GError *error,
                                            const GSList *uids)
 {
-	if (error) {
-		/* Translators: This is prefix to a detailed error message */
+	DirectOperationData *data;
+
+	/* Translators: This is prefix to a detailed error message */
+	if (error)
 		g_prefix_error (&error, "%s", _("Cannot get contact list uids: "));
+
+	data = op_complete (book, opid);
+
+	if (data) {
+
+		if (error) {
+			g_simple_async_result_set_error (data->result,
+							 error->domain,
+							 error->code,
+							 "%s", error->message);
+		} else {
+			g_simple_async_result_set_check_cancellable (data->result,
+								     data->cancellable);
+
+			if (!g_cancellable_is_cancelled (data->cancellable)) {
+				GSList *ret_uids = NULL;
+
+				ret_uids = e_util_copy_string_slist (NULL, uids);
+
+				g_simple_async_result_set_op_res_gpointer (data->result, ret_uids,
+									   (GDestroyNotify)e_util_free_string_slist);
+			}
+		}
+
+		/* Deliver the result to the caller */
+		direct_operation_complete (data);
+
+	} else if (error) {
+
 		e_gdbus_book_emit_get_contact_list_uids_done (book->priv->dbus_interface, opid, error, NULL);
-		g_error_free (error);
 	} else {
 		gchar **array;
 		const GSList *l;
@@ -960,6 +1272,10 @@ e_data_book_respond_get_contact_list_uids (EDataBook *book,
 
 		g_strfreev (array);
 	}
+
+	if (error)
+		g_error_free (error);
+
 }
 
 /**
@@ -1180,17 +1496,18 @@ static void
 data_book_set_connection (EDataBook *book,
                           GDBusConnection *connection)
 {
-	g_return_if_fail (G_IS_DBUS_CONNECTION (connection));
+	g_return_if_fail (connection == NULL ||
+			  G_IS_DBUS_CONNECTION (connection));
 	g_return_if_fail (book->priv->connection == NULL);
 
-	book->priv->connection = g_object_ref (connection);
+	if (connection)
+		book->priv->connection = g_object_ref (connection);
 }
 
 static void
 data_book_set_object_path (EDataBook *book,
                            const gchar *object_path)
 {
-	g_return_if_fail (object_path != NULL);
 	g_return_if_fail (book->priv->object_path == NULL);
 
 	book->priv->object_path = g_strdup (object_path);
@@ -1274,6 +1591,16 @@ data_book_dispose (GObject *object)
 		priv->backend = NULL;
 	}
 
+	if (priv->direct_book) {
+		g_object_unref (priv->direct_book);
+		priv->direct_book = NULL;
+	}
+
+	if (priv->direct_module) {
+		g_type_module_unuse (G_TYPE_MODULE (priv->direct_module));
+		priv->direct_module = NULL;
+	}
+
 	/* Chain up to parent's dispose() metnod. */
 	G_OBJECT_CLASS (e_data_book_parent_class)->dispose (object);
 }
@@ -1293,6 +1620,10 @@ data_book_finalize (GObject *object)
 	}
 
 	g_rec_mutex_clear (&priv->pending_ops_lock);
+	if (priv->direct_ops) {
+		g_hash_table_destroy (priv->direct_ops);
+		priv->direct_ops = NULL;
+	}
 
 	if (priv->dbus_interface) {
 		g_object_unref (priv->dbus_interface);
@@ -1312,11 +1643,74 @@ data_book_initable_init (GInitable *initable,
 
 	book = E_DATA_BOOK (initable);
 
-	return e_gdbus_book_register_object (
-		book->priv->dbus_interface,
-		book->priv->connection,
-		book->priv->object_path,
-		error);
+	if (book->priv->connection && book->priv->object_path) {
+		book->priv->dbus_interface = e_gdbus_book_stub_new ();
+
+		g_signal_connect (
+		        book->priv->dbus_interface, "handle-open",
+			G_CALLBACK (impl_Book_open), book);
+		g_signal_connect (
+		        book->priv->dbus_interface, "handle-refresh",
+			G_CALLBACK (impl_Book_refresh), book);
+		g_signal_connect (
+		        book->priv->dbus_interface, "handle-get-contact",
+			G_CALLBACK (impl_Book_get_contact), book);
+		g_signal_connect (
+			book->priv->dbus_interface, "handle-get-contact-list",
+			G_CALLBACK (impl_Book_get_contact_list), book);
+		g_signal_connect (
+		        book->priv->dbus_interface, "handle-get-contact-list-uids",
+			G_CALLBACK (impl_Book_get_contact_list_uids), book);
+		g_signal_connect (
+			book->priv->dbus_interface, "handle-add-contacts",
+			G_CALLBACK (impl_Book_add_contacts), book);
+		g_signal_connect (
+			book->priv->dbus_interface, "handle-remove-contacts",
+			G_CALLBACK (impl_Book_remove_contacts), book);
+		g_signal_connect (
+			book->priv->dbus_interface, "handle-modify-contacts",
+			G_CALLBACK (impl_Book_modify_contacts), book);
+		g_signal_connect (
+			book->priv->dbus_interface, "handle-get-backend-property",
+			G_CALLBACK (impl_Book_get_backend_property), book);
+		g_signal_connect (
+			book->priv->dbus_interface, "handle-set-backend-property",
+			G_CALLBACK (impl_Book_set_backend_property), book);
+		g_signal_connect (
+			book->priv->dbus_interface, "handle-get-view",
+			G_CALLBACK (impl_Book_get_view), book);
+		g_signal_connect (
+			book->priv->dbus_interface, "handle-cancel-operation",
+			G_CALLBACK (impl_Book_cancel_operation), book);
+		g_signal_connect (
+			book->priv->dbus_interface, "handle-cancel-all",
+			G_CALLBACK (impl_Book_cancel_all), book);
+		g_signal_connect (
+			book->priv->dbus_interface, "handle-close",
+			G_CALLBACK (impl_Book_close), book);
+
+		/* This will be NULL for a backend that does not support direct read access */
+		book->priv->direct_book =
+			e_book_backend_get_direct_book (book->priv->backend);
+
+		if (book->priv->direct_book) {
+
+			if (!e_data_book_direct_register_gdbus_object (
+			             book->priv->direct_book,
+				     book->priv->connection,
+				     book->priv->object_path,
+				     error))
+				return FALSE;
+		}
+
+		return e_gdbus_book_register_object (
+		               book->priv->dbus_interface,
+			       book->priv->connection,
+			       book->priv->object_path,
+			       error);
+	}
+
+	return TRUE;
 }
 
 static void
@@ -1383,58 +1777,14 @@ e_data_book_initable_init (GInitableIface *interface)
 static void
 e_data_book_init (EDataBook *ebook)
 {
-	EGdbusBook *dbus_interface;
-
 	ebook->priv = E_DATA_BOOK_GET_PRIVATE (ebook);
 
-	ebook->priv->dbus_interface = e_gdbus_book_stub_new ();
 	ebook->priv->pending_ops = g_hash_table_new_full (
 		g_direct_hash, g_direct_equal, NULL, g_object_unref);
+	ebook->priv->direct_ops = g_hash_table_new_full (
+	        g_direct_hash, g_direct_equal, NULL,
+		(GDestroyNotify)direct_operation_data_free);
 	g_rec_mutex_init (&ebook->priv->pending_ops_lock);
-
-	dbus_interface = ebook->priv->dbus_interface;
-	g_signal_connect (
-		dbus_interface, "handle-open",
-		G_CALLBACK (impl_Book_open), ebook);
-	g_signal_connect (
-		dbus_interface, "handle-refresh",
-		G_CALLBACK (impl_Book_refresh), ebook);
-	g_signal_connect (
-		dbus_interface, "handle-get-contact",
-		G_CALLBACK (impl_Book_get_contact), ebook);
-	g_signal_connect (
-		dbus_interface, "handle-get-contact-list",
-		G_CALLBACK (impl_Book_get_contact_list), ebook);
-	g_signal_connect (
-		dbus_interface, "handle-get-contact-list-uids",
-		G_CALLBACK (impl_Book_get_contact_list_uids), ebook);
-	g_signal_connect (
-		dbus_interface, "handle-add-contacts",
-		G_CALLBACK (impl_Book_add_contacts), ebook);
-	g_signal_connect (
-		dbus_interface, "handle-remove-contacts",
-		G_CALLBACK (impl_Book_remove_contacts), ebook);
-	g_signal_connect (
-		dbus_interface, "handle-modify-contacts",
-		G_CALLBACK (impl_Book_modify_contacts), ebook);
-	g_signal_connect (
-		dbus_interface, "handle-get-backend-property",
-		G_CALLBACK (impl_Book_get_backend_property), ebook);
-	g_signal_connect (
-		dbus_interface, "handle-set-backend-property",
-		G_CALLBACK (impl_Book_set_backend_property), ebook);
-	g_signal_connect (
-		dbus_interface, "handle-get-view",
-		G_CALLBACK (impl_Book_get_view), ebook);
-	g_signal_connect (
-		dbus_interface, "handle-cancel-operation",
-		G_CALLBACK (impl_Book_cancel_operation), ebook);
-	g_signal_connect (
-		dbus_interface, "handle-cancel-all",
-		G_CALLBACK (impl_Book_cancel_all), ebook);
-	g_signal_connect (
-		dbus_interface, "handle-close",
-		G_CALLBACK (impl_Book_close), ebook);
 }
 
 /**
@@ -1469,6 +1819,61 @@ e_data_book_new (EBookBackend *backend,
 		NULL);
 }
 
+EDataBook *
+e_data_book_new_direct (ESourceRegistry *registry,
+			ESource *source,
+			const gchar *backend_path,
+			const gchar *backend_name,
+			const gchar *config)
+{
+	EDataBook    *book = NULL;
+	EModule      *module;
+	EBookBackend *backend;
+	GType         backend_type;
+	GType         factory_type;
+	GTypeClass   *factory_class;
+
+	g_return_val_if_fail (E_IS_SOURCE_REGISTRY (registry), NULL);
+	g_return_val_if_fail (E_IS_SOURCE (source), NULL);
+	g_return_val_if_fail (backend_path && backend_path[0], NULL);
+	g_return_val_if_fail (backend_name && backend_name[0], NULL);
+
+	module = load_module (backend_path);
+	if (!module)
+		goto new_direct_finish;
+
+	if (!g_type_module_use (G_TYPE_MODULE (module))) {
+		g_warning ("Failed to load EModule at path: %s", backend_path);
+		goto new_direct_finish;
+	}
+
+	factory_type = g_type_from_name (backend_name);
+	if (factory_type == 0) {
+		g_warning ("Failed to get backend factory '%s' from EModule at path: %s",
+			   backend_name, backend_path);
+		g_type_module_unuse (G_TYPE_MODULE (module));
+		goto new_direct_finish;
+	}
+
+	factory_class = g_type_class_ref (factory_type);
+	backend_type  = E_BOOK_BACKEND_FACTORY_CLASS (factory_class)->backend_type;
+	g_type_class_unref (factory_class);
+
+	backend = g_object_new (backend_type,
+				"registry", registry,
+				"source", source, NULL);
+
+	e_book_backend_configure_direct (backend, config);
+
+	book = g_object_new (E_TYPE_DATA_BOOK, "backend", backend, NULL);
+	book->priv->direct_module = module;
+	g_object_unref (backend);
+
+ new_direct_finish:
+
+	return book;
+}
+
 /**
  * e_data_book_get_backend:
  * @book: an #EDataBook
@@ -1524,3 +1929,356 @@ e_data_book_get_object_path (EDataBook *book)
 	return book->priv->object_path;
 }
 
+/*************************************************************************
+ *                        Direct Read Access APIs                        *
+ *************************************************************************/
+void
+e_data_book_open (EDataBook *book,
+		  gboolean only_if_exists,
+		  GCancellable *cancellable,
+		  GAsyncReadyCallback callback,
+		  gpointer user_data)
+{
+	OperationData *op;
+
+	g_return_if_fail (E_IS_DATA_BOOK (book));
+
+	op = op_direct_new (OP_OPEN, book, cancellable, callback, user_data, e_data_book_open, FALSE, NULL);
+	op->d.only_if_exists = only_if_exists;
+
+	e_operation_pool_push (ops_pool, op);
+}
+
+gboolean
+e_data_book_open_finish (EDataBook *book,
+			 GAsyncResult *result,
+			 GError **error)
+{
+	gboolean res;
+
+	g_return_val_if_fail (E_IS_DATA_BOOK (book), FALSE);
+	g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
+
+	res = g_simple_async_result_get_op_res_gboolean (G_SIMPLE_ASYNC_RESULT (result));
+	g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result), error);
+
+	return res;
+}
+
+gboolean
+e_data_book_open_sync (EDataBook *book,
+		       gboolean only_if_exists,
+		       GCancellable *cancellable,
+		       GError **error)
+{
+	DirectOperationData *data = NULL;
+	OperationData *op;
+	gboolean result = FALSE;
+
+	g_return_val_if_fail (E_IS_DATA_BOOK (book), FALSE);
+
+	op = op_direct_new (OP_OPEN, book, cancellable, NULL, NULL, e_data_book_open_sync, TRUE, &data);
+	op->d.only_if_exists = only_if_exists;
+
+	e_operation_pool_push (ops_pool, op);
+
+	direct_operation_wait (data);
+	result = e_data_book_open_finish (book, G_ASYNC_RESULT (data->result), error);
+	direct_operation_data_free (data);
+
+	return result;
+}
+
+static void
+e_data_book_respond_close (EDataBook *book,
+			   guint opid,
+			   GError *error)
+{
+	DirectOperationData *data;
+
+	data = op_complete (book, opid);
+
+	if (data) {
+		gboolean result = FALSE;
+
+		if (error)
+			g_simple_async_result_set_error (data->result,
+							 error->domain,
+							 error->code,
+							 "%s", error->message);
+
+		else {
+			if (!g_cancellable_is_cancelled (data->cancellable))
+				result = TRUE;
+
+			g_simple_async_result_set_check_cancellable (data->result,
+								     data->cancellable);
+		}
+
+		g_simple_async_result_set_op_res_gboolean (data->result, result);
+
+		/* Deliver the result to the caller */
+		direct_operation_complete (data);
+	}
+
+	if (error)
+		g_error_free (error);
+}
+
+void
+e_data_book_close (EDataBook *book,
+		   GCancellable *cancellable,
+		   GAsyncReadyCallback callback,
+		   gpointer user_data)
+{
+	OperationData *op;
+
+	g_return_if_fail (E_IS_DATA_BOOK (book));
+
+	op = op_direct_new (OP_CLOSE, book, cancellable, callback, user_data, e_data_book_close, FALSE, NULL);
+	e_operation_pool_push (ops_pool, op);
+}
+
+gboolean
+e_data_book_close_finish (EDataBook *book,
+			  GAsyncResult *result,
+			  GError **error)
+{
+	gboolean res;
+
+	g_return_val_if_fail (E_IS_DATA_BOOK (book), FALSE);
+	g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
+
+	res = g_simple_async_result_get_op_res_gboolean (G_SIMPLE_ASYNC_RESULT (result));
+	g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result), error);
+
+	return res;
+}
+
+gboolean
+e_data_book_close_sync (EDataBook *book,
+			GCancellable *cancellable,
+			GError **error)
+{
+	DirectOperationData *data = NULL;
+	OperationData *op;
+	gboolean result = FALSE;
+
+	g_return_val_if_fail (E_IS_DATA_BOOK (book), FALSE);
+
+	op = op_direct_new (OP_CLOSE, book, cancellable, NULL, NULL, e_data_book_close_sync, TRUE, &data);
+	e_operation_pool_push (ops_pool, op);
+
+	direct_operation_wait (data);
+	result = e_data_book_close_finish (book, G_ASYNC_RESULT (data->result), error);
+	direct_operation_data_free (data);
+
+	return result;
+}
+
+void
+e_data_book_get_contact (EDataBook *book,
+			 const gchar *uid,
+			 GCancellable *cancellable,
+			 GAsyncReadyCallback callback,
+			 gpointer user_data)
+{
+	OperationData *op;
+
+	g_return_if_fail (E_IS_DATA_BOOK (book));
+	g_return_if_fail (uid && uid[0]);
+
+	op = op_direct_new (OP_GET_CONTACT, book, cancellable, callback, user_data, e_data_book_get_contact, FALSE, NULL);
+	op->d.uid = g_strdup (uid);
+
+	e_operation_pool_push (ops_pool, op);
+}
+
+gboolean
+e_data_book_get_contact_finish (EDataBook *book,
+				GAsyncResult *result,
+				EContact **contact,
+				GError **error)
+{
+	EContact *ret_contact;
+
+	g_return_val_if_fail (E_IS_DATA_BOOK (book), FALSE);
+	g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
+
+	ret_contact = g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (result));
+	g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result), error);
+
+	if (contact) {
+		if (ret_contact)
+			*contact = g_object_ref (ret_contact);
+		else
+			*contact = NULL;
+	}
+
+	return ret_contact != NULL;
+}
+
+gboolean
+e_data_book_get_contact_sync (EDataBook *book,
+			      const gchar *uid,
+			      EContact **contact,
+			      GCancellable *cancellable,
+			      GError **error)
+{
+	DirectOperationData *data = NULL;
+	OperationData *op;
+	gboolean result = FALSE;
+
+	g_return_val_if_fail (E_IS_DATA_BOOK (book), FALSE);
+	g_return_val_if_fail (uid && uid[0], FALSE);
+
+	op = op_direct_new (OP_GET_CONTACT, book, cancellable, NULL, NULL, e_data_book_open_sync, TRUE, &data);
+	op->d.uid = g_strdup (uid);
+
+	e_operation_pool_push (ops_pool, op);
+
+	direct_operation_wait (data);
+	result = e_data_book_get_contact_finish (book, G_ASYNC_RESULT (data->result), contact, error);
+	direct_operation_data_free (data);
+
+	return result;
+}
+
+void
+e_data_book_get_contacts (EDataBook *book,
+			  const gchar *sexp,
+			  GCancellable *cancellable,
+			  GAsyncReadyCallback callback,
+			  gpointer user_data)
+{
+	OperationData *op;
+
+	g_return_if_fail (E_IS_DATA_BOOK (book));
+
+	op = op_direct_new (OP_GET_CONTACTS, book, cancellable, callback, user_data, e_data_book_get_contact, FALSE, NULL);
+	op->d.query = g_strdup (sexp);
+
+	e_operation_pool_push (ops_pool, op);
+}
+
+gboolean
+e_data_book_get_contacts_finish (EDataBook *book,
+				 GAsyncResult *result,
+				 GSList **contacts,
+				 GError **error)
+{
+	GSList *ret_contacts;
+
+	g_return_val_if_fail (E_IS_DATA_BOOK (book), FALSE);
+	g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
+
+	ret_contacts = g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (result));
+	g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result), error);
+
+	if (contacts) {
+		if (ret_contacts)
+			*contacts = e_util_copy_object_slist (NULL, ret_contacts);
+		else
+			*contacts = NULL;
+	}
+
+	/* How can we tell if it failed ? ... we need to check the error but
+	 * GSimpleAsyncResult doesnt tell us if there was an error, only propagates it
+	 */
+	return TRUE;
+}
+
+gboolean
+e_data_book_get_contacts_sync (EDataBook *book,
+			       const gchar *sexp,
+			       GSList **contacts,
+			       GCancellable *cancellable,
+			       GError **error)
+{
+	DirectOperationData *data = NULL;
+	OperationData *op;
+	gboolean result = FALSE;
+
+	g_return_val_if_fail (E_IS_DATA_BOOK (book), FALSE);
+
+	op = op_direct_new (OP_GET_CONTACTS, book, cancellable, NULL, NULL, e_data_book_open_sync, TRUE, &data);
+	op->d.query = g_strdup (sexp);
+
+	e_operation_pool_push (ops_pool, op);
+
+	direct_operation_wait (data);
+	result = e_data_book_get_contacts_finish (book, G_ASYNC_RESULT (data->result), contacts, error);
+	direct_operation_data_free (data);
+
+	return result;
+}
+
+void
+e_data_book_get_contacts_uids (EDataBook *book,
+			       const gchar *sexp,
+			       GCancellable *cancellable,
+			       GAsyncReadyCallback callback,
+			       gpointer user_data)
+{
+	OperationData *op;
+
+	g_return_if_fail (E_IS_DATA_BOOK (book));
+
+	op = op_direct_new (OP_GET_CONTACTS_UIDS, book, cancellable, callback, user_data, e_data_book_get_contact, FALSE, NULL);
+	op->d.query = g_strdup (sexp);
+
+	e_operation_pool_push (ops_pool, op);
+}
+
+gboolean
+e_data_book_get_contacts_uids_finish (EDataBook *book,
+				      GAsyncResult *result,
+				      GSList **contacts_uids,
+				      GError **error)
+{
+	GSList *ret_uids;
+
+	g_return_val_if_fail (E_IS_DATA_BOOK (book), FALSE);
+	g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
+
+	ret_uids = g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (result));
+	g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result), error);
+
+	if (contacts_uids) {
+		if (ret_uids)
+			*contacts_uids = e_util_copy_string_slist (NULL, ret_uids);
+		else
+			*contacts_uids = NULL;
+	}
+
+	/* How can we tell if it failed ? ... we need to check the error but
+	 * GSimpleAsyncResult doesnt tell us if there was an error, only propagates it
+	 */
+	return TRUE;
+}
+
+gboolean
+e_data_book_get_contacts_uids_sync (EDataBook *book,
+				    const gchar *sexp,
+				    GSList **contacts_uids,
+				    GCancellable *cancellable,
+				    GError **error)
+{
+	DirectOperationData *data = NULL;
+	OperationData *op;
+	gboolean result = FALSE;
+
+	g_return_val_if_fail (E_IS_DATA_BOOK (book), FALSE);
+
+	op = op_direct_new (OP_GET_CONTACTS_UIDS, book, cancellable, NULL, NULL, e_data_book_open_sync, TRUE, &data);
+	op->d.query = g_strdup (sexp);
+
+	e_operation_pool_push (ops_pool, op);
+
+	direct_operation_wait (data);
+	result = e_data_book_get_contacts_uids_finish (book, G_ASYNC_RESULT (data->result), contacts_uids, error);
+	direct_operation_data_free (data);
+
+	return result;
+}
+
diff --git a/addressbook/libedata-book/e-data-book.h b/addressbook/libedata-book/e-data-book.h
index e0827b8..7f5b906 100644
--- a/addressbook/libedata-book/e-data-book.h
+++ b/addressbook/libedata-book/e-data-book.h
@@ -146,6 +146,11 @@ EDataBook *	e_data_book_new			(struct _EBookBackend *backend,
 						 GDBusConnection *connection,
 						 const gchar *object_path,
 						 GError **error);
+EDataBook *	e_data_book_new_direct		(ESourceRegistry *registry,
+						 ESource *source,
+						 const gchar *backend_path,
+						 const gchar *backend_name,
+						 const gchar *config);
 struct _EBookBackend *
 		e_data_book_get_backend		(EDataBook *book);
 GDBusConnection *
@@ -213,6 +218,28 @@ void		e_data_book_report_backend_property_changed
 gchar *		e_data_book_string_slist_to_comma_string
 						(const GSList *strings);
 
+/* Direct read access apis */
+void		e_data_book_open		                (EDataBook *book, gboolean only_if_exists, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data);
+gboolean	e_data_book_open_finish                         (EDataBook *book, GAsyncResult *result, GError **error);
+gboolean	e_data_book_open_sync		                (EDataBook *book, gboolean only_if_exists, GCancellable *cancellable, GError **error);
+
+void		e_data_book_close		                (EDataBook *book, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data);
+gboolean	e_data_book_close_finish                        (EDataBook *book, GAsyncResult *result, GError **error);
+gboolean	e_data_book_close_sync		                (EDataBook *book, GCancellable *cancellable, GError **error);
+
+void		e_data_book_get_contact			        (EDataBook *book, const gchar *uid, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data);
+gboolean	e_data_book_get_contact_finish                  (EDataBook *book, GAsyncResult *result, EContact **contact, GError **error);
+gboolean	e_data_book_get_contact_sync                    (EDataBook *book, const gchar *uid, EContact **contact, GCancellable *cancellable, GError **error);
+
+void		e_data_book_get_contacts			(EDataBook *book, const gchar *sexp, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data);
+gboolean	e_data_book_get_contacts_finish                 (EDataBook *book, GAsyncResult *result, GSList **contacts, GError **error);
+gboolean	e_data_book_get_contacts_sync			(EDataBook *book, const gchar *sexp, GSList **contacts, GCancellable *cancellable, GError **error);
+
+void		e_data_book_get_contacts_uids			(EDataBook *book, const gchar *sexp, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data);
+gboolean	e_data_book_get_contacts_uids_finish		(EDataBook *book, GAsyncResult *result, GSList **contacts_uids, GError **error);
+gboolean	e_data_book_get_contacts_uids_sync		(EDataBook *book, const gchar *sexp, GSList **contacts_uids, GCancellable *cancellable, GError **error);
+
+
 G_END_DECLS
 
 #endif /* E_DATA_BOOK_H */
diff --git a/addressbook/libedata-book/libedata-book.h b/addressbook/libedata-book/libedata-book.h
index ecd52ec..ec15c83 100644
--- a/addressbook/libedata-book/libedata-book.h
+++ b/addressbook/libedata-book/libedata-book.h
@@ -21,7 +21,7 @@
 
 #define __LIBEDATA_BOOK_H_INSIDE__
 
-#include <libebook/libebook.h>
+#include <libebook-contacts/libebook-contacts.h>
 #include <libebackend/libebackend.h>
 
 #include <libedata-book/e-book-backend-cache.h>
@@ -34,6 +34,7 @@
 #include <libedata-book/e-book-backend.h>
 #include <libedata-book/e-data-book-factory.h>
 #include <libedata-book/e-data-book-view.h>
+#include <libedata-book/e-data-book-direct.h>
 #include <libedata-book/e-data-book.h>
 
 #undef __LIBEDATA_BOOK_H_INSIDE__
diff --git a/addressbook/libegdbus/Makefile.am b/addressbook/libegdbus/Makefile.am
index d176dac..28b248a 100644
--- a/addressbook/libegdbus/Makefile.am
+++ b/addressbook/libegdbus/Makefile.am
@@ -7,12 +7,15 @@ libegdbus_book_la_CPPFLAGS =			\
 	-I$(top_srcdir)				\
 	-I$(top_srcdir)/addressbook		\
 	$(E_DATA_SERVER_CFLAGS)			\
+	$(GIO_UNIX_CFLAGS)			\
 	$(CODE_COVERAGE_CFLAGS)			\
 	$(NULL)
 
 libegdbus_book_la_SOURCES =			\
 	e-gdbus-book.h				\
 	e-gdbus-book.c				\
+	e-gdbus-book-direct.h			\
+	e-gdbus-book-direct.c			\
 	e-gdbus-book-factory.h			\
 	e-gdbus-book-factory.c			\
 	e-gdbus-book-view.h			\
@@ -20,7 +23,9 @@ libegdbus_book_la_SOURCES =			\
 
 libegdbus_book_la_LIBADD =			\
 	$(top_builddir)/libedataserver/libedataserver-1.2.la	\
-	$(E_DATA_SERVER_LIBS)
+	$(E_DATA_SERVER_LIBS)	\
+	$(GIO_UNIX_LIBS)
+
 
 libegdbus_book_la_LDFLAGS = $(NO_UNDEFINED) \
 	$(CODE_COVERAGE_LDFLAGS) \
diff --git a/addressbook/libegdbus/e-gdbus-book-direct.c b/addressbook/libegdbus/e-gdbus-book-direct.c
new file mode 100644
index 0000000..03107c5
--- /dev/null
+++ b/addressbook/libegdbus/e-gdbus-book-direct.c
@@ -0,0 +1,1359 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 2012 Intel Corporation
+ *
+ * This program 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; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program 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 the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ * Author: Tristan Van Berkom <tristanvb openismus com>
+ */
+
+#ifdef HAVE_CONFIG_H
+#  include "config.h"
+#endif
+
+#include "e-gdbus-book-direct.h"
+
+#include <string.h>
+#ifdef G_OS_UNIX
+#  include <gio/gunixfdlist.h>
+#endif
+
+typedef struct
+{
+  GDBusArgInfo parent_struct;
+  gboolean use_gvariant;
+} _ExtendedGDBusArgInfo;
+
+typedef struct
+{
+  GDBusMethodInfo parent_struct;
+  const gchar *signal_name;
+  gboolean pass_fdlist;
+} _ExtendedGDBusMethodInfo;
+
+typedef struct
+{
+  GDBusSignalInfo parent_struct;
+  const gchar *signal_name;
+} _ExtendedGDBusSignalInfo;
+
+typedef struct
+{
+  GDBusPropertyInfo parent_struct;
+  const gchar *hyphen_name;
+  gboolean use_gvariant;
+} _ExtendedGDBusPropertyInfo;
+
+typedef struct
+{
+  GDBusInterfaceInfo parent_struct;
+  const gchar *hyphen_name;
+} _ExtendedGDBusInterfaceInfo;
+
+typedef struct
+{
+  const _ExtendedGDBusPropertyInfo *info;
+  guint prop_id;
+  GValue orig_value; /* the value before the change */
+} ChangedProperty;
+
+static void
+_changed_property_free (ChangedProperty *data)
+{
+  g_value_unset (&data->orig_value);
+  g_free (data);
+}
+
+static gboolean
+_g_strv_equal0 (gchar **a, gchar **b)
+{
+  gboolean ret = FALSE;
+  guint n;
+  if (a == NULL && b == NULL)
+    {
+      ret = TRUE;
+      goto out;
+    }
+  if (a == NULL || b == NULL)
+    goto out;
+  if (g_strv_length (a) != g_strv_length (b))
+    goto out;
+  for (n = 0; a[n] != NULL; n++)
+    if (g_strcmp0 (a[n], b[n]) != 0)
+      goto out;
+  ret = TRUE;
+out:
+  return ret;
+}
+
+static gboolean
+_g_variant_equal0 (GVariant *a, GVariant *b)
+{
+  gboolean ret = FALSE;
+  if (a == NULL && b == NULL)
+    {
+      ret = TRUE;
+      goto out;
+    }
+  if (a == NULL || b == NULL)
+    goto out;
+  ret = g_variant_equal (a, b);
+out:
+  return ret;
+}
+
+G_GNUC_UNUSED static gboolean
+_g_value_equal (const GValue *a, const GValue *b)
+{
+  gboolean ret = FALSE;
+  g_assert (G_VALUE_TYPE (a) == G_VALUE_TYPE (b));
+  switch (G_VALUE_TYPE (a))
+    {
+      case G_TYPE_BOOLEAN:
+        ret = (g_value_get_boolean (a) == g_value_get_boolean (b));
+        break;
+      case G_TYPE_UCHAR:
+        ret = (g_value_get_uchar (a) == g_value_get_uchar (b));
+        break;
+      case G_TYPE_INT:
+        ret = (g_value_get_int (a) == g_value_get_int (b));
+        break;
+      case G_TYPE_UINT:
+        ret = (g_value_get_uint (a) == g_value_get_uint (b));
+        break;
+      case G_TYPE_INT64:
+        ret = (g_value_get_int64 (a) == g_value_get_int64 (b));
+        break;
+      case G_TYPE_UINT64:
+        ret = (g_value_get_uint64 (a) == g_value_get_uint64 (b));
+        break;
+      case G_TYPE_DOUBLE:
+        {
+          /* Avoid -Wfloat-equal warnings by doing a direct bit compare */
+          gdouble da = g_value_get_double (a);
+          gdouble db = g_value_get_double (b);
+          ret = memcmp (&da, &db, sizeof (gdouble)) == 0;
+        }
+        break;
+      case G_TYPE_STRING:
+        ret = (g_strcmp0 (g_value_get_string (a), g_value_get_string (b)) == 0);
+        break;
+      case G_TYPE_VARIANT:
+        ret = _g_variant_equal0 (g_value_get_variant (a), g_value_get_variant (b));
+        break;
+      default:
+        if (G_VALUE_TYPE (a) == G_TYPE_STRV)
+          ret = _g_strv_equal0 (g_value_get_boxed (a), g_value_get_boxed (b));
+        else
+          g_critical ("_g_value_equal() does not handle type %s", g_type_name (G_VALUE_TYPE (a)));
+        break;
+    }
+  return ret;
+}
+
+/* ------------------------------------------------------------------------
+ * Code for interface org.gnome.evolution.dataserver.AddressBookDirect
+ * ------------------------------------------------------------------------
+ */
+
+/**
+ * SECTION:EGdbusBookDirect
+ * @title: EGdbusBookDirect
+ * @short_description: Generated C code for the org.gnome.evolution.dataserver.AddressBookDirect D-Bus interface
+ *
+ * This section contains code for working with the <link linkend="gdbus-interface-org-gnome-evolution-dataserver-AddressBookDirect.top_of_page">org.gnome.evolution.dataserver.AddressBookDirect</link> D-Bus interface in C.
+ */
+
+/* ---- Introspection data for org.gnome.evolution.dataserver.AddressBookDirect ---- */
+
+static const _ExtendedGDBusPropertyInfo _e_gdbus_book_direct_property_info_backend_path =
+{
+  {
+    -1,
+    (gchar *) "BackendPath",
+    (gchar *) "s",
+    G_DBUS_PROPERTY_INFO_FLAGS_READABLE,
+    NULL
+  },
+  "backend-path",
+  FALSE
+};
+
+static const _ExtendedGDBusPropertyInfo _e_gdbus_book_direct_property_info_backend_name =
+{
+  {
+    -1,
+    (gchar *) "BackendName",
+    (gchar *) "s",
+    G_DBUS_PROPERTY_INFO_FLAGS_READABLE,
+    NULL
+  },
+  "backend-name",
+  FALSE
+};
+
+static const _ExtendedGDBusPropertyInfo _e_gdbus_book_direct_property_info_backend_config =
+{
+  {
+    -1,
+    (gchar *) "BackendConfig",
+    (gchar *) "s",
+    G_DBUS_PROPERTY_INFO_FLAGS_READABLE,
+    NULL
+  },
+  "backend-config",
+  FALSE
+};
+
+static const _ExtendedGDBusPropertyInfo * const _e_gdbus_book_direct_property_info_pointers[] =
+{
+  &_e_gdbus_book_direct_property_info_backend_path,
+  &_e_gdbus_book_direct_property_info_backend_name,
+  &_e_gdbus_book_direct_property_info_backend_config,
+  NULL
+};
+
+static const _ExtendedGDBusInterfaceInfo _e_gdbus_book_direct_interface_info =
+{
+  {
+    -1,
+    (gchar *) "org.gnome.evolution.dataserver.AddressBookDirect",
+    NULL,
+    NULL,
+    (GDBusPropertyInfo **) &_e_gdbus_book_direct_property_info_pointers,
+    NULL
+  },
+  "address-book-direct",
+};
+
+
+/**
+ * e_gdbus_book_direct_interface_info:
+ *
+ * Gets a machine-readable description of the <link linkend="gdbus-interface-org-gnome-evolution-dataserver-AddressBookDirect.top_of_page">org.gnome.evolution.dataserver.AddressBookDirect</link> D-Bus interface.
+ *
+ * Returns: (transfer none): A #GDBusInterfaceInfo. Do not free.
+ */
+GDBusInterfaceInfo *
+e_gdbus_book_direct_interface_info (void)
+{
+  return (GDBusInterfaceInfo *) &_e_gdbus_book_direct_interface_info.parent_struct;
+}
+
+/**
+ * e_gdbus_book_direct_override_properties:
+ * @klass: The class structure for a #GObject<!-- -->-derived class.
+ * @property_id_begin: The property id to assign to the first overridden property.
+ *
+ * Overrides all #GObject properties in the #EGdbusBookDirect interface for a concrete class.
+ * The properties are overridden in the order they are defined.
+ *
+ * Returns: The last property id.
+ */
+guint
+e_gdbus_book_direct_override_properties (GObjectClass *klass, guint property_id_begin)
+{
+  g_object_class_override_property (klass, property_id_begin++, "backend-path");
+  g_object_class_override_property (klass, property_id_begin++, "backend-name");
+  g_object_class_override_property (klass, property_id_begin++, "backend-config");
+  return property_id_begin - 1;
+}
+
+
+
+/**
+ * EGdbusBookDirect:
+ *
+ * Abstract interface type for the D-Bus interface <link linkend="gdbus-interface-org-gnome-evolution-dataserver-AddressBookDirect.top_of_page">org.gnome.evolution.dataserver.AddressBookDirect</link>.
+ */
+
+/**
+ * EGdbusBookDirectIface:
+ * @parent_iface: The parent interface.
+ * @get_backend_config: Getter for the #EGdbusBookDirect:backend-config property.
+ * @get_backend_name: Getter for the #EGdbusBookDirect:backend-name property.
+ * @get_backend_path: Getter for the #EGdbusBookDirect:backend-path property.
+ *
+ * Virtual table for the D-Bus interface <link linkend="gdbus-interface-org-gnome-evolution-dataserver-AddressBookDirect.top_of_page">org.gnome.evolution.dataserver.AddressBookDirect</link>.
+ */
+typedef EGdbusBookDirectIface EGdbusBookDirectInterface;
+G_DEFINE_INTERFACE (EGdbusBookDirect, e_gdbus_book_direct, G_TYPE_OBJECT);
+
+static void
+e_gdbus_book_direct_default_init (EGdbusBookDirectIface *iface)
+{
+  /* GObject properties for D-Bus properties: */
+  g_object_interface_install_property (iface,
+    g_param_spec_string ("backend-path", "BackendPath", "BackendPath", NULL, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+  g_object_interface_install_property (iface,
+    g_param_spec_string ("backend-name", "BackendName", "BackendName", NULL, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+  g_object_interface_install_property (iface,
+    g_param_spec_string ("backend-config", "BackendConfig", "BackendConfig", NULL, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+}
+
+/**
+ * e_gdbus_book_direct_get_backend_path: (skip)
+ * @object: A #EGdbusBookDirect.
+ *
+ * Gets the value of the <link linkend="gdbus-property-org-gnome-evolution-dataserver-AddressBookDirect.BackendPath">"BackendPath"</link> D-Bus property.
+ *
+ * Since this D-Bus property is readable, it is meaningful to use this function on both the client- and service-side.
+ *
+ * <warning>The returned value is only valid until the property changes so on the client-side it is only safe to use this function on the thread where @object was constructed. Use e_gdbus_book_direct_dup_backend_path() if on another thread.</warning>
+ *
+ * Returns: (transfer none): The property value or %NULL if the property is not set. Do not free the returned value, it belongs to @object.
+ */
+const gchar *
+e_gdbus_book_direct_get_backend_path (EGdbusBookDirect *object)
+{
+  return E_GDBUS_BOOK_DIRECT_GET_IFACE (object)->get_backend_path (object);
+}
+
+/**
+ * e_gdbus_book_direct_dup_backend_path: (skip)
+ * @object: A #EGdbusBookDirect.
+ *
+ * Gets a copy of the <link linkend="gdbus-property-org-gnome-evolution-dataserver-AddressBookDirect.BackendPath">"BackendPath"</link> D-Bus property.
+ *
+ * Since this D-Bus property is readable, it is meaningful to use this function on both the client- and service-side.
+ *
+ * Returns: (transfer full): The property value or %NULL if the property is not set. The returned value should be freed with g_free().
+ */
+gchar *
+e_gdbus_book_direct_dup_backend_path (EGdbusBookDirect *object)
+{
+  gchar *value;
+  g_object_get (G_OBJECT (object), "backend-path", &value, NULL);
+  return value;
+}
+
+/**
+ * e_gdbus_book_direct_set_backend_path: (skip)
+ * @object: A #EGdbusBookDirect.
+ * @value: The value to set.
+ *
+ * Sets the <link linkend="gdbus-property-org-gnome-evolution-dataserver-AddressBookDirect.BackendPath">"BackendPath"</link> D-Bus property to @value.
+ *
+ * Since this D-Bus property is not writable, it is only meaningful to use this function on the service-side.
+ */
+void
+e_gdbus_book_direct_set_backend_path (EGdbusBookDirect *object, const gchar *value)
+{
+  g_object_set (G_OBJECT (object), "backend-path", value, NULL);
+}
+
+/**
+ * e_gdbus_book_direct_get_backend_name: (skip)
+ * @object: A #EGdbusBookDirect.
+ *
+ * Gets the value of the <link linkend="gdbus-property-org-gnome-evolution-dataserver-AddressBookDirect.BackendName">"BackendName"</link> D-Bus property.
+ *
+ * Since this D-Bus property is readable, it is meaningful to use this function on both the client- and service-side.
+ *
+ * <warning>The returned value is only valid until the property changes so on the client-side it is only safe to use this function on the thread where @object was constructed. Use e_gdbus_book_direct_dup_backend_name() if on another thread.</warning>
+ *
+ * Returns: (transfer none): The property value or %NULL if the property is not set. Do not free the returned value, it belongs to @object.
+ */
+const gchar *
+e_gdbus_book_direct_get_backend_name (EGdbusBookDirect *object)
+{
+  return E_GDBUS_BOOK_DIRECT_GET_IFACE (object)->get_backend_name (object);
+}
+
+/**
+ * e_gdbus_book_direct_dup_backend_name: (skip)
+ * @object: A #EGdbusBookDirect.
+ *
+ * Gets a copy of the <link linkend="gdbus-property-org-gnome-evolution-dataserver-AddressBookDirect.BackendName">"BackendName"</link> D-Bus property.
+ *
+ * Since this D-Bus property is readable, it is meaningful to use this function on both the client- and service-side.
+ *
+ * Returns: (transfer full): The property value or %NULL if the property is not set. The returned value should be freed with g_free().
+ */
+gchar *
+e_gdbus_book_direct_dup_backend_name (EGdbusBookDirect *object)
+{
+  gchar *value;
+  g_object_get (G_OBJECT (object), "backend-name", &value, NULL);
+  return value;
+}
+
+/**
+ * e_gdbus_book_direct_set_backend_name: (skip)
+ * @object: A #EGdbusBookDirect.
+ * @value: The value to set.
+ *
+ * Sets the <link linkend="gdbus-property-org-gnome-evolution-dataserver-AddressBookDirect.BackendName">"BackendName"</link> D-Bus property to @value.
+ *
+ * Since this D-Bus property is not writable, it is only meaningful to use this function on the service-side.
+ */
+void
+e_gdbus_book_direct_set_backend_name (EGdbusBookDirect *object, const gchar *value)
+{
+  g_object_set (G_OBJECT (object), "backend-name", value, NULL);
+}
+
+/**
+ * e_gdbus_book_direct_get_backend_config: (skip)
+ * @object: A #EGdbusBookDirect.
+ *
+ * Gets the value of the <link linkend="gdbus-property-org-gnome-evolution-dataserver-AddressBookDirect.BackendConfig">"BackendConfig"</link> D-Bus property.
+ *
+ * Since this D-Bus property is readable, it is meaningful to use this function on both the client- and service-side.
+ *
+ * <warning>The returned value is only valid until the property changes so on the client-side it is only safe to use this function on the thread where @object was constructed. Use e_gdbus_book_direct_dup_backend_config() if on another thread.</warning>
+ *
+ * Returns: (transfer none): The property value or %NULL if the property is not set. Do not free the returned value, it belongs to @object.
+ */
+const gchar *
+e_gdbus_book_direct_get_backend_config (EGdbusBookDirect *object)
+{
+  return E_GDBUS_BOOK_DIRECT_GET_IFACE (object)->get_backend_config (object);
+}
+
+/**
+ * e_gdbus_book_direct_dup_backend_config: (skip)
+ * @object: A #EGdbusBookDirect.
+ *
+ * Gets a copy of the <link linkend="gdbus-property-org-gnome-evolution-dataserver-AddressBookDirect.BackendConfig">"BackendConfig"</link> D-Bus property.
+ *
+ * Since this D-Bus property is readable, it is meaningful to use this function on both the client- and service-side.
+ *
+ * Returns: (transfer full): The property value or %NULL if the property is not set. The returned value should be freed with g_free().
+ */
+gchar *
+e_gdbus_book_direct_dup_backend_config (EGdbusBookDirect *object)
+{
+  gchar *value;
+  g_object_get (G_OBJECT (object), "backend-config", &value, NULL);
+  return value;
+}
+
+/**
+ * e_gdbus_book_direct_set_backend_config: (skip)
+ * @object: A #EGdbusBookDirect.
+ * @value: The value to set.
+ *
+ * Sets the <link linkend="gdbus-property-org-gnome-evolution-dataserver-AddressBookDirect.BackendConfig">"BackendConfig"</link> D-Bus property to @value.
+ *
+ * Since this D-Bus property is not writable, it is only meaningful to use this function on the service-side.
+ */
+void
+e_gdbus_book_direct_set_backend_config (EGdbusBookDirect *object, const gchar *value)
+{
+  g_object_set (G_OBJECT (object), "backend-config", value, NULL);
+}
+
+/* ------------------------------------------------------------------------ */
+
+/**
+ * EGdbusBookDirectProxy:
+ *
+ * The #EGdbusBookDirectProxy structure contains only private data and should only be accessed using the provided API.
+ */
+
+/**
+ * EGdbusBookDirectProxyClass:
+ * @parent_class: The parent class.
+ *
+ * Class structure for #EGdbusBookDirectProxy.
+ */
+
+struct _EGdbusBookDirectProxyPrivate
+{
+  GData *qdata;
+};
+
+static void e_gdbus_book_direct_proxy_iface_init (EGdbusBookDirectIface *iface);
+
+G_DEFINE_TYPE_WITH_CODE (EGdbusBookDirectProxy, e_gdbus_book_direct_proxy, G_TYPE_DBUS_PROXY,
+                         G_IMPLEMENT_INTERFACE (E_GDBUS_TYPE_BOOK_DIRECT, e_gdbus_book_direct_proxy_iface_init));
+
+static void
+e_gdbus_book_direct_proxy_finalize (GObject *object)
+{
+  EGdbusBookDirectProxy *proxy = E_GDBUS_BOOK_DIRECT_PROXY (object);
+  g_datalist_clear (&proxy->priv->qdata);
+  G_OBJECT_CLASS (e_gdbus_book_direct_proxy_parent_class)->finalize (object);
+}
+
+static void
+e_gdbus_book_direct_proxy_get_property (GObject      *object,
+  guint         prop_id,
+  GValue       *value,
+  GParamSpec   *pspec)
+{
+  const _ExtendedGDBusPropertyInfo *info;
+  GVariant *variant;
+  g_assert (prop_id != 0 && prop_id - 1 < 3);
+  info = _e_gdbus_book_direct_property_info_pointers[prop_id - 1];
+  variant = g_dbus_proxy_get_cached_property (G_DBUS_PROXY (object), info->parent_struct.name);
+  if (info->use_gvariant)
+    {
+      g_value_set_variant (value, variant);
+    }
+  else
+    {
+      if (variant != NULL)
+        g_dbus_gvariant_to_gvalue (variant, value);
+    }
+  if (variant != NULL)
+    g_variant_unref (variant);
+}
+
+static void
+e_gdbus_book_direct_proxy_set_property_cb (GDBusProxy *proxy,
+  GAsyncResult *res,
+  gpointer      user_data)
+{
+  const _ExtendedGDBusPropertyInfo *info = user_data;
+  GError *error;
+  error = NULL;
+  if (!g_dbus_proxy_call_finish (proxy, res, &error))
+    {
+      g_warning ("Error setting property `%s' on interface org.gnome.evolution.dataserver.AddressBookDirect: %s (%s, %d)",
+                 info->parent_struct.name, 
+                 error->message, g_quark_to_string (error->domain), error->code);
+      g_error_free (error);
+    }
+}
+
+static void
+e_gdbus_book_direct_proxy_set_property (GObject      *object,
+  guint         prop_id,
+  const GValue *value,
+  GParamSpec   *pspec)
+{
+  const _ExtendedGDBusPropertyInfo *info;
+  GVariant *variant;
+  g_assert (prop_id != 0 && prop_id - 1 < 3);
+  info = _e_gdbus_book_direct_property_info_pointers[prop_id - 1];
+  variant = g_dbus_gvalue_to_gvariant (value, G_VARIANT_TYPE (info->parent_struct.signature));
+  g_dbus_proxy_call (G_DBUS_PROXY (object),
+    "org.freedesktop.DBus.Properties.Set",
+    g_variant_new ("(ssv)", "org.gnome.evolution.dataserver.AddressBookDirect", info->parent_struct.name, variant),
+    G_DBUS_CALL_FLAGS_NONE,
+    -1,
+    NULL, (GAsyncReadyCallback) e_gdbus_book_direct_proxy_set_property_cb, (GDBusPropertyInfo *) &info->parent_struct);
+  g_variant_unref (variant);
+}
+
+static void
+e_gdbus_book_direct_proxy_g_signal (GDBusProxy *proxy,
+  const gchar *sender_name,
+  const gchar *signal_name,
+  GVariant *parameters)
+{
+  _ExtendedGDBusSignalInfo *info;
+  GVariantIter iter;
+  GVariant *child;
+  GValue *paramv;
+  guint num_params;
+  guint n;
+  guint signal_id;
+  info = (_ExtendedGDBusSignalInfo *) g_dbus_interface_info_lookup_signal ((GDBusInterfaceInfo *) &_e_gdbus_book_direct_interface_info.parent_struct, signal_name);
+  if (info == NULL)
+    return;
+  num_params = g_variant_n_children (parameters);
+  paramv = g_new0 (GValue, num_params + 1);
+  g_value_init (&paramv[0], E_GDBUS_TYPE_BOOK_DIRECT);
+  g_value_set_object (&paramv[0], proxy);
+  g_variant_iter_init (&iter, parameters);
+  n = 1;
+  while ((child = g_variant_iter_next_value (&iter)) != NULL)
+    {
+      _ExtendedGDBusArgInfo *arg_info = (_ExtendedGDBusArgInfo *) info->parent_struct.args[n - 1];
+      if (arg_info->use_gvariant)
+        {
+          g_value_init (&paramv[n], G_TYPE_VARIANT);
+          g_value_set_variant (&paramv[n], child);
+          n++;
+        }
+      else
+        g_dbus_gvariant_to_gvalue (child, &paramv[n++]);
+      g_variant_unref (child);
+    }
+  signal_id = g_signal_lookup (info->signal_name, E_GDBUS_TYPE_BOOK_DIRECT);
+  g_signal_emitv (paramv, signal_id, 0, NULL);
+  for (n = 0; n < num_params + 1; n++)
+    g_value_unset (&paramv[n]);
+  g_free (paramv);
+}
+
+static void
+e_gdbus_book_direct_proxy_g_properties_changed (GDBusProxy *_proxy,
+  GVariant *changed_properties,
+  const gchar *const *invalidated_properties)
+{
+  EGdbusBookDirectProxy *proxy = E_GDBUS_BOOK_DIRECT_PROXY (_proxy);
+  guint n;
+  const gchar *key;
+  GVariantIter *iter;
+  _ExtendedGDBusPropertyInfo *info;
+  g_variant_get (changed_properties, "a{sv}", &iter);
+  while (g_variant_iter_next (iter, "{&sv}", &key, NULL))
+    {
+      info = (_ExtendedGDBusPropertyInfo *) g_dbus_interface_info_lookup_property ((GDBusInterfaceInfo *) &_e_gdbus_book_direct_interface_info.parent_struct, key);
+      g_datalist_remove_data (&proxy->priv->qdata, key);
+      if (info != NULL)
+        g_object_notify (G_OBJECT (proxy), info->hyphen_name);
+    }
+  g_variant_iter_free (iter);
+  for (n = 0; invalidated_properties[n] != NULL; n++)
+    {
+      info = (_ExtendedGDBusPropertyInfo *) g_dbus_interface_info_lookup_property ((GDBusInterfaceInfo *) &_e_gdbus_book_direct_interface_info.parent_struct, invalidated_properties[n]);
+      g_datalist_remove_data (&proxy->priv->qdata, invalidated_properties[n]);
+      if (info != NULL)
+        g_object_notify (G_OBJECT (proxy), info->hyphen_name);
+    }
+}
+
+static const gchar *
+e_gdbus_book_direct_proxy_get_backend_path (EGdbusBookDirect *object)
+{
+  EGdbusBookDirectProxy *proxy = E_GDBUS_BOOK_DIRECT_PROXY (object);
+  GVariant *variant;
+  const gchar *value = NULL;
+  variant = g_dbus_proxy_get_cached_property (G_DBUS_PROXY (proxy), "BackendPath");
+  if (variant != NULL)
+    {
+      value = g_variant_get_string (variant, NULL);
+      g_variant_unref (variant);
+    }
+  return value;
+}
+
+static const gchar *
+e_gdbus_book_direct_proxy_get_backend_name (EGdbusBookDirect *object)
+{
+  EGdbusBookDirectProxy *proxy = E_GDBUS_BOOK_DIRECT_PROXY (object);
+  GVariant *variant;
+  const gchar *value = NULL;
+  variant = g_dbus_proxy_get_cached_property (G_DBUS_PROXY (proxy), "BackendName");
+  if (variant != NULL)
+    {
+      value = g_variant_get_string (variant, NULL);
+      g_variant_unref (variant);
+    }
+  return value;
+}
+
+static const gchar *
+e_gdbus_book_direct_proxy_get_backend_config (EGdbusBookDirect *object)
+{
+  EGdbusBookDirectProxy *proxy = E_GDBUS_BOOK_DIRECT_PROXY (object);
+  GVariant *variant;
+  const gchar *value = NULL;
+  variant = g_dbus_proxy_get_cached_property (G_DBUS_PROXY (proxy), "BackendConfig");
+  if (variant != NULL)
+    {
+      value = g_variant_get_string (variant, NULL);
+      g_variant_unref (variant);
+    }
+  return value;
+}
+
+static void
+e_gdbus_book_direct_proxy_init (EGdbusBookDirectProxy *proxy)
+{
+  proxy->priv = G_TYPE_INSTANCE_GET_PRIVATE (proxy, E_GDBUS_TYPE_BOOK_DIRECT_PROXY, EGdbusBookDirectProxyPrivate);
+  g_dbus_proxy_set_interface_info (G_DBUS_PROXY (proxy), e_gdbus_book_direct_interface_info ());
+}
+
+static void
+e_gdbus_book_direct_proxy_class_init (EGdbusBookDirectProxyClass *klass)
+{
+  GObjectClass *gobject_class;
+  GDBusProxyClass *proxy_class;
+
+  g_type_class_add_private (klass, sizeof (EGdbusBookDirectProxyPrivate));
+
+  gobject_class = G_OBJECT_CLASS (klass);
+  gobject_class->finalize     = e_gdbus_book_direct_proxy_finalize;
+  gobject_class->get_property = e_gdbus_book_direct_proxy_get_property;
+  gobject_class->set_property = e_gdbus_book_direct_proxy_set_property;
+
+  proxy_class = G_DBUS_PROXY_CLASS (klass);
+  proxy_class->g_signal = e_gdbus_book_direct_proxy_g_signal;
+  proxy_class->g_properties_changed = e_gdbus_book_direct_proxy_g_properties_changed;
+
+
+  e_gdbus_book_direct_override_properties (gobject_class, 1);
+}
+
+static void
+e_gdbus_book_direct_proxy_iface_init (EGdbusBookDirectIface *iface)
+{
+  iface->get_backend_path = e_gdbus_book_direct_proxy_get_backend_path;
+  iface->get_backend_name = e_gdbus_book_direct_proxy_get_backend_name;
+  iface->get_backend_config = e_gdbus_book_direct_proxy_get_backend_config;
+}
+
+/**
+ * e_gdbus_book_direct_proxy_new:
+ * @connection: A #GDBusConnection.
+ * @flags: Flags from the #GDBusProxyFlags enumeration.
+ * @name: (allow-none): A bus name (well-known or unique) or %NULL if @connection is not a message bus connection.
+ * @object_path: An object path.
+ * @cancellable: (allow-none): A #GCancellable or %NULL.
+ * @callback: A #GAsyncReadyCallback to call when the request is satisfied.
+ * @user_data: User data to pass to @callback.
+ *
+ * Asynchronously creates a proxy for the D-Bus interface <link linkend="gdbus-interface-org-gnome-evolution-dataserver-AddressBookDirect.top_of_page">org.gnome.evolution.dataserver.AddressBookDirect</link>. See g_dbus_proxy_new() for more details.
+ *
+ * When the operation is finished, @callback will be invoked in the <link linkend="g-main-context-push-thread-default">thread-default main loop</link> of the thread you are calling this method from.
+ * You can then call e_gdbus_book_direct_proxy_new_finish() to get the result of the operation.
+ *
+ * See e_gdbus_book_direct_proxy_new_sync() for the synchronous, blocking version of this constructor.
+ */
+void
+e_gdbus_book_direct_proxy_new (
+    GDBusConnection     *connection,
+    GDBusProxyFlags      flags,
+    const gchar         *name,
+    const gchar         *object_path,
+    GCancellable        *cancellable,
+    GAsyncReadyCallback  callback,
+    gpointer             user_data)
+{
+  g_async_initable_new_async (E_GDBUS_TYPE_BOOK_DIRECT_PROXY, G_PRIORITY_DEFAULT, cancellable, callback, user_data, "g-flags", flags, "g-name", name, "g-connection", connection, "g-object-path", object_path, "g-interface-name", "org.gnome.evolution.dataserver.AddressBookDirect", NULL);
+}
+
+/**
+ * e_gdbus_book_direct_proxy_new_finish:
+ * @res: The #GAsyncResult obtained from the #GAsyncReadyCallback passed to e_gdbus_book_direct_proxy_new().
+ * @error: Return location for error or %NULL
+ *
+ * Finishes an operation started with e_gdbus_book_direct_proxy_new().
+ *
+ * Returns: (transfer full) (type EGdbusBookDirectProxy): The constructed proxy object or %NULL if @error is set.
+ */
+EGdbusBookDirect *
+e_gdbus_book_direct_proxy_new_finish (
+    GAsyncResult        *res,
+    GError             **error)
+{
+  GObject *ret;
+  GObject *source_object;
+  source_object = g_async_result_get_source_object (res);
+  ret = g_async_initable_new_finish (G_ASYNC_INITABLE (source_object), res, error);
+  g_object_unref (source_object);
+  if (ret != NULL)
+    return E_GDBUS_BOOK_DIRECT (ret);
+  else
+    return NULL;
+}
+
+/**
+ * e_gdbus_book_direct_proxy_new_sync:
+ * @connection: A #GDBusConnection.
+ * @flags: Flags from the #GDBusProxyFlags enumeration.
+ * @name: (allow-none): A bus name (well-known or unique) or %NULL if @connection is not a message bus connection.
+ * @object_path: An object path.
+ * @cancellable: (allow-none): A #GCancellable or %NULL.
+ * @error: Return location for error or %NULL
+ *
+ * Synchronously creates a proxy for the D-Bus interface <link linkend="gdbus-interface-org-gnome-evolution-dataserver-AddressBookDirect.top_of_page">org.gnome.evolution.dataserver.AddressBookDirect</link>. See g_dbus_proxy_new_sync() for more details.
+ *
+ * The calling thread is blocked until a reply is received.
+ *
+ * See e_gdbus_book_direct_proxy_new() for the asynchronous version of this constructor.
+ *
+ * Returns: (transfer full) (type EGdbusBookDirectProxy): The constructed proxy object or %NULL if @error is set.
+ */
+EGdbusBookDirect *
+e_gdbus_book_direct_proxy_new_sync (
+    GDBusConnection     *connection,
+    GDBusProxyFlags      flags,
+    const gchar         *name,
+    const gchar         *object_path,
+    GCancellable        *cancellable,
+    GError             **error)
+{
+  GInitable *ret;
+  ret = g_initable_new (E_GDBUS_TYPE_BOOK_DIRECT_PROXY, cancellable, error, "g-flags", flags, "g-name", name, "g-connection", connection, "g-object-path", object_path, "g-interface-name", "org.gnome.evolution.dataserver.AddressBookDirect", NULL);
+  if (ret != NULL)
+    return E_GDBUS_BOOK_DIRECT (ret);
+  else
+    return NULL;
+}
+
+
+/**
+ * e_gdbus_book_direct_proxy_new_for_bus:
+ * @bus_type: A #GBusType.
+ * @flags: Flags from the #GDBusProxyFlags enumeration.
+ * @name: A bus name (well-known or unique).
+ * @object_path: An object path.
+ * @cancellable: (allow-none): A #GCancellable or %NULL.
+ * @callback: A #GAsyncReadyCallback to call when the request is satisfied.
+ * @user_data: User data to pass to @callback.
+ *
+ * Like e_gdbus_book_direct_proxy_new() but takes a #GBusType instead of a #GDBusConnection.
+ *
+ * When the operation is finished, @callback will be invoked in the <link linkend="g-main-context-push-thread-default">thread-default main loop</link> of the thread you are calling this method from.
+ * You can then call e_gdbus_book_direct_proxy_new_for_bus_finish() to get the result of the operation.
+ *
+ * See e_gdbus_book_direct_proxy_new_for_bus_sync() for the synchronous, blocking version of this constructor.
+ */
+void
+e_gdbus_book_direct_proxy_new_for_bus (
+    GBusType             bus_type,
+    GDBusProxyFlags      flags,
+    const gchar         *name,
+    const gchar         *object_path,
+    GCancellable        *cancellable,
+    GAsyncReadyCallback  callback,
+    gpointer             user_data)
+{
+  g_async_initable_new_async (E_GDBUS_TYPE_BOOK_DIRECT_PROXY, G_PRIORITY_DEFAULT, cancellable, callback, user_data, "g-flags", flags, "g-name", name, "g-bus-type", bus_type, "g-object-path", object_path, "g-interface-name", "org.gnome.evolution.dataserver.AddressBookDirect", NULL);
+}
+
+/**
+ * e_gdbus_book_direct_proxy_new_for_bus_finish:
+ * @res: The #GAsyncResult obtained from the #GAsyncReadyCallback passed to e_gdbus_book_direct_proxy_new_for_bus().
+ * @error: Return location for error or %NULL
+ *
+ * Finishes an operation started with e_gdbus_book_direct_proxy_new_for_bus().
+ *
+ * Returns: (transfer full) (type EGdbusBookDirectProxy): The constructed proxy object or %NULL if @error is set.
+ */
+EGdbusBookDirect *
+e_gdbus_book_direct_proxy_new_for_bus_finish (
+    GAsyncResult        *res,
+    GError             **error)
+{
+  GObject *ret;
+  GObject *source_object;
+  source_object = g_async_result_get_source_object (res);
+  ret = g_async_initable_new_finish (G_ASYNC_INITABLE (source_object), res, error);
+  g_object_unref (source_object);
+  if (ret != NULL)
+    return E_GDBUS_BOOK_DIRECT (ret);
+  else
+    return NULL;
+}
+
+/**
+ * e_gdbus_book_direct_proxy_new_for_bus_sync:
+ * @bus_type: A #GBusType.
+ * @flags: Flags from the #GDBusProxyFlags enumeration.
+ * @name: A bus name (well-known or unique).
+ * @object_path: An object path.
+ * @cancellable: (allow-none): A #GCancellable or %NULL.
+ * @error: Return location for error or %NULL
+ *
+ * Like e_gdbus_book_direct_proxy_new_sync() but takes a #GBusType instead of a #GDBusConnection.
+ *
+ * The calling thread is blocked until a reply is received.
+ *
+ * See e_gdbus_book_direct_proxy_new_for_bus() for the asynchronous version of this constructor.
+ *
+ * Returns: (transfer full) (type EGdbusBookDirectProxy): The constructed proxy object or %NULL if @error is set.
+ */
+EGdbusBookDirect *
+e_gdbus_book_direct_proxy_new_for_bus_sync (
+    GBusType             bus_type,
+    GDBusProxyFlags      flags,
+    const gchar         *name,
+    const gchar         *object_path,
+    GCancellable        *cancellable,
+    GError             **error)
+{
+  GInitable *ret;
+  ret = g_initable_new (E_GDBUS_TYPE_BOOK_DIRECT_PROXY, cancellable, error, "g-flags", flags, "g-name", name, "g-bus-type", bus_type, "g-object-path", object_path, "g-interface-name", "org.gnome.evolution.dataserver.AddressBookDirect", NULL);
+  if (ret != NULL)
+    return E_GDBUS_BOOK_DIRECT (ret);
+  else
+    return NULL;
+}
+
+
+/* ------------------------------------------------------------------------ */
+
+/**
+ * EGdbusBookDirectSkeleton:
+ *
+ * The #EGdbusBookDirectSkeleton structure contains only private data and should only be accessed using the provided API.
+ */
+
+/**
+ * EGdbusBookDirectSkeletonClass:
+ * @parent_class: The parent class.
+ *
+ * Class structure for #EGdbusBookDirectSkeleton.
+ */
+
+struct _EGdbusBookDirectSkeletonPrivate
+{
+  GValue *properties;
+  GList *changed_properties;
+  GSource *changed_properties_idle_source;
+  GMainContext *context;
+  GMutex lock;
+};
+
+static void
+_e_gdbus_book_direct_skeleton_handle_method_call (
+  GDBusConnection *connection,
+  const gchar *sender,
+  const gchar *object_path,
+  const gchar *interface_name,
+  const gchar *method_name,
+  GVariant *parameters,
+  GDBusMethodInvocation *invocation,
+  gpointer user_data)
+{
+  EGdbusBookDirectSkeleton *skeleton = E_GDBUS_BOOK_DIRECT_SKELETON (user_data);
+  _ExtendedGDBusMethodInfo *info;
+  GVariantIter iter;
+  GVariant *child;
+  GValue *paramv;
+  guint num_params;
+  guint num_extra;
+  guint n;
+  guint signal_id;
+  GValue return_value = G_VALUE_INIT;
+  info = (_ExtendedGDBusMethodInfo *) g_dbus_method_invocation_get_method_info (invocation);
+  g_assert (info != NULL);
+  num_params = g_variant_n_children (parameters);
+  num_extra = info->pass_fdlist ? 3 : 2;  paramv = g_new0 (GValue, num_params + num_extra);
+  n = 0;
+  g_value_init (&paramv[n], E_GDBUS_TYPE_BOOK_DIRECT);
+  g_value_set_object (&paramv[n++], skeleton);
+  g_value_init (&paramv[n], G_TYPE_DBUS_METHOD_INVOCATION);
+  g_value_set_object (&paramv[n++], invocation);
+  if (info->pass_fdlist)
+    {
+#ifdef G_OS_UNIX
+      g_value_init (&paramv[n], G_TYPE_UNIX_FD_LIST);
+      g_value_set_object (&paramv[n++], g_dbus_message_get_unix_fd_list (g_dbus_method_invocation_get_message (invocation)));
+#else
+      g_assert_not_reached ();
+#endif
+    }
+  g_variant_iter_init (&iter, parameters);
+  while ((child = g_variant_iter_next_value (&iter)) != NULL)
+    {
+      _ExtendedGDBusArgInfo *arg_info = (_ExtendedGDBusArgInfo *) info->parent_struct.in_args[n - num_extra];
+      if (arg_info->use_gvariant)
+        {
+          g_value_init (&paramv[n], G_TYPE_VARIANT);
+          g_value_set_variant (&paramv[n], child);
+          n++;
+        }
+      else
+        g_dbus_gvariant_to_gvalue (child, &paramv[n++]);
+      g_variant_unref (child);
+    }
+  signal_id = g_signal_lookup (info->signal_name, E_GDBUS_TYPE_BOOK_DIRECT);
+  g_value_init (&return_value, G_TYPE_BOOLEAN);
+  g_signal_emitv (paramv, signal_id, 0, &return_value);
+  if (!g_value_get_boolean (&return_value))
+    g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, G_DBUS_ERROR_UNKNOWN_METHOD, "Method %s is not implemented on interface %s", method_name, interface_name);
+  g_value_unset (&return_value);
+  for (n = 0; n < num_params + num_extra; n++)
+    g_value_unset (&paramv[n]);
+  g_free (paramv);
+}
+
+static GVariant *
+_e_gdbus_book_direct_skeleton_handle_get_property (
+  GDBusConnection *connection,
+  const gchar *sender,
+  const gchar *object_path,
+  const gchar *interface_name,
+  const gchar *property_name,
+  GError **error,
+  gpointer user_data)
+{
+  EGdbusBookDirectSkeleton *skeleton = E_GDBUS_BOOK_DIRECT_SKELETON (user_data);
+  GValue value = G_VALUE_INIT;
+  GParamSpec *pspec;
+  _ExtendedGDBusPropertyInfo *info;
+  GVariant *ret;
+  ret = NULL;
+  info = (_ExtendedGDBusPropertyInfo *) g_dbus_interface_info_lookup_property ((GDBusInterfaceInfo *) &_e_gdbus_book_direct_interface_info.parent_struct, property_name);
+  g_assert (info != NULL);
+  pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (skeleton), info->hyphen_name);
+  if (pspec == NULL)
+    {
+      g_set_error (error, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS, "No property with name %s", property_name);
+    }
+  else
+    {
+      g_value_init (&value, pspec->value_type);
+      g_object_get_property (G_OBJECT (skeleton), info->hyphen_name, &value);
+      ret = g_dbus_gvalue_to_gvariant (&value, G_VARIANT_TYPE (info->parent_struct.signature));
+      g_value_unset (&value);
+    }
+  return ret;
+}
+
+static gboolean
+_e_gdbus_book_direct_skeleton_handle_set_property (
+  GDBusConnection *connection,
+  const gchar *sender,
+  const gchar *object_path,
+  const gchar *interface_name,
+  const gchar *property_name,
+  GVariant *variant,
+  GError **error,
+  gpointer user_data)
+{
+  EGdbusBookDirectSkeleton *skeleton = E_GDBUS_BOOK_DIRECT_SKELETON (user_data);
+  GValue value = G_VALUE_INIT;
+  GParamSpec *pspec;
+  _ExtendedGDBusPropertyInfo *info;
+  gboolean ret;
+  ret = FALSE;
+  info = (_ExtendedGDBusPropertyInfo *) g_dbus_interface_info_lookup_property ((GDBusInterfaceInfo *) &_e_gdbus_book_direct_interface_info.parent_struct, property_name);
+  g_assert (info != NULL);
+  pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (skeleton), info->hyphen_name);
+  if (pspec == NULL)
+    {
+      g_set_error (error, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS, "No property with name %s", property_name);
+    }
+  else
+    {
+      if (info->use_gvariant)
+        g_value_set_variant (&value, variant);
+      else
+        g_dbus_gvariant_to_gvalue (variant, &value);
+      g_object_set_property (G_OBJECT (skeleton), info->hyphen_name, &value);
+      g_value_unset (&value);
+      ret = TRUE;
+    }
+  return ret;
+}
+
+static const GDBusInterfaceVTable _e_gdbus_book_direct_skeleton_vtable =
+{
+  _e_gdbus_book_direct_skeleton_handle_method_call,
+  _e_gdbus_book_direct_skeleton_handle_get_property,
+  _e_gdbus_book_direct_skeleton_handle_set_property
+};
+
+static GDBusInterfaceInfo *
+e_gdbus_book_direct_skeleton_dbus_interface_get_info (GDBusInterfaceSkeleton *skeleton)
+{
+  return e_gdbus_book_direct_interface_info ();
+}
+
+static GDBusInterfaceVTable *
+e_gdbus_book_direct_skeleton_dbus_interface_get_vtable (GDBusInterfaceSkeleton *skeleton)
+{
+  return (GDBusInterfaceVTable *) &_e_gdbus_book_direct_skeleton_vtable;
+}
+
+static GVariant *
+e_gdbus_book_direct_skeleton_dbus_interface_get_properties (GDBusInterfaceSkeleton *_skeleton)
+{
+  EGdbusBookDirectSkeleton *skeleton = E_GDBUS_BOOK_DIRECT_SKELETON (_skeleton);
+
+  GVariantBuilder builder;
+  guint n;
+  g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{sv}"));
+  if (_e_gdbus_book_direct_interface_info.parent_struct.properties == NULL)
+    goto out;
+  for (n = 0; _e_gdbus_book_direct_interface_info.parent_struct.properties[n] != NULL; n++)
+    {
+      GDBusPropertyInfo *info = _e_gdbus_book_direct_interface_info.parent_struct.properties[n];
+      if (info->flags & G_DBUS_PROPERTY_INFO_FLAGS_READABLE)
+        {
+          GVariant *value;
+          value = _e_gdbus_book_direct_skeleton_handle_get_property (g_dbus_interface_skeleton_get_connection (G_DBUS_INTERFACE_SKELETON (skeleton)), NULL, g_dbus_interface_skeleton_get_object_path (G_DBUS_INTERFACE_SKELETON (skeleton)), "org.gnome.evolution.dataserver.AddressBookDirect", info->name, NULL, skeleton);
+          if (value != NULL)
+            {
+              g_variant_take_ref (value);
+              g_variant_builder_add (&builder, "{sv}", info->name, value);
+              g_variant_unref (value);
+            }
+        }
+    }
+out:
+  return g_variant_builder_end (&builder);
+}
+
+static gboolean _e_gdbus_book_direct_emit_changed (gpointer user_data);
+
+static void
+e_gdbus_book_direct_skeleton_dbus_interface_flush (GDBusInterfaceSkeleton *_skeleton)
+{
+  EGdbusBookDirectSkeleton *skeleton = E_GDBUS_BOOK_DIRECT_SKELETON (_skeleton);
+  gboolean emit_changed = FALSE;
+
+  g_mutex_lock (&skeleton->priv->lock);
+  if (skeleton->priv->changed_properties_idle_source != NULL)
+    {
+      g_source_destroy (skeleton->priv->changed_properties_idle_source);
+      skeleton->priv->changed_properties_idle_source = NULL;
+      emit_changed = TRUE;
+    }
+  g_mutex_unlock (&skeleton->priv->lock);
+
+  if (emit_changed)
+    _e_gdbus_book_direct_emit_changed (skeleton);
+}
+
+static void e_gdbus_book_direct_skeleton_iface_init (EGdbusBookDirectIface *iface);
+G_DEFINE_TYPE_WITH_CODE (EGdbusBookDirectSkeleton, e_gdbus_book_direct_skeleton, G_TYPE_DBUS_INTERFACE_SKELETON,
+                         G_IMPLEMENT_INTERFACE (E_GDBUS_TYPE_BOOK_DIRECT, e_gdbus_book_direct_skeleton_iface_init));
+
+static void
+e_gdbus_book_direct_skeleton_finalize (GObject *object)
+{
+  EGdbusBookDirectSkeleton *skeleton = E_GDBUS_BOOK_DIRECT_SKELETON (object);
+  guint n;
+  for (n = 0; n < 3; n++)
+    g_value_unset (&skeleton->priv->properties[n]);
+  g_free (skeleton->priv->properties);
+  g_list_free_full (skeleton->priv->changed_properties, (GDestroyNotify) _changed_property_free);
+  if (skeleton->priv->changed_properties_idle_source != NULL)
+    g_source_destroy (skeleton->priv->changed_properties_idle_source);
+  g_main_context_unref (skeleton->priv->context);
+  g_mutex_clear (&skeleton->priv->lock);
+  G_OBJECT_CLASS (e_gdbus_book_direct_skeleton_parent_class)->finalize (object);
+}
+
+static void
+e_gdbus_book_direct_skeleton_get_property (GObject      *object,
+  guint         prop_id,
+  GValue       *value,
+  GParamSpec   *pspec)
+{
+  EGdbusBookDirectSkeleton *skeleton = E_GDBUS_BOOK_DIRECT_SKELETON (object);
+  g_assert (prop_id != 0 && prop_id - 1 < 3);
+  g_mutex_lock (&skeleton->priv->lock);
+  g_value_copy (&skeleton->priv->properties[prop_id - 1], value);
+  g_mutex_unlock (&skeleton->priv->lock);
+}
+
+static gboolean
+_e_gdbus_book_direct_emit_changed (gpointer user_data)
+{
+  EGdbusBookDirectSkeleton *skeleton = E_GDBUS_BOOK_DIRECT_SKELETON (user_data);
+  GList *l;
+  GVariantBuilder builder;
+  GVariantBuilder invalidated_builder;
+  guint num_changes;
+
+  g_mutex_lock (&skeleton->priv->lock);
+  g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{sv}"));
+  g_variant_builder_init (&invalidated_builder, G_VARIANT_TYPE ("as"));
+  for (l = skeleton->priv->changed_properties, num_changes = 0; l != NULL; l = l->next)
+    {
+      ChangedProperty *cp = l->data;
+      GVariant *variant;
+      const GValue *cur_value;
+
+      cur_value = &skeleton->priv->properties[cp->prop_id - 1];
+      if (!_g_value_equal (cur_value, &cp->orig_value))
+        {
+          variant = g_dbus_gvalue_to_gvariant (cur_value, G_VARIANT_TYPE (cp->info->parent_struct.signature));
+          g_variant_builder_add (&builder, "{sv}", cp->info->parent_struct.name, variant);
+          g_variant_unref (variant);
+          num_changes++;
+        }
+    }
+  if (num_changes > 0)
+    {
+      GList *connections, *ll;
+      GVariant *signal_variant;
+      signal_variant = g_variant_ref_sink (g_variant_new ("(sa{sv}as)", "org.gnome.evolution.dataserver.AddressBookDirect",
+                                           &builder, &invalidated_builder));
+      connections = g_dbus_interface_skeleton_get_connections (G_DBUS_INTERFACE_SKELETON (skeleton));
+      for (ll = connections; ll != NULL; ll = ll->next)
+        {
+          GDBusConnection *connection = ll->data;
+
+          g_dbus_connection_emit_signal (connection,
+                                         NULL, g_dbus_interface_skeleton_get_object_path (G_DBUS_INTERFACE_SKELETON (skeleton)),
+                                         "org.freedesktop.DBus.Properties",
+                                         "PropertiesChanged",
+                                         signal_variant,
+                                         NULL);
+        }
+      g_variant_unref (signal_variant);
+      g_list_free_full (connections, g_object_unref);
+    }
+  else
+    {
+      g_variant_builder_clear (&builder);
+      g_variant_builder_clear (&invalidated_builder);
+    }
+  g_list_free_full (skeleton->priv->changed_properties, (GDestroyNotify) _changed_property_free);
+  skeleton->priv->changed_properties = NULL;
+  skeleton->priv->changed_properties_idle_source = NULL;
+  g_mutex_unlock (&skeleton->priv->lock);
+  return FALSE;
+}
+
+static void
+_e_gdbus_book_direct_schedule_emit_changed (EGdbusBookDirectSkeleton *skeleton, const _ExtendedGDBusPropertyInfo *info, guint prop_id, const GValue *orig_value)
+{
+  ChangedProperty *cp;
+  GList *l;
+  cp = NULL;
+  for (l = skeleton->priv->changed_properties; l != NULL; l = l->next)
+    {
+      ChangedProperty *i_cp = l->data;
+      if (i_cp->info == info)
+        {
+          cp = i_cp;
+          break;
+        }
+    }
+  if (cp == NULL)
+    {
+      cp = g_new0 (ChangedProperty, 1);
+      cp->prop_id = prop_id;
+      cp->info = info;
+      skeleton->priv->changed_properties = g_list_prepend (skeleton->priv->changed_properties, cp);
+      g_value_init (&cp->orig_value, G_VALUE_TYPE (orig_value));
+      g_value_copy (orig_value, &cp->orig_value);
+    }
+}
+
+static void
+e_gdbus_book_direct_skeleton_notify (GObject      *object,
+  GParamSpec *pspec)
+{
+  EGdbusBookDirectSkeleton *skeleton = E_GDBUS_BOOK_DIRECT_SKELETON (object);
+  g_mutex_lock (&skeleton->priv->lock);
+  if (skeleton->priv->changed_properties != NULL &&
+      skeleton->priv->changed_properties_idle_source == NULL)
+    {
+      skeleton->priv->changed_properties_idle_source = g_idle_source_new ();
+      g_source_set_priority (skeleton->priv->changed_properties_idle_source, G_PRIORITY_DEFAULT);
+      g_source_set_callback (skeleton->priv->changed_properties_idle_source, _e_gdbus_book_direct_emit_changed, g_object_ref (skeleton), (GDestroyNotify) g_object_unref);
+      g_source_attach (skeleton->priv->changed_properties_idle_source, skeleton->priv->context);
+      g_source_unref (skeleton->priv->changed_properties_idle_source);
+    }
+  g_mutex_unlock (&skeleton->priv->lock);
+}
+
+static void
+e_gdbus_book_direct_skeleton_set_property (GObject      *object,
+  guint         prop_id,
+  const GValue *value,
+  GParamSpec   *pspec)
+{
+  EGdbusBookDirectSkeleton *skeleton = E_GDBUS_BOOK_DIRECT_SKELETON (object);
+  g_assert (prop_id != 0 && prop_id - 1 < 3);
+  g_mutex_lock (&skeleton->priv->lock);
+  g_object_freeze_notify (object);
+  if (!_g_value_equal (value, &skeleton->priv->properties[prop_id - 1]))
+    {
+      if (g_dbus_interface_skeleton_get_connection (G_DBUS_INTERFACE_SKELETON (skeleton)) != NULL)
+        _e_gdbus_book_direct_schedule_emit_changed (skeleton, _e_gdbus_book_direct_property_info_pointers[prop_id - 1], prop_id, &skeleton->priv->properties[prop_id - 1]);
+      g_value_copy (value, &skeleton->priv->properties[prop_id - 1]);
+      g_object_notify_by_pspec (object, pspec);
+    }
+  g_mutex_unlock (&skeleton->priv->lock);
+  g_object_thaw_notify (object);
+}
+
+static void
+e_gdbus_book_direct_skeleton_init (EGdbusBookDirectSkeleton *skeleton)
+{
+  skeleton->priv = G_TYPE_INSTANCE_GET_PRIVATE (skeleton, E_GDBUS_TYPE_BOOK_DIRECT_SKELETON, EGdbusBookDirectSkeletonPrivate);
+  g_mutex_init (&skeleton->priv->lock);
+  skeleton->priv->context = g_main_context_ref_thread_default ();
+  skeleton->priv->properties = g_new0 (GValue, 3);
+  g_value_init (&skeleton->priv->properties[0], G_TYPE_STRING);
+  g_value_init (&skeleton->priv->properties[1], G_TYPE_STRING);
+  g_value_init (&skeleton->priv->properties[2], G_TYPE_STRING);
+}
+
+static const gchar *
+e_gdbus_book_direct_skeleton_get_backend_path (EGdbusBookDirect *object)
+{
+  EGdbusBookDirectSkeleton *skeleton = E_GDBUS_BOOK_DIRECT_SKELETON (object);
+  const gchar *value;
+  g_mutex_lock (&skeleton->priv->lock);
+  value = g_value_get_string (&(skeleton->priv->properties[0]));
+  g_mutex_unlock (&skeleton->priv->lock);
+  return value;
+}
+
+static const gchar *
+e_gdbus_book_direct_skeleton_get_backend_name (EGdbusBookDirect *object)
+{
+  EGdbusBookDirectSkeleton *skeleton = E_GDBUS_BOOK_DIRECT_SKELETON (object);
+  const gchar *value;
+  g_mutex_lock (&skeleton->priv->lock);
+  value = g_value_get_string (&(skeleton->priv->properties[1]));
+  g_mutex_unlock (&skeleton->priv->lock);
+  return value;
+}
+
+static const gchar *
+e_gdbus_book_direct_skeleton_get_backend_config (EGdbusBookDirect *object)
+{
+  EGdbusBookDirectSkeleton *skeleton = E_GDBUS_BOOK_DIRECT_SKELETON (object);
+  const gchar *value;
+  g_mutex_lock (&skeleton->priv->lock);
+  value = g_value_get_string (&(skeleton->priv->properties[2]));
+  g_mutex_unlock (&skeleton->priv->lock);
+  return value;
+}
+
+static void
+e_gdbus_book_direct_skeleton_class_init (EGdbusBookDirectSkeletonClass *klass)
+{
+  GObjectClass *gobject_class;
+  GDBusInterfaceSkeletonClass *skeleton_class;
+
+  g_type_class_add_private (klass, sizeof (EGdbusBookDirectSkeletonPrivate));
+
+  gobject_class = G_OBJECT_CLASS (klass);
+  gobject_class->finalize = e_gdbus_book_direct_skeleton_finalize;
+  gobject_class->get_property = e_gdbus_book_direct_skeleton_get_property;
+  gobject_class->set_property = e_gdbus_book_direct_skeleton_set_property;
+  gobject_class->notify       = e_gdbus_book_direct_skeleton_notify;
+
+
+  e_gdbus_book_direct_override_properties (gobject_class, 1);
+
+  skeleton_class = G_DBUS_INTERFACE_SKELETON_CLASS (klass);
+  skeleton_class->get_info = e_gdbus_book_direct_skeleton_dbus_interface_get_info;
+  skeleton_class->get_properties = e_gdbus_book_direct_skeleton_dbus_interface_get_properties;
+  skeleton_class->flush = e_gdbus_book_direct_skeleton_dbus_interface_flush;
+  skeleton_class->get_vtable = e_gdbus_book_direct_skeleton_dbus_interface_get_vtable;
+}
+
+static void
+e_gdbus_book_direct_skeleton_iface_init (EGdbusBookDirectIface *iface)
+{
+  iface->get_backend_path = e_gdbus_book_direct_skeleton_get_backend_path;
+  iface->get_backend_name = e_gdbus_book_direct_skeleton_get_backend_name;
+  iface->get_backend_config = e_gdbus_book_direct_skeleton_get_backend_config;
+}
+
+/**
+ * e_gdbus_book_direct_skeleton_new:
+ *
+ * Creates a skeleton object for the D-Bus interface <link linkend="gdbus-interface-org-gnome-evolution-dataserver-AddressBookDirect.top_of_page">org.gnome.evolution.dataserver.AddressBookDirect</link>.
+ *
+ * Returns: (transfer full) (type EGdbusBookDirectSkeleton): The skeleton object.
+ */
+EGdbusBookDirect *
+e_gdbus_book_direct_skeleton_new (void)
+{
+  return E_GDBUS_BOOK_DIRECT (g_object_new (E_GDBUS_TYPE_BOOK_DIRECT_SKELETON, NULL));
+}
+
diff --git a/addressbook/libegdbus/e-gdbus-book-direct.h b/addressbook/libegdbus/e-gdbus-book-direct.h
new file mode 100644
index 0000000..9395d45
--- /dev/null
+++ b/addressbook/libegdbus/e-gdbus-book-direct.h
@@ -0,0 +1,173 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 2012 Intel Corporation
+ *
+ * This program 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; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program 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 the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ * Author: Tristan Van Berkom <tristanvb openismus com>
+ */
+
+#ifndef E_GDBUS_BOOK_DIRECT_H
+#define E_GDBUS_BOOK_DIRECT_H
+
+#include <gio/gio.h>
+
+#include <libedataserver/libedataserver.h>
+
+G_BEGIN_DECLS
+
+
+/* ------------------------------------------------------------------------ */
+/* Declarations for org.gnome.evolution.dataserver.AddressBookDirect */
+
+#define E_GDBUS_TYPE_BOOK_DIRECT (e_gdbus_book_direct_get_type ())
+#define E_GDBUS_BOOK_DIRECT(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), E_GDBUS_TYPE_BOOK_DIRECT, EGdbusBookDirect))
+#define E_GDBUS_IS_BOOK_DIRECT(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), E_GDBUS_TYPE_BOOK_DIRECT))
+#define E_GDBUS_BOOK_DIRECT_GET_IFACE(o) (G_TYPE_INSTANCE_GET_INTERFACE ((o), E_GDBUS_TYPE_BOOK_DIRECT, EGdbusBookDirectIface))
+
+struct _EGdbusBookDirect;
+typedef struct _EGdbusBookDirect EGdbusBookDirect;
+typedef struct _EGdbusBookDirectIface EGdbusBookDirectIface;
+
+struct _EGdbusBookDirectIface
+{
+  GTypeInterface parent_iface;
+
+  const gchar * (*get_backend_config) (EGdbusBookDirect *object);
+
+  const gchar * (*get_backend_name) (EGdbusBookDirect *object);
+
+  const gchar * (*get_backend_path) (EGdbusBookDirect *object);
+
+};
+
+GType e_gdbus_book_direct_get_type (void) G_GNUC_CONST;
+
+GDBusInterfaceInfo *e_gdbus_book_direct_interface_info (void);
+guint e_gdbus_book_direct_override_properties (GObjectClass *klass, guint property_id_begin);
+
+
+/* D-Bus property accessors: */
+const gchar *e_gdbus_book_direct_get_backend_path (EGdbusBookDirect *object);
+gchar *e_gdbus_book_direct_dup_backend_path (EGdbusBookDirect *object);
+void e_gdbus_book_direct_set_backend_path (EGdbusBookDirect *object, const gchar *value);
+
+const gchar *e_gdbus_book_direct_get_backend_name (EGdbusBookDirect *object);
+gchar *e_gdbus_book_direct_dup_backend_name (EGdbusBookDirect *object);
+void e_gdbus_book_direct_set_backend_name (EGdbusBookDirect *object, const gchar *value);
+
+const gchar *e_gdbus_book_direct_get_backend_config (EGdbusBookDirect *object);
+gchar *e_gdbus_book_direct_dup_backend_config (EGdbusBookDirect *object);
+void e_gdbus_book_direct_set_backend_config (EGdbusBookDirect *object, const gchar *value);
+
+
+/* ---- */
+
+#define E_GDBUS_TYPE_BOOK_DIRECT_PROXY (e_gdbus_book_direct_proxy_get_type ())
+#define E_GDBUS_BOOK_DIRECT_PROXY(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), E_GDBUS_TYPE_BOOK_DIRECT_PROXY, EGdbusBookDirectProxy))
+#define E_GDBUS_BOOK_DIRECT_PROXY_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), E_GDBUS_TYPE_BOOK_DIRECT_PROXY, EGdbusBookDirectProxyClass))
+#define E_GDBUS_BOOK_DIRECT_PROXY_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), E_GDBUS_TYPE_BOOK_DIRECT_PROXY, EGdbusBookDirectProxyClass))
+#define E_GDBUS_IS_BOOK_DIRECT_PROXY(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), E_GDBUS_TYPE_BOOK_DIRECT_PROXY))
+#define E_GDBUS_IS_BOOK_DIRECT_PROXY_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), E_GDBUS_TYPE_BOOK_DIRECT_PROXY))
+
+typedef struct _EGdbusBookDirectProxy EGdbusBookDirectProxy;
+typedef struct _EGdbusBookDirectProxyClass EGdbusBookDirectProxyClass;
+typedef struct _EGdbusBookDirectProxyPrivate EGdbusBookDirectProxyPrivate;
+
+struct _EGdbusBookDirectProxy
+{
+  /*< private >*/
+  GDBusProxy parent_instance;
+  EGdbusBookDirectProxyPrivate *priv;
+};
+
+struct _EGdbusBookDirectProxyClass
+{
+  GDBusProxyClass parent_class;
+};
+
+GType e_gdbus_book_direct_proxy_get_type (void) G_GNUC_CONST;
+
+void e_gdbus_book_direct_proxy_new (
+    GDBusConnection     *connection,
+    GDBusProxyFlags      flags,
+    const gchar         *name,
+    const gchar         *object_path,
+    GCancellable        *cancellable,
+    GAsyncReadyCallback  callback,
+    gpointer             user_data);
+EGdbusBookDirect *e_gdbus_book_direct_proxy_new_finish (
+    GAsyncResult        *res,
+    GError             **error);
+EGdbusBookDirect *e_gdbus_book_direct_proxy_new_sync (
+    GDBusConnection     *connection,
+    GDBusProxyFlags      flags,
+    const gchar         *name,
+    const gchar         *object_path,
+    GCancellable        *cancellable,
+    GError             **error);
+
+void e_gdbus_book_direct_proxy_new_for_bus (
+    GBusType             bus_type,
+    GDBusProxyFlags      flags,
+    const gchar         *name,
+    const gchar         *object_path,
+    GCancellable        *cancellable,
+    GAsyncReadyCallback  callback,
+    gpointer             user_data);
+EGdbusBookDirect *e_gdbus_book_direct_proxy_new_for_bus_finish (
+    GAsyncResult        *res,
+    GError             **error);
+EGdbusBookDirect *e_gdbus_book_direct_proxy_new_for_bus_sync (
+    GBusType             bus_type,
+    GDBusProxyFlags      flags,
+    const gchar         *name,
+    const gchar         *object_path,
+    GCancellable        *cancellable,
+    GError             **error);
+
+
+/* ---- */
+
+#define E_GDBUS_TYPE_BOOK_DIRECT_SKELETON (e_gdbus_book_direct_skeleton_get_type ())
+#define E_GDBUS_BOOK_DIRECT_SKELETON(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), E_GDBUS_TYPE_BOOK_DIRECT_SKELETON, EGdbusBookDirectSkeleton))
+#define E_GDBUS_BOOK_DIRECT_SKELETON_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), E_GDBUS_TYPE_BOOK_DIRECT_SKELETON, EGdbusBookDirectSkeletonClass))
+#define E_GDBUS_BOOK_DIRECT_SKELETON_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), E_GDBUS_TYPE_BOOK_DIRECT_SKELETON, EGdbusBookDirectSkeletonClass))
+#define E_GDBUS_IS_BOOK_DIRECT_SKELETON(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), E_GDBUS_TYPE_BOOK_DIRECT_SKELETON))
+#define E_GDBUS_IS_BOOK_DIRECT_SKELETON_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), E_GDBUS_TYPE_BOOK_DIRECT_SKELETON))
+
+typedef struct _EGdbusBookDirectSkeleton EGdbusBookDirectSkeleton;
+typedef struct _EGdbusBookDirectSkeletonClass EGdbusBookDirectSkeletonClass;
+typedef struct _EGdbusBookDirectSkeletonPrivate EGdbusBookDirectSkeletonPrivate;
+
+struct _EGdbusBookDirectSkeleton
+{
+  /*< private >*/
+  GDBusInterfaceSkeleton parent_instance;
+  EGdbusBookDirectSkeletonPrivate *priv;
+};
+
+struct _EGdbusBookDirectSkeletonClass
+{
+  GDBusInterfaceSkeletonClass parent_class;
+};
+
+GType e_gdbus_book_direct_skeleton_get_type (void) G_GNUC_CONST;
+
+EGdbusBookDirect *e_gdbus_book_direct_skeleton_new (void);
+
+
+G_END_DECLS
+
+#endif /* E_GDBUS_BOOK_DIRECT_H */
diff --git a/calendar/backends/contacts/Makefile.am b/calendar/backends/contacts/Makefile.am
index 02acf51..9e7fa18 100644
--- a/calendar/backends/contacts/Makefile.am
+++ b/calendar/backends/contacts/Makefile.am
@@ -26,6 +26,7 @@ libecalbackendcontacts_la_LIBADD =					\
 	$(top_builddir)/calendar/libecal/libecal-1.2.la			\
 	$(top_builddir)/calendar/libedata-cal/libedata-cal-1.2.la	\
 	$(top_builddir)/addressbook/libebook/libebook-1.2.la		\
+	$(top_builddir)/addressbook/libebook-contacts/libebook-contacts-1.2.la		\
 	$(top_builddir)/libedataserver/libedataserver-1.2.la		\
 	$(top_builddir)/libebackend/libebackend-1.2.la			\
 	$(EVOLUTION_CALENDAR_LIBS)					\
diff --git a/configure.ac b/configure.ac
index 1128e30..dfeb365 100644
--- a/configure.ac
+++ b/configure.ac
@@ -124,6 +124,10 @@ LIBEBOOK_CURRENT=17
 LIBEBOOK_REVISION=1
 LIBEBOOK_AGE=3
 
+LIBEBOOK_CONTACTS_CURRENT=0
+LIBEBOOK_CONTACTS_REVISION=0
+LIBEBOOK_CONTACTS_AGE=0
+
 LIBCAMEL_CURRENT=43
 LIBCAMEL_REVISION=0
 LIBCAMEL_AGE=0
@@ -144,6 +148,9 @@ AC_SUBST(LIBECAL_AGE)
 AC_SUBST(LIBEDATACAL_CURRENT)
 AC_SUBST(LIBEDATACAL_REVISION)
 AC_SUBST(LIBEDATACAL_AGE)
+AC_SUBST(LIBEBOOK_CONTACTS_CURRENT)
+AC_SUBST(LIBEBOOK_CONTACTS_REVISION)
+AC_SUBST(LIBEBOOK_CONTACTS_AGE)
 AC_SUBST(LIBEBOOK_CURRENT)
 AC_SUBST(LIBEBOOK_REVISION)
 AC_SUBST(LIBEBOOK_AGE)
@@ -1577,6 +1584,8 @@ evolution-data-server.pc
 addressbook/Makefile
 addressbook/libebook/Makefile
 addressbook/libebook/libebook.pc
+addressbook/libebook-contacts/Makefile
+addressbook/libebook-contacts/libebook-contacts.pc
 addressbook/libedata-book/Makefile
 addressbook/libedata-book/libedata-book.pc
 addressbook/libegdbus/Makefile
diff --git a/docs/reference/addressbook/libebook/Makefile.am b/docs/reference/addressbook/libebook/Makefile.am
index 1d96640..c8bf347 100644
--- a/docs/reference/addressbook/libebook/Makefile.am
+++ b/docs/reference/addressbook/libebook/Makefile.am
@@ -31,6 +31,7 @@ GTKDOC_CFLAGS = \
 	$(CAMEL_CFLAGS)
 
 GTKDOC_LIBS = \
+	$(top_builddir)/addressbook/libebook-contacts/libebook-contacts-1.2.la		\
 	$(top_builddir)/addressbook/libebook/libebook-1.2.la	\
 	$(top_builddir)/libedataserver/libedataserver-1.2.la	\
 	$(EVOLUTION_ADDRESSBOOK_LIBS)				\
diff --git a/docs/reference/addressbook/libedata-book/Makefile.am b/docs/reference/addressbook/libedata-book/Makefile.am
index e984856..0e71940 100644
--- a/docs/reference/addressbook/libedata-book/Makefile.am
+++ b/docs/reference/addressbook/libedata-book/Makefile.am
@@ -32,6 +32,7 @@ GTKDOC_CFLAGS = \
 
 GTKDOC_LIBS = \
 	$(top_builddir)/addressbook/libedata-book/libedata-book-1.2.la	\
+	$(top_builddir)/addressbook/libebook-contacts/libebook-contacts-1.2.la	\
 	$(top_builddir)/addressbook/libebook/libebook-1.2.la		\
 	$(top_builddir)/libebackend/libebackend-1.2.la			\
 	$(top_builddir)/libedataserver/libedataserver-1.2.la		\
diff --git a/tests/libebook/Makefile.am b/tests/libebook/Makefile.am
index 7fff918..3dd07bb 100644
--- a/tests/libebook/Makefile.am
+++ b/tests/libebook/Makefile.am
@@ -2,8 +2,6 @@ SUBDIRS = vcard client
 
 @GNOME_CODE_COVERAGE_RULES@
 
-### EBook Tests (deprecated) ###
-
 noinst_LTLIBRARIES = libebook-test-utils.la
 libebook_test_utils_la_SOURCES = ebook-test-utils.c ebook-test-utils.h
 
@@ -23,6 +21,7 @@ libebook_test_utils_la_CPPFLAGS = \
 	$(NULL)
 
 libebook_test_utils_la_LIBADD = \
+	$(top_builddir)/addressbook/libebook-contacts/libebook-contacts-1.2.la	\
 	$(top_builddir)/addressbook/libebook/libebook-1.2.la	\
 	$(top_builddir)/tests/test-server-utils/libetestserverutils.la	\
 	$(EVOLUTION_ADDRESSBOOK_LIBS)                           \
diff --git a/tests/libebook/client/Makefile.am b/tests/libebook/client/Makefile.am
index d67ad31..679334a 100644
--- a/tests/libebook/client/Makefile.am
+++ b/tests/libebook/client/Makefile.am
@@ -18,6 +18,7 @@ libclient_test_utils_la_CPPFLAGS =				\
 	$(NULL)
 
 libclient_test_utils_la_LIBADD = 				\
+	$(top_builddir)/addressbook/libebook-contacts/libebook-contacts-1.2.la		\
 	$(top_builddir)/addressbook/libebook/libebook-1.2.la	\
 	$(top_builddir)/tests/test-server-utils/libetestserverutils.la	\
 	$(EVOLUTION_ADDRESSBOOK_LIBS)				\
diff --git a/tests/libebook/vcard/Makefile.am b/tests/libebook/vcard/Makefile.am
index bc20146..1f510bc 100644
--- a/tests/libebook/vcard/Makefile.am
+++ b/tests/libebook/vcard/Makefile.am
@@ -9,6 +9,7 @@ dump_vcard_CPPFLAGS = \
 	$(CAMEL_CFLAGS)
 
 dump_vcard_LDADD = 						\
+	$(top_builddir)/addressbook/libebook-contacts/libebook-contacts-1.2.la		\
 	$(top_builddir)/addressbook/libebook/libebook-1.2.la	\
 	$(top_builddir)/libedataserver/libedataserver-1.2.la	\
 	$(EVOLUTION_ADDRESSBOOK_LIBS)				\
diff --git a/vala/EBook-1.2.metadata b/vala/EBook-1.2.metadata
index 8e0106c..69015ed 100644
--- a/vala/EBook-1.2.metadata
+++ b/vala/EBook-1.2.metadata
@@ -1,26 +1,3 @@
 BookClientView.objects_added#signal.object type="GLib.List<weak void*>"
 BookClientView.objects_removed#signal.object type="GLib.List<weak void*>"
 BookClientView.objects_modified#signal.object type="GLib.List<weak void*>"
-Contact.get skip
-Contact.get_const skip
-Contact.set skip
-ContactName.family unowned=false
-ContactName.given unowned=false
-ContactName.additional unowned=false
-ContactName.prefixes unowned=false
-ContactName.suffixes unowned=false
-ContactAddress.address_format unowned=false
-ContactAddress.code unowned=false
-ContactAddress.country unowned=false
-ContactAddress.ext unowned=false
-ContactAddress.locality unowned=false
-ContactAddress.po unowned=false
-ContactAddress.region unowned=false
-ContactAddress.street unowned=false
-ContactPhoto.get_inlined nullable=true
-ContactPhoto.get_mime_type nullable=true
-ContactPhoto.get_uri nullable=true
-VCard.get_attribute nullable=true
-VCard.get_attribute_if_parsed nullable=true
-VCardAttribute.get_group nullable=true
-VCardAttribute.get_value nullable=true
diff --git a/vala/EBookContacts-1.2.metadata b/vala/EBookContacts-1.2.metadata
new file mode 100644
index 0000000..7b30232
--- /dev/null
+++ b/vala/EBookContacts-1.2.metadata
@@ -0,0 +1,23 @@
+Contact.get skip
+Contact.get_const skip
+Contact.set skip
+ContactName.family unowned=false
+ContactName.given unowned=false
+ContactName.additional unowned=false
+ContactName.prefixes unowned=false
+ContactName.suffixes unowned=false
+ContactAddress.address_format unowned=false
+ContactAddress.code unowned=false
+ContactAddress.country unowned=false
+ContactAddress.ext unowned=false
+ContactAddress.locality unowned=false
+ContactAddress.po unowned=false
+ContactAddress.region unowned=false
+ContactAddress.street unowned=false
+ContactPhoto.get_inlined nullable=true
+ContactPhoto.get_mime_type nullable=true
+ContactPhoto.get_uri nullable=true
+VCard.get_attribute nullable=true
+VCard.get_attribute_if_parsed nullable=true
+VCardAttribute.get_group nullable=true
+VCardAttribute.get_value nullable=true
diff --git a/vala/Makefile.am b/vala/Makefile.am
index 44913da..5265332 100644
--- a/vala/Makefile.am
+++ b/vala/Makefile.am
@@ -2,15 +2,21 @@ vapidir = $(datarootdir)/vala/vapi
 vapi_DATA = \
 	libedataserver-1.2.vapi \
 	libebook-1.2.vapi \
+	libebook-contacts-1.2.vapi \
+	libecalendar-1.2.vapi \
 	$(NULL)
 dist_vapi_DATA = \
 	libedataserver-1.2.deps \
 	libebook-1.2.deps \
+	libebook-contacts-1.2.deps \
+	libecalendar-1.2.deps \
 	$(NULL)
 
 EXTRA_DIST = \
 	EBook-1.2.metadata \
-	libebook-1.2-custom.vala \
+	EBookContacts-1.2.metadata \
+	libebook-contacts-1.2-custom.vala \
+	ECalendar-1.2.metadata \
 	EDataServer-1.2.metadata \
 	$(NULL)
 
@@ -32,18 +38,45 @@ libedataserver-1.2.vapi: $(top_builddir)/libedataserver/EDataServer-1.2.gir  lib
 		$< \
 		$(NULL)
 
-libebook-1.2.vapi: $(top_builddir)/addressbook/libebook/EBook-1.2.gir libedataserver-1.2.vapi libebook-1.2-custom.vala libebook-1.2.deps
+libecalendar-1.2.vapi: $(top_builddir)/calendar/libecal/ECalendar-1.2.gir libedataserver-1.2.vapi
+	$(VAPIGEN_V)$(VAPIGEN) \
+		--vapidir=. \
+		--girdir=$(top_builddir)/libedataserver \
+		--pkg libedataserver-1.2 \
+		--pkg gio-2.0 \
+		--pkg libxml-2.0 \
+		--library libecalendar-1.2 \
+		--metadatadir=$(srcdir) \
+		$< \
+		$(NULL)
+
+libebook-contacts-1.2.vapi: $(top_builddir)/addressbook/libebook-contacts/EBookContacts-1.2.gir libedataserver-1.2.vapi libebook-contacts-1.2-custom.vala
+	$(VAPIGEN_V)$(VAPIGEN) \
+		--vapidir=. \
+		--vapidir=$(srcdir) \
+		--girdir=$(top_builddir)/libedataserver \
+		--pkg libedataserver-1.2 \
+		--pkg gio-2.0 \
+		--pkg libxml-2.0 \
+		--library libebook-contacts-1.2 \
+		--metadatadir=$(srcdir) \
+		$< \
+		$(srcdir)/libebook-contacts-1.2-custom.vala \
+		$(NULL)
+
+libebook-1.2.vapi: $(top_builddir)/addressbook/libebook/EBook-1.2.gir libedataserver-1.2.vapi libebook-contacts-1.2.vapi
 	$(VAPIGEN_V)$(VAPIGEN) \
 		--vapidir=. \
 		--vapidir=$(srcdir) \
 		--girdir=$(top_builddir)/libedataserver \
+		--girdir=$(top_builddir)/addressbook/libebook-contacts \
 		--pkg libedataserver-1.2 \
+		--pkg libebook-contacts-1.2 \
 		--pkg gio-2.0 \
 		--pkg libxml-2.0 \
 		--library libebook-1.2 \
 		--metadatadir=$(srcdir) \
 		$< \
-		$(srcdir)/libebook-1.2-custom.vala \
 		$(NULL)
 
 CLEANFILES = \
diff --git a/vala/libebook-1.2.deps b/vala/libebook-1.2.deps
index ef26377..dd769f0 100644
--- a/vala/libebook-1.2.deps
+++ b/vala/libebook-1.2.deps
@@ -1,3 +1,3 @@
-libedataserver-1.2
+libebook-contacts-1.2
 libxml-2.0
 gio-2.0
diff --git a/vala/libebook-1.2-custom.vala b/vala/libebook-contacts-1.2-custom.vala
similarity index 100%
rename from vala/libebook-1.2-custom.vala
rename to vala/libebook-contacts-1.2-custom.vala
diff --git a/vala/libebook-contacts-1.2.deps b/vala/libebook-contacts-1.2.deps
new file mode 100644
index 0000000..ef26377
--- /dev/null
+++ b/vala/libebook-contacts-1.2.deps
@@ -0,0 +1,3 @@
+libedataserver-1.2
+libxml-2.0
+gio-2.0



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