[evolution-mapi] Make it work with API changes for 3.5.3



commit 2ae3ff016b0bbffb78c1b7cb11098b7f99c256bf
Author: Milan Crha <mcrha redhat com>
Date:   Fri Jun 22 16:15:09 2012 +0200

    Make it work with API changes for 3.5.3

 Makefile.am                                        |    1 -
 autogen.sh                                         |    4 +-
 configure.ac                                       |   27 +-
 eplugin-rule.mk                                    |   11 -
 po/POTFILES.in                                     |   15 +-
 src/Makefile.am                                    |    4 +-
 src/account-setup-eplugin/Makefile.am              |   52 -
 .../e-mapi-account-listener.c                      | 1312 --------------
 .../e-mapi-account-listener.h                      |   55 -
 .../e-mapi-account-settings.c                      |  826 ---------
 src/account-setup-eplugin/e-mapi-account-setup.c   | 1794 --------------------
 src/account-setup-eplugin/e-mapi-account-setup.h   |   65 -
 .../org-gnome-exchange-mapi.eplug.xml              |  127 --
 src/addressbook/e-book-backend-mapi-contacts.c     |   35 +-
 src/addressbook/e-book-backend-mapi-factory.c      |    6 +-
 src/addressbook/e-book-backend-mapi-gal.c          |   26 +-
 src/addressbook/e-book-backend-mapi.c              |  228 ++--
 src/addressbook/e-book-backend-mapi.h              |    7 +-
 src/calendar/e-cal-backend-mapi-factory.c          |    6 +-
 src/calendar/e-cal-backend-mapi.c                  |  410 +++---
 src/calendar/e-cal-backend-mapi.h                  |    2 +-
 src/camel/Makefile.am                              |    2 +
 src/camel/camel-mapi-store.c                       |   94 +-
 src/collection/Makefile.am                         |   35 +
 src/collection/e-mapi-backend-factory.c            |  100 ++
 src/collection/e-mapi-backend-factory.h            |   64 +
 src/collection/e-mapi-backend.c                    |  573 +++++++
 src/collection/e-mapi-backend.h                    |   63 +
 .../module-mapi-backend.c}                         |   36 +-
 src/configuration/Makefile.am                      |   57 +
 src/configuration/e-book-config-mapi.c             |   75 +
 src/configuration/e-book-config-mapi.h             |   63 +
 src/configuration/e-book-config-mapigal.c          |  106 ++
 src/configuration/e-book-config-mapigal.h          |   63 +
 src/configuration/e-cal-config-mapi.c              |   75 +
 src/configuration/e-cal-config-mapi.h              |   63 +
 src/configuration/e-mail-config-mapi-backend.c     |  841 +++++++++
 src/configuration/e-mail-config-mapi-backend.h     |   63 +
 src/configuration/e-mail-config-mapi-extension.c   |  121 ++
 .../e-mail-config-mapi-extension.h}                |   30 +-
 src/configuration/e-mail-config-mapi-page.c        |  296 ++++
 src/configuration/e-mail-config-mapi-page.h        |   71 +
 src/configuration/e-mapi-config-ui-extension.c     |  154 ++
 .../e-mapi-config-ui-extension.h}                  |   43 +-
 src/configuration/e-mapi-config-utils.c            | 1698 ++++++++++++++++++
 src/configuration/e-mapi-config-utils.h            |   74 +
 .../e-mapi-edit-folder-permissions.c               |   52 +-
 .../e-mapi-edit-folder-permissions.h               |   10 +-
 .../e-mapi-search-gal-user.c                       |    2 +-
 .../e-mapi-search-gal-user.h                       |    0
 .../e-mapi-subscribe-foreign-folder.c              |   34 +-
 .../e-mapi-subscribe-foreign-folder.h              |    0
 src/configuration/module-mapi-configuration.c      |   49 +
 src/libexchangemapi/Makefile.am                    |    4 +-
 src/libexchangemapi/e-mapi-book-utils.c            |    2 +-
 src/libexchangemapi/e-mapi-book-utils.h            |    2 +-
 src/libexchangemapi/e-mapi-cal-recur-utils.c       |    3 +-
 src/libexchangemapi/e-mapi-cal-tz-utils.c          |    6 +-
 src/libexchangemapi/e-mapi-cal-utils.c             |    5 +-
 src/libexchangemapi/e-mapi-cal-utils.h             |    2 +-
 src/libexchangemapi/e-mapi-connection.c            |  137 +-
 src/libexchangemapi/e-mapi-connection.h            |   12 +-
 src/libexchangemapi/e-mapi-folder.c                |  376 ++---
 src/libexchangemapi/e-mapi-folder.h                |   54 +-
 src/libexchangemapi/e-mapi-mail-utils.c            |    2 +-
 src/libexchangemapi/e-mapi-utils.c                 |  105 ++-
 src/libexchangemapi/e-mapi-utils.h                 |   11 +
 src/libexchangemapi/e-source-mapi-folder.c         |  488 ++++++
 src/libexchangemapi/e-source-mapi-folder.h         |   99 ++
 69 files changed, 6236 insertions(+), 5092 deletions(-)
---
diff --git a/Makefile.am b/Makefile.am
index daba3e9..6fe03d6 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -3,7 +3,6 @@ DIST_SUBDIRS= src po
 
 EXTRA_DIST = 			\
 	ChangeLog		\
-	eplugin-rule.mk		\
 	intltool-merge.in	\
 	intltool-update.in	\
 	intltool-extract.in	
diff --git a/autogen.sh b/autogen.sh
index d3e2104..3f6236e 100755
--- a/autogen.sh
+++ b/autogen.sh
@@ -12,14 +12,14 @@ REQUIRED_INTLTOOL_VERSION=0.35.5
 
 (test -f $srcdir/configure.ac \
   && test -f $srcdir/ChangeLog \
-  && test -d $srcdir/src/account-setup-eplugin) || {
+  && test -d $srcdir/src/configuration) || {
     echo -n "**Error**: Directory "\`$srcdir\'" does not look like the"
     echo " top-level $PKG_NAME directory"
     exit 1
 }
 
 which gnome-autogen.sh || {
-    echo "You need to install gnome-common from the GNOME SVN"
+    echo "You need to install gnome-common from the GNOME git"
     exit 1
 }
 USE_GNOME2_MACROS=1 . gnome-autogen.sh
diff --git a/configure.ac b/configure.ac
index f6c5184..ab88a7d 100644
--- a/configure.ac
+++ b/configure.ac
@@ -30,7 +30,6 @@ m4_define([evo_minimum_version], [ema_version])
 m4_define([libmapi_minimum_version], [1.0])
 m4_define([glib_minimum_version], [2.16.1])
 m4_define([gtk_minimum_version], [2.99.2])
-m4_define([gconf_minimum_version], [2.0.0])
 
 dnl ***********************************
 dnl Automake 1.11 - Silent Build Rules
@@ -102,8 +101,7 @@ dnl Check for GNOME Platform
 dnl *****************************
 PKG_CHECK_MODULES(GNOME_PLATFORM,
 	[glib-2.0 >= glib_minimum_version
-	gtk+-3.0 >= gtk_minimum_version
-	gconf-2.0 >= gconf_minimum_version])
+	gtk+-3.0 >= gtk_minimum_version])
 
 dnl ********************************
 dnl Check for evolution-data-server 
@@ -119,9 +117,10 @@ PKG_CHECK_MODULES(LIBEDATABOOK, libedata-book-$EDS_PACKAGE >= eds_minimum_versio
 PKG_CHECK_MODULES(CAMEL, camel-$EDS_PACKAGE >= eds_minimum_version)
 
 dnl ****************************
-dnl Check for evolution plugins 
+dnl Check for evolution stuff
 dnl ****************************
-PKG_CHECK_MODULES(EVOLUTION_PLUGIN, evolution-plugin-3.0 >= evo_minimum_version)
+PKG_CHECK_MODULES(EVOLUTION_SHELL, evolution-shell-3.0 >= evo_minimum_version)
+PKG_CHECK_MODULES(EVOLUTION_MAIL, evolution-mail-3.0 >= evo_minimum_version)
 
 dnl ****************************
 dnl Check for LibMAPI
@@ -164,18 +163,9 @@ AC_SUBST(EVO_REQUIRED)
 LIBMAPI_REQUIRED=libmapi_minimum_version
 AC_SUBST(LIBMAPI_REQUIRED)
 
-dnl *******************************
-dnl Add evolution plugin rules here
-dnl *******************************
-EVO_PLUGIN_RULE=$srcdir/eplugin-rule.mk
-AC_SUBST_FILE(EVO_PLUGIN_RULE)
-
 dnl *******************
 dnl Special directories
 dnl *******************
-plugindir=`$PKG_CONFIG --variable=plugindir evolution-plugin-3.0`
-AC_SUBST(plugindir)
-
 ebook_backenddir=`$PKG_CONFIG --variable=backenddir libedata-book-1.2`
 AC_SUBST(ebook_backenddir)
 
@@ -188,6 +178,12 @@ AC_SUBST(camel_providerdir)
 edataserver_privincludedir=`$PKG_CONFIG --variable=privincludedir libedataserver-$EDS_PACKAGE`
 AC_SUBST(edataserver_privincludedir)
 
+eds_moduledir=`$PKG_CONFIG --variable=moduledir libebackend-1.2`
+AC_SUBST(eds_moduledir)
+
+evo_moduledir=`$PKG_CONFIG --variable=moduledir evolution-shell-3.0`
+AC_SUBST(evo_moduledir)
+
 libmapi_ldif_dir=`$PKG_CONFIG --variable=datadir libmapi`/setup
 AC_SUBST(libmapi_ldif_dir)
 
@@ -205,10 +201,11 @@ dnl **************************
 AC_CONFIG_FILES([
 Makefile 
 src/Makefile
-src/account-setup-eplugin/Makefile
 src/addressbook/Makefile
 src/calendar/Makefile
 src/camel/Makefile
+src/collection/Makefile
+src/configuration/Makefile
 src/libexchangemapi/Makefile
 src/libexchangemapi/libexchangemapi-]EVO_MAPI_API_VERSION_MACRO[.pc:src/libexchangemapi/libexchangemapi.pc.in
 po/Makefile.in
diff --git a/po/POTFILES.in b/po/POTFILES.in
index c44f2ec..85b08dd 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -1,10 +1,3 @@
-src/account-setup-eplugin/e-mapi-account-listener.c
-src/account-setup-eplugin/e-mapi-account-setup.c
-src/account-setup-eplugin/e-mapi-account-settings.c
-src/account-setup-eplugin/e-mapi-edit-folder-permissions.c
-src/account-setup-eplugin/e-mapi-search-gal-user.c
-src/account-setup-eplugin/e-mapi-subscribe-foreign-folder.c
-src/account-setup-eplugin/org-gnome-exchange-mapi.eplug.xml
 src/addressbook/e-book-backend-mapi.c
 src/addressbook/e-book-backend-mapi-contacts.c
 src/addressbook/e-book-backend-mapi-gal.c
@@ -13,6 +6,14 @@ src/camel/camel-mapi-folder.c
 src/camel/camel-mapi-provider.c
 src/camel/camel-mapi-store.c
 src/camel/camel-mapi-transport.c
+src/collection/e-mapi-backend.c
+src/configuration/e-book-config-mapigal.c
+src/configuration/e-mail-config-mapi-backend.c
+src/configuration/e-mail-config-mapi-page.c
+src/configuration/e-mapi-config-utils.c
+src/configuration/e-mapi-edit-folder-permissions.c
+src/configuration/e-mapi-search-gal-user.c
+src/configuration/e-mapi-subscribe-foreign-folder.c
 src/libexchangemapi/e-mapi-cal-utils.c
 src/libexchangemapi/e-mapi-connection.c
 src/libexchangemapi/e-mapi-folder.c
diff --git a/src/Makefile.am b/src/Makefile.am
index 7e02ee8..122a097 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1,3 +1,3 @@
-SUBDIRS=libexchangemapi calendar addressbook camel account-setup-eplugin
-DIST_SUBDIRS=libexchangemapi calendar addressbook camel account-setup-eplugin
+SUBDIRS=libexchangemapi addressbook calendar camel collection configuration
+
 -include $(top_srcdir)/git.mk
diff --git a/src/addressbook/e-book-backend-mapi-contacts.c b/src/addressbook/e-book-backend-mapi-contacts.c
index 7cc87a3..ae9cea6 100644
--- a/src/addressbook/e-book-backend-mapi-contacts.c
+++ b/src/addressbook/e-book-backend-mapi-contacts.c
@@ -33,20 +33,14 @@
 #include <glib/gi18n-lib.h>
 
 #include <sys/time.h>
-/*
-** #include <glib/gi18n-lib.h>
-*/
 
-#include <libedataserver/e-sexp.h>
-#include "libedataserver/e-flag.h"
-#include <libebook/e-contact.h>
+#include <libedataserver/libedataserver.h>
+#include <libedata-book/libedata-book.h>
+#include <libebook/libebook.h>
 #include <camel/camel.h>
 
-#include <libedata-book/e-book-backend-sexp.h>
-#include <libedata-book/e-data-book.h>
-#include <libedata-book/e-data-book-view.h>
-
 #include "e-book-backend-mapi-contacts.h"
+#include "e-source-mapi-folder.h"
 
 G_DEFINE_TYPE (EBookBackendMAPIContacts, e_book_backend_mapi_contacts, E_TYPE_BOOK_BACKEND_MAPI)
 
@@ -146,7 +140,7 @@ transfer_contact_cb (EMapiConnection *conn,
 	g_return_val_if_fail (tc->ebma != NULL, FALSE);
 	g_return_val_if_fail (object != NULL, FALSE);
 
-	tc->contact = e_mapi_book_utils_contact_from_object (conn, object, e_book_backend_mapi_get_book_uri (tc->ebma));
+	tc->contact = e_mapi_book_utils_contact_from_object (conn, object, e_book_backend_mapi_get_book_uid (tc->ebma));
 	if (tc->contact)
 		return e_book_backend_mapi_notify_contact_update (tc->ebma, NULL, tc->contact, obj_index, obj_total, NULL);
 
@@ -202,7 +196,7 @@ transfer_contacts_cb (EMapiConnection *conn,
 	g_return_val_if_fail (object != NULL, FALSE);
 	g_return_val_if_fail (tcd->ebma != NULL, FALSE);
 
-	contact = e_mapi_book_utils_contact_from_object (conn, object, e_book_backend_mapi_get_book_uri (tcd->ebma));
+	contact = e_mapi_book_utils_contact_from_object (conn, object, e_book_backend_mapi_get_book_uid (tcd->ebma));
 	if (contact) {
 		if (tcd->cards)
 			*tcd->cards = g_slist_prepend (*tcd->cards, e_vcard_to_string (E_VCARD (contact), EVC_FORMAT_VCARD_30));
@@ -319,6 +313,7 @@ static void
 ebbm_contacts_open (EBookBackendMAPI *ebma, GCancellable *cancellable, gboolean only_if_exists, GError **perror)
 {
 	ESource *source = e_backend_get_source (E_BACKEND (ebma));
+	ESourceMapiFolder *ext_mapi_folder;
 	EBookBackendMAPIContactsPrivate *priv = ((EBookBackendMAPIContacts *) ebma)->priv;
 	GError *err = NULL;
 
@@ -328,10 +323,11 @@ ebbm_contacts_open (EBookBackendMAPI *ebma, GCancellable *cancellable, gboolean
 		return;
 	}
 
-	priv->fid = 0;
-	priv->is_public_folder = g_strcmp0 (e_source_get_property (source, "public"), "yes") == 0;
-	priv->foreign_username = e_source_get_duped_property (source, "foreign-username");
-	e_mapi_util_mapi_id_from_string (e_source_get_property (source, "folder-id"), &priv->fid);
+	ext_mapi_folder = e_source_get_extension (source, E_SOURCE_EXTENSION_MAPI_FOLDER);
+
+	priv->fid = e_source_mapi_folder_get_id (ext_mapi_folder);
+	priv->is_public_folder = e_source_mapi_folder_is_public (ext_mapi_folder);
+	priv->foreign_username = e_source_mapi_folder_dup_foreign_username (ext_mapi_folder);
 
 	if (priv->foreign_username && !*priv->foreign_username) {
 		g_free (priv->foreign_username);
@@ -350,6 +346,7 @@ static void
 ebbm_contacts_connection_status_changed (EBookBackendMAPI *ebma, gboolean is_online)
 {
 	ESource *source;
+	ESourceMapiFolder *ext_mapi_folder;
 
 	e_book_backend_notify_readonly (E_BOOK_BACKEND (ebma), !is_online);
 
@@ -357,7 +354,9 @@ ebbm_contacts_connection_status_changed (EBookBackendMAPI *ebma, gboolean is_onl
 		return;
 
 	source = e_backend_get_source (E_BACKEND (ebma));
-	if (source && g_strcmp0 (e_source_get_property (source, "server-notification"), "true") == 0) {
+	ext_mapi_folder = e_source_get_extension (source, E_SOURCE_EXTENSION_MAPI_FOLDER);
+
+	if (e_source_mapi_folder_get_server_notification (ext_mapi_folder)) {
 		EMapiConnection *conn;
 		mapi_object_t obj_folder;
 		gboolean status;
@@ -505,7 +504,7 @@ ebbm_contacts_create_contacts (EBookBackendMAPI *ebma, GCancellable *cancellable
 
 	/* UID of the contact is nothing but the concatenated string of hex id of folder and the message.*/
 	e_contact_set (contact, E_CONTACT_UID, id);
-	e_contact_set (contact, E_CONTACT_BOOK_URI, e_book_backend_mapi_get_book_uri (ebma));
+	e_contact_set (contact, E_CONTACT_BOOK_URI, e_book_backend_mapi_get_book_uid (ebma));
 
 	g_free (id);
 
diff --git a/src/addressbook/e-book-backend-mapi-factory.c b/src/addressbook/e-book-backend-mapi-factory.c
index ef10df5..bbbcd64 100644
--- a/src/addressbook/e-book-backend-mapi-factory.c
+++ b/src/addressbook/e-book-backend-mapi-factory.c
@@ -23,9 +23,11 @@
 
 #include <config.h>
 
-#include <libedata-book/e-book-backend-factory.h>
+#include <libedata-book/libedata-book.h>
+
 #include "e-book-backend-mapi-contacts.h"
 #include "e-book-backend-mapi-gal.h"
+#include "e-source-mapi-folder.h"
 
 typedef EBookBackendFactory EBookBackendMapiContactsFactory;
 typedef EBookBackendFactoryClass EBookBackendMapiContactsFactoryClass;
@@ -88,6 +90,8 @@ e_book_backend_mapi_gal_factory_init (EBookBackendFactory *factory)
 G_MODULE_EXPORT void
 e_module_load (GTypeModule *type_module)
 {
+	e_source_mapi_folder_type_register (type_module);
+
 	e_book_backend_mapi_contacts_factory_register_type (type_module);
 	e_book_backend_mapi_gal_factory_register_type (type_module);
 }
diff --git a/src/addressbook/e-book-backend-mapi-gal.c b/src/addressbook/e-book-backend-mapi-gal.c
index b4711cb..d92fab2 100644
--- a/src/addressbook/e-book-backend-mapi-gal.c
+++ b/src/addressbook/e-book-backend-mapi-gal.c
@@ -34,15 +34,12 @@
 
 #include <sys/time.h>
 
-#include <libedataserver/e-sexp.h>
-#include "libedataserver/e-flag.h"
-#include <libebook/e-contact.h>
-
-#include <libedata-book/e-book-backend-sexp.h>
-#include <libedata-book/e-data-book.h>
-#include <libedata-book/e-data-book-view.h>
+#include <libedataserver/libedataserver.h>
+#include <libedata-book/libedata-book.h>
+#include <libebook/libebook.h>
 
 #include "e-book-backend-mapi-gal.h"
+#include "e-source-mapi-folder.h"
 
 /* default value for "partial-count", upper bound of objects to download during partial search */
 #define DEFAULT_PARTIAL_COUNT 50
@@ -81,7 +78,7 @@ transfer_gal_cb (EMapiConnection *conn,
 	g_return_val_if_fail (object != NULL, FALSE);
 	g_return_val_if_fail (tg != NULL, FALSE);
 
-	contact = e_mapi_book_utils_contact_from_object (conn, object, e_book_backend_mapi_get_book_uri (tg->ebma));
+	contact = e_mapi_book_utils_contact_from_object (conn, object, e_book_backend_mapi_get_book_uid (tg->ebma));
 	if (!contact) {
 		/* this is GAL, just ignore them */
 		return TRUE;
@@ -173,6 +170,7 @@ ebbm_gal_transfer_contacts (EBookBackendMAPI *ebma,
 	struct TransferGalData tg = { 0 };
 	EMapiConnection *conn;
 	ESource *source;
+	ESourceMapiFolder *ext_mapi_folder;
 	GSList *get_mids = NULL;
 	const GSList *iter;
 	gint partial_count = -1;
@@ -188,14 +186,12 @@ ebbm_gal_transfer_contacts (EBookBackendMAPI *ebma,
 	}
 
 	source = e_backend_get_source (E_BACKEND (ebma));
-	if (source &&
-	    !e_book_backend_mapi_is_marked_for_offline (ebma) &&
-	    g_strcmp0 (e_source_get_property (source, "allow-partial"), "true") == 0) {
-		const gchar *partial_count_str = e_source_get_property (source, "partial-count");
+	ext_mapi_folder = e_source_get_extension (source, E_SOURCE_EXTENSION_MAPI_FOLDER);
 
-		partial_count = 0;
-		if (partial_count_str)
-			partial_count = atoi (partial_count_str);
+	if (ext_mapi_folder &&
+	    !e_book_backend_mapi_is_marked_for_offline (ebma) &&
+	    e_source_mapi_folder_get_allow_partial (ext_mapi_folder)) {
+		partial_count = e_source_mapi_folder_get_partial_count (ext_mapi_folder);
 
 		if (partial_count <= 0)
 			partial_count = DEFAULT_PARTIAL_COUNT;
diff --git a/src/addressbook/e-book-backend-mapi.c b/src/addressbook/e-book-backend-mapi.c
index 2fb8378..1142114 100644
--- a/src/addressbook/e-book-backend-mapi.c
+++ b/src/addressbook/e-book-backend-mapi.c
@@ -26,14 +26,13 @@
 #endif
 
 #include <stdlib.h>
-#include <fcntl.h>
 #include <string.h>
 #include <glib.h>
 #include <glib/gstdio.h>
 #include <glib/gi18n-lib.h>
 
-#include <libebook/e-contact.h>
-#include <libedataserver/e-data-server-util.h>
+#include <libebook/libebook.h>
+#include <libedataserver/libedataserver.h>
 #include <camel/camel.h>
 
 #include <e-mapi-operation-queue.h>
@@ -43,7 +42,10 @@
 
 #include "e-book-backend-mapi.h"
 
-G_DEFINE_TYPE (EBookBackendMAPI, e_book_backend_mapi, E_TYPE_BOOK_BACKEND)
+static void e_book_backend_mapi_authenticator_init (ESourceAuthenticatorInterface *interface);
+
+G_DEFINE_TYPE_WITH_CODE (EBookBackendMAPI, e_book_backend_mapi, E_TYPE_BOOK_BACKEND,
+	G_IMPLEMENT_INTERFACE (E_TYPE_SOURCE_AUTHENTICATOR, e_book_backend_mapi_authenticator_init))
 
 struct _EBookBackendMAPIPrivate
 {
@@ -51,8 +53,7 @@ struct _EBookBackendMAPIPrivate
 
 	GMutex *conn_lock;
 	EMapiConnection *conn;
-	gchar *profile;
-	gchar *book_uri;
+	gchar *book_uid;
 	gboolean marked_for_offline;
 
 	GThread *update_cache_thread;
@@ -71,6 +72,35 @@ struct _EBookBackendMAPIPrivate
 	GMutex *running_views_lock;
 };
 
+static CamelMapiSettings *
+ebbm_get_collection_settings (EBookBackendMAPI *ebbm)
+{
+	ESource *source;
+	ESource *collection;
+	ESourceCamel *extension;
+	ESourceRegistry *registry;
+	CamelSettings *settings;
+	const gchar *extension_name;
+
+	source = e_backend_get_source (E_BACKEND (ebbm));
+	registry = e_book_backend_get_registry (E_BOOK_BACKEND (ebbm));
+
+	extension_name = e_source_camel_get_extension_name ("mapi");
+	e_source_camel_generate_subtype ("mapi", CAMEL_TYPE_MAPI_SETTINGS);
+
+	/* The collection settings live in our parent data source. */
+	collection = e_source_registry_find_extension (
+		registry, source, extension_name);
+	g_return_val_if_fail (collection != NULL, NULL);
+
+	extension = e_source_get_extension (collection, extension_name);
+	settings = e_source_camel_get_settings (extension);
+
+	g_object_unref (collection);
+
+	return CAMEL_MAPI_SETTINGS (settings);
+}
+
 static glong
 get_current_time_ms (void)
 {
@@ -322,12 +352,18 @@ ebbm_maybe_invoke_cache_update (EBookBackendMAPI *ebma)
 	}
 }
 
-static void
-ebbm_connect_user (EBookBackendMAPI *ebma, GCancellable *cancellable, const gchar *password, GError **error)
+static ESourceAuthenticationResult
+ebbm_connect_user (EBookBackendMAPI *ebma,
+		   GCancellable *cancellable,
+		   const GString *password,
+		   GError **error)
 {
 	EBookBackendMAPIPrivate *priv = ebma->priv;
-	GError *mapi_error = NULL;
 	EMapiConnection *old_conn;
+	CamelMapiSettings *settings;
+	GError *mapi_error = NULL;
+
+	settings = ebbm_get_collection_settings (ebma);
 
 	if (!e_backend_get_online (E_BACKEND (ebma))) {
 		ebbm_notify_connection_status (ebma, FALSE);
@@ -342,18 +378,18 @@ ebbm_connect_user (EBookBackendMAPI *ebma, GCancellable *cancellable, const gcha
 
 		if (g_cancellable_set_error_if_cancelled (cancellable, error)) {
 			e_book_backend_mapi_unlock_connection (ebma);
-			return;
+			return E_SOURCE_AUTHENTICATION_ERROR;
 		}
 
 		old_conn = priv->conn;
 		priv->conn = NULL;
 
-		priv->conn = e_mapi_connection_new (priv->profile,
-							   password,
-							   cancellable,
-							   &mapi_error);
+		priv->conn = e_mapi_connection_new (
+			e_book_backend_get_registry (E_BOOK_BACKEND (ebma)),
+			camel_mapi_settings_get_profile (settings),
+			password, cancellable, &mapi_error);
 		if (!priv->conn) {
-			priv->conn = e_mapi_connection_find (priv->profile);
+			priv->conn = e_mapi_connection_find (camel_mapi_settings_get_profile (settings));
 			if (priv->conn && !e_mapi_connection_connected (priv->conn))
 				e_mapi_connection_reconnect (priv->conn, password, cancellable, &mapi_error);
 		}
@@ -362,6 +398,8 @@ ebbm_connect_user (EBookBackendMAPI *ebma, GCancellable *cancellable, const gcha
 			g_object_unref (old_conn);
 
 		if (!priv->conn || mapi_error) {
+			gboolean is_network_error = g_error_matches (mapi_error, E_MAPI_ERROR, MAPI_E_NETWORK_ERROR);
+
 			if (priv->conn) {
 				g_object_unref (priv->conn);
 				priv->conn = NULL;
@@ -374,7 +412,8 @@ ebbm_connect_user (EBookBackendMAPI *ebma, GCancellable *cancellable, const gcha
 				g_error_free (mapi_error);
 
 			ebbm_notify_connection_status (ebma, FALSE);
-			return;
+
+			return is_network_error ? E_SOURCE_AUTHENTICATION_ERROR : E_SOURCE_AUTHENTICATION_REJECTED;
 		}
 
 		e_book_backend_mapi_unlock_connection (ebma);
@@ -385,15 +424,21 @@ ebbm_connect_user (EBookBackendMAPI *ebma, GCancellable *cancellable, const gcha
 			ebbm_maybe_invoke_cache_update (ebma);
 		}
 	}
+
+	return E_SOURCE_AUTHENTICATION_ACCEPTED;
 }
 
 static void
-ebbm_open (EBookBackendMAPI *ebma, GCancellable *cancellable, gboolean only_if_exists, GError **perror)
+ebbm_open (EBookBackendMAPI *ebma,
+	   GCancellable *cancellable,
+	   gboolean only_if_exists,
+	   GError **perror)
 {
 	EBookBackendMAPIPrivate *priv = ebma->priv;
 	ESource *source = e_backend_get_source (E_BACKEND (ebma));
-	const gchar *offline;
-	const gchar *cache_dir, *krb_sso;
+	ESourceOffline *offline_extension;
+	CamelMapiSettings *settings;
+	const gchar *cache_dir;
 	GError *error = NULL;
 
 	if (e_book_backend_is_opened (E_BOOK_BACKEND (ebma))) {
@@ -401,15 +446,14 @@ ebbm_open (EBookBackendMAPI *ebma, GCancellable *cancellable, gboolean only_if_e
 		return;
 	}
 
-	offline = e_source_get_property (source, "offline_sync");
-	priv->marked_for_offline = offline  && g_str_equal (offline, "1");
+	settings = ebbm_get_collection_settings (ebma);
 
-	if (priv->book_uri)
-		g_free (priv->book_uri);
-	priv->book_uri = e_source_get_uri (source);
+	offline_extension = e_source_get_extension (source, E_SOURCE_EXTENSION_OFFLINE);
+	priv->marked_for_offline = e_source_offline_get_stay_synchronized (offline_extension);
 
-	g_free (priv->profile);
-	priv->profile = g_strdup (e_source_get_property (source, "profile"));
+	if (priv->book_uid)
+		g_free (priv->book_uid);
+	priv->book_uid = e_source_dup_uid (source);
 
 	cache_dir = e_book_backend_get_cache_dir (E_BOOK_BACKEND (ebma));
 
@@ -446,14 +490,33 @@ ebbm_open (EBookBackendMAPI *ebma, GCancellable *cancellable, gboolean only_if_e
 	}
 
 	e_book_backend_notify_online (E_BOOK_BACKEND (ebma), TRUE);
-	krb_sso = e_source_get_property (source, "kerberos");
-	if (!krb_sso || !g_str_equal (krb_sso, "required")) {
-		e_book_backend_notify_auth_required (E_BOOK_BACKEND (ebma),
-						     TRUE, NULL);
-	} else {
-		ebbm_connect_user (ebma, cancellable, NULL, perror);
-		e_book_backend_notify_opened (E_BOOK_BACKEND (ebma), NULL);
+
+
+	if (!camel_mapi_settings_get_kerberos (settings) ||
+	    ebbm_connect_user (ebma, cancellable, NULL, &error) != E_SOURCE_AUTHENTICATION_ACCEPTED) {
+		ESourceRegistry *registry;
+
+		registry = e_book_backend_get_registry (E_BOOK_BACKEND (ebma));
+
+		e_source_registry_authenticate_sync (
+			registry, source,
+			E_SOURCE_AUTHENTICATOR (ebma),
+			cancellable, &error);
 	}
+
+	if (error && perror)
+		g_propagate_error (perror, g_error_copy (error));
+
+	e_book_backend_notify_opened (E_BOOK_BACKEND (ebma), error);
+}
+
+static ESourceAuthenticationResult
+ebbm_try_password_sync (ESourceAuthenticator *authenticator,
+			const GString *password,
+			GCancellable *cancellable,
+			GError **error)
+{
+	return ebbm_connect_user (E_BOOK_BACKEND_MAPI (authenticator), cancellable, password, error);
 }
 
 static void
@@ -467,7 +530,7 @@ ebbm_remove (EBookBackendMAPI *ebma, GCancellable *cancellable, GError **error)
 
 	priv = ebma->priv;
 
-	if (!priv->book_uri)
+	if (!priv->book_uid)
 		return;
 
 	e_book_backend_mapi_lock_connection (ebma);
@@ -524,34 +587,17 @@ ebbm_get_backend_property (EBookBackendMAPI *ebma, const gchar *prop_name, gchar
 }
 
 static void
-ebbm_authenticate_user (EBookBackendMAPI *ebma, GCancellable *cancellable, ECredentials *credentials, GError **error)
-{
-	const gchar *password;
-
-	if (!e_backend_get_online (E_BACKEND (ebma))) {
-		ebbm_notify_connection_status (ebma, FALSE);
-	} else {
-		password = e_credentials_peek (credentials, E_CREDENTIALS_KEY_PASSWORD);
-		ebbm_connect_user (ebma, cancellable, password, error);
-	}
-}
-
-static void
 ebbm_notify_online_cb (EBookBackend *backend, GParamSpec *pspec)
 {
 	EBookBackendMAPI *ebma = E_BOOK_BACKEND_MAPI (backend);
 	EBookBackendMAPIPrivate *priv = ebma->priv;
-	ESource *esource;
-	const gchar *krb_sso = NULL;
 	gboolean online;
 
 	online = e_backend_get_online (E_BACKEND (backend));
 
-	e_book_backend_notify_online (backend, online);
 	if (e_book_backend_is_opened (backend)) {
 		e_book_backend_mapi_lock_connection (ebma);
 
-		esource = e_backend_get_source (E_BACKEND (ebma));
 		if (!online) {
 			e_book_backend_notify_readonly (backend, TRUE);
 			ebbm_notify_connection_status (ebma, FALSE);
@@ -562,23 +608,12 @@ ebbm_notify_online_cb (EBookBackend *backend, GParamSpec *pspec)
 			}
 		} else {
 			ebbm_notify_connection_status (ebma, TRUE);
-			if (!priv->conn) {
-				krb_sso = e_source_get_property (esource,
-								 "kerberos");
-				if (!krb_sso
-				    || !g_str_equal (krb_sso, "required")) {
-					e_book_backend_notify_auth_required (backend, TRUE, NULL);
-				} else {
-					ebbm_connect_user (ebma, NULL, NULL,
-							   NULL);
-					e_book_backend_notify_opened (backend,
-								      NULL);
-				}
-			}
 		}
 
 		e_book_backend_mapi_unlock_connection (ebma);
 	}
+
+	e_book_backend_notify_online (backend, online);
 }
 
 static void
@@ -770,7 +805,6 @@ typedef enum {
 	OP_GET_CONTACT_LIST,
 	OP_START_BOOK_VIEW,
 	OP_STOP_BOOK_VIEW,
-	OP_AUTHENTICATE_USER,
 	OP_GET_BACKEND_PROPERTY
 } OperationType;
 
@@ -791,12 +825,6 @@ typedef struct {
 typedef struct {
 	OperationBase base;
 
-	ECredentials *credentials;
-} OperationAuthenticateUser;
-
-typedef struct {
-	OperationBase base;
-
 	gchar *str;
 } OperationStr;
 
@@ -1026,20 +1054,6 @@ ebbm_operation_cb (OperationBase *op, gboolean cancelled, EBookBackend *backend)
 
 		g_object_unref (opbv->book_view);
 	} break;
-	case OP_AUTHENTICATE_USER: {
-		OperationAuthenticateUser *opau = (OperationAuthenticateUser *) op;
-
-		if (!cancelled) {
-			if (ebmac->op_authenticate_user)
-				ebmac->op_authenticate_user (ebma, op->cancellable, opau->credentials, &error);
-			else
-				error = EDB_ERROR (NOT_SUPPORTED);
-
-			e_book_backend_notify_opened (E_BOOK_BACKEND (ebma), error);
-		}
-
-		e_credentials_free (opau->credentials);
-	} break;
 	case OP_GET_BACKEND_PROPERTY: {
 		OperationStr *ops = (OperationStr *) op;
 		const gchar *prop_name = ops->str;
@@ -1286,35 +1300,6 @@ ebbm_op_stop_book_view (EBookBackend *backend, EDataBookView *book_view)
 }
 
 static void
-ebbm_op_authenticate_user (EBookBackend *backend, GCancellable *cancellable, ECredentials *credentials)
-{
-	OperationAuthenticateUser *op;
-	EBookBackendMAPI *ebbm;
-	EBookBackendMAPIPrivate *priv;
-
-	g_return_if_fail (backend != NULL);
-	g_return_if_fail (E_IS_BOOK_BACKEND_MAPI (backend));
-
-	ebbm = E_BOOK_BACKEND_MAPI (backend);
-	priv = ebbm->priv;
-	g_return_if_fail (priv != NULL);
-
-	if (cancellable)
-		g_object_ref (cancellable);
-
-	g_object_ref (ebbm);
-
-	op = g_new0 (OperationAuthenticateUser, 1);
-	op->base.ot = OP_AUTHENTICATE_USER;
-	op->base.book = NULL;
-	op->base.opid = 0;
-	op->base.cancellable = cancellable;
-	op->credentials = e_credentials_new_clone (credentials);
-
-	e_mapi_operation_queue_push (priv->op_queue, op);
-}
-
-static void
 e_book_backend_mapi_init (EBookBackendMAPI *ebma)
 {
 	ebma->priv = G_TYPE_INSTANCE_GET_PRIVATE (ebma, E_TYPE_BOOK_BACKEND_MAPI, EBookBackendMAPIPrivate);
@@ -1360,8 +1345,7 @@ ebbm_dispose (GObject *object)
 		UNREF (priv->db);
 		UNREF (priv->update_cache);
 
-		FREE (priv->profile);
-		FREE (priv->book_uri);
+		FREE (priv->book_uid);
 
 		g_hash_table_destroy (priv->running_views);
 		g_mutex_free (priv->running_views_lock);
@@ -1397,11 +1381,9 @@ e_book_backend_mapi_class_init (EBookBackendMAPIClass *klass)
 	backend_class->get_contact_list		= ebbm_op_get_contact_list;
 	backend_class->start_book_view		= ebbm_op_start_book_view;
 	backend_class->stop_book_view		= ebbm_op_stop_book_view;
-	backend_class->authenticate_user	= ebbm_op_authenticate_user;
 	backend_class->get_backend_property	= ebbm_op_get_backend_property;
 	klass->op_open				= ebbm_open;
 	klass->op_remove			= ebbm_remove;
-	klass->op_authenticate_user		= ebbm_authenticate_user;
 	klass->op_get_contact			= ebbm_get_contact;
 	klass->op_get_contact_list		= ebbm_get_contact_list;
 
@@ -1413,13 +1395,19 @@ e_book_backend_mapi_class_init (EBookBackendMAPIClass *klass)
 	klass->op_transfer_contacts		= NULL;
 }
 
+static void
+e_book_backend_mapi_authenticator_init (ESourceAuthenticatorInterface *interface)
+{
+	interface->try_password_sync = ebbm_try_password_sync;
+}
+
 const gchar *
-e_book_backend_mapi_get_book_uri (EBookBackendMAPI *ebma)
+e_book_backend_mapi_get_book_uid (EBookBackendMAPI *ebma)
 {
 	g_return_val_if_fail (E_IS_BOOK_BACKEND_MAPI (ebma), NULL);
 	g_return_val_if_fail (ebma->priv != NULL, NULL);
 
-	return ebma->priv->book_uri;
+	return ebma->priv->book_uid;
 }
 
 void
diff --git a/src/addressbook/e-book-backend-mapi.h b/src/addressbook/e-book-backend-mapi.h
index 49abb27..97e6429 100644
--- a/src/addressbook/e-book-backend-mapi.h
+++ b/src/addressbook/e-book-backend-mapi.h
@@ -24,11 +24,8 @@
 #include <glib.h>
 #include <gio/gio.h>
 
-#include <libedata-book/e-book-backend.h>
-#include <libedata-book/e-data-book.h>
-#include <libedata-book/e-data-book-view.h>
+#include <libedata-book/libedata-book.h>
 
-#include <libedata-book/e-book-backend-sqlitedb.h>
 #include "e-mapi-connection.h"
 #include "e-mapi-defs.h"
 #include "e-mapi-utils.h"
@@ -100,7 +97,7 @@ typedef struct
 
 GType e_book_backend_mapi_get_type (void);
 
-const gchar *e_book_backend_mapi_get_book_uri (EBookBackendMAPI *ebma);
+const gchar *e_book_backend_mapi_get_book_uid (EBookBackendMAPI *ebma);
 void e_book_backend_mapi_lock_connection (EBookBackendMAPI *ebma);
 void e_book_backend_mapi_unlock_connection (EBookBackendMAPI *ebma);
 EMapiConnection *e_book_backend_mapi_get_connection (EBookBackendMAPI *ebma);
diff --git a/src/calendar/e-cal-backend-mapi-factory.c b/src/calendar/e-cal-backend-mapi-factory.c
index a5e6460..d61263b 100644
--- a/src/calendar/e-cal-backend-mapi-factory.c
+++ b/src/calendar/e-cal-backend-mapi-factory.c
@@ -23,7 +23,9 @@
 
 #include <config.h>
 
-#include <libedata-cal/e-cal-backend-factory.h>
+#include <libedata-cal/libedata-cal.h>
+
+#include "e-source-mapi-folder.h"
 #include "e-cal-backend-mapi.h"
 
 #define FACTORY_NAME "mapi"
@@ -118,6 +120,8 @@ e_cal_backend_mapi_todos_factory_init (ECalBackendFactory *factory)
 G_MODULE_EXPORT void
 e_module_load (GTypeModule *type_module)
 {
+	e_source_mapi_folder_type_register (type_module);
+
 	e_cal_backend_mapi_events_factory_register_type (type_module);
 	e_cal_backend_mapi_journal_factory_register_type (type_module);
 	e_cal_backend_mapi_todos_factory_register_type (type_module);
diff --git a/src/calendar/e-cal-backend-mapi.c b/src/calendar/e-cal-backend-mapi.c
index 19b35f2..ec487fa 100644
--- a/src/calendar/e-cal-backend-mapi.c
+++ b/src/calendar/e-cal-backend-mapi.c
@@ -30,13 +30,14 @@
 
 #include <libical/icaltz-util.h>
 
-#include <libedata-cal/e-cal-backend-file-store.h>
-#include <libedataserver/e-data-server-util.h>
+#include <libedata-cal/libedata-cal.h>
+#include <libedataserver/libedataserver.h>
 
 #include <e-mapi-connection.h>
 #include <e-mapi-cal-utils.h>
 #include <e-mapi-utils.h>
 #include <e-mapi-operation-queue.h>
+#include <e-source-mapi-folder.h>
 
 #include "e-cal-backend-mapi.h"
 
@@ -55,7 +56,10 @@
 #define EDC_ERROR(_code) e_data_cal_create_error (_code, NULL)
 #define EDC_ERROR_EX(_code, _msg) e_data_cal_create_error (_code, _msg)
 
-G_DEFINE_TYPE (ECalBackendMAPI, e_cal_backend_mapi, E_TYPE_CAL_BACKEND)
+static void e_cal_backend_mapi_authenticator_init (ESourceAuthenticatorInterface *interface);
+
+G_DEFINE_TYPE_WITH_CODE (ECalBackendMAPI, e_cal_backend_mapi, E_TYPE_CAL_BACKEND,
+	G_IMPLEMENT_INTERFACE (E_TYPE_SOURCE_AUTHENTICATOR, e_cal_backend_mapi_authenticator_init))
 
 typedef struct {
 	GCond *cond;
@@ -68,17 +72,10 @@ struct _ECalBackendMAPIPrivate {
 	EMapiOperationQueue *op_queue;
 
 	mapi_id_t		fid;
-	gchar			*profile;
 	gboolean is_public_folder;
 	gchar *foreign_username;
 	EMapiConnection *conn;
 
-	/* These fields are entirely for access rights */
-	gchar			*owner_name;
-	gchar			*owner_email;
-	gchar			*user_name;
-	gchar			*user_email;
-
 	/* A mutex to control access to the private structure */
 	GMutex			*mutex;
 	ECalBackendStore	*store;
@@ -102,6 +99,35 @@ struct _ECalBackendMAPIPrivate {
 	GCancellable *cancellable;
 };
 
+static CamelMapiSettings *
+ecbm_get_collection_settings (ECalBackendMAPI *ecbm)
+{
+	ESource *source;
+	ESource *collection;
+	ESourceCamel *extension;
+	ESourceRegistry *registry;
+	CamelSettings *settings;
+	const gchar *extension_name;
+
+	source = e_backend_get_source (E_BACKEND (ecbm));
+	registry = e_cal_backend_get_registry (E_CAL_BACKEND (ecbm));
+
+	extension_name = e_source_camel_get_extension_name ("mapi");
+	e_source_camel_generate_subtype ("mapi", CAMEL_TYPE_MAPI_SETTINGS);
+
+	/* The collection settings live in our parent data source. */
+	collection = e_source_registry_find_extension (
+		registry, source, extension_name);
+	g_return_val_if_fail (collection != NULL, NULL);
+
+	extension = e_source_get_extension (collection, extension_name);
+	settings = e_source_camel_get_settings (extension);
+
+	g_object_unref (collection);
+
+	return CAMEL_MAPI_SETTINGS (settings);
+}
+
 static gboolean
 ecbm_open_folder (ECalBackendMAPI *ecbm,
 		  EMapiConnection *conn,
@@ -185,44 +211,92 @@ get_comp_mid (icalcomponent *icalcomp, mapi_id_t *mid)
 	}
 }
 
+static ESource *
+ecbm_find_identity_source (ECalBackendMAPI *cbmapi)
+{
+	ESourceRegistry *registry;
+	GList *all_sources, *my_sources, *iter;
+	CamelMapiSettings *settings;
+	ESource *res = NULL;
+
+	g_return_val_if_fail (E_IS_CAL_BACKEND_MAPI (cbmapi), NULL);
+
+	settings = ecbm_get_collection_settings (cbmapi);
+	g_return_val_if_fail (settings != NULL, NULL);
+
+	registry = e_cal_backend_get_registry (E_CAL_BACKEND (cbmapi));
+	all_sources = e_source_registry_list_sources (registry, NULL);
+	my_sources = e_mapi_utils_filter_sources_for_profile (all_sources,
+		camel_mapi_settings_get_profile (settings));
+	g_list_free_full (all_sources, g_object_unref);
+
+	for (iter = my_sources; iter; iter = iter->next) {
+		ESource *source = iter->data;
+
+		if (!source)
+			continue;
+
+		if (e_source_has_extension (source, E_SOURCE_EXTENSION_MAIL_IDENTITY)) {
+			res = g_object_ref (source);
+			break;
+		}
+	}
+
+	g_list_free_full (my_sources, g_object_unref);
+
+	return res;
+}
+
 static const gchar *
 ecbm_get_owner_name (ECalBackendMAPI *cbmapi)
 {
-	ECalBackendMAPIPrivate *priv;
+	ESource *identity_source;
+	ESourceMailIdentity *identity_ext;
+	const gchar *res = NULL;
 
-	priv = cbmapi->priv;
+	identity_source = ecbm_find_identity_source (cbmapi);
+	if (!identity_source)
+		return NULL;
+
+	identity_ext = e_source_get_extension (identity_source, E_SOURCE_EXTENSION_MAIL_IDENTITY);
+	if (identity_ext)
+		res = e_source_mail_identity_get_name (identity_ext);
 
-	return priv->owner_name;
+	g_object_unref (identity_source);
+
+	return res;
 }
 
 static const gchar *
 ecbm_get_owner_email (ECalBackendMAPI *cbmapi)
 {
-	ECalBackendMAPIPrivate *priv;
+	ESource *identity_source;
+	ESourceMailIdentity *identity_ext;
+	const gchar *res = NULL;
 
-	priv = cbmapi->priv;
+	identity_source = ecbm_find_identity_source (cbmapi);
+	if (!identity_source)
+		return NULL;
+
+	identity_ext = e_source_get_extension (identity_source, E_SOURCE_EXTENSION_MAIL_IDENTITY);
+	if (identity_ext)
+		res = e_source_mail_identity_get_address (identity_ext);
 
-	return priv->owner_email;
+	g_object_unref (identity_source);
+
+	return res;
 }
 
 static const gchar *
 ecbm_get_user_name (ECalBackendMAPI *cbmapi)
 {
-	ECalBackendMAPIPrivate *priv;
-
-	priv = cbmapi->priv;
-
-	return priv->user_name;
+	return ecbm_get_owner_name (cbmapi);
 }
 
 static const gchar *
 ecbm_get_user_email (ECalBackendMAPI *cbmapi)
 {
-	ECalBackendMAPIPrivate *priv;
-
-	priv = cbmapi->priv;
-
-	return priv->user_email;
+	return ecbm_get_owner_email (cbmapi);
 }
 
 static gboolean
@@ -252,12 +326,10 @@ ecbm_get_backend_property (ECalBackend *backend, EDataCal *cal, const gchar *pro
 				  );
 	} else if (g_str_equal (prop_name, CAL_BACKEND_PROPERTY_CAL_EMAIL_ADDRESS)) {
 		ECalBackendMAPI *cbmapi;
-		ECalBackendMAPIPrivate *priv;
 
 		cbmapi = E_CAL_BACKEND_MAPI (backend);
-		priv = cbmapi->priv;
 
-		*prop_value = g_strdup (priv->user_email);
+		*prop_value = g_strdup (ecbm_get_user_email (cbmapi));
 	} else if (g_str_equal (prop_name, CAL_BACKEND_PROPERTY_ALARM_EMAIL_ADDRESS)) {
 		/* We don't support email alarms. This should not have been called. */
 		*prop_value = NULL;
@@ -394,7 +466,7 @@ notify_view_progress (ECalBackendMAPI *cbmapi, guint index, guint total)
 
 	/* To translators: This message is displayed on the status bar when calendar/tasks/memo items are being fetched from the server. */
 	progress_string = g_strdup_printf (_("Loading items in folder %s"),
-				e_source_peek_name (e_backend_get_source (E_BACKEND (cbmapi))));
+				e_source_get_display_name (e_backend_get_source (E_BACKEND (cbmapi))));
 
 	pd.msg = progress_string;
 
@@ -1041,36 +1113,6 @@ run_delta_thread (ECalBackendMAPI *cbmapi)
 }
 
 static void
-ecbm_connect (ECalBackendMAPI *cbmapi, GError **perror)
-{
-	ECalBackendMAPIPrivate *priv;
-
-	priv = cbmapi->priv;
-
-	if (!priv->fid) {
-		g_propagate_error (perror, EDC_ERROR_EX (OtherError, "No folder ID set"));
-		return;
-	}
-
-	if (!priv->conn || !e_mapi_connection_connected (priv->conn)) {
-		g_propagate_error (perror, EDC_ERROR (AuthenticationFailed));
-		return;
-	}
-
-	/* We have established a connection */
-	if (priv->store && priv->fid) {
-		e_cal_backend_notify_online (E_CAL_BACKEND (cbmapi), TRUE);
-
-		if (priv->mode_changed && !priv->dthread) {
-			priv->mode_changed = FALSE;
-			run_delta_thread (cbmapi);
-		}
-	}
-
-	priv->mode_changed = FALSE;
-}
-
-static void
 ecbm_server_notification_cb (EMapiConnection *conn,
 			     guint event_mask,
 			     gpointer event_data,
@@ -1138,11 +1180,15 @@ ecbm_server_notification_cb (EMapiConnection *conn,
 		run_delta_thread (cbmapi);
 }
 
-static void
-ecbm_connect_user (ECalBackend *backend, GCancellable *cancellable, const gchar *password, GError **perror)
+static ESourceAuthenticationResult
+ecbm_connect_user (ECalBackend *backend,
+		   GCancellable *cancellable,
+		   const GString *password,
+		   GError **perror)
 {
 	ECalBackendMAPI *cbmapi;
 	ECalBackendMAPIPrivate *priv;
+	CamelMapiSettings *settings;
 	EMapiConnection *old_conn;
 	GError *mapi_error = NULL;
 
@@ -1152,10 +1198,13 @@ ecbm_connect_user (ECalBackend *backend, GCancellable *cancellable, const gchar
 	priv = cbmapi->priv;
 
 	old_conn = priv->conn;
+	settings = ecbm_get_collection_settings (cbmapi);
 
-	priv->conn = e_mapi_connection_new (priv->profile, password, cancellable, &mapi_error);
+	priv->conn = e_mapi_connection_new (
+		e_cal_backend_get_registry (backend),
+		camel_mapi_settings_get_profile (settings), password, cancellable, &mapi_error);
 	if (!priv->conn) {
-		priv->conn = e_mapi_connection_find (priv->profile);
+		priv->conn = e_mapi_connection_find (camel_mapi_settings_get_profile (settings));
 		if (priv->conn
 		    && !e_mapi_connection_connected (priv->conn)) {
 			e_mapi_connection_reconnect (priv->conn, password, cancellable, &mapi_error);
@@ -1168,9 +1217,11 @@ ecbm_connect_user (ECalBackend *backend, GCancellable *cancellable, const gchar
 	if (priv->conn && e_mapi_connection_connected (priv->conn)) {
 		/* Success */
 		ESource *source;
+		ESourceMapiFolder *ext_mapi_folder;
 
 		source = e_backend_get_source (E_BACKEND (cbmapi));
-		if (source && g_strcmp0 (e_source_get_property (source, "server-notification"), "true") == 0) {
+		ext_mapi_folder = e_source_get_extension (source, E_SOURCE_EXTENSION_MAPI_FOLDER);
+		if (ext_mapi_folder && e_source_mapi_folder_get_server_notification (ext_mapi_folder)) {
 			mapi_object_t obj_folder;
 			gboolean status;
 
@@ -1186,36 +1237,67 @@ ecbm_connect_user (ECalBackend *backend, GCancellable *cancellable, const gchar
 			g_signal_connect (priv->conn, "server-notification", G_CALLBACK (ecbm_server_notification_cb), cbmapi);
 		}
 	} else {
-		mapi_error_to_edc_error (perror, mapi_error, g_error_matches (mapi_error, E_MAPI_ERROR, MAPI_E_NETWORK_ERROR) ? OtherError : AuthenticationFailed, NULL);
+		gboolean is_network_error = g_error_matches (mapi_error, E_MAPI_ERROR, MAPI_E_NETWORK_ERROR);
+
+		mapi_error_to_edc_error (perror, mapi_error, is_network_error ? OtherError : AuthenticationFailed, NULL);
 		if (mapi_error)
 			g_error_free (mapi_error);
 		g_static_mutex_unlock (&auth_mutex);
-		return;
+		return is_network_error ? E_SOURCE_AUTHENTICATION_ERROR : E_SOURCE_AUTHENTICATION_REJECTED;
 	}
 
 	if (mapi_error) {
 		mapi_error_to_edc_error (perror, mapi_error, AuthenticationFailed, NULL);
 		g_error_free (mapi_error);
 		g_static_mutex_unlock (&auth_mutex);
-		return;
+		return E_SOURCE_AUTHENTICATION_REJECTED;
 	}
 
 	g_static_mutex_unlock (&auth_mutex);
 
-	ecbm_connect (cbmapi, perror);
+	if (!priv->fid) {
+		g_propagate_error (perror, EDC_ERROR_EX (OtherError, "No folder ID set"));
+		return E_SOURCE_AUTHENTICATION_ERROR;
+	}
+
+	if (!priv->conn || !e_mapi_connection_connected (priv->conn)) {
+		g_propagate_error (perror, EDC_ERROR (AuthenticationFailed));
+		return E_SOURCE_AUTHENTICATION_REJECTED;
+	}
+
+	/* We have established a connection */
+	if (priv->store && priv->fid) {
+		e_cal_backend_notify_online (E_CAL_BACKEND (cbmapi), TRUE);
+
+		if (priv->mode_changed && !priv->dthread) {
+			priv->mode_changed = FALSE;
+			run_delta_thread (cbmapi);
+		}
+	}
+
+	priv->mode_changed = FALSE;
+
+	return E_SOURCE_AUTHENTICATION_ACCEPTED;
 }
 
 
 static void
-ecbm_open (ECalBackend *backend, EDataCal *cal, GCancellable *cancellable, gboolean only_if_exists, GError **perror)
+ecbm_open (ECalBackend *backend,
+	   EDataCal *cal,
+	   GCancellable *cancellable,
+	   gboolean only_if_exists,
+	   GError **perror)
 {
 	ECalBackendMAPI *cbmapi;
 	ECalBackendMAPIPrivate *priv;
 	ESource *esource;
-	const gchar *fid = NULL;
-	const gchar *cache_dir, *krb_sso = NULL;
+	ESourceMapiFolder *ext_mapi_folder;
+	guint64 fid;
+	const gchar *cache_dir;
+	CamelMapiSettings *settings;
+	GError *error = NULL;
 
-	if (e_cal_backend_is_opened (E_CAL_BACKEND (backend))) {
+	if (e_cal_backend_is_opened (backend)) {
 		e_cal_backend_notify_opened (backend, NULL);
 		return /* Success */;
 	}
@@ -1223,9 +1305,12 @@ ecbm_open (ECalBackend *backend, EDataCal *cal, GCancellable *cancellable, gbool
 	cbmapi = E_CAL_BACKEND_MAPI (backend);
 	priv = cbmapi->priv;
 
+	settings = ecbm_get_collection_settings (cbmapi);
+
 	esource = e_backend_get_source (E_BACKEND (cbmapi));
-	fid = e_source_get_property (esource, "folder-id");
-	if (!(fid && *fid)) {
+	ext_mapi_folder = e_source_get_extension (esource, E_SOURCE_EXTENSION_MAPI_FOLDER);
+	fid = e_source_mapi_folder_get_id (ext_mapi_folder);
+	if (!fid) {
 		g_propagate_error (perror, EDC_ERROR_EX (OtherError, "No folder ID set"));
 		e_cal_backend_notify_opened (backend, EDC_ERROR_EX (OtherError, "No folder ID set"));
 		return;
@@ -1255,13 +1340,13 @@ ecbm_open (ECalBackend *backend, EDataCal *cal, GCancellable *cancellable, gbool
 
 	/* Not for remote */
 	if (!e_backend_get_online (E_BACKEND (backend))) {
-		const gchar *display_contents = NULL;
+		ESourceOffline *offline_extension;
 
 		cbmapi->priv->read_only = TRUE;
 
-		display_contents = e_source_get_property (esource, "offline_sync");
+		offline_extension = e_source_get_extension (esource, E_SOURCE_EXTENSION_OFFLINE);
 
-		if (!display_contents || !g_str_equal (display_contents, "1")) {
+		if (!e_source_offline_get_stay_synchronized (offline_extension)) {
 			g_mutex_unlock (priv->mutex);
 			g_propagate_error (perror, EDC_ERROR (RepositoryOffline));
 			e_cal_backend_notify_opened (backend, EDC_ERROR (RepositoryOffline));
@@ -1275,51 +1360,48 @@ ecbm_open (ECalBackend *backend, EDataCal *cal, GCancellable *cancellable, gbool
 		return /* Success */;
 	}
 
-	g_free (priv->profile);
-	g_free (priv->user_name);
-	g_free (priv->user_email);
-	g_free (priv->owner_name);
-	g_free (priv->owner_email);
 	g_free (priv->foreign_username);
 
-	priv->profile = e_source_get_duped_property (esource, "profile");
-	priv->user_name = e_source_get_duped_property (esource, "acl-user-name");
-	priv->user_email = e_source_get_duped_property (esource, "acl-user-email");
-	priv->owner_name = e_source_get_duped_property (esource, "acl-owner-name");
-	priv->owner_email = e_source_get_duped_property (esource, "acl-owner-email");
-
-	e_mapi_util_mapi_id_from_string (fid, &priv->fid);
-	priv->is_public_folder = g_strcmp0 (e_source_get_property (esource, "public"), "yes") == 0;
-	priv->foreign_username = e_source_get_duped_property (esource, "foreign-username");
+	priv->fid = fid;
+	priv->is_public_folder = e_source_mapi_folder_is_public (ext_mapi_folder);
+	priv->foreign_username = e_source_mapi_folder_dup_foreign_username (ext_mapi_folder);
 
 	if (priv->foreign_username && !*priv->foreign_username) {
 		g_free (priv->foreign_username);
 		priv->foreign_username = NULL;
 	}
 
-	krb_sso = e_source_get_property (esource, "kerberos");
 	g_mutex_unlock (priv->mutex);
 
 	e_cal_backend_notify_online (backend, TRUE);
 	e_cal_backend_notify_readonly (backend, priv->read_only);
 
-	if (!krb_sso || !g_str_equal (krb_sso, "required")) {
-		e_cal_backend_notify_auth_required (backend, TRUE, NULL);
-	} else {
-		ecbm_connect_user (backend, cancellable, NULL, perror);
-		e_cal_backend_notify_opened (backend, NULL);
+	if (!camel_mapi_settings_get_kerberos (settings) ||
+	    ecbm_connect_user (backend, cancellable, NULL, &error) != E_SOURCE_AUTHENTICATION_ACCEPTED) {
+		ESourceRegistry *registry;
+
+		registry = e_cal_backend_get_registry (backend);
+
+		e_source_registry_authenticate_sync (
+			registry, esource,
+			E_SOURCE_AUTHENTICATOR (backend),
+			cancellable, &error);
 	}
+
+	if (error && perror)
+		g_propagate_error (perror, g_error_copy (error));
+
+	e_cal_backend_notify_opened (backend, error);
 }
 
-static void
-ecbm_authenticate_user (ECalBackend *backend, GCancellable *cancellable, ECredentials *credentials, GError **perror)
-{
-	const gchar *password;
 
-	g_static_mutex_lock (&auth_mutex);
-	password = e_credentials_peek (credentials, E_CREDENTIALS_KEY_PASSWORD);
-	g_static_mutex_unlock (&auth_mutex);
-	ecbm_connect_user (backend, cancellable, password, perror);
+static ESourceAuthenticationResult
+ecbm_try_password_sync (ESourceAuthenticator *authenticator,
+			const GString *password,
+			GCancellable *cancellable,
+			GError **error)
+{
+	return ecbm_connect_user (E_CAL_BACKEND (authenticator), cancellable, password, error);
 }
 
 static gboolean
@@ -1509,7 +1591,6 @@ ecbm_create_object (ECalBackend *backend, EDataCal *cal, GCancellable *cancellab
 	ECalComponent *comp;
 	mapi_id_t mid = 0;
 	gchar *tmp = NULL;
-	struct cal_cbdata cbdata = { 0 };
 	struct icaltimetype current;
 	GError *mapi_error = NULL;
 
@@ -1547,22 +1628,23 @@ ecbm_create_object (ECalBackend *backend, EDataCal *cal, GCancellable *cancellab
 	e_cal_component_set_created (comp, &current);
 	e_cal_component_set_last_modified (comp, &current);
 
-	cbdata.kind = kind;
-	cbdata.username = (gchar *) ecbm_get_user_name (cbmapi);
-	cbdata.useridtype = (gchar *) "SMTP";
-	cbdata.userid = (gchar *) ecbm_get_user_email (cbmapi);
-	cbdata.ownername = (gchar *) ecbm_get_owner_name (cbmapi);
-	cbdata.owneridtype = (gchar *) "SMTP";
-	cbdata.ownerid = (gchar *) ecbm_get_owner_email (cbmapi);
-	cbdata.get_timezone = (icaltimezone * (*)(gpointer data, const gchar *tzid)) ecbm_internal_get_timezone;
-	cbdata.get_tz_data = cbmapi;
-
 	/* Check if object exists */
 	if (e_backend_get_online (E_BACKEND (backend))) {
+		struct cal_cbdata cbdata = { 0 };
 		gboolean status;
 		mapi_object_t obj_folder;
 		gboolean has_attendees = e_cal_component_has_attendees (comp);
 
+		cbdata.kind = kind;
+		cbdata.username = g_strdup (ecbm_get_user_name (cbmapi));
+		cbdata.useridtype = (gchar *) "SMTP";
+		cbdata.userid = g_strdup (ecbm_get_user_email (cbmapi));
+		cbdata.ownername = g_strdup (ecbm_get_owner_name (cbmapi));
+		cbdata.owneridtype = (gchar *) "SMTP";
+		cbdata.ownerid = g_strdup (ecbm_get_owner_email (cbmapi));
+		cbdata.get_timezone = (icaltimezone * (*)(gpointer data, const gchar *tzid)) ecbm_internal_get_timezone;
+		cbdata.get_tz_data = cbmapi;
+
 		/* Create an appointment */
 		cbdata.comp = comp;
 		cbdata.is_modify = FALSE;
@@ -1583,6 +1665,11 @@ ecbm_create_object (ECalBackend *backend, EDataCal *cal, GCancellable *cancellab
 			e_mapi_connection_close_folder (priv->conn, &obj_folder, cancellable, &mapi_error);
 		}
 
+		g_free (cbdata.username);
+		g_free (cbdata.userid);
+		g_free (cbdata.ownername);
+		g_free (cbdata.ownerid);
+
 		if (!mid) {
 			g_object_unref (comp);
 			mapi_error_to_edc_error (error, mapi_error, OtherError, _("Failed to create item on a server"));
@@ -2384,8 +2471,6 @@ ecbm_notify_online_cb (ECalBackend *backend, GParamSpec *pspec)
 {
 	ECalBackendMAPI *cbmapi;
 	ECalBackendMAPIPrivate *priv;
-	ESource *esource = NULL;
-	const gchar *krb_sso = NULL;
 	gboolean online;
 
 	cbmapi = E_CAL_BACKEND_MAPI (backend);
@@ -2395,17 +2480,9 @@ ecbm_notify_online_cb (ECalBackend *backend, GParamSpec *pspec)
 
 	g_mutex_lock (priv->mutex);
 
-	esource = e_backend_get_source (E_BACKEND (cbmapi));
-	krb_sso = e_source_get_property (esource, "kerberos");
-	e_cal_backend_notify_online (backend, online);
-
 	priv->mode_changed = TRUE;
 	if (online) {
 		priv->read_only = FALSE;
-		if (e_cal_backend_is_opened (backend)
-		    && ! (krb_sso && g_str_equal (krb_sso, "required"))) {
-			e_cal_backend_notify_auth_required (backend, TRUE, NULL);
-		}
 	} else {
 		priv->read_only = TRUE;
 
@@ -2414,6 +2491,7 @@ ecbm_notify_online_cb (ECalBackend *backend, GParamSpec *pspec)
 	}
 
 	e_cal_backend_notify_readonly (backend, priv->read_only);
+	e_cal_backend_notify_online (backend, online);
 	g_mutex_unlock (priv->mutex);
 }
 
@@ -2472,7 +2550,6 @@ ecbm_internal_get_timezone (ECalBackend *backend, const gchar *tzid)
 typedef enum {
 	OP_GET_BACKEND_PROPERTY,
 	OP_OPEN,
-	OP_AUTHENTICATE_USER,
 	OP_REFRESH,
 	OP_REMOVE,
 	OP_CREATE_OBJECTS,
@@ -2507,13 +2584,6 @@ typedef struct {
 typedef struct {
 	OperationBase base;
 
-	ECredentials *credentials;
-	GCancellable *cancellable;
-} OperationAuthenticateUser;
-
-typedef struct {
-	OperationBase base;
-
 	GSList *calobjs;
 } OperationCreate;
 
@@ -2601,16 +2671,6 @@ ecbm_operation_cb (OperationBase *op, gboolean cancelled, ECalBackend *backend)
 			e_data_cal_respond_open (op->cal, op->opid, error);
 		}
 	} break;
-	case OP_AUTHENTICATE_USER: {
-		OperationAuthenticateUser *opau = (OperationAuthenticateUser *) op;
-
-		if (!cancelled) {
-			ecbm_authenticate_user (backend, op->cancellable, opau->credentials, &error);
-
-			e_cal_backend_notify_opened (backend, error);
-		}
-		e_credentials_free (opau->credentials);
-	} break;
 	case OP_REFRESH: {
 		if (!cancelled) {
 			ecbm_refresh (backend, op->cal, op->cancellable, &error);
@@ -3099,34 +3159,6 @@ ecbm_op_open (ECalBackend *backend, EDataCal *cal, guint32 opid, GCancellable *c
 	e_mapi_operation_queue_push (priv->op_queue, op);
 }
 
-static void
-ecbm_op_authenticate_user (ECalBackend *backend, GCancellable *cancellable, ECredentials *credentials)
-{
-	OperationAuthenticateUser *op;
-	ECalBackendMAPI *cbmapi;
-	ECalBackendMAPIPrivate *priv;
-
-	g_return_if_fail (backend != NULL);
-	g_return_if_fail (E_IS_CAL_BACKEND_MAPI (backend));
-
-	cbmapi = E_CAL_BACKEND_MAPI (backend);
-	priv = cbmapi->priv;
-	g_return_if_fail (priv != NULL);
-
-	g_object_ref (cbmapi);
-	if (cancellable)
-		g_object_ref (cancellable);
-
-	op = g_new0 (OperationAuthenticateUser, 1);
-	op->base.ot = OP_AUTHENTICATE_USER;
-	op->base.cal = NULL;
-	op->base.opid = 0;
-	op->base.cancellable = cancellable;
-	op->credentials = e_credentials_new_clone (credentials);
-
-	e_mapi_operation_queue_push (priv->op_queue, op);
-}
-
 STR_OP_DEF (ecbm_op_get_backend_property, OP_GET_BACKEND_PROPERTY)
 BASE_OP_DEF (ecbm_op_refresh, OP_REFRESH)
 BASE_OP_DEF (ecbm_op_remove, OP_REMOVE)
@@ -3430,31 +3462,6 @@ ecbm_finalize (GObject *object)
 		priv->store = NULL;
 	}
 
-	if (priv->profile) {
-		g_free (priv->profile);
-		priv->profile = NULL;
-	}
-
-	if (priv->user_name) {
-		g_free (priv->user_name);
-		priv->user_name = NULL;
-	}
-
-	if (priv->user_email) {
-		g_free (priv->user_email);
-		priv->user_email = NULL;
-	}
-
-	if (priv->owner_name) {
-		g_free (priv->owner_name);
-		priv->owner_name = NULL;
-	}
-
-	if (priv->owner_email) {
-		g_free (priv->owner_email);
-		priv->owner_email = NULL;
-	}
-
 	if (priv->sendoptions_sync_timeout) {
 		g_source_remove (priv->sendoptions_sync_timeout);
 		priv->sendoptions_sync_timeout = 0;
@@ -3493,7 +3500,6 @@ e_cal_backend_mapi_class_init (ECalBackendMAPIClass *class)
 	/* functions done asynchronously */
 	backend_class->get_backend_property = ecbm_op_get_backend_property;
 	backend_class->open = ecbm_op_open;
-	backend_class->authenticate_user = ecbm_op_authenticate_user;
 	backend_class->refresh = ecbm_op_refresh;
 	backend_class->remove = ecbm_op_remove;
 	backend_class->get_object = ecbm_op_get_object;
@@ -3515,6 +3521,12 @@ e_cal_backend_mapi_class_init (ECalBackendMAPIClass *class)
 }
 
 static void
+e_cal_backend_mapi_authenticator_init (ESourceAuthenticatorInterface *interface)
+{
+	interface->try_password_sync = ecbm_try_password_sync;
+}
+
+static void
 e_cal_backend_mapi_init (ECalBackendMAPI *cbmapi)
 {
 	ECalBackendMAPIPrivate *priv;
diff --git a/src/calendar/e-cal-backend-mapi.h b/src/calendar/e-cal-backend-mapi.h
index 91374d0..dc8689f 100644
--- a/src/calendar/e-cal-backend-mapi.h
+++ b/src/calendar/e-cal-backend-mapi.h
@@ -26,7 +26,7 @@
 
 #include <glib.h>
 
-#include <libedata-cal/e-cal-backend.h>
+#include <libedata-cal/libedata-cal.h>
 
 G_BEGIN_DECLS
 
diff --git a/src/camel/Makefile.am b/src/camel/Makefile.am
index ce4cc97..6b7ab43 100644
--- a/src/camel/Makefile.am
+++ b/src/camel/Makefile.am
@@ -7,6 +7,7 @@ AM_CPPFLAGS = -I.. 				\
 	-I$(top_srcdir)/src/			\
 	-I$(top_srcdir)/src/camel		\
 	-I$(top_srcdir)/src/libexchangemapi	\
+	$(EVOLUTION_MAIL_CFLAGS)		\
 	$(CAMEL_CFLAGS)				\
 	$(LIBECAL_CFLAGS)			\
         $(LIBMAPI_CFLAGS)                       \
@@ -31,6 +32,7 @@ noinst_HEADERS =         			\
 libcamelmapi_la_LDFLAGS = -avoid-version -module $(NO_UNDEFINED)
 libcamelmapi_la_LIBADD = 			\
 	$(top_builddir)/src/libexchangemapi/libexchangemapi-1.0.la \
+	$(EVOLUTION_MAIL_LIBS)			\
 	$(CAMEL_LIBS) 				\
 	$(LIBECAL_LIBS)				\
         $(LIBMAPI_LIBS)
diff --git a/src/camel/camel-mapi-store.c b/src/camel/camel-mapi-store.c
index c5cb5a5..2a42fcc 100644
--- a/src/camel/camel-mapi-store.c
+++ b/src/camel/camel-mapi-store.c
@@ -35,6 +35,7 @@
 #include <errno.h>
 
 #include <libmapi/libmapi.h>
+#include <libemail-engine/e-mail-session.h>
 
 #include <glib/gi18n-lib.h>
 #include <glib/gstdio.h>
@@ -313,7 +314,7 @@ mapi_convert_to_folder_info (CamelMapiStore *store,
 
 	name = escape_slash (e_mapi_folder_get_name (folder));
 
-	id = g_strdup_printf ("%016" G_GINT64_MODIFIER "X", e_mapi_folder_get_fid (folder));
+	id = g_strdup_printf ("%016" G_GINT64_MODIFIER "X", e_mapi_folder_get_id (folder));
 
 	fi = camel_folder_info_new ();
 
@@ -518,7 +519,7 @@ mapi_folders_sync (CamelMapiStore *store, guint32 flags, GCancellable *cancellab
 		gchar *fid = NULL, *parent_id = NULL, *tmp = NULL;
 		guint *folder_type = g_new0 (guint, 1);
 
-		fid = g_strdup_printf ("%016" G_GINT64_MODIFIER "X", e_mapi_folder_get_fid((EMapiFolder *)(temp_list->data)));
+		fid = g_strdup_printf ("%016" G_GINT64_MODIFIER "X", e_mapi_folder_get_id ((EMapiFolder *)(temp_list->data)));
 		parent_id = g_strdup_printf ("%016" G_GINT64_MODIFIER "X", e_mapi_folder_get_parent_id ((EMapiFolder *)(temp_list->data)));
 		full_name = g_hash_table_lookup (priv->id_hash, fid);
 		if (!full_name) {
@@ -569,7 +570,7 @@ mapi_folders_sync (CamelMapiStore *store, guint32 flags, GCancellable *cancellab
 			if (!msi) {
 				msi = (CamelMapiStoreInfo *) camel_mapi_store_summary_add_from_full (store->summary,
 						info->full_name,
-						e_mapi_folder_get_fid (folder),
+						e_mapi_folder_get_id (folder),
 						e_mapi_folder_get_parent_id (folder),
 						info->flags,
 						folder->category == E_MAPI_FOLDER_CATEGORY_PERSONAL ? CAMEL_MAPI_STORE_FOLDER_FLAG_PERSONAL :
@@ -600,7 +601,7 @@ mapi_folders_sync (CamelMapiStore *store, guint32 flags, GCancellable *cancellab
 			if (!msi) {
 				msi = (CamelMapiStoreInfo *) camel_mapi_store_summary_add_from_full (store->summary,
 						info->full_name,
-						e_mapi_folder_get_fid (folder),
+						e_mapi_folder_get_id (folder),
 						e_mapi_folder_get_parent_id (folder),
 						info->flags,
 						CAMEL_MAPI_STORE_FOLDER_FLAG_PUBLIC | CAMEL_MAPI_STORE_FOLDER_FLAG_PUBLIC_REAL,
@@ -693,12 +694,17 @@ unescape_folder_names (CamelFolderInfo *fi)
 }
 
 static CamelFolderInfo *
-mapi_get_folder_info_offline (CamelStore *store, const gchar *top,
-			 guint32 flags, GError **error)
+mapi_get_folder_info_offline (CamelStore *store,
+			      const gchar *top,
+			      guint32 flags,
+			      GCancellable *cancellable,
+			      GError **error)
 {
 	CamelMapiStore *mapi_store = CAMEL_MAPI_STORE (store);
-	CamelNetworkSettings *network_settings;
+	CamelMapiSettings *settings;
 	CamelFolderInfo *fi;
+	ESourceRegistry *registry = NULL;
+	GList *my_sources = NULL;
 	GPtrArray *folders;
 	gchar *path;
 	gint i, count;
@@ -708,9 +714,23 @@ mapi_get_folder_info_offline (CamelStore *store, const gchar *top,
 	subscription_list = (flags & CAMEL_STORE_FOLDER_INFO_SUBSCRIPTION_LIST);
 	subscribed = (flags & CAMEL_STORE_FOLDER_INFO_SUBSCRIBED);
 
-	network_settings = CAMEL_NETWORK_SETTINGS (camel_service_get_settings (CAMEL_SERVICE (store)));
+	settings = CAMEL_MAPI_SETTINGS (camel_service_get_settings (CAMEL_SERVICE (store)));
 	folders = g_ptr_array_new ();
 
+	if (subscription_list) {
+		GError *local_error = NULL;
+
+		registry = e_source_registry_new_sync (cancellable, &local_error);
+		if (registry) {
+			GList *all_sources = e_source_registry_list_sources (registry, NULL);
+
+			my_sources = e_mapi_utils_filter_sources_for_profile (all_sources,
+				camel_mapi_settings_get_profile (settings));
+
+			g_list_free_full (all_sources, g_object_unref);
+		}
+	}
+
 	if (!top || !*top)
 		top = "";
 
@@ -778,15 +798,10 @@ mapi_get_folder_info_offline (CamelStore *store, const gchar *top,
 
 				folder_type = mapi_folders_hash_table_type_lookup (mapi_store, camel_store_info_path (mapi_store->summary, si));
 				if (folder_type != E_MAPI_FOLDER_TYPE_UNKNOWN && folder_type != E_MAPI_FOLDER_TYPE_MAIL) {
-					gchar *fid = e_mapi_util_mapi_id_to_string (msi->folder_id);
-
-					if (e_mapi_folder_is_subscribed_as_esource (folder_type,
-						camel_network_settings_get_host (network_settings),
-						camel_network_settings_get_user (network_settings),
-						fid))
+					if (e_mapi_folder_is_subscribed_as_esource (my_sources,
+						camel_mapi_settings_get_profile (settings),
+						msi->folder_id))
 						fi->flags |= CAMEL_FOLDER_SUBSCRIBED;
-
-					g_free (fid);
 				}
 			}
 
@@ -823,6 +838,10 @@ mapi_get_folder_info_offline (CamelStore *store, const gchar *top,
 			(flags & CAMEL_STORE_FOLDER_INFO_SUBSCRIPTION_LIST) != 0 ?
 			_("No public folder found") : _("No folder found"));
 
+	g_list_free_full (my_sources, g_object_unref);
+	if (registry)
+		g_object_unref (registry);
+
 	return fi;
 }
 
@@ -1191,7 +1210,7 @@ mapi_store_get_folder_info_sync (CamelStore *store,
 		}
 	}
 
-	return mapi_get_folder_info_offline (store, top, flags, error);
+	return mapi_get_folder_info_offline (store, top, flags, cancellable, error);
 }
 
 static CamelFolder *
@@ -1792,8 +1811,6 @@ mapi_store_subscribe_folder_sync (CamelSubscribable *subscribable,
 	} else {
 		CamelSettings *settings;
 		CamelMapiSettings *mapi_settings;
-		CamelNetworkSettings *network_settings;
-		gchar *folder_id;
 		guint folder_type = mapi_folders_hash_table_type_lookup (mapi_store, folder_name);
 
 		/* remember the folder, thus it can be removed and checked in Subscriptions dialog */
@@ -1802,31 +1819,22 @@ mapi_store_subscribe_folder_sync (CamelSubscribable *subscribable,
 
 		settings = camel_service_get_settings (CAMEL_SERVICE (mapi_store));
 		mapi_settings = CAMEL_MAPI_SETTINGS (settings);
-		network_settings = CAMEL_NETWORK_SETTINGS (settings);
-
-		folder_id = e_mapi_util_mapi_id_to_string (msi->folder_id);
 
-		if (!e_mapi_folder_add_as_esource (folder_type,
+		if (!e_mapi_folder_add_as_esource (NULL, folder_type,
 			camel_mapi_settings_get_profile (mapi_settings),
-			camel_mapi_settings_get_domain (mapi_settings),
-			camel_mapi_settings_get_realm (mapi_settings),
-			camel_network_settings_get_host (network_settings),
-			camel_network_settings_get_user (network_settings),
-			camel_mapi_settings_get_kerberos (mapi_settings),
 			TRUE /* camel_offline_settings_get_stay_synchronized (CAMEL_OFFLINE_SETTINGS (mapi_settings)) */,
 			E_MAPI_FOLDER_CATEGORY_PUBLIC,
 			NULL,
 			use_folder_name,
-			folder_id,
+			msi->folder_id,
+			(gint) msi->folder_id,
+			cancellable,
 			error)) {
 			camel_store_summary_info_free (mapi_store->summary, si);
-			g_free (folder_id);
 			g_free (path);
 
 			return FALSE;
 		}
-
-		g_free (folder_id);
 	}
 	camel_store_summary_info_free (mapi_store->summary, si);
 	camel_store_summary_save (mapi_store->summary);
@@ -1884,17 +1892,14 @@ mapi_store_unsubscribe_folder_sync (CamelSubscribable *subscribable,
 			g_debug ("%s: Failed to find subscribed by folder ID", G_STRFUNC);
 		}
 	} else {
-		CamelSettings *settings;
-		CamelNetworkSettings *network_settings;
-		guint folder_type = mapi_folders_hash_table_type_lookup (mapi_store, folder_name);
+		CamelMapiSettings *settings;
 
-		settings = camel_service_get_settings (CAMEL_SERVICE (mapi_store));
-		network_settings = CAMEL_NETWORK_SETTINGS (settings);
+		settings = CAMEL_MAPI_SETTINGS (camel_service_get_settings (CAMEL_SERVICE (mapi_store)));
 
-		res = e_mapi_folder_remove_as_esource (folder_type,
-			camel_network_settings_get_host (network_settings),
-			camel_network_settings_get_user (network_settings),
-			camel_mapi_store_folder_id_lookup (mapi_store, folder_name),
+		res = e_mapi_folder_remove_as_esource (NULL,
+			camel_mapi_settings_get_profile (settings),
+			msi->folder_id,
+			cancellable,
 			error);
 	}
 
@@ -2516,6 +2521,7 @@ mapi_authenticate_sync (CamelService *service,
 	const gchar *profile;
 	const gchar *password;
 	GError *mapi_error = NULL;
+	GString *password_str;
 
 	settings = camel_service_get_settings (service);
 	mapi_settings = CAMEL_MAPI_SETTINGS (settings);
@@ -2544,7 +2550,11 @@ mapi_authenticate_sync (CamelService *service,
 		return CAMEL_AUTHENTICATION_ERROR;
 	}
 
-	store->priv->conn = e_mapi_connection_new (profile, password, cancellable, &mapi_error);
+	password_str = g_string_new (password);
+	store->priv->conn = e_mapi_connection_new (
+		e_mail_session_get_registry (E_MAIL_SESSION (camel_service_get_session (service))),
+		profile, password_str, cancellable, &mapi_error);
+	g_string_free (password_str, TRUE);
 	if (store->priv->conn && e_mapi_connection_connected (store->priv->conn)) {
 		result = CAMEL_AUTHENTICATION_ACCEPTED;
 
diff --git a/src/collection/Makefile.am b/src/collection/Makefile.am
new file mode 100644
index 0000000..f6b4ab3
--- /dev/null
+++ b/src/collection/Makefile.am
@@ -0,0 +1,35 @@
+NULL =
+
+eds_module_LTLIBRARIES = module-mapi-backend.la
+
+module_mapi_backend_la_CPPFLAGS =		\
+	$(AM_CPPFLAGS)				\
+	-DG_LOG_DOMAIN=\"module-mapi-backend\"	\
+	-I$(top_srcdir)/src/libexchangemapi	\
+	$(LIBEDATASERVER_CFLAGS)		\
+	$(LIBEBACKEND_CFLAGS)			\
+	$(LIBMAPI_CFLAGS)			\
+	$(CAMEL_CFLAGS)				\
+	$(NULL)
+
+module_mapi_backend_la_SOURCES =	\
+	module-mapi-backend.c		\
+	e-mapi-backend.c		\
+	e-mapi-backend.h		\
+	e-mapi-backend-factory.c	\
+	e-mapi-backend-factory.h	\
+	$(NULL)
+
+module_mapi_backend_la_LIBADD =		\
+	$(top_builddir)/src/libexchangemapi/libexchangemapi-1.0.la \
+	$(LIBEDATASERVER_LIBS)		\
+	$(LIBEBACKEND_LIBS)		\
+	$(LIBMAPI_LIBS)			\
+	$(CAMEL_LIBS)			\
+	$(NULL)
+
+module_mapi_backend_la_LDFLAGS = \
+	-module -avoid-version $(NO_UNDEFINED) \
+	$(NULL)
+
+-include $(top_srcdir)/git.mk
diff --git a/src/collection/e-mapi-backend-factory.c b/src/collection/e-mapi-backend-factory.c
new file mode 100644
index 0000000..18dcc24
--- /dev/null
+++ b/src/collection/e-mapi-backend-factory.c
@@ -0,0 +1,100 @@
+/*
+ * e-mapi-backend-factory.c
+ *
+ * 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/>
+ *
+ */
+
+#include "e-mapi-backend-factory.h"
+
+#include "e-mapi-backend.h"
+
+G_DEFINE_DYNAMIC_TYPE (
+	EMapiBackendFactory,
+	e_mapi_backend_factory,
+	E_TYPE_COLLECTION_BACKEND_FACTORY)
+
+static void
+mapi_backend_prepare_mail_account_source (ESource *source)
+{
+	ESourceBackend *extension;
+	const gchar *extension_name;
+
+	extension_name = E_SOURCE_EXTENSION_MAIL_ACCOUNT;
+	extension = e_source_get_extension (source, extension_name);
+	e_source_backend_set_backend_name (extension, "mapi");
+}
+
+static void
+mapi_backend_prepare_mail_transport_source (ESource *source)
+{
+	ESourceBackend *extension;
+	const gchar *extension_name;
+
+	extension_name = E_SOURCE_EXTENSION_MAIL_TRANSPORT;
+	extension = e_source_get_extension (source, extension_name);
+	e_source_backend_set_backend_name (extension, "mapi");
+}
+
+static void
+mapi_backend_factory_prepare_mail (ECollectionBackendFactory *factory,
+                                   ESource *mail_account_source,
+                                   ESource *mail_identity_source,
+                                   ESource *mail_transport_source)
+{
+	ECollectionBackendFactoryClass *parent_class;
+
+	/* Chain up to parent's prepare_mail() method. */
+	parent_class =
+		E_COLLECTION_BACKEND_FACTORY_CLASS (
+		e_mapi_backend_factory_parent_class);
+	parent_class->prepare_mail (
+		factory,
+		mail_account_source,
+		mail_identity_source,
+		mail_transport_source);
+
+	mapi_backend_prepare_mail_account_source (mail_account_source);
+	mapi_backend_prepare_mail_transport_source (mail_transport_source);
+}
+
+static void
+e_mapi_backend_factory_class_init (EMapiBackendFactoryClass *class)
+{
+	ECollectionBackendFactoryClass *factory_class;
+
+	factory_class = E_COLLECTION_BACKEND_FACTORY_CLASS (class);
+	factory_class->factory_name = "mapi";
+	factory_class->backend_type = E_TYPE_MAPI_BACKEND;
+	factory_class->prepare_mail = mapi_backend_factory_prepare_mail;
+}
+
+static void
+e_mapi_backend_factory_class_finalize (EMapiBackendFactoryClass *class)
+{
+}
+
+static void
+e_mapi_backend_factory_init (EMapiBackendFactory *factory)
+{
+}
+
+void
+e_mapi_backend_factory_type_register (GTypeModule *type_module)
+{
+	/* XXX G_DEFINE_DYNAMIC_TYPE declares a static type registration
+	 *     function, so we have to wrap it with a public function in
+	 *     order to register types from a separate compilation unit. */
+	e_mapi_backend_factory_register_type (type_module);
+}
diff --git a/src/collection/e-mapi-backend-factory.h b/src/collection/e-mapi-backend-factory.h
new file mode 100644
index 0000000..2c339ac
--- /dev/null
+++ b/src/collection/e-mapi-backend-factory.h
@@ -0,0 +1,64 @@
+/*
+ * e-mapi-backend-factory.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 E_MAPI_BACKEND_FACTORY_H
+#define E_MAPI_BACKEND_FACTORY_H
+
+#include <libebackend/libebackend.h>
+
+/* Standard GObject macros */
+#define E_TYPE_MAPI_BACKEND_FACTORY \
+	(e_mapi_backend_factory_get_type ())
+#define E_MAPI_BACKEND_FACTORY(obj) \
+	(G_TYPE_CHECK_INSTANCE_CAST \
+	((obj), E_TYPE_MAPI_BACKEND_FACTORY, EMapiBackendFactory))
+#define E_MAPI_BACKEND_FACTORY_CLASS(cls) \
+	(G_TYPE_CHECK_CLASS_CAST \
+	((cls), E_TYPE_MAPI_BACKEND_FACTORY, EMapiBackendFactoryClass))
+#define E_IS_MAPI_BACKEND_FACTORY(obj) \
+	(G_TYPE_CHECK_INSTANCE_TYPE \
+	((obj), E_TYPE_MAPI_BACKEND_FACTORY))
+#define E_IS_MAPI_BACKEND_FACTORY_CLASS(cls) \
+	(G_TYPE_CHECK_CLASS_TYPE \
+	((cls), E_TYPE_MAPI_BACKEND_FACTORY))
+#define E_MAPI_BACKEND_FACTORY_GET_CLASS(obj) \
+	(G_TYPE_INSTANCE_GET_CLASS \
+	((obj), E_TYPE_MAPI_BACKEND_FACTORY, EMapiBackendFactoryClass))
+
+G_BEGIN_DECLS
+
+typedef struct _EMapiBackendFactory EMapiBackendFactory;
+typedef struct _EMapiBackendFactoryClass EMapiBackendFactoryClass;
+typedef struct _EMapiBackendFactoryPrivate EMapiBackendFactoryPrivate;
+
+struct _EMapiBackendFactory {
+	ECollectionBackendFactory parent;
+	EMapiBackendFactoryPrivate *priv;
+};
+
+struct _EMapiBackendFactoryClass {
+	ECollectionBackendFactoryClass parent_class;
+};
+
+GType		e_mapi_backend_factory_get_type	(void) G_GNUC_CONST;
+void		e_mapi_backend_factory_type_register
+						(GTypeModule *type_module);
+
+G_END_DECLS
+
+#endif /* E_MAPI_BACKEND_FACTORY_H */
diff --git a/src/collection/e-mapi-backend.c b/src/collection/e-mapi-backend.c
new file mode 100644
index 0000000..82e8dd1
--- /dev/null
+++ b/src/collection/e-mapi-backend.c
@@ -0,0 +1,573 @@
+/*
+ * e-mapi-backend.c
+ *
+ * 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/>
+ *
+ */
+
+#include "e-mapi-backend.h"
+
+#include <config.h>
+#include <glib/gi18n-lib.h>
+
+#include <e-mapi-connection.h>
+#include <e-mapi-folder.h>
+#include <e-mapi-utils.h>
+#include <e-source-mapi-folder.h>
+#include <camel-mapi-settings.h>
+
+#define E_MAPI_BACKEND_GET_PRIVATE(obj) \
+	(G_TYPE_INSTANCE_GET_PRIVATE \
+	((obj), E_TYPE_MAPI_BACKEND, EMapiBackendPrivate))
+
+struct _EMapiBackendPrivate {
+	/* Folder ID -> ESource */
+	GHashTable *folders;
+
+	gboolean need_update_folders;
+};
+
+static void e_mapi_backend_authenticator_init (ESourceAuthenticatorInterface *interface);
+
+G_DEFINE_DYNAMIC_TYPE_EXTENDED (
+	EMapiBackend,
+	e_mapi_backend,
+	E_TYPE_COLLECTION_BACKEND,
+	0,
+	G_IMPLEMENT_INTERFACE_DYNAMIC (
+		E_TYPE_SOURCE_AUTHENTICATOR,
+		e_mapi_backend_authenticator_init))
+
+static CamelMapiSettings *
+mapi_backend_get_settings (EMapiBackend *backend)
+{
+	ESource *source;
+	ESourceCamel *extension;
+	CamelSettings *settings;
+	const gchar *extension_name;
+
+	source = e_backend_get_source (E_BACKEND (backend));
+	extension_name = e_source_camel_get_extension_name ("mapi");
+	extension = e_source_get_extension (source, extension_name);
+	settings = e_source_camel_get_settings (extension);
+
+	return CAMEL_MAPI_SETTINGS (settings);
+}
+
+static void
+mapi_backend_queue_auth_session (EMapiBackend *backend)
+{
+	ESourceRegistryServer *server;
+	EAuthenticationSession *session;
+	ESource *source;
+
+	backend->priv->need_update_folders = FALSE;
+
+	server = e_collection_backend_ref_server (E_COLLECTION_BACKEND (backend));
+	source = e_backend_get_source (E_BACKEND (backend));
+
+	session = e_authentication_session_new (
+		server, E_SOURCE_AUTHENTICATOR (backend),
+		e_source_get_uid (source));
+
+	e_source_registry_server_queue_auth_session (server, session);
+
+	g_object_unref (session);
+	g_object_unref (server);
+}
+
+struct SyndFoldersData
+{
+	EMapiBackend *backend;
+	GSList *folders;
+	gchar *profile;
+};
+
+static void
+sync_folders_data_free (gpointer data)
+{
+	struct SyndFoldersData *sfd = data;
+
+	if (!sfd)
+		return;
+
+	e_mapi_folder_free_list (sfd->folders);
+	g_object_unref (sfd->backend);
+	g_free (sfd->profile);
+	g_free (sfd);
+}
+
+static gboolean
+mapi_backend_sync_folders_idle_cb (gpointer user_data)
+{
+	struct SyndFoldersData *sfd = user_data;
+	GSList *iter;
+	GList *configured, *all_sources, *citer;
+	ESourceRegistryServer *server;
+	EMapiBackend *backend;
+	GSList *mapi_folders;
+	gboolean has_gal = FALSE;
+	gint color_seed;
+
+	g_return_val_if_fail (sfd != NULL, FALSE);
+	g_return_val_if_fail (sfd->backend != NULL, FALSE);
+	g_return_val_if_fail (sfd->profile != NULL, FALSE);
+
+	backend = sfd->backend;
+	mapi_folders = sfd->folders;
+
+	server = e_collection_backend_ref_server (E_COLLECTION_BACKEND (backend));
+	all_sources = e_source_registry_server_list_sources (server, NULL);
+	configured = e_mapi_utils_filter_sources_for_profile (all_sources, sfd->profile);
+	g_list_free_full (all_sources, g_object_unref);
+
+	color_seed = g_list_length (configured);
+
+	for (iter = mapi_folders; iter; iter = iter->next) {
+		EMapiFolder *folder = iter->data;
+		ESource *source;
+
+		if (e_mapi_folder_get_category (folder) != E_MAPI_FOLDER_CATEGORY_PERSONAL)
+			continue;
+
+		switch (e_mapi_folder_get_type (folder)) {
+		case E_MAPI_FOLDER_TYPE_APPOINTMENT:
+		case E_MAPI_FOLDER_TYPE_CONTACT:
+		case E_MAPI_FOLDER_TYPE_MEMO:
+		case E_MAPI_FOLDER_TYPE_JOURNAL:
+		case E_MAPI_FOLDER_TYPE_TASK:
+			break;
+		default:
+			continue;
+		}
+
+		source = e_mapi_utils_get_source_for_folder (configured, sfd->profile, e_mapi_folder_get_id (folder));
+		if (source) {
+			if (g_strcmp0 (e_source_get_display_name (source), e_mapi_folder_get_name (folder)) != 0)
+				e_source_set_display_name (source, e_mapi_folder_get_name (folder));
+
+			configured = g_list_remove (configured, source);
+			g_object_unref (source);
+		} else {
+			gchar *fid_str, *res_id;
+			const gchar *parent_id;
+
+			source = e_backend_get_source (E_BACKEND (backend));
+
+			parent_id = e_source_get_uid (source);
+			fid_str = e_mapi_util_mapi_id_to_string (e_mapi_folder_get_id (folder));
+			res_id = g_strconcat (parent_id ? parent_id : "mapi", ".", fid_str, NULL);
+			g_free (fid_str);
+
+			source = e_collection_backend_new_child (E_COLLECTION_BACKEND (backend), res_id);
+
+			if (e_mapi_folder_populate_esource (
+				source,
+				configured,
+				e_mapi_folder_get_type (folder),
+				sfd->profile,
+				TRUE,
+				E_MAPI_FOLDER_CATEGORY_PERSONAL,
+				NULL,
+				e_mapi_folder_get_name (folder),
+				e_mapi_folder_get_id (folder),
+				color_seed,
+				NULL,
+				NULL)) {
+				color_seed++;
+				e_source_registry_server_add_source (server, source);
+			}
+
+			g_free (res_id);
+			g_object_unref (source);
+		}
+	}
+
+	/* those which left are either mail sources, GAL or removed from the server */
+	for (citer = configured; citer; citer = citer->next) {
+		ESource *source = citer->data;
+		ESourceMapiFolder *folder_ext;
+		const gchar *foreign_user_name;
+
+		if (!e_source_has_extension (source, E_SOURCE_EXTENSION_MAPI_FOLDER))
+			continue;
+
+		if (!e_source_has_extension (source, E_SOURCE_EXTENSION_ADDRESS_BOOK) &&
+		    !e_source_has_extension (source, E_SOURCE_EXTENSION_CALENDAR) &&
+		    !e_source_has_extension (source, E_SOURCE_EXTENSION_MEMO_LIST) &&
+		    !e_source_has_extension (source, E_SOURCE_EXTENSION_TASK_LIST))
+			continue;
+
+		folder_ext = e_source_get_extension (source, E_SOURCE_EXTENSION_MAPI_FOLDER);
+		if (e_source_mapi_folder_is_public (folder_ext))
+			continue;
+
+		foreign_user_name = e_source_mapi_folder_get_foreign_username (folder_ext);
+		if (foreign_user_name && *foreign_user_name)
+			continue;
+
+		/* test GAL */
+		if (!has_gal && e_source_has_extension (source, E_SOURCE_EXTENSION_ADDRESS_BOOK)) {
+			ESourceAddressBook *book_ext;
+
+			book_ext = e_source_get_extension (source, E_SOURCE_EXTENSION_ADDRESS_BOOK);
+			has_gal = g_strcmp0 ("mapigal", e_source_backend_get_backend_name (E_SOURCE_BACKEND (book_ext))) == 0;
+			if (has_gal)
+				continue;
+		}
+
+		e_source_registry_server_remove_source (server, source);
+	}
+
+	/* add GAL, if not there already */
+	if (!has_gal) {
+		ESource *source;
+
+		source = e_collection_backend_new_child (E_COLLECTION_BACKEND (backend), "mapigal");
+
+		if (e_mapi_folder_populate_esource (
+			source,
+			configured,
+			E_MAPI_FOLDER_TYPE_CONTACT,
+			sfd->profile,
+			FALSE,
+			E_MAPI_FOLDER_CATEGORY_PERSONAL,
+			NULL,
+			_("Global Address List"),
+			-1,
+			0,
+			NULL,
+			NULL)) {
+			ESourceAddressBook *book_ext;
+			/* ESourceContancts *contacts_ext; */
+
+			book_ext = e_source_get_extension (source, E_SOURCE_EXTENSION_ADDRESS_BOOK);
+			e_source_backend_set_backend_name (E_SOURCE_BACKEND (book_ext), "mapigal");
+
+			/* exclude GAL from Birthday & Anniversaries calendar by default */
+			/* but it is not accessible from outside (yet)
+			contacts_ext = e_source_get_extension (source, E_SOURCE_EXTENSION_CONTACTS_BACKEND);
+			e_source_contacts_set_include_me (contacts_ext, FALSE); */
+
+			e_source_registry_server_add_source (server, source);
+		}
+
+		g_object_unref (source);
+	}
+
+	g_list_free_full (configured, g_object_unref);
+	g_object_unref (server);
+
+	return FALSE;
+}
+
+static void
+mapi_backend_source_changed_cb (ESource *source,
+				EMapiBackend *backend)
+{
+	/* does nothing currently */
+	if (!e_source_get_enabled (source)) {
+		backend->priv->need_update_folders = TRUE;
+		return;
+	}
+
+	if (e_source_get_enabled (source) &&
+	    e_backend_get_online (E_BACKEND (backend)) &&
+	    backend->priv->need_update_folders)
+		mapi_backend_queue_auth_session (backend);
+}
+
+static void
+mapi_backend_dispose (GObject *object)
+{
+	EMapiBackendPrivate *priv;
+
+	priv = E_MAPI_BACKEND_GET_PRIVATE (object);
+
+	g_hash_table_remove_all (priv->folders);
+
+	/* Chain up to parent's dispose() method. */
+	G_OBJECT_CLASS (e_mapi_backend_parent_class)->dispose (object);
+}
+
+static void
+mapi_backend_finalize (GObject *object)
+{
+	EMapiBackendPrivate *priv;
+
+	priv = E_MAPI_BACKEND_GET_PRIVATE (object);
+
+	g_hash_table_destroy (priv->folders);
+
+	/* Chain up to parent's finalize() method. */
+	G_OBJECT_CLASS (e_mapi_backend_parent_class)->finalize (object);
+}
+
+static void
+mapi_backend_populate (ECollectionBackend *backend)
+{
+	ESource *source;
+	EMapiBackend *mapi_backend = E_MAPI_BACKEND (backend);
+
+	source = e_backend_get_source (E_BACKEND (backend));
+
+	mapi_backend->priv->need_update_folders = TRUE;
+
+	/* do not do anything, if account is disabled */
+	if (!e_source_get_enabled (source) ||
+	    !e_backend_get_online (E_BACKEND (backend)))
+		return;
+
+	/* We test authentication passwords by attempting to synchronize
+	 * the folder hierarchy.  Since we want to synchronize the folder
+	 * hierarchy immediately on startup, schedule an authentication
+	 * session first thing. */
+	mapi_backend_queue_auth_session (mapi_backend);
+
+	g_signal_connect (
+		source, "changed",
+		G_CALLBACK (mapi_backend_source_changed_cb), backend);
+}
+
+static gchar *
+mapi_backend_dup_resource_id (ECollectionBackend *backend,
+			      ESource *child_source)
+{
+	ESourceMapiFolder *extension;
+	const gchar *extension_name;
+	gchar *fid_str, *res_id;
+	const gchar *parent_id;
+	ESource *source;
+
+	extension_name = E_SOURCE_EXTENSION_MAPI_FOLDER;
+	extension = e_source_get_extension (child_source, extension_name);
+	source = e_backend_get_source (E_BACKEND (backend));
+
+	parent_id = e_source_get_uid (source);
+	fid_str = e_mapi_util_mapi_id_to_string (e_source_mapi_folder_get_id (extension));
+	res_id = g_strconcat (parent_id ? parent_id : "mapi", ".", fid_str, NULL);
+	g_free (fid_str);
+
+	return res_id;
+}
+
+static void
+mapi_backend_child_added (ECollectionBackend *backend,
+                          ESource *child_source)
+{
+	EMapiBackendPrivate *priv;
+	ESource *collection_source;
+	const gchar *extension_name;
+	gboolean is_mail = FALSE;
+
+	priv = E_MAPI_BACKEND_GET_PRIVATE (backend);
+
+	collection_source = e_backend_get_source (E_BACKEND (backend));
+
+	extension_name = E_SOURCE_EXTENSION_MAIL_ACCOUNT;
+	is_mail |= e_source_has_extension (child_source, extension_name);
+
+	extension_name = E_SOURCE_EXTENSION_MAIL_IDENTITY;
+	is_mail |= e_source_has_extension (child_source, extension_name);
+
+	extension_name = E_SOURCE_EXTENSION_MAIL_TRANSPORT;
+	is_mail |= e_source_has_extension (child_source, extension_name);
+
+	/* Synchronize mail-related display names with the collection. */
+	if (is_mail)
+		g_object_bind_property (
+			collection_source, "display-name",
+			child_source, "display-name",
+			G_BINDING_SYNC_CREATE);
+
+	/* Synchronize mail-related user with the collection identity. */
+	extension_name = E_SOURCE_EXTENSION_AUTHENTICATION;
+	if (is_mail && e_source_has_extension (child_source, extension_name)) {
+		ESourceAuthentication *auth_child_extension;
+		ESourceCollection *collection_extension;
+
+		extension_name = E_SOURCE_EXTENSION_COLLECTION;
+		collection_extension = e_source_get_extension (
+			collection_source, extension_name);
+
+		extension_name = E_SOURCE_EXTENSION_AUTHENTICATION;
+		auth_child_extension = e_source_get_extension (
+			child_source, extension_name);
+
+		g_object_bind_property (
+			collection_extension, "identity",
+			auth_child_extension, "user",
+			G_BINDING_SYNC_CREATE);
+	}
+
+	/* We track MAPI folders in a hash table by folder ID. */
+	extension_name = E_SOURCE_EXTENSION_MAPI_FOLDER;
+	if (e_source_has_extension (child_source, extension_name)) {
+		ESourceMapiFolder *extension;
+		gchar *folder_id;
+
+		extension = e_source_get_extension (
+			child_source, extension_name);
+		folder_id = e_mapi_util_mapi_id_to_string (e_source_mapi_folder_get_id (extension));
+		if (folder_id != NULL)
+			g_hash_table_insert (
+				priv->folders, folder_id,
+				g_object_ref (child_source));
+	}
+
+	/* Chain up to parent's child_added() method. */
+	E_COLLECTION_BACKEND_CLASS (e_mapi_backend_parent_class)->
+		child_added (backend, child_source);
+}
+
+static void
+mapi_backend_child_removed (ECollectionBackend *backend,
+                            ESource *child_source)
+{
+	EMapiBackendPrivate *priv;
+	const gchar *extension_name;
+
+	priv = E_MAPI_BACKEND_GET_PRIVATE (backend);
+
+	/* We track MAPI folders in a hash table by folder ID. */
+	extension_name = E_SOURCE_EXTENSION_MAPI_FOLDER;
+	if (e_source_has_extension (child_source, extension_name)) {
+		ESourceMapiFolder *extension;
+		gchar *folder_id;
+
+		extension = e_source_get_extension (child_source, extension_name);
+		folder_id = e_mapi_util_mapi_id_to_string (e_source_mapi_folder_get_id (extension));
+		if (folder_id != NULL)
+			g_hash_table_remove (priv->folders, folder_id);
+		g_free (folder_id);
+	}
+
+	/* Chain up to parent's child_removed() method. */
+	E_COLLECTION_BACKEND_CLASS (e_mapi_backend_parent_class)->
+		child_removed (backend, child_source);
+}
+
+static ESourceAuthenticationResult
+mapi_backend_try_password_sync (ESourceAuthenticator *authenticator,
+				const GString *password,
+				GCancellable *cancellable,
+				GError **error)
+{
+	EMapiBackend *backend;
+	EMapiConnection *conn;
+	CamelMapiSettings *settings;
+	GSList *mapi_folders = NULL;
+	GError *mapi_error = NULL;
+
+	backend = E_MAPI_BACKEND (authenticator);
+	settings = mapi_backend_get_settings (backend);
+
+	conn = e_mapi_connection_new (NULL,
+		camel_mapi_settings_get_profile (settings),
+		password, cancellable, &mapi_error);
+
+	if (!conn) {
+		ESourceAuthenticationResult res = E_SOURCE_AUTHENTICATION_ERROR;
+
+		backend->priv->need_update_folders = TRUE;
+
+		if (g_error_matches (mapi_error, E_MAPI_ERROR, MAPI_E_PASSWORD_CHANGE_REQUIRED) ||
+		    g_error_matches (mapi_error, E_MAPI_ERROR, MAPI_E_PASSWORD_EXPIRED))
+			res = E_SOURCE_AUTHENTICATION_REJECTED;
+
+		g_propagate_error (error, mapi_error);
+
+		return res;
+	}
+
+	if (e_mapi_connection_get_folders_list (conn, &mapi_folders, NULL, NULL, cancellable, &mapi_error)) {
+		struct SyndFoldersData *sfd;
+
+		sfd = g_new0 (struct SyndFoldersData, 1);
+		sfd->folders = mapi_folders;
+		sfd->backend = g_object_ref (backend);
+		sfd->profile = camel_mapi_settings_dup_profile (settings);
+
+		g_idle_add_full (
+			G_PRIORITY_DEFAULT_IDLE,
+			mapi_backend_sync_folders_idle_cb, sfd,
+			sync_folders_data_free);
+	} else {
+		ESource *source = e_backend_get_source (E_BACKEND (backend));
+
+		backend->priv->need_update_folders = TRUE;
+
+		g_message ("%s: Failed to get list of user's folders for '%s': %s",
+			G_STRFUNC, e_source_get_display_name (source), mapi_error ? mapi_error->message : "Unknown error");
+	}
+
+	g_object_unref (conn);
+	g_clear_error (&mapi_error);
+
+	return E_SOURCE_AUTHENTICATION_ACCEPTED;
+}
+
+static void
+e_mapi_backend_class_init (EMapiBackendClass *class)
+{
+	GObjectClass *object_class;
+	ECollectionBackendClass *backend_class;
+
+	g_type_class_add_private (class, sizeof (EMapiBackendPrivate));
+
+	object_class = G_OBJECT_CLASS (class);
+	object_class->dispose = mapi_backend_dispose;
+	object_class->finalize = mapi_backend_finalize;
+
+	backend_class = E_COLLECTION_BACKEND_CLASS (class);
+	backend_class->populate = mapi_backend_populate;
+	backend_class->dup_resource_id = mapi_backend_dup_resource_id;
+	backend_class->child_added = mapi_backend_child_added;
+	backend_class->child_removed = mapi_backend_child_removed;
+
+	/* This generates an ESourceCamel subtype for CamelMapiSettings. */
+	e_source_camel_generate_subtype ("mapi", CAMEL_TYPE_MAPI_SETTINGS);
+}
+
+static void
+e_mapi_backend_class_finalize (EMapiBackendClass *class)
+{
+}
+
+static void
+e_mapi_backend_authenticator_init (ESourceAuthenticatorInterface *interface)
+{
+	interface->try_password_sync = mapi_backend_try_password_sync;
+}
+
+static void
+e_mapi_backend_init (EMapiBackend *backend)
+{
+	backend->priv = E_MAPI_BACKEND_GET_PRIVATE (backend);
+
+	backend->priv->folders = g_hash_table_new_full (
+		(GHashFunc) g_str_hash,
+		(GEqualFunc) g_str_equal,
+		(GDestroyNotify) g_free,
+		(GDestroyNotify) g_object_unref);
+}
+
+void
+e_mapi_backend_type_register (GTypeModule *type_module)
+{
+	/* XXX G_DEFINE_DYNAMIC_TYPE declares a static type registration
+	 *     function, so we have to wrap it with a public function in
+	 *     order to register types from a separate compilation unit. */
+	e_mapi_backend_register_type (type_module);
+}
diff --git a/src/collection/e-mapi-backend.h b/src/collection/e-mapi-backend.h
new file mode 100644
index 0000000..d30e65c
--- /dev/null
+++ b/src/collection/e-mapi-backend.h
@@ -0,0 +1,63 @@
+/*
+ * e-mapi-backend.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 E_MAPI_BACKEND_H
+#define E_MAPI_BACKEND_H
+
+#include <libebackend/libebackend.h>
+
+/* Standard GObject macros */
+#define E_TYPE_MAPI_BACKEND \
+	(e_mapi_backend_get_type ())
+#define E_MAPI_BACKEND(obj) \
+	(G_TYPE_CHECK_INSTANCE_CAST \
+	((obj), E_TYPE_MAPI_BACKEND, EMapiBackend))
+#define E_MAPI_BACKEND_CLASS(cls) \
+	(G_TYPE_CHECK_CLASS_CAST \
+	((cls), E_TYPE_MAPI_BACKEND, EMapiBackendClass))
+#define E_IS_MAPI_BACKEND(obj) \
+	(G_TYPE_CHECK_INSTANCE_TYPE \
+	((obj), E_TYPE_MAPI_BACKEND))
+#define E_IS_MAPI_BACKEND_CLASS(cls) \
+	(G_TYPE_CHECK_CLASS_TYPE \
+	((cls), E_TYPE_MAPI_BACKEND))
+#define E_MAPI_BACKEND_GET_CLASS(obj) \
+	(G_TYPE_INSTANCE_GET_CLASS \
+	((obj), E_TYPE_MAPI_BACKEND, EMapiBackendClass))
+
+G_BEGIN_DECLS
+
+typedef struct _EMapiBackend EMapiBackend;
+typedef struct _EMapiBackendClass EMapiBackendClass;
+typedef struct _EMapiBackendPrivate EMapiBackendPrivate;
+
+struct _EMapiBackend {
+	ECollectionBackend parent;
+	EMapiBackendPrivate *priv;
+};
+
+struct _EMapiBackendClass {
+	ECollectionBackendClass parent_class;
+};
+
+GType		e_mapi_backend_get_type		(void) G_GNUC_CONST;
+void		e_mapi_backend_type_register	(GTypeModule *type_module);
+
+G_END_DECLS
+
+#endif /* E_MAPI_BACKEND_H */
diff --git a/src/account-setup-eplugin/e-mapi-subscribe-foreign-folder.h b/src/collection/module-mapi-backend.c
similarity index 55%
copy from src/account-setup-eplugin/e-mapi-subscribe-foreign-folder.h
copy to src/collection/module-mapi-backend.c
index debf5b5..50cd84f 100644
--- a/src/account-setup-eplugin/e-mapi-subscribe-foreign-folder.h
+++ b/src/collection/module-mapi-backend.c
@@ -1,5 +1,6 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
 /*
+ * module-mapi-backend.c
+ *
  * 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
@@ -13,22 +14,27 @@
  * 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/>
  *
- *
- * Authors:
- *    Milan Crha <mcrha redhat com>
- *
- * Copyright (C) 2012 Red Hat, Inc. (www.redhat.com)
- *
  */
 
-#ifndef E_MAPI_SUBSCRIBE_FOREIGN_FOLDER_H
-#define E_MAPI_SUBSCRIBE_FOREIGN_FOLDER_H
+#include "e-source-mapi-folder.h"
+
+#include "e-mapi-backend.h"
+#include "e-mapi-backend-factory.h"
+
+/* Module Entry Points */
+void e_module_load (GTypeModule *type_module);
+void e_module_unload (GTypeModule *type_module);
 
-#include <gtk/gtk.h>
-#include <camel/camel.h>
+G_MODULE_EXPORT void
+e_module_load (GTypeModule *type_module)
+{
+	e_mapi_backend_type_register (type_module);
+	e_mapi_backend_factory_type_register (type_module);
 
-void	e_mapi_subscribe_foreign_folder	(GtkWindow *parent,
-					 CamelSession *session,
-					 CamelStore *store);
+	e_source_mapi_folder_type_register (type_module);
+}
 
-#endif /* E_MAPI_SUBSCRIBE_FOREIGN_FOLDER_H */
+G_MODULE_EXPORT void
+e_module_unload (GTypeModule *type_module)
+{
+}
diff --git a/src/configuration/Makefile.am b/src/configuration/Makefile.am
new file mode 100644
index 0000000..d3cb06a
--- /dev/null
+++ b/src/configuration/Makefile.am
@@ -0,0 +1,57 @@
+NULL =
+
+evo_module_LTLIBRARIES = module-mapi-configuration.la
+
+module_mapi_configuration_la_CPPFLAGS =			\
+	$(AM_CPPFLAGS)					\
+	-DG_LOG_DOMAIN=\"module-mapi-configuration\"	\
+	-I$(top_srcdir)/src				\
+	-I$(top_srcdir)/src/libexchangemapi		\
+	$(LIBECAL_CFLAGS)				\
+	$(LIBEDATASERVER_CFLAGS)			\
+	$(CAMEL_CFLAGS)					\
+	$(EVOLUTION_MAIL_CFLAGS)			\
+	$(EVOLUTION_SHELL_CFLAGS)			\
+	$(LIBMAPI_CFLAGS)				\
+	$(NULL)
+
+module_mapi_configuration_la_SOURCES =		\
+	module-mapi-configuration.c		\
+	e-book-config-mapi.c			\
+	e-book-config-mapi.h			\
+	e-book-config-mapigal.c			\
+	e-book-config-mapigal.h			\
+	e-cal-config-mapi.c			\
+	e-cal-config-mapi.h			\
+	e-mail-config-mapi-backend.c		\
+	e-mail-config-mapi-backend.h		\
+	e-mail-config-mapi-page.c		\
+	e-mail-config-mapi-page.h		\
+	e-mail-config-mapi-extension.c		\
+	e-mail-config-mapi-extension.h		\
+	e-mapi-config-ui-extension.c		\
+	e-mapi-config-ui-extension.h		\
+	e-mapi-config-utils.c			\
+	e-mapi-config-utils.h			\
+	e-mapi-edit-folder-permissions.c	\
+	e-mapi-edit-folder-permissions.h	\
+	e-mapi-search-gal-user.c		\
+	e-mapi-search-gal-user.h		\
+	e-mapi-subscribe-foreign-folder.c	\
+	e-mapi-subscribe-foreign-folder.h	\
+	$(NULL)
+
+module_mapi_configuration_la_LIBADD =		\
+	$(top_builddir)/src/libexchangemapi/libexchangemapi-1.0.la \
+	$(LIBECAL_LIBS)				\
+	$(LIBEDATASERVER_LIBS)			\
+	$(CAMEL_LIBS)				\
+	$(EVOLUTION_MAIL_LIBS)			\
+	$(EVOLUTION_SHELL_LIBS)			\
+	$(LIBMAPI_LIBS)				\
+	$(NULL)
+
+module_mapi_configuration_la_LDFLAGS = \
+	-module -avoid-version $(NO_UNDEFINED)
+
+-include $(top_srcdir)/git.mk
diff --git a/src/configuration/e-book-config-mapi.c b/src/configuration/e-book-config-mapi.c
new file mode 100644
index 0000000..48c954d
--- /dev/null
+++ b/src/configuration/e-book-config-mapi.c
@@ -0,0 +1,75 @@
+/*
+ * e-book-config-mapi.c
+ *
+ * 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/>
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <misc/e-book-source-config.h>
+
+#include "e-book-config-mapi.h"
+#include "e-mapi-config-utils.h"
+
+G_DEFINE_DYNAMIC_TYPE (EBookConfigMapi, e_book_config_mapi, E_TYPE_SOURCE_CONFIG_BACKEND)
+
+static gboolean
+book_config_mapi_allow_creation (ESourceConfigBackend *backend)
+{
+	return TRUE;
+}
+
+static void
+book_config_mapi_insert_widgets (ESourceConfigBackend *backend,
+				 ESource *scratch_source)
+{
+	e_mapi_config_utils_insert_widgets (backend, scratch_source);
+}
+
+static void
+e_book_config_mapi_class_init (EBookConfigMapiClass *class)
+{
+	EExtensionClass *extension_class;
+	ESourceConfigBackendClass *backend_class;
+
+	extension_class = E_EXTENSION_CLASS (class);
+	extension_class->extensible_type = E_TYPE_BOOK_SOURCE_CONFIG;
+
+	backend_class = E_SOURCE_CONFIG_BACKEND_CLASS (class);
+	backend_class->backend_name = "mapi";
+	backend_class->allow_creation = book_config_mapi_allow_creation;
+	backend_class->insert_widgets = book_config_mapi_insert_widgets;
+}
+
+static void
+e_book_config_mapi_class_finalize (EBookConfigMapiClass *class)
+{
+}
+
+static void
+e_book_config_mapi_init (EBookConfigMapi *backend)
+{
+}
+
+void
+e_book_config_mapi_type_register (GTypeModule *type_module)
+{
+	/* XXX G_DEFINE_DYNAMIC_TYPE declares a static type registration
+	 *     function, so we have to wrap it with a public function in
+	 *     order to register types from a separate compilation unit. */
+	e_book_config_mapi_register_type (type_module);
+}
diff --git a/src/configuration/e-book-config-mapi.h b/src/configuration/e-book-config-mapi.h
new file mode 100644
index 0000000..1274551
--- /dev/null
+++ b/src/configuration/e-book-config-mapi.h
@@ -0,0 +1,63 @@
+/*
+ * e-book-config-mapi.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 E_BOOK_CONFIG_MAPI_H
+#define E_BOOK_CONFIG_MAPI_H
+
+#include <misc/e-source-config-backend.h>
+
+/* Standard GObject macros */
+#define E_TYPE_BOOK_CONFIG_MAPI \
+	(e_book_config_mapi_get_type ())
+#define E_BOOK_CONFIG_MAPI(obj) \
+	(G_TYPE_CHECK_INSTANCE_CAST \
+	((obj), E_TYPE_BOOK_CONFIG_MAPI, EBookConfigMapi))
+#define E_BOOK_CONFIG_MAPI_CLASS(cls) \
+	(G_TYPE_CHECK_CLASS_CAST \
+	((cls), E_TYPE_BOOK_CONFIG_MAPI, EBookConfigMapiClass))
+#define E_IS_BOOK_CONFIG_MAPI(obj) \
+	(G_TYPE_CHECK_INSTANCE_TYPE \
+	((obj), E_TYPE_BOOK_CONFIG_MAPI))
+#define E_IS_BOOK_CONFIG_MAPI_CLASS(cls) \
+	(G_TYPE_CHECK_CLASS_TYPE \
+	((cls), E_TYPE_BOOK_CONFIG_MAPI))
+#define E_BOOK_CONFIG_MAPI_GET_CLASS(obj) \
+	(G_TYPE_INSTANCE_GET_CLASS \
+	((obj), E_TYPE_BOOK_CONFIG_MAPI, EBookConfigMapiClass))
+
+G_BEGIN_DECLS
+
+typedef struct _EBookConfigMapi EBookConfigMapi;
+typedef struct _EBookConfigMapiClass EBookConfigMapiClass;
+typedef struct _EBookConfigMapiPrivate EBookConfigMapiPrivate;
+
+struct _EBookConfigMapi {
+	ESourceConfigBackend parent;
+	EBookConfigMapiPrivate *priv;
+};
+
+struct _EBookConfigMapiClass {
+	ESourceConfigBackendClass parent_class;
+};
+
+GType	e_book_config_mapi_get_type		(void) G_GNUC_CONST;
+void	e_book_config_mapi_type_register	(GTypeModule *type_module);
+
+G_END_DECLS
+
+#endif /* E_BOOK_CONFIG_MAPI_H */
diff --git a/src/configuration/e-book-config-mapigal.c b/src/configuration/e-book-config-mapigal.c
new file mode 100644
index 0000000..fe7945c
--- /dev/null
+++ b/src/configuration/e-book-config-mapigal.c
@@ -0,0 +1,106 @@
+/*
+ * e-book-config-mapigal.c
+ *
+ * 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/>
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <glib/gi18n-lib.h>
+
+#include <misc/e-book-source-config.h>
+
+#include "e-source-mapi-folder.h"
+#include "e-book-config-mapigal.h"
+
+G_DEFINE_DYNAMIC_TYPE (
+	EBookConfigMapigal,
+	e_book_config_mapigal,
+	E_TYPE_SOURCE_CONFIG_BACKEND)
+
+static gboolean
+book_config_mapigal_allow_creation (ESourceConfigBackend *backend)
+{
+	return FALSE;
+}
+
+static void
+book_config_mapigal_insert_widgets (ESourceConfigBackend *backend,
+				    ESource *scratch_source)
+{
+	ESourceBackend *backend_ext;
+	ESourceMapiFolder *folder_ext;
+	ESourceConfig *config;
+	GtkWidget *widget;
+
+	if (!e_source_has_extension (scratch_source, E_SOURCE_EXTENSION_ADDRESS_BOOK))
+		return;
+
+	backend_ext = e_source_get_extension (scratch_source, E_SOURCE_EXTENSION_ADDRESS_BOOK);
+	if (!backend_ext || g_strcmp0 (e_source_backend_get_backend_name (backend_ext), "mapigal") != 0)
+		return;
+
+	folder_ext = e_source_get_extension (scratch_source, E_SOURCE_EXTENSION_MAPI_FOLDER);
+	g_return_if_fail (folder_ext != NULL);
+
+	config = e_source_config_backend_get_config (backend);
+	e_book_source_config_add_offline_toggle (E_BOOK_SOURCE_CONFIG (config), scratch_source);
+
+	widget = gtk_check_button_new_with_mnemonic (_("Allow _partial search results"));
+	e_source_config_insert_widget (config, scratch_source, NULL, widget);
+	gtk_widget_show (widget);
+
+	g_object_bind_property (
+		folder_ext, "allow-partial",
+		widget, "active",
+		G_BINDING_BIDIRECTIONAL |
+		G_BINDING_SYNC_CREATE);
+}
+
+static void
+e_book_config_mapigal_class_init (EBookConfigMapigalClass *class)
+{
+	EExtensionClass *extension_class;
+	ESourceConfigBackendClass *backend_class;
+
+	extension_class = E_EXTENSION_CLASS (class);
+	extension_class->extensible_type = E_TYPE_BOOK_SOURCE_CONFIG;
+
+	backend_class = E_SOURCE_CONFIG_BACKEND_CLASS (class);
+	backend_class->backend_name = "mapigal";
+	backend_class->allow_creation = book_config_mapigal_allow_creation;
+	backend_class->insert_widgets = book_config_mapigal_insert_widgets;
+}
+
+static void
+e_book_config_mapigal_class_finalize (EBookConfigMapigalClass *class)
+{
+}
+
+static void
+e_book_config_mapigal_init (EBookConfigMapigal *backend)
+{
+}
+
+void
+e_book_config_mapigal_type_register (GTypeModule *type_module)
+{
+	/* XXX G_DEFINE_DYNAMIC_TYPE declares a static type registration
+	 *     function, so we have to wrap it with a public function in
+	 *     order to register types from a separate compilation unit. */
+	e_book_config_mapigal_register_type (type_module);
+}
diff --git a/src/configuration/e-book-config-mapigal.h b/src/configuration/e-book-config-mapigal.h
new file mode 100644
index 0000000..d1bad9c
--- /dev/null
+++ b/src/configuration/e-book-config-mapigal.h
@@ -0,0 +1,63 @@
+/*
+ * e-book-config-mapigal.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 E_BOOK_CONFIG_MAPIGAL_H
+#define E_BOOK_CONFIG_MAPIGAL_H
+
+#include <misc/e-source-config-backend.h>
+
+/* Standard GObject macros */
+#define E_TYPE_BOOK_CONFIG_MAPIGAL \
+	(e_book_config_mapigal_get_type ())
+#define E_BOOK_CONFIG_MAPIGAL(obj) \
+	(G_TYPE_CHECK_INSTANCE_CAST \
+	((obj), E_TYPE_BOOK_CONFIG_MAPIGAL, EBookConfigMapigal))
+#define E_BOOK_CONFIG_MAPIGAL_CLASS(cls) \
+	(G_TYPE_CHECK_CLASS_CAST \
+	((cls), E_TYPE_BOOK_CONFIG_MAPIGAL, EBookConfigMapigalClass))
+#define E_IS_BOOK_CONFIG_MAPIGAL(obj) \
+	(G_TYPE_CHECK_INSTANCE_TYPE \
+	((obj), E_TYPE_BOOK_CONFIG_MAPIGAL))
+#define E_IS_BOOK_CONFIG_MAPIGAL_CLASS(cls) \
+	(G_TYPE_CHECK_CLASS_TYPE \
+	((cls), E_TYPE_BOOK_CONFIG_MAPIGAL))
+#define E_BOOK_CONFIG_MAPIGAL_GET_CLASS(obj) \
+	(G_TYPE_INSTANCE_GET_CLASS \
+	((obj), E_TYPE_BOOK_CONFIG_MAPIGAL, EBookConfigMapigalClass))
+
+G_BEGIN_DECLS
+
+typedef struct _EBookConfigMapigal EBookConfigMapigal;
+typedef struct _EBookConfigMapigalClass EBookConfigMapigalClass;
+typedef struct _EBookConfigMapigalPrivate EBookConfigMapigalPrivate;
+
+struct _EBookConfigMapigal {
+	ESourceConfigBackend parent;
+	EBookConfigMapigalPrivate *priv;
+};
+
+struct _EBookConfigMapigalClass {
+	ESourceConfigBackendClass parent_class;
+};
+
+GType	e_book_config_mapigal_get_type		(void) G_GNUC_CONST;
+void	e_book_config_mapigal_type_register	(GTypeModule *type_module);
+
+G_END_DECLS
+
+#endif /* E_BOOK_CONFIG_MAPIGAL_H */
diff --git a/src/configuration/e-cal-config-mapi.c b/src/configuration/e-cal-config-mapi.c
new file mode 100644
index 0000000..b724c1f
--- /dev/null
+++ b/src/configuration/e-cal-config-mapi.c
@@ -0,0 +1,75 @@
+/*
+ * e-cal-config-mapi.c
+ *
+ * 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/>
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <misc/e-cal-source-config.h>
+
+#include "e-cal-config-mapi.h"
+#include "e-mapi-config-utils.h"
+
+G_DEFINE_DYNAMIC_TYPE (ECalConfigMapi, e_cal_config_mapi, E_TYPE_SOURCE_CONFIG_BACKEND)
+
+static gboolean
+cal_config_mapi_allow_creation (ESourceConfigBackend *backend)
+{
+	return TRUE;
+}
+
+static void
+cal_config_mapi_insert_widgets (ESourceConfigBackend *backend,
+				ESource *scratch_source)
+{
+	e_mapi_config_utils_insert_widgets (backend, scratch_source);
+}
+
+static void
+e_cal_config_mapi_class_init (ECalConfigMapiClass *class)
+{
+	EExtensionClass *extension_class;
+	ESourceConfigBackendClass *backend_class;
+
+	extension_class = E_EXTENSION_CLASS (class);
+	extension_class->extensible_type = E_TYPE_CAL_SOURCE_CONFIG;
+
+	backend_class = E_SOURCE_CONFIG_BACKEND_CLASS (class);
+	backend_class->backend_name = "mapi";
+	backend_class->allow_creation = cal_config_mapi_allow_creation;
+	backend_class->insert_widgets = cal_config_mapi_insert_widgets;
+}
+
+static void
+e_cal_config_mapi_class_finalize (ECalConfigMapiClass *class)
+{
+}
+
+static void
+e_cal_config_mapi_init (ECalConfigMapi *backend)
+{
+}
+
+void
+e_cal_config_mapi_type_register (GTypeModule *type_module)
+{
+	/* XXX G_DEFINE_DYNAMIC_TYPE declares a static type registration
+	 *     function, so we have to wrap it with a public function in
+	 *     order to register types from a separate compilation unit. */
+	e_cal_config_mapi_register_type (type_module);
+}
diff --git a/src/configuration/e-cal-config-mapi.h b/src/configuration/e-cal-config-mapi.h
new file mode 100644
index 0000000..af0ee5b
--- /dev/null
+++ b/src/configuration/e-cal-config-mapi.h
@@ -0,0 +1,63 @@
+/*
+ * e-cal-config-mapi.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 E_CAL_CONFIG_MAPI_H
+#define E_CAL_CONFIG_MAPI_H
+
+#include <misc/e-source-config-backend.h>
+
+/* Standard GObject macros */
+#define E_TYPE_CAL_CONFIG_MAPI \
+	(e_cal_config_mapi_get_type ())
+#define E_CAL_CONFIG_MAPI(obj) \
+	(G_TYPE_CHECK_INSTANCE_CAST \
+	((obj), E_TYPE_CAL_CONFIG_MAPI, ECalConfigMapi))
+#define E_CAL_CONFIG_MAPI_CLASS(cls) \
+	(G_TYPE_CHECK_CLASS_CAST \
+	((cls), E_TYPE_CAL_CONFIG_MAPI, ECalConfigMapiClass))
+#define E_IS_CAL_CONFIG_MAPI(obj) \
+	(G_TYPE_CHECK_INSTANCE_TYPE \
+	((obj), E_TYPE_CAL_CONFIG_MAPI))
+#define E_IS_CAL_CONFIG_MAPI_CLASS(cls) \
+	(G_TYPE_CHECK_CLASS_TYPE \
+	((cls), E_TYPE_CAL_CONFIG_MAPI))
+#define E_CAL_CONFIG_MAPI_GET_CLASS(obj) \
+	(G_TYPE_INSTANCE_GET_CLASS \
+	((obj), E_TYPE_CAL_CONFIG_MAPI, ECalConfigMapiClass))
+
+G_BEGIN_DECLS
+
+typedef struct _ECalConfigMapi ECalConfigMapi;
+typedef struct _ECalConfigMapiClass ECalConfigMapiClass;
+typedef struct _ECalConfigMapiPrivate ECalConfigMapiPrivate;
+
+struct _ECalConfigMapi {
+	ESourceConfigBackend parent;
+	ECalConfigMapiPrivate *priv;
+};
+
+struct _ECalConfigMapiClass {
+	ESourceConfigBackendClass parent_class;
+};
+
+GType	e_cal_config_mapi_get_type	(void) G_GNUC_CONST;
+void	e_cal_config_mapi_type_register	(GTypeModule *type_module);
+
+G_END_DECLS
+
+#endif /* E_CAL_CONFIG_MAPI_H */
diff --git a/src/configuration/e-mail-config-mapi-backend.c b/src/configuration/e-mail-config-mapi-backend.c
new file mode 100644
index 0000000..4f40e8e
--- /dev/null
+++ b/src/configuration/e-mail-config-mapi-backend.c
@@ -0,0 +1,841 @@
+/*
+ * e-mail-config-mapi-backend.c
+ *
+ * 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/>
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <glib/gi18n-lib.h>
+
+#include <camel/camel.h>
+#include <libebackend/libebackend.h>
+#include <libedataserver/libedataserver.h>
+
+#include <e-util/e-dialog-utils.h>
+#include <mail/e-mail-config-auth-check.h>
+#include <mail/e-mail-config-receiving-page.h>
+#include <shell/e-shell.h>
+
+#include "camel-mapi-settings.h"
+#include "e-mapi-folder.h"
+#include "e-mapi-connection.h"
+#include "e-mapi-utils.h"
+#include "e-mapi-config-utils.h"
+
+#include "e-mail-config-mapi-backend.h"
+
+#define E_MAIL_CONFIG_MAPI_BACKEND_GET_PRIVATE(obj) \
+	(G_TYPE_INSTANCE_GET_PRIVATE \
+	((obj), E_TYPE_MAIL_CONFIG_MAPI_BACKEND, EMailConfigMapiBackendPrivate))
+
+struct _EMailConfigMapiBackendPrivate {
+	gint unused;
+};
+
+G_DEFINE_DYNAMIC_TYPE (
+	EMailConfigMapiBackend,
+	e_mail_config_mapi_backend,
+	E_TYPE_MAIL_CONFIG_SERVICE_BACKEND)
+
+enum {
+	COL_MAPI_FULL_NAME = 0,
+	COL_MAPI_ACCOUNT,
+	COL_MAPI_INDEX,
+	COLS_MAX
+};
+
+static void
+tree_selection_changed (GtkTreeSelection *selection, GtkDialog *dialog)
+{
+	gtk_dialog_set_response_sensitive (dialog, GTK_RESPONSE_ACCEPT, gtk_tree_selection_get_selected (selection, NULL, NULL));
+}
+
+static gboolean
+transform_security_method_to_boolean (GBinding *binding,
+                                      const GValue *source_value,
+                                      GValue *target_value,
+                                      gpointer not_used)
+{
+	CamelNetworkSecurityMethod security_method;
+	gboolean use_ssl;
+
+	security_method = g_value_get_enum (source_value);
+	use_ssl = (security_method != CAMEL_NETWORK_SECURITY_METHOD_NONE);
+	g_value_set_boolean (target_value, use_ssl);
+
+	return TRUE;
+}
+
+static gboolean
+transform_boolean_to_security_method (GBinding *binding,
+                                      const GValue *source_value,
+                                      GValue *target_value,
+                                      gpointer not_used)
+{
+	CamelNetworkSecurityMethod security_method;
+	gboolean use_ssl;
+
+	use_ssl = g_value_get_boolean (source_value);
+	if (use_ssl)
+		security_method = CAMEL_NETWORK_SECURITY_METHOD_SSL_ON_ALTERNATE_PORT;
+	else
+		security_method = CAMEL_NETWORK_SECURITY_METHOD_NONE;
+	g_value_set_enum (target_value, security_method);
+
+	return TRUE;
+}
+
+struct ECreateProfileData
+{
+	const gchar *username;
+	struct SRowSet *rowset;
+	gint index;
+	EFlag *flag;
+};
+
+static gboolean
+create_profile_callback_in_main (gpointer user_data)
+{
+	struct ECreateProfileData *cpd = user_data;
+	gint response;
+	gint i, index = 0;
+	GtkTreeIter iter;
+	GtkListStore *store;
+	GtkCellRenderer *renderer;
+	GtkTreeSelection *selection;
+	GtkWidget *dialog, *view;
+	GtkBox *content_area;
+
+	g_return_val_if_fail (cpd != NULL, FALSE);
+
+	dialog = gtk_dialog_new_with_buttons (_("Select username"),
+					      NULL, GTK_DIALOG_MODAL,
+					      GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT,
+					      GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
+					      NULL);
+
+	/*Tree View */
+	view = gtk_tree_view_new ();
+	renderer = gtk_cell_renderer_text_new ();
+	gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (view),
+						     -1, _("Full name"), renderer,
+						     "text", COL_MAPI_FULL_NAME, NULL);
+
+	renderer = gtk_cell_renderer_text_new ();
+	gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (view),
+						     -1, _("Username"), renderer,
+						     "text", COL_MAPI_ACCOUNT, NULL);
+
+	gtk_tree_view_column_set_resizable (gtk_tree_view_get_column (GTK_TREE_VIEW (view), 0), TRUE);
+	gtk_tree_view_column_set_resizable (gtk_tree_view_get_column (GTK_TREE_VIEW (view), 1), TRUE);
+
+	/* Model for TreeView */
+	store = gtk_list_store_new (3, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INT);
+	gtk_tree_view_set_model (GTK_TREE_VIEW (view), GTK_TREE_MODEL (store));
+
+	for (i = 0; i < cpd->rowset->cRows; i++) {
+		const gchar *fullname = e_mapi_util_find_row_propval (&(cpd->rowset->aRow[i]), PidTagDisplayName);
+		const gchar *account = e_mapi_util_find_row_propval (&(cpd->rowset->aRow[i]), PidTagAccount);
+
+		if (fullname && account) {
+			gtk_list_store_append (store, &iter);
+			/* Preserve the index inside the store*/
+			gtk_list_store_set (store, &iter,
+					    COL_MAPI_FULL_NAME, fullname,
+					    COL_MAPI_ACCOUNT, account,
+					    COL_MAPI_INDEX, i, -1);
+		}
+	}
+
+	/* Pack the TreeView into dialog's content area */
+	content_area = GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog)));
+
+	gtk_box_pack_start (content_area, gtk_label_new (_("There are more users with similar user name on a server.\nPlease select that you would like to use from the below list.")), TRUE, TRUE, 6);
+	gtk_box_pack_start (content_area, view, TRUE, TRUE, 6);
+
+	gtk_widget_show_all (GTK_WIDGET (content_area));
+
+	selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (view));
+	g_signal_connect (selection, "changed", G_CALLBACK (tree_selection_changed), dialog);
+	tree_selection_changed (selection, GTK_DIALOG (dialog));
+
+	response = gtk_dialog_run (GTK_DIALOG (dialog));
+	if (response == GTK_RESPONSE_ACCEPT) {
+	       /* Get the index from the selected value */
+		if (gtk_tree_selection_get_selected (selection, NULL, &iter))
+			gtk_tree_model_get (GTK_TREE_MODEL (store), &iter, COL_MAPI_INDEX, &index, -1);
+		else
+			index = cpd->rowset->cRows + 1;
+	} else /* If we return a value > available, we are canceling the login.*/
+	       index = cpd->rowset->cRows + 1;
+
+	gtk_widget_destroy (dialog);
+
+	cpd->index = index;
+	e_flag_set (cpd->flag);
+
+	return FALSE;
+}
+
+/* Callback for ProcessNetworkProfile. If we have more than one username,
+ we need to let the user select. */
+static gint
+create_profile_callback_in_thread (struct SRowSet *rowset,
+				   gconstpointer data)
+{
+	struct ECreateProfileData cpd;
+	const gchar *username = (const gchar *) data;
+	gint i;
+
+	/* If we can find the exact username, then find & return its index. */
+	for (i = 0; i < rowset->cRows; i++) {
+		const gchar *account = e_mapi_util_find_row_propval (&(rowset->aRow[i]), PidTagAccount);
+
+		if (account && g_strcmp0 (username, account) == 0)
+			return i;
+	}
+
+	cpd.username = username;
+	cpd.rowset = rowset;
+	cpd.index = -1;
+	cpd.flag = e_flag_new ();
+
+	g_timeout_add (100, create_profile_callback_in_main, &cpd);
+
+	e_flag_wait (cpd.flag);
+	e_flag_free (cpd.flag);
+
+	return cpd.index;
+}
+
+static gboolean
+validate_credentials_test (ESourceRegistry *registry,
+			   EMapiProfileData *empd,
+			   CamelMapiSettings *mapi_settings,
+			   GCancellable *cancellable,
+			   GError **perror)
+{
+	gboolean status, success = FALSE;
+	struct mapi_context *mapi_ctx = NULL;
+
+	status = e_mapi_utils_create_mapi_context (&mapi_ctx, perror);
+	status = status && e_mapi_create_profile (mapi_ctx, empd, create_profile_callback_in_thread, empd->username, NULL, perror);
+	if (status && !g_cancellable_is_cancelled (cancellable)) {
+		/* profile was created, try to connect to the server */
+		EMapiConnection *conn;
+		gchar *profname;
+
+		status = FALSE;
+		profname = e_mapi_util_profile_name (mapi_ctx, empd, FALSE);
+
+		conn = e_mapi_connection_new (registry, profname, empd->password, cancellable, perror);
+		if (conn) {
+			status = e_mapi_connection_connected (conn);
+			g_object_unref (conn);
+		}
+
+		g_free (profname);
+	}
+
+	if (status) {
+		/* Things are successful */
+		gchar *profname = NULL;
+
+		profname = e_mapi_util_profile_name (mapi_ctx, empd, FALSE);
+		camel_mapi_settings_set_profile (mapi_settings, profname);
+		g_free (profname);
+
+		success = TRUE;
+	}
+
+	e_mapi_utils_destroy_mapi_context (mapi_ctx);
+
+	return success;
+}
+
+typedef struct _EMailConfigMapiAuthenticator EMailConfigMapiAuthenticator;
+typedef struct _EMailConfigMapiAuthenticatorClass EMailConfigMapiAuthenticatorClass;
+
+struct _EMailConfigMapiAuthenticator {
+	GObject parent;
+
+	gchar *username;
+	gchar *domain;
+	gchar *server;
+	gboolean use_ssl;
+	gboolean krb_sso;
+	gchar *krb_realm;
+	CamelMapiSettings *mapi_settings;
+	EMailConfigServiceBackend *backend;
+	gboolean success;
+};
+
+struct _EMailConfigMapiAuthenticatorClass {
+	GObjectClass parent_class;
+};
+
+static ESourceAuthenticationResult
+mail_config_mapi_authenticator_try_password_sync (ESourceAuthenticator *auth,
+						  const GString *password,
+						  GCancellable *cancellable,
+						  GError **error)
+{
+	EMailConfigMapiAuthenticator *mapi_authenticator = (EMailConfigMapiAuthenticator *) auth;
+	EMailConfigServicePage *page;
+	ESourceRegistry *registry;
+	EMapiProfileData empd;
+	GError *mapi_error = NULL;
+
+	empd.username = mapi_authenticator->username;
+	empd.domain = mapi_authenticator->domain;
+	empd.server = mapi_authenticator->server;
+	empd.password = (GString *) password;
+	empd.use_ssl = mapi_authenticator->use_ssl;
+	empd.krb_sso = mapi_authenticator->krb_sso;
+	empd.krb_realm = mapi_authenticator->krb_realm;
+
+	page = e_mail_config_service_backend_get_page (mapi_authenticator->backend);
+	registry = e_mail_config_service_page_get_registry (page);
+
+	mapi_authenticator->success = validate_credentials_test (
+		registry,
+		&empd, 
+		mapi_authenticator->mapi_settings,
+		cancellable,
+		&mapi_error);
+
+	if (mapi_error) {
+		gboolean is_network_error = g_error_matches (mapi_error, E_MAPI_ERROR, MAPI_E_NETWORK_ERROR);
+
+		g_warn_if_fail (!mapi_authenticator->success);
+		mapi_authenticator->success = FALSE;
+
+		g_propagate_error (error, mapi_error);
+
+		return is_network_error ? E_SOURCE_AUTHENTICATION_ERROR : E_SOURCE_AUTHENTICATION_REJECTED;
+	}
+
+	g_warn_if_fail (mapi_authenticator->success);
+
+	return E_SOURCE_AUTHENTICATION_ACCEPTED;
+}
+
+#define E_TYPE_MAIL_CONFIG_MAPI_AUTHENTICATOR (e_mail_config_mapi_authenticator_get_type ())
+
+GType e_mail_config_mapi_authenticator_get_type (void) G_GNUC_CONST;
+
+static void e_mail_config_mapi_authenticator_authenticator_init (ESourceAuthenticatorInterface *interface);
+
+G_DEFINE_TYPE_EXTENDED (EMailConfigMapiAuthenticator, e_mail_config_mapi_authenticator, G_TYPE_OBJECT, 0,
+	G_IMPLEMENT_INTERFACE (E_TYPE_SOURCE_AUTHENTICATOR, e_mail_config_mapi_authenticator_authenticator_init))
+
+static void
+mail_config_mapi_authenticator_finalize (GObject *object)
+{
+	EMailConfigMapiAuthenticator *mapi_authenticator = (EMailConfigMapiAuthenticator *) object;
+
+	g_free (mapi_authenticator->username);
+	g_free (mapi_authenticator->domain);
+	g_free (mapi_authenticator->server);
+	g_free (mapi_authenticator->krb_realm);
+	g_object_unref (mapi_authenticator->mapi_settings);
+	g_object_unref (mapi_authenticator->backend);
+
+	G_OBJECT_CLASS (e_mail_config_mapi_authenticator_parent_class)->finalize (object);
+}
+
+static void
+e_mail_config_mapi_authenticator_class_init (EMailConfigMapiAuthenticatorClass *class)
+{
+	GObjectClass *object_class;
+
+	object_class = G_OBJECT_CLASS (class);
+	object_class->finalize = mail_config_mapi_authenticator_finalize;
+}
+
+static void
+e_mail_config_mapi_authenticator_authenticator_init (ESourceAuthenticatorInterface *interface)
+{
+	interface->try_password_sync = mail_config_mapi_authenticator_try_password_sync;
+}
+
+static void
+e_mail_config_mapi_authenticator_init (EMailConfigMapiAuthenticator *mapi_authenticator)
+{
+}
+
+static void
+validate_credentials_idle (GObject *button,
+			   gpointer user_data,
+			   GCancellable *cancellable,
+			   GError **perror)
+{
+	EMailConfigMapiAuthenticator *mapi_authenticator = user_data;
+
+	g_return_if_fail (mapi_authenticator != NULL);
+
+	if (mapi_authenticator->success)
+		e_notice (NULL, GTK_MESSAGE_INFO, "%s", _("Authentication finished successfully."));
+	else
+		e_notice (NULL, GTK_MESSAGE_ERROR, "%s", _("Authentication failed."));
+}
+
+static void
+validate_credentials_thread (GObject *button,
+			     gpointer user_data,
+			     GCancellable *cancellable,
+			     GError **perror)
+{
+	EMailConfigMapiAuthenticator *mapi_authenticator = user_data;
+	EMailConfigServicePage *page;
+	ESourceRegistry *registry;
+
+	g_return_if_fail (mapi_authenticator != NULL);
+
+	page = e_mail_config_service_backend_get_page (mapi_authenticator->backend);
+	registry = e_mail_config_service_page_get_registry (page);
+
+	if (mapi_authenticator->krb_sso) {
+		GError *error = NULL;
+		EMapiProfileData empd;
+
+		empd.username = mapi_authenticator->username;
+		empd.domain = mapi_authenticator->domain;
+		empd.server = mapi_authenticator->server;
+		empd.use_ssl = mapi_authenticator->use_ssl;
+		empd.krb_sso = mapi_authenticator->krb_sso;
+		empd.krb_realm = mapi_authenticator->krb_realm;
+
+		e_mapi_util_trigger_krb_auth (&empd, &error);
+		g_clear_error (&error);
+
+		mapi_authenticator->success = validate_credentials_test (
+			registry,
+			&empd, 
+			mapi_authenticator->mapi_settings,
+			cancellable,
+			perror);
+	} else {
+		ESource *source;
+
+		source = e_mail_config_service_backend_get_source (mapi_authenticator->backend);
+
+		e_source_registry_authenticate_sync (
+			registry, source, E_SOURCE_AUTHENTICATOR (mapi_authenticator),
+			cancellable, perror);
+	}
+}
+
+static void
+validate_credentials_cb (GtkWidget *widget,
+			 EMailConfigServiceBackend *backend)
+{
+	EMapiProfileData empd = { 0 };
+	CamelSettings *settings;
+	CamelMapiSettings *mapi_settings;
+	CamelNetworkSettings *network_settings;
+	const gchar *host;
+	const gchar *user;
+	GError *error = NULL;
+
+	if (!e_mapi_config_utils_is_online ()) {
+		e_notice (NULL, GTK_MESSAGE_ERROR, "%s", _("Cannot authenticate MAPI accounts in offline mode"));
+		return;
+	}
+
+	settings = e_mail_config_service_backend_get_settings (backend);
+	mapi_settings = CAMEL_MAPI_SETTINGS (settings);
+	network_settings = CAMEL_NETWORK_SETTINGS (settings);
+
+	host = camel_network_settings_get_host (network_settings);
+	user = camel_network_settings_get_user (network_settings);
+
+	/* Silently remove domain part from a username when user enters it as such.
+	   This change will be visible in the UI on new edit open. */
+	if (user != NULL && strchr (user, '\\') != NULL) {
+		gchar *at;
+
+		at = strrchr (user, '\\') + 1;
+		camel_network_settings_set_user (network_settings, at);
+		user = camel_network_settings_get_user (network_settings);
+	}
+
+	empd.server = host;
+	empd.username = user;
+	e_mapi_util_profiledata_from_settings (&empd, mapi_settings);
+
+	if (!empd.username || !*(empd.username)
+	    || !empd.server || !*(empd.server)
+	    || ((!empd.domain || !*(empd.domain))
+		&& !empd.krb_sso)) {
+		e_notice (NULL, GTK_MESSAGE_ERROR, "%s", _("Server, username and domain name cannot be empty. Please fill them with correct values."));
+		return;
+	} else if (empd.krb_sso && (!empd.krb_realm || !*(empd.krb_realm))) {
+		e_notice (NULL, GTK_MESSAGE_ERROR, "%s", _("Realm name cannot be empty when kerberos is selected. Please fill them with correct values."));
+		return;
+	}
+
+	if (COMPLETE_PROFILEDATA (&empd)) {
+		EMailConfigMapiAuthenticator *mapi_authenticator;
+
+		mapi_authenticator = g_object_new (E_TYPE_MAIL_CONFIG_MAPI_AUTHENTICATOR, NULL);
+
+		mapi_authenticator->username = g_strdup (empd.username);
+		mapi_authenticator->domain = g_strdup (empd.domain);
+		mapi_authenticator->server = g_strdup (empd.server);
+		mapi_authenticator->use_ssl = empd.use_ssl;
+		mapi_authenticator->krb_sso = empd.krb_sso;
+		mapi_authenticator->krb_realm = g_strdup (empd.krb_realm);
+		mapi_authenticator->mapi_settings = g_object_ref (mapi_settings);
+		mapi_authenticator->backend = g_object_ref (backend);
+		mapi_authenticator->success = FALSE;
+
+		e_mapi_config_utils_run_in_thread_with_feedback_modal (e_mapi_config_utils_get_widget_toplevel_window (widget),
+			G_OBJECT (widget),
+			_("Connecting to the server, please wait..."),
+			validate_credentials_thread,
+			validate_credentials_idle,
+			mapi_authenticator,
+			g_object_unref);
+	} else {
+		e_notice (NULL, GTK_MESSAGE_ERROR, "%s", _("Authentication failed."));
+	}
+
+	if (error)
+		g_error_free (error);
+
+	if (empd.password) {
+		memset (empd.password->str, 0, empd.password->len);
+		g_string_free (empd.password, TRUE);
+	}
+}
+
+static ESource *
+mail_config_mapi_backend_new_collection (EMailConfigServiceBackend *backend)
+{
+	EMailConfigServiceBackendClass *class;
+	ESourceBackend *extension;
+	ESource *source;
+	const gchar *extension_name;
+
+	/* This backend serves double duty.  One instance holds the
+	 * mail account source, another holds the mail transport source.
+	 * We can differentiate by examining the EMailConfigServicePage
+	 * the backend is associated with.  We return a new collection
+	 * for both the Receiving Page and Sending Page.  Although the
+	 * Sending Page instance ultimately gets discarded, it's still
+	 * needed to avoid creating a [Mapi Backend] extension in the
+	 * mail transport source. */
+
+	class = E_MAIL_CONFIG_SERVICE_BACKEND_GET_CLASS (backend);
+
+	source = e_source_new (NULL, NULL, NULL);
+	extension_name = E_SOURCE_EXTENSION_COLLECTION;
+	extension = e_source_get_extension (source, extension_name);
+	e_source_backend_set_backend_name (extension, class->backend_name);
+
+	return source;
+}
+
+static void
+mail_config_mapi_backend_insert_widgets (EMailConfigServiceBackend *backend,
+					 GtkBox *parent)
+{
+	EMailConfigServicePage *page;
+	ESource *source;
+	ESourceExtension *extension;
+	CamelSettings *settings;
+	GtkWidget *hgrid = NULL;
+	GtkWidget *label, *entry;
+	GtkWidget *auth_button;
+	GtkWidget *secure_conn;
+	GtkWidget *krb_sso;
+	GtkGrid *content_grid;
+	gchar *markup;
+	gint irow;
+
+	page = e_mail_config_service_backend_get_page (backend);
+
+	/* This backend serves double duty.  One instance holds the
+	 * mail account source, another holds the mail transport source.
+	 * We can differentiate by examining the EMailConfigServicePage
+	 * the backend is associated with.  This method only applies to
+	 * the Receiving Page. */
+	if (!E_IS_MAIL_CONFIG_RECEIVING_PAGE (page))
+		return;
+
+	/* This needs to come _after_ the page type check so we don't
+	 * introduce a backend extension in the mail transport source. */
+	settings = e_mail_config_service_backend_get_settings (backend);
+
+	content_grid = GTK_GRID (gtk_grid_new ());
+	gtk_widget_set_margin_left (GTK_WIDGET (content_grid), 12);
+	gtk_grid_set_row_spacing (content_grid, 6);
+	gtk_grid_set_column_spacing (content_grid, 6);
+	gtk_box_pack_start (GTK_BOX (parent), GTK_WIDGET (content_grid), FALSE, FALSE, 0);
+
+	irow = 0;
+
+	markup = g_markup_printf_escaped ("<b>%s</b>", _("Configuration"));
+	label = gtk_label_new (markup);
+	gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
+	gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
+	g_free (markup);
+
+	gtk_grid_attach (content_grid, label, 0, irow, 2, 1);
+	irow++;
+
+	label = gtk_label_new_with_mnemonic (_("_Server:"));
+	gtk_misc_set_alignment (GTK_MISC (label), 1.0, 0.5);
+
+	entry = gtk_entry_new ();
+	gtk_widget_set_hexpand (entry, TRUE);
+	gtk_label_set_mnemonic_widget (GTK_LABEL (label), entry);
+
+	g_object_bind_property (
+		settings, "host",
+		entry, "text",
+		G_BINDING_BIDIRECTIONAL |
+		G_BINDING_SYNC_CREATE);
+
+	gtk_grid_attach (content_grid, label, 0, irow, 1, 1);
+	gtk_grid_attach (content_grid, entry, 1, irow, 1, 1);
+	irow++;
+
+	label = gtk_label_new_with_mnemonic (_("User_name:"));
+	gtk_misc_set_alignment (GTK_MISC (label), 1.0, 0.5);
+
+	entry = gtk_entry_new ();
+	gtk_widget_set_hexpand (entry, TRUE);
+	gtk_label_set_mnemonic_widget (GTK_LABEL (label), entry);
+
+	g_object_bind_property (
+		settings, "user",
+		entry, "text",
+		G_BINDING_BIDIRECTIONAL |
+		G_BINDING_SYNC_CREATE);
+
+	gtk_grid_attach (content_grid, label, 0, irow, 1, 1);
+	gtk_grid_attach (content_grid, entry, 1, irow, 1, 1);
+	irow++;
+
+	/* Domain name & Authenticate Button */
+	hgrid = g_object_new (GTK_TYPE_GRID,
+		"column-homogeneous", FALSE,
+		"column-spacing", 6,
+		"orientation", GTK_ORIENTATION_HORIZONTAL,
+		NULL);
+	gtk_widget_set_hexpand (hgrid, TRUE);
+
+	label = gtk_label_new_with_mnemonic (_("_Domain name:"));
+	gtk_misc_set_alignment (GTK_MISC (label), 1.0, 0.5);
+
+	entry = gtk_entry_new ();
+	gtk_label_set_mnemonic_widget (GTK_LABEL (label), entry);
+	gtk_widget_set_hexpand (entry, TRUE);
+	gtk_container_add (GTK_CONTAINER (hgrid), entry);
+	g_object_bind_property (
+		settings, "domain",
+		entry, "text",
+		G_BINDING_BIDIRECTIONAL |
+		G_BINDING_SYNC_CREATE);
+
+	auth_button = gtk_button_new_with_mnemonic (_("_Authenticate"));
+	gtk_container_add (GTK_CONTAINER (hgrid), auth_button);
+	g_signal_connect (auth_button, "clicked",  G_CALLBACK (validate_credentials_cb), backend);
+
+	gtk_grid_attach (content_grid, label, 0, irow, 1, 1);
+	gtk_grid_attach (content_grid, hgrid, 1, irow, 1, 1);
+	irow++;
+
+	secure_conn = gtk_check_button_new_with_mnemonic (_("_Use secure connection"));
+	gtk_widget_set_hexpand (secure_conn, TRUE);
+	
+	gtk_grid_attach (content_grid, secure_conn, 1, irow, 1, 1);
+	irow++;
+
+	g_object_bind_property_full (
+		settings, "security-method",
+		secure_conn, "active",
+		G_BINDING_BIDIRECTIONAL |
+		G_BINDING_SYNC_CREATE,
+		transform_security_method_to_boolean,
+		transform_boolean_to_security_method,
+		NULL, (GDestroyNotify) NULL);
+
+	krb_sso = gtk_check_button_new_with_mnemonic (_("_Kerberos authentication"));
+	gtk_widget_set_hexpand (secure_conn, TRUE);
+
+	g_object_bind_property (
+		settings, "kerberos",
+		krb_sso, "active",
+		G_BINDING_BIDIRECTIONAL |
+		G_BINDING_SYNC_CREATE);
+
+	gtk_grid_attach (content_grid, krb_sso, 1, irow, 1, 1);
+	irow++;
+
+	label = gtk_label_new_with_mnemonic (_("_Realm name:"));
+	gtk_misc_set_alignment (GTK_MISC (label), 1.0, 0.5);
+
+	g_object_bind_property (
+		settings, "kerberos",
+		label, "sensitive",
+		G_BINDING_SYNC_CREATE);
+
+	entry = gtk_entry_new ();
+	gtk_widget_set_hexpand (entry, TRUE);
+	gtk_label_set_mnemonic_widget (GTK_LABEL (label), entry);
+
+	g_object_bind_property (
+		settings, "realm",
+		entry, "text",
+		G_BINDING_BIDIRECTIONAL |
+		G_BINDING_SYNC_CREATE);
+
+	g_object_bind_property (
+		settings, "kerberos",
+		entry, "sensitive",
+		G_BINDING_SYNC_CREATE);
+
+	gtk_grid_attach (content_grid, label, 0, irow, 1, 1);
+	gtk_grid_attach (content_grid, entry, 1, irow, 1, 1);
+
+	source = e_mail_config_service_backend_get_collection (backend);
+	extension = e_source_get_extension (source, E_SOURCE_EXTENSION_COLLECTION);
+
+	/* The collection identity is the user name. */
+	g_object_bind_property (
+		settings, "user",
+		extension, "identity",
+		G_BINDING_BIDIRECTIONAL |
+		G_BINDING_SYNC_CREATE);
+
+	gtk_widget_show_all (GTK_WIDGET (content_grid));
+}
+
+static void
+mail_config_mapi_backend_setup_defaults (EMailConfigServiceBackend *backend)
+{
+	CamelSettings *settings;
+	EMailConfigServicePage *page;
+	const gchar *email_address;
+	gchar **parts = NULL;
+
+	page = e_mail_config_service_backend_get_page (backend);
+
+	/* This backend serves double duty.  One instance holds the
+	 * mail account source, another holds the mail transport source.
+	 * We can differentiate by examining the EMailConfigServicePage
+	 * the backend is associated with.  This method only applies to
+	 * the Receiving Page. */
+	if (!E_IS_MAIL_CONFIG_RECEIVING_PAGE (page))
+		return;
+
+	/* This needs to come _after_ the page type check so we don't
+	 * introduce a backend extension in the mail transport source. */
+	settings = e_mail_config_service_backend_get_settings (backend);
+
+	email_address = e_mail_config_service_page_get_email_address (page);
+	if (email_address != NULL)
+		parts = g_strsplit (email_address, "@", 2);
+
+	if (parts != NULL && g_strv_length (parts) >= 2) {
+		CamelNetworkSettings *network_settings;
+		gchar *host;
+
+		g_strstrip (parts[0]);  /* user name */
+		g_strstrip (parts[1]);  /* domain name */
+
+		host = g_strdup_printf ("exchange.%s", parts[1]);
+
+		network_settings = CAMEL_NETWORK_SETTINGS (settings);
+		camel_network_settings_set_host (network_settings, host);
+		camel_network_settings_set_user (network_settings, parts[0]);
+
+		g_free (host);
+	}
+
+	g_strfreev (parts);
+}
+
+static gboolean
+mail_config_mapi_backend_check_complete (EMailConfigServiceBackend *backend)
+{
+	EMailConfigServicePage *page;
+	CamelSettings *settings;
+	CamelMapiSettings *mapi_settings;
+	const gchar *profile;
+
+	page = e_mail_config_service_backend_get_page (backend);
+
+	/* This backend serves double duty.  One instance holds the
+	 * mail account source, another holds the mail transport source.
+	 * We can differentiate by examining the EMailConfigServicePage
+	 * the backend is associated with.  This method only applies to
+	 * the Receiving Page. */
+	if (!E_IS_MAIL_CONFIG_RECEIVING_PAGE (page))
+		return TRUE;
+
+	/* This needs to come _after_ the page type check so we don't
+	 * introduce a backend extension in the mail transport source. */
+	settings = e_mail_config_service_backend_get_settings (backend);
+	mapi_settings = CAMEL_MAPI_SETTINGS (settings);
+
+	/* We assume that if the profile is set, then the setting is valid. */
+	profile = camel_mapi_settings_get_profile (mapi_settings);
+
+	/* Profile not set. Do not proceed with account creation.*/
+	return (profile != NULL && *profile != '\0');
+}
+
+static void
+e_mail_config_mapi_backend_class_init (EMailConfigMapiBackendClass *class)
+{
+	EMailConfigServiceBackendClass *backend_class;
+
+	g_type_class_add_private (
+		class, sizeof (EMailConfigMapiBackendPrivate));
+
+	backend_class = E_MAIL_CONFIG_SERVICE_BACKEND_CLASS (class);
+	backend_class->backend_name = "mapi";
+	backend_class->new_collection = mail_config_mapi_backend_new_collection;
+	backend_class->insert_widgets = mail_config_mapi_backend_insert_widgets;
+	backend_class->setup_defaults = mail_config_mapi_backend_setup_defaults;
+	backend_class->check_complete = mail_config_mapi_backend_check_complete;
+}
+
+static void
+e_mail_config_mapi_backend_class_finalize (EMailConfigMapiBackendClass *class)
+{
+}
+
+static void
+e_mail_config_mapi_backend_init (EMailConfigMapiBackend *backend)
+{
+	backend->priv = E_MAIL_CONFIG_MAPI_BACKEND_GET_PRIVATE (backend);
+}
+
+void
+e_mail_config_mapi_backend_type_register (GTypeModule *type_module)
+{
+	/* XXX G_DEFINE_DYNAMIC_TYPE declares a static type registration
+	 *     function, so we have to wrap it with a public function in
+	 *     order to register types from a separate compilation unit. */
+	e_mail_config_mapi_backend_register_type (type_module);
+}
diff --git a/src/configuration/e-mail-config-mapi-backend.h b/src/configuration/e-mail-config-mapi-backend.h
new file mode 100644
index 0000000..feb16a1
--- /dev/null
+++ b/src/configuration/e-mail-config-mapi-backend.h
@@ -0,0 +1,63 @@
+/*
+ * e-mail-config-mapi-backend.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 E_MAIL_CONFIG_MAPI_BACKEND_H
+#define E_MAIL_CONFIG_MAPI_BACKEND_H
+
+#include <mail/e-mail-config-service-backend.h>
+
+/* Standard GObject macros */
+#define E_TYPE_MAIL_CONFIG_MAPI_BACKEND \
+	(e_mail_config_mapi_backend_get_type ())
+#define E_MAIL_CONFIG_MAPI_BACKEND(obj) \
+	(G_TYPE_CHECK_INSTANCE_CAST \
+	((obj), E_TYPE_MAIL_CONFIG_MAPI_BACKEND, EMailConfigMapiBackend))
+#define E_MAIL_CONFIG_MAPI_BACKEND_CLASS(cls) \
+	(G_TYPE_CHECK_CLASS_CAST \
+	((cls), E_TYPE_MAIL_CONFIG_MAPI_BACKEND, EMailConfigMapiBackendClass))
+#define E_IS_MAIL_CONFIG_MAPI_BACKEND(obj) \
+	(G_TYPE_CHECK_INSTANCE_TYPE \
+	((obj), E_TYPE_MAIL_CONFIG_MAPI_BACKEND))
+#define E_IS_MAIL_CONFIG_MAPI_BACKEND_CLASS(cls) \
+	(G_TYPE_CHECK_CLASS_TYPE \
+	((cls), E_TYPE_MAIL_CONFIG_MAPI_BACKEND))
+#define E_MAIL_CONFIG_MAPI_BACKEND_GET_CLASS(obj) \
+	(G_TYPE_INSTANCE_GET_CLASS \
+	((obj), E_TYPE_MAIL_CONFIG_MAPI_BACKEND, EMailConfigMapiBackendClass))
+
+G_BEGIN_DECLS
+
+typedef struct _EMailConfigMapiBackend EMailConfigMapiBackend;
+typedef struct _EMailConfigMapiBackendClass EMailConfigMapiBackendClass;
+typedef struct _EMailConfigMapiBackendPrivate EMailConfigMapiBackendPrivate;
+
+struct _EMailConfigMapiBackend {
+	EMailConfigServiceBackend parent;
+	EMailConfigMapiBackendPrivate *priv;
+};
+
+struct _EMailConfigMapiBackendClass {
+	EMailConfigServiceBackendClass parent_class;
+};
+
+GType	e_mail_config_mapi_backend_get_type		(void) G_GNUC_CONST;
+void	e_mail_config_mapi_backend_type_register	(GTypeModule *type_module);
+
+G_END_DECLS
+
+#endif /* E_MAIL_CONFIG_MAPI_BACKEND_H */
diff --git a/src/configuration/e-mail-config-mapi-extension.c b/src/configuration/e-mail-config-mapi-extension.c
new file mode 100644
index 0000000..186d685
--- /dev/null
+++ b/src/configuration/e-mail-config-mapi-extension.c
@@ -0,0 +1,121 @@
+/*
+ * e-mail-config-mapi-extension.c
+ *
+ * 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/>
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <mail/e-mail-config-notebook.h>
+
+#include "e-mail-config-mapi-page.h"
+#include "camel-mapi-settings.h"
+
+#include "e-mail-config-mapi-extension.h"
+
+G_DEFINE_DYNAMIC_TYPE (
+	EMailConfigMapiExtension,
+	e_mail_config_mapi_extension,
+	E_TYPE_EXTENSION)
+
+static void
+e_mail_config_mapi_extension_constructed (GObject *object)
+{
+	EExtension *extension;
+	EExtensible *extensible;
+	ESource *source;
+	ESourceBackend *backend_ext;
+	EMailConfigNotebook *notebook;
+	const gchar *backend_name;
+	const gchar *extension_name;
+
+	extension = E_EXTENSION (object);
+	extensible = e_extension_get_extensible (extension);
+
+	/* Chain up to parent's constructed() method. */
+	G_OBJECT_CLASS (e_mail_config_mapi_extension_parent_class)->constructed (object);
+
+	notebook = E_MAIL_CONFIG_NOTEBOOK (extensible);
+	source = e_mail_config_notebook_get_account_source (notebook);
+
+	extension_name = E_SOURCE_EXTENSION_MAIL_ACCOUNT;
+	backend_ext = e_source_get_extension (source, extension_name);
+	backend_name = e_source_backend_get_backend_name (backend_ext);
+
+	if (g_strcmp0 (backend_name, "mapi") == 0) {
+		ESource *profile_source;
+		ESourceCamel *camel_ext;
+		ESourceRegistry *registry;
+		EMailSession *mail_session;
+		CamelSettings *settings;
+		const gchar *profile;
+
+		mail_session = e_mail_config_notebook_get_session (notebook);
+		registry = e_mail_session_get_registry (mail_session);
+
+		if (e_source_get_parent (source))
+			profile_source = e_source_registry_ref_source (registry, e_source_get_parent (source));
+		else
+			profile_source = g_object_ref (source);
+
+		camel_ext = e_source_get_extension (profile_source, e_source_camel_get_extension_name (backend_name));
+		settings = e_source_camel_get_settings (camel_ext);
+		profile = camel_mapi_settings_get_profile (CAMEL_MAPI_SETTINGS (settings));
+
+		/* add page only when editing already configured accounts */
+		if (profile && *profile) {
+			EMailConfigPage *page;
+
+			page = e_mail_config_mapi_page_new (source, registry);
+			e_mail_config_notebook_add_page (notebook, page);
+		}
+
+		g_object_unref (profile_source);
+	}
+}
+
+static void
+e_mail_config_mapi_extension_class_init (EMailConfigMapiExtensionClass *class)
+{
+	GObjectClass *object_class;
+	EExtensionClass *extension_class;
+
+	object_class = G_OBJECT_CLASS (class);
+	object_class->constructed = e_mail_config_mapi_extension_constructed;
+
+	extension_class = E_EXTENSION_CLASS (class);
+	extension_class->extensible_type = E_TYPE_MAIL_CONFIG_NOTEBOOK;
+}
+
+static void
+e_mail_config_mapi_extension_class_finalize (EMailConfigMapiExtensionClass *class)
+{
+}
+
+static void
+e_mail_config_mapi_extension_init (EMailConfigMapiExtension *extension)
+{
+}
+
+void
+e_mail_config_mapi_extension_type_register (GTypeModule *type_module)
+{
+	/* XXX G_DEFINE_DYNAMIC_TYPE declares a static type registration
+	 *     function, so we have to wrap it with a public function in
+	 *     order to register types from a separate compilation unit. */
+	e_mail_config_mapi_extension_register_type (type_module);
+}
diff --git a/src/account-setup-eplugin/e-mapi-subscribe-foreign-folder.h b/src/configuration/e-mail-config-mapi-extension.h
similarity index 58%
copy from src/account-setup-eplugin/e-mapi-subscribe-foreign-folder.h
copy to src/configuration/e-mail-config-mapi-extension.h
index debf5b5..4981f4d 100644
--- a/src/account-setup-eplugin/e-mapi-subscribe-foreign-folder.h
+++ b/src/configuration/e-mail-config-mapi-extension.h
@@ -1,5 +1,6 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
 /*
+ * e-mail-config-mapi-extension.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
@@ -13,22 +14,21 @@
  * 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/>
  *
- *
- * Authors:
- *    Milan Crha <mcrha redhat com>
- *
- * Copyright (C) 2012 Red Hat, Inc. (www.redhat.com)
- *
  */
 
-#ifndef E_MAPI_SUBSCRIBE_FOREIGN_FOLDER_H
-#define E_MAPI_SUBSCRIBE_FOREIGN_FOLDER_H
+#ifndef E_MAIL_CONFIG_MAPI_EXTENSION_H
+#define E_MAIL_CONFIG_MAPI_EXTENSION_H
+
+#include <libebackend/libebackend.h>
+
+G_BEGIN_DECLS
+
+typedef EExtension EMailConfigMapiExtension;
+typedef EExtensionClass EMailConfigMapiExtensionClass;
 
-#include <gtk/gtk.h>
-#include <camel/camel.h>
+GType	e_mail_config_mapi_extension_get_type		(void);
+void	e_mail_config_mapi_extension_type_register	(GTypeModule *type_module);
 
-void	e_mapi_subscribe_foreign_folder	(GtkWindow *parent,
-					 CamelSession *session,
-					 CamelStore *store);
+G_END_DECLS
 
-#endif /* E_MAPI_SUBSCRIBE_FOREIGN_FOLDER_H */
+#endif /* E_MAIL_CONFIG_MAPI_EXTENSION_H */
diff --git a/src/configuration/e-mail-config-mapi-page.c b/src/configuration/e-mail-config-mapi-page.c
new file mode 100644
index 0000000..408d0b3
--- /dev/null
+++ b/src/configuration/e-mail-config-mapi-page.c
@@ -0,0 +1,296 @@
+/*
+ * e-mail-config-mapi-page.c
+ *
+ * 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/>
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <gtk/gtk.h>
+#include <glib/gi18n-lib.h>
+
+#include <mail/e-mail-config-page.h>
+#include <mail/e-mail-config-security-page.h>
+
+#include "e-mapi-config-utils.h"
+
+#include "e-mail-config-mapi-page.h"
+
+#define E_MAIL_CONFIG_MAPI_PAGE_GET_PRIVATE(obj) \
+	(G_TYPE_INSTANCE_GET_PRIVATE \
+	((obj), E_TYPE_MAIL_CONFIG_MAPI_PAGE, EMailConfigMapiPagePrivate))
+
+#define E_MAIL_CONFIG_MAPI_PAGE_SORT_ORDER \
+	(E_MAIL_CONFIG_SECURITY_PAGE_SORT_ORDER + 10)
+
+struct _EMailConfigMapiPagePrivate {
+	ESource *account_source;
+	ESourceRegistry *registry;
+};
+
+enum {
+	PROP_0,
+	PROP_ACCOUNT_SOURCE,
+	PROP_SOURCE_REGISTRY
+};
+
+static void e_mail_config_mapi_page_interface_init (EMailConfigPageInterface *interface);
+
+G_DEFINE_DYNAMIC_TYPE_EXTENDED (EMailConfigMapiPage, e_mail_config_mapi_page, GTK_TYPE_BOX, 0,
+	G_IMPLEMENT_INTERFACE_DYNAMIC (E_TYPE_MAIL_CONFIG_PAGE, e_mail_config_mapi_page_interface_init))
+
+static void
+folder_size_clicked_cb (GtkWidget *button,
+			EMailConfigMapiPage *page)
+{
+	ESource *source, *setting_source;
+	ESourceCamel *camel_ext;
+	ESourceRegistry *registry;
+	CamelSettings *settings;
+
+	g_return_if_fail (page != NULL);
+
+	source = e_mail_config_mapi_page_get_account_source (page);
+	registry = e_mail_config_mapi_page_get_source_registry (page);
+
+	if (e_source_get_parent (source))
+		setting_source = e_source_registry_ref_source (registry, e_source_get_parent (source));
+	else
+		setting_source = g_object_ref (source);
+
+	camel_ext = e_source_get_extension (setting_source, e_source_camel_get_extension_name ("mapi"));
+	settings = e_source_camel_get_settings (camel_ext);
+
+	e_mapi_config_utils_run_folder_size_dialog (registry, source, CAMEL_MAPI_SETTINGS (settings));
+
+	g_object_unref (setting_source);
+}
+
+static void
+mail_config_mapi_page_set_account_source (EMailConfigMapiPage *page,
+					  ESource *account_source)
+{
+	g_return_if_fail (E_IS_SOURCE (account_source));
+	g_return_if_fail (page->priv->account_source == NULL);
+
+	page->priv->account_source = g_object_ref (account_source);
+}
+
+static void
+mail_config_mapi_page_set_source_registry (EMailConfigMapiPage *page,
+					   ESourceRegistry *registry)
+{
+	g_return_if_fail (E_IS_SOURCE_REGISTRY (registry));
+	g_return_if_fail (page->priv->registry == NULL);
+
+	page->priv->registry = g_object_ref (registry);
+}
+
+static void
+mail_config_mapi_page_set_property (GObject *object,
+				    guint property_id,
+				    const GValue *value,
+				    GParamSpec *pspec)
+{
+	switch (property_id) {
+		case PROP_ACCOUNT_SOURCE:
+			mail_config_mapi_page_set_account_source (
+				E_MAIL_CONFIG_MAPI_PAGE (object),
+				g_value_get_object (value));
+			return;
+
+		case PROP_SOURCE_REGISTRY:
+			mail_config_mapi_page_set_source_registry (
+				E_MAIL_CONFIG_MAPI_PAGE (object),
+				g_value_get_object (value));
+			return;
+	}
+
+	G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+mail_config_mapi_page_get_property (GObject *object,
+				    guint property_id,
+				    GValue *value,
+				    GParamSpec *pspec)
+{
+	switch (property_id) {
+		case PROP_ACCOUNT_SOURCE:
+			g_value_set_object (
+				value,
+				e_mail_config_mapi_page_get_account_source (
+				E_MAIL_CONFIG_MAPI_PAGE (object)));
+			return;
+
+		case PROP_SOURCE_REGISTRY:
+			g_value_set_object (
+				value,
+				e_mail_config_mapi_page_get_source_registry (
+				E_MAIL_CONFIG_MAPI_PAGE (object)));
+			return;
+	}
+
+	G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+mail_config_mapi_page_dispose (GObject *object)
+{
+	EMailConfigMapiPagePrivate *priv;
+
+	priv = E_MAIL_CONFIG_MAPI_PAGE_GET_PRIVATE (object);
+
+	if (priv->account_source != NULL) {
+		g_object_unref (priv->account_source);
+		priv->account_source = NULL;
+	}
+
+	/* Chain up to parent's dispose() method. */
+	G_OBJECT_CLASS (e_mail_config_mapi_page_parent_class)->dispose (object);
+}
+
+static void
+mail_config_mapi_page_constructed (GObject *object)
+{
+	EMailConfigMapiPage *page = E_MAIL_CONFIG_MAPI_PAGE (object);
+	GtkWidget *widget;
+	GtkGrid *content_grid;
+	gchar *markup;
+
+	/* Chain up to parent's constructed() method. */
+	G_OBJECT_CLASS (e_mail_config_mapi_page_parent_class)->constructed (object);
+
+	gtk_orientable_set_orientation (GTK_ORIENTABLE (page), GTK_ORIENTATION_VERTICAL);
+	gtk_box_set_spacing (GTK_BOX (page), 12);
+
+	content_grid = GTK_GRID (gtk_grid_new ());
+	gtk_grid_set_row_spacing (content_grid, 6);
+	gtk_grid_set_column_spacing (content_grid, 6);
+	gtk_box_pack_start (GTK_BOX (page), GTK_WIDGET (content_grid), FALSE, FALSE, 0);
+
+	markup = g_markup_printf_escaped ("<b>%s</b>", _("MAPI Settings"));
+	widget = gtk_label_new (markup);
+	gtk_label_set_use_markup (GTK_LABEL (widget), TRUE);
+	gtk_misc_set_alignment (GTK_MISC (widget), 0.0, 0.5);
+	gtk_grid_attach (content_grid, widget, 0, 0, 2, 1);
+
+	widget = gtk_label_new (_("View the size of all Exchange folders"));
+	gtk_misc_set_alignment (GTK_MISC (widget), 0, 0.5);
+	gtk_grid_attach (content_grid, widget, 0, 1, 1, 1);
+
+	widget = gtk_button_new_with_mnemonic (_("Folder _Size"));
+	g_signal_connect (widget, "clicked", G_CALLBACK (folder_size_clicked_cb), page);
+	gtk_grid_attach (content_grid, widget, 1, 1, 1, 1);
+
+	gtk_widget_show_all (GTK_WIDGET (page));
+}
+
+static void
+e_mail_config_mapi_page_class_init (EMailConfigMapiPageClass *class)
+{
+	GObjectClass *object_class;
+
+	g_type_class_add_private (class, sizeof (EMailConfigMapiPagePrivate));
+
+	object_class = G_OBJECT_CLASS (class);
+	object_class->set_property = mail_config_mapi_page_set_property;
+	object_class->get_property = mail_config_mapi_page_get_property;
+	object_class->dispose = mail_config_mapi_page_dispose;
+	object_class->constructed = mail_config_mapi_page_constructed;
+
+	g_object_class_install_property (
+		object_class,
+		PROP_ACCOUNT_SOURCE,
+		g_param_spec_object (
+			"account-source",
+			"Account Source",
+			"Mail account source being edited",
+			E_TYPE_SOURCE,
+			G_PARAM_READWRITE |
+			G_PARAM_CONSTRUCT_ONLY));
+
+	g_object_class_install_property (
+		object_class,
+		PROP_SOURCE_REGISTRY,
+		g_param_spec_object (
+			"source-registry",
+			"Source Registry",
+			NULL,
+			E_TYPE_SOURCE_REGISTRY,
+			G_PARAM_READWRITE |
+			G_PARAM_CONSTRUCT_ONLY));
+}
+
+static void
+e_mail_config_mapi_page_class_finalize (EMailConfigMapiPageClass *class)
+{
+}
+
+static void
+e_mail_config_mapi_page_interface_init (EMailConfigPageInterface *interface)
+{
+	interface->title = _("MAPI Settings");
+	interface->sort_order = E_MAIL_CONFIG_MAPI_PAGE_SORT_ORDER;
+}
+
+static void
+e_mail_config_mapi_page_init (EMailConfigMapiPage *page)
+{
+	page->priv = E_MAIL_CONFIG_MAPI_PAGE_GET_PRIVATE (page);
+}
+
+void
+e_mail_config_mapi_page_type_register (GTypeModule *type_module)
+{
+	/* XXX G_DEFINE_DYNAMIC_TYPE declares a static type registration
+	 *     function, so we have to wrap it with a public function in
+	 *     order to register types from a separate compilation unit. */
+	e_mail_config_mapi_page_register_type (type_module);
+}
+
+EMailConfigPage *
+e_mail_config_mapi_page_new (ESource *account_source,
+			     ESourceRegistry *registry)
+{
+	EMailConfigPage *page;
+
+	g_return_val_if_fail (E_IS_SOURCE (account_source), NULL);
+
+	page = g_object_new (E_TYPE_MAIL_CONFIG_MAPI_PAGE,
+		"account-source", account_source,
+		"source-registry", registry,
+		NULL);
+
+	return page;
+}
+
+ESource *
+e_mail_config_mapi_page_get_account_source (EMailConfigMapiPage *page)
+{
+	g_return_val_if_fail (E_IS_MAIL_CONFIG_MAPI_PAGE (page), NULL);
+
+	return page->priv->account_source;
+}
+
+ESourceRegistry *
+e_mail_config_mapi_page_get_source_registry (EMailConfigMapiPage *page)
+{
+	g_return_val_if_fail (E_IS_MAIL_CONFIG_MAPI_PAGE (page), NULL);
+
+	return page->priv->registry;
+}
diff --git a/src/configuration/e-mail-config-mapi-page.h b/src/configuration/e-mail-config-mapi-page.h
new file mode 100644
index 0000000..6098d82
--- /dev/null
+++ b/src/configuration/e-mail-config-mapi-page.h
@@ -0,0 +1,71 @@
+/*
+ * e-mail-config-mapi-page.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 E_MAIL_CONFIG_MAPI_PAGE_H
+#define E_MAIL_CONFIG_MAPI_PAGE_H
+
+#include <gtk/gtk.h>
+#include <libedataserver/libedataserver.h>
+
+#include <mail/e-mail-config-page.h>
+
+/* Standard GObject macros */
+#define E_TYPE_MAIL_CONFIG_MAPI_PAGE \
+	(e_mail_config_mapi_page_get_type ())
+#define E_MAIL_CONFIG_MAPI_PAGE(obj) \
+	(G_TYPE_CHECK_INSTANCE_CAST \
+	((obj), E_TYPE_MAIL_CONFIG_MAPI_PAGE, EMailConfigMapiPage))
+#define E_MAIL_CONFIG_MAPI_PAGE_CLASS(cls) \
+	(G_TYPE_CHECK_CLASS_CAST \
+	((cls), E_TYPE_MAIL_CONFIG_MAPI_PAGE, EMailConfigMapiPageClass))
+#define E_IS_MAIL_CONFIG_MAPI_PAGE(obj) \
+	(G_TYPE_CHECK_INSTANCE_TYPE \
+	((obj), E_TYPE_MAIL_CONFIG_MAPI_PAGE))
+#define E_IS_MAIL_CONFIG_MAPI_PAGE_CLASS(cls) \
+	(G_TYPE_CHECK_CLASS_TYPE \
+	((cls), E_TYPE_MAIL_CONFIG_MAPI_PAGE))
+#define E_MAIL_CONFIG_MAPI_PAGE_GET_CLASS(obj) \
+	(G_TYPE_INSTANCE_GET_CLASS \
+	((obj), E_TYPE_MAIL_CONFIG_MAPI_PAGE, EMailConfigMapiPage))
+
+G_BEGIN_DECLS
+
+typedef struct _EMailConfigMapiPage EMailConfigMapiPage;
+typedef struct _EMailConfigMapiPageClass EMailConfigMapiPageClass;
+typedef struct _EMailConfigMapiPagePrivate EMailConfigMapiPagePrivate;
+
+struct _EMailConfigMapiPage {
+	GtkBox parent;
+	EMailConfigMapiPagePrivate *priv;
+};
+
+struct _EMailConfigMapiPageClass {
+	GtkBoxClass parent_class;
+};
+
+GType			e_mail_config_mapi_page_get_type		(void) G_GNUC_CONST;
+void			e_mail_config_mapi_page_type_register		(GTypeModule *type_module);
+EMailConfigPage *	e_mail_config_mapi_page_new			(ESource *account_source,
+									 ESourceRegistry *registry);
+
+ESource *		e_mail_config_mapi_page_get_account_source	(EMailConfigMapiPage *page);
+ESourceRegistry *	e_mail_config_mapi_page_get_source_registry	(EMailConfigMapiPage *page);
+
+G_END_DECLS
+
+#endif /* E_MAIL_CONFIG_MAPI_PAGE_H */
diff --git a/src/configuration/e-mapi-config-ui-extension.c b/src/configuration/e-mapi-config-ui-extension.c
new file mode 100644
index 0000000..cdaf2ac
--- /dev/null
+++ b/src/configuration/e-mapi-config-ui-extension.c
@@ -0,0 +1,154 @@
+/*
+ * e-mapi-config-ui-extension.c
+ *
+ * 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/>
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <glib/gi18n-lib.h>
+#include <gtk/gtk.h>
+
+#include <shell/e-shell-view.h>
+
+#include "e-mapi-config-utils.h"
+
+#include "e-mapi-config-ui-extension.h"
+
+G_DEFINE_DYNAMIC_TYPE (
+	EMapiConfigUIExtension,
+	e_mapi_config_ui_extension,
+	E_TYPE_EXTENSION)
+
+static void
+e_mapi_config_ui_extension_shell_view_toggled_cb (EShellView *shell_view,
+						  EMapiConfigUIExtension *ui_ext)
+{
+	EShellViewClass *shell_view_class;
+	EShellWindow *shell_window;
+	GtkUIManager *ui_manager;
+	gpointer key = NULL, value = NULL;
+	const gchar *ui_def;
+	gboolean is_active, need_update;
+
+	g_return_if_fail (E_IS_SHELL_VIEW (shell_view));
+	g_return_if_fail (ui_ext != NULL);
+
+	shell_view_class = E_SHELL_VIEW_GET_CLASS (shell_view);
+	g_return_if_fail (shell_view_class != NULL);
+
+	shell_window = e_shell_view_get_shell_window (shell_view);
+	ui_manager = e_shell_window_get_ui_manager (shell_window);
+
+	need_update = ui_ext->current_ui_id != 0;
+	if (ui_ext->current_ui_id) {
+		gtk_ui_manager_remove_ui (ui_manager, ui_ext->current_ui_id);
+		ui_ext->current_ui_id = 0;
+	}
+
+	is_active = e_shell_view_is_active (shell_view);
+	if (!is_active) {
+		if (need_update)
+			gtk_ui_manager_ensure_update (ui_manager);
+
+		return;
+	}
+
+	if (!g_hash_table_lookup_extended (ui_ext->ui_definitions, shell_view_class->ui_manager_id, &key, &value)) {
+		gchar *ui_definition = NULL;
+
+		e_mapi_config_utils_init_ui (shell_view, shell_view_class->ui_manager_id, &ui_definition);
+		g_hash_table_insert (ui_ext->ui_definitions, g_strdup (shell_view_class->ui_manager_id), ui_definition);
+	}
+
+	ui_def = g_hash_table_lookup (ui_ext->ui_definitions, shell_view_class->ui_manager_id);
+	if (ui_def) {
+		GError *error = NULL;
+
+		ui_ext->current_ui_id = gtk_ui_manager_add_ui_from_string (ui_manager, ui_def, -1, &error);
+		need_update = TRUE;
+
+		if (error) {
+			g_warning ("%s: Failed to add ui definition: %s", G_STRFUNC, error->message);
+			g_error_free (error);
+		}
+	}
+
+	if (need_update)
+		gtk_ui_manager_ensure_update (ui_manager);
+}
+
+static void
+e_mapi_config_ui_extension_constructed (GObject *object)
+{
+	EExtension *extension;
+	EExtensible *extensible;
+
+	extension = E_EXTENSION (object);
+	extensible = e_extension_get_extensible (extension);
+
+	/* Chain up to parent's constructed() method. */
+	G_OBJECT_CLASS (e_mapi_config_ui_extension_parent_class)->constructed (object);
+
+	g_signal_connect (E_SHELL_VIEW (extensible), "toggled", G_CALLBACK (e_mapi_config_ui_extension_shell_view_toggled_cb), extension);
+}
+
+static void
+e_mapi_config_ui_extension_finalize (GObject *object)
+{
+	EMapiConfigUIExtension *ui_ext = (EMapiConfigUIExtension *) object;
+
+	/* Chain up to parent's finalize() method. */
+	G_OBJECT_CLASS (e_mapi_config_ui_extension_parent_class)->finalize (object);
+
+	g_hash_table_destroy (ui_ext->ui_definitions);
+}
+
+static void
+e_mapi_config_ui_extension_class_init (EMapiConfigUIExtensionClass *class)
+{
+	GObjectClass *object_class;
+	EExtensionClass *extension_class;
+
+	object_class = G_OBJECT_CLASS (class);
+	object_class->constructed = e_mapi_config_ui_extension_constructed;
+	object_class->finalize = e_mapi_config_ui_extension_finalize;
+
+	extension_class = E_EXTENSION_CLASS (class);
+	extension_class->extensible_type = E_TYPE_SHELL_VIEW;
+}
+
+static void
+e_mapi_config_ui_extension_class_finalize (EMapiConfigUIExtensionClass *class)
+{
+}
+
+static void
+e_mapi_config_ui_extension_init (EMapiConfigUIExtension *extension)
+{
+	extension->current_ui_id = 0;
+	extension->ui_definitions = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
+}
+
+void
+e_mapi_config_ui_extension_type_register (GTypeModule *type_module)
+{
+	/* XXX G_DEFINE_DYNAMIC_TYPE declares a static type registration
+	 *     function, so we have to wrap it with a public function in
+	 *     order to register types from a separate compilation unit. */
+	e_mapi_config_ui_extension_register_type (type_module);
+}
diff --git a/src/account-setup-eplugin/e-mapi-subscribe-foreign-folder.h b/src/configuration/e-mapi-config-ui-extension.h
similarity index 50%
copy from src/account-setup-eplugin/e-mapi-subscribe-foreign-folder.h
copy to src/configuration/e-mapi-config-ui-extension.h
index debf5b5..d7b999d 100644
--- a/src/account-setup-eplugin/e-mapi-subscribe-foreign-folder.h
+++ b/src/configuration/e-mapi-config-ui-extension.h
@@ -1,5 +1,6 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
 /*
+ * e-mapi-config-ui-extension.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
@@ -13,22 +14,34 @@
  * 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/>
  *
- *
- * Authors:
- *    Milan Crha <mcrha redhat com>
- *
- * Copyright (C) 2012 Red Hat, Inc. (www.redhat.com)
- *
  */
 
-#ifndef E_MAPI_SUBSCRIBE_FOREIGN_FOLDER_H
-#define E_MAPI_SUBSCRIBE_FOREIGN_FOLDER_H
+#ifndef E_MAPI_CONFIG_UI_EXTENSION_H
+#define E_MAPI_CONFIG_UI_EXTENSION_H
+
+#include <libebackend/libebackend.h>
+
+G_BEGIN_DECLS
+
+typedef struct _EMapiConfigUIExtension EMapiConfigUIExtension;
+typedef struct _EMapiConfigUIExtensionClass EMapiConfigUIExtensionClass;
+
+struct _EMapiConfigUIExtension
+{
+	EExtension parent;
+
+	guint current_ui_id;
+	GHashTable *ui_definitions;
+};
+
+struct _EMapiConfigUIExtensionClass
+{
+	EExtensionClass parent;
+};
 
-#include <gtk/gtk.h>
-#include <camel/camel.h>
+GType	e_mapi_config_ui_extension_get_type		(void);
+void	e_mapi_config_ui_extension_type_register	(GTypeModule *type_module);
 
-void	e_mapi_subscribe_foreign_folder	(GtkWindow *parent,
-					 CamelSession *session,
-					 CamelStore *store);
+G_END_DECLS
 
-#endif /* E_MAPI_SUBSCRIBE_FOREIGN_FOLDER_H */
+#endif /* E_MAPI_CONFIG_UI_EXTENSION_H */
diff --git a/src/configuration/e-mapi-config-utils.c b/src/configuration/e-mapi-config-utils.c
new file mode 100644
index 0000000..69ce568
--- /dev/null
+++ b/src/configuration/e-mapi-config-utils.c
@@ -0,0 +1,1698 @@
+/*
+ * e-mapi-config-utils.c
+ *
+ * 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/>
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <string.h>
+#include <unistd.h>
+#include <glib/gi18n-lib.h>
+
+#include <gtk/gtk.h>
+#include <libedataserver/libedataserver.h>
+#include <libedataserverui/libedataserverui.h>
+#include <e-util/e-dialog-utils.h>
+#include <e-util/e-util.h>
+#include <mail/em-folder-tree.h>
+#include <misc/e-book-source-config.h>
+#include <misc/e-cal-source-config.h>
+#include <shell/e-shell.h>
+#include <shell/e-shell-sidebar.h>
+#include <shell/e-shell-view.h>
+#include <shell/e-shell-window.h>
+
+#include "e-mapi-folder.h"
+#include "e-mapi-connection.h"
+#include "e-mapi-utils.h"
+#include "e-source-mapi-folder.h"
+
+#include "e-mapi-subscribe-foreign-folder.h"
+#include "e-mapi-edit-folder-permissions.h"
+
+#include "camel/camel-mapi-store.h"
+#include "camel/camel-mapi-store-summary.h"
+
+#include "e-mapi-config-utils.h"
+
+struct RunWithFeedbackData
+{
+	GtkWindow *parent;
+	GtkWidget *dialog;
+	GCancellable *cancellable;
+	GObject *with_object;
+	EMapiSetupFunc thread_func;
+	EMapiSetupFunc idle_func;
+	gpointer user_data;
+	GDestroyNotify free_user_data;
+	GError *error;
+	gboolean run_modal;
+};
+
+static void
+free_run_with_feedback_data (gpointer ptr)
+{
+	struct RunWithFeedbackData *rfd = ptr;
+
+	if (!rfd)
+		return;
+
+	if (rfd->dialog)
+		gtk_widget_destroy (rfd->dialog);
+
+	g_object_unref (rfd->cancellable);
+	g_object_unref (rfd->with_object);
+
+	if (rfd->free_user_data)
+		rfd->free_user_data (rfd->user_data);
+
+	g_clear_error (&rfd->error);
+
+	g_free (rfd);
+}
+
+static gboolean
+run_with_feedback_idle (gpointer user_data)
+{
+	struct RunWithFeedbackData *rfd = user_data;
+	gboolean was_cancelled = FALSE;
+
+	g_return_val_if_fail (rfd != NULL, FALSE);
+
+	if (!g_cancellable_is_cancelled (rfd->cancellable)) {
+		if (rfd->idle_func && !rfd->error)
+			rfd->idle_func (rfd->with_object, rfd->user_data, rfd->cancellable, &rfd->error);
+
+		was_cancelled = g_cancellable_is_cancelled (rfd->cancellable);
+
+		if (rfd->dialog) {
+			gtk_widget_destroy (rfd->dialog);
+			rfd->dialog = NULL;
+		}
+	} else {
+		was_cancelled = TRUE;
+	}
+
+	if (!was_cancelled) {
+		if (rfd->error)
+			e_notice (rfd->parent, GTK_MESSAGE_ERROR, "%s", rfd->error->message);
+	}
+
+	free_run_with_feedback_data (rfd);
+
+	return FALSE;
+}
+
+static gpointer
+run_with_feedback_thread (gpointer user_data)
+{
+	struct RunWithFeedbackData *rfd = user_data;
+
+	g_return_val_if_fail (rfd != NULL, NULL);
+	g_return_val_if_fail (rfd->thread_func != NULL, NULL);
+
+	if (!g_cancellable_is_cancelled (rfd->cancellable))
+		rfd->thread_func (rfd->with_object, rfd->user_data, rfd->cancellable, &rfd->error);
+
+	g_idle_add (run_with_feedback_idle, rfd);
+
+	return NULL;
+}
+
+static void
+run_with_feedback_response_cb (GtkWidget *dialog,
+			       gint resonse_id,
+			       struct RunWithFeedbackData *rfd)
+{
+	g_return_if_fail (rfd != NULL);
+
+	rfd->dialog = NULL;
+
+	g_cancellable_cancel (rfd->cancellable);
+
+	gtk_widget_destroy (dialog);
+}
+
+static void
+e_mapi_config_utils_run_in_thread_with_feedback_general (GtkWindow *parent,
+					    GObject *with_object,
+					    const gchar *description,
+					    EMapiSetupFunc thread_func,
+					    EMapiSetupFunc idle_func,
+					    gpointer user_data,
+					    GDestroyNotify free_user_data,
+					    gboolean run_modal)
+{
+	GtkWidget *dialog, *label, *content;
+	struct RunWithFeedbackData *rfd;
+
+	g_return_if_fail (with_object != NULL);
+	g_return_if_fail (description != NULL);
+	g_return_if_fail (thread_func != NULL);
+
+	dialog = gtk_dialog_new_with_buttons ("",
+		parent,
+		GTK_DIALOG_MODAL,
+		GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+		NULL);
+
+	label = gtk_label_new (description);
+	gtk_widget_show (label);
+
+	content = gtk_dialog_get_content_area (GTK_DIALOG (dialog));
+
+	gtk_container_add (GTK_CONTAINER (content), label);
+	gtk_container_set_border_width (GTK_CONTAINER (content), 12);
+
+	rfd = g_new0 (struct RunWithFeedbackData, 1);
+	rfd->parent = parent;
+	rfd->dialog = dialog;
+	rfd->cancellable = g_cancellable_new ();
+	rfd->with_object = g_object_ref (with_object);
+	rfd->thread_func = thread_func;
+	rfd->idle_func = idle_func;
+	rfd->user_data = user_data;
+	rfd->free_user_data = free_user_data;
+	rfd->error = NULL;
+	rfd->run_modal = run_modal;
+
+	g_signal_connect (dialog, "response", G_CALLBACK (run_with_feedback_response_cb), rfd);
+
+	if (run_modal) {
+		GCancellable *cancellable;
+
+		cancellable = g_object_ref (rfd->cancellable);
+
+		g_return_if_fail (g_thread_create (run_with_feedback_thread, rfd, FALSE, NULL));
+
+		gtk_dialog_run (GTK_DIALOG (dialog));
+
+		g_cancellable_cancel (cancellable);
+		g_object_unref (cancellable);
+	} else {
+		gtk_widget_show (dialog);
+
+		g_return_if_fail (g_thread_create (run_with_feedback_thread, rfd, FALSE, NULL));
+	}
+}
+
+void
+e_mapi_config_utils_run_in_thread_with_feedback (GtkWindow *parent,
+				    GObject *with_object,
+				    const gchar *description,
+				    EMapiSetupFunc thread_func,
+				    EMapiSetupFunc idle_func,
+				    gpointer user_data,
+				    GDestroyNotify free_user_data)
+{
+	e_mapi_config_utils_run_in_thread_with_feedback_general (parent, with_object, description, thread_func, idle_func, user_data, free_user_data, FALSE);
+}
+
+void
+e_mapi_config_utils_run_in_thread_with_feedback_modal (GtkWindow *parent,
+					  GObject *with_object,
+					  const gchar *description,
+					  EMapiSetupFunc thread_func,
+					  EMapiSetupFunc idle_func,
+					  gpointer user_data,
+					  GDestroyNotify free_user_data)
+{
+	e_mapi_config_utils_run_in_thread_with_feedback_general (parent, with_object, description, thread_func, idle_func, user_data, free_user_data, TRUE);
+}
+
+typedef struct _EMapiConfigUtilsAuthenticator EMapiConfigUtilsAuthenticator;
+typedef struct _EMapiConfigUtilsAuthenticatorClass EMapiConfigUtilsAuthenticatorClass;
+
+struct _EMapiConfigUtilsAuthenticator {
+	GObject parent;
+
+	ESourceRegistry *registry;
+	CamelMapiSettings *mapi_settings;
+	EMapiConnection *conn;
+};
+
+struct _EMapiConfigUtilsAuthenticatorClass {
+	GObjectClass parent_class;
+};
+
+static ESourceAuthenticationResult
+mapi_config_utils_authenticator_try_password_sync (ESourceAuthenticator *auth,
+						   const GString *password,
+						   GCancellable *cancellable,
+						   GError **error)
+{
+	EMapiConfigUtilsAuthenticator *authenticator = (EMapiConfigUtilsAuthenticator *) auth;
+	EMapiProfileData empd;
+	CamelNetworkSettings *network_settings;
+	GError *mapi_error = NULL;
+
+	network_settings = CAMEL_NETWORK_SETTINGS (authenticator->mapi_settings);
+
+	empd.server = camel_network_settings_get_host (network_settings);
+	empd.username = camel_network_settings_get_user (network_settings);
+	e_mapi_util_profiledata_from_settings (&empd, authenticator->mapi_settings);
+
+	authenticator->conn = e_mapi_connection_new (
+		authenticator->registry,
+		camel_mapi_settings_get_profile (authenticator->mapi_settings),
+		password, cancellable, &mapi_error);
+
+	if (mapi_error) {
+		g_warn_if_fail (!authenticator->conn);
+		authenticator->conn = NULL;
+
+		g_propagate_error (error, mapi_error);
+
+		return E_SOURCE_AUTHENTICATION_ERROR;
+	}
+
+	g_warn_if_fail (authenticator->conn);
+
+	return E_SOURCE_AUTHENTICATION_ACCEPTED;
+}
+
+#define E_TYPE_MAPI_CONFIG_UTILS_AUTHENTICATOR (e_mapi_config_utils_authenticator_get_type ())
+
+GType e_mapi_config_utils_authenticator_get_type (void) G_GNUC_CONST;
+
+static void e_mapi_config_utils_authenticator_authenticator_init (ESourceAuthenticatorInterface *interface);
+
+G_DEFINE_TYPE_EXTENDED (EMapiConfigUtilsAuthenticator, e_mapi_config_utils_authenticator, G_TYPE_OBJECT, 0,
+	G_IMPLEMENT_INTERFACE (E_TYPE_SOURCE_AUTHENTICATOR, e_mapi_config_utils_authenticator_authenticator_init))
+
+static void
+mapi_config_utils_authenticator_finalize (GObject *object)
+{
+	EMapiConfigUtilsAuthenticator *authenticator = (EMapiConfigUtilsAuthenticator *) object;
+
+	g_object_unref (authenticator->registry);
+	g_object_unref (authenticator->mapi_settings);
+	if (authenticator->conn)
+		g_object_unref (authenticator->conn);
+
+	G_OBJECT_CLASS (e_mapi_config_utils_authenticator_parent_class)->finalize (object);
+}
+
+static void
+e_mapi_config_utils_authenticator_class_init (EMapiConfigUtilsAuthenticatorClass *class)
+{
+	GObjectClass *object_class;
+
+	object_class = G_OBJECT_CLASS (class);
+	object_class->finalize = mapi_config_utils_authenticator_finalize;
+}
+
+static void
+e_mapi_config_utils_authenticator_authenticator_init (ESourceAuthenticatorInterface *interface)
+{
+	interface->try_password_sync = mapi_config_utils_authenticator_try_password_sync;
+}
+
+static void
+e_mapi_config_utils_authenticator_init (EMapiConfigUtilsAuthenticator *authenticator)
+{
+}
+
+EMapiConnection	*
+e_mapi_config_utils_open_connection_for (GtkWindow *parent,
+					 ESourceRegistry *registry,
+					 ESource *source,
+					 CamelMapiSettings *mapi_settings,
+					 GCancellable *cancellable,
+					 GError **perror)
+{
+	const gchar *profile;
+	EMapiConnection *conn = NULL;
+	EMapiProfileData empd = { 0 };
+	CamelNetworkSettings *network_settings;
+	GError *local_error = NULL;
+
+	g_return_val_if_fail (registry != NULL, NULL);
+	g_return_val_if_fail (source != NULL, NULL);
+	g_return_val_if_fail (mapi_settings != NULL, NULL);
+
+	profile = camel_mapi_settings_get_profile (mapi_settings);
+
+	/* use the one from mailer, if there, otherwise open new */
+	conn = e_mapi_connection_find (profile);
+	if (conn)
+		return conn;
+
+	network_settings = CAMEL_NETWORK_SETTINGS (mapi_settings);
+
+	empd.server = camel_network_settings_get_host (network_settings);
+	empd.username = camel_network_settings_get_user (network_settings);
+	e_mapi_util_profiledata_from_settings (&empd, mapi_settings);
+
+	if (empd.krb_sso)
+		conn = e_mapi_connection_new (registry, profile, NULL, cancellable, &local_error);
+
+	while (!conn && !g_cancellable_is_cancelled (cancellable) && !local_error) {
+		if (empd.krb_sso) {
+			e_mapi_util_trigger_krb_auth (&empd, &local_error);
+			g_clear_error (&local_error);
+
+			conn = e_mapi_connection_new (registry, profile, NULL, cancellable, &local_error);
+		} else {
+			EMapiConfigUtilsAuthenticator *authenticator = g_object_new (E_TYPE_MAPI_CONFIG_UTILS_AUTHENTICATOR, NULL);
+
+			authenticator->mapi_settings = g_object_ref (mapi_settings);
+			authenticator->registry = g_object_ref (registry);
+
+			e_source_registry_authenticate_sync (
+				registry, source, E_SOURCE_AUTHENTICATOR (authenticator),
+				cancellable, &local_error);
+
+			if (authenticator->conn)
+				conn = g_object_ref (authenticator->conn);
+
+			g_object_unref (authenticator);
+		}
+	}
+
+	if (local_error)
+		g_propagate_error (perror, local_error);
+
+	return conn;
+}
+
+#define FOLDERSIZE_MENU_ITEM 0
+
+enum {
+	COL_FOLDERSIZE_NAME = 0,
+	COL_FOLDERSIZE_SIZE,
+	COL_FOLDERSIZE_MAX
+};
+
+typedef struct
+{
+	GtkDialog *dialog;
+	GtkGrid *spinner_grid;
+
+	ESourceRegistry *registry;
+	ESource *source;
+	CamelMapiSettings *mapi_settings;
+
+	GSList *folder_list;
+	GCancellable *cancellable;
+	GError *error;
+} FolderSizeDialogData;
+
+static gboolean
+mapi_settings_get_folder_size_idle (gpointer user_data)
+{
+	GtkWidget *widget;
+	GtkCellRenderer *renderer;
+	GtkListStore *store;
+	GtkTreeIter iter;
+	GtkBox *content_area;
+	FolderSizeDialogData *fsd = user_data;
+
+	g_return_val_if_fail (fsd != NULL, FALSE);
+
+	if (g_cancellable_is_cancelled (fsd->cancellable))
+		goto cleanup;
+
+	/* Hide progress bar. Set status*/
+	gtk_widget_destroy (GTK_WIDGET (fsd->spinner_grid));
+
+	if (fsd->folder_list) {
+		GtkWidget *scrolledwindow, *tree_view;
+		GSList *fiter;
+
+		scrolledwindow = gtk_scrolled_window_new (NULL, NULL);
+		gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwindow), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+		gtk_widget_show (scrolledwindow);
+
+		/*Tree View */
+		tree_view =  gtk_tree_view_new ();
+		renderer = gtk_cell_renderer_text_new ();
+		gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (tree_view),-1,
+							     _("Folder"), renderer, "text", COL_FOLDERSIZE_NAME,
+							     NULL);
+
+		renderer = gtk_cell_renderer_text_new ();
+		gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (tree_view),-1,
+							     _("Size"), renderer, "text", COL_FOLDERSIZE_SIZE,
+							     NULL);
+		/* Model for TreeView */
+		store = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_STRING);
+		gtk_tree_view_set_model (GTK_TREE_VIEW (tree_view), GTK_TREE_MODEL (store));
+
+		/* Populate model with data */
+		for (fiter = fsd->folder_list; fiter;  fiter = fiter->next) {
+			EMapiFolder *folder = fiter->data;
+			gchar *folder_size = g_format_size (folder->size);
+
+			gtk_list_store_append (store, &iter);
+			gtk_list_store_set (store, &iter,
+					    COL_FOLDERSIZE_NAME, folder->folder_name,
+					    COL_FOLDERSIZE_SIZE, folder_size,
+					    -1);
+
+			g_free (folder_size);
+		}
+
+		gtk_container_add (GTK_CONTAINER (scrolledwindow), tree_view);
+		widget = scrolledwindow;
+	} else if (fsd->error) {
+		gchar *msg = g_strconcat (_("Unable to retrieve folder size information"), "\n", fsd->error->message, NULL);
+		widget = gtk_label_new (msg);
+		g_free (msg);
+	} else {
+		widget = gtk_label_new (_("Unable to retrieve folder size information"));
+	}
+
+	gtk_widget_show_all (widget);
+
+	/* Pack into content_area */
+	content_area = GTK_BOX (gtk_dialog_get_content_area (fsd->dialog));
+	gtk_box_pack_start (content_area, widget, TRUE, TRUE, 6);
+
+ cleanup:
+	e_mapi_folder_free_list (fsd->folder_list);
+	g_object_unref (fsd->registry);
+	g_object_unref (fsd->source);
+	g_object_unref (fsd->mapi_settings);
+	g_object_unref (fsd->cancellable);
+	g_clear_error (&fsd->error);
+	g_free (fsd);
+
+	return FALSE;
+}
+
+static gpointer
+mapi_settings_get_folder_size_thread (gpointer user_data)
+{
+	FolderSizeDialogData *fsd = user_data;
+	EMapiConnection *conn;
+
+	g_return_val_if_fail (fsd != NULL, NULL);
+
+	fsd->folder_list = NULL;
+	conn = e_mapi_config_utils_open_connection_for (GTK_WINDOW (fsd->dialog),
+		fsd->registry,
+		fsd->source,
+		fsd->mapi_settings,
+		fsd->cancellable,
+		&fsd->error);
+
+	if (conn && e_mapi_connection_connected (conn)) {
+		fsd->folder_list = NULL;
+		e_mapi_connection_get_folders_list (conn,
+			&fsd->folder_list,
+			NULL, NULL,
+			fsd->cancellable, &fsd->error);
+	}
+
+	if (conn)
+		g_object_unref (conn);
+
+	g_idle_add (mapi_settings_get_folder_size_idle, fsd);
+
+	return NULL;
+}
+
+void
+e_mapi_config_utils_run_folder_size_dialog (ESourceRegistry *registry,
+					    ESource *source,
+					    CamelMapiSettings *mapi_settings)
+{
+	GtkBox *content_area;
+	GtkWidget *spinner, *alignment, *dialog;
+	GtkWidget *spinner_label;
+	GCancellable *cancellable;
+	FolderSizeDialogData *fsd;
+
+	g_return_if_fail (mapi_settings != NULL);
+
+	dialog = gtk_dialog_new_with_buttons (_("Folder Size"), NULL,
+		GTK_DIALOG_DESTROY_WITH_PARENT,
+		GTK_STOCK_CLOSE, GTK_RESPONSE_ACCEPT,
+		NULL);
+
+	fsd = g_new0 (FolderSizeDialogData, 1);
+	fsd->dialog = GTK_DIALOG (dialog);
+
+	gtk_window_set_default_size (GTK_WINDOW (fsd->dialog), 250, 300);
+
+	content_area = GTK_BOX (gtk_dialog_get_content_area (fsd->dialog));
+
+	spinner = gtk_spinner_new ();
+	gtk_spinner_start (GTK_SPINNER (spinner));
+	spinner_label = gtk_label_new (_("Fetching folder listâ"));
+
+	fsd->spinner_grid = GTK_GRID (gtk_grid_new ());
+	gtk_grid_set_column_spacing (fsd->spinner_grid, 6);
+	gtk_grid_set_column_homogeneous (fsd->spinner_grid, FALSE);
+	gtk_orientable_set_orientation (GTK_ORIENTABLE (fsd->spinner_grid), GTK_ORIENTATION_HORIZONTAL);
+
+	alignment = gtk_alignment_new (1.0, 0.5, 0.0, 1.0);
+	gtk_container_add (GTK_CONTAINER (alignment), spinner);
+	gtk_misc_set_alignment (GTK_MISC (spinner_label), 0.0, 0.5);
+
+	gtk_container_add (GTK_CONTAINER (fsd->spinner_grid), alignment);
+	gtk_container_add (GTK_CONTAINER (fsd->spinner_grid), spinner_label);
+
+	/* Pack the TreeView into dialog's content area */
+	gtk_box_pack_start (content_area, GTK_WIDGET (fsd->spinner_grid), TRUE, TRUE, 6);
+	gtk_widget_show_all (GTK_WIDGET (fsd->dialog));
+
+	cancellable = g_cancellable_new ();
+	fsd->registry = g_object_ref (registry);
+	fsd->source = g_object_ref (source);
+	fsd->mapi_settings = g_object_ref (mapi_settings);
+	fsd->cancellable = g_object_ref (cancellable);
+
+	g_return_if_fail (g_thread_create (mapi_settings_get_folder_size_thread, fsd, FALSE, NULL));
+
+	/* Start the dialog */
+	gtk_dialog_run (GTK_DIALOG (dialog));
+
+	g_cancellable_cancel (cancellable);
+	g_object_unref (cancellable);
+	gtk_widget_destroy (GTK_WIDGET (dialog));
+}
+
+static gchar *
+get_profile_name_from_folder_tree (EShellView *shell_view,
+				   gchar **pfolder_path,
+				   CamelStore **pstore)
+{
+	EShellSidebar *shell_sidebar;
+	EMFolderTree *folder_tree;
+	gchar *profile = NULL, *selected_path = NULL;
+	CamelStore *selected_store = NULL;
+
+	/* Get hold of Folder Tree */
+	shell_sidebar = e_shell_view_get_shell_sidebar (shell_view);
+	g_object_get (shell_sidebar, "folder-tree", &folder_tree, NULL);
+	if (em_folder_tree_get_selected (folder_tree, &selected_store, &selected_path) ||
+	    em_folder_tree_store_root_selected (folder_tree, &selected_store)) {
+		if (selected_store) {
+			CamelProvider *provider = camel_service_get_provider (CAMEL_SERVICE (selected_store));
+
+			if (provider && g_ascii_strcasecmp (provider->protocol, "mapi") == 0) {
+				CamelService *service;
+				CamelSettings *settings;
+
+				service = CAMEL_SERVICE (selected_store);
+				settings = camel_service_get_settings (service);
+				g_object_get (settings, "profile", &profile, NULL);
+
+				if (pstore && profile)
+					*pstore = g_object_ref (selected_store);
+
+				if (pfolder_path)
+					*pfolder_path = selected_path;
+				else
+					g_free (selected_path);
+
+				selected_path = NULL;
+			}
+
+			g_object_unref (selected_store);
+		}
+
+		g_free (selected_path);
+	}
+
+	g_object_unref (folder_tree);
+
+	return profile;
+}
+
+static void
+action_folder_size_cb (GtkAction *action,
+		       EShellView *shell_view)
+{
+	gchar *profile;
+	CamelSession *session;
+	CamelStore *store = NULL;
+	CamelMapiSettings *mapi_settings;
+
+	profile = get_profile_name_from_folder_tree (shell_view, NULL, &store);
+	if (profile && store) {
+		ESourceRegistry *registry;
+		ESource *source;
+
+		mapi_settings = CAMEL_MAPI_SETTINGS (camel_service_get_settings (CAMEL_SERVICE (store)));
+		session = camel_service_get_session (CAMEL_SERVICE (store));
+		registry = e_mail_session_get_registry (E_MAIL_SESSION (session));
+		source = e_source_registry_ref_source (registry, camel_service_get_uid (CAMEL_SERVICE (store)));
+
+		e_mapi_config_utils_run_folder_size_dialog (
+			registry, source, mapi_settings);
+
+		g_object_unref (source); 
+	}
+
+	g_free (profile);
+	if (store)
+		g_object_unref (store);
+}
+
+static void
+action_subscribe_foreign_folder_cb (GtkAction *action,
+				    EShellView *shell_view)
+{
+	gchar *profile;
+	GtkWindow *parent;
+	EShellBackend *backend;
+	CamelSession *session = NULL;
+	CamelStore *store = NULL;
+
+	profile = get_profile_name_from_folder_tree (shell_view, NULL, &store);
+	if (!profile)
+		return;
+
+	parent = GTK_WINDOW (e_shell_view_get_shell_window (shell_view));
+	backend = e_shell_view_get_shell_backend (shell_view);
+	g_object_get (G_OBJECT (backend), "session", &session, NULL);
+
+	e_mapi_subscribe_foreign_folder (parent, session, store);
+
+	g_object_unref (session);
+	g_object_unref (store);
+	g_free (profile);
+}
+
+static void
+action_folder_permissions_mail_cb (GtkAction *action,
+				   EShellView *shell_view)
+{
+	gchar *profile, *folder_path = NULL;
+	EShellWindow *shell_window;
+	GtkWindow *parent;
+	CamelStore *store = NULL;
+	CamelMapiStore *mapi_store;
+	CamelNetworkSettings *network_settings;
+	CamelStoreInfo *si;
+
+	profile = get_profile_name_from_folder_tree (shell_view, &folder_path, &store);
+	if (!profile)
+		return;
+
+	mapi_store = CAMEL_MAPI_STORE (store);
+	g_return_if_fail (mapi_store != NULL);
+	g_return_if_fail (folder_path != NULL);
+
+	network_settings = CAMEL_NETWORK_SETTINGS (camel_service_get_settings (CAMEL_SERVICE (store)));
+	g_return_if_fail (network_settings != NULL);
+
+	shell_window = e_shell_view_get_shell_window (shell_view);
+	parent = GTK_WINDOW (shell_window);
+
+	si = camel_store_summary_path (mapi_store->summary, folder_path);
+	if (!si) {
+		e_notice (parent, GTK_MESSAGE_ERROR, _("Cannot edit permissions of folder '%s', choose other folder."), folder_path);
+	} else {
+		CamelMapiStoreInfo *msi = (CamelMapiStoreInfo *) si;
+		ESourceRegistry *registry = e_shell_get_registry (e_shell_window_get_shell (shell_window));
+		ESource *source;
+
+		source = e_source_registry_ref_source (registry, camel_service_get_uid (CAMEL_SERVICE (store)));
+		g_return_if_fail (source != NULL);
+
+		e_mapi_edit_folder_permissions (parent,
+			registry,
+			source,
+			CAMEL_MAPI_SETTINGS (network_settings),
+			camel_service_get_display_name (CAMEL_SERVICE (store)),
+			folder_path,
+			msi->folder_id,
+			(msi->mapi_folder_flags & CAMEL_MAPI_STORE_FOLDER_FLAG_FOREIGN) != 0 ? E_MAPI_FOLDER_CATEGORY_FOREIGN :
+			(msi->mapi_folder_flags & CAMEL_MAPI_STORE_FOLDER_FLAG_PUBLIC) != 0 ? E_MAPI_FOLDER_CATEGORY_PUBLIC :
+			E_MAPI_FOLDER_CATEGORY_PERSONAL,
+			msi->foreign_username,
+			FALSE);
+
+		g_object_unref (source);
+	}
+
+	g_object_unref (store);
+	g_free (folder_path);
+}
+
+static void
+mapi_ui_enable_actions (GtkActionGroup *action_group,
+			const GtkActionEntry *entries,
+			guint n_entries,
+			gboolean can_show,
+			gboolean is_online)
+{
+	gint ii;
+
+	g_return_if_fail (action_group != NULL);
+	g_return_if_fail (entries != NULL);
+
+	for (ii = 0; ii < n_entries; ii++) {
+		GtkAction *action;
+
+		action = gtk_action_group_get_action (action_group, entries[ii].name);
+		if (!action)
+			continue;
+
+		gtk_action_set_visible (action, can_show);
+		if (can_show)
+			gtk_action_set_sensitive (action, is_online);
+	}
+}
+
+static GtkActionEntry mail_account_context_entries[] = {
+
+	{ "mail-mapi-folder-size",
+	  NULL,
+	  N_("Folder size..."),
+	  NULL,
+	  NULL,  /* XXX Add a tooltip! */
+	  G_CALLBACK (action_folder_size_cb) },
+
+	{ "mail-mapi-subscribe-foreign-folder",
+	  NULL,
+	  N_("Subscribe to folder of other user..."),
+	  NULL,
+	  NULL,  /* XXX Add a tooltip! */
+	  G_CALLBACK (action_subscribe_foreign_folder_cb) }
+};
+
+static GtkActionEntry mail_folder_context_entries[] = {
+	{ "mail-mapi-folder-permissions",
+	  "folder-new",
+	  N_("Permissions..."),
+	  NULL,
+	  N_("Edit MAPI folder permissions"),
+	  G_CALLBACK (action_folder_permissions_mail_cb) }
+};
+
+static const gchar *mapi_ui_mail_def =
+	"<popup name=\"mail-folder-popup\">\n"
+	"  <placeholder name=\"mail-folder-popup-actions\">\n"
+	"    <menuitem action=\"mail-mapi-folder-size\"/>\n"
+	"    <menuitem action=\"mail-mapi-subscribe-foreign-folder\"/>\n"
+	"    <menuitem action=\"mail-mapi-folder-permissions\"/>\n"
+	"  </placeholder>\n"
+	"</popup>\n";
+
+static void
+mapi_ui_update_actions_mail_cb (EShellView *shell_view,
+				GtkActionEntry *entries)
+{
+	EShellWindow *shell_window;
+	GtkActionGroup *action_group;
+	GtkUIManager *ui_manager;
+	EShellSidebar *shell_sidebar;
+	EMFolderTree *folder_tree;
+	CamelStore *selected_store = NULL;
+	gchar *selected_path = NULL;
+	gboolean account_node = FALSE, folder_node = FALSE;
+	gboolean online = FALSE;
+
+	shell_sidebar = e_shell_view_get_shell_sidebar (shell_view);
+	g_object_get (shell_sidebar, "folder-tree", &folder_tree, NULL);
+	if (em_folder_tree_get_selected (folder_tree, &selected_store, &selected_path) ||
+	    em_folder_tree_store_root_selected (folder_tree, &selected_store)) {
+		if (selected_store) {
+			CamelProvider *provider = camel_service_get_provider (CAMEL_SERVICE (selected_store));
+
+			if (provider && g_ascii_strcasecmp (provider->protocol, "mapi") == 0) {
+				account_node = !selected_path || !*selected_path;
+				folder_node = !account_node;
+			}
+
+			g_object_unref (selected_store);
+		}
+	}
+	g_object_unref (folder_tree);
+
+	g_free (selected_path);
+
+	shell_window = e_shell_view_get_shell_window (shell_view);
+	ui_manager = e_shell_window_get_ui_manager (shell_window);
+	action_group = e_lookup_action_group (ui_manager, "mail");
+
+	if (account_node || folder_node) {
+		EShellBackend *backend;
+		CamelSession *session = NULL;
+
+		backend = e_shell_view_get_shell_backend (shell_view);
+		g_object_get (G_OBJECT (backend), "session", &session, NULL);
+
+		online = session && camel_session_get_online (session);
+
+		if (session)
+			g_object_unref (session);
+	}
+
+	mapi_ui_enable_actions (action_group, mail_account_context_entries, G_N_ELEMENTS (mail_account_context_entries), account_node, online);
+	mapi_ui_enable_actions (action_group, mail_folder_context_entries, G_N_ELEMENTS (mail_folder_context_entries), folder_node, online);
+}
+
+static void
+mapi_ui_init_mail (GtkUIManager *ui_manager,
+                   EShellView *shell_view,
+		   gchar **ui_definition)
+{
+	EShellWindow *shell_window;
+	GtkActionGroup *action_group;
+
+	g_return_if_fail (ui_definition != NULL);
+
+	*ui_definition = g_strdup (mapi_ui_mail_def);
+
+	shell_window = e_shell_view_get_shell_window (shell_view);
+	action_group = e_shell_window_get_action_group (shell_window, "mail");
+
+	/* Add actions to the "mail" action group. */
+	e_action_group_add_actions_localized (action_group, GETTEXT_PACKAGE,
+		mail_account_context_entries, G_N_ELEMENTS (mail_account_context_entries), shell_view);
+	e_action_group_add_actions_localized (action_group, GETTEXT_PACKAGE,
+		mail_folder_context_entries, G_N_ELEMENTS (mail_folder_context_entries), shell_view);
+
+	/* Decide whether we want this option to be visible or not */
+	g_signal_connect (shell_view, "update-actions",
+			  G_CALLBACK (mapi_ui_update_actions_mail_cb),
+			  shell_view);
+
+	g_object_unref (action_group);
+}
+
+static gboolean
+get_selected_mapi_source (EShellView *shell_view,
+			  ESource **selected_source,
+			  ESourceRegistry **registry)
+{
+	ESource *source;
+	EShellSidebar *shell_sidebar;
+	ESourceSelector *selector = NULL;
+
+	g_return_val_if_fail (shell_view != NULL, FALSE);
+
+	shell_sidebar = e_shell_view_get_shell_sidebar (shell_view);
+	g_return_val_if_fail (shell_sidebar != NULL, FALSE);
+
+	g_object_get (shell_sidebar, "selector", &selector, NULL);
+	g_return_val_if_fail (selector != NULL, FALSE);
+
+	source = e_source_selector_ref_primary_selection (selector);
+	if (source) {
+		ESourceBackend *backend_ext = NULL;
+
+		if (e_source_has_extension (source, E_SOURCE_EXTENSION_ADDRESS_BOOK))
+			backend_ext = e_source_get_extension (source, E_SOURCE_EXTENSION_ADDRESS_BOOK);
+		else if (e_source_has_extension (source, E_SOURCE_EXTENSION_CALENDAR))
+			backend_ext = e_source_get_extension (source, E_SOURCE_EXTENSION_CALENDAR);
+		else if (e_source_has_extension (source, E_SOURCE_EXTENSION_MEMO_LIST))
+			backend_ext = e_source_get_extension (source, E_SOURCE_EXTENSION_MEMO_LIST);
+		else if (e_source_has_extension (source, E_SOURCE_EXTENSION_TASK_LIST))
+			backend_ext = e_source_get_extension (source, E_SOURCE_EXTENSION_TASK_LIST);
+		else if (e_source_has_extension (source, E_SOURCE_EXTENSION_MAIL_ACCOUNT))
+			backend_ext = e_source_get_extension (source, E_SOURCE_EXTENSION_MAIL_ACCOUNT);
+
+		if (!backend_ext ||
+		    g_strcmp0 (e_source_backend_get_backend_name (backend_ext), "mapi") != 0) {
+			g_object_unref (source);
+			source = NULL;
+		}
+	}
+
+	if (source && registry)
+		*registry = g_object_ref (e_source_selector_get_registry (selector));
+
+	g_object_unref (selector);
+
+	if (selected_source)
+		*selected_source = source;
+	else if (source)
+		g_object_unref (source);
+
+	return source != NULL;
+}
+
+/* how many menu entries are defined; all calendar/tasks/memos/contacts
+   actions should have same count */
+#define MAPI_ESOURCE_NUM_ENTRIES 1
+
+static void
+update_mapi_source_entries_cb (EShellView *shell_view,
+			       GtkActionEntry *entries)
+{
+	GtkActionGroup *action_group;
+	EShell *shell;
+	EShellWindow *shell_window;
+	const gchar *group;
+	gboolean is_mapi_source, is_online;
+
+	g_return_if_fail (E_IS_SHELL_VIEW (shell_view));
+	g_return_if_fail (entries != NULL);
+
+	if (strstr (entries->name, "calendar"))
+		group = "calendar";
+	else if (strstr (entries->name, "tasks"))
+		group = "tasks";
+	else if (strstr (entries->name, "memos"))
+		group = "memos";
+	else if (strstr (entries->name, "contacts"))
+		group = "contacts";
+	else
+		g_return_if_reached ();
+
+	is_mapi_source = get_selected_mapi_source (shell_view, NULL, NULL);
+	shell_window = e_shell_view_get_shell_window (shell_view);
+	shell = e_shell_window_get_shell (shell_window);
+
+	is_online = shell && e_shell_get_online (shell);
+	action_group = e_shell_window_get_action_group (shell_window, group);
+
+	mapi_ui_enable_actions (action_group, entries, MAPI_ESOURCE_NUM_ENTRIES, is_mapi_source, is_online);
+}
+
+static void
+setup_mapi_source_actions (EShellView *shell_view,
+			   GtkUIManager *ui_manager,
+			   GtkActionEntry *entries,
+			   guint n_entries)
+{
+	EShellWindow *shell_window;
+	const gchar *group;
+
+	g_return_if_fail (shell_view != NULL);
+	g_return_if_fail (ui_manager != NULL);
+	g_return_if_fail (entries != NULL);
+	g_return_if_fail (n_entries > 0);
+	g_return_if_fail (n_entries == MAPI_ESOURCE_NUM_ENTRIES);
+
+	if (strstr (entries->name, "calendar"))
+		group = "calendar";
+	else if (strstr (entries->name, "tasks"))
+		group = "tasks";
+	else if (strstr (entries->name, "memos"))
+		group = "memos";
+	else if (strstr (entries->name, "contacts"))
+		group = "contacts";
+	else
+		g_return_if_reached ();
+
+	shell_window = e_shell_view_get_shell_window (shell_view);
+
+	e_action_group_add_actions_localized (
+		e_shell_window_get_action_group (shell_window, group), GETTEXT_PACKAGE,
+		entries, MAPI_ESOURCE_NUM_ENTRIES, shell_view);
+
+	g_signal_connect (shell_view, "update-actions", G_CALLBACK (update_mapi_source_entries_cb), entries);
+}
+
+static void
+action_folder_permissions_source_cb (GtkAction *action,
+				     EShellView *shell_view)
+{
+	ESourceRegistry *registry = NULL;
+	ESource *source = NULL, *parent_source;
+	ESourceMapiFolder *folder_ext;
+	mapi_id_t folder_id = 0;
+	const gchar *foreign_username;
+	gboolean is_public;
+	ESourceCamel *extension;
+	CamelSettings *settings;
+	const gchar *extension_name;
+
+	g_return_if_fail (action != NULL);
+	g_return_if_fail (shell_view != NULL);
+	g_return_if_fail (get_selected_mapi_source (shell_view, &source, &registry));
+	g_return_if_fail (source != NULL);
+	g_return_if_fail (e_source_has_extension (source, E_SOURCE_EXTENSION_MAPI_FOLDER));
+	g_return_if_fail (gtk_action_get_name (action) != NULL);
+
+	folder_ext = e_source_get_extension (source, E_SOURCE_EXTENSION_MAPI_FOLDER);
+	folder_id = e_source_mapi_folder_get_id (folder_ext);
+	g_return_if_fail (folder_id != 0);
+
+	foreign_username = e_source_mapi_folder_get_foreign_username (folder_ext);
+	is_public = !foreign_username && e_source_mapi_folder_is_public (folder_ext);
+
+	parent_source = e_source_registry_ref_source (registry, e_source_get_parent (source));
+
+	extension_name = e_source_camel_get_extension_name ("mapi");
+	extension = e_source_get_extension (parent_source, extension_name);
+	settings = e_source_camel_get_settings (extension);
+
+	e_mapi_edit_folder_permissions (NULL,
+		registry,
+		source,
+		CAMEL_MAPI_SETTINGS (settings),
+		e_source_get_display_name (parent_source),
+		e_source_get_display_name (source),
+		folder_id,
+		foreign_username ? E_MAPI_FOLDER_CATEGORY_FOREIGN :
+		is_public ? E_MAPI_FOLDER_CATEGORY_PUBLIC :
+		E_MAPI_FOLDER_CATEGORY_PERSONAL,
+		foreign_username,
+		strstr (gtk_action_get_name (action), "calendar") != NULL);
+
+	g_object_unref (source);
+	g_object_unref (parent_source);
+	g_object_unref (registry);
+}
+
+static GtkActionEntry calendar_context_entries[] = {
+
+	{ "calendar-mapi-folder-permissions",
+	  "folder-new",
+	  N_("Permissions..."),
+	  NULL,
+	  N_("Edit MAPI calendar permissions"),
+	  G_CALLBACK (action_folder_permissions_source_cb) }
+};
+
+static const gchar *mapi_ui_cal_def =
+	"<popup name=\"calendar-popup\">\n"
+	"  <placeholder name=\"calendar-popup-actions\">\n"
+	"    <menuitem action=\"calendar-mapi-folder-permissions\"/>\n"
+	"  </placeholder>\n"
+	"</popup>\n";
+
+static void
+mapi_ui_init_calendar (GtkUIManager *ui_manager,
+		       EShellView *shell_view,
+		       gchar **ui_definition)
+{
+	g_return_if_fail (ui_definition != NULL);
+
+	*ui_definition = g_strdup (mapi_ui_cal_def);
+
+	setup_mapi_source_actions (shell_view, ui_manager,
+		calendar_context_entries, G_N_ELEMENTS (calendar_context_entries));
+}
+
+GtkActionEntry tasks_context_entries[] = {
+
+	{ "tasks-mapi-folder-permissions",
+	  "folder-new",
+	  N_("Permissions..."),
+	  NULL,
+	  N_("Edit MAPI tasks permissions"),
+	  G_CALLBACK (action_folder_permissions_source_cb) }
+};
+
+const gchar *mapi_ui_task_def =
+	"<popup name=\"task-list-popup\">\n"
+	"  <placeholder name=\"task-list-popup-actions\">\n"
+	"    <menuitem action=\"tasks-mapi-folder-permissions\"/>\n"
+	"  </placeholder>\n"
+	"</popup>\n";
+
+static void
+mapi_ui_init_tasks (GtkUIManager *ui_manager,
+		    EShellView *shell_view,
+		    gchar **ui_definition)
+{
+	g_return_if_fail (ui_definition != NULL);
+
+	*ui_definition = g_strdup (mapi_ui_task_def);
+
+	setup_mapi_source_actions (shell_view, ui_manager,
+		tasks_context_entries, G_N_ELEMENTS (tasks_context_entries));
+}
+
+static GtkActionEntry memos_context_entries[] = {
+
+	{ "memos-mapi-folder-permissions",
+	  "folder-new",
+	  N_("Permissions..."),
+	  NULL,
+	  N_("Edit MAPI memos permissions"),
+	  G_CALLBACK (action_folder_permissions_source_cb) }
+};
+
+const gchar *mapi_ui_memo_def =
+	"<popup name=\"memo-list-popup\">\n"
+	"  <placeholder name=\"memo-list-popup-actions\">\n"
+	"    <menuitem action=\"memos-mapi-folder-permissions\"/>\n"
+	"  </placeholder>\n"
+	"</popup>\n";
+
+static void
+mapi_ui_init_memos (GtkUIManager *ui_manager,
+		    EShellView *shell_view,
+		    gchar **ui_definition)
+{
+	g_return_if_fail (ui_definition != NULL);
+
+	*ui_definition = g_strdup (mapi_ui_memo_def);
+
+	setup_mapi_source_actions (shell_view, ui_manager,
+		memos_context_entries, G_N_ELEMENTS (memos_context_entries));
+}
+
+static GtkActionEntry contacts_context_entries[] = {
+
+	{ "contacts-mapi-folder-permissions",
+	  "folder-new",
+	  N_("Permissions..."),
+	  NULL,
+	  N_("Edit MAPI contacts permissions"),
+	  G_CALLBACK (action_folder_permissions_source_cb) }
+};
+
+const gchar *mapi_ui_book_def =
+	"<popup name=\"address-book-popup\">\n"
+	"  <placeholder name=\"address-book-popup-actions\">\n"
+	"    <menuitem action=\"contacts-mapi-folder-permissions\"/>\n"
+	"  </placeholder>\n"
+	"</popup>\n";
+
+static void
+mapi_ui_init_contacts (GtkUIManager *ui_manager,
+		       EShellView *shell_view,
+		       gchar **ui_definition)
+{
+	g_return_if_fail (ui_definition != NULL);
+
+	*ui_definition = g_strdup (mapi_ui_book_def);
+
+	setup_mapi_source_actions (shell_view, ui_manager,
+		contacts_context_entries, G_N_ELEMENTS (contacts_context_entries));
+}
+
+void
+e_mapi_config_utils_init_ui (EShellView *shell_view,
+			     const gchar *ui_manager_id,
+			     gchar **ui_definition)
+{
+	EShellWindow *shell_window;
+	GtkUIManager *ui_manager;
+
+	g_return_if_fail (shell_view != NULL);
+	g_return_if_fail (ui_manager_id != NULL);
+	g_return_if_fail (ui_definition != NULL);
+
+	shell_window = e_shell_view_get_shell_window (shell_view);
+	ui_manager = e_shell_window_get_ui_manager (shell_window);
+
+	if (g_strcmp0 (ui_manager_id, "org.gnome.evolution.mail") == 0)
+		mapi_ui_init_mail (ui_manager, shell_view, ui_definition);
+	else if (g_strcmp0 (ui_manager_id, "org.gnome.evolution.calendars") == 0)
+		mapi_ui_init_calendar (ui_manager, shell_view, ui_definition);
+	else if (g_strcmp0 (ui_manager_id, "org.gnome.evolution.tasks") == 0)
+		mapi_ui_init_tasks (ui_manager, shell_view, ui_definition);
+	else if (g_strcmp0 (ui_manager_id, "org.gnome.evolution.memos") == 0)
+		mapi_ui_init_memos (ui_manager, shell_view, ui_definition);
+	else if (g_strcmp0 (ui_manager_id, "org.gnome.evolution.contacts") == 0)
+		mapi_ui_init_contacts (ui_manager, shell_view, ui_definition);
+}
+
+gboolean
+e_mapi_config_utils_is_online (void)
+{
+	EShell *shell;
+
+	shell = e_shell_get_default ();
+
+	return shell && e_shell_get_online (shell);
+}
+
+GtkWindow *
+e_mapi_config_utils_get_widget_toplevel_window (GtkWidget *widget)
+{
+	if (!widget)
+		return NULL;
+
+	if (!GTK_IS_WINDOW (widget))
+		widget = gtk_widget_get_toplevel (widget);
+
+	if (GTK_IS_WINDOW (widget))
+		return GTK_WINDOW (widget);
+
+	return NULL;
+}
+
+enum {
+	NAME_COL,
+	FID_COL,
+	FOLDER_COL,
+	NUM_COLS
+};
+
+static gboolean
+check_node (GtkTreeStore *ts, EMapiFolder *folder, GtkTreeIter iter)
+{
+	GtkTreeModel *ts_model;
+	mapi_id_t fid;
+
+	ts_model = GTK_TREE_MODEL (ts);
+
+	gtk_tree_model_get (ts_model, &iter, 1, &fid, -1);
+	if (fid && folder->parent_folder_id == fid) {
+		/* Do something */
+		GtkTreeIter node;
+		gtk_tree_store_append (ts, &node, &iter);
+		gtk_tree_store_set (ts, &node, NAME_COL, folder->folder_name, FID_COL, folder->folder_id, FOLDER_COL, folder,-1);
+		return TRUE;
+	}
+
+	if (gtk_tree_model_iter_has_child (ts_model, &iter)) {
+		GtkTreeIter child;
+		gtk_tree_model_iter_children (ts_model, &child, &iter);
+		if (check_node (ts, folder, child))
+		    return TRUE;
+	}
+
+	if (gtk_tree_model_iter_next (ts_model, &iter)) {
+		return check_node (ts, folder, iter);
+	}
+
+	return FALSE;
+}
+
+static void
+add_to_store (GtkTreeStore *ts, EMapiFolder *folder)
+{
+	GtkTreeModel *ts_model;
+	GtkTreeIter iter;
+
+	ts_model = GTK_TREE_MODEL (ts);
+
+	g_return_if_fail (gtk_tree_model_get_iter_first (ts_model, &iter));
+	if (!check_node (ts, folder, iter)) {
+		GtkTreeIter node;
+		gtk_tree_store_append (ts, &node, &iter);
+		gtk_tree_store_set (ts, &node, NAME_COL, folder->folder_name, FID_COL, folder->folder_id, FOLDER_COL, folder, -1);
+	}
+}
+
+static void
+traverse_tree (GtkTreeModel *model, GtkTreeIter iter, EMapiFolderType folder_type, gboolean *pany_sub_used)
+{
+	gboolean any_sub_used = FALSE;
+	gboolean has_next = TRUE;
+
+	do {
+		gboolean sub_used = FALSE;
+		GtkTreeIter next = iter;
+		EMapiFolder *folder = NULL;
+
+		has_next = gtk_tree_model_iter_next (model, &next);
+
+		if (gtk_tree_model_iter_has_child (model, &iter)) {
+			GtkTreeIter child;
+
+			gtk_tree_model_iter_children (model, &child, &iter);
+			traverse_tree (model, child, folder_type, &sub_used);
+		}
+
+		gtk_tree_model_get (model, &iter, FOLDER_COL, &folder, -1);
+		if (folder && (e_mapi_folder_get_type (folder) == folder_type || (folder_type == E_MAPI_FOLDER_TYPE_MEMO && e_mapi_folder_get_type (folder) == E_MAPI_FOLDER_TYPE_JOURNAL))) {
+			sub_used = TRUE;
+		}
+
+		if (sub_used)
+			any_sub_used = TRUE;
+		else if (pany_sub_used && folder)
+			gtk_tree_store_remove (GTK_TREE_STORE (model), &iter);
+
+		iter = next;
+	} while (has_next);
+
+	if (pany_sub_used && any_sub_used)
+		*pany_sub_used = TRUE;
+}
+
+static void
+add_folders (GSList *folders, GtkTreeStore *ts, EMapiFolderType folder_type)
+{
+	GSList *tmp = folders;
+	GtkTreeIter iter;
+	GtkTreeModel *model = GTK_TREE_MODEL (ts);
+	gchar *node = _("Personal Folders");
+
+	/* add all... */
+	gtk_tree_store_append (ts, &iter, NULL);
+	gtk_tree_store_set (ts, &iter, NAME_COL, node, -1);
+	while (tmp) {
+		EMapiFolder *folder = tmp->data;
+		add_to_store (ts, folder);
+		tmp = tmp->next;
+	}
+
+	/* ... then remove those which don't belong to folder_type */
+	if (gtk_tree_model_get_iter_first (model, &iter)) {
+		traverse_tree (model, iter, folder_type, NULL);
+	}
+}
+
+static void
+select_folder (GtkTreeModel *model,
+	       mapi_id_t fid,
+	       GtkWidget *tree_view)
+{
+	GtkTreeIter iter, next;
+	gboolean found = FALSE, can = TRUE;
+
+	g_return_if_fail (model != NULL);
+	g_return_if_fail (tree_view != NULL);
+
+	if (!gtk_tree_model_get_iter_first (model, &iter))
+		return;
+
+	while (!found && can) {
+		EMapiFolder *folder = NULL;
+
+		gtk_tree_model_get (model, &iter, FOLDER_COL, &folder, -1);
+
+		if (folder && e_mapi_folder_get_id (folder) == fid) {
+			gtk_tree_selection_select_iter (gtk_tree_view_get_selection (GTK_TREE_VIEW (tree_view)), &iter);
+			found = TRUE;
+			break;
+		}
+
+		can = FALSE;
+		if (gtk_tree_model_iter_children (model, &next, &iter)) {
+			iter = next;
+			can = TRUE;
+		}
+
+		next = iter;
+		if (!can && gtk_tree_model_iter_next (model, &next)) {
+			iter = next;
+			can = TRUE;
+		}
+
+		if (!can && gtk_tree_model_iter_parent (model, &next, &iter)) {
+			while (!can) {
+				iter = next;
+
+				if (gtk_tree_model_iter_next (model, &iter)) {
+					can = TRUE;
+					break;
+				}
+
+				iter = next;
+				if (!gtk_tree_model_iter_parent (model, &next, &iter))
+					break;
+			}
+		}
+	}
+}
+
+static void
+e_mapi_cursor_change (GtkTreeView *treeview,
+		      ESource *source)
+{
+	ESourceMapiFolder *folder_ext;
+	GtkTreeSelection *selection;
+	GtkTreeModel *model;
+	GtkTreeIter iter;
+	mapi_id_t pfid;
+
+	selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview));
+	if (!selection)
+		return;
+
+	if (gtk_tree_selection_get_selected (selection, &model, &iter)) {
+		gtk_tree_model_get (model, &iter, FID_COL, &pfid, -1);
+	} else {
+		pfid = 0;
+	}
+
+	folder_ext = e_source_get_extension (source, E_SOURCE_EXTENSION_MAPI_FOLDER);
+	e_source_mapi_folder_set_parent_id (folder_ext, pfid);
+}
+
+struct EMapiFolderStructureData
+{
+	EMapiFolderType folder_type;
+	GSList *folders;
+	GtkWidget *tree_view;
+	ESource *source;
+	ESource *child_source;
+	ESourceRegistry *registry;
+};
+
+static void
+e_mapi_folder_structure_data_free (gpointer ptr)
+{
+	struct EMapiFolderStructureData *fsd = ptr;
+
+	if (!fsd)
+		return;
+
+	e_mapi_folder_free_list (fsd->folders);
+	g_object_unref (fsd->tree_view);
+	g_object_unref (fsd->source);
+	g_object_unref (fsd->child_source);
+	g_object_unref (fsd->registry);
+	g_free (fsd);
+}
+
+static void
+e_mapi_download_folder_structure_idle (GObject *source_obj,
+				       gpointer user_data,
+				       GCancellable *cancellable,
+				       GError **perror)
+{
+	struct EMapiFolderStructureData *fsd = user_data;
+	ESourceMapiFolder *folder_ext;
+	GtkTreeStore *tree_store;
+
+	g_return_if_fail (fsd != NULL);
+	g_return_if_fail (fsd->tree_view != NULL);
+	g_return_if_fail (source_obj != NULL);
+	g_return_if_fail (E_IS_SOURCE (source_obj));
+
+	tree_store = GTK_TREE_STORE (gtk_tree_view_get_model (GTK_TREE_VIEW (fsd->tree_view)));
+	g_return_if_fail (tree_store != NULL);
+
+	add_folders (fsd->folders, tree_store, fsd->folder_type);
+	gtk_tree_view_expand_all (GTK_TREE_VIEW (fsd->tree_view));
+
+	folder_ext = e_source_get_extension (fsd->child_source, E_SOURCE_EXTENSION_MAPI_FOLDER);
+	if (e_source_mapi_folder_get_id (folder_ext)) {
+		select_folder (GTK_TREE_MODEL (tree_store),
+			e_source_mapi_folder_get_id (folder_ext),
+			fsd->tree_view);
+	}
+}
+
+static void
+e_mapi_download_folder_structure_thread (GObject *source_obj,
+					 gpointer user_data,
+					 GCancellable *cancellable,
+					 GError **perror)
+{
+	struct EMapiFolderStructureData *fsd = user_data;
+	const gchar *extension_name;
+	ESource *source;
+	ESourceCamel *extension;
+	EMapiConnection *conn;
+	CamelSettings *settings;
+	CamelMapiSettings *mapi_settings;
+
+	g_return_if_fail (fsd != NULL);
+	g_return_if_fail (fsd->tree_view != NULL);
+	g_return_if_fail (source_obj != NULL);
+	g_return_if_fail (E_IS_SOURCE (source_obj));
+
+	source = E_SOURCE (source_obj);
+
+	extension_name = e_source_camel_get_extension_name ("mapi");
+	g_return_if_fail (e_source_has_extension (source, extension_name));
+
+	extension = e_source_get_extension (source, extension_name);
+	settings = e_source_camel_get_settings (extension);
+	mapi_settings = CAMEL_MAPI_SETTINGS (settings);
+
+	conn = e_mapi_config_utils_open_connection_for (NULL,
+		fsd->registry,
+		source,
+		mapi_settings,
+		cancellable,
+		perror);
+
+	if (!conn)
+		return;
+
+	if (conn && e_mapi_connection_connected (conn)) {
+		fsd->folders = e_mapi_connection_peek_folders_list (conn);
+		if (fsd->folders)
+			fsd->folders = e_mapi_folder_copy_list (fsd->folders);
+	}
+
+	if (conn)
+		g_object_unref (conn);
+}
+
+static gboolean
+e_mapi_invoke_folder_structure_download_idle (gpointer user_data)
+{
+	struct EMapiFolderStructureData *fsd = user_data;
+
+	g_return_val_if_fail (fsd != NULL, FALSE);
+
+	e_mapi_config_utils_run_in_thread_with_feedback (e_mapi_config_utils_get_widget_toplevel_window (fsd->tree_view),
+		G_OBJECT (fsd->source),
+		_("Searching remote MAPI folder structure, please wait..."),
+		e_mapi_download_folder_structure_thread,
+		e_mapi_download_folder_structure_idle,
+		fsd,
+		e_mapi_folder_structure_data_free);
+
+	return FALSE;
+}
+
+void
+e_mapi_config_utils_insert_widgets (ESourceConfigBackend *backend,
+				    ESource *scratch_source)
+{
+	ESourceBackend *backend_ext = NULL;
+	ESourceMapiFolder *folder_ext;
+	ESourceConfig *config;
+	GtkWidget *widget;
+	gboolean is_new_source;
+	EMapiFolderType folder_type = E_MAPI_FOLDER_TYPE_UNKNOWN;
+
+	g_return_if_fail (backend != NULL);
+	g_return_if_fail (scratch_source != NULL);
+
+	if (e_source_has_extension (scratch_source, E_SOURCE_EXTENSION_ADDRESS_BOOK)) {
+		backend_ext = e_source_get_extension (scratch_source, E_SOURCE_EXTENSION_ADDRESS_BOOK);
+		folder_type = E_MAPI_FOLDER_TYPE_CONTACT;
+	} else if (e_source_has_extension (scratch_source, E_SOURCE_EXTENSION_CALENDAR)) {
+		backend_ext = e_source_get_extension (scratch_source, E_SOURCE_EXTENSION_CALENDAR);
+		folder_type = E_MAPI_FOLDER_TYPE_APPOINTMENT;
+	} else if (e_source_has_extension (scratch_source, E_SOURCE_EXTENSION_TASK_LIST)) {
+		backend_ext = e_source_get_extension (scratch_source, E_SOURCE_EXTENSION_TASK_LIST);
+		folder_type = E_MAPI_FOLDER_TYPE_TASK;
+	} else if (e_source_has_extension (scratch_source, E_SOURCE_EXTENSION_MEMO_LIST)) {
+		backend_ext = e_source_get_extension (scratch_source, E_SOURCE_EXTENSION_MEMO_LIST);
+		folder_type = E_MAPI_FOLDER_TYPE_MEMO;
+	}
+
+	if (!backend_ext || g_strcmp0 (e_source_backend_get_backend_name (backend_ext), "mapi") != 0)
+		return;
+
+	folder_ext = e_source_get_extension (scratch_source, E_SOURCE_EXTENSION_MAPI_FOLDER);
+	g_return_if_fail (folder_ext != NULL);
+
+	config = e_source_config_backend_get_config (backend);
+	if (E_IS_BOOK_SOURCE_CONFIG (config))
+		e_book_source_config_add_offline_toggle (E_BOOK_SOURCE_CONFIG (config), scratch_source);
+	else if (E_IS_CAL_SOURCE_CONFIG (config))
+		e_cal_source_config_add_offline_toggle (E_CAL_SOURCE_CONFIG (config), scratch_source);
+
+	widget = gtk_check_button_new_with_mnemonic (_("Lis_ten for server notifications"));
+	e_source_config_insert_widget (config, scratch_source, NULL, widget);
+	gtk_widget_show (widget);
+
+	g_object_bind_property (
+		folder_ext, "server-notification",
+		widget, "active",
+		G_BINDING_BIDIRECTIONAL |
+		G_BINDING_SYNC_CREATE);
+
+	/* no extra options for subscribed folders */
+	if (e_source_mapi_folder_is_public (folder_ext) ||
+	    e_source_mapi_folder_get_foreign_username (folder_ext))
+		return;
+
+	is_new_source = e_source_mapi_folder_get_id (folder_ext) == 0;
+	if (is_new_source && !e_mapi_config_utils_is_online ()) {
+		const gchar *msg;
+
+		switch (folder_type) {
+		case E_MAPI_FOLDER_TYPE_APPOINTMENT:
+			msg = _("Cannot create MAPI calendar in offline mode");
+			break;
+		case E_MAPI_FOLDER_TYPE_TASK:
+			msg = _("Cannot create MAPI task list in offline mode");
+			break;
+		case E_MAPI_FOLDER_TYPE_MEMO:
+			msg = _("Cannot create MAPI memo list in offline mode");
+			break;
+		case E_MAPI_FOLDER_TYPE_CONTACT:
+			msg = _("Cannot create MAPI address book in offline mode");
+			break;
+		default:
+			g_warn_if_reached ();
+			msg = _("Cannot create MAPI source in offline mode");
+			break;
+		}
+
+		widget = gtk_label_new (msg);
+		gtk_widget_show (widget);
+		gtk_misc_set_alignment (GTK_MISC (widget), 0.0, 0.5);
+
+		e_source_config_insert_widget (config, scratch_source, NULL, widget);
+	} else {
+		GtkGrid *content_grid;
+		GtkCellRenderer *renderer;
+		GtkTreeViewColumn *column;
+		GtkTreeStore *tree_store;
+		GtkWidget *tree_view, *scrolled_window;
+		ESource *parent_source;
+
+		content_grid = GTK_GRID (gtk_grid_new ());
+		gtk_grid_set_row_spacing (content_grid, 2);
+		gtk_grid_set_column_spacing (content_grid, 6);
+
+		widget = gtk_label_new_with_mnemonic (_("_Location:"));
+		gtk_misc_set_alignment (GTK_MISC (widget), 0.0, 0.5);
+		gtk_widget_set_hexpand (widget, TRUE);
+		gtk_grid_attach (content_grid, widget, 0, 0, 1, 1);
+
+		tree_store = gtk_tree_store_new (NUM_COLS, G_TYPE_STRING, G_TYPE_UINT64, G_TYPE_POINTER);
+
+		parent_source = e_source_config_get_collection_source (config);
+		renderer = gtk_cell_renderer_text_new ();
+		column = gtk_tree_view_column_new_with_attributes (e_source_get_display_name (parent_source), renderer, "text", NAME_COL, NULL);
+		tree_view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (tree_store));
+		gtk_tree_view_append_column (GTK_TREE_VIEW (tree_view), column);
+		g_object_set (tree_view, "expander-column", column, "headers-visible", TRUE, NULL);
+		gtk_widget_set_sensitive (tree_view, is_new_source);
+
+		scrolled_window = gtk_scrolled_window_new (NULL, NULL);
+		gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+		gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolled_window), GTK_SHADOW_IN);
+		g_object_set (scrolled_window, "height-request", 150, NULL);
+		gtk_container_add (GTK_CONTAINER (scrolled_window), tree_view);
+		gtk_label_set_mnemonic_widget (GTK_LABEL (widget), scrolled_window);
+		g_signal_connect (G_OBJECT (tree_view), "cursor-changed", G_CALLBACK (e_mapi_cursor_change), scratch_source);
+		gtk_widget_show_all (scrolled_window);
+
+		gtk_grid_attach (content_grid, scrolled_window, 0, 1, 1, 1);
+
+		if (e_mapi_config_utils_is_online ()) {
+			struct EMapiFolderStructureData *fsd;
+
+			fsd = g_new0 (struct EMapiFolderStructureData, 1);
+			fsd->folder_type = folder_type;
+			fsd->folders = NULL;
+			fsd->tree_view = g_object_ref (tree_view);
+			fsd->source = g_object_ref (parent_source);
+			fsd->child_source = g_object_ref (scratch_source);
+			fsd->registry = g_object_ref (e_source_config_get_registry (config));
+
+			g_idle_add (e_mapi_invoke_folder_structure_download_idle, fsd);
+		}
+
+		gtk_widget_set_hexpand (GTK_WIDGET (content_grid), TRUE);
+		gtk_widget_set_vexpand (GTK_WIDGET (content_grid), TRUE);
+		gtk_widget_show_all (GTK_WIDGET (content_grid));
+
+		e_source_config_insert_widget (config, scratch_source, NULL, GTK_WIDGET (content_grid));
+	}
+}
diff --git a/src/configuration/e-mapi-config-utils.h b/src/configuration/e-mapi-config-utils.h
new file mode 100644
index 0000000..f119749
--- /dev/null
+++ b/src/configuration/e-mapi-config-utils.h
@@ -0,0 +1,74 @@
+/*
+ * e-mapi-config-utils.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 E_MAPI_CONFIG_UTILS_H
+#define E_MAPI_CONFIG_UTILS_H
+
+#include <gtk/gtk.h>
+
+#include <shell/e-shell-view.h>
+#include <misc/e-source-config.h>
+#include <misc/e-source-config-backend.h>
+
+#include "e-mapi-connection.h"
+#include "camel-mapi-settings.h"
+
+typedef void		(* EMapiSetupFunc)					(GObject *with_object,
+										 gpointer user_data,
+										 GCancellable *cancellable,
+										 GError **perror);
+
+void			e_mapi_config_utils_run_in_thread_with_feedback		(GtkWindow *parent,
+										 GObject *with_object,
+										 const gchar *description,
+										 EMapiSetupFunc thread_func,
+										 EMapiSetupFunc idle_func,
+										 gpointer user_data,
+										 GDestroyNotify free_user_data);
+
+void			e_mapi_config_utils_run_in_thread_with_feedback_modal	(GtkWindow *parent,
+										 GObject *with_object,
+										 const gchar *description,
+										 EMapiSetupFunc thread_func,
+										 EMapiSetupFunc idle_func,
+										 gpointer user_data,
+										 GDestroyNotify free_user_data);
+
+EMapiConnection	*	e_mapi_config_utils_open_connection_for			(GtkWindow *parent,
+										 ESourceRegistry *registry,
+										 ESource *source,
+										 CamelMapiSettings *mapi_settings,
+										 GCancellable *cancellable,
+										 GError **perror);
+
+void			e_mapi_config_utils_run_folder_size_dialog		(ESourceRegistry *registry,
+										 ESource *source,
+										 CamelMapiSettings *mapi_settings);
+
+void			e_mapi_config_utils_init_ui				(EShellView *shell_view,
+										 const gchar *ui_manager_id,
+										 gchar **ui_definition);
+
+gboolean		e_mapi_config_utils_is_online				(void);
+
+GtkWindow *		e_mapi_config_utils_get_widget_toplevel_window		(GtkWidget *widget);
+
+void			e_mapi_config_utils_insert_widgets			(ESourceConfigBackend *backend,
+										 ESource *scratch_source);
+
+#endif /* E_MAPI_CONFIG_UTILS */
diff --git a/src/account-setup-eplugin/e-mapi-edit-folder-permissions.c b/src/configuration/e-mapi-edit-folder-permissions.c
similarity index 97%
rename from src/account-setup-eplugin/e-mapi-edit-folder-permissions.c
rename to src/configuration/e-mapi-edit-folder-permissions.c
index 8c8ef73..0c7d41d 100644
--- a/src/account-setup-eplugin/e-mapi-edit-folder-permissions.c
+++ b/src/configuration/e-mapi-edit-folder-permissions.c
@@ -28,7 +28,7 @@
 #include <glib/gi18n-lib.h>
 #include <gtk/gtk.h>
 
-#include "e-mapi-account-setup.h"
+#include "e-mapi-config-utils.h"
 #include "e-mapi-edit-folder-permissions.h"
 #include "e-mapi-search-gal-user.h"
 #include "e-mapi-utils.h"
@@ -45,9 +45,9 @@ enum {
 
 struct EMapiPermissionsDialogWidgets
 {
-	gchar *login_profile;
-	gchar *login_username;
-	gchar *login_url;
+	ESourceRegistry *registry;
+	ESource *source;
+	CamelMapiSettings *mapi_settings;
 	mapi_id_t folder_id;
 	EMapiFolderCategory folder_category;
 	gchar *foreign_username;
@@ -149,9 +149,9 @@ edit_permissions_widgets_free (gpointer ptr)
 	if (!widgets)
 		return;
 
-	g_free (widgets->login_profile);
-	g_free (widgets->login_username);
-	g_free (widgets->login_url);
+	g_object_unref (widgets->registry);
+	g_object_unref (widgets->source);
+	g_object_unref (widgets->mapi_settings);
 	g_free (widgets->foreign_username);
 	if (widgets->conn)
 		e_mapi_utils_unref_in_thread (G_OBJECT (widgets->conn));
@@ -270,7 +270,7 @@ edit_permissions_response_cb (GObject *dialog,
 		write_entries = g_slist_reverse (write_entries);
 	}
 
-	e_mapi_run_in_thread_with_feedback (GTK_WINDOW (dialog), dialog,
+	e_mapi_config_utils_run_in_thread_with_feedback (GTK_WINDOW (dialog), dialog,
 		_("Writing folder permissions, please wait..."),
 		write_folder_permissions_thread,
 		write_folder_permissions_idle,
@@ -705,14 +705,14 @@ read_folder_permissions_thread (GObject *dialog,
 
 	widgets = g_object_get_data (dialog, E_MAPI_PERM_DLG_WIDGETS);
 	g_return_if_fail (widgets != NULL);
-	g_return_if_fail (widgets->login_profile != NULL);
-	g_return_if_fail (widgets->login_username != NULL);
-	g_return_if_fail (widgets->login_url != NULL);
-
-	widgets->conn = e_mapi_account_open_connection_for (GTK_WINDOW (dialog),
-		widgets->login_profile,
-		widgets->login_username,
-		widgets->login_url,
+	g_return_if_fail (widgets->registry != NULL);
+	g_return_if_fail (widgets->source != NULL);
+	g_return_if_fail (widgets->mapi_settings != NULL);
+
+	widgets->conn = e_mapi_config_utils_open_connection_for (GTK_WINDOW (dialog),
+		widgets->registry,
+		widgets->source,
+		widgets->mapi_settings,
 		cancellable,
 		perror);
 
@@ -894,9 +894,9 @@ create_permissions_tree_view (GObject *dialog,
    users in the given store */
 void
 e_mapi_edit_folder_permissions (GtkWindow *parent,
-				const gchar *login_profile,
-				const gchar *login_username,
-				const gchar *login_url,
+				ESourceRegistry *registry,
+				ESource *source,
+				CamelMapiSettings *mapi_settings,
 				const gchar *account_name,
 				const gchar *folder_name,
 				mapi_id_t folder_id,
@@ -916,17 +916,17 @@ e_mapi_edit_folder_permissions (GtkWindow *parent,
 	gchar *str;
 	gint row, ii;
 
-	g_return_if_fail (login_profile != NULL);
-	g_return_if_fail (login_username != NULL);
-	g_return_if_fail (login_url != NULL);
+	g_return_if_fail (registry != NULL);
+	g_return_if_fail (source != NULL);
+	g_return_if_fail (mapi_settings != NULL);
 	g_return_if_fail (account_name != NULL);
 	g_return_if_fail (folder_name != NULL);
 	g_return_if_fail (folder_id != 0);
 
 	widgets = g_new0 (struct EMapiPermissionsDialogWidgets, 1);
-	widgets->login_profile = g_strdup (login_profile);
-	widgets->login_username = g_strdup (login_username);
-	widgets->login_url = g_strdup (login_url);
+	widgets->registry = g_object_ref (registry);
+	widgets->source = g_object_ref (source);
+	widgets->mapi_settings = g_object_ref (mapi_settings);
 	widgets->folder_id = folder_id;
 	widgets->folder_category = folder_category;
 	widgets->foreign_username = g_strdup (foreign_username);
@@ -1275,7 +1275,7 @@ e_mapi_edit_folder_permissions (GtkWindow *parent,
 
 	found_entries = g_new0 (GSList *, 1);
 
-	e_mapi_run_in_thread_with_feedback (GTK_WINDOW (dialog), dialog,
+	e_mapi_config_utils_run_in_thread_with_feedback (GTK_WINDOW (dialog), dialog,
 		_("Reading folder permissions, please wait..."),
 		read_folder_permissions_thread,
 		read_folder_permissions_idle,
diff --git a/src/account-setup-eplugin/e-mapi-edit-folder-permissions.h b/src/configuration/e-mapi-edit-folder-permissions.h
similarity index 86%
rename from src/account-setup-eplugin/e-mapi-edit-folder-permissions.h
rename to src/configuration/e-mapi-edit-folder-permissions.h
index 8e9d613..3927bdb 100644
--- a/src/account-setup-eplugin/e-mapi-edit-folder-permissions.h
+++ b/src/configuration/e-mapi-edit-folder-permissions.h
@@ -26,13 +26,15 @@
 
 #include <gtk/gtk.h>
 #include <libmapi/libmapi.h>
+#include <libedataserver/libedataserver.h>
 
-#include <e-mapi-folder.h>
+#include "e-mapi-folder.h"
+#include "camel-mapi-settings.h"
 
 void	e_mapi_edit_folder_permissions	(GtkWindow *parent,
-					 const gchar *login_profile,
-					 const gchar *login_username,
-					 const gchar *login_url,
+					 ESourceRegistry *registry,
+					 ESource *source,
+					 CamelMapiSettings *mapi_settings,
 					 const gchar *account_name,
 					 const gchar *folder_name,
 					 mapi_id_t folder_id,
diff --git a/src/account-setup-eplugin/e-mapi-search-gal-user.c b/src/configuration/e-mapi-search-gal-user.c
similarity index 99%
rename from src/account-setup-eplugin/e-mapi-search-gal-user.c
rename to src/configuration/e-mapi-search-gal-user.c
index 2cc6044..c09007b 100644
--- a/src/account-setup-eplugin/e-mapi-search-gal-user.c
+++ b/src/configuration/e-mapi-search-gal-user.c
@@ -28,7 +28,7 @@
 #include <glib/gi18n-lib.h>
 #include <gtk/gtk.h>
 
-#include "e-mapi-account-setup.h"
+#include "e-mapi-config-utils.h"
 #include "e-mapi-search-gal-user.h"
 #include "e-mapi-utils.h"
 #include "e-mapi-defs.h"
diff --git a/src/account-setup-eplugin/e-mapi-search-gal-user.h b/src/configuration/e-mapi-search-gal-user.h
similarity index 100%
rename from src/account-setup-eplugin/e-mapi-search-gal-user.h
rename to src/configuration/e-mapi-search-gal-user.h
diff --git a/src/account-setup-eplugin/e-mapi-subscribe-foreign-folder.c b/src/configuration/e-mapi-subscribe-foreign-folder.c
similarity index 96%
rename from src/account-setup-eplugin/e-mapi-subscribe-foreign-folder.c
rename to src/configuration/e-mapi-subscribe-foreign-folder.c
index e382295..ff77e62 100644
--- a/src/account-setup-eplugin/e-mapi-subscribe-foreign-folder.c
+++ b/src/configuration/e-mapi-subscribe-foreign-folder.c
@@ -28,12 +28,13 @@
 #include <glib/gi18n-lib.h>
 #include <gtk/gtk.h>
 
-#include <libedataserverui/e-name-selector.h>
+#include <libedataserverui/libedataserverui.h>
+#include <libemail-engine/e-mail-session.h>
 
 #include "camel/camel-mapi-store.h"
 #include "camel/camel-mapi-store-summary.h"
 
-#include "e-mapi-account-setup.h"
+#include "e-mapi-config-utils.h"
 #include "e-mapi-search-gal-user.h"
 #include "e-mapi-subscribe-foreign-folder.h"
 #include "e-mapi-utils.h"
@@ -366,12 +367,13 @@ check_foreign_folder_idle (GObject *with_object,
 			   GError **perror)
 {
 	struct EMapiCheckForeignFolderData *cffd = user_data;
-	gchar *fid, *folder_name;
+	gchar *folder_name;
 	const gchar *base_username, *base_foldername;
 	CamelSettings *settings;
 	CamelMapiSettings *mapi_settings;
 	CamelMapiStore *mapi_store;
-	CamelNetworkSettings *network_settings;
+	ESourceRegistry *registry = NULL;
+	CamelSession *session;
 	EMapiFolderType folder_type;
 
 	g_return_if_fail (with_object != NULL);
@@ -383,9 +385,6 @@ check_foreign_folder_idle (GObject *with_object,
 	if (!cffd->folder_id)
 		return;
 
-	fid = e_mapi_util_mapi_id_to_string (cffd->folder_id);
-	g_return_if_fail (fid != NULL);
-
 	base_username = cffd->user_displayname ? cffd->user_displayname : cffd->username;
 	base_foldername = cffd->folder_displayname ? cffd->folder_displayname : cffd->orig_foldername;
 
@@ -399,7 +398,9 @@ check_foreign_folder_idle (GObject *with_object,
 	mapi_store = CAMEL_MAPI_STORE (with_object);
 	settings = camel_service_get_settings (CAMEL_SERVICE (mapi_store));
 	mapi_settings = CAMEL_MAPI_SETTINGS (settings);
-	network_settings = CAMEL_NETWORK_SETTINGS (settings);
+	session = camel_service_get_session (CAMEL_SERVICE (mapi_store));
+	if (E_IS_MAIL_SESSION (session))
+		registry = e_mail_session_get_registry (E_MAIL_SESSION (session));
 
 	folder_type = e_mapi_folder_type_from_string (cffd->folder_container_class);
 	if ((folder_type == E_MAPI_FOLDER_TYPE_MAIL &&
@@ -410,25 +411,22 @@ check_foreign_folder_idle (GObject *with_object,
 		base_username,
 		base_foldername,
 		perror)) ||
-	    (folder_type != E_MAPI_FOLDER_TYPE_MAIL && !e_mapi_folder_add_as_esource (folder_type,
+	    (folder_type != E_MAPI_FOLDER_TYPE_MAIL && !e_mapi_folder_add_as_esource (registry,
+		folder_type,
 		camel_mapi_settings_get_profile (mapi_settings),
-		camel_mapi_settings_get_domain (mapi_settings),
-		camel_mapi_settings_get_realm (mapi_settings),
-		camel_network_settings_get_host (network_settings),
-		camel_network_settings_get_user (network_settings),
-		camel_mapi_settings_get_kerberos (mapi_settings),
 		TRUE /* camel_offline_settings_get_stay_synchronized (CAMEL_OFFLINE_SETTINGS (mapi_settings)) */,
 		E_MAPI_FOLDER_CATEGORY_FOREIGN,
 		cffd->username,
 		folder_name,
-		fid,
+		cffd->folder_id,
+		0,
+		cancellable,
 		perror))) {
 		/* to not destroy the dialog on error */
 		cffd->folder_id = 0;
 	}
 
 	g_free (folder_name);
-	g_free (fid);
 }
 
 static void
@@ -508,7 +506,7 @@ subscribe_foreign_response_cb (GObject *dialog,
 
 	description = g_strdup_printf (_("Testing availability of folder '%s' of user '%s', please wait..."), cffd->orig_foldername, cffd->username);
 
-	e_mapi_run_in_thread_with_feedback (
+	e_mapi_config_utils_run_in_thread_with_feedback (
 		GTK_WINDOW (dialog),
 		G_OBJECT (cstore),
 		description,
@@ -629,7 +627,7 @@ e_mapi_subscribe_foreign_folder (GtkWindow *parent,
 
 	row++;
 
-	name_selector = e_name_selector_new ();
+	name_selector = e_name_selector_new (e_mail_session_get_registry (E_MAIL_SESSION (session)));
 	name_selector_model = e_name_selector_peek_model (name_selector);
 	e_name_selector_model_add_section (name_selector_model, "User", _("User"), NULL);
 	name_selector_dialog = e_name_selector_peek_dialog (name_selector);
diff --git a/src/account-setup-eplugin/e-mapi-subscribe-foreign-folder.h b/src/configuration/e-mapi-subscribe-foreign-folder.h
similarity index 100%
rename from src/account-setup-eplugin/e-mapi-subscribe-foreign-folder.h
rename to src/configuration/e-mapi-subscribe-foreign-folder.h
diff --git a/src/configuration/module-mapi-configuration.c b/src/configuration/module-mapi-configuration.c
new file mode 100644
index 0000000..0709493
--- /dev/null
+++ b/src/configuration/module-mapi-configuration.c
@@ -0,0 +1,49 @@
+/*
+ * module-mapi-mail-config.c
+ *
+ * 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/>
+ *
+ */
+
+#include "e-book-config-mapi.h"
+#include "e-book-config-mapigal.h"
+#include "e-cal-config-mapi.h"
+#include "e-mail-config-mapi-backend.h"
+#include "e-mail-config-mapi-page.h"
+#include "e-mail-config-mapi-extension.h"
+#include "e-mapi-config-ui-extension.h"
+#include "e-source-mapi-folder.h"
+
+/* Module Entry Points */
+void e_module_load (GTypeModule *type_module);
+void e_module_unload (GTypeModule *type_module);
+
+G_MODULE_EXPORT void
+e_module_load (GTypeModule *type_module)
+{
+	e_book_config_mapi_type_register (type_module);
+	e_book_config_mapigal_type_register (type_module);
+	e_cal_config_mapi_type_register (type_module);
+	e_mail_config_mapi_backend_type_register (type_module);
+	e_mail_config_mapi_page_type_register (type_module);
+	e_mail_config_mapi_extension_type_register (type_module);
+	e_mapi_config_ui_extension_type_register (type_module);
+
+	e_source_mapi_folder_type_register (type_module);
+}
+
+G_MODULE_EXPORT void
+e_module_unload (GTypeModule *type_module)
+{
+}
diff --git a/src/libexchangemapi/Makefile.am b/src/libexchangemapi/Makefile.am
index 4786f8c..d6efaba 100644
--- a/src/libexchangemapi/Makefile.am
+++ b/src/libexchangemapi/Makefile.am
@@ -42,7 +42,9 @@ libexchangemapi_1_0_la_SOURCES =	\
 	e-mapi-mail-utils.c		\
 	e-mapi-mail-utils.h		\
 	e-mapi-operation-queue.c	\
-	e-mapi-operation-queue.h
+	e-mapi-operation-queue.h	\
+	e-source-mapi-folder.c		\
+	e-source-mapi-folder.h
 
 
 libexchangemapi_1_0_la_LIBADD =			\
diff --git a/src/libexchangemapi/e-mapi-book-utils.c b/src/libexchangemapi/e-mapi-book-utils.c
index 476d8d4..6ca91d4 100644
--- a/src/libexchangemapi/e-mapi-book-utils.c
+++ b/src/libexchangemapi/e-mapi-book-utils.c
@@ -22,7 +22,7 @@
 #include <config.h>
 #endif
 
-#include <libedataserver/e-sexp.h>
+#include <libedataserver/libedataserver.h>
 
 #include "e-mapi-book-utils.h"
 
diff --git a/src/libexchangemapi/e-mapi-book-utils.h b/src/libexchangemapi/e-mapi-book-utils.h
index 6ec2d9c..b01d479 100644
--- a/src/libexchangemapi/e-mapi-book-utils.h
+++ b/src/libexchangemapi/e-mapi-book-utils.h
@@ -21,7 +21,7 @@
 #ifndef E_MAPI_BOOK_UTILS_H
 #define E_MAPI_BOOK_UTILS_H
 
-#include <libebook/e-contact.h>
+#include <libebook/libebook.h>
 
 #include <e-mapi-connection.h>
 #include <e-mapi-defs.h>
diff --git a/src/libexchangemapi/e-mapi-cal-recur-utils.c b/src/libexchangemapi/e-mapi-cal-recur-utils.c
index 9e1f7b4..250f643 100644
--- a/src/libexchangemapi/e-mapi-cal-recur-utils.c
+++ b/src/libexchangemapi/e-mapi-cal-recur-utils.c
@@ -25,8 +25,9 @@
 #include <config.h>
 #endif
 
+#include <libecal/libecal.h>
+
 #include "e-mapi-cal-recur-utils.h"
-#include <libecal/e-cal-util.h>
 
 /* Reader/Writer versions */
 #define READER_VERSION	0x3004
diff --git a/src/libexchangemapi/e-mapi-cal-tz-utils.c b/src/libexchangemapi/e-mapi-cal-tz-utils.c
index 689311d..af091eb 100644
--- a/src/libexchangemapi/e-mapi-cal-tz-utils.c
+++ b/src/libexchangemapi/e-mapi-cal-tz-utils.c
@@ -81,8 +81,8 @@ e_mapi_cal_tz_util_get_ical_equivalent (const gchar *mapi_tz_location)
 }
 
 static struct icaltimetype
-tm_to_icaltimetype (struct tm *tm,
-		    gboolean dst)
+e_mapi_tm_to_icaltimetype (struct tm *tm,
+			   gboolean dst)
 {
 	struct icaltimetype itt;
 
@@ -112,7 +112,7 @@ get_offset (icaltimezone *zone,
 	time_t now = time (NULL);
 
 	gmtime_r (&now, &local);
-	tt = tm_to_icaltimetype (&local, dst);
+	tt = e_mapi_tm_to_icaltimetype (&local, dst);
 	offset = icaltimezone_get_utc_offset (zone, &tt, NULL);
 
 	return offset / -60;
diff --git a/src/libexchangemapi/e-mapi-cal-utils.c b/src/libexchangemapi/e-mapi-cal-utils.c
index 2abf26f..e756537 100644
--- a/src/libexchangemapi/e-mapi-cal-utils.c
+++ b/src/libexchangemapi/e-mapi-cal-utils.c
@@ -27,9 +27,8 @@
 
 #include <glib/gstdio.h>
 #include <glib/gi18n-lib.h>
-#include <fcntl.h>
-#include <libecal/e-cal-util.h>
-#include <libedataserver/e-data-server-util.h>
+#include <libecal/libecal.h>
+#include <libedataserver/libedataserver.h>
 
 #include "e-mapi-mail-utils.h"
 #include "e-mapi-cal-utils.h"
diff --git a/src/libexchangemapi/e-mapi-cal-utils.h b/src/libexchangemapi/e-mapi-cal-utils.h
index d4f056f..ae536cf 100644
--- a/src/libexchangemapi/e-mapi-cal-utils.h
+++ b/src/libexchangemapi/e-mapi-cal-utils.h
@@ -24,7 +24,7 @@
 #ifndef E_MAPI_CAL_UTILS_H
 #define E_MAPI_CAL_UTILS_H
 
-#include <libecal/e-cal-component.h>
+#include <libecal/libecal.h>
 
 #include "e-mapi-connection.h"
 #include "e-mapi-defs.h"
diff --git a/src/libexchangemapi/e-mapi-connection.c b/src/libexchangemapi/e-mapi-connection.c
index b18d8a1..c5c241a 100644
--- a/src/libexchangemapi/e-mapi-connection.c
+++ b/src/libexchangemapi/e-mapi-connection.c
@@ -28,10 +28,7 @@
 
 #include <glib/gi18n-lib.h>
 #include <camel/camel.h>
-#include <libedataserver/e-account.h>
-#include <libedataserver/e-account-list.h>
-#include <libedataserver/e-data-server-util.h>
-#include <libedataserver/e-flag.h>
+#include <libedataserver/libedataserver.h>
 
 #include <tevent.h>
 
@@ -52,7 +49,7 @@
 static void register_connection (EMapiConnection *conn);
 static void unregister_connection (EMapiConnection *conn);
 static gboolean mapi_profile_create (struct mapi_context *mapi_ctx, const EMapiProfileData *empd, mapi_profile_callback_t callback, gconstpointer data, GCancellable *cancellable, GError **perror, gboolean use_locking);
-static struct mapi_session *mapi_profile_load (struct mapi_context *mapi_ctx, const gchar *profname, const gchar *password, GCancellable *cancellable, GError **perror);
+static struct mapi_session *mapi_profile_load (ESourceRegistry *registry, struct mapi_context *mapi_ctx, const gchar *profname, const gchar *password, GCancellable *cancellable, GError **perror);
 
 /* GObject foo - begin */
 
@@ -165,6 +162,8 @@ make_mapi_error (GError **perror, const gchar *context, enum MAPISTATUS mapi_sta
 }
 
 struct _EMapiConnectionPrivate {
+	ESourceRegistry *registry;
+
 	struct mapi_context *mapi_ctx;
 	struct mapi_session *session;
 	GStaticRecMutex session_lock;
@@ -410,6 +409,10 @@ e_mapi_connection_finalize (GObject *object)
 
 		e_flag_free (priv->notification_flag);
 		priv->notification_flag = NULL;
+
+		if (priv->registry)
+			g_object_unref (priv->registry);
+		priv->registry = NULL;
 	}
 
 	if (G_OBJECT_CLASS (e_mapi_connection_parent_class)->finalize)
@@ -555,7 +558,11 @@ e_mapi_connection_find (const gchar *profile)
 
 /* Creates a new connection object and connects to a server as defined in 'profile' */
 EMapiConnection *
-e_mapi_connection_new (const gchar *profile, const gchar *password, GCancellable *cancellable, GError **perror)
+e_mapi_connection_new (ESourceRegistry *registry,
+		       const gchar *profile,
+		       const GString *password,
+		       GCancellable *cancellable,
+		       GError **perror)
 {
 	EMapiConnection *conn;
 	EMapiConnectionPrivate *priv;
@@ -568,7 +575,7 @@ e_mapi_connection_new (const gchar *profile, const gchar *password, GCancellable
 	if (!e_mapi_utils_create_mapi_context (&mapi_ctx, perror))
 		return NULL;
 
-	session = mapi_profile_load (mapi_ctx, profile, password, cancellable, perror);
+	session = mapi_profile_load (registry, mapi_ctx, profile, password ? password->str : NULL, cancellable, perror);
 	if (!session) {
 		e_mapi_utils_destroy_mapi_context (mapi_ctx);
 		return NULL;
@@ -580,6 +587,7 @@ e_mapi_connection_new (const gchar *profile, const gchar *password, GCancellable
 
 	LOCK ();
 	mapi_object_init (&priv->msg_store);
+	priv->registry = registry ? g_object_ref (registry) : NULL;
 	priv->mapi_ctx = mapi_ctx;
 	priv->session = session;
 
@@ -632,7 +640,10 @@ e_mapi_connection_close (EMapiConnection *conn)
 }
 
 gboolean
-e_mapi_connection_reconnect (EMapiConnection *conn, const gchar *password, GCancellable *cancellable, GError **perror)
+e_mapi_connection_reconnect (EMapiConnection *conn,
+			     const GString *password,
+			     GCancellable *cancellable,
+			     GError **perror)
 {
 	enum MAPISTATUS ms;
 
@@ -644,7 +655,7 @@ e_mapi_connection_reconnect (EMapiConnection *conn, const gchar *password, GCanc
 	if (priv->session)
 		e_mapi_connection_close (conn);
 
-	priv->session = mapi_profile_load (priv->mapi_ctx, priv->profile, password, cancellable, perror);
+	priv->session = mapi_profile_load (priv->registry, priv->mapi_ctx, priv->profile, password ? password->str : NULL, cancellable, perror);
 	if (!priv->session) {
 		e_mapi_debug_print ("%s: %s: Login failed ", G_STRLOC, G_STRFUNC);
 		UNLOCK ();
@@ -6503,6 +6514,7 @@ e_mapi_connection_disable_notifications	(EMapiConnection *conn,
 
 struct tcp_data
 {
+	ESourceRegistry *registry;
 	struct mapi_context *mapi_ctx;
 	const gchar *profname;
 	const gchar *password;
@@ -6516,57 +6528,59 @@ struct tcp_data
 static gboolean
 try_create_profile_main_thread_cb (struct tcp_data *data)
 {
-	EAccountList *accounts;
 	EMapiProfileData empd = { 0 };
-	EIterator *iter;
-	GConfClient *gconf;
+	GList *all_sources;
+	ESource *source;
 
 	g_return_val_if_fail (data != NULL, FALSE);
+	if (!data->registry) {
+		e_flag_set (data->eflag);
+		return FALSE;
+	}
 
-	gconf = gconf_client_get_default ();
-	accounts = e_account_list_new (gconf);
-	for (iter = e_list_get_iterator (E_LIST (accounts)); e_iterator_is_valid (iter); e_iterator_next (iter)) {
-		EAccount *account = E_ACCOUNT (e_iterator_get (iter));
-		if (account && account->source && account->source->url && g_ascii_strncasecmp (account->source->url, "mapi://", 7) == 0) {
-			CamelURL *url;
-			CamelSettings *settings;
-			const gchar *url_string;
-
-			url_string = e_account_get_string (account, E_ACCOUNT_SOURCE_URL);
-			url = camel_url_new (url_string, NULL);
-
-			settings = g_object_new (CAMEL_TYPE_MAPI_SETTINGS, NULL);
-			camel_settings_load_from_url (settings, url);
-
-			empd.server = url->host;
-			empd.username = url->user;
-			e_mapi_util_profiledata_from_settings (&empd, CAMEL_MAPI_SETTINGS (settings));
-			/* cast away the const, but promise not to touch it */
-			empd.password = (gchar*)data->password;
-
-			if (COMPLETE_PROFILEDATA(&empd)) {
-				gchar *profname = e_mapi_util_profile_name (data->mapi_ctx, &empd, FALSE);
-
-				if (profname && g_str_equal (profname, data->profname)) {
-					/* do not use locking here, because when this is called then other thread is holding the lock */
-					data->has_profile = mapi_profile_create (data->mapi_ctx, &empd, NULL, NULL, NULL, data->perror, FALSE);
-
-					g_free (profname);
-					g_object_unref (settings);
-					camel_url_free (url);
-					break;
-				}
+	all_sources = e_source_registry_list_sources (data->registry, NULL);
+	source = e_mapi_utils_get_master_source (all_sources, data->profname);
 
-				g_free (profname);
+	if (source) {
+		ESourceCamel *extension;
+		CamelSettings *settings;
+		const gchar *extension_name;
+		CamelNetworkSettings *network_settings;
+
+		extension_name = e_source_camel_get_extension_name ("mapi");
+		extension = e_source_get_extension (source, extension_name);
+		settings = e_source_camel_get_settings (extension);
+
+		network_settings = CAMEL_NETWORK_SETTINGS (settings);
+
+		empd.server = camel_network_settings_get_host (network_settings);
+		empd.username = camel_network_settings_get_user (network_settings);
+		e_mapi_util_profiledata_from_settings (&empd, CAMEL_MAPI_SETTINGS (settings));
+
+		if (data->password)
+			empd.password = g_string_new (data->password);
+		else
+			data->password = NULL;
+
+		if (COMPLETE_PROFILEDATA (&empd)) {
+			gchar *profname = e_mapi_util_profile_name (data->mapi_ctx, &empd, FALSE);
+
+			if (profname && g_str_equal (profname, data->profname)) {
+				/* do not use locking here, because when this is called then other thread is holding the lock */
+				data->has_profile = mapi_profile_create (data->mapi_ctx, &empd, NULL, NULL, NULL, data->perror, FALSE);
 			}
 
-			g_object_unref (settings);
-			camel_url_free (url);
+			g_free (profname);
+		}
+
+		if (empd.password) {
+			if (empd.password->len)
+				memset (empd.password->str, 0, empd.password->len);
+			g_string_free (empd.password, TRUE);
 		}
 	}
 
-	g_object_unref (accounts);
-	g_object_unref (gconf);
+	g_list_free_full (all_sources, g_object_unref);
 
 	e_flag_set (data->eflag);
 
@@ -6574,7 +6588,12 @@ try_create_profile_main_thread_cb (struct tcp_data *data)
 }
 
 static gboolean
-try_create_profile (struct mapi_context *mapi_ctx, const gchar *profname, const gchar *password, GCancellable *cancellable, GError **perror)
+try_create_profile (ESourceRegistry *registry,
+		    struct mapi_context *mapi_ctx,
+		    const gchar *profname,
+		    const gchar *password,
+		    GCancellable *cancellable,
+		    GError **perror)
 {
 	struct tcp_data data;
 
@@ -6582,6 +6601,7 @@ try_create_profile (struct mapi_context *mapi_ctx, const gchar *profname, const
 	g_return_val_if_fail (profname != NULL, FALSE);
 	g_return_val_if_fail (*profname != 0, FALSE);
 
+	data.registry = registry;
 	data.mapi_ctx = mapi_ctx;
 	data.profname = profname;
 	data.password = password;
@@ -6604,7 +6624,12 @@ try_create_profile (struct mapi_context *mapi_ctx, const gchar *profname, const
 }
 
 static struct mapi_session *
-mapi_profile_load (struct mapi_context *mapi_ctx, const gchar *profname, const gchar *password, GCancellable *cancellable, GError **perror)
+mapi_profile_load (ESourceRegistry *registry,
+		   struct mapi_context *mapi_ctx,
+		   const gchar *profname,
+		   const gchar *password,
+		   GCancellable *cancellable,
+		   GError **perror)
 {
 	enum MAPISTATUS	ms = MAPI_E_SUCCESS;
 	struct mapi_session *session = NULL;
@@ -6627,7 +6652,7 @@ mapi_profile_load (struct mapi_context *mapi_ctx, const gchar *profname, const g
 	e_mapi_debug_print("Loading profile %s ", profname);
 
 	ms = MapiLogonEx (mapi_ctx, &session, profname, password);
-	if (ms == MAPI_E_NOT_FOUND && try_create_profile (mapi_ctx, profname, password, cancellable, perror))
+	if (ms == MAPI_E_NOT_FOUND && try_create_profile (registry, mapi_ctx, profname, password, cancellable, perror))
 		ms = MapiLogonEx (mapi_ctx, &session, profname, password);
 
 	if (ms != MAPI_E_SUCCESS) {
@@ -6684,7 +6709,7 @@ mapi_profile_create (struct mapi_context *mapi_ctx,
 	}
 
 	/*We need all the params before proceeding.*/
-	e_return_val_mapi_error_if_fail (COMPLETE_PROFILEDATA(empd),
+	e_return_val_mapi_error_if_fail (COMPLETE_PROFILEDATA (empd) && empd->password && empd->password->len,
 					 MAPI_E_INVALID_PARAMETER, FALSE);
 
 	if (use_locking)
@@ -6700,7 +6725,7 @@ mapi_profile_create (struct mapi_context *mapi_ctx,
 	/* don't bother to check error - it would be valid if we got an error */
 
 	ms = CreateProfile (mapi_ctx, profname, empd->username,
-			    empd->password, OC_PROFILE_NOPASSWORD);
+			    empd->password->str, OC_PROFILE_NOPASSWORD);
 	if (ms != MAPI_E_SUCCESS) {
 		make_mapi_error (perror, "CreateProfile", ms);
 		goto cleanup;
@@ -6732,7 +6757,7 @@ mapi_profile_create (struct mapi_context *mapi_ctx,
 
 	/* Login now */
 	e_mapi_debug_print("Logging into the server... ");
-	ms = MapiLogonProvider (mapi_ctx, &session, profname, empd->password,
+	ms = MapiLogonProvider (mapi_ctx, &session, profname, empd->password->str,
 				PROVIDER_ID_NSPI);
 	if (ms != MAPI_E_SUCCESS) {
 		make_mapi_error (perror, "MapiLogonProvider", ms);
diff --git a/src/libexchangemapi/e-mapi-connection.h b/src/libexchangemapi/e-mapi-connection.h
index 2eebbff..25c3450 100644
--- a/src/libexchangemapi/e-mapi-connection.h
+++ b/src/libexchangemapi/e-mapi-connection.h
@@ -31,6 +31,7 @@
 
 #include <libmapi/libmapi.h>
 #include <libmapi/mapi_nameid.h>
+#include <libedataserver/libedataserver.h>
 
 /* Standard GObject macros */
 #define E_MAPI_TYPE_CONNECTION (e_mapi_connection_get_type ())
@@ -229,13 +230,14 @@ struct _EMapiConnectionClass {
 };
 
 GType			e_mapi_connection_get_type		(void);
-EMapiConnection *	e_mapi_connection_new			(const gchar *profile,
-								 const gchar *password,
+EMapiConnection *	e_mapi_connection_new			(ESourceRegistry *registry,
+								 const gchar *profile,
+								 const GString *password,
 								 GCancellable *cancellable,
 								 GError **perror);
 EMapiConnection *	e_mapi_connection_find			(const gchar *profile);
 gboolean		e_mapi_connection_reconnect		(EMapiConnection *conn,
-								 const gchar *password,
+								 const GString *password,
 								 GCancellable *cancellable,
 								 GError **perror);
 gboolean		e_mapi_connection_close			(EMapiConnection *conn);
@@ -515,7 +517,7 @@ gboolean		e_mapi_connection_disable_notifications	(EMapiConnection *conn,
 
 typedef struct {
 	const gchar *username;
-	gchar *password;
+	GString *password;
 	const gchar *domain;
 	const gchar *server;
 	gboolean use_ssl;
@@ -525,7 +527,7 @@ typedef struct {
 
 #define COMPLETE_PROFILEDATA(x) \
 	((x)->username && *(x)->username && (x)->server && *(x)->server \
-	 && (((x)->domain && *(x)->domain && (x)->password && *(x)->password) \
+	 && (((x)->domain && *(x)->domain) \
 	     || ((x)->krb_sso && (x)->krb_realm && *(x)->krb_realm)))
 
 gboolean		e_mapi_create_profile			(struct mapi_context *mapi_ctx,
diff --git a/src/libexchangemapi/e-mapi-folder.c b/src/libexchangemapi/e-mapi-folder.c
index cb81763..a1cdb13 100644
--- a/src/libexchangemapi/e-mapi-folder.c
+++ b/src/libexchangemapi/e-mapi-folder.c
@@ -27,12 +27,12 @@
 
 #include <glib/gi18n-lib.h>
 
-#include <libedataserver/e-source.h>
-#include <libedataserver/e-source-group.h>
-#include <libedataserver/e-source-list.h>
+#include <libedataserver/libedataserver.h>
 
 #include "e-mapi-connection.h"
 #include "e-mapi-folder.h"
+#include "e-mapi-utils.h"
+#include "e-source-mapi-folder.h"
 
 #define d(x)
 
@@ -143,7 +143,7 @@ e_mapi_folder_get_name (EMapiFolder *folder)
 }
 
 guint64
-e_mapi_folder_get_fid (EMapiFolder *folder)
+e_mapi_folder_get_id (EMapiFolder *folder)
 {
 	return folder->folder_id;
 }
@@ -166,6 +166,12 @@ e_mapi_folder_get_type (EMapiFolder *folder)
 	return folder->container_class;
 }
 
+EMapiFolderCategory
+e_mapi_folder_get_category (EMapiFolder *folder)
+{
+	return folder->category;
+}
+
 guint32
 e_mapi_folder_get_unread_count (EMapiFolder *folder)
 {
@@ -252,258 +258,174 @@ e_mapi_folder_pick_color_spec (gint move_by,
 	return g_strdup_printf ("#%06x", color);
 }
 
-#define MAPI_URI_PREFIX   "mapi://" 
-
-static const gchar *
-get_gconf_key_for_folder_type (EMapiFolderType folder_type)
+gboolean
+e_mapi_folder_populate_esource (ESource *source,
+				const GList *sources,
+				EMapiFolderType folder_type,
+				const gchar *profile,
+				gboolean offline_sync,
+				EMapiFolderCategory folder_category,
+				const gchar *foreign_username, /* NULL for public folder */
+				const gchar *folder_name,
+				mapi_id_t folder_id,
+				gint color_seed,
+				GCancellable *cancellable,
+				GError **perror)
 {
-	if (folder_type == E_MAPI_FOLDER_TYPE_APPOINTMENT)
-		return CALENDAR_SOURCES;
-	else if (folder_type == E_MAPI_FOLDER_TYPE_TASK)
-		return TASK_SOURCES;
-	else if (folder_type == E_MAPI_FOLDER_TYPE_MEMO)
-		return JOURNAL_SOURCES;
-	else if (folder_type == E_MAPI_FOLDER_TYPE_JOURNAL)
-		return JOURNAL_SOURCES;
-	else if (folder_type == E_MAPI_FOLDER_TYPE_CONTACT)
-		return ADDRESSBOOK_SOURCES;
+	ESource *master_source;
+	gboolean res = FALSE;
 
-	return NULL;
-}
+	master_source = e_mapi_utils_get_master_source (sources, profile);
 
-gboolean
-e_mapi_folder_add_as_esource (EMapiFolderType folder_type,
-			      const gchar *login_profile,
-			      const gchar *login_domain,
-			      const gchar *login_realm,
-			      const gchar *login_host,
-			      const gchar *login_user,
-			      gboolean login_kerberos,
-			      gboolean offline_sync,
-			      EMapiFolderCategory folder_category,
-			      const gchar *foreign_username, /* NULL for public folder */
-			      const gchar *folder_name,
-			      const gchar *fid,
-			      GError **perror)
-{
-	ESourceList *source_list = NULL;
-	ESourceGroup *group = NULL;
-	const gchar *conf_key = NULL;
-	GConfClient* client;
-	GSList *sources;
-	ESource *source = NULL;
-	gchar *relative_uri = NULL;
-	gchar *base_uri = NULL;
-
-	g_return_val_if_fail (login_profile != NULL, FALSE);
-	g_return_val_if_fail (login_host != NULL, FALSE);
-	g_return_val_if_fail (login_user != NULL, FALSE);
-	g_return_val_if_fail (folder_name != NULL, FALSE);
-	g_return_val_if_fail (fid != NULL, FALSE);
-	g_return_val_if_fail (folder_category == E_MAPI_FOLDER_CATEGORY_PUBLIC || folder_category == E_MAPI_FOLDER_CATEGORY_FOREIGN, FALSE);
-	if (folder_category == E_MAPI_FOLDER_CATEGORY_FOREIGN)
-		g_return_val_if_fail (foreign_username != NULL, FALSE);
-
-	conf_key = get_gconf_key_for_folder_type (folder_type);
-	if (!conf_key) {
-		g_propagate_error (perror, g_error_new_literal (E_MAPI_ERROR, MAPI_E_INVALID_PARAMETER, _("Cannot add folder, unsupported folder type")));
-		return FALSE;
-	}
+	if (master_source) {
+		ESourceBackend *backend_ext;
 
-	client = gconf_client_get_default ();
-	source_list = e_source_list_new_for_gconf (client, conf_key);
-	base_uri = g_strdup_printf ("%s%s %s/", MAPI_URI_PREFIX, login_user, login_host);
-	group = e_source_list_peek_group_by_base_uri (source_list, base_uri);
-	if (!group) {
-		g_propagate_error (perror, g_error_new_literal (E_MAPI_ERROR, MAPI_E_INVALID_PARAMETER, _("Cannot add folder, group of sources not found")));
-		g_object_unref (source_list);
-		g_object_unref (client);
-		g_free (base_uri);
-
-		return FALSE;
-	}
+		e_source_set_parent (source, e_source_get_uid (master_source));
+		e_source_set_display_name (source, folder_name);
+
+		switch (folder_type) {
+			case E_MAPI_FOLDER_TYPE_APPOINTMENT:
+				backend_ext = e_source_get_extension (source, E_SOURCE_EXTENSION_CALENDAR);
+				break;
+			case E_MAPI_FOLDER_TYPE_JOURNAL:
+			case E_MAPI_FOLDER_TYPE_MEMO:
+				backend_ext = e_source_get_extension (source, E_SOURCE_EXTENSION_MEMO_LIST);
+				break;
+			case E_MAPI_FOLDER_TYPE_TASK:
+				backend_ext = e_source_get_extension (source, E_SOURCE_EXTENSION_TASK_LIST);
+				break;
+			case E_MAPI_FOLDER_TYPE_CONTACT:
+				backend_ext = e_source_get_extension (source, E_SOURCE_EXTENSION_ADDRESS_BOOK);
+				break;
+			default:
+				backend_ext = NULL;
+				break;
+		}
 
-	sources = e_source_group_peek_sources (group);
-	for (; sources != NULL; sources = g_slist_next (sources)) {
-		ESource *source = E_SOURCE (sources->data);
-		gchar *folder_id = e_source_get_duped_property (source, "folder-id");
-		if (folder_id) {
-			if (g_str_equal (fid, folder_id)) {
-				g_propagate_error (perror,
-					g_error_new (E_MAPI_ERROR, MAPI_E_INVALID_PARAMETER,
-						_("Cannot add folder, folder already exists as '%s'"), e_source_peek_name (source)));
-
-				g_object_unref (source_list);
-				g_object_unref (client);
-				g_free (folder_id);
-				g_free (base_uri);
-
-				return FALSE;
+		if (backend_ext) {
+			ESourceMapiFolder *folder_ext;
+			ESourceOffline *offline_ext;
+
+			e_source_backend_set_backend_name (backend_ext , "mapi");
+
+			folder_ext = e_source_get_extension (source, E_SOURCE_EXTENSION_MAPI_FOLDER);
+			e_source_mapi_folder_set_id (folder_ext, folder_id);
+			if (folder_category == E_MAPI_FOLDER_CATEGORY_PUBLIC)
+				e_source_mapi_folder_set_is_public (folder_ext, TRUE);
+			else
+				e_source_mapi_folder_set_foreign_username (folder_ext, foreign_username);
+			
+			offline_ext = e_source_get_extension (source, E_SOURCE_EXTENSION_OFFLINE);
+			e_source_offline_set_stay_synchronized (offline_ext, offline_sync);
+
+			/* set also color for calendar-like sources */
+			if (folder_type != E_MAPI_FOLDER_TYPE_CONTACT) {
+				gchar *color_str;
+
+				color_str = e_mapi_folder_pick_color_spec (1 + g_list_length ((GList *) sources), folder_type != E_MAPI_FOLDER_TYPE_APPOINTMENT);
+				e_source_selectable_set_color (E_SOURCE_SELECTABLE (backend_ext), color_str);
+				g_free (color_str);
 			}
 
-			g_free (folder_id);
+			res = TRUE;
+		} else {
+			g_propagate_error (perror, g_error_new_literal (E_MAPI_ERROR, MAPI_E_INVALID_PARAMETER, _("Cannot add folder, unsupported folder type")));
 		}
-	}
-
-	relative_uri = g_strconcat (";", fid, NULL);
-	source = e_source_new (folder_name, relative_uri);
-	e_source_set_property (source, "username", login_user);
-	e_source_set_property (source, "host", login_host);
-	e_source_set_property (source, "profile", login_profile);
-	e_source_set_property (source, "domain", login_domain);
-	e_source_set_property (source, "realm", login_realm);
-	e_source_set_property (source, "folder-id", fid);
-	e_source_set_property (source, "offline_sync", offline_sync ? "1" : "0");
-	e_source_set_property (source, "delete", "yes");
-	if (folder_category == E_MAPI_FOLDER_CATEGORY_PUBLIC)
-		e_source_set_property (source, "public", "yes");
-	else
-		e_source_set_property (source, "foreign-username", foreign_username);
-	if (login_kerberos) {
-		e_source_set_property (source, "kerberos", "required");
 	} else {
-		e_source_set_property (source, "auth", "1");
-		e_source_set_property (source, "auth-type", "plain/password");
+		g_propagate_error (perror, g_error_new_literal (E_MAPI_ERROR, MAPI_E_INVALID_PARAMETER, _("Cannot add folder, master source not found")));
 	}
 
-	/* set also color for calendar-like sources */
-	if (folder_type != E_MAPI_FOLDER_TYPE_CONTACT) {
-		GSList *sources = e_source_group_peek_sources (group);
-		gchar *color_str;
+	return res;
+}
 
-		color_str = e_mapi_folder_pick_color_spec (1 + g_slist_length (sources), folder_type != E_MAPI_FOLDER_TYPE_APPOINTMENT);
-		e_source_set_color_spec (source, color_str);
-		g_free (color_str);
+gboolean
+e_mapi_folder_add_as_esource (ESourceRegistry *pregistry,
+			      EMapiFolderType folder_type,
+			      const gchar *profile,
+			      gboolean offline_sync,
+			      EMapiFolderCategory folder_category,
+			      const gchar *foreign_username, /* NULL for public folder */
+			      const gchar *folder_name,
+			      mapi_id_t folder_id,
+			      gint color_seed,
+			      GCancellable *cancellable,
+			      GError **perror)
+{
+	ESourceRegistry *registry;
+	GList *sources;
+	ESource *source;
+	gboolean res = FALSE;
+
+	registry = pregistry;
+	if (!registry) {
+		registry = e_source_registry_new_sync (cancellable, perror);
+		if (!registry)
+			return FALSE;
 	}
 
-	e_source_group_add_source (group, source, -1);
-
+	sources = e_source_registry_list_sources (registry, NULL);
+	source = e_source_new (NULL, NULL, NULL);
+
+	if (e_mapi_folder_populate_esource (
+		source,
+		sources,
+		folder_type,
+		profile,
+		offline_sync,
+		folder_category,
+		foreign_username,
+		folder_name,
+		folder_id,
+		color_seed,
+		cancellable,
+		perror)) {
+		res = e_source_registry_commit_source_sync (registry, source, cancellable, perror);
+	}
 	g_object_unref (source);
-	g_object_unref (client);
-	g_free (relative_uri);
-	g_free (base_uri);
 
-	if (!e_source_list_sync (source_list, perror)) {
-		g_object_unref (source_list);
-		return FALSE;
-	}
+	g_list_free_full (sources, g_object_unref);
+	if (!pregistry)
+		g_object_unref (registry);
 
-	g_object_unref (source_list);
-	return TRUE;
+	return res;
 }
 
 gboolean
-e_mapi_folder_remove_as_esource (EMapiFolderType folder_type,
-				 const gchar *login_host,
-				 const gchar *login_user,
-				 const gchar *fid,
+e_mapi_folder_remove_as_esource (ESourceRegistry *pregistry,
+				 const gchar *profile,
+				 mapi_id_t folder_id,
+				 GCancellable *cancellable,
 				 GError **perror)
 {
-	ESourceList *source_list = NULL;
-	ESourceGroup *group = NULL;
-	const gchar *conf_key = NULL;
-	GConfClient* client;
-	GSList *sources = NULL;
-	gchar *base_uri = NULL;
-
-	g_return_val_if_fail (login_host != NULL, FALSE);
-	g_return_val_if_fail (login_user != NULL, FALSE);
-	g_return_val_if_fail (fid != NULL, FALSE);
-
-	conf_key = get_gconf_key_for_folder_type (folder_type);
-	if (!conf_key) {
-		g_propagate_error (perror, g_error_new_literal (E_MAPI_ERROR, MAPI_E_INVALID_PARAMETER, _("Cannot remove folder, unsupported folder type")));
-		return FALSE;
+	ESourceRegistry *registry;
+	ESource *source;
+	GList *sources;
+	gboolean res = TRUE;
+
+	registry = pregistry;
+	if (!registry) {
+		registry = e_source_registry_new_sync (cancellable, perror);
+		if (!registry)
+			return FALSE;
 	}
 
-	client = gconf_client_get_default ();
-	source_list = e_source_list_new_for_gconf (client, conf_key);
-	base_uri = g_strdup_printf ("%s%s %s/", MAPI_URI_PREFIX, login_user, login_host);
-	group = e_source_list_peek_group_by_base_uri (source_list, base_uri);
-	if (!group) {
-		g_free (base_uri);
-		g_object_unref (source_list);
-		g_object_unref (client);
-
-		return TRUE;
-	}
-
-	sources = e_source_group_peek_sources (group);
-	for (; sources != NULL; sources = g_slist_next (sources)) {
-		ESource *source = E_SOURCE (sources->data);
-		gchar *folder_id = e_source_get_duped_property (source, "folder-id");
-		if (folder_id) {
-			if (g_str_equal (fid, folder_id)) {
-				g_free (folder_id);
-
-				e_source_group_remove_source (group, source);
-				break;
-			}
+	sources = e_source_registry_list_sources (registry, NULL);
+	source = e_mapi_utils_get_source_for_folder (sources, profile, folder_id);
 
-			g_free (folder_id);
-		}
-	}
+	if (source)
+		res = e_source_remove_sync (source, cancellable, perror);
 
-	g_free (base_uri);
-	g_object_unref (source_list);
-	g_object_unref (client);
+	g_list_free_full (sources, g_object_unref);
+	if (!pregistry)
+		g_object_unref (registry);
 
-	return TRUE;
+	return res;
 }
 
 gboolean
-e_mapi_folder_is_subscribed_as_esource (EMapiFolderType folder_type,
-					const gchar *login_host,
-					const gchar *login_user,
-					const gchar *fid)
+e_mapi_folder_is_subscribed_as_esource (const GList *esources,
+					const gchar *profile,
+					mapi_id_t fid)
 {
-	ESourceList *source_list = NULL;
-	ESourceGroup *group = NULL;
-	const gchar *conf_key = NULL;
-	GConfClient* client;
-	GSList *sources = NULL;
-	gchar *base_uri = NULL;
-	gboolean found = FALSE;
-
-	g_return_val_if_fail (login_host != NULL, FALSE);
-	g_return_val_if_fail (login_user != NULL, FALSE);
-	g_return_val_if_fail (fid != NULL, FALSE);
-
-	conf_key = get_gconf_key_for_folder_type (folder_type);
-	if (!conf_key)
-		return FALSE;
-
-	client = gconf_client_get_default ();
-	source_list = e_source_list_new_for_gconf (client, conf_key);
-	base_uri = g_strdup_printf ("%s%s %s/", MAPI_URI_PREFIX, login_user, login_host);
-	group = e_source_list_peek_group_by_base_uri (source_list, base_uri);
-	if (!group) {
-		g_free (base_uri);
-		g_object_unref (source_list);
-		g_object_unref (client);
-
-		return FALSE;
-	}
-
-	sources = e_source_group_peek_sources (group);
-	for (; sources != NULL; sources = g_slist_next (sources)) {
-		ESource *source = E_SOURCE (sources->data);
-		gchar *folder_id = e_source_get_duped_property (source, "folder-id");
-		if (folder_id) {
-			if (g_str_equal (fid, folder_id)) {
-				g_free (folder_id);
-
-				found = TRUE;
-				break;
-			}
-
-			g_free (folder_id);
-		}
-	}
-
-	g_free (base_uri);
-	g_object_unref (source_list);
-	g_object_unref (client);
-
-	return found;
+	return e_mapi_utils_get_source_for_folder (esources, profile, fid) != NULL;
 }
diff --git a/src/libexchangemapi/e-mapi-folder.h b/src/libexchangemapi/e-mapi-folder.h
index e65a087..2e4b9b7 100644
--- a/src/libexchangemapi/e-mapi-folder.h
+++ b/src/libexchangemapi/e-mapi-folder.h
@@ -27,14 +27,7 @@
 #include <glib.h>
 
 #include <libmapi/libmapi.h>
-
-#define CALENDAR_SOURCES	"/apps/evolution/calendar/sources"
-#define TASK_SOURCES		"/apps/evolution/tasks/sources"
-#define JOURNAL_SOURCES		"/apps/evolution/memos/sources"
-#define SELECTED_CALENDARS	"/apps/evolution/calendar/display/selected_calendars"
-#define SELECTED_TASKS		"/apps/evolution/calendar/tasks/selected_tasks"
-#define SELECTED_JOURNALS	"/apps/evolution/calendar/memos/selected_memos"
-#define ADDRESSBOOK_SOURCES     "/apps/evolution/addressbook/sources"
+#include <libedataserver/libedataserver.h>
 
 typedef enum  {
 	E_MAPI_FOLDER_TYPE_UNKNOWN = 0,
@@ -96,9 +89,10 @@ EMapiFolder *		e_mapi_folder_copy		(EMapiFolder *src);
 void			e_mapi_folder_free		(EMapiFolder *folder);
 
 const gchar *		e_mapi_folder_get_name		(EMapiFolder *folder);
-mapi_id_t		e_mapi_folder_get_fid		(EMapiFolder *folder);
+mapi_id_t		e_mapi_folder_get_id		(EMapiFolder *folder);
 mapi_id_t		e_mapi_folder_get_parent_id	(EMapiFolder *folder);
 EMapiFolderType		e_mapi_folder_get_type		(EMapiFolder *folder);
+EMapiFolderCategory	e_mapi_folder_get_category	(EMapiFolder *folder);
 guint32			e_mapi_folder_get_unread_count	(EMapiFolder *folder);
 guint32			e_mapi_folder_get_total_count	(EMapiFolder *folder);
 gboolean		e_mapi_folder_is_root		(EMapiFolder *folder);
@@ -109,29 +103,39 @@ void			e_mapi_folder_free_list		(GSList *folder_list);
 gchar *			e_mapi_folder_pick_color_spec	(gint move_by,
 							 gboolean around_middle);
 
-gboolean		e_mapi_folder_add_as_esource	(EMapiFolderType folder_type,
-							 const gchar *login_profile,
-							 const gchar *login_domain,
-							 const gchar *login_realm,
-							 const gchar *login_host,
-							 const gchar *login_user,
-							 gboolean login_kerberos,
+gboolean		e_mapi_folder_populate_esource	(ESource *source,
+							 const GList *sources,
+							 EMapiFolderType folder_type,
+							 const gchar *profile,
+							 gboolean offline_sync,
+							 EMapiFolderCategory folder_category,
+							 const gchar *foreign_username, /* NULL for public folder */
+							 const gchar *folder_name,
+							 mapi_id_t folder_id,
+							 gint color_seed,
+							 GCancellable *cancellable,
+							 GError **perror);
+
+gboolean		e_mapi_folder_add_as_esource	(ESourceRegistry *pregistry,
+							 EMapiFolderType folder_type,
+							 const gchar *profile,
 							 gboolean offline_sync,
 							 EMapiFolderCategory folder_category,
 							 const gchar *foreign_username, /* NULL for public folder */
 							 const gchar *folder_name,
-							 const gchar *fid,
+							 mapi_id_t folder_id,
+							 gint color_seed,
+							 GCancellable *cancellable,
 							 GError **perror);
 
-gboolean		e_mapi_folder_remove_as_esource	(EMapiFolderType folder_type,
-							 const gchar *login_host,
-							 const gchar *login_user,
-							 const gchar *fid,
+gboolean		e_mapi_folder_remove_as_esource	(ESourceRegistry *pregistry,
+							 const gchar *profile,
+							 mapi_id_t folder_id,
+							 GCancellable *cancellable,
 							 GError **perror);
 
 gboolean		e_mapi_folder_is_subscribed_as_esource
-							(EMapiFolderType folder_type,
-							 const gchar *login_host,
-							 const gchar *login_user,
-							 const gchar *fid);
+							(const GList *esources,
+							 const gchar *profile,
+							 mapi_id_t fid);
 #endif
diff --git a/src/libexchangemapi/e-mapi-mail-utils.c b/src/libexchangemapi/e-mapi-mail-utils.c
index a60e920..05130e2 100644
--- a/src/libexchangemapi/e-mapi-mail-utils.c
+++ b/src/libexchangemapi/e-mapi-mail-utils.c
@@ -22,7 +22,7 @@
 #endif
 
 #include <camel/camel.h>
-#include <libecal/e-cal-util.h>
+#include <libecal/libecal.h>
 
 #include "e-mapi-defs.h"
 #include "e-mapi-utils.h"
diff --git a/src/libexchangemapi/e-mapi-utils.c b/src/libexchangemapi/e-mapi-utils.c
index 47bf2d3..6ae30c8 100644
--- a/src/libexchangemapi/e-mapi-utils.c
+++ b/src/libexchangemapi/e-mapi-utils.c
@@ -28,10 +28,11 @@
 #include <glib.h>
 #include <gio/gio.h>
 
-#include <libedataserver/e-data-server-util.h>
+#include <libedataserver/libedataserver.h>
 
 #include "e-mapi-utils.h"
 #include "e-mapi-mail-utils.h"
+#include "e-source-mapi-folder.h"
 
 #ifdef G_OS_WIN32
 /* Undef the similar macro from pthread.h, it doesn't check if
@@ -655,7 +656,9 @@ e_mapi_util_profiledata_from_settings (EMapiProfileData *empd, CamelMapiSettings
 }
 
 gboolean
-e_mapi_util_trigger_krb_auth (const EMapiProfileData *empd, GError **error) {
+e_mapi_util_trigger_krb_auth (const EMapiProfileData *empd,
+			      GError **error)
+{
 	gint success = FALSE;
 	GError *local_error = NULL;
 	GDBusConnection *connection;
@@ -1279,3 +1282,101 @@ e_mapi_utils_unref_in_thread (GObject *object)
 		g_object_unref (object);
 	}
 }
+
+static gboolean
+is_for_profile (ESource *source,
+		const gchar *profile)
+{
+	ESourceCamel *extension;
+	CamelMapiSettings *settings;
+	const gchar *extension_name;
+
+	if (!source)
+		return FALSE;
+
+	if (!profile)
+		return TRUE;
+
+	extension_name = e_source_camel_get_extension_name ("mapi");
+	if (!e_source_has_extension (source, extension_name))
+		return FALSE;
+
+	extension = e_source_get_extension (source, extension_name);
+	settings = CAMEL_MAPI_SETTINGS (e_source_camel_get_settings (extension));
+
+	return settings && g_strcmp0 (camel_mapi_settings_get_profile (settings), profile) == 0;
+}
+
+/* filters @esources thus the resulting list will contain ESource-s only for @profile;
+   free returned list with g_list_free_full (list, g_object_unref); */
+GList *
+e_mapi_utils_filter_sources_for_profile (const GList *esources,
+					 const gchar *profile)
+{
+	GList *found = NULL;
+	const GList *iter;
+	ESource *master_source;
+
+	master_source = e_mapi_utils_get_master_source (esources, profile);
+	if (!master_source)
+		return NULL;
+
+	for (iter = esources; iter; iter = iter->next) {
+		ESource *source = iter->data;
+
+		if (is_for_profile (source, profile) ||
+		    g_strcmp0 (e_source_get_uid (master_source), e_source_get_parent (source)) == 0)
+			found = g_list_prepend (found, g_object_ref (source));
+	}
+
+	return g_list_reverse (found);
+}
+
+/* returns (not-reffed) member of @esources, which is for @profile and @folder_id */
+ESource *
+e_mapi_utils_get_source_for_folder (const GList *esources,
+				    const gchar *profile,
+				    mapi_id_t folder_id)
+{
+	ESource *master_source;
+	const GList *iter;
+	
+	master_source = e_mapi_utils_get_master_source (esources, profile);
+	if (!master_source)
+		return NULL;
+
+	for (iter = esources; iter; iter = iter->next) {
+		ESource *source = iter->data;
+
+		if ((is_for_profile (source, profile) ||
+		    g_strcmp0 (e_source_get_uid (master_source), e_source_get_parent (source)) == 0) &&
+		    e_source_has_extension (source, E_SOURCE_EXTENSION_MAPI_FOLDER)) {
+			ESourceMapiFolder *folder_ext = e_source_get_extension (source, E_SOURCE_EXTENSION_MAPI_FOLDER);
+
+			g_return_val_if_fail (folder_ext != NULL, NULL);
+
+			if (e_source_mapi_folder_get_id (folder_ext) == folder_id)
+				return source;
+		}
+	}
+
+	return NULL;
+}
+
+/* returns (not-reffed) member of @esources, which is master (with no parent) source for @profile */
+ESource *
+e_mapi_utils_get_master_source (const GList *esources,
+				const gchar *profile)
+{
+	const GList *iter;
+
+	for (iter = esources; iter; iter = iter->next) {
+		ESource *source = iter->data;
+
+		if (!e_source_get_parent (source) &&
+		    is_for_profile (source, profile))
+			return source;
+	}
+
+	return NULL;
+}
diff --git a/src/libexchangemapi/e-mapi-utils.h b/src/libexchangemapi/e-mapi-utils.h
index 1e66f70..f9577c2 100644
--- a/src/libexchangemapi/e-mapi-utils.h
+++ b/src/libexchangemapi/e-mapi-utils.h
@@ -24,6 +24,8 @@
 #ifndef E_MAPI_UTILS_H
 #define E_MAPI_UTILS_H 
 
+#include <libedataserver/libedataserver.h>
+
 #include "camel-mapi-settings.h"
 #include "e-mapi-debug.h"
 #include "e-mapi-connection.h"
@@ -128,4 +130,13 @@ gboolean	e_mapi_utils_copy_to_mapi_SPropValue		(TALLOC_CTX *mem_ctx,
 
 void		e_mapi_utils_unref_in_thread			(GObject *object);
 
+GList *		e_mapi_utils_filter_sources_for_profile		(const GList *esources,
+								 const gchar *profile);
+
+ESource *	e_mapi_utils_get_source_for_folder		(const GList *esources,
+								 const gchar *profile,
+								 mapi_id_t folder_id);
+
+ESource *	e_mapi_utils_get_master_source			(const GList *esources,
+								 const gchar *profile);
 #endif
diff --git a/src/libexchangemapi/e-source-mapi-folder.c b/src/libexchangemapi/e-source-mapi-folder.c
new file mode 100644
index 0000000..06d2e7b
--- /dev/null
+++ b/src/libexchangemapi/e-source-mapi-folder.c
@@ -0,0 +1,488 @@
+/*
+ * e-source-mapi-folder.c
+ *
+ * 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/>
+ *
+ */
+
+#include "e-source-mapi-folder.h"
+
+#define E_SOURCE_MAPI_FOLDER_GET_PRIVATE(obj) \
+	(G_TYPE_INSTANCE_GET_PRIVATE \
+	((obj), E_TYPE_SOURCE_MAPI_FOLDER, ESourceMapiFolderPrivate))
+
+struct _ESourceMapiFolderPrivate {
+	GMutex *property_lock;
+	guint64 fid;
+	guint64 parent_fid;
+	gboolean is_public;
+	gboolean server_notification;
+	gchar *foreign_username;
+	gboolean allow_partial;
+	gint partial_count;
+};
+
+enum {
+	PROP_0,
+	PROP_ID,
+	PROP_PARENT_ID,
+	PROP_IS_PUBLIC,
+	PROP_SERVER_NOTIFICATION,
+	PROP_FOREIGN_USERNAME,
+	PROP_ALLOW_PARTIAL,
+	PROP_PARTIAL_COUNT
+};
+
+G_DEFINE_DYNAMIC_TYPE (
+	ESourceMapiFolder,
+	e_source_mapi_folder,
+	E_TYPE_SOURCE_EXTENSION)
+
+static void
+source_mapi_folder_set_property (GObject *object,
+				 guint property_id,
+                                 const GValue *value,
+                                 GParamSpec *pspec)
+{
+	switch (property_id) {
+		case PROP_ID:
+			e_source_mapi_folder_set_id (
+				E_SOURCE_MAPI_FOLDER (object),
+				g_value_get_uint64 (value));
+			return;
+
+		case PROP_PARENT_ID:
+			e_source_mapi_folder_set_parent_id (
+				E_SOURCE_MAPI_FOLDER (object),
+				g_value_get_uint64 (value));
+			return;
+
+		case PROP_IS_PUBLIC:
+			e_source_mapi_folder_set_is_public (
+				E_SOURCE_MAPI_FOLDER (object),
+				g_value_get_boolean (value));
+			return;
+
+		case PROP_SERVER_NOTIFICATION:
+			e_source_mapi_folder_set_server_notification (
+				E_SOURCE_MAPI_FOLDER (object),
+				g_value_get_boolean (value));
+			return;
+
+		case PROP_FOREIGN_USERNAME:
+			e_source_mapi_folder_set_foreign_username (
+				E_SOURCE_MAPI_FOLDER (object),
+				g_value_get_string (value));
+			return;
+
+		case PROP_ALLOW_PARTIAL:
+			e_source_mapi_folder_set_allow_partial (
+				E_SOURCE_MAPI_FOLDER (object),
+				g_value_get_boolean (value));
+			return;
+
+		case PROP_PARTIAL_COUNT:
+			e_source_mapi_folder_set_partial_count (
+				E_SOURCE_MAPI_FOLDER (object),
+				g_value_get_int (value));
+			return;
+	}
+
+	G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+source_mapi_folder_get_property (GObject *object,
+				 guint property_id,
+                                 GValue *value,
+                                 GParamSpec *pspec)
+{
+	switch (property_id) {
+		case PROP_ID:
+			g_value_set_uint64 (
+				value,
+				e_source_mapi_folder_get_id (
+				E_SOURCE_MAPI_FOLDER (object)));
+			return;
+
+		case PROP_PARENT_ID:
+			g_value_set_uint64 (
+				value,
+				e_source_mapi_folder_get_parent_id (
+				E_SOURCE_MAPI_FOLDER (object)));
+			return;
+
+		case PROP_IS_PUBLIC:
+			g_value_set_boolean (
+				value,
+				e_source_mapi_folder_is_public (
+				E_SOURCE_MAPI_FOLDER (object)));
+			return;
+
+		case PROP_SERVER_NOTIFICATION:
+			g_value_set_boolean (
+				value,
+				e_source_mapi_folder_get_server_notification (
+				E_SOURCE_MAPI_FOLDER (object)));
+			return;
+
+		case PROP_FOREIGN_USERNAME:
+			g_value_take_string (
+				value,
+				e_source_mapi_folder_dup_foreign_username (
+				E_SOURCE_MAPI_FOLDER (object)));
+			return;
+
+		case PROP_ALLOW_PARTIAL:
+			g_value_set_boolean (
+				value,
+				e_source_mapi_folder_get_allow_partial (
+				E_SOURCE_MAPI_FOLDER (object)));
+			return;
+
+		case PROP_PARTIAL_COUNT:
+			g_value_set_int (
+				value,
+				e_source_mapi_folder_get_partial_count (
+				E_SOURCE_MAPI_FOLDER (object)));
+			return;
+	}
+
+	G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+source_mapi_folder_finalize (GObject *object)
+{
+	ESourceMapiFolderPrivate *priv;
+
+	priv = E_SOURCE_MAPI_FOLDER_GET_PRIVATE (object);
+
+	g_mutex_free (priv->property_lock);
+
+	g_free (priv->foreign_username);
+
+	/* Chain up to parent's finalize() method. */
+	G_OBJECT_CLASS (e_source_mapi_folder_parent_class)->finalize (object);
+}
+
+static void
+e_source_mapi_folder_class_init (ESourceMapiFolderClass *class)
+{
+	GObjectClass *object_class;
+	ESourceExtensionClass *extension_class;
+
+	g_type_class_add_private (class, sizeof (ESourceMapiFolderPrivate));
+
+	object_class = G_OBJECT_CLASS (class);
+	object_class->set_property = source_mapi_folder_set_property;
+	object_class->get_property = source_mapi_folder_get_property;
+	object_class->finalize = source_mapi_folder_finalize;
+
+	extension_class = E_SOURCE_EXTENSION_CLASS (class);
+	extension_class->name = E_SOURCE_EXTENSION_MAPI_FOLDER;
+
+	g_object_class_install_property (
+		object_class,
+		PROP_ID,
+		g_param_spec_uint64 (
+			"id",
+			"ID",
+			"The server-assigned folder ID",
+			0, G_MAXUINT64, 0,
+			G_PARAM_READWRITE |
+			G_PARAM_STATIC_STRINGS |
+			E_SOURCE_PARAM_SETTING));
+
+	g_object_class_install_property (
+		object_class,
+		PROP_PARENT_ID,
+		g_param_spec_uint64 (
+			"parent-id",
+			"Parent ID",
+			"The server-assigned folder's parent ID",
+			0, G_MAXUINT64, 0,
+			G_PARAM_READWRITE |
+			G_PARAM_STATIC_STRINGS |
+			E_SOURCE_PARAM_SETTING));
+
+	g_object_class_install_property (
+		object_class,
+		PROP_IS_PUBLIC,
+		g_param_spec_boolean (
+			"is-public",
+			"Is Public",
+			"Folder is a public folder",
+			FALSE,
+			G_PARAM_READWRITE |
+			G_PARAM_STATIC_STRINGS |
+			E_SOURCE_PARAM_SETTING));
+
+	g_object_class_install_property (
+		object_class,
+		PROP_SERVER_NOTIFICATION,
+		g_param_spec_boolean (
+			"server-notification",
+			"Server Notification",
+			"Whether to listen for server notifications on this folder",
+			FALSE,
+			G_PARAM_READWRITE |
+			G_PARAM_STATIC_STRINGS |
+			E_SOURCE_PARAM_SETTING));
+
+	g_object_class_install_property (
+		object_class,
+		PROP_FOREIGN_USERNAME,
+		g_param_spec_string (
+			"foreign-username",
+			"Foreign Username",
+			"Set for folders belonging to other (foreign) users",
+			NULL,
+			G_PARAM_READWRITE |
+			G_PARAM_STATIC_STRINGS |
+			E_SOURCE_PARAM_SETTING));
+
+	g_object_class_install_property (
+		object_class,
+		PROP_ALLOW_PARTIAL,
+		g_param_spec_boolean (
+			"allow-partial",
+			"Allow Partial",
+			"Allow Partial fetching for GAL",
+			TRUE,
+			G_PARAM_READWRITE |
+			G_PARAM_STATIC_STRINGS |
+			E_SOURCE_PARAM_SETTING));
+
+	g_object_class_install_property (
+		object_class,
+		PROP_PARTIAL_COUNT,
+		g_param_spec_int (
+			"partial-count",
+			"Partial Count",
+			"Count of contacts for Partial fetching of GAL",
+			G_MININT, G_MAXINT, 50,
+			G_PARAM_READWRITE |
+			G_PARAM_STATIC_STRINGS |
+			E_SOURCE_PARAM_SETTING));
+}
+
+static void
+e_source_mapi_folder_class_finalize (ESourceMapiFolderClass *class)
+{
+}
+
+static void
+e_source_mapi_folder_init (ESourceMapiFolder *extension)
+{
+	extension->priv = E_SOURCE_MAPI_FOLDER_GET_PRIVATE (extension);
+	extension->priv->property_lock = g_mutex_new ();
+
+	extension->priv->fid = 0;
+	extension->priv->parent_fid = 0;
+	extension->priv->is_public = FALSE;
+	extension->priv->server_notification = FALSE;
+	extension->priv->foreign_username = NULL;
+	extension->priv->allow_partial = TRUE;
+	extension->priv->partial_count = 50;
+}
+
+void
+e_source_mapi_folder_type_register (GTypeModule *type_module)
+{
+	/* XXX G_DEFINE_DYNAMIC_TYPE declares a static type registration
+	 *     function, so we have to wrap it with a public function in
+	 *     order to register types from a separate compilation unit. */
+	e_source_mapi_folder_register_type (type_module);
+}
+
+guint64
+e_source_mapi_folder_get_id (ESourceMapiFolder *extension)
+{
+	g_return_val_if_fail (E_IS_SOURCE_MAPI_FOLDER (extension), 0);
+
+	return extension->priv->fid;
+}
+
+void
+e_source_mapi_folder_set_id (ESourceMapiFolder *extension,
+			     guint64 id)
+{
+	g_return_if_fail (E_IS_SOURCE_MAPI_FOLDER (extension));
+
+	if (extension->priv->fid == id)
+		return;
+
+	extension->priv->fid = id;
+
+	g_object_notify (G_OBJECT (extension), "id");
+}
+
+guint64
+e_source_mapi_folder_get_parent_id (ESourceMapiFolder *extension)
+{
+	g_return_val_if_fail (E_IS_SOURCE_MAPI_FOLDER (extension), 0);
+
+	return extension->priv->parent_fid;
+}
+
+void
+e_source_mapi_folder_set_parent_id (ESourceMapiFolder *extension,
+				    guint64 id)
+{
+	g_return_if_fail (E_IS_SOURCE_MAPI_FOLDER (extension));
+
+	if (extension->priv->parent_fid == id)
+		return;
+
+	extension->priv->parent_fid = id;
+
+	g_object_notify (G_OBJECT (extension), "parent-id");
+}
+
+gboolean
+e_source_mapi_folder_is_public (ESourceMapiFolder *extension)
+{
+	g_return_val_if_fail (E_IS_SOURCE_MAPI_FOLDER (extension), FALSE);
+
+	return extension->priv->is_public;
+}
+
+void
+e_source_mapi_folder_set_is_public (ESourceMapiFolder *extension,
+				    gboolean is_public)
+{
+	g_return_if_fail (E_IS_SOURCE_MAPI_FOLDER (extension));
+
+	if ((extension->priv->is_public ? 1 : 0) == (is_public ? 1 : 0))
+		return;
+
+	extension->priv->is_public = is_public;
+
+	g_object_notify (G_OBJECT (extension), "is-public");
+}
+
+gboolean
+e_source_mapi_folder_get_allow_partial (ESourceMapiFolder *extension)
+{
+	g_return_val_if_fail (E_IS_SOURCE_MAPI_FOLDER (extension), FALSE);
+
+	return extension->priv->allow_partial;
+}
+
+void
+e_source_mapi_folder_set_allow_partial (ESourceMapiFolder *extension,
+					gboolean allow_partial)
+{
+	g_return_if_fail (E_IS_SOURCE_MAPI_FOLDER (extension));
+
+	if ((extension->priv->allow_partial ? 1 : 0) == (allow_partial ? 1 : 0))
+		return;
+
+	extension->priv->allow_partial = allow_partial;
+
+	g_object_notify (G_OBJECT (extension), "allow-partial");
+}
+
+gint
+e_source_mapi_folder_get_partial_count (ESourceMapiFolder *extension)
+{
+	g_return_val_if_fail (E_IS_SOURCE_MAPI_FOLDER (extension), FALSE);
+
+	return extension->priv->partial_count;
+}
+
+void
+e_source_mapi_folder_set_partial_count (ESourceMapiFolder *extension,
+					gint partial_count)
+{
+	g_return_if_fail (E_IS_SOURCE_MAPI_FOLDER (extension));
+
+	if (extension->priv->partial_count == partial_count)
+		return;
+
+	extension->priv->partial_count = partial_count;
+
+	g_object_notify (G_OBJECT (extension), "partial-count");
+}
+
+gboolean
+e_source_mapi_folder_get_server_notification (ESourceMapiFolder *extension)
+{
+	g_return_val_if_fail (E_IS_SOURCE_MAPI_FOLDER (extension), FALSE);
+
+	return extension->priv->server_notification;
+}
+
+void
+e_source_mapi_folder_set_server_notification (ESourceMapiFolder *extension,
+					      gboolean server_notification)
+{
+	g_return_if_fail (E_IS_SOURCE_MAPI_FOLDER (extension));
+
+	if ((extension->priv->server_notification ? 1 : 0) == (server_notification ? 1 : 0))
+		return;
+
+	extension->priv->server_notification = server_notification;
+
+	g_object_notify (G_OBJECT (extension), "server-notification");
+}
+
+const gchar *
+e_source_mapi_folder_get_foreign_username (ESourceMapiFolder *extension)
+{
+	g_return_val_if_fail (E_IS_SOURCE_MAPI_FOLDER (extension), NULL);
+
+	return extension->priv->foreign_username;
+}
+
+gchar *
+e_source_mapi_folder_dup_foreign_username (ESourceMapiFolder *extension)
+{
+	gchar *duplicate;
+
+	g_return_val_if_fail (E_IS_SOURCE_MAPI_FOLDER (extension), NULL);
+
+	g_mutex_lock (extension->priv->property_lock);
+
+	duplicate = g_strdup (e_source_mapi_folder_get_foreign_username (extension));
+
+	g_mutex_unlock (extension->priv->property_lock);
+
+	return duplicate;
+}
+
+void
+e_source_mapi_folder_set_foreign_username (ESourceMapiFolder *extension,
+					  const gchar *foreign_username)
+{
+	g_return_if_fail (E_IS_SOURCE_MAPI_FOLDER (extension));
+
+	g_mutex_lock (extension->priv->property_lock);
+
+	if (foreign_username && !*foreign_username)
+		foreign_username = NULL;
+
+	if (g_strcmp0 (extension->priv->foreign_username, foreign_username) == 0) {
+		g_mutex_unlock (extension->priv->property_lock);
+		return;
+	}
+
+	g_free (extension->priv->foreign_username);
+	extension->priv->foreign_username = g_strdup (foreign_username);
+
+	g_mutex_unlock (extension->priv->property_lock);
+
+	g_object_notify (G_OBJECT (extension), "foreign-username");
+}
diff --git a/src/libexchangemapi/e-source-mapi-folder.h b/src/libexchangemapi/e-source-mapi-folder.h
new file mode 100644
index 0000000..4d7d620
--- /dev/null
+++ b/src/libexchangemapi/e-source-mapi-folder.h
@@ -0,0 +1,99 @@
+/*
+ * e-source-mapi-folder.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 E_SOURCE_MAPI_FOLDER_H
+#define E_SOURCE_MAPI_FOLDER_H
+
+#include <libedataserver/libedataserver.h>
+
+/* Standard GObject macros */
+#define E_TYPE_SOURCE_MAPI_FOLDER \
+	(e_source_mapi_folder_get_type ())
+#define E_SOURCE_MAPI_FOLDER(obj) \
+	(G_TYPE_CHECK_INSTANCE_CAST \
+	((obj), E_TYPE_SOURCE_MAPI_FOLDER, ESourceMapiFolder))
+#define E_SOURCE_MAPI_FOLDER_CLASS(cls) \
+	(G_TYPE_CHECK_CLASS_CAST \
+	((cls), E_TYPE_SOURCE_MAPI_FOLDER, ESourceMapiFolderClass))
+#define E_IS_SOURCE_MAPI_FOLDER(obj) \
+	(G_TYPE_CHECK_INSTANCE_TYPE \
+	((obj), E_TYPE_SOURCE_MAPI_FOLDER))
+#define E_IS_SOURCE_MAPI_FOLDER_CLASS(cls) \
+	(G_TYPE_CHECK_CLASS_TYPE \
+	((cls), E_TYPE_SOURCE_MAPI_FOLDER))
+#define E_SOURCE_MAPI_FOLDER_GET_CLASS(obj) \
+	(G_TYPE_INSTANCE_GET_CLASS \
+	((obj), E_TYPE_SOURCE_MAPI_FOLDER, ESourceMapiFolderClass))
+
+#define E_SOURCE_EXTENSION_MAPI_FOLDER "Exchange MAPI Folder"
+
+G_BEGIN_DECLS
+
+typedef struct _ESourceMapiFolder ESourceMapiFolder;
+typedef struct _ESourceMapiFolderClass ESourceMapiFolderClass;
+typedef struct _ESourceMapiFolderPrivate ESourceMapiFolderPrivate;
+
+struct _ESourceMapiFolder {
+	ESourceExtension parent;
+	ESourceMapiFolderPrivate *priv;
+};
+
+struct _ESourceMapiFolderClass {
+	ESourceExtensionClass parent_class;
+};
+
+GType		e_source_mapi_folder_get_type		(void) G_GNUC_CONST;
+void		e_source_mapi_folder_type_register	(GTypeModule *type_module);
+
+guint64		e_source_mapi_folder_get_id		(ESourceMapiFolder *extension);
+void		e_source_mapi_folder_set_id		(ESourceMapiFolder *extension,
+							 guint64 id);
+
+guint64		e_source_mapi_folder_get_parent_id	(ESourceMapiFolder *extension);
+void		e_source_mapi_folder_set_parent_id	(ESourceMapiFolder *extension,
+							 guint64 id);
+
+gboolean	e_source_mapi_folder_is_public		(ESourceMapiFolder *extension);
+void		e_source_mapi_folder_set_is_public	(ESourceMapiFolder *extension,
+							 gboolean is_public);
+
+gboolean	e_source_mapi_folder_get_allow_partial	(ESourceMapiFolder *extension);
+void		e_source_mapi_folder_set_allow_partial	(ESourceMapiFolder *extension,
+							 gboolean allow_partial);
+
+gint		e_source_mapi_folder_get_partial_count	(ESourceMapiFolder *extension);
+void		e_source_mapi_folder_set_partial_count	(ESourceMapiFolder *extension,
+							 gint partial_count);
+
+gboolean	e_source_mapi_folder_get_server_notification
+							(ESourceMapiFolder *extension);
+void		e_source_mapi_folder_set_server_notification
+							(ESourceMapiFolder *extension,
+							 gboolean server_notification);
+
+const gchar *	e_source_mapi_folder_get_foreign_username
+							(ESourceMapiFolder *extension);
+gchar *		e_source_mapi_folder_dup_foreign_username
+							(ESourceMapiFolder *extension);
+void		e_source_mapi_folder_set_foreign_username
+							(ESourceMapiFolder *extension,
+							 const gchar *foreign_username);
+
+G_END_DECLS
+
+#endif /* E_SOURCE_MAPI_FOLDER_H */



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