[evolution/account-mgmt: 20/48] Adapt mail to the new ESource API.



commit 8c3b42c4e04da289dca3e12099208a05a8f95926
Author: Matthew Barnes <mbarnes redhat com>
Date:   Wed Apr 13 10:30:40 2011 -0400

    Adapt mail to the new ESource API.

 mail/Makefile.am                |   37 +-
 mail/e-mail-authenticator.c     |  267 ++++++
 mail/e-mail-authenticator.h     |   76 ++
 mail/e-mail-backend.c           |  209 +++--
 mail/e-mail-folder-pane.c       |   17 +-
 mail/e-mail-migrate-accounts.c  | 1954 +++++++++++++++++++++++++++++++++++++++
 mail/e-mail-migrate.c           |  199 +----
 mail/e-mail-paned-view.c        |    8 +-
 mail/e-mail-reader-utils.c      |   26 +-
 mail/e-mail-reader.c            |   52 +-
 mail/e-mail-session-utils.c     |   37 +-
 mail/e-mail-session-utils.h     |    2 +
 mail/e-mail-session.c           |  591 ++++++++-----
 mail/e-mail-session.h           |    5 +-
 mail/e-mail-store.c             |  235 +++---
 mail/e-mail-store.h             |   11 +-
 mail/e-mail.h                   |    1 +
 mail/e-source-camel.c           |  565 +++++++++++
 mail/e-source-camel.h           |   83 ++
 mail/em-account-editor.c        |  114 +++-
 mail/em-account-editor.h        |    4 +
 mail/em-composer-utils.c        |  368 +++++---
 mail/em-composer-utils.h        |    6 +-
 mail/em-config.h                |    2 +-
 mail/em-filter-source-element.c |  112 +--
 mail/em-folder-tree-model.c     |  197 ++---
 mail/em-subscription-editor.c   |   19 +-
 mail/em-utils.c                 |  692 +++++++++------
 mail/em-utils.h                 |   39 +-
 mail/mail-config.c              |   27 +-
 mail/mail-config.h              |    1 -
 mail/mail-config.ui             |   50 -
 mail/mail-folder-cache.c        |   14 +-
 mail/mail-ops.c                 |  223 +++--
 mail/mail-send-recv.c           |   27 +-
 mail/mail-send-recv.h           |    3 +-
 mail/mail-vfolder.c             |   50 +-
 mail/mail.error.xml             |   28 -
 38 files changed, 4824 insertions(+), 1527 deletions(-)
---
diff --git a/mail/Makefile.am b/mail/Makefile.am
index 1ddbec6..73a7d56 100644
--- a/mail/Makefile.am
+++ b/mail/Makefile.am
@@ -46,17 +46,14 @@ libevolution_mail_la_CPPFLAGS =				\
 
 mailinclude_HEADERS =					\
 	e-mail.h					\
-	e-mail-view.h					\
-	e-mail-folder-pane.h				\
-	e-mail-message-pane.h				\
-	e-mail-paned-view.h				\
-	e-mail-notebook-view.h				\
 	e-mail-attachment-bar.h				\
+	e-mail-authenticator.h				\
 	e-mail-backend.h				\
 	e-mail-browser.h				\
 	e-mail-display.h				\
 	e-mail-enums.h					\
 	e-mail-enumtypes.h				\
+	e-mail-folder-pane.h				\
 	e-mail-folder-utils.h				\
 	e-mail-junk-filter.h				\
 	e-mail-junk-options.h				\
@@ -66,15 +63,20 @@ mailinclude_HEADERS =					\
 	e-mail-label-manager.h				\
 	e-mail-label-tree-view.h			\
 	e-mail-local.h					\
+	e-mail-message-pane.h				\
 	e-mail-migrate.h				\
-	e-mail-reader.h					\
+	e-mail-notebook-view.h				\
+	e-mail-paned-view.h				\
 	e-mail-reader-utils.h				\
-	e-mail-session.h				\
+	e-mail-reader.h					\
 	e-mail-session-utils.h				\
+	e-mail-session.h				\
 	e-mail-sidebar.h				\
-	e-mail-store.h					\
 	e-mail-store-utils.h				\
+	e-mail-store.h					\
 	e-mail-tag-editor.h				\
+	e-mail-view.h					\
+	e-source-camel.h				\
 	em-account-editor.h				\
 	em-composer-utils.h				\
 	em-config.h					\
@@ -120,16 +122,13 @@ mailinclude_HEADERS +=					\
 endif
 
 libevolution_mail_la_SOURCES =				\
-	e-mail-view.c					\
-	e-mail-folder-pane.c				\
-	e-mail-message-pane.c				\
-	e-mail-paned-view.c				\
-	e-mail-notebook-view.c				\
 	e-mail-attachment-bar.c				\
+	e-mail-authenticator.c				\
 	e-mail-backend.c				\
 	e-mail-browser.c				\
 	e-mail-display.c				\
 	e-mail-enumtypes.c				\
+	e-mail-folder-pane.c				\
 	e-mail-folder-utils.c				\
 	e-mail-junk-filter.c				\
 	e-mail-junk-options.c				\
@@ -139,15 +138,21 @@ libevolution_mail_la_SOURCES =				\
 	e-mail-label-manager.c				\
 	e-mail-label-tree-view.c			\
 	e-mail-local.c					\
+	e-mail-message-pane.c				\
 	e-mail-migrate.c				\
-	e-mail-reader.c					\
+	e-mail-migrate-accounts.c			\
+	e-mail-notebook-view.c				\
+	e-mail-paned-view.c				\
 	e-mail-reader-utils.c				\
-	e-mail-session.c				\
+	e-mail-reader.c					\
 	e-mail-session-utils.c				\
+	e-mail-session.c				\
 	e-mail-sidebar.c				\
-	e-mail-store.c					\
 	e-mail-store-utils.c				\
+	e-mail-store.c					\
 	e-mail-tag-editor.c				\
+	e-mail-view.c					\
+	e-source-camel.c				\
 	em-account-editor.c				\
 	em-composer-utils.c				\
 	em-config.c					\
diff --git a/mail/e-mail-authenticator.c b/mail/e-mail-authenticator.c
new file mode 100644
index 0000000..9729d35
--- /dev/null
+++ b/mail/e-mail-authenticator.c
@@ -0,0 +1,267 @@
+/*
+ * e-mail-authenticator.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-mail-authenticator.h"
+
+#include <config.h>
+#include <glib/gi18n-lib.h>
+
+#define E_MAIL_AUTHENTICATOR_GET_PRIVATE(obj) \
+	(G_TYPE_INSTANCE_GET_PRIVATE \
+	((obj), E_TYPE_MAIL_AUTHENTICATOR, EMailAuthenticatorPrivate))
+
+struct _EMailAuthenticatorPrivate {
+	CamelService *service;
+	gchar *mechanism;
+};
+
+enum {
+	PROP_0,
+	PROP_MECHANISM,
+	PROP_SERVICE
+};
+
+/* Forward Declarations */
+static void	e_mail_authenticator_interface_init
+				(ESourceAuthenticatorInterface *interface);
+
+G_DEFINE_TYPE_WITH_CODE (
+	EMailAuthenticator,
+	e_mail_authenticator,
+	G_TYPE_OBJECT,
+	G_IMPLEMENT_INTERFACE (
+		E_TYPE_SOURCE_AUTHENTICATOR,
+		e_mail_authenticator_interface_init))
+
+static void
+mail_authenticator_set_mechanism (EMailAuthenticator *auth,
+                                  const gchar *mechanism)
+{
+	g_return_if_fail (auth->priv->mechanism == NULL);
+
+	auth->priv->mechanism = g_strdup (mechanism);
+}
+
+static void
+mail_authenticator_set_service (EMailAuthenticator *auth,
+                                CamelService *service)
+{
+	g_return_if_fail (CAMEL_IS_SERVICE (service));
+	g_return_if_fail (auth->priv->service == NULL);
+
+	auth->priv->service = g_object_ref (service);
+}
+
+static void
+mail_authenticator_set_property (GObject *object,
+                                 guint property_id,
+                                 const GValue *value,
+                                 GParamSpec *pspec)
+{
+	switch (property_id) {
+		case PROP_MECHANISM:
+			mail_authenticator_set_mechanism (
+				E_MAIL_AUTHENTICATOR (object),
+				g_value_get_string (value));
+			return;
+
+		case PROP_SERVICE:
+			mail_authenticator_set_service (
+				E_MAIL_AUTHENTICATOR (object),
+				g_value_get_object (value));
+			return;
+	}
+
+	G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+mail_authenticator_get_property (GObject *object,
+                                 guint property_id,
+                                 GValue *value,
+                                 GParamSpec *pspec)
+{
+	switch (property_id) {
+		case PROP_MECHANISM:
+			g_value_set_string (
+				value,
+				e_mail_authenticator_get_mechanism (
+				E_MAIL_AUTHENTICATOR (object)));
+			return;
+
+		case PROP_SERVICE:
+			g_value_set_object (
+				value,
+				e_mail_authenticator_get_service (
+				E_MAIL_AUTHENTICATOR (object)));
+			return;
+	}
+
+	G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+mail_authenticator_dispose (GObject *object)
+{
+	EMailAuthenticatorPrivate *priv;
+
+	priv = E_MAIL_AUTHENTICATOR_GET_PRIVATE (object);
+
+	if (priv->service != NULL) {
+		g_object_unref (priv->service);
+		priv->service = NULL;
+	}
+
+	/* Chain up to parent's dispose() method. */
+	G_OBJECT_CLASS (e_mail_authenticator_parent_class)->dispose (object);
+}
+
+static void
+mail_authenticator_finalize (GObject *object)
+{
+	EMailAuthenticatorPrivate *priv;
+
+	priv = E_MAIL_AUTHENTICATOR_GET_PRIVATE (object);
+
+	g_free (priv->mechanism);
+
+	/* Chain up to parent's finalize() method. */
+	G_OBJECT_CLASS (e_mail_authenticator_parent_class)->finalize (object);
+}
+
+static ESourceAuthenticationResult
+mail_authenticator_try_password_sync (ESourceAuthenticator *auth,
+                                      const GString *password,
+                                      GCancellable *cancellable,
+                                      GError **error)
+{
+	CamelService *service;
+	EMailAuthenticator *mail_auth;
+	CamelAuthenticationResult camel_result;
+	ESourceAuthenticationResult source_result;
+	const gchar *mechanism;
+
+	mail_auth = E_MAIL_AUTHENTICATOR (auth);
+	service = e_mail_authenticator_get_service (mail_auth);
+	mechanism = e_mail_authenticator_get_mechanism (mail_auth);
+
+	camel_service_set_password (service, password->str);
+
+	camel_result = camel_service_authenticate_sync (
+		service, mechanism, cancellable, error);
+
+	switch (camel_result) {
+		case CAMEL_AUTHENTICATION_ERROR:
+			source_result = E_SOURCE_AUTHENTICATION_ERROR;
+			break;
+		case CAMEL_AUTHENTICATION_ACCEPTED:
+			source_result = E_SOURCE_AUTHENTICATION_ACCEPTED;
+			break;
+		case CAMEL_AUTHENTICATION_REJECTED:
+			source_result = E_SOURCE_AUTHENTICATION_REJECTED;
+			break;
+		default:
+			g_set_error (
+				error, CAMEL_SERVICE_ERROR,
+				CAMEL_SERVICE_ERROR_CANT_AUTHENTICATE,
+				_("Invalid authentication result code (%d)"),
+				camel_result);
+			source_result = E_SOURCE_AUTHENTICATION_ERROR;
+			break;
+	}
+
+	return source_result;
+}
+
+static void
+e_mail_authenticator_class_init (EMailAuthenticatorClass *class)
+{
+	GObjectClass *object_class;
+
+	g_type_class_add_private (class, sizeof (EMailAuthenticatorPrivate));
+
+	object_class = G_OBJECT_CLASS (class);
+	object_class->set_property = mail_authenticator_set_property;
+	object_class->get_property = mail_authenticator_get_property;
+	object_class->dispose = mail_authenticator_dispose;
+	object_class->finalize = mail_authenticator_finalize;
+
+	g_object_class_install_property (
+		object_class,
+		PROP_MECHANISM,
+		g_param_spec_string (
+			"mechanism",
+			"Mechanism",
+			"Authentication mechanism",
+			NULL,
+			G_PARAM_READWRITE |
+			G_PARAM_CONSTRUCT_ONLY |
+			G_PARAM_STATIC_STRINGS));
+
+	g_object_class_install_property (
+		object_class,
+		PROP_SERVICE,
+		g_param_spec_object (
+			"service",
+			"Service",
+			"The CamelService to authenticate",
+			CAMEL_TYPE_SERVICE,
+			G_PARAM_READWRITE |
+			G_PARAM_CONSTRUCT_ONLY |
+			G_PARAM_STATIC_STRINGS));
+}
+
+static void
+e_mail_authenticator_interface_init (ESourceAuthenticatorInterface *interface)
+{
+	interface->try_password_sync = mail_authenticator_try_password_sync;
+}
+
+static void
+e_mail_authenticator_init (EMailAuthenticator *auth)
+{
+	auth->priv = E_MAIL_AUTHENTICATOR_GET_PRIVATE (auth);
+}
+
+ESourceAuthenticator *
+e_mail_authenticator_new (CamelService *service,
+                          const gchar *mechanism)
+{
+	g_return_val_if_fail (CAMEL_IS_SERVICE (service), NULL);
+
+	return g_object_new (
+		E_TYPE_MAIL_AUTHENTICATOR,
+		"service", service, "mechanism", mechanism, NULL);
+}
+
+CamelService *
+e_mail_authenticator_get_service (EMailAuthenticator *auth)
+{
+	g_return_val_if_fail (E_IS_MAIL_AUTHENTICATOR (auth), NULL);
+
+	return auth->priv->service;
+}
+
+const gchar *
+e_mail_authenticator_get_mechanism (EMailAuthenticator *auth)
+{
+	g_return_val_if_fail (E_IS_MAIL_AUTHENTICATOR (auth), NULL);
+
+	return auth->priv->mechanism;
+}
+
diff --git a/mail/e-mail-authenticator.h b/mail/e-mail-authenticator.h
new file mode 100644
index 0000000..bcc3299
--- /dev/null
+++ b/mail/e-mail-authenticator.h
@@ -0,0 +1,76 @@
+/*
+ * e-mail-authenticator.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_AUTHENTICATOR_H
+#define E_MAIL_AUTHENTICATOR_H
+
+#include <camel/camel.h>
+#include <libedataserver/e-source-authenticator.h>
+
+/* Standard GObject macros */
+#define E_TYPE_MAIL_AUTHENTICATOR \
+	(e_mail_authenticator_get_type ())
+#define E_MAIL_AUTHENTICATOR(obj) \
+	(G_TYPE_CHECK_INSTANCE_CAST \
+	((obj), E_TYPE_MAIL_AUTHENTICATOR, EMailAuthenticator))
+#define E_MAIL_AUTHENTICATOR_CLASS(cls) \
+	(G_TYPE_CHECK_CLASS_CAST \
+	((cls), E_TYPE_MAIL_AUTHENTICATOR, EMailAuthenticatorClass))
+#define E_IS_MAIL_AUTHENTICATOR(obj) \
+	(G_TYPE_CHECK_INSTANCE_TYPE \
+	((obj), E_TYPE_MAIL_AUTHENTICATOR))
+#define E_IS_MAIL_AUTHENTICATOR_CLASS(cls) \
+	(G_TYPE_CHECK_CLASS_TYPE \
+	((cls), E_TYPE_MAIL_AUTHENTICATOR))
+#define E_MAIL_AUTHENTICATOR_GET_CLASS(obj) \
+	(G_TYPE_INSTANCE_GET_CLASS \
+	((obj), E_TYPE_MAIL_AUTHENTICATOR, EMailAuthenticatorClass))
+
+G_BEGIN_DECLS
+
+typedef struct _EMailAuthenticator EMailAuthenticator;
+typedef struct _EMailAuthenticatorClass EMailAuthenticatorClass;
+typedef struct _EMailAuthenticatorPrivate EMailAuthenticatorPrivate;
+
+/**
+ * EMailAuthenticator:
+ *
+ * Contains only private data that should be read and manipulated using the
+ * functions below.
+ **/
+struct _EMailAuthenticator {
+	GObject parent;
+	EMailAuthenticatorPrivate *priv;
+};
+
+struct _EMailAuthenticatorClass {
+	GObjectClass parent_class;
+};
+
+GType		e_mail_authenticator_get_type	(void);
+ESourceAuthenticator *
+		e_mail_authenticator_new	(CamelService *service,
+						 const gchar *mechanism);
+CamelService *	e_mail_authenticator_get_service
+						(EMailAuthenticator *auth);
+const gchar *	e_mail_authenticator_get_mechanism
+						(EMailAuthenticator *auth);
+
+G_END_DECLS
+
+#endif /* E_MAIL_AUTHENTICATOR_H */
diff --git a/mail/e-mail-backend.c b/mail/e-mail-backend.c
index aedbdd2..63e6da2 100644
--- a/mail/e-mail-backend.c
+++ b/mail/e-mail-backend.c
@@ -31,13 +31,12 @@
 #include <string.h>
 #include <glib/gstdio.h>
 #include <libedataserver/e-data-server-util.h>
+#include <libedataserver/e-source-mail-composition.h>
+#include <libedataserver/e-source-mail-submission.h>
 
-#include "e-util/e-account-utils.h"
 #include "e-util/e-alert-dialog.h"
 #include "e-util/e-alert-sink.h"
 
-#include "misc/e-account-combo-box.h"
-
 #include "shell/e-shell.h"
 
 #include "mail/e-mail-folder-utils.h"
@@ -46,6 +45,7 @@
 #include "mail/e-mail-session.h"
 #include "mail/e-mail-store.h"
 #include "mail/e-mail-store-utils.h"
+#include "mail/e-source-camel.h"
 #include "mail/em-event.h"
 #include "mail/em-folder-tree-model.h"
 #include "mail/em-utils.h"
@@ -271,7 +271,6 @@ mail_backend_prepare_for_quit_cb (EShell *shell,
                                   EActivity *activity,
                                   EMailBackend *backend)
 {
-	EAccountList *account_list;
 	EMailSession *session;
 	gboolean delete_junk;
 	gboolean empty_trash;
@@ -288,9 +287,6 @@ mail_backend_prepare_for_quit_cb (EShell *shell,
 
 	camel_application_is_exiting = TRUE;
 
-	account_list = e_get_account_list ();
-	e_account_list_prune_proxies (account_list);
-
 	mail_vfolder_shutdown ();
 
 	/* Cancel all pending activities. */
@@ -370,18 +366,24 @@ mail_backend_folder_deleted_cb (MailFolderCache *folder_cache,
                                 const gchar *folder_name,
                                 EMailBackend *backend)
 {
+	EShell *shell;
 	CamelStoreClass *class;
-	EAccountList *account_list;
-	EIterator *iterator;
+	ESourceRegistry *registry;
+	EShellBackend *shell_backend;
+	GList *list, *link;
+	const gchar *extension_name;
 	const gchar *local_drafts_folder_uri;
 	const gchar *local_sent_folder_uri;
-	gboolean write_config = FALSE;
 	gchar *uri;
 
 	/* Check whether the deleted folder was a designated Drafts or
 	 * Sent folder for any mail account, and if so revert the setting
 	 * to the equivalent local folder, which is always present. */
 
+	shell_backend = E_SHELL_BACKEND (backend);
+	shell = e_shell_backend_get_shell (shell_backend);
+	registry = e_shell_get_registry (shell);
+
 	class = CAMEL_STORE_GET_CLASS (store);
 	g_return_if_fail (class->compare_folder_name != NULL);
 
@@ -392,51 +394,69 @@ mail_backend_folder_deleted_cb (MailFolderCache *folder_cache,
 
 	uri = e_mail_folder_uri_build (store, folder_name);
 
-	account_list = e_get_account_list ();
-	iterator = e_list_get_iterator (E_LIST (account_list));
+	extension_name = E_SOURCE_EXTENSION_MAIL_COMPOSITION;
+	list = e_source_registry_list_sources (registry, extension_name);
+
+	for (link = list; link != NULL; link = g_list_next (link)) {
+		ESource *source = E_SOURCE (link->data);
+		ESourceExtension *extension;
+		const gchar *drafts_folder_uri;
 
-	while (e_iterator_is_valid (iterator)) {
-		EAccount *account;
+		extension = e_source_get_extension (source, extension_name);
 
-		/* XXX EIterator misuses const. */
-		account = (EAccount *) e_iterator_get (iterator);
+		drafts_folder_uri =
+			e_source_mail_composition_get_drafts_folder (
+			E_SOURCE_MAIL_COMPOSITION (extension));
 
-		if (account->sent_folder_uri != NULL) {
-			gboolean match;
+		if (class->compare_folder_name (drafts_folder_uri, uri)) {
+			GError *error = NULL;
 
-			match = class->compare_folder_name (
-				account->sent_folder_uri, uri);
+			e_source_mail_composition_set_drafts_folder (
+				E_SOURCE_MAIL_COMPOSITION (extension),
+				local_drafts_folder_uri);
 
-			if (match) {
-				g_free (account->sent_folder_uri);
-				account->sent_folder_uri =
-					g_strdup (local_sent_folder_uri);
-				write_config = TRUE;
+			/* FIXME This is a blocking D-Bus method call. */
+			if (!e_source_submit_sync (source, NULL, &error)) {
+				g_warning ("%s", error->message);
+				g_error_free (error);
 			}
 		}
+	}
+
+	g_list_free (list);
 
-		if (account->drafts_folder_uri != NULL) {
-			gboolean match;
+	extension_name = E_SOURCE_EXTENSION_MAIL_SUBMISSION;
+	list = e_source_registry_list_sources (registry, extension_name);
 
-			match = class->compare_folder_name (
-				account->drafts_folder_uri, uri);
+	for (link = list; link != NULL; link = g_list_next (link)) {
+		ESource *source = E_SOURCE (link->data);
+		ESourceExtension *extension;
+		const gchar *sent_folder_uri;
 
-			if (match) {
-				g_free (account->drafts_folder_uri);
-				account->drafts_folder_uri =
-					g_strdup (local_drafts_folder_uri);
-				write_config = TRUE;
+		extension = e_source_get_extension (source, extension_name);
+
+		sent_folder_uri =
+			e_source_mail_submission_get_sent_folder (
+			E_SOURCE_MAIL_SUBMISSION (extension));
+
+		if (class->compare_folder_name (sent_folder_uri, uri)) {
+			GError *error = NULL;
+
+			e_source_mail_submission_set_sent_folder (
+				E_SOURCE_MAIL_SUBMISSION (extension),
+				local_sent_folder_uri);
+
+			/* FIXME This is a blocking D-Bus method call. */
+			if (!e_source_submit_sync (source, NULL, &error)) {
+				g_warning ("%s", error->message);
+				g_error_free (error);
 			}
 		}
-
-		e_iterator_next (iterator);
 	}
 
-	g_object_unref (iterator);
-	g_free (uri);
+	g_list_free (list);
 
-	if (write_config)
-		mail_config_write ();
+	g_free (uri);
 
 	/* This does something completely different.
 	 * XXX Make it a separate signal handler? */
@@ -450,10 +470,12 @@ mail_backend_folder_renamed_cb (MailFolderCache *folder_cache,
                                 const gchar *new_folder_name,
                                 EMailBackend *backend)
 {
+	EShell *shell;
 	CamelStoreClass *class;
-	EAccountList *account_list;
-	EIterator *iterator;
-	gboolean write_config = FALSE;
+	ESourceRegistry *registry;
+	EShellBackend *shell_backend;
+	GList *list, *link;
+	const gchar *extension_name;
 	gchar *old_uri;
 	gchar *new_uri;
 	gint ii;
@@ -463,54 +485,84 @@ mail_backend_folder_renamed_cb (MailFolderCache *folder_cache,
 		"views/custom_view-"
 	};
 
+	/* Check whether the renamed folder was a designated Drafts or
+	 * Sent folder for any mail account, and if so update the setting
+	 * to the new folder name. */
+
+	shell_backend = E_SHELL_BACKEND (backend);
+	shell = e_shell_backend_get_shell (shell_backend);
+	registry = e_shell_get_registry (shell);
+
 	class = CAMEL_STORE_GET_CLASS (store);
 	g_return_if_fail (class->compare_folder_name != NULL);
 
 	old_uri = e_mail_folder_uri_build (store, old_folder_name);
 	new_uri = e_mail_folder_uri_build (store, new_folder_name);
 
-	account_list = e_get_account_list ();
-	iterator = e_list_get_iterator (E_LIST (account_list));
+	extension_name = E_SOURCE_EXTENSION_MAIL_COMPOSITION;
+	list = e_source_registry_list_sources (registry, extension_name);
+
+	for (link = list; link != NULL; link = g_list_next (link)) {
+		ESource *source = E_SOURCE (link->data);
+		ESourceExtension *extension;
+		const gchar *drafts_folder_uri;
 
-	while (e_iterator_is_valid (iterator)) {
-		EAccount *account;
+		extension = e_source_get_extension (source, extension_name);
 
-		/* XXX EIterator misuses const. */
-		account = (EAccount *) e_iterator_get (iterator);
+		drafts_folder_uri =
+			e_source_mail_composition_get_drafts_folder (
+			E_SOURCE_MAIL_COMPOSITION (extension));
 
-		if (account->sent_folder_uri != NULL) {
-			gboolean match;
+		if (class->compare_folder_name (drafts_folder_uri, old_uri)) {
+			GError *error = NULL;
 
-			match = class->compare_folder_name (
-				account->sent_folder_uri, old_uri);
+			e_source_mail_composition_set_drafts_folder (
+				E_SOURCE_MAIL_COMPOSITION (extension),
+				new_uri);
 
-			if (match) {
-				g_free (account->sent_folder_uri);
-				account->sent_folder_uri = g_strdup (new_uri);
-				write_config = TRUE;
+			/* FIXME This is a blocking D-Bus method call. */
+			if (!e_source_submit_sync (source, NULL, &error)) {
+				g_warning ("%s", error->message);
+				g_error_free (error);
 			}
 		}
+	}
+
+	g_list_free (list);
+
+	extension_name = E_SOURCE_EXTENSION_MAIL_SUBMISSION;
+	list = e_source_registry_list_sources (registry, extension_name);
+
+	for (link = list; link != NULL; link = g_list_next (link)) {
+		ESource *source = E_SOURCE (link->data);
+		ESourceExtension *extension;
+		const gchar *sent_folder_uri;
+
+		extension = e_source_get_extension (source, extension_name);
 
-		if (account->drafts_folder_uri != NULL) {
-			gboolean match;
+		sent_folder_uri =
+			e_source_mail_submission_get_sent_folder (
+			E_SOURCE_MAIL_SUBMISSION (extension));
 
-			match = class->compare_folder_name (
-				account->drafts_folder_uri, old_uri);
+		if (class->compare_folder_name (sent_folder_uri, old_uri)) {
+			GError *error = NULL;
 
-			if (match) {
-				g_free (account->drafts_folder_uri);
-				account->drafts_folder_uri = g_strdup (new_uri);
-				write_config = TRUE;
+			e_source_mail_submission_set_sent_folder (
+				E_SOURCE_MAIL_SUBMISSION (extension),
+				new_uri);
+
+			/* FIXME This is a blocking D-Bus method call. */
+			if (!e_source_submit_sync (source, NULL, &error)) {
+				g_warning ("%s", error->message);
+				g_error_free (error);
 			}
 		}
-
-		e_iterator_next (iterator);
 	}
 
-	g_object_unref (iterator);
+	g_list_free (list);
 
-	if (write_config)
-		mail_config_write ();
+	g_free (old_uri);
+	g_free (new_uri);
 
 	/* Rename GalView files. */
 
@@ -528,9 +580,6 @@ mail_backend_folder_renamed_cb (MailFolderCache *folder_cache,
 		g_free (newname);
 	}
 
-	g_free (old_uri);
-	g_free (new_uri);
-
 	/* This does something completely different.
 	 * XXX Make it a separate signal handler? */
 	mail_filter_rename_folder (
@@ -566,10 +615,8 @@ mail_backend_folder_changed_cb (MailFolderCache *folder_cache,
 			g_object_unref (folder);
 	}
 
-	g_free (folder_uri);
-
 	target = em_event_target_new_folder (
-		event, store, folder_name, new_messages,
+		event, store, folder_uri, new_messages,
 		msg_uid, msg_sender, msg_subject);
 
 	folder_type = (flags & CAMEL_FOLDER_TYPE_MASK);
@@ -746,6 +793,7 @@ mail_backend_constructed (GObject *object)
 	EShellBackend *shell_backend;
 	EMFolderTreeModel *folder_tree_model;
 	MailFolderCache *folder_cache;
+	ESourceRegistry *registry;
 
 	priv = E_MAIL_BACKEND_GET_PRIVATE (object);
 
@@ -755,9 +803,10 @@ mail_backend_constructed (GObject *object)
 	if (camel_init (e_get_user_data_dir (), TRUE) != 0)
 		exit (0);
 
-	camel_provider_init ();
+	e_source_camel_register_types ();
 
-	priv->session = e_mail_session_new ();
+	registry = e_shell_get_registry (shell);
+	priv->session = e_mail_session_new (registry);
 	folder_cache = e_mail_session_get_folder_cache (priv->session);
 
 	g_object_bind_property (
@@ -775,10 +824,6 @@ mail_backend_constructed (GObject *object)
 		G_CALLBACK (mail_backend_job_finished_cb),
 		shell_backend);
 
-	/* FIXME This is an evil hack that needs to die.
-	 *       Give EAccountComboBox a CamelSession property. */
-	e_account_combo_box_set_session (CAMEL_SESSION (priv->session));
-
 	/* FIXME EMailBackend should own the default EMFolderTreeModel. */
 	folder_tree_model = em_folder_tree_model_get_default ();
 
diff --git a/mail/e-mail-folder-pane.c b/mail/e-mail-folder-pane.c
index e9aa029..a8b164f 100644
--- a/mail/e-mail-folder-pane.c
+++ b/mail/e-mail-folder-pane.c
@@ -67,7 +67,10 @@ folder_pane_set_preview_visible (EMailView *view,
 static guint
 mail_paned_view_open_selected_mail (EMailPanedView *view)
 {
+	EShell *shell;
 	EMailReader *reader;
+	EMailBackend *backend;
+	ESourceRegistry *registry;
 	GPtrArray *uids;
 	gint i;
 	GtkWindow *window;
@@ -81,6 +84,10 @@ mail_paned_view_open_selected_mail (EMailPanedView *view)
 	uids = e_mail_reader_get_selected_uids (reader);
 	g_return_val_if_fail (uids != NULL, 0);
 
+	backend = e_mail_reader_get_backend (reader);
+	shell = e_shell_backend_get_shell (E_SHELL_BACKEND (backend));
+	registry = e_shell_get_registry (shell);
+
 	/* XXX Either e_mail_reader_get_selected_uids()
 	 *     or MessageList should do this itself. */
 	g_ptr_array_set_free_func (uids, (GDestroyNotify) g_free);
@@ -90,9 +97,9 @@ mail_paned_view_open_selected_mail (EMailPanedView *view)
 		return 0;
 	}
 
-	if (em_utils_folder_is_drafts (folder) ||
-		em_utils_folder_is_outbox (folder) ||
-		em_utils_folder_is_templates (folder)) {
+	if (em_utils_folder_is_drafts (registry, folder) ||
+		em_utils_folder_is_outbox (registry, folder) ||
+		em_utils_folder_is_templates (registry, folder)) {
 		em_utils_edit_messages (reader, folder, uids, TRUE);
 		g_ptr_array_unref (uids);
 		return 0;
@@ -120,8 +127,8 @@ mail_paned_view_open_selected_mail (EMailPanedView *view)
 			CAMEL_VEE_FOLDER (folder),
 			(CamelVeeMessageInfo *) info, &real_uid);
 
-		if (em_utils_folder_is_drafts (real_folder) ||
-			em_utils_folder_is_outbox (real_folder)) {
+		if (em_utils_folder_is_drafts (registry, real_folder) ||
+			em_utils_folder_is_outbox (registry, real_folder)) {
 			GPtrArray *edits;
 
 			edits = g_ptr_array_new_with_free_func (
diff --git a/mail/e-mail-migrate-accounts.c b/mail/e-mail-migrate-accounts.c
new file mode 100644
index 0000000..9af6c58
--- /dev/null
+++ b/mail/e-mail-migrate-accounts.c
@@ -0,0 +1,1954 @@
+/*
+ * e-mail-migrate-accounts.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 <errno.h>
+#include <string.h>
+#include <glib/gstdio.h>
+#include <camel/camel.h>
+#include <libsoup/soup.h>
+#include <gnome-keyring.h>
+
+#include <libedataserver/e-uid.h>
+#include <libedataserver/e-data-server-util.h>
+
+#include "e-source-camel.h"
+
+/* These constants are collected from various e-source-*.h files
+ * throughout evolution-data-server and known extension packages. */
+#define E_SOURCE_GROUP_NAME			"Data Source"
+#define E_SOURCE_EXTENSION_AUTHENTICATION	"Authentication"
+#define E_SOURCE_EXTENSION_MAIL_ACCOUNT		"Mail Account"
+#define E_SOURCE_EXTENSION_MAIL_COMPOSITION	"Mail Composition"
+#define E_SOURCE_EXTENSION_MAIL_IDENTITY	"Mail Identity"
+#define E_SOURCE_EXTENSION_MAIL_SIGNATURE	"Mail Signature"
+#define E_SOURCE_EXTENSION_MAIL_SUBMISSION	"Mail Submission"
+#define E_SOURCE_EXTENSION_MAIL_TRANSPORT	"Mail Transport"
+#define E_SOURCE_EXTENSION_OFFLINE		"Offline"
+#define E_SOURCE_EXTENSION_OPENPGP		"Pretty Good Privacy (OpenPGP)"
+#define E_SOURCE_EXTENSION_REFRESH		"Refresh"
+#define E_SOURCE_EXTENSION_SECURITY		"Security"
+#define E_SOURCE_EXTENSION_SMIME		"Secure MIME (S/MIME)"
+
+/* These constants are copied from e-source-password.c. */
+#define KEYRING_ITEM_ATTRIBUTE_NAME		"e-source-uid"
+#define KEYRING_ITEM_DISPLAY_FORMAT		"Evolution Data Source %s"
+
+typedef struct _ParseData ParseData;
+
+typedef enum {
+	PARSE_STATE_INITIAL,
+
+	PARSE_STATE_IN_GCONF,			/* GConf XML */
+	PARSE_STATE_IN_ACCOUNTS_ENTRY,		/* GConf XML */
+	PARSE_STATE_IN_ACCOUNTS_VALUE,		/* GConf XML */
+	PARSE_STATE_IN_SIGNATURES_ENTRY,	/* GConf XML */
+	PARSE_STATE_IN_SIGNATURES_VALUE,	/* GConf XML */
+
+	PARSE_STATE_IN_ACCOUNT,			/* EAccount XML */
+	PARSE_STATE_IN_IDENTITY,		/* EAccount XML */
+	PARSE_STATE_IN_IDENTITY_NAME,		/* EAccount XML */
+	PARSE_STATE_IN_IDENTITY_ADDR_SPEC,	/* EAccount XML */
+	PARSE_STATE_IN_IDENTITY_REPLY_TO,	/* EAccount XML */
+	PARSE_STATE_IN_IDENTITY_ORGANIZATION,	/* EAccount XML */
+	PARSE_STATE_IN_IDENTITY_SIGNATURE,	/* EAccount XML */
+	PARSE_STATE_IN_SOURCE,			/* EAccount XML */
+	PARSE_STATE_IN_SOURCE_URL,		/* EAccount XML */
+	PARSE_STATE_IN_TRANSPORT,		/* EAccount XML */
+	PARSE_STATE_IN_TRANSPORT_URL,		/* EAccount XML */
+	PARSE_STATE_IN_AUTO_CC,			/* EAccount XML */
+	PARSE_STATE_IN_AUTO_CC_RECIPIENTS,	/* EAccount XML */
+	PARSE_STATE_IN_AUTO_BCC,		/* EAccount XML */
+	PARSE_STATE_IN_AUTO_BCC_RECIPIENTS,	/* EAccount XML */
+	PARSE_STATE_IN_DRAFTS_FOLDER,		/* EAccount XML */
+	PARSE_STATE_IN_SENT_FOLDER,		/* EAccount XML */
+	PARSE_STATE_IN_RECEIPT_POLICY,		/* EAccount XML */
+	PARSE_STATE_IN_PGP,			/* EAccount XML */
+	PARSE_STATE_IN_PGP_KEY_ID,		/* EAccount XML */
+	PARSE_STATE_IN_SMIME,			/* EAccount XML */
+	PARSE_STATE_IN_SMIME_SIGN_KEY_ID,	/* EAccount XML */
+	PARSE_STATE_IN_SMIME_ENCRYPT_KEY_ID,	/* EAccount XML */
+
+	PARSE_STATE_IN_SIGNATURE,		/* ESignature XML */
+	PARSE_STATE_IN_FILENAME			/* ESignature XML */
+} ParseState;
+
+struct _ParseData {
+	ParseState state;
+
+	/* Set by <account> and <signature> tags. */
+	gchar *filename;
+	GKeyFile *key_file;
+
+	/* Set by <source> tags. */
+	gboolean auto_bcc;
+	gboolean auto_cc;
+
+	/* Set by <transport> tags. */
+	gchar *transport_filename;
+	GKeyFile *transport_key_file;
+
+	/* Set by <signature> tags. */
+	GFile *signature_file;
+	gboolean is_script;
+};
+
+static GnomeKeyringPasswordSchema schema = {
+	GNOME_KEYRING_ITEM_GENERIC_SECRET,
+	{
+		{ KEYRING_ITEM_ATTRIBUTE_NAME,
+		  GNOME_KEYRING_ATTRIBUTE_TYPE_STRING },
+		{ NULL, 0 }
+	}
+};
+
+/* Forward Declarations */
+void e_mail_migrate_sources (void);
+
+static ParseData *
+parse_data_new (void)
+{
+	ParseData *parse_data;
+
+	parse_data = g_slice_new0 (ParseData);
+	parse_data->state = PARSE_STATE_INITIAL;
+
+	return parse_data;
+}
+
+static void
+parse_data_free (ParseData *parse_data)
+{
+	/* Normally the allocated data in ParseData is freed and the
+	 * pointers are cleared before we get here.  But if an error
+	 * occurred we may leave data behind.  This cleans it up. */
+
+	g_free (parse_data->filename);
+	g_free (parse_data->transport_filename);
+
+	if (parse_data->key_file != NULL)
+		g_key_file_free (parse_data->key_file);
+
+	if (parse_data->transport_key_file != NULL)
+		g_key_file_free (parse_data->transport_key_file);
+
+	if (parse_data->signature_file != NULL)
+		g_object_unref (parse_data->signature_file);
+
+	g_slice_free (ParseData, parse_data);
+}
+
+static void
+migrate_keyring_entry (const gchar *uid,
+                       const CamelURL *url)
+{
+	GnomeKeyringAttributeList *attributes;
+	GList *found_list = NULL;
+	gchar *display_name;
+
+	/* This is a best-effort routine, so we don't really care about
+	 * errors.  We leave the old keyring entry in place since it may
+	 * be reused for address book or calendar migration. */
+
+	display_name = g_strdup_printf (KEYRING_ITEM_DISPLAY_FORMAT, uid);
+
+	attributes = gnome_keyring_attribute_list_new ();
+
+	gnome_keyring_attribute_list_append_string (
+		attributes, "application", "Evolution");
+	if (url->user != NULL)
+		gnome_keyring_attribute_list_append_string (
+			attributes, "user", url->user);
+	if (url->host != NULL)
+		gnome_keyring_attribute_list_append_string (
+			attributes, "server", url->host);
+	if (url->protocol != NULL)
+		gnome_keyring_attribute_list_append_string (
+			attributes, "protocol", url->protocol);
+
+	gnome_keyring_find_items_sync (
+		GNOME_KEYRING_ITEM_NETWORK_PASSWORD, attributes, &found_list);
+
+	/* Pick the first match we find. */
+	if (found_list != NULL) {
+		GnomeKeyringFound *found = found_list->data;
+
+		/* Sanity check. */
+		g_return_if_fail (found->secret != NULL);
+
+		gnome_keyring_store_password_sync (
+			&schema, GNOME_KEYRING_DEFAULT, display_name,
+			found->secret, KEYRING_ITEM_ATTRIBUTE_NAME, uid, NULL);
+	}
+
+	gnome_keyring_attribute_list_free (attributes);
+	gnome_keyring_found_list_free (found_list);
+
+	g_free (display_name);
+}
+
+static gboolean
+migrate_parse_commit_changes (const gchar *filename,
+                              GKeyFile *key_file,
+                              GError **error)
+{
+	gchar *contents;
+	gchar *uid;
+	gsize length;
+	gboolean success;
+
+	uid = g_path_get_basename (filename);
+
+	g_print ("  * Source: %s\n", uid);
+
+	g_print ("    Writing key file...\n");
+
+	/* Save the key file contents to disk. */
+	contents = g_key_file_to_data (key_file, &length, NULL);
+	success = g_file_set_contents (filename, contents, length, error);
+	g_free (contents);
+
+	g_free (uid);
+
+	return success;
+}
+
+static void
+migrate_parse_account (ParseData *parse_data,
+                       const gchar *element_name,
+                       const gchar **attribute_names,
+                       const gchar **attribute_values,
+                       GError **error)
+{
+	const gchar *uid;
+	const gchar *name;
+	const gchar *config_dir;
+	gchar *directory;
+	gchar *transport_uid;
+	gboolean enabled;
+	gboolean success;
+
+	success = g_markup_collect_attributes (
+		element_name,
+		attribute_names,
+		attribute_values,
+		error,
+		G_MARKUP_COLLECT_STRING,
+		"uid", &uid,
+		G_MARKUP_COLLECT_STRING,
+		"name", &name,
+		G_MARKUP_COLLECT_BOOLEAN,
+		"enabled", &enabled,
+		G_MARKUP_COLLECT_INVALID);
+
+	if (!success)
+		return;
+
+	config_dir = e_get_user_config_dir ();
+	directory = g_build_filename (config_dir, "sources", NULL);
+	g_mkdir_with_parents (directory, 0700);
+
+	parse_data->filename = g_build_filename (directory, uid, NULL);
+
+	/* If the file already exists, skip this source.  It may be that we
+	 * already migrated it, in which case we don't want to overwrite it. */
+	if (g_file_test (parse_data->filename, G_FILE_TEST_EXISTS))
+		return;
+
+	parse_data->key_file = g_key_file_new ();
+
+	transport_uid = e_uid_new ();
+	parse_data->transport_filename =
+		g_build_filename (directory, transport_uid, NULL);
+	parse_data->transport_key_file = g_key_file_new ();
+
+	g_key_file_set_string (
+		parse_data->key_file,
+		E_SOURCE_GROUP_NAME,
+		"DisplayName", name);
+
+	g_key_file_set_boolean (
+		parse_data->key_file,
+		E_SOURCE_GROUP_NAME,
+		"Enabled", enabled);
+
+	/* Mail account source doubles as an identity source. */
+	g_key_file_set_string (
+		parse_data->key_file,
+		E_SOURCE_EXTENSION_MAIL_ACCOUNT,
+		"IdentityUid", "self");
+
+	/* Mail account source references the transport source. */
+	g_key_file_set_string (
+		parse_data->key_file,
+		E_SOURCE_EXTENSION_MAIL_SUBMISSION,
+		"TransportUid", transport_uid);
+
+	/* Transport source gets the same display name. */
+	g_key_file_set_string (
+		parse_data->transport_key_file,
+		E_SOURCE_GROUP_NAME,
+		"DisplayName", name);
+
+	/* XXX Every key file group needs at least one key,
+	 *     so this stupid "Placeholder" key just ensures
+	 *     the [Mail Transport] group gets written to disk. */
+	g_key_file_set_string (
+		parse_data->transport_key_file,
+		E_SOURCE_EXTENSION_MAIL_TRANSPORT,
+		"Placeholder", "Disregard This");
+
+	g_free (directory);
+	g_free (transport_uid);
+}
+
+static void
+migrate_parse_pgp (ParseData *parse_data,
+                   const gchar *element_name,
+                   const gchar **attribute_names,
+                   const gchar **attribute_values,
+                   GError **error)
+{
+	const gchar *hash_algo;
+	gboolean always_sign;
+	gboolean always_trust;
+	gboolean encrypt_to_self;
+	gboolean no_imip_sign;
+	gboolean success;
+
+	success = g_markup_collect_attributes (
+		element_name,
+		attribute_names,
+		attribute_values,
+		error,
+		G_MARKUP_COLLECT_BOOLEAN,
+		"always-sign", &always_sign,
+		G_MARKUP_COLLECT_BOOLEAN,
+		"always-trust", &always_trust,
+		G_MARKUP_COLLECT_BOOLEAN,
+		"encrypt-to-self", &encrypt_to_self,
+		G_MARKUP_COLLECT_BOOLEAN,
+		"no-imip-sign", &no_imip_sign,
+		G_MARKUP_COLLECT_STRING |
+		G_MARKUP_COLLECT_OPTIONAL,
+		"hash-algo", &hash_algo,
+		G_MARKUP_COLLECT_INVALID);
+
+	if (!success)
+		return;
+
+	g_key_file_set_boolean (
+		parse_data->key_file,
+		E_SOURCE_EXTENSION_OPENPGP,
+		"AlwaysSign", always_sign);
+
+	g_key_file_set_boolean (
+		parse_data->key_file,
+		E_SOURCE_EXTENSION_OPENPGP,
+		"AlwaysTrust", always_trust);
+
+	g_key_file_set_boolean (
+		parse_data->key_file,
+		E_SOURCE_EXTENSION_OPENPGP,
+		"EncryptToSelf", encrypt_to_self);
+
+	if (hash_algo != NULL && *hash_algo != '\0')
+		g_key_file_set_string (
+			parse_data->key_file,
+			E_SOURCE_EXTENSION_OPENPGP,
+			"SigningAlgorithm", hash_algo);
+
+	/* XXX Don't know why this is under the <pgp>
+	 *     element, it applies to S/MIME as well.
+	 *     Also note we're inverting the setting. */
+	g_key_file_set_boolean (
+		parse_data->key_file,
+		E_SOURCE_EXTENSION_MAIL_COMPOSITION,
+		"SignImip", !no_imip_sign);
+}
+
+static void
+migrate_parse_recipients (ParseData *parse_data,
+                          const gchar *key,
+                          const gchar *recipients)
+{
+	CamelAddress *address;
+	CamelInternetAddress *inet_address;
+	gchar **string_list;
+	gint ii, length;
+	gsize index = 0;
+
+	if (recipients == NULL || *recipients == '\0')
+		return;
+
+	inet_address = camel_internet_address_new ();
+	address = CAMEL_ADDRESS (inet_address);
+
+	if (camel_address_decode (address, recipients) == -1)
+		goto exit;
+
+	length = camel_address_length (address);
+	string_list = g_new0 (gchar *, length + 1);
+
+	for (ii = 0; ii < length; ii++) {
+		const gchar *name, *addr;
+
+		if (!camel_internet_address_get (
+			inet_address, ii, &name, &addr))
+			continue;
+
+		string_list[index++] =
+			camel_internet_address_format_address (name, addr);
+	}
+
+	g_key_file_set_string_list (
+		parse_data->key_file,
+		E_SOURCE_EXTENSION_MAIL_COMPOSITION, key,
+		(const gchar *const *) string_list, index);
+
+	g_strfreev (string_list);
+
+exit:
+	g_object_unref (inet_address);
+}
+
+static void
+migrate_parse_smime (ParseData *parse_data,
+                     const gchar *element_name,
+                     const gchar **attribute_names,
+                     const gchar **attribute_values,
+                     GError **error)
+{
+	const gchar *hash_algo;
+	gboolean encrypt_default;
+	gboolean encrypt_to_self;
+	gboolean sign_default;
+	gboolean success;
+
+	success = g_markup_collect_attributes (
+		element_name,
+		attribute_names,
+		attribute_values,
+		error,
+		G_MARKUP_COLLECT_BOOLEAN,
+		"encrypt-default", &encrypt_default,
+		G_MARKUP_COLLECT_BOOLEAN,
+		"encrypt-to-self", &encrypt_to_self,
+		G_MARKUP_COLLECT_STRING |
+		G_MARKUP_COLLECT_OPTIONAL,
+		"hash-algo", &hash_algo,
+		G_MARKUP_COLLECT_BOOLEAN,
+		"sign-default", &sign_default,
+		G_MARKUP_COLLECT_INVALID);
+
+	if (!success)
+		return;
+
+	g_key_file_set_boolean (
+		parse_data->key_file,
+		E_SOURCE_EXTENSION_SMIME,
+		"EncryptByDefault", encrypt_default);
+
+	g_key_file_set_boolean (
+		parse_data->key_file,
+		E_SOURCE_EXTENSION_SMIME,
+		"EncryptToSelf", encrypt_to_self);
+
+	if (hash_algo != NULL && *hash_algo != '\0')
+		g_key_file_set_string (
+			parse_data->key_file,
+			E_SOURCE_EXTENSION_SMIME,
+			"SigningAlgorithm", hash_algo);
+
+	g_key_file_set_boolean (
+		parse_data->key_file,
+		E_SOURCE_EXTENSION_SMIME,
+		"SignByDefault", sign_default);
+}
+
+static void
+migrate_parse_source (ParseData *parse_data,
+                      const gchar *element_name,
+                      const gchar **attribute_names,
+                      const gchar **attribute_values,
+                      GError **error)
+{
+	const gchar *auto_check_timeout;
+	glong interval_minutes = 0;
+	gboolean auto_check;
+	gboolean success;
+
+	/* Disregard "keep-on-server" and "save-passwd" attributes. */
+	success = g_markup_collect_attributes (
+		element_name,
+		attribute_names,
+		attribute_values,
+		error,
+		G_MARKUP_COLLECT_BOOLEAN,
+		"auto-check", &auto_check,
+		G_MARKUP_COLLECT_STRING,
+		"auto-check-timeout", &auto_check_timeout,
+		G_MARKUP_COLLECT_BOOLEAN |
+		G_MARKUP_COLLECT_OPTIONAL,
+		"keep-on-server", NULL,
+		G_MARKUP_COLLECT_BOOLEAN |
+		G_MARKUP_COLLECT_OPTIONAL,
+		"save-passwd", NULL,
+		G_MARKUP_COLLECT_INVALID);
+
+	if (!success)
+		return;
+
+	if (auto_check_timeout != NULL)
+		interval_minutes = strtol (auto_check_timeout, NULL, 10);
+
+	g_key_file_set_boolean (
+		parse_data->key_file,
+		E_SOURCE_EXTENSION_REFRESH,
+		"Enabled", auto_check);
+
+	if (interval_minutes > 0)
+		g_key_file_set_integer (
+			parse_data->key_file,
+			E_SOURCE_EXTENSION_REFRESH,
+			"IntervalMinutes", interval_minutes);
+}
+
+static void
+migrate_parse_url_rename_params (CamelURL *url)
+{
+	/* This list includes known URL parameters from built-in providers
+	 * in Camel, as well as from evolution-exchange, evolution-groupwise,
+	 * and evolution-mapi.  Add more as needed. */
+	static struct {
+		const gchar *url_parameter;
+		const gchar *property_name;
+	} camel_url_conversion[] = {
+		{ "ad_auth",			"gc-auth-method" },
+		{ "ad_browse",			"gc-allow-browse" },
+		{ "ad_expand_groups",		"gc-expand-groups" },
+		{ "ad_limit",			"gc-results-limit" },
+		{ "ad_server",			"gc-server-name" },
+		{ "all_headers",		"fetch-headers" },
+		{ "basic_headers",		"fetch-headers" },
+		{ "cachedconn"			"concurrent-connections" },
+		{ "check_all",			"check-all" },
+		{ "check_lsub",			"check-subscribed" },
+		{ "command",			"shell-command" },
+		{ "delete_after",		"delete-after-days" },
+		{ "delete_expunged",		"delete-expunged" },
+		{ "disable_extensions",		"disable-extensions" },
+		{ "dotfolders",			"use-dot-folders" },
+		{ "filter",			"filter-inbox" },
+		{ "filter_junk",		"filter-junk" },
+		{ "filter_junk_inbox",		"filter-junk-inbox" },
+		{ "folder_hierarchy_relative",	"folder-hierarchy-relative" },
+		{ "imap_custom_headers",	"fetch-headers-extra" },
+		{ "keep_on_server",		"keep-on-server" },
+		{ "offline_sync",		"stay-synchronized" },
+		{ "override_namespace",		"use-namespace" },
+		{ "owa_path",			"owa-path" },
+		{ "owa_url",			"owa-url" },
+		{ "password_exp_warn_period",	"password-exp-warn-period" },
+		{ "real_junk_path",		"real-junk-path" },
+		{ "real_trash_path",		"real-trash-path" },
+		{ "show_short_notation",	"short-folder-names" },
+		{ "soap_port",			"soap-port" },
+		{ "ssl",			"security-method" },
+		{ "sync_offline",		"stay-synchronized" },
+		{ "use_command",		"use-shell-command" },
+		{ "use_idle",			"use-idle" },
+		{ "use_lsub",			"use-subscriptions" },
+		{ "use_qresync",		"use-qresync" },
+		{ "use_ssl",			"security-method" },
+		{ "xstatus",			"use-xstatus-headers" }
+	};
+
+	const gchar *param;
+	const gchar *use_param;
+	gint ii;
+
+	for (ii = 0; ii < G_N_ELEMENTS (camel_url_conversion); ii++) {
+		const gchar *key;
+		gpointer value;
+
+		key = camel_url_conversion[ii].url_parameter;
+		value = g_datalist_get_data (&url->params, key);
+
+		if (value == NULL)
+			continue;
+
+		g_datalist_remove_no_notify (&url->params, key);
+
+		key = camel_url_conversion[ii].property_name;
+
+		/* Deal with a few special enum cases where
+		 * the parameter value also needs renamed. */
+
+		if (strcmp (key, "all_headers") == 0) {
+			GEnumClass *enum_class;
+			GEnumValue *enum_value;
+
+			enum_class = g_type_class_ref (
+				CAMEL_TYPE_FETCH_HEADERS_TYPE);
+			enum_value = g_enum_get_value (
+				enum_class, CAMEL_FETCH_HEADERS_ALL);
+			if (enum_value != NULL) {
+				g_free (value);
+				value = g_strdup (enum_value->value_nick);
+			} else
+				g_warn_if_reached ();
+			g_type_class_unref (enum_class);
+		}
+
+		if (strcmp (key, "basic_headers") == 0) {
+			GEnumClass *enum_class;
+			GEnumValue *enum_value;
+
+			enum_class = g_type_class_ref (
+				CAMEL_TYPE_FETCH_HEADERS_TYPE);
+			enum_value = g_enum_get_value (
+				enum_class, CAMEL_FETCH_HEADERS_BASIC);
+			if (enum_value != NULL) {
+				g_free (value);
+				value = g_strdup (enum_value->value_nick);
+			} else
+				g_warn_if_reached ();
+			g_type_class_unref (enum_class);
+		}
+
+		if (strcmp (key, "imap_custom_headers") == 0)
+			g_strdelimit (value, " ", ',');
+
+		if (strcmp (key, "security-method") == 0) {
+			CamelNetworkSecurityMethod method;
+			GEnumClass *enum_class;
+			GEnumValue *enum_value;
+
+			if (strcmp (value, "always") == 0)
+				method = CAMEL_NETWORK_SECURITY_METHOD_SSL_ON_ALTERNATE_PORT;
+			else if (strcmp (value, "1") == 0)
+				method = CAMEL_NETWORK_SECURITY_METHOD_SSL_ON_ALTERNATE_PORT;
+			else if (strcmp (value, "when-possible") == 0)
+				method = CAMEL_NETWORK_SECURITY_METHOD_STARTTLS_ON_STANDARD_PORT;
+			else
+				method = CAMEL_NETWORK_SECURITY_METHOD_NONE;
+
+			enum_class = g_type_class_ref (
+				CAMEL_TYPE_NETWORK_SECURITY_METHOD);
+			enum_value = g_enum_get_value (enum_class, method);
+			if (enum_value != NULL) {
+				g_free (value);
+				value = g_strdup (enum_value->value_nick);
+			} else
+				g_warn_if_reached ();
+			g_type_class_unref (enum_class);
+		}
+
+		g_datalist_set_data_full (&url->params, key, value, g_free);
+	}
+
+	/* A few more adjustments...
+	 *
+	 * These are all CAMEL_PROVIDER_CONF_CHECKSPIN settings.  The spin
+	 * button value is bound to "param" and the checkbox state is bound
+	 * to "use-param".  The "use-param" settings are new.  If "param"
+	 * exists but no "use-param", then set "use-param" to "true". */
+
+	param = g_datalist_get_data (&url->params, "gc-results-limit");
+	use_param = g_datalist_get_data (&url->params, "use-gc-results-limit");
+	if (param != NULL && *param != '\0' && use_param == NULL) {
+		g_datalist_set_data_full (
+			&url->params, "use-gc-results-limit",
+			g_strdup ("true"), (GDestroyNotify) g_free);
+	}
+
+	param = g_datalist_get_data (&url->params, "kerberos");
+	if (g_strcmp0 (param, "required") == 0) {
+		g_datalist_set_data_full (
+			&url->params, "kerberos",
+			g_strdup ("true"), (GDestroyNotify) g_free);
+	}
+
+	param = g_datalist_get_data (
+		&url->params, "password-exp-warn-period");
+	use_param = g_datalist_get_data (
+		&url->params, "use-password-exp-warn-period");
+	if (param != NULL && *param != '\0' && use_param == NULL) {
+		g_datalist_set_data_full (
+			&url->params, "use-password-exp-warn-period",
+			g_strdup ("true"), (GDestroyNotify) g_free);
+	}
+
+	param = g_datalist_get_data (&url->params, "real-junk-path");
+	use_param = g_datalist_get_data (&url->params, "use-real-junk-path");
+	if (param != NULL && *param != '\0' && use_param == NULL) {
+		g_datalist_set_data_full (
+			&url->params, "use-real-junk-path",
+			g_strdup ("true"), (GDestroyNotify) g_free);
+	}
+
+	param = g_datalist_get_data (&url->params, "real-trash-path");
+	use_param = g_datalist_get_data (&url->params, "use-real-trash-path");
+	if (param != NULL && *param != '\0' && use_param == NULL) {
+		g_datalist_set_data_full (
+			&url->params, "use-real-trash-path",
+			g_strdup ("true"), (GDestroyNotify) g_free);
+	}
+}
+
+static void
+migrate_parse_url_foreach (GQuark key_id,
+                           const gchar *value,
+                           gpointer user_data)
+{
+	const gchar *param_name;
+	const gchar *key;
+
+	struct {
+		GKeyFile *key_file;
+		const gchar *group_name;
+	} *foreach_data = user_data;
+
+	g_return_if_fail (value != NULL);
+
+	param_name = g_quark_to_string (key_id);
+	key = e_source_parameter_to_key (param_name);
+
+	/* If the value is empty, then the mere
+	 * presence of the parameter implies TRUE. */
+	if (*value == '\0')
+		value = "true";
+
+	g_key_file_set_string (
+		foreach_data->key_file,
+		foreach_data->group_name,
+		key, value);
+}
+
+static void
+migrate_parse_url (GKeyFile *key_file,
+                   const gchar *filename,
+                   const gchar *url_string,
+                   GError **error)
+{
+	CamelURL *url;
+	const gchar *extension_name;
+	const gchar *value;
+	gchar *uid;
+
+	struct {
+		GKeyFile *key_file;
+		const gchar *group_name;
+	} foreach_data;
+
+	url = camel_url_new (url_string, error);
+	if (url == NULL)
+		return;
+
+	/* Rename URL params as necessary to match
+	 * their ESourceExtension property names. */
+	migrate_parse_url_rename_params (url);
+
+	extension_name = e_source_camel_get_extension_name (url->protocol);
+
+	/* Set authentication details. */
+
+	if (url->protocol != NULL)
+		g_key_file_set_string (
+			key_file,
+			E_SOURCE_GROUP_NAME,
+			"BackendName", url->protocol);
+
+	if (url->host != NULL)
+		g_key_file_set_string (
+			key_file,
+			E_SOURCE_EXTENSION_AUTHENTICATION,
+			"Host", url->host);
+
+	if (url->authmech != NULL)
+		g_key_file_set_string (
+			key_file,
+			E_SOURCE_EXTENSION_AUTHENTICATION,
+			"Method", url->authmech);
+
+	if (url->port > 0)
+		g_key_file_set_integer (
+			key_file,
+			E_SOURCE_EXTENSION_AUTHENTICATION,
+			"Port", url->port);
+
+	if (url->user != NULL)
+		g_key_file_set_string (
+			key_file,
+			E_SOURCE_EXTENSION_AUTHENTICATION,
+			"User", url->user);
+
+	/* Pick out particular URL parameters we know about. */
+
+	/* If set, this should be "true" or "false",
+	 * but we'll just write it like it's a string. */
+	value = g_datalist_get_data (&url->params, "stay-synchronized");
+	if (value != NULL)
+		g_key_file_set_string (
+			key_file,
+			E_SOURCE_EXTENSION_OFFLINE,
+			"StaySynchronized", value);
+	g_datalist_set_data (&url->params, "stay-synchronized", NULL);
+
+	value = g_datalist_get_data (&url->params, "security-method");
+	if (value != NULL)
+		g_key_file_set_string (
+			key_file,
+			E_SOURCE_EXTENSION_SECURITY,
+			"Method", value);
+	g_datalist_set_data (&url->params, "security-method", NULL);
+
+	/* The rest of the URL parameters go in the backend group. */
+
+	foreach_data.key_file = key_file;
+	foreach_data.group_name = extension_name;
+
+	g_datalist_foreach (
+		&url->params, (GDataForeachFunc)
+		migrate_parse_url_foreach, &foreach_data);
+
+	uid = g_path_get_basename (filename);
+	migrate_keyring_entry (uid, url);
+	g_free (uid);
+
+	camel_url_free (url);
+}
+
+static void
+migrate_parse_account_xml_start_element (GMarkupParseContext *context,
+                                         const gchar *element_name,
+                                         const gchar **attribute_names,
+                                         const gchar **attribute_values,
+                                         gpointer user_data,
+                                         GError **error)
+{
+	ParseData *parse_data = user_data;
+
+	if (g_strcmp0 (element_name, "account") == 0) {
+		if (parse_data->state != PARSE_STATE_IN_ACCOUNTS_VALUE)
+			goto invalid_content;
+
+		parse_data->state = PARSE_STATE_IN_ACCOUNT;
+
+		migrate_parse_account (
+			parse_data,
+			element_name,
+			attribute_names,
+			attribute_values,
+			error);
+
+		return;
+	}
+
+	if (g_strcmp0 (element_name, "addr-spec") == 0) {
+		if (parse_data->state != PARSE_STATE_IN_IDENTITY)
+			goto invalid_content;
+
+		parse_data->state = PARSE_STATE_IN_IDENTITY_ADDR_SPEC;
+
+		return;
+	}
+
+	if (g_strcmp0 (element_name, "auto-bcc") == 0) {
+		if (parse_data->state != PARSE_STATE_IN_ACCOUNT)
+			goto invalid_content;
+
+		parse_data->state = PARSE_STATE_IN_AUTO_BCC;
+
+		g_markup_collect_attributes (
+			element_name,
+			attribute_names,
+			attribute_values,
+			error,
+			G_MARKUP_COLLECT_BOOLEAN,
+			"always", &parse_data->auto_bcc,
+			G_MARKUP_COLLECT_INVALID);
+
+		return;
+	}
+
+	if (g_strcmp0 (element_name, "auto-cc") == 0) {
+		if (parse_data->state != PARSE_STATE_IN_ACCOUNT)
+			goto invalid_content;
+
+		parse_data->state = PARSE_STATE_IN_AUTO_CC;
+
+		g_markup_collect_attributes (
+			element_name,
+			attribute_names,
+			attribute_values,
+			error,
+			G_MARKUP_COLLECT_BOOLEAN,
+			"always", &parse_data->auto_cc,
+			G_MARKUP_COLLECT_INVALID);
+
+		return;
+	}
+
+	if (g_strcmp0 (element_name, "drafts-folder") == 0) {
+		if (parse_data->state != PARSE_STATE_IN_ACCOUNT)
+			goto invalid_content;
+
+		parse_data->state = PARSE_STATE_IN_DRAFTS_FOLDER;
+
+		return;
+	}
+
+	if (g_strcmp0 (element_name, "encrypt-key-id") == 0) {
+		if (parse_data->state != PARSE_STATE_IN_SMIME)
+			goto invalid_content;
+
+		parse_data->state = PARSE_STATE_IN_SMIME_ENCRYPT_KEY_ID;
+
+		return;
+	}
+
+	if (g_strcmp0 (element_name, "identity") == 0) {
+		if (parse_data->state != PARSE_STATE_IN_ACCOUNT)
+			goto invalid_content;
+
+		parse_data->state = PARSE_STATE_IN_IDENTITY;
+
+		return;
+	}
+
+	if (g_strcmp0 (element_name, "key-id") == 0) {
+		if (parse_data->state != PARSE_STATE_IN_PGP)
+			goto invalid_content;
+
+		parse_data->state = PARSE_STATE_IN_PGP_KEY_ID;
+
+		return;
+	}
+
+	if (g_strcmp0 (element_name, "name") == 0) {
+		if (parse_data->state != PARSE_STATE_IN_IDENTITY)
+			goto invalid_content;
+
+		parse_data->state = PARSE_STATE_IN_IDENTITY_NAME;
+
+		return;
+	}
+
+	if (g_strcmp0 (element_name, "reply-to") == 0) {
+		if (parse_data->state != PARSE_STATE_IN_IDENTITY)
+			goto invalid_content;
+
+		parse_data->state = PARSE_STATE_IN_IDENTITY_REPLY_TO;
+
+		return;
+	}
+
+	if (g_strcmp0 (element_name, "organization") == 0) {
+		if (parse_data->state != PARSE_STATE_IN_IDENTITY)
+			goto invalid_content;
+
+		parse_data->state = PARSE_STATE_IN_IDENTITY_ORGANIZATION;
+
+		return;
+	}
+
+	if (g_strcmp0 (element_name, "pgp") == 0) {
+		if (parse_data->state != PARSE_STATE_IN_ACCOUNT)
+			goto invalid_content;
+
+		parse_data->state = PARSE_STATE_IN_PGP;
+
+		migrate_parse_pgp (
+			parse_data,
+			element_name,
+			attribute_names,
+			attribute_values,
+			error);
+
+		return;
+	}
+
+	if (g_strcmp0 (element_name, "receipt-policy") == 0) {
+		const gchar *policy;
+		gboolean success;
+
+		if (parse_data->state != PARSE_STATE_IN_ACCOUNT)
+			goto invalid_content;
+
+		parse_data->state = PARSE_STATE_IN_RECEIPT_POLICY;
+
+		success = g_markup_collect_attributes (
+			element_name,
+			attribute_names,
+			attribute_values,
+			error,
+			G_MARKUP_COLLECT_STRING,
+			"policy", &policy,
+			G_MARKUP_COLLECT_INVALID);
+
+		/* The new enum strings match the old ones. */
+		if (success && policy != NULL)
+			g_key_file_set_string (
+				parse_data->key_file,
+				E_SOURCE_EXTENSION_MAIL_ACCOUNT,
+				"MdnRequestPolicy", policy);
+
+		return;
+	}
+
+	if (g_strcmp0 (element_name, "recipients") == 0) {
+		if (parse_data->state == PARSE_STATE_IN_AUTO_BCC) {
+			parse_data->state = PARSE_STATE_IN_AUTO_BCC_RECIPIENTS;
+			return;
+		}
+
+		if (parse_data->state == PARSE_STATE_IN_AUTO_CC) {
+			parse_data->state = PARSE_STATE_IN_AUTO_CC_RECIPIENTS;
+			return;
+		}
+
+		goto invalid_content;
+	}
+
+	if (g_strcmp0 (element_name, "sent-folder") == 0) {
+		if (parse_data->state != PARSE_STATE_IN_ACCOUNT)
+			goto invalid_content;
+
+		parse_data->state = PARSE_STATE_IN_SENT_FOLDER;
+
+		return;
+	}
+
+	if (g_strcmp0 (element_name, "signature") == 0) {
+		const gchar *uid;
+		gboolean success;
+
+		if (parse_data->state != PARSE_STATE_IN_IDENTITY)
+			goto invalid_content;
+
+		parse_data->state = PARSE_STATE_IN_IDENTITY_SIGNATURE;
+
+		success = g_markup_collect_attributes (
+			element_name,
+			attribute_names,
+			attribute_values,
+			error,
+			G_MARKUP_COLLECT_STRING,
+			"uid", &uid,
+			G_MARKUP_COLLECT_INVALID);
+
+		if (success && uid != NULL)
+			g_key_file_set_string (
+				parse_data->key_file,
+				E_SOURCE_EXTENSION_MAIL_IDENTITY,
+				"SignatureUid", uid);
+
+		return;
+	}
+
+	if (g_strcmp0 (element_name, "sign-key-id") == 0) {
+		if (parse_data->state != PARSE_STATE_IN_SMIME)
+			goto invalid_content;
+
+		parse_data->state = PARSE_STATE_IN_SMIME_SIGN_KEY_ID;
+
+		return;
+	}
+
+	if (g_strcmp0 (element_name, "smime") == 0) {
+		if (parse_data->state != PARSE_STATE_IN_ACCOUNT)
+			goto invalid_content;
+
+		parse_data->state = PARSE_STATE_IN_SMIME;
+
+		migrate_parse_smime (
+			parse_data,
+			element_name,
+			attribute_names,
+			attribute_values,
+			error);
+
+		return;
+	}
+
+	if (g_strcmp0 (element_name, "source") == 0) {
+		if (parse_data->state != PARSE_STATE_IN_ACCOUNT)
+			goto invalid_content;
+
+		parse_data->state = PARSE_STATE_IN_SOURCE;
+
+		migrate_parse_source (
+			parse_data,
+			element_name,
+			attribute_names,
+			attribute_values,
+			error);
+
+		return;
+	}
+
+	if (g_strcmp0 (element_name, "transport") == 0) {
+		if (parse_data->state != PARSE_STATE_IN_ACCOUNT)
+			goto invalid_content;
+
+		parse_data->state = PARSE_STATE_IN_TRANSPORT;
+
+		return;
+	}
+
+	if (g_strcmp0 (element_name, "url") == 0) {
+		if (parse_data->state == PARSE_STATE_IN_SOURCE) {
+			parse_data->state = PARSE_STATE_IN_SOURCE_URL;
+			return;
+		}
+
+		if (parse_data->state == PARSE_STATE_IN_TRANSPORT) {
+			parse_data->state = PARSE_STATE_IN_TRANSPORT_URL;
+			return;
+		}
+
+		goto invalid_content;
+	}
+
+	g_set_error (
+		error, G_MARKUP_ERROR, G_MARKUP_ERROR_UNKNOWN_ELEMENT,
+		"Unknown element <%s>", element_name);
+
+	return;
+
+invalid_content:
+
+	g_set_error (
+		error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
+		"Element <%s> at unexpected location", element_name);
+}
+
+static void
+migrate_parse_account_xml_end_element (GMarkupParseContext *context,
+                                       const gchar *element_name,
+                                       gpointer user_data,
+                                       GError **error)
+{
+	ParseData *parse_data = user_data;
+
+	if (g_strcmp0 (element_name, "account") == 0) {
+		if (parse_data->state == PARSE_STATE_IN_ACCOUNT) {
+			parse_data->state = PARSE_STATE_IN_ACCOUNTS_VALUE;
+
+			/* Clean up <account> tag data. */
+
+			/* The key file will be NULL if we decided to skip it.
+			 * e.g. A file with the same UID may already exist. */
+			if (parse_data->key_file != NULL) {
+				GError *local_error = NULL;
+
+				migrate_parse_commit_changes (
+					parse_data->filename,
+					parse_data->key_file,
+					&local_error);
+
+				if (local_error != NULL) {
+					g_printerr (
+						"  FAILED: %s\n",
+						local_error->message);
+					g_error_free (local_error);
+				}
+
+				g_key_file_free (parse_data->key_file);
+				parse_data->key_file = NULL;
+			}
+
+			/* Same deal for the transport key file. */
+			if (parse_data->transport_key_file != NULL) {
+				GError *local_error = NULL;
+
+				migrate_parse_commit_changes (
+					parse_data->transport_filename,
+					parse_data->transport_key_file,
+					&local_error);
+
+				if (local_error != NULL) {
+					g_printerr (
+						"  FAILED: %s\n",
+						local_error->message);
+					g_error_free (local_error);
+				}
+
+				g_key_file_free (parse_data->transport_key_file);
+				parse_data->transport_key_file = NULL;
+			}
+
+			g_free (parse_data->filename);
+			parse_data->filename = NULL;
+
+			g_free (parse_data->transport_filename);
+			parse_data->transport_filename = NULL;
+		}
+		return;
+	}
+
+	if (g_strcmp0 (element_name, "addr-spec") == 0) {
+		if (parse_data->state == PARSE_STATE_IN_IDENTITY_ADDR_SPEC)
+			parse_data->state = PARSE_STATE_IN_IDENTITY;
+		return;
+	}
+
+	if (g_strcmp0 (element_name, "auto-bcc") == 0) {
+		if (parse_data->state == PARSE_STATE_IN_AUTO_BCC)
+			parse_data->state = PARSE_STATE_IN_ACCOUNT;
+		return;
+	}
+
+	if (g_strcmp0 (element_name, "auto-cc") == 0) {
+		if (parse_data->state == PARSE_STATE_IN_AUTO_CC)
+			parse_data->state = PARSE_STATE_IN_ACCOUNT;
+		return;
+	}
+
+	if (g_strcmp0 (element_name, "drafts-folder") == 0) {
+		if (parse_data->state == PARSE_STATE_IN_DRAFTS_FOLDER)
+			parse_data->state = PARSE_STATE_IN_ACCOUNT;
+		return;
+	}
+
+	if (g_strcmp0 (element_name, "encrypt-key-id") == 0) {
+		if (parse_data->state == PARSE_STATE_IN_SMIME_ENCRYPT_KEY_ID)
+			parse_data->state = PARSE_STATE_IN_SMIME;
+		return;
+	}
+
+	if (g_strcmp0 (element_name, "identity") == 0) {
+		if (parse_data->state == PARSE_STATE_IN_IDENTITY)
+			parse_data->state = PARSE_STATE_IN_ACCOUNT;
+		return;
+	}
+
+	if (g_strcmp0 (element_name, "key-id") == 0) {
+		if (parse_data->state == PARSE_STATE_IN_PGP_KEY_ID)
+			parse_data->state = PARSE_STATE_IN_PGP;
+		return;
+	}
+
+	if (g_strcmp0 (element_name, "name") == 0) {
+		if (parse_data->state == PARSE_STATE_IN_IDENTITY_NAME)
+			parse_data->state = PARSE_STATE_IN_IDENTITY;
+		return;
+	}
+
+	if (g_strcmp0 (element_name, "organization") == 0) {
+		if (parse_data->state == PARSE_STATE_IN_IDENTITY_ORGANIZATION)
+			parse_data->state = PARSE_STATE_IN_IDENTITY;
+		return;
+	}
+
+	if (g_strcmp0 (element_name, "pgp") == 0) {
+		if (parse_data->state == PARSE_STATE_IN_PGP)
+			parse_data->state = PARSE_STATE_IN_ACCOUNT;
+		return;
+	}
+
+	if (g_strcmp0 (element_name, "receipt-policy") == 0) {
+		if (parse_data->state == PARSE_STATE_IN_RECEIPT_POLICY)
+			parse_data->state = PARSE_STATE_IN_ACCOUNT;
+		return;
+	}
+
+	if (g_strcmp0 (element_name, "recipients") == 0) {
+		if (parse_data->state == PARSE_STATE_IN_AUTO_BCC_RECIPIENTS)
+			parse_data->state = PARSE_STATE_IN_AUTO_BCC;
+		if (parse_data->state == PARSE_STATE_IN_AUTO_CC_RECIPIENTS)
+			parse_data->state = PARSE_STATE_IN_AUTO_CC;
+		return;
+	}
+
+	if (g_strcmp0 (element_name, "reply-to") == 0) {
+		if (parse_data->state == PARSE_STATE_IN_IDENTITY_REPLY_TO)
+			parse_data->state = PARSE_STATE_IN_IDENTITY;
+		return;
+	}
+
+	if (g_strcmp0 (element_name, "sent-folder") == 0) {
+		if (parse_data->state == PARSE_STATE_IN_SENT_FOLDER)
+			parse_data->state = PARSE_STATE_IN_ACCOUNT;
+		return;
+	}
+
+	if (g_strcmp0 (element_name, "signature") == 0) {
+		if (parse_data->state == PARSE_STATE_IN_IDENTITY_SIGNATURE)
+			parse_data->state = PARSE_STATE_IN_IDENTITY;
+		return;
+	}
+
+	if (g_strcmp0 (element_name, "sign-key-id") == 0) {
+		if (parse_data->state == PARSE_STATE_IN_SMIME_SIGN_KEY_ID)
+			parse_data->state = PARSE_STATE_IN_SMIME;
+		return;
+	}
+
+	if (g_strcmp0 (element_name, "smime") == 0) {
+		if (parse_data->state == PARSE_STATE_IN_SMIME)
+			parse_data->state = PARSE_STATE_IN_ACCOUNT;
+		return;
+	}
+
+	if (g_strcmp0 (element_name, "source") == 0) {
+		if (parse_data->state == PARSE_STATE_IN_SOURCE)
+			parse_data->state = PARSE_STATE_IN_ACCOUNT;
+		return;
+	}
+
+	if (g_strcmp0 (element_name, "transport") == 0) {
+		if (parse_data->state == PARSE_STATE_IN_TRANSPORT)
+			parse_data->state = PARSE_STATE_IN_ACCOUNT;
+		return;
+	}
+
+	if (g_strcmp0 (element_name, "url") == 0) {
+		if (parse_data->state == PARSE_STATE_IN_SOURCE_URL)
+			parse_data->state = PARSE_STATE_IN_SOURCE;
+		if (parse_data->state == PARSE_STATE_IN_TRANSPORT_URL)
+			parse_data->state = PARSE_STATE_IN_TRANSPORT;
+		return;
+	}
+}
+
+static void
+migrate_parse_account_xml_text (GMarkupParseContext *context,
+                                const gchar *text,
+                                gsize text_len,
+                                gpointer user_data,
+                                GError **error)
+{
+	ParseData *parse_data = user_data;
+
+	switch (parse_data->state) {
+		case PARSE_STATE_IN_AUTO_BCC_RECIPIENTS:
+			/* Disregard the recipient list if
+			 * we're not going to auto-BCC them. */
+			if (parse_data->auto_bcc)
+				migrate_parse_recipients (
+					parse_data, "Bcc", text);
+			break;
+
+		case PARSE_STATE_IN_AUTO_CC_RECIPIENTS:
+			/* Disregard the recipient list if
+			 * we're not going to auto-CC them. */
+			if (parse_data->auto_cc)
+				migrate_parse_recipients (
+					parse_data, "Cc", text);
+			break;
+
+		case PARSE_STATE_IN_DRAFTS_FOLDER:
+			g_key_file_set_string (
+				parse_data->key_file,
+				E_SOURCE_EXTENSION_MAIL_COMPOSITION,
+				"DraftsFolder", text);
+			break;
+
+		case PARSE_STATE_IN_SMIME_ENCRYPT_KEY_ID:
+			g_key_file_set_string (
+				parse_data->key_file,
+				E_SOURCE_EXTENSION_SMIME,
+				"EncryptionCertificate", text);
+			break;
+
+		case PARSE_STATE_IN_IDENTITY_ADDR_SPEC:
+			g_key_file_set_string (
+				parse_data->key_file,
+				E_SOURCE_EXTENSION_MAIL_IDENTITY,
+				"Address", text);
+			break;
+
+		case PARSE_STATE_IN_IDENTITY_NAME:
+			g_key_file_set_string (
+				parse_data->key_file,
+				E_SOURCE_EXTENSION_MAIL_IDENTITY,
+				"Name", text);
+			break;
+
+		case PARSE_STATE_IN_IDENTITY_ORGANIZATION:
+			g_key_file_set_string (
+				parse_data->key_file,
+				E_SOURCE_EXTENSION_MAIL_IDENTITY,
+				"Organization", text);
+			break;
+
+		case PARSE_STATE_IN_IDENTITY_REPLY_TO:
+			g_key_file_set_string (
+				parse_data->key_file,
+				E_SOURCE_EXTENSION_MAIL_IDENTITY,
+				"ReplyTo", text);
+			break;
+
+		case PARSE_STATE_IN_PGP_KEY_ID:
+			g_key_file_set_string (
+				parse_data->key_file,
+				E_SOURCE_EXTENSION_OPENPGP,
+				"KeyId", text);
+			break;
+
+		case PARSE_STATE_IN_SENT_FOLDER:
+			g_key_file_set_string (
+				parse_data->key_file,
+				E_SOURCE_EXTENSION_MAIL_SUBMISSION,
+				"SentFolder", text);
+			break;
+
+		case PARSE_STATE_IN_SMIME_SIGN_KEY_ID:
+			g_key_file_set_string (
+				parse_data->key_file,
+				E_SOURCE_EXTENSION_SMIME,
+				"SigningCertificate", text);
+			break;
+
+		case PARSE_STATE_IN_SOURCE_URL:
+			migrate_parse_url (
+				parse_data->key_file,
+				parse_data->filename,
+				text, error);
+			break;
+
+		case PARSE_STATE_IN_TRANSPORT_URL:
+			migrate_parse_url (
+				parse_data->transport_key_file,
+				parse_data->transport_filename,
+				text, error);
+			break;
+
+		default:
+			break;
+	}
+}
+
+static GMarkupParser account_xml_parser = {
+	migrate_parse_account_xml_start_element,
+	migrate_parse_account_xml_end_element,
+	migrate_parse_account_xml_text,
+	NULL,  /* passthrough */
+	NULL   /* error */
+};
+
+static void
+migrate_parse_signature (ParseData *parse_data,
+                         const gchar *element_name,
+                         const gchar **attribute_names,
+                         const gchar **attribute_values,
+                         GError **error)
+{
+	const gchar *uid;
+	const gchar *name;
+	const gchar *format;
+	const gchar *config_dir;
+	gchar *directory;
+	gchar *absolute_path;
+	gboolean autogenerated;
+	gboolean success;
+
+	success = g_markup_collect_attributes (
+		element_name,
+		attribute_names,
+		attribute_values,
+		error,
+		G_MARKUP_COLLECT_STRING,
+		"uid", &uid,
+		G_MARKUP_COLLECT_STRING,
+		"name", &name,
+		G_MARKUP_COLLECT_BOOLEAN,
+		"auto", &autogenerated,
+		G_MARKUP_COLLECT_STRING |
+		G_MARKUP_COLLECT_OPTIONAL,
+		"format", &format,
+		G_MARKUP_COLLECT_INVALID);
+
+	if (!success)
+		return;
+
+	/* Skip the "autogenerated" signature. */
+	if (autogenerated)
+		return;
+
+	config_dir = e_get_user_config_dir ();
+
+	directory = g_build_filename (config_dir, "sources", NULL);
+	parse_data->filename = g_build_filename (directory, uid, NULL);
+	g_mkdir_with_parents (directory, 0700);
+	g_free (directory);
+
+	directory = g_build_filename (config_dir, "signatures", NULL);
+	absolute_path = g_build_filename (directory, uid, NULL);
+	parse_data->signature_file = g_file_new_for_path (absolute_path);
+	g_mkdir_with_parents (directory, 0700);
+	g_free (absolute_path);
+	g_free (directory);
+
+	/* If the file already exists, skip this source.  It may be that we
+	 * already migrated it, in which case we don't want to overwrite it. */
+	if (g_file_test (parse_data->filename, G_FILE_TEST_EXISTS))
+		return;
+
+	parse_data->key_file = g_key_file_new ();
+
+	g_key_file_set_string (
+		parse_data->key_file,
+		E_SOURCE_GROUP_NAME,
+		"DisplayName", name);
+
+	g_key_file_set_string (
+		parse_data->key_file,
+		E_SOURCE_EXTENSION_MAIL_SIGNATURE,
+		"MimeType", format);
+}
+
+static void
+migrate_parse_signature_xml_start_element (GMarkupParseContext *context,
+                                           const gchar *element_name,
+                                           const gchar **attribute_names,
+                                           const gchar **attribute_values,
+                                           gpointer user_data,
+                                           GError **error)
+{
+	ParseData *parse_data = user_data;
+
+	if (g_strcmp0 (element_name, "filename") == 0) {
+		if (parse_data->state != PARSE_STATE_IN_SIGNATURE)
+			goto invalid_content;
+
+		parse_data->state = PARSE_STATE_IN_FILENAME;
+
+		g_markup_collect_attributes (
+			element_name,
+			attribute_names,
+			attribute_values,
+			error,
+			G_MARKUP_COLLECT_BOOLEAN |
+			G_MARKUP_COLLECT_OPTIONAL,
+			"script", &parse_data->is_script,
+			G_MARKUP_COLLECT_INVALID);
+
+		return;
+	}
+
+	if (g_strcmp0 (element_name, "signature") == 0) {
+		if (parse_data->state != PARSE_STATE_IN_SIGNATURES_VALUE)
+			goto invalid_content;
+
+		parse_data->state = PARSE_STATE_IN_SIGNATURE;
+
+		migrate_parse_signature (
+			parse_data,
+			element_name,
+			attribute_names,
+			attribute_values,
+			error);
+
+		return;
+	}
+
+	g_set_error (
+		error, G_MARKUP_ERROR, G_MARKUP_ERROR_UNKNOWN_ELEMENT,
+		"Unknown element <%s>", element_name);
+
+	return;
+
+invalid_content:
+
+	g_set_error (
+		error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
+		"Element <%s> at unexpected location", element_name);
+}
+
+static void
+migrate_parse_signature_xml_end_element (GMarkupParseContext *context,
+                                         const gchar *element_name,
+                                         gpointer user_data,
+                                         GError **error)
+{
+	ParseData *parse_data = user_data;
+
+	if (g_strcmp0 (element_name, "filename") == 0) {
+		if (parse_data->state == PARSE_STATE_IN_FILENAME) {
+			parse_data->state = PARSE_STATE_IN_SIGNATURE;
+
+			return;
+		}
+	}
+
+	if (g_strcmp0 (element_name, "signature") == 0) {
+		if (parse_data->state == PARSE_STATE_IN_SIGNATURE) {
+			parse_data->state = PARSE_STATE_IN_SIGNATURES_VALUE;
+
+			/* Clean up <signature> tag data. */
+
+			/* The key file will be NULL if we decided to skip it.
+			 * e.g. A file with the same UID may already exist. */
+			if (parse_data->key_file != NULL) {
+				GError *local_error = NULL;
+
+				migrate_parse_commit_changes (
+					parse_data->filename,
+					parse_data->key_file,
+					&local_error);
+
+				if (local_error != NULL) {
+					g_printerr (
+						"  FAILED: %s\n",
+						local_error->message);
+					g_error_free (local_error);
+				}
+
+				g_key_file_free (parse_data->key_file);
+				parse_data->key_file = NULL;
+			}
+
+			g_free (parse_data->filename);
+			parse_data->filename = NULL;
+
+			return;
+		}
+	}
+}
+
+static void
+migrate_parse_signature_xml_text (GMarkupParseContext *context,
+                                  const gchar *text,
+                                  gsize text_len,
+                                  gpointer user_data,
+                                  GError **error)
+{
+	ParseData *parse_data = user_data;
+
+	if (parse_data->state == PARSE_STATE_IN_FILENAME) {
+		GFile *old_signature_file;
+		GFile *new_signature_file;
+		const gchar *data_dir;
+		gchar *absolute_path;
+
+		/* Note we're moving the signature files
+		 * from $XDG_DATA_HOME to $XDG_CONFIG_HOME. */
+		data_dir = e_get_user_data_dir ();
+
+		/* Text should be either an absolute file name
+		 * or a base file name with no path components. */
+		if (g_path_is_absolute (text))
+			absolute_path = g_strdup (text);
+		else
+			absolute_path = g_build_filename (
+				data_dir, "signatures", text, NULL);
+
+		old_signature_file = g_file_new_for_path (absolute_path);
+		new_signature_file = parse_data->signature_file;
+		parse_data->signature_file = NULL;
+
+		/* If the signature is a script, we symlink to it.
+		 * Otherwise we move and rename the regular file. */
+		if (parse_data->is_script)
+			g_file_make_symbolic_link (
+				new_signature_file,
+				absolute_path, NULL, error);
+		else
+			g_file_move (
+				old_signature_file,
+				new_signature_file,
+				G_FILE_COPY_NONE,
+				NULL, NULL, NULL, error);
+
+		g_object_unref (old_signature_file);
+		g_object_unref (new_signature_file);
+		g_free (absolute_path);
+	}
+}
+
+static GMarkupParser signature_xml_parser = {
+	migrate_parse_signature_xml_start_element,
+	migrate_parse_signature_xml_end_element,
+	migrate_parse_signature_xml_text,
+	NULL,  /* passthrough */
+	NULL   /* error */
+};
+
+static void
+migrate_parse_gconf_xml_start_element (GMarkupParseContext *context,
+                                       const gchar *element_name,
+                                       const gchar **attribute_names,
+                                       const gchar **attribute_values,
+                                       gpointer user_data,
+                                       GError **error)
+{
+	ParseData *parse_data = user_data;
+
+	if (g_strcmp0 (element_name, "gconf") == 0) {
+		if (parse_data->state != PARSE_STATE_INITIAL)
+			goto invalid_content;
+
+		parse_data->state = PARSE_STATE_IN_GCONF;
+
+		return;
+	}
+
+	if (g_strcmp0 (element_name, "entry") == 0) {
+		const gchar *name;
+		gboolean success;
+
+		if (parse_data->state != PARSE_STATE_IN_GCONF)
+			goto invalid_content;
+
+		success = g_markup_collect_attributes (
+			element_name,
+			attribute_names,
+			attribute_values,
+			error,
+			G_MARKUP_COLLECT_STRING,
+			"name", &name,
+			G_MARKUP_COLLECT_STRING,
+			"mtime", NULL,
+			G_MARKUP_COLLECT_STRING |
+			G_MARKUP_COLLECT_OPTIONAL,
+			"type", NULL,
+			G_MARKUP_COLLECT_STRING |
+			G_MARKUP_COLLECT_OPTIONAL,
+			"ltype", NULL,
+			G_MARKUP_COLLECT_STRING |
+			G_MARKUP_COLLECT_OPTIONAL,
+			"schema", NULL,
+			G_MARKUP_COLLECT_STRING |
+			G_MARKUP_COLLECT_OPTIONAL,
+			"value", NULL,
+			G_MARKUP_COLLECT_INVALID);
+
+		if (success && g_strcmp0 (name, "accounts") == 0)
+			parse_data->state = PARSE_STATE_IN_ACCOUNTS_ENTRY;
+
+		if (success && g_strcmp0 (name, "signatues") == 0)
+			parse_data->state = PARSE_STATE_IN_SIGNATURES_ENTRY;
+
+		return;
+	}
+
+	if (g_strcmp0 (element_name, "li") == 0)
+		return;
+
+	if (g_strcmp0 (element_name, "stringvalue") == 0) {
+		if (parse_data->state == PARSE_STATE_IN_ACCOUNTS_ENTRY)
+			parse_data->state = PARSE_STATE_IN_ACCOUNTS_VALUE;
+
+		if (parse_data->state == PARSE_STATE_IN_SIGNATURES_ENTRY)
+			parse_data->state = PARSE_STATE_IN_SIGNATURES_VALUE;
+
+		return;
+	}
+
+	g_set_error (
+		error, G_MARKUP_ERROR, G_MARKUP_ERROR_UNKNOWN_ELEMENT,
+		"Unknown element <%s>", element_name);
+
+	return;
+
+invalid_content:
+
+	g_set_error (
+		error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
+		"Element <%s> at unexpected location", element_name);
+}
+
+static void
+migrate_parse_gconf_xml_end_element (GMarkupParseContext *context,
+                                     const gchar *element_name,
+                                     gpointer user_data,
+                                     GError **error)
+{
+	ParseData *parse_data = user_data;
+
+	if (g_strcmp0 (element_name, "gconf") == 0) {
+		if (parse_data->state == PARSE_STATE_IN_GCONF) {
+			parse_data->state = PARSE_STATE_INITIAL;
+			return;
+		}
+	}
+
+	if (g_strcmp0 (element_name, "entry") == 0) {
+		if (parse_data->state == PARSE_STATE_IN_ACCOUNTS_ENTRY) {
+			parse_data->state = PARSE_STATE_IN_GCONF;
+			return;
+		}
+	}
+
+	if (g_strcmp0 (element_name, "stringvalue") == 0) {
+		if (parse_data->state == PARSE_STATE_IN_ACCOUNTS_VALUE) {
+			parse_data->state = PARSE_STATE_IN_ACCOUNTS_ENTRY;
+			return;
+		}
+
+		if (parse_data->state == PARSE_STATE_IN_SIGNATURES_VALUE) {
+			parse_data->state = PARSE_STATE_IN_SIGNATURES_VALUE;
+			return;
+		}
+	}
+}
+
+static void
+migrate_parse_gconf_xml_text (GMarkupParseContext *context,
+                              const gchar *text,
+                              gsize length,
+                              gpointer user_data,
+                              GError **error)
+{
+	ParseData *parse_data = user_data;
+
+	/* The account and signature data is encoded XML stuffed into
+	 * GConf XML (yuck!).  Fortunately GMarkupParseContext decodes
+	 * the XML for us, so we just have to feed it to a nested
+	 * GMarkupParseContext. */
+
+	switch (parse_data->state) {
+		case PARSE_STATE_IN_ACCOUNTS_VALUE:
+			context = g_markup_parse_context_new (
+				&account_xml_parser, 0, parse_data, NULL);
+			break;
+
+		case PARSE_STATE_IN_SIGNATURES_VALUE:
+			context = g_markup_parse_context_new (
+				&signature_xml_parser, 0, parse_data, NULL);
+			break;
+
+		default:
+			return;
+	}
+
+	if (g_markup_parse_context_parse (context, text, length, error))
+		g_markup_parse_context_end_parse (context, error);
+
+	g_markup_parse_context_free (context);
+}
+
+static GMarkupParser gconf_xml_parser = {
+	migrate_parse_gconf_xml_start_element,
+	migrate_parse_gconf_xml_end_element,
+	migrate_parse_gconf_xml_text,
+	NULL,  /* passthrough */
+	NULL   /* error */
+};
+
+static gboolean
+migrate_parse_gconf_xml (const gchar *contents,
+                         gsize length,
+                         GError **error)
+{
+	GMarkupParseContext *context;
+	ParseData *parse_data;
+	gboolean success = FALSE;
+
+	parse_data = parse_data_new ();
+
+	context = g_markup_parse_context_new (
+		&gconf_xml_parser, 0, parse_data,
+		(GDestroyNotify) parse_data_free);
+
+	if (g_markup_parse_context_parse (context, contents, length, error))
+		if (g_markup_parse_context_end_parse (context, error))
+			success = TRUE;
+
+	g_markup_parse_context_free (context);
+
+	return success;
+}
+
+static void
+migrate_remove_gconf_xml (const gchar *gconf_key,
+                          const gchar *gconf_xml)
+{
+	/* Remove the GConf string list so the user is not haunted by
+	 * old data sources being resurrected from leftover GConf data.
+	 * Also delete the %gconf.xml file itself.  If gconfd is running
+	 * then it will just recreate the file from memory when it exits
+	 * (which is why we invoke gconftool-2), otherwise the file will
+	 * stay deleted. */
+
+	gchar *path_to_program;
+
+	path_to_program = g_find_program_in_path ("gconftool-2");
+
+	if (path_to_program != NULL) {
+		gchar *command_line;
+		GError *error = NULL;
+
+		command_line = g_strjoin (
+			" ",
+			path_to_program,
+			"--set",
+			"--type=list",
+			"--list-type=string",
+			gconf_key, "[]", NULL);
+
+		/* We don't really care if the command worked or not,
+		 * just check that the program got spawned successfully. */
+		if (!g_spawn_command_line_async (command_line, &error)) {
+			g_printerr (
+				"Failed to spawn '%s': %s\n",
+				path_to_program, error->message);
+			g_error_free (error);
+		}
+
+		g_free (path_to_program);
+		g_free (command_line);
+	}
+
+	if (g_file_test (gconf_xml, G_FILE_TEST_IS_REGULAR)) {
+		if (g_remove (gconf_xml) == -1) {
+			g_printerr (
+				"Failed to remove '%s': %s\n",
+				gconf_xml, g_strerror (errno));
+		}
+	}
+}
+
+void
+e_mail_migrate_sources (void)
+{
+	gchar *base_dir;
+	gchar *contents;
+	gchar *gconf_xml;
+	gsize length;
+	const gchar *gconf_key;
+	GError *error = NULL;
+
+	base_dir = g_build_filename (
+		g_get_home_dir (), ".gconf", "apps", "evolution", NULL);
+
+	g_print ("Migrating mail accounts from GConf...\n");
+
+	gconf_xml = g_build_filename (
+		base_dir, "mail", "%gconf.xml", NULL);
+	g_file_get_contents (gconf_xml, &contents, &length, &error);
+
+	if (error == NULL) {
+		migrate_parse_gconf_xml (contents, length, &error);
+		g_free (contents);
+	}
+
+	if (error == NULL) {
+		gconf_key = "/apps/evolution/mail/accounts";
+		migrate_remove_gconf_xml (gconf_key, gconf_xml);
+	} else {
+		g_printerr ("  FAILED: %s\n", error->message);
+		g_clear_error (&error);
+	}
+
+	g_free (gconf_xml);
+	g_free (base_dir);
+}
diff --git a/mail/e-mail-migrate.c b/mail/e-mail-migrate.c
index 59605e2..29e05dc 100644
--- a/mail/e-mail-migrate.c
+++ b/mail/e-mail-migrate.c
@@ -53,11 +53,9 @@
 #include <libedataserver/e-data-server-util.h>
 #include <e-util/e-xml-utils.h>
 
-#include "e-util/e-account-utils.h"
 #include "e-util/e-alert-dialog.h"
 #include "e-util/e-util-private.h"
 #include "e-util/e-plugin.h"
-#include "e-util/e-signature-utils.h"
 
 #include "shell/e-shell.h"
 #include "shell/e-shell-migrate.h"
@@ -77,6 +75,8 @@ struct _MigrateStateInfo {
 	gdouble progress;
 };
 
+void e_mail_migrate_sources (void);
+
 static gboolean
 update_states_in_main_thread (MigrateStateInfo *info);
 
@@ -329,6 +329,7 @@ cp (const gchar *src,
 static void
 em_update_accounts_2_11 (void)
 {
+#if 0  /* ACCOUNT_MGMT */
 	EAccountList *accounts;
 	EIterator *iter;
 	gboolean changed = FALSE;
@@ -361,6 +362,7 @@ em_update_accounts_2_11 (void)
 
 	if (changed)
 		e_account_list_save (accounts);
+#endif /* ACCOUNT_MGMT */
 }
 
 #endif	/* !G_OS_WIN32 */
@@ -698,6 +700,7 @@ migrate_folders_to_db_thread (struct migrate_folders_to_db_structure *migrate_db
 static void
 migrate_to_db (EShellBackend *shell_backend)
 {
+#if 0  /* ACCOUNT_MGMT */
 	EMMigrateSession *session;
 	EAccountList *accounts;
 	EMailBackend *mail_backend;
@@ -809,6 +812,7 @@ migrate_to_db (EShellBackend *shell_backend)
 	em_migrate_close_progress_dialog ();
 
 	g_object_unref (session);
+#endif /* ACCOUNT_MGMT */
 }
 
 #endif
@@ -1017,6 +1021,7 @@ static gboolean
 create_mbox_account (EShellBackend *shell_backend,
                      EMMigrateSession *session)
 {
+#if 0 /* ACCOUNT_MGMT */
 	EMailBackend *mail_backend;
 	EMailSession *mail_session;
 	CamelStore *store;
@@ -1084,6 +1089,7 @@ exit:
 	g_free (uri);
 	g_free (name);
 	g_free (id);
+#endif /* ACCOUNT_MGMT */
 
 	return TRUE;
 }
@@ -1091,6 +1097,7 @@ exit:
 static void
 change_sent_and_drafts_local_folders (EShellBackend *shell_backend)
 {
+#if 0  /* ACCOUNT_MGMT */
 	EAccountList *accounts;
 	EIterator *iter;
 	const gchar *data_dir;
@@ -1167,194 +1174,13 @@ change_sent_and_drafts_local_folders (EShellBackend *shell_backend)
 
 	if (changed)
 		e_account_list_save (accounts);
-}
-
-static void
-em_rename_camel_url_params (CamelURL *url)
-{
-	/* This list includes known URL parameters from built-in providers
-	 * in Camel, as well as from evolution-exchange, evolution-groupwise,
-	 * and evolution-mapi.  Add more as needed. */
-	static struct {
-		const gchar *url_parameter;
-		const gchar *property_name;
-	} camel_url_conversion[] = {
-		{ "ad_auth",			"gc-auth-method" },
-		{ "ad_browse",			"gc-allow-browse" },
-		{ "ad_expand_groups",		"gc-expand-groups" },
-		{ "ad_limit",			"gc-results-limit" },
-		{ "ad_server",			"gc-server-name" },
-		{ "all_headers",		"fetch-headers" },
-		{ "basic_headers",		"fetch-headers" },
-		{ "cachedconn"			"concurrent-connections" },
-		{ "check_all",			"check-all" },
-		{ "check_lsub",			"check-subscribed" },
-		{ "command",			"shell-command" },
-		{ "delete_after",		"delete-after-days" },
-		{ "delete_expunged",		"delete-expunged" },
-		{ "disable_extensions",		"disable-extensions" },
-		{ "dotfolders",			"use-dot-folders" },
-		{ "filter",			"filter-inbox" },
-		{ "filter_junk",		"filter-junk" },
-		{ "filter_junk_inbox",		"filter-junk-inbox" },
-		{ "folder_hierarchy_relative",	"folder-hierarchy-relative" },
-		{ "imap_custom_headers",	"fetch-headers-extra" },
-		{ "keep_on_server",		"keep-on-server" },
-		{ "offline_sync",		"stay-synchronized" },
-		{ "override_namespace",		"use-namespace" },
-		{ "owa_path",			"owa-path" },
-		{ "owa_url",			"owa-url" },
-		{ "password_exp_warn_period",	"password-exp-warn-period" },
-		{ "real_junk_path",		"real-junk-path" },
-		{ "real_trash_path",		"real-trash-path" },
-		{ "show_short_notation",	"short-folder-names" },
-		{ "soap_port",			"soap-port" },
-		{ "ssl",			"security-method" },
-		{ "sync_offline",		"stay-synchronized" },
-		{ "use_command",		"use-shell-command" },
-		{ "use_idle",			"use-idle" },
-		{ "use_lsub",			"use-subscriptions" },
-		{ "use_qresync",		"use-qresync" },
-		{ "use_ssl",			"security-method" },
-		{ "xstatus",			"use-xstatus-headers" }
-	};
-
-	const gchar *param;
-	const gchar *use_param;
-	gint ii;
-
-	for (ii = 0; ii < G_N_ELEMENTS (camel_url_conversion); ii++) {
-		const gchar *key;
-		gpointer value;
-
-		key = camel_url_conversion[ii].url_parameter;
-		value = g_datalist_get_data (&url->params, key);
-
-		if (value == NULL)
-			continue;
-
-		g_datalist_remove_no_notify (&url->params, key);
-
-		key = camel_url_conversion[ii].property_name;
-
-		/* Deal with a few special enum cases where
-		 * the parameter value also needs renamed. */
-
-		if (strcmp (key, "all_headers") == 0) {
-			GEnumClass *enum_class;
-			GEnumValue *enum_value;
-
-			enum_class = g_type_class_ref (
-				CAMEL_TYPE_FETCH_HEADERS_TYPE);
-			enum_value = g_enum_get_value (
-				enum_class, CAMEL_FETCH_HEADERS_ALL);
-			if (enum_value != NULL) {
-				g_free (value);
-				value = g_strdup (enum_value->value_nick);
-			} else
-				g_warn_if_reached ();
-			g_type_class_unref (enum_class);
-		}
-
-		if (strcmp (key, "basic_headers") == 0) {
-			GEnumClass *enum_class;
-			GEnumValue *enum_value;
-
-			enum_class = g_type_class_ref (
-				CAMEL_TYPE_FETCH_HEADERS_TYPE);
-			enum_value = g_enum_get_value (
-				enum_class, CAMEL_FETCH_HEADERS_BASIC);
-			if (enum_value != NULL) {
-				g_free (value);
-				value = g_strdup (enum_value->value_nick);
-			} else
-				g_warn_if_reached ();
-			g_type_class_unref (enum_class);
-		}
-
-		if (strcmp (key, "imap_custom_headers") == 0)
-			g_strdelimit (value, " ", ',');
-
-		if (strcmp (key, "security-method") == 0) {
-			CamelNetworkSecurityMethod method;
-			GEnumClass *enum_class;
-			GEnumValue *enum_value;
-
-			if (strcmp (value, "always") == 0)
-				method = CAMEL_NETWORK_SECURITY_METHOD_SSL_ON_ALTERNATE_PORT;
-			else if (strcmp (value, "1") == 0)
-				method = CAMEL_NETWORK_SECURITY_METHOD_SSL_ON_ALTERNATE_PORT;
-			else if (strcmp (value, "when-possible") == 0)
-				method = CAMEL_NETWORK_SECURITY_METHOD_STARTTLS_ON_STANDARD_PORT;
-			else
-				method = CAMEL_NETWORK_SECURITY_METHOD_NONE;
-
-			enum_class = g_type_class_ref (
-				CAMEL_TYPE_NETWORK_SECURITY_METHOD);
-			enum_value = g_enum_get_value (enum_class, method);
-			if (enum_value != NULL) {
-				g_free (value);
-				value = g_strdup (enum_value->value_nick);
-			} else
-				g_warn_if_reached ();
-			g_type_class_unref (enum_class);
-		}
-
-		g_datalist_set_data_full (&url->params, key, value, g_free);
-	}
-
-	/* A few more adjustments...
-	 *
-	 * These are all CAMEL_PROVIDER_CONF_CHECKSPIN settings.  The spin
-	 * button value is bound to "param" and the checkbox state is bound
-	 * to "use-param".  The "use-param" settings are new.  If "param"
-	 * exists but no "use-param", then set "use-param" to "true". */
-
-	param = g_datalist_get_data (&url->params, "gc-results-limit");
-	use_param = g_datalist_get_data (&url->params, "use-gc-results-limit");
-	if (param != NULL && *param != '\0' && use_param == NULL) {
-		g_datalist_set_data_full (
-			&url->params, "use-gc-results-limit",
-			g_strdup ("true"), (GDestroyNotify) g_free);
-	}
-
-	param = g_datalist_get_data (&url->params, "kerberos");
-	if (g_strcmp0 (param, "required") == 0) {
-		g_datalist_set_data_full (
-			&url->params, "kerberos",
-			g_strdup ("true"), (GDestroyNotify) g_free);
-	}
-
-	param = g_datalist_get_data (
-		&url->params, "password-exp-warn-period");
-	use_param = g_datalist_get_data (
-		&url->params, "use-password-exp-warn-period");
-	if (param != NULL && *param != '\0' && use_param == NULL) {
-		g_datalist_set_data_full (
-			&url->params, "use-password-exp-warn-period",
-			g_strdup ("true"), (GDestroyNotify) g_free);
-	}
-
-	param = g_datalist_get_data (&url->params, "real-junk-path");
-	use_param = g_datalist_get_data (&url->params, "use-real-junk-path");
-	if (param != NULL && *param != '\0' && use_param == NULL) {
-		g_datalist_set_data_full (
-			&url->params, "use-real-junk-path",
-			g_strdup ("true"), (GDestroyNotify) g_free);
-	}
-
-	param = g_datalist_get_data (&url->params, "real-trash-path");
-	use_param = g_datalist_get_data (&url->params, "use-real-trash-path");
-	if (param != NULL && *param != '\0' && use_param == NULL) {
-		g_datalist_set_data_full (
-			&url->params, "use-real-trash-path",
-			g_strdup ("true"), (GDestroyNotify) g_free);
-	}
+#endif /* ACCOUNT_MGMT */
 }
 
 static void
 em_rename_account_params (void)
 {
+#if 0  /* ACCOUNT_MGMT */
 	EAccountList *account_list;
 	EIterator *iterator;
 
@@ -1404,6 +1230,7 @@ em_rename_account_params (void)
 
 	g_object_unref (iterator);
 	e_account_list_save (account_list);
+#endif /* ACCOUNT_MGMT */
 }
 
 static gboolean
@@ -1558,6 +1385,8 @@ e_mail_migrate (EShellBackend *shell_backend,
 	 * match CamelSettings property names. */
 	em_rename_account_params ();
 
+	e_mail_migrate_sources ();
+
 	if (!migrate_local_store (shell_backend))
 		return FALSE;
 
diff --git a/mail/e-mail-paned-view.c b/mail/e-mail-paned-view.c
index c9ebb8a..25e4276 100644
--- a/mail/e-mail-paned-view.c
+++ b/mail/e-mail-paned-view.c
@@ -767,6 +767,7 @@ mail_paned_view_update_view_instance (EMailView *view)
 	EShellWindow *shell_window;
 	EShellViewClass *shell_view_class;
 	EShellSettings *shell_settings;
+	ESourceRegistry *registry;
 	GalViewCollection *view_collection;
 	GalViewInstance *view_instance;
 	CamelFolder *folder;
@@ -784,6 +785,7 @@ mail_paned_view_update_view_instance (EMailView *view)
 
 	shell_window = e_shell_view_get_shell_window (shell_view);
 	shell = e_shell_window_get_shell (shell_window);
+	registry = e_shell_get_registry (shell);
 	shell_settings = e_shell_get_shell_settings (shell);
 
 	reader = E_MAIL_READER (view);
@@ -802,9 +804,9 @@ mail_paned_view_update_view_instance (EMailView *view)
 	e_filename_make_safe (view_id);
 
 	outgoing_folder =
-		em_utils_folder_is_drafts (folder) ||
-		em_utils_folder_is_outbox (folder) ||
-		em_utils_folder_is_sent (folder);
+		em_utils_folder_is_drafts (registry, folder) ||
+		em_utils_folder_is_outbox (registry, folder) ||
+		em_utils_folder_is_sent (registry, folder);
 
 	if (e_shell_settings_get_boolean (shell_settings, "mail-global-view-setting"))
 		view_instance = e_shell_view_new_view_instance (
diff --git a/mail/e-mail-reader-utils.c b/mail/e-mail-reader-utils.c
index 725a0c6..9c18baf 100644
--- a/mail/e-mail-reader-utils.c
+++ b/mail/e-mail-reader-utils.c
@@ -370,7 +370,9 @@ copy_tree_state (EMailReader *src_reader,
 guint
 e_mail_reader_open_selected (EMailReader *reader)
 {
+	EShell *shell;
 	EMailBackend *backend;
+	ESourceRegistry *registry;
 	CamelFolder *folder;
 	GtkWindow *window;
 	GPtrArray *views;
@@ -380,6 +382,9 @@ e_mail_reader_open_selected (EMailReader *reader)
 	g_return_val_if_fail (E_IS_MAIL_READER (reader), 0);
 
 	backend = e_mail_reader_get_backend (reader);
+	shell = e_shell_backend_get_shell (E_SHELL_BACKEND (backend));
+	registry = e_shell_get_registry (shell);
+
 	folder = e_mail_reader_get_folder (reader);
 	uids = e_mail_reader_get_selected_uids (reader);
 	window = e_mail_reader_get_window (reader);
@@ -389,9 +394,9 @@ e_mail_reader_open_selected (EMailReader *reader)
 		return 0;
 	}
 
-	if (em_utils_folder_is_drafts (folder) ||
-		em_utils_folder_is_outbox (folder) ||
-		em_utils_folder_is_templates (folder)) {
+	if (em_utils_folder_is_drafts (registry, folder) ||
+		em_utils_folder_is_outbox (registry, folder) ||
+		em_utils_folder_is_templates (registry, folder)) {
 		em_utils_edit_messages (reader, folder, uids, TRUE);
 		return uids->len;
 	}
@@ -418,8 +423,8 @@ e_mail_reader_open_selected (EMailReader *reader)
 			CAMEL_VEE_FOLDER (folder),
 			(CamelVeeMessageInfo *) info, &real_uid);
 
-		if (em_utils_folder_is_drafts (real_folder) ||
-			em_utils_folder_is_outbox (real_folder)) {
+		if (em_utils_folder_is_drafts (registry, real_folder) ||
+			em_utils_folder_is_outbox (registry, real_folder)) {
 			GPtrArray *edits;
 
 			edits = g_ptr_array_new ();
@@ -1175,9 +1180,12 @@ void
 e_mail_reader_create_filter_from_selected (EMailReader *reader,
                                            gint filter_type)
 {
+	EShell *shell;
 	EActivity *activity;
+	EMailBackend *backend;
 	AsyncContext *context;
 	GCancellable *cancellable;
+	ESourceRegistry *registry;
 	CamelFolder *folder;
 	GPtrArray *uids;
 	const gchar *filter_source;
@@ -1185,12 +1193,16 @@ e_mail_reader_create_filter_from_selected (EMailReader *reader,
 
 	g_return_if_fail (E_IS_MAIL_READER (reader));
 
+	backend = e_mail_reader_get_backend (reader);
+	shell = e_shell_backend_get_shell (E_SHELL_BACKEND (backend));
+	registry = e_shell_get_registry (shell);
+
 	folder = e_mail_reader_get_folder (reader);
 	g_return_if_fail (CAMEL_IS_FOLDER (folder));
 
-	if (em_utils_folder_is_sent (folder))
+	if (em_utils_folder_is_sent (registry, folder))
 		filter_source = E_FILTER_SOURCE_OUTGOING;
-	else if (em_utils_folder_is_outbox (folder))
+	else if (em_utils_folder_is_outbox (registry, folder))
 		filter_source = E_FILTER_SOURCE_OUTGOING;
 	else
 		filter_source = E_FILTER_SOURCE_INCOMING;
diff --git a/mail/e-mail-reader.c b/mail/e-mail-reader.c
index 8b7c803..68df2f7 100644
--- a/mail/e-mail-reader.c
+++ b/mail/e-mail-reader.c
@@ -28,11 +28,12 @@
 #include <glib/gi18n.h>
 #include <gdk/gdkkeysyms.h>
 
+#include <libedataserver/e-source-mail-account.h>
+
 #ifdef HAVE_XFREE
 #include <X11/XF86keysym.h>
 #endif
 
-#include "e-util/e-account-utils.h"
 #include "e-util/e-charset.h"
 #include "e-util/e-util.h"
 #include "e-util/e-alert-dialog.h"
@@ -751,6 +752,9 @@ static void
 action_mail_message_edit_cb (GtkAction *action,
                              EMailReader *reader)
 {
+	EShell *shell;
+	EMailBackend *backend;
+	ESourceRegistry *registry;
 	CamelFolder *folder;
 	GPtrArray *uids;
 	gboolean replace;
@@ -759,11 +763,15 @@ action_mail_message_edit_cb (GtkAction *action,
 	uids = e_mail_reader_get_selected_uids (reader);
 	g_return_if_fail (uids != NULL);
 
+	backend = e_mail_reader_get_backend (reader);
+	shell = e_shell_backend_get_shell (E_SHELL_BACKEND (backend));
+	registry = e_shell_get_registry (shell);
+
 	/* XXX Either e_mail_reader_get_selected_uids()
 	 *     or MessageList should do this itself. */
 	g_ptr_array_set_free_func (uids, (GDestroyNotify) g_free);
 
-	replace = em_utils_folder_is_drafts (folder);
+	replace = em_utils_folder_is_drafts (registry, folder);
 	em_utils_edit_messages (reader, folder, uids, replace);
 
 	g_ptr_array_unref (uids);
@@ -2833,6 +2841,7 @@ mail_reader_set_folder (EMailReader *reader,
 	EMailReaderPrivate *priv;
 	EMFormatHTML *formatter;
 	CamelFolder *previous_folder;
+	ESourceRegistry *registry;
 	GtkWidget *message_list;
 	EMailBackend *backend;
 	EShell *shell;
@@ -2840,13 +2849,14 @@ mail_reader_set_folder (EMailReader *reader,
 
 	priv = E_MAIL_READER_GET_PRIVATE (reader);
 
-	backend = e_mail_reader_get_backend (reader);
 	formatter = e_mail_reader_get_formatter (reader);
 	message_list = e_mail_reader_get_message_list (reader);
 
 	previous_folder = e_mail_reader_get_folder (reader);
 
+	backend = e_mail_reader_get_backend (reader);
 	shell = e_shell_backend_get_shell (E_SHELL_BACKEND (backend));
+	registry = e_shell_get_registry (shell);
 
 	/* Only synchronize the folder if we're online. */
 	if (previous_folder != NULL && e_shell_get_online (shell))
@@ -2857,9 +2867,9 @@ mail_reader_set_folder (EMailReader *reader,
 		return;
 
 	outgoing = folder != NULL && (
-		em_utils_folder_is_drafts (folder) ||
-		em_utils_folder_is_outbox (folder) ||
-		em_utils_folder_is_sent (folder));
+		em_utils_folder_is_drafts (registry, folder) ||
+		em_utils_folder_is_outbox (registry, folder) ||
+		em_utils_folder_is_sent (registry, folder));
 
 	/* FIXME Need to pass a GCancellable. */
 	em_format_format (EM_FORMAT (formatter), NULL, NULL, NULL, NULL);
@@ -3715,9 +3725,14 @@ e_mail_reader_changed (EMailReader *reader)
 guint32
 e_mail_reader_check_state (EMailReader *reader)
 {
+	EShell *shell;
 	GPtrArray *uids;
 	CamelFolder *folder;
 	CamelStore *store = NULL;
+	EMailBackend *backend;
+	ESourceRegistry *registry;
+	GList *list, *iter;
+	const gchar *extension_name;
 	const gchar *tag;
 	gboolean can_clear_flags = FALSE;
 	gboolean can_flag_completed = FALSE;
@@ -3731,6 +3746,7 @@ e_mail_reader_check_state (EMailReader *reader)
 	gboolean has_undeleted = FALSE;
 	gboolean has_unimportant = FALSE;
 	gboolean has_unread = FALSE;
+	gboolean have_enabled_account = FALSE;
 	gboolean drafts_or_outbox = FALSE;
 	gboolean store_supports_vjunk = FALSE;
 	gboolean is_mailing_list;
@@ -3740,6 +3756,10 @@ e_mail_reader_check_state (EMailReader *reader)
 
 	g_return_val_if_fail (E_IS_MAIL_READER (reader), 0);
 
+	backend = e_mail_reader_get_backend (reader);
+	shell = e_shell_backend_get_shell (E_SHELL_BACKEND (backend));
+	registry = e_shell_get_registry (shell);
+
 	folder = e_mail_reader_get_folder (reader);
 	uids = e_mail_reader_get_selected_uids (reader);
 
@@ -3749,8 +3769,8 @@ e_mail_reader_check_state (EMailReader *reader)
 		is_junk_folder =
 			(folder->folder_flags & CAMEL_FOLDER_IS_JUNK) != 0;
 		drafts_or_outbox =
-			em_utils_folder_is_drafts (folder) ||
-			em_utils_folder_is_outbox (folder);
+			em_utils_folder_is_drafts (registry, folder) ||
+			em_utils_folder_is_outbox (registry, folder);
 	}
 
 	/* Initialize this flag based on whether there are any
@@ -3835,7 +3855,21 @@ e_mail_reader_check_state (EMailReader *reader)
 		camel_folder_free_message_info (folder, info);
 	}
 
-	if (e_get_any_enabled_account () != NULL)
+	extension_name = E_SOURCE_EXTENSION_MAIL_ACCOUNT;
+	list = e_source_registry_list_sources (registry, extension_name);
+
+	for (iter = list; iter != NULL; iter = g_list_next (iter)) {
+		ESource *source = E_SOURCE (iter->data);
+
+		if (e_source_get_enabled (source)) {
+			have_enabled_account = TRUE;
+			break;
+		}
+	}
+
+	g_list_free (list);
+
+	if (have_enabled_account)
 		state |= E_MAIL_READER_HAVE_ENABLED_ACCOUNT;
 	if (uids->len == 1)
 		state |= E_MAIL_READER_SELECTION_SINGLE;
diff --git a/mail/e-mail-session-utils.c b/mail/e-mail-session-utils.c
index eca58bc..590318e 100644
--- a/mail/e-mail-session-utils.c
+++ b/mail/e-mail-session-utils.c
@@ -25,11 +25,11 @@
 #include "em-utils.h"
 
 #include <glib/gi18n-lib.h>
+#include <libedataserver/e-source-mail-submission.h>
 
 #include <mail/mail-tools.h>
 #include <mail/e-mail-local.h>
 #include <mail/e-mail-folder-utils.h>
-#include <e-util/e-account-utils.h>
 #include <filter/e-filter-rule.h>
 
 /* X-Mailer header value */
@@ -627,6 +627,7 @@ exit:
 
 void
 e_mail_session_send_to (EMailSession *session,
+                        ESourceRegistry *registry,
                         CamelMimeMessage *message,
                         gint io_priority,
                         GCancellable *cancellable,
@@ -641,7 +642,7 @@ e_mail_session_send_to (EMailSession *session,
 	CamelAddress *recipients;
 	CamelMedium *medium;
 	CamelMessageInfo *info;
-	EAccount *account = NULL;
+	ESource *source;
 	GPtrArray *post_to_uris;
 	struct _camel_header_raw *xev;
 	struct _camel_header_raw *header;
@@ -652,6 +653,7 @@ e_mail_session_send_to (EMailSession *session,
 	GError *error = NULL;
 
 	g_return_if_fail (E_IS_MAIL_SESSION (session));
+	g_return_if_fail (E_IS_SOURCE_REGISTRY (registry));
 	g_return_if_fail (CAMEL_IS_MIME_MESSAGE (message));
 
 	medium = CAMEL_MEDIUM (message);
@@ -662,28 +664,25 @@ e_mail_session_send_to (EMailSession *session,
 
 	/* Extract directives from X-Evolution headers. */
 
-	string = camel_header_raw_find (&xev, "X-Evolution-Account", NULL);
+	string = camel_header_raw_find (&xev, "X-Evolution-Identity", NULL);
 	if (string != NULL) {
-		gchar *account_uid;
-
-		account_uid = g_strstrip (g_strdup (string));
-		account = e_get_account_by_uid (account_uid);
-		g_free (account_uid);
+		gchar *uid = g_strstrip (g_strdup (string));
+		source = e_source_registry_lookup_by_uid (registry, uid);
+		g_free (uid);
 	}
 
-	if (account != NULL) {
-		if (account->transport != NULL) {
+	if (E_IS_SOURCE (source)) {
+		ESourceMailSubmission *extension;
+		const gchar *extension_name;
 
-			/* XXX Transport UIDs are kludgy right now.  We
-			 *     use the EAccount's regular UID and tack on
-			 *     "-transport".  Will be better soon. */
-			transport_uid = g_strconcat (
-				account->uid, "-transport", NULL);
+		extension_name = E_SOURCE_EXTENSION_MAIL_SUBMISSION;
+		extension = e_source_get_extension (source, extension_name);
 
-			/* to reprompt password on sending if needed */
-			account->transport->get_password_canceled = FALSE;
-		}
-		sent_folder_uri = g_strdup (account->sent_folder_uri);
+		string = e_source_mail_submission_get_sent_folder (extension);
+		sent_folder_uri = g_strdup (string);
+
+		string = e_source_mail_submission_get_transport_uid (extension);
+		transport_uid = g_strdup (string);
 	}
 
 	string = camel_header_raw_find (&xev, "X-Evolution-Fcc", NULL);
diff --git a/mail/e-mail-session-utils.h b/mail/e-mail-session-utils.h
index b398be5..2d0c15f 100644
--- a/mail/e-mail-session-utils.h
+++ b/mail/e-mail-session-utils.h
@@ -22,6 +22,7 @@
 /* High-level operations with Evolution-specific policies. */
 
 #include <mail/e-mail-session.h>
+#include <libedataserver/e-source-registry.h>
 
 #define E_MAIL_ERROR (e_mail_error_quark ())
 
@@ -65,6 +66,7 @@ gboolean	e_mail_session_handle_source_headers_finish
 						 GAsyncResult *result,
 						 GError **error);
 void		e_mail_session_send_to		(EMailSession *session,
+						 ESourceRegistry *registry,
 						 CamelMimeMessage *message,
 						 gint io_priority,
 						 GCancellable *cancellable,
diff --git a/mail/e-mail-session.c b/mail/e-mail-session.c
index 39ccbbb..40c7832 100644
--- a/mail/e-mail-session.c
+++ b/mail/e-mail-session.c
@@ -47,21 +47,30 @@
 #include <libedataserver/e-flag.h>
 #include <libedataserver/e-proxy.h>
 #include <libebackend/e-extensible.h>
+#include <libedataserver/e-source-authentication.h>
+#include <libedataserver/e-source-mail-account.h>
+#include <libedataserver/e-source-mail-identity.h>
+#include <libedataserver/e-source-mail-submission.h>
+#include <libedataserver/e-source-mail-transport.h>
+#include <libedataserver/e-source-password.h>
 #include <libedataserverui/e-passwords.h>
 
 #include "e-util/e-util.h"
-#include "e-util/e-account-utils.h"
 #include "e-util/e-alert-dialog.h"
 #include "e-util/e-util-private.h"
 #include "e-util/gconf-bridge.h"
 
+#include "e-mail-authenticator.h"
 #include "e-mail-folder-utils.h"
 #include "e-mail-junk-filter.h"
 #include "e-mail-local.h"
 #include "e-mail-session.h"
+#include "e-mail-store.h"
+#include "e-source-camel.h"
 #include "em-composer-utils.h"
 #include "em-filter-context.h"
 #include "em-filter-rule.h"
+#include "em-folder-tree-model.h"
 #include "em-utils.h"
 #include "mail-config.h"
 #include "mail-mt.h"
@@ -79,6 +88,7 @@ typedef struct _AsyncContext AsyncContext;
 
 struct _EMailSessionPrivate {
 	MailFolderCache *folder_cache;
+	ESourceRegistry *registry;
 
 	FILE *filter_logfile;
 	GHashTable *junk_filters;
@@ -98,7 +108,8 @@ struct _AsyncContext {
 enum {
 	PROP_0,
 	PROP_FOLDER_CACHE,
-	PROP_JUNK_FILTER_NAME
+	PROP_JUNK_FILTER_NAME,
+	PROP_REGISTRY
 };
 
 static gchar *mail_data_dir;
@@ -453,22 +464,131 @@ async_context_free (AsyncContext *context)
 	g_slice_free (AsyncContext, context);
 }
 
+static void
+mail_session_source_added_cb (ESourceRegistry *registry,
+                              ESource *source,
+                              EMailSession *session)
+{
+	CamelProviderType provider_type;
+	const gchar *extension_name;
+
+	if (!e_source_get_enabled (source))
+		return;
+
+	provider_type = CAMEL_PROVIDER_STORE;
+	extension_name = E_SOURCE_EXTENSION_MAIL_ACCOUNT;
+
+	if (e_source_has_extension (source, extension_name))
+		e_mail_store_add_by_source (session, provider_type, source);
+
+	provider_type = CAMEL_PROVIDER_TRANSPORT;
+	extension_name = E_SOURCE_EXTENSION_MAIL_TRANSPORT;
+
+	if (e_source_has_extension (source, extension_name))
+		e_mail_store_add_by_source (session, provider_type, source);
+}
+
+static void
+mail_session_source_removed_cb (ESourceRegistry *registry,
+                                ESource *source,
+                                EMailSession *session)
+{
+	/* The ESource could be anything: a calendar, address book, etc.
+	 * This will return quietly if there's no matching CamelService. */
+	e_mail_store_remove_by_source (session, source);
+}
+
+static void
+mail_session_source_changed_cb (ESourceRegistry *registry,
+                                ESource *source,
+                                EMailSession *session)
+{
+	EMFolderTreeModel *default_model;
+	CamelService *service;
+	const gchar *extension_name;
+	const gchar *uid;
+
+	extension_name = E_SOURCE_EXTENSION_MAIL_ACCOUNT;
+	if (!e_source_has_extension (source, extension_name))
+		return;
+
+	uid = e_source_get_uid (source);
+	service = camel_session_get_service (CAMEL_SESSION (session), uid);
+
+	if (!CAMEL_IS_STORE (service))
+		return;
+
+	default_model = em_folder_tree_model_get_default ();
+
+	em_folder_tree_model_remove_store (
+		default_model, CAMEL_STORE (service));
+
+	if (!e_source_get_enabled (source))
+		return;
+
+	em_folder_tree_model_add_store (
+		default_model, CAMEL_STORE (service));
+}
+
 static gchar *
-mail_session_make_key (CamelService *service,
-                       const gchar *item)
+mail_session_resolve_popb4smtp (ESourceRegistry *registry,
+                                CamelService *smtp_service)
 {
-	gchar *key;
+	GList *list, *link;
+	const gchar *extension_name;
+	const gchar *smtp_uid;
+	gchar *pop_uid = NULL;
 
-	if (service != NULL) {
-		CamelURL *url;
+	/* Find a POP account that uses the given smtp_service as its
+	 * transport.  XXX This isn't foolproof though, since we don't
+	 * check that the POP server is at the same domain as the SMTP
+	 * server, which is kind of the point of POPB4SMTP. */
 
-		url = camel_service_new_camel_url (service);
-		key = camel_url_to_string (url, CAMEL_URL_HIDE_ALL);
-		camel_url_free (url);
-	} else
-		key = g_strdup (item);
+	smtp_uid = camel_service_get_uid (smtp_service);
 
-	return key;
+	extension_name = E_SOURCE_EXTENSION_MAIL_ACCOUNT;
+	list = e_source_registry_list_sources (registry, extension_name);
+
+	for (link = list; link != NULL; link = g_list_next (link)) {
+		ESource *source = E_SOURCE (link->data);
+		ESourceExtension *extension;
+		const gchar *backend_name;
+		const gchar *uid;
+
+		/* We're only interested in POP accounts. */
+		backend_name = e_source_get_backend_name (source);
+		if (g_strcmp0 (backend_name, "pop") != 0)
+			continue;
+
+		/* Get the mail account's default mail identity. */
+
+		extension_name = E_SOURCE_EXTENSION_MAIL_ACCOUNT;
+		extension = e_source_get_extension (source, extension_name);
+
+		source = e_source_mail_account_get_identity (
+			E_SOURCE_MAIL_ACCOUNT (extension));
+		if (source == NULL)
+			continue;
+
+		/* Get the mail identity's default mail transport. */
+
+		extension_name = E_SOURCE_EXTENSION_MAIL_SUBMISSION;
+		extension = e_source_get_extension (source, extension_name);
+
+		uid = e_source_mail_submission_get_transport_uid (
+			E_SOURCE_MAIL_SUBMISSION (extension));
+		if (uid == NULL)
+			continue;
+
+		if (g_strcmp0 (uid, smtp_uid) == 0) {
+			pop_uid = g_strdup (uid);
+			break;
+		}
+	}
+
+	g_list_free (list);
+
+	return pop_uid;
 }
 
 static void
@@ -554,6 +674,16 @@ mail_session_set_junk_filter_name (EMailSession *session,
 }
 
 static void
+mail_session_set_registry (EMailSession *session,
+                           ESourceRegistry *registry)
+{
+	g_return_if_fail (E_IS_SOURCE_REGISTRY (registry));
+	g_return_if_fail (session->priv->registry == NULL);
+
+	session->priv->registry = g_object_ref (registry);
+}
+
+static void
 mail_session_set_property (GObject *object,
                            guint property_id,
                            const GValue *value,
@@ -565,6 +695,12 @@ mail_session_set_property (GObject *object,
 				E_MAIL_SESSION (object),
 				g_value_get_string (value));
 			return;
+
+		case PROP_REGISTRY:
+			mail_session_set_registry (
+				E_MAIL_SESSION (object),
+				g_value_get_object (value));
+			return;
 	}
 
 	G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
@@ -590,6 +726,13 @@ mail_session_get_property (GObject *object,
 				mail_session_get_junk_filter_name (
 				E_MAIL_SESSION (object)));
 			return;
+
+		case PROP_REGISTRY:
+			g_value_set_object (
+				value,
+				e_mail_session_get_registry (
+				E_MAIL_SESSION (object)));
+			return;
 	}
 
 	G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
@@ -607,6 +750,14 @@ mail_session_dispose (GObject *object)
 		priv->folder_cache = NULL;
 	}
 
+	if (priv->registry != NULL) {
+		g_signal_handlers_disconnect_matched (
+			priv->registry, G_SIGNAL_MATCH_DATA,
+			0, 0, NULL, NULL, object);
+		g_object_unref (priv->registry);
+		priv->registry = NULL;
+	}
+
 	/* Chain up to parent's dispose() method. */
 	G_OBJECT_CLASS (e_mail_session_parent_class)->dispose (object);
 }
@@ -653,12 +804,14 @@ mail_session_notify (GObject *object,
 static void
 mail_session_constructed (GObject *object)
 {
-	EMailSessionPrivate *priv;
+	EMailSession *session;
 	EExtensible *extensible;
+	ESourceRegistry *registry;
 	GType extension_type;
 	GList *list, *iter;
 
-	priv = E_MAIL_SESSION_GET_PRIVATE (object);
+	session = E_MAIL_SESSION (object);
+	registry = e_mail_session_get_registry (session);
 
 	/* Chain up to parent's constructed() method. */
 	G_OBJECT_CLASS (e_mail_session_parent_class)->constructed (object);
@@ -703,7 +856,7 @@ mail_session_constructed (GObject *object)
 		/* No need to reference the EMailJunkFilter since
 		 * EMailSession owns the reference to it already. */
 		g_hash_table_insert (
-			priv->junk_filters,
+			session->priv->junk_filters,
 			(gpointer) class->filter_name,
 			junk_filter);
 	}
@@ -717,6 +870,20 @@ mail_session_constructed (GObject *object)
 		gconf_bridge_get (),
 		"/apps/evolution/mail/junk/default_plugin",
 		object, "junk-filter-name");
+
+	/* Listen for registry changes. */
+
+	g_signal_connect (
+		registry, "source-added",
+		G_CALLBACK (mail_session_source_added_cb), session);
+
+	g_signal_connect (
+		registry, "source-removed",
+		G_CALLBACK (mail_session_source_removed_cb), session);
+
+	g_signal_connect (
+		registry, "source-changed",
+		G_CALLBACK (mail_session_source_changed_cb), session);
 }
 
 static CamelService *
@@ -726,55 +893,56 @@ mail_session_add_service (CamelSession *session,
                           CamelProviderType type,
                           GError **error)
 {
+	ESourceRegistry *registry;
 	CamelService *service;
 
+	registry = e_mail_session_get_registry (E_MAIL_SESSION (session));
+
 	/* Chain up to parents add_service() method. */
 	service = CAMEL_SESSION_CLASS (e_mail_session_parent_class)->
 		add_service (session, uid, protocol, type, error);
 
-	/* Initialize the CamelSettings object from CamelURL parameters.
-	 * This is temporary; soon we'll read settings from key files. */
+	/* Configure the CamelService from the corresponding ESource. */
 
 	if (CAMEL_IS_SERVICE (service)) {
-		EAccount *account;
-		CamelURL *url = NULL;
-
-		account = e_get_account_by_uid (uid);
-		if (account != NULL) {
-			const gchar *url_string = NULL;
-
-			switch (type) {
-				case CAMEL_PROVIDER_STORE:
-					url_string = account->source->url;
-					break;
-				case CAMEL_PROVIDER_TRANSPORT:
-					url_string = account->transport->url;
-					break;
-				default:
-					break;
-			}
+		ESource *source;
 
-			if (url_string != NULL) {
-				url = camel_url_new (url_string, error);
-				if (url == NULL) {
-					g_object_unref (service);
-					service = NULL;
-				}
-			}
-		}
+		/* We'd like to emit a warning if we fail to find an
+		 * ESource with a matching UID, but we don't want to
+		 * emit false positives.  The built-in CamelServices
+		 * ("local" and "vfolder") do not have corresponding
+		 * ESources, so check for those cases first. */
 
-		if (url != NULL) {
-			CamelSettings *settings;
+		if (g_strcmp0 (uid, "local") == 0)
+			return service;
 
-			settings = camel_service_get_settings (service);
-			camel_settings_load_from_url (settings, url);
-			camel_url_free (url);
+		if (g_strcmp0 (uid, "vfolder") == 0)
+			return service;
 
-			/* Migrate files for this service from its old
-			 * URL-based directory to a UID-based directory
-			 * if necessary. */
-			camel_service_migrate_files (service);
-		}
+		/* Now we should get an ESource.  Note we still return
+		 * the CamelService even if we have to emit a warning. */
+
+		source = e_source_registry_lookup_by_uid (registry, uid);
+		g_return_val_if_fail (E_IS_SOURCE (source), service);
+
+		/* This handles all the messy property bindings. */
+		e_source_camel_configure_service (source, service);
+
+		g_object_bind_property (
+			source, "display-name",
+			service, "display-name",
+			G_BINDING_BIDIRECTIONAL |
+			G_BINDING_SYNC_CREATE);
+
+		/* Migrate files for this service from its old
+		 * URL-based directory to a UID-based directory
+		 * if necessary. */
+		camel_service_migrate_files (service);
+
+		g_debug ("Added %s '%s' (%s)",
+			G_OBJECT_TYPE_NAME (service),
+			camel_service_get_display_name (service),
+			camel_service_get_uid (service));
 	}
 
 	return service;
@@ -788,114 +956,69 @@ mail_session_get_password (CamelSession *session,
                            guint32 flags,
                            GError **error)
 {
-	EAccount *account = NULL;
-	const gchar *display_name = NULL;
-	const gchar *uid = NULL;
-	gchar *ret = NULL;
-
-	if (CAMEL_IS_SERVICE (service)) {
-		display_name = camel_service_get_display_name (service);
-		uid = camel_service_get_uid (service);
-		account = e_get_account_by_uid (uid);
-	}
-
-	if (!strcmp(item, "popb4smtp_uid")) {
-		/* not 100% mt safe, but should be ok */
-		ret = g_strdup ((account != NULL) ? account->uid : uid);
-	} else {
-		gchar *key = mail_session_make_key (service, item);
-		EAccountService *config_service = NULL;
-
-		ret = e_passwords_get_password (NULL, key);
-		if (ret == NULL || (flags & CAMEL_SESSION_PASSWORD_REPROMPT)) {
-			gboolean remember;
-
-			g_free (ret);
-			ret = NULL;
-
-			if (account != NULL) {
-				if (CAMEL_IS_STORE (service))
-					config_service = account->source;
-				if (CAMEL_IS_TRANSPORT (service))
-					config_service = account->transport;
-			}
-
-			remember = config_service ? config_service->save_passwd : FALSE;
-
-			if (!config_service || (config_service &&
-				!config_service->get_password_canceled)) {
-				guint32 eflags;
-				gchar *title;
-
-				if (flags & CAMEL_SESSION_PASSPHRASE) {
-					if (display_name != NULL)
-						title = g_strdup_printf (
-							_("Enter Passphrase for %s"),
-							display_name);
-					else
-						title = g_strdup (
-							_("Enter Passphrase"));
-				} else {
-					if (display_name != NULL)
-						title = g_strdup_printf (
-							_("Enter Password for %s"),
-							display_name);
-					else
-						title = g_strdup (
-							_("Enter Password"));
-				}
-				if ((flags & CAMEL_SESSION_PASSWORD_STATIC) != 0)
-					eflags = E_PASSWORDS_REMEMBER_NEVER;
-				else if (config_service == NULL)
-					eflags = E_PASSWORDS_REMEMBER_SESSION;
-				else
-					eflags = E_PASSWORDS_REMEMBER_FOREVER;
-
-				if (flags & CAMEL_SESSION_PASSWORD_REPROMPT)
-					eflags |= E_PASSWORDS_REPROMPT;
-
-				if (flags & CAMEL_SESSION_PASSWORD_SECRET)
-					eflags |= E_PASSWORDS_SECRET;
-
-				if (flags & CAMEL_SESSION_PASSPHRASE)
-					eflags |= E_PASSWORDS_PASSPHRASE;
-
-				/* HACK: breaks abstraction ...
-				 * e_account_writable() doesn't use the
-				 * EAccount, it also uses the same writable
-				 * key for source and transport. */
-				if (!e_account_writable (NULL, E_ACCOUNT_SOURCE_SAVE_PASSWD))
-					eflags |= E_PASSWORDS_DISABLE_REMEMBER;
-
-				ret = e_passwords_ask_password (
-					title, NULL, key, prompt,
-					eflags, &remember, NULL);
-
-				if (!ret)
-					e_passwords_forget_password (NULL, key);
-
-				g_free (title);
-
-				if (ret && config_service) {
-					config_service->save_passwd = remember;
-					e_account_list_save (e_get_account_list ());
-				}
-
-				if (config_service)
-					config_service->get_password_canceled = ret == NULL;
-			}
-		}
-
-		g_free (key);
+	ESourceRegistry *registry;
+	gchar *password = NULL;
+
+	/* XXX This method is now only for fringe cases.  For normal
+	 *     CamelService authentication, use authenticate_sync().
+	 *
+	 *     The two known fringe cases that still need this are:
+	 *
+	 *     1) CamelSaslPOPB4SMTP, where the CamelService is an SMTP
+	 *        transport and the item name is always "popb4smtp_uid".
+	 *        (This is a dirty hack, Camel just needs some way to
+	 *        pair up a CamelService and CamelTransport.  Not sure
+	 *        what that should look like just yet...)
+	 *
+	 *     2) CamelGpgContext, where the CamelService is NULL and
+	 *        the item name is a user ID (I think).  (Seahorse, or
+	 *        one of its dependent libraries, ought to handle this
+	 *        transparently once Camel fully transitions to GIO.)
+	 */
+
+	registry = e_mail_session_get_registry (E_MAIL_SESSION (session));
+
+	/* Handle the CamelSaslPOPB4SMTP case. */
+	if (g_strcmp0 (item, "popb4smtp_uid") == 0)
+		return mail_session_resolve_popb4smtp (registry, service);
+
+	/* Otherwise this had better be the CamelGpgContext case. */
+	g_return_val_if_fail (service == NULL, NULL);
+
+	password = e_passwords_get_password (NULL, item);
+
+	if (password == NULL || (flags & CAMEL_SESSION_PASSWORD_REPROMPT)) {
+		gboolean remember;
+		guint eflags = 0;
+
+		if (flags & CAMEL_SESSION_PASSWORD_STATIC)
+			eflags |= E_PASSWORDS_REMEMBER_NEVER;
+		else
+			eflags |= E_PASSWORDS_REMEMBER_SESSION;
+
+		if (flags & CAMEL_SESSION_PASSWORD_REPROMPT)
+			eflags |= E_PASSWORDS_REPROMPT;
+
+		if (flags & CAMEL_SESSION_PASSWORD_SECRET)
+			eflags |= E_PASSWORDS_SECRET;
+
+		if (flags & CAMEL_SESSION_PASSPHRASE)
+			eflags |= E_PASSWORDS_PASSPHRASE;
+
+		password = e_passwords_ask_password (
+			"", NULL, item, prompt, eflags, &remember, NULL);
+
+		if (password == NULL)
+			e_passwords_forget_password (NULL, item);
 	}
 
-	if (ret == NULL)
+	if (password == NULL)
 		g_set_error (
 			error, G_IO_ERROR,
 			G_IO_ERROR_CANCELLED,
-			_("User canceled operation."));
+			_("User cancelled operation"));
 
-	return ret;
+	return password;
 }
 
 static gboolean
@@ -904,15 +1027,29 @@ mail_session_forget_password (CamelSession *session,
                               const gchar *item,
                               GError **error)
 {
-	gchar *key;
+	ESource *source;
+	ESourceRegistry *registry;
+	const gchar *uid;
 
-	key = mail_session_make_key (service, item);
+	registry = e_mail_session_get_registry (E_MAIL_SESSION (session));
 
-	e_passwords_forget_password (NULL, key);
+	if (!CAMEL_IS_SERVICE (service))
+		goto no_service;
 
-	g_free (key);
+	uid = camel_service_get_uid (service);
+	source = e_source_registry_lookup_by_uid (registry, uid);
+	g_return_val_if_fail (source != NULL, FALSE);
 
-	return TRUE;
+	return e_source_password_delete_sync (source, NULL, error);
+
+no_service:
+
+	/* FIXME: ACCOUNT_MGMT
+	 *
+	 * How to deal with this?
+	 * GPG password requests don't pass up a CamelService. */
+
+	return FALSE;
 }
 
 static gboolean
@@ -988,13 +1125,18 @@ mail_session_forward_to (CamelSession *session,
                          const gchar *address,
                          GError **error)
 {
-	EAccount *account;
+	ESource *source;
+	ESourceRegistry *registry;
+	ESourceMailIdentity *extension;
 	CamelMimeMessage *forward;
 	CamelStream *mem;
 	CamelInternetAddress *addr;
 	CamelFolder *out_folder;
 	CamelMessageInfo *info;
 	CamelMedium *medium;
+	const gchar *extension_name;
+	const gchar *from_address;
+	const gchar *from_name;
 	const gchar *header_name;
 	struct _camel_header_raw *xev;
 	gchar *subject;
@@ -1006,20 +1148,28 @@ mail_session_forward_to (CamelSession *session,
 	if (!*address) {
 		g_set_error (
 			error, CAMEL_ERROR, CAMEL_ERROR_GENERIC,
-			_("No destination address provided, forward "
+			_("No destination address provided, forwarding "
 			  "of the message has been cancelled."));
 		return FALSE;
 	}
 
-	account = em_utils_guess_account_with_recipients (message, folder);
-	if (!account) {
+	registry = e_mail_session_get_registry (E_MAIL_SESSION (session));
+
+	source = em_utils_guess_mail_identity_with_recipients (
+		registry, message, folder);
+	if (source == NULL) {
 		g_set_error (
 			error, CAMEL_ERROR, CAMEL_ERROR_GENERIC,
-			_("No account found to use, forward of the "
-			  "message has been cancelled."));
+			_("No identity found to use, forwarding "
+			  "of the message has been cancelled."));
 		return FALSE;
 	}
 
+	extension_name = E_SOURCE_EXTENSION_MAIL_IDENTITY;
+	extension = e_source_get_extension (source, extension_name);
+	from_address = e_source_mail_identity_get_address (extension);
+	from_name = e_source_mail_identity_get_name (extension);
+
 	forward = camel_mime_message_new ();
 
 	/* make copy of the message, because we are going to modify it */
@@ -1062,8 +1212,7 @@ mail_session_forward_to (CamelSession *session,
 
 	/* from */
 	addr = camel_internet_address_new ();
-	camel_internet_address_add (
-		addr, account->id->name, account->id->address);
+	camel_internet_address_add (addr, from_name, from_address);
 	camel_mime_message_set_from (forward, addr);
 	g_object_unref (addr);
 
@@ -1138,19 +1287,23 @@ mail_session_authenticate_sync (CamelSession *session,
                                 GCancellable *cancellable,
                                 GError **error)
 {
+	ESource *source;
+	ESourceRegistry *registry;
+	ESourceAuthenticator *auth;
 	CamelServiceAuthType *authtype = NULL;
 	CamelAuthenticationResult result;
-	CamelProvider *provider;
-	CamelSettings *settings;
-	const gchar *password;
-	guint32 password_flags;
+	const gchar *uid;
+	gboolean authenticated;
 	GError *local_error = NULL;
 
 	/* Do not chain up.  Camel's default method is only an example for
 	 * subclasses to follow.  Instead we mimic most of its logic here. */
 
-	provider = camel_service_get_provider (service);
-	settings = camel_service_get_settings (service);
+	registry = e_mail_session_get_registry (E_MAIL_SESSION (session));
+
+	/* Treat a mechanism name of "none" as NULL. */
+	if (g_strcmp0 (mechanism, "none") == 0)
+		mechanism = NULL;
 
 	/* APOP is one case where a non-SASL mechanism name is passed, so
 	 * don't bail if the CamelServiceAuthType struct comes back NULL. */
@@ -1203,58 +1356,26 @@ mail_session_authenticate_sync (CamelSession *session,
 
 	g_clear_error (&local_error);
 
-	password_flags = CAMEL_SESSION_PASSWORD_SECRET;
-
-retry:
-	password = camel_service_get_password (service);
-
-	if (password == NULL) {
-		CamelNetworkSettings *network_settings;
-		const gchar *host;
-		const gchar *user;
-		gchar *prompt;
-		gchar *new_passwd;
-
-		network_settings = CAMEL_NETWORK_SETTINGS (settings);
-		host = camel_network_settings_get_host (network_settings);
-		user = camel_network_settings_get_user (network_settings);
-
-		prompt = camel_session_build_password_prompt (
-			provider->name, user, host);
-
-		new_passwd = camel_session_get_password (
-			session, service, prompt, "password",
-			password_flags, &local_error);
-		camel_service_set_password (service, new_passwd);
-		password = camel_service_get_password (service);
-		g_free (new_passwd);
+	/* Find a matching ESource for this CamelService. */
+	uid = camel_service_get_uid (service);
+	source = e_source_registry_lookup_by_uid (registry, uid);
 
-		g_free (prompt);
-
-		if (local_error != NULL) {
-			g_propagate_error (error, local_error);
-			return FALSE;
-		}
-
-		if (password == NULL) {
-			g_set_error (
-				error, CAMEL_SERVICE_ERROR,
-				CAMEL_SERVICE_ERROR_CANT_AUTHENTICATE,
-				_("No password was provided"));
-			return FALSE;
-		}
+	if (source == NULL) {
+		g_set_error (
+			error, CAMEL_SERVICE_ERROR,
+			CAMEL_SERVICE_ERROR_CANT_AUTHENTICATE,
+			_("No data source found for UID '%s'"), uid);
+		return FALSE;
 	}
 
-	result = camel_service_authenticate_sync (
-		service, mechanism, cancellable, error);
+	auth = e_mail_authenticator_new (service, mechanism);
 
-	if (result == CAMEL_AUTHENTICATION_REJECTED) {
-		password_flags |= CAMEL_SESSION_PASSWORD_REPROMPT;
-		camel_service_set_password (service, NULL);
-		goto retry;
-	}
+	authenticated = e_source_authenticate_sync (
+		source, auth, cancellable, error);
 
-	return (result == CAMEL_AUTHENTICATION_ACCEPTED);
+	g_object_unref (auth);
+
+	return authenticated;
 }
 
 static void
@@ -1308,6 +1429,18 @@ e_mail_session_class_init (EMailSessionClass *class)
 			NULL,
 			G_PARAM_READWRITE |
 			G_PARAM_STATIC_STRINGS));
+
+	g_object_class_install_property (
+		object_class,
+		PROP_REGISTRY,
+		g_param_spec_object (
+			"registry",
+			"Registry",
+			"Data source registry",
+			E_TYPE_SOURCE_REGISTRY,
+			G_PARAM_READWRITE |
+			G_PARAM_CONSTRUCT_ONLY |
+			G_PARAM_STATIC_STRINGS));
 }
 
 static void
@@ -1321,9 +1454,6 @@ e_mail_session_init (EMailSession *session)
 		(GHashFunc) g_str_hash, (GEqualFunc) g_str_equal);
 	session->priv->proxy = e_proxy_new ();
 
-	/* Initialize the EAccount setup. */
-	e_account_writable (NULL, E_ACCOUNT_SOURCE_SAVE_PASSWD);
-
 	client = gconf_client_get_default ();
 
 	gconf_client_add_dir (
@@ -1345,11 +1475,13 @@ e_mail_session_init (EMailSession *session)
 }
 
 EMailSession *
-e_mail_session_new (void)
+e_mail_session_new (ESourceRegistry *registry)
 {
 	const gchar *user_data_dir;
 	const gchar *user_cache_dir;
 
+	g_return_val_if_fail (E_IS_SOURCE_REGISTRY (registry), NULL);
+
 	user_data_dir = mail_session_get_data_dir ();
 	user_cache_dir = mail_session_get_cache_dir ();
 
@@ -1357,6 +1489,7 @@ e_mail_session_new (void)
 		E_TYPE_MAIL_SESSION,
 		"user-data-dir", user_data_dir,
 		"user-cache-dir", user_cache_dir,
+		"registry", registry,
 		NULL);
 }
 
@@ -1368,6 +1501,14 @@ e_mail_session_get_folder_cache (EMailSession *session)
 	return session->priv->folder_cache;
 }
 
+ESourceRegistry *
+e_mail_session_get_registry (EMailSession *session)
+{
+	g_return_val_if_fail (E_IS_MAIL_SESSION (session), NULL);
+
+	return session->priv->registry;
+}
+
 GList *
 e_mail_session_get_available_junk_filters (EMailSession *session)
 {
diff --git a/mail/e-mail-session.h b/mail/e-mail-session.h
index 165b335..e0fc425 100644
--- a/mail/e-mail-session.h
+++ b/mail/e-mail-session.h
@@ -27,6 +27,7 @@
 
 #include <camel/camel.h>
 #include <mail/mail-folder-cache.h>
+#include <libedataserver/e-source-registry.h>
 
 /* Standard GObject macros */
 #define E_TYPE_MAIL_SESSION \
@@ -63,9 +64,11 @@ struct _EMailSessionClass {
 };
 
 GType		e_mail_session_get_type		(void);
-EMailSession *	e_mail_session_new		(void);
+EMailSession *	e_mail_session_new		(ESourceRegistry *registry);
 MailFolderCache *
 		e_mail_session_get_folder_cache	(EMailSession *session);
+ESourceRegistry *
+		e_mail_session_get_registry	(EMailSession *session);
 GList *		e_mail_session_get_available_junk_filters
 						(EMailSession *session);
 CamelFolder *	e_mail_session_get_inbox_sync	(EMailSession *session,
diff --git a/mail/e-mail-store.c b/mail/e-mail-store.c
index c995f42..2488429 100644
--- a/mail/e-mail-store.c
+++ b/mail/e-mail-store.c
@@ -27,17 +27,17 @@
 
 #include <glib/gi18n.h>
 #include <camel/camel.h>
-#include <libedataserver/e-account.h>
-#include <libedataserver/e-account-list.h>
-
-#include "e-util/e-account-utils.h"
-
-#include "mail/e-mail-local.h"
-#include "mail/em-folder-tree-model.h"
-#include "mail/em-utils.h"
-#include "mail/mail-folder-cache.h"
-#include "mail/mail-mt.h"
-#include "mail/mail-ops.h"
+#include <libedataserver/e-source-authentication.h>
+#include <libedataserver/e-source-mail-account.h>
+#include <libedataserver/e-source-mail-transport.h>
+
+#include <shell/e-shell.h>
+#include <mail/e-mail-local.h>
+#include <mail/em-folder-tree-model.h>
+#include <mail/em-utils.h>
+#include <mail/mail-folder-cache.h>
+#include <mail/mail-mt.h>
+#include <mail/mail-ops.h>
 
 #include "shell/e-shell.h"
 #include "shell/e-shell-settings.h"
@@ -181,6 +181,38 @@ special_mail_store_is_enabled (CamelStore *store)
 	return e_shell_settings_get_boolean (shell_settings, prop);
 }
 
+static CamelService *
+mail_store_add_service_from_source (EMailSession *session,
+                                    CamelProviderType type,
+                                    ESource *source)
+{
+	CamelService *service;
+	const gchar *uid;
+	const gchar *backend_name;
+	const gchar *display_name;
+	GError *error = NULL;
+
+	uid = e_source_get_uid (source);
+	backend_name = e_source_get_backend_name (source);
+	display_name = e_source_get_display_name (source);
+
+	/* Sanity checks. */
+	g_return_val_if_fail (uid != NULL, NULL);
+	g_return_val_if_fail (backend_name != NULL, NULL);
+
+	service = camel_session_add_service (
+		CAMEL_SESSION (session), uid, backend_name, type, &error);
+
+	if (error != NULL) {
+		g_warn_if_fail (service == NULL);
+		g_warning (
+			"Failed to add service '%s' (%s): %s",
+			display_name, uid, error->message);
+	}
+
+	return service;
+}
+
 static void
 mail_store_add (EMailSession *session,
                 CamelStore *store,
@@ -230,9 +262,13 @@ static void
 mail_store_load_accounts (EMailSession *session,
                           const gchar *data_dir)
 {
+	ESourceRegistry *registry;
+	CamelProviderType provider_type;
 	CamelStore *local_store;
-	EAccountList *account_list;
-	EIterator *iter;
+	GList *list, *link;
+	const gchar *extension_name;
+
+	registry = e_mail_session_get_registry (session);
 
 	/* Add the local store. */
 
@@ -243,23 +279,39 @@ mail_store_load_accounts (EMailSession *session,
 		session, local_store, (AddStoreCallback)
 		mail_store_add_local_done_cb);
 
-	/* Add mail accounts.. */
+	/* Add mail accounts. */
+
+	provider_type = CAMEL_PROVIDER_STORE;
+	extension_name = E_SOURCE_EXTENSION_MAIL_ACCOUNT;
+	list = e_source_registry_list_sources (registry, extension_name);
+
+	for (link = list; link != NULL; link = g_list_next (link)) {
+		ESource *source = E_SOURCE (link->data);
+
+		if (!e_source_get_enabled (source))
+			continue;
+
+		e_mail_store_add_by_source (session, provider_type, source);
+	}
 
-	account_list = e_get_account_list ();
+	g_list_free (list);
 
-	for (iter = e_list_get_iterator ((EList *) account_list);
-	     e_iterator_is_valid (iter); e_iterator_next (iter)) {
-		EAccount *account;
+	/* Add mail transports. */
 
-		account = (EAccount *) e_iterator_get (iter);
+	provider_type = CAMEL_PROVIDER_TRANSPORT;
+	extension_name = E_SOURCE_EXTENSION_MAIL_TRANSPORT;
+	list = e_source_registry_list_sources (registry, extension_name);
 
-		if (!account->enabled)
+	for (link = list; link != NULL; link = g_list_next (link)) {
+		ESource *source = E_SOURCE (link->data);
+
+		if (!e_source_get_enabled (source))
 			continue;
 
-		e_mail_store_add_by_account (session, account);
+		e_mail_store_add_by_source (session, provider_type, source);
 	}
 
-	g_object_unref (iter);
+	g_list_free (list);
 }
 
 void
@@ -297,123 +349,44 @@ e_mail_store_add (EMailSession *session,
 	mail_store_add (session, store, NULL);
 }
 
-CamelStore *
-e_mail_store_add_by_account (EMailSession *session,
-                             EAccount *account)
+CamelService *
+e_mail_store_add_by_source (EMailSession *session,
+                            CamelProviderType type,
+                            ESource *source)
 {
 	CamelService *service = NULL;
 	CamelProvider *provider;
 	CamelURL *url;
-	gboolean transport_only;
-	gboolean service_is_local_delivery;
 	gboolean service_belongs_in_tree_model;
-	GError *error = NULL;
 
-	g_return_val_if_fail (E_IS_MAIL_SESSION (session), NULL);
-	g_return_val_if_fail (E_IS_ACCOUNT (account), NULL);
+	/* Note, this function handles both stores and transports. */
 
-	/* check whether it's transport-only accounts */
-	transport_only =
-		(account->source == NULL) ||
-		(account->source->url == NULL) ||
-		(*account->source->url == '\0');
-	if (transport_only)
-		goto handle_transport;
+	g_return_val_if_fail (E_IS_MAIL_SESSION (session), NULL);
+	g_return_val_if_fail (E_IS_SOURCE (source), NULL);
 
 	/* Load the service, but don't connect.  Check its provider,
 	 * and if this belongs in the folder tree model, add it. */
 
-	url = camel_url_new (account->source->url, NULL);
-	if (url != NULL) {
-		service_is_local_delivery =
-			em_utils_is_local_delivery_mbox_file (url);
-		provider = camel_provider_get (url->protocol, NULL);
-		camel_url_free (url);
-	} else {
-		service_is_local_delivery = FALSE;
-		provider = NULL;
-	}
-
-	if (provider == NULL) {
-		/* In case we do not have a provider here, we handle
-		 * the special case of having multiple mail identities
-		 * eg. a dummy account having just SMTP server defined */
-		goto handle_transport;
-	}
-
-	service = camel_session_add_service (
-		CAMEL_SESSION (session),
-		account->uid, provider->protocol,
-		CAMEL_PROVIDER_STORE, &error);
+	service = mail_store_add_service_from_source (session, type, source);
 
-	if (!CAMEL_IS_STORE (service))
-		goto fail;
+	if (!CAMEL_IS_SERVICE (service))
+		return NULL;
 
-	camel_service_set_display_name (service, account->name);
+	url = camel_service_new_camel_url (service);
+	provider = camel_service_get_provider (service);
+	g_warn_if_fail (provider != NULL);
 
 	service_belongs_in_tree_model =
+		(type == CAMEL_PROVIDER_STORE) &&
 		(provider->flags & CAMEL_PROVIDER_IS_STORAGE) &&
-		!service_is_local_delivery;
+		em_utils_is_local_delivery_mbox_file (url);
 
 	if (service_belongs_in_tree_model && store_table != NULL)
 		e_mail_store_add (session, CAMEL_STORE (service));
 
-handle_transport:
-
-	/* While we're at it, add the account's transport (if it has one)
-	 * to the CamelSession.  The transport's UID is a kludge for now.
-	 * We take the EAccount's UID and tack on "-transport". */
-
-	if (account->transport) {
-		GError *transport_error = NULL;
-
-		url = camel_url_new (
-			account->transport->url,
-			&transport_error);
-
-		if (url != NULL) {
-			provider = camel_provider_get (
-				url->protocol, &transport_error);
-			camel_url_free (url);
-		} else
-			provider = NULL;
-
-		if (provider != NULL) {
-			gchar *transport_uid;
-
-			transport_uid = g_strconcat (
-				account->uid, "-transport", NULL);
+	camel_url_free (url);
 
-			camel_session_add_service (
-				CAMEL_SESSION (session),
-				transport_uid, provider->protocol,
-				CAMEL_PROVIDER_TRANSPORT, &transport_error);
-
-			g_free (transport_uid);
-		}
-
-		if (transport_error) {
-			g_warning (
-				"%s: Failed to add transport service: %s",
-				G_STRFUNC, transport_error->message);
-			g_error_free (transport_error);
-		}
-	}
-
-	if (transport_only)
-		return NULL;
-
-	return CAMEL_STORE (service);
-
-fail:
-	/* FIXME: Show an error dialog. */
-	g_warning (
-		"Couldn't get service: %s: %s", account->name,
-		error ? error->message : "Not a CamelStore");
-	if (error)
-		g_error_free (error);
-
-	return NULL;
+	return service;
 }
 
 void
@@ -450,29 +423,33 @@ e_mail_store_remove (EMailSession *session,
 	g_object_unref (store);
 }
 
-void
-e_mail_store_remove_by_account (EMailSession *session,
-                                EAccount *account)
+gboolean
+e_mail_store_remove_by_source (EMailSession *session,
+                               ESource *source)
 {
 	CamelService *service;
 	CamelProvider *provider;
 	const gchar *uid;
 
-	g_return_if_fail (E_IS_MAIL_SESSION (session));
-	g_return_if_fail (E_IS_ACCOUNT (account));
+	g_return_val_if_fail (E_IS_MAIL_SESSION (session), FALSE);
+	g_return_val_if_fail (E_IS_SOURCE (source), FALSE);
 
-	uid = account->uid;
+	uid = e_source_get_uid (source);
 
 	service = camel_session_get_service (CAMEL_SESSION (session), uid);
-	g_return_if_fail (CAMEL_IS_STORE (service));
+
+	if (service == NULL)
+		return FALSE;
 
 	provider = camel_service_get_provider (service);
-	g_return_if_fail (provider != NULL);
+	g_return_val_if_fail (provider != NULL, FALSE);
 
-	if (!(provider->flags & CAMEL_PROVIDER_IS_STORAGE) || store_table == NULL)
-		return;
+	if (store_table != NULL)
+		e_mail_store_remove (session, CAMEL_STORE (service));
+
+	camel_session_remove_service (CAMEL_SESSION (session), uid);
 
-	e_mail_store_remove (session, CAMEL_STORE (service));
+	return TRUE;
 }
 
 void
diff --git a/mail/e-mail-store.h b/mail/e-mail-store.h
index 5dca416..130a01a 100644
--- a/mail/e-mail-store.h
+++ b/mail/e-mail-store.h
@@ -24,7 +24,7 @@
 
 #include <camel/camel.h>
 #include <mail/e-mail-session.h>
-#include <libedataserver/e-account.h>
+#include <libedataserver/e-source.h>
 
 G_BEGIN_DECLS
 
@@ -32,12 +32,13 @@ void		e_mail_store_init		(EMailSession *session,
 						 const gchar *data_dir);
 void		e_mail_store_add		(EMailSession *session,
 						 CamelStore *store);
-CamelStore *	e_mail_store_add_by_account	(EMailSession *session,
-						 EAccount *account);
+CamelService *	e_mail_store_add_by_source	(EMailSession *session,
+						 CamelProviderType type,
+						 ESource *source);
 void		e_mail_store_remove		(EMailSession *session,
 						 CamelStore *store);
-void		e_mail_store_remove_by_account	(EMailSession *session,
-						 EAccount *account);
+gboolean	e_mail_store_remove_by_source	(EMailSession *session,
+						 ESource *source);
 void		e_mail_store_foreach		(EMailSession *session,
 						 GFunc func,
 						 gpointer user_data);
diff --git a/mail/e-mail.h b/mail/e-mail.h
index 7c40b20..074ba1d 100644
--- a/mail/e-mail.h
+++ b/mail/e-mail.h
@@ -20,6 +20,7 @@
 #define E_MAIL_H
 
 #include <mail/e-mail-attachment-bar.h>
+#include <mail/e-mail-authenticator.h>
 #include <mail/e-mail-backend.h>
 #include <mail/e-mail-browser.h>
 #include <mail/e-mail-display.h>
diff --git a/mail/e-source-camel.c b/mail/e-source-camel.c
new file mode 100644
index 0000000..09d3f6b
--- /dev/null
+++ b/mail/e-source-camel.c
@@ -0,0 +1,565 @@
+/*
+ * e-source-camel-provider.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/>
+ *
+ */
+
+/**
+ * SECTION: e-source-camel-provider
+ * @include: mail/e-source-camel-provider.h
+ * @short_description: #ESource extension for #CamelSettings
+ *
+ * #ESourceCamel itself is abstract.  Its sole function is to
+ * bridge #GObject properties from the #CamelSettings framework to the
+ * #ESource framework.  It does this by procedurally registering an
+ * #ESourceCamel subtype for each available #CamelService subtype,
+ * and then registering #GObject properties to proxy the properties in the
+ * corresponding #CamelSettings subtype.  The #ESourceCamel owns an
+ * instance of the appropriate #CamelSettings subtype, and redirects all
+ * get/set operations on its own #GObject properties to its #CamelSettings
+ * instance.  The #CamelSettings instance, now fully initialized from a key
+ * file, can then be inserted into a new #CamelService instance using
+ * camel_service_set_settings().
+ *
+ * Ultimately, this is all just implementation detail for glueing two
+ * unrelated class hierarchies together.  If you need to access provider
+ * specific settings, use the #CamelSettings API, not this.
+ **/
+
+/* XXX This class MIGHT make sense in libedataserver with the other
+ *     ESourceExtensions were it not for the fact that Camel links
+ *     to libedataserver, so we'd have a circular dependency. */
+
+#include "e-source-camel.h"
+
+#include <string.h>
+#include <glib/gprintf.h>
+
+#include <e-util/e-util.h>
+#include <libedataserver/e-source-authentication.h>
+#include <libedataserver/e-source-offline.h>
+#include <libedataserver/e-source-security.h>
+
+#define E_SOURCE_CAMEL_GET_PRIVATE(obj) \
+	(G_TYPE_INSTANCE_GET_PRIVATE \
+	((obj), E_TYPE_SOURCE_CAMEL, ESourceCamelPrivate))
+
+struct _ESourceCamelPrivate {
+	CamelSettings *settings;
+	GArray *value_array;
+};
+
+enum {
+	PROP_0,
+	PROP_SETTINGS
+};
+
+typedef struct {
+	const gchar *extension_name;
+	const gchar *extension_property_name;
+	const gchar *settings_property_name;
+	GBindingTransformFunc extension_to_settings;
+	GBindingTransformFunc settings_to_extension;
+} BindingData;
+
+static gboolean
+transform_none_to_null (GBinding *binding,
+                        const GValue *source_value,
+                        GValue *target_value,
+                        gpointer not_used)
+{
+	const gchar *v_string;
+
+	/* XXX Camel doesn't understand ESource's convention of using
+	 *     "none" to represent no value, instead of NULL or empty
+	 *     strings.  So convert "none" to NULL for Camel. */
+
+	v_string = g_value_get_string (source_value);
+
+	if (g_strcmp0 (v_string, "none") == 0)
+		v_string = NULL;
+
+	g_value_set_string (target_value, v_string);
+
+	return TRUE;
+}
+
+static BindingData bindings[] = {
+
+	{ E_SOURCE_EXTENSION_AUTHENTICATION,
+	  "host", "host" },
+
+	{ E_SOURCE_EXTENSION_AUTHENTICATION,
+	  "method", "auth-mechanism",
+	  transform_none_to_null,
+	  NULL },
+
+	{ E_SOURCE_EXTENSION_AUTHENTICATION,
+	  "port", "port" },
+
+	{ E_SOURCE_EXTENSION_AUTHENTICATION,
+	  "user", "user" },
+
+	{ E_SOURCE_EXTENSION_OFFLINE,
+	  "stay-synchronized", "stay-synchronized" },
+
+	{ E_SOURCE_EXTENSION_SECURITY,
+	  "method", "security-method",
+	  e_binding_transform_enum_nick_to_value,
+	  e_binding_transform_enum_value_to_nick }
+};
+
+G_DEFINE_ABSTRACT_TYPE (
+	ESourceCamel,
+	e_source_camel,
+	E_TYPE_SOURCE_EXTENSION)
+
+static gint
+subclass_get_binding_index (GParamSpec *settings_property)
+{
+	gint ii;
+
+	/* Return the index in the bindings list for the given
+	 * CamelSettings property specification, or else -1. */
+
+	for (ii = 0; ii < G_N_ELEMENTS (bindings); ii++) {
+		const gchar *property_name;
+
+		property_name = bindings[ii].settings_property_name;
+		if (g_strcmp0 (settings_property->name, property_name) == 0)
+			return ii;
+	}
+
+	return -1;
+}
+
+static void
+subclass_set_property (GObject *object,
+                       guint property_id,
+                       const GValue *src_value,
+                       GParamSpec *pspec)
+{
+	ESourceCamel *extension;
+	GArray *value_array;
+	GValue *dst_value;
+
+	extension = E_SOURCE_CAMEL (object);
+	value_array = extension->priv->value_array;
+
+	dst_value = &g_array_index (value_array, GValue, property_id - 1);
+	g_value_copy (src_value, dst_value);
+}
+
+static void
+subclass_get_property (GObject *object,
+                       guint property_id,
+                       GValue *dst_value,
+                       GParamSpec *pspec)
+{
+	ESourceCamel *extension;
+	GArray *value_array;
+	GValue *src_value;
+
+	extension = E_SOURCE_CAMEL (object);
+	value_array = extension->priv->value_array;
+
+	src_value = &g_array_index (value_array, GValue, property_id - 1);
+	g_value_copy (src_value, dst_value);
+}
+
+static void
+subclass_init (GObjectClass *object_class)
+{
+	/* source_camel_register_subtype() does all the
+	 * dynamic class initialization.  We just do what static
+	 * initialization we can here. */
+
+	object_class->set_property = subclass_set_property;
+	object_class->get_property = subclass_get_property;
+}
+
+static void
+source_camel_register_subtype (GType service_type,
+                               const gchar *type_name,
+                               const gchar *extension_name)
+{
+	ESourceCamelClass *class;
+	CamelServiceClass *service_class;
+	GObjectClass *settings_class;
+	GParamSpec **properties;
+	guint ii, n_properties;
+	guint prop_id = 1;
+	GTypeInfo type_info;
+	GType parent_type;
+	GType type;
+
+	/* Check if the type name is already registered. */
+	if (g_type_from_name (type_name) != G_TYPE_INVALID)
+		return;
+
+	memset (&type_info, 0, sizeof (GTypeInfo));
+	type_info.class_size = sizeof (ESourceCamelClass);
+	type_info.class_init = (GClassInitFunc) subclass_init;
+	type_info.instance_size = sizeof (ESourceCamel);
+
+	parent_type = E_TYPE_SOURCE_CAMEL;
+	type = g_type_register_static (parent_type, type_name, &type_info, 0);
+
+	/* Since we have first access to the newly registered GType, and
+	 * because initializing its class structure requires some of the
+	 * arguments we were passed, we'll complete class initialization
+	 * here rather than trying to do it all in subclass_init(). */
+
+	class = g_type_class_ref (type);
+	service_class = g_type_class_ref (service_type);
+	settings_class = g_type_class_ref (service_class->settings_type);
+
+	/* Initialize more class members. */
+	class->settings_type = G_OBJECT_CLASS_TYPE (settings_class);
+	class->parent_class.name = g_intern_string (extension_name);
+
+	/* For each property in the CamelSettings class, register
+	 * an equivalent GObject property in this class and add an
+	 * E_SOURCE_PARAM_SETTING flag so the value gets written to
+	 * the ESource's key file. */
+
+	properties = g_object_class_list_properties (
+		settings_class, &n_properties);
+
+	for (ii = 0; ii < n_properties; ii++) {
+		GParamSpec *pspec;
+		const gchar *name;
+
+		/* Some properties in CamelSettings may be covered
+		 * by other ESourceExtensions.  Skip them here. */
+		if (subclass_get_binding_index (properties[ii]) >= 0)
+			continue;
+
+		name = properties[ii]->name;
+		pspec = g_param_spec_override (name, properties[ii]);
+		pspec->flags |= E_SOURCE_PARAM_SETTING;
+
+		/* Clear the G_PARAM_CONSTRUCT flag.  We apply default
+		 * property values to our GValue array during instance
+		 * initialization. */
+		pspec->flags &= ~G_PARAM_CONSTRUCT;
+
+		g_object_class_install_property (
+			G_OBJECT_CLASS (class), prop_id++, pspec);
+	}
+
+	g_free (properties);
+
+	g_type_class_unref (class);
+	g_type_class_unref (service_class);
+	g_type_class_unref (settings_class);
+}
+
+static void
+source_camel_get_property (GObject *object,
+                           guint property_id,
+                           GValue *value,
+                           GParamSpec *pspec)
+{
+	switch (property_id) {
+		case PROP_SETTINGS:
+			g_value_set_object (
+				value,
+				e_source_camel_get_settings (
+				E_SOURCE_CAMEL (object)));
+			return;
+	}
+
+	G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+source_camel_dispose (GObject *object)
+{
+	ESourceCamelPrivate *priv;
+
+	priv = E_SOURCE_CAMEL_GET_PRIVATE (object);
+
+	if (priv->settings != NULL) {
+		g_object_unref (priv->settings);
+		priv->settings = NULL;
+	}
+
+	/* Chain up to parent's dispose() method. */
+	G_OBJECT_CLASS (e_source_camel_parent_class)->dispose (object);
+}
+
+static void
+source_camel_finalize (GObject *object)
+{
+	ESourceCamelPrivate *priv;
+	guint ii;
+
+	priv = E_SOURCE_CAMEL_GET_PRIVATE (object);
+
+	for (ii = 0; ii < priv->value_array->len; ii++)
+		g_value_unset (&g_array_index (priv->value_array, GValue, ii));
+
+	g_array_free (priv->value_array, TRUE);
+
+	/* Chain up to parent's finalize() method. */
+	G_OBJECT_CLASS (e_source_camel_parent_class)->finalize (object);
+}
+
+static void
+source_camel_constructed (GObject *object)
+{
+	ESource *source;
+	ESourceCamelClass *class;
+	ESourceCamelPrivate *priv;
+	GObjectClass *settings_class;
+	GParamSpec **properties;
+	guint ii, n_properties;
+	guint array_index = 0;
+
+	/* Chain up to parent's constructed() method. */
+	G_OBJECT_CLASS (e_source_camel_parent_class)->
+		constructed (object);
+
+	class = E_SOURCE_CAMEL_GET_CLASS (object);
+	priv = E_SOURCE_CAMEL_GET_PRIVATE (object);
+
+	source = e_source_extension_get_source (E_SOURCE_EXTENSION (object));
+
+	priv->settings = g_object_new (class->settings_type, NULL);
+
+	/* Here we bind all the GObject properties in the newly-created
+	 * CamelSettings instance to either our own identical properties
+	 * or properties in another ESourceExtensions.  The bindings list
+	 * at the top of the file maps out bindings to other extensions. */
+
+	settings_class = G_OBJECT_GET_CLASS (priv->settings);
+
+	properties = g_object_class_list_properties (
+		settings_class, &n_properties);
+
+	/* Allocate more elements than we need, since some CamelSettings
+	 * properties get bound to properties of other ESourceExtensions.
+	 * We'll trim off the extra elements later. */
+	g_array_set_size (priv->value_array, n_properties);
+
+	for (ii = 0; ii < n_properties; ii++) {
+		GParamSpec *pspec = properties[ii];
+		GBindingTransformFunc transform_to = NULL;
+		GBindingTransformFunc transform_from = NULL;
+		ESourceExtension *extension;
+		const gchar *source_property;
+		const gchar *target_property;
+		gint binding_index;
+
+		binding_index = subclass_get_binding_index (pspec);
+
+		/* Bind the CamelSettings property to
+		 * one in a different ESourceExtension. */
+		if (binding_index >= 0) {
+			BindingData *binding;
+
+			binding = &bindings[binding_index];
+
+			extension = e_source_get_extension (
+				source, binding->extension_name);
+
+			source_property = binding->extension_property_name;
+			target_property = binding->settings_property_name;
+
+			transform_to = binding->extension_to_settings;
+			transform_from = binding->settings_to_extension;
+
+		/* Bind the CamelSettings property to our own
+		 * equivalent E_SOURCE_PARAM_SETTING property. */
+		} else {
+			GValue *value;
+
+			extension = E_SOURCE_EXTENSION (object);
+
+			source_property = pspec->name;
+			target_property = pspec->name;
+
+			/* Initialize the array element to
+			 * hold the GParamSpec's value type. */
+			value = &g_array_index (
+				priv->value_array, GValue, array_index++);
+			g_value_init (value, G_PARAM_SPEC_VALUE_TYPE (pspec));
+
+			/* Set the array element to the GParamSpec's default
+			 * value.  This allows us to avoid declaring our own
+			 * properties with a G_PARAM_CONSTRUCT flag. */
+			g_param_value_set_default (pspec, value);
+		}
+
+		g_object_bind_property_full (
+			extension, source_property,
+			priv->settings, target_property,
+			G_BINDING_BIDIRECTIONAL |
+			G_BINDING_SYNC_CREATE,
+			transform_to, transform_from,
+			NULL, (GDestroyNotify) NULL);
+	}
+
+	/* Trim off any extra array elements. */
+	g_array_set_size (priv->value_array, array_index);
+
+	g_free (properties);
+}
+
+static void
+e_source_camel_class_init (ESourceCamelClass *class)
+{
+	GObjectClass *object_class;
+
+	g_type_class_add_private (class, sizeof (ESourceCamelPrivate));
+
+	object_class = G_OBJECT_CLASS (class);
+	object_class->get_property = source_camel_get_property;
+	object_class->dispose = source_camel_dispose;
+	object_class->finalize = source_camel_finalize;
+	object_class->constructed = source_camel_constructed;
+
+	/* CamelSettings itself has no properties. */
+	class->settings_type = CAMEL_TYPE_SETTINGS;
+
+	/* XXX This kind of stomps on CamelSettings' namespace, but it's
+	 *     unlikely a CamelSettings subclass would define a property
+	 *     named "settings". */
+	g_object_class_install_property (
+		object_class,
+		PROP_SETTINGS,
+		g_param_spec_object (
+			"settings",
+			"Settings",
+			"The CamelSettings instance being proxied",
+			CAMEL_TYPE_SETTINGS,
+			G_PARAM_READABLE |
+			G_PARAM_STATIC_STRINGS));
+}
+
+static void
+e_source_camel_init (ESourceCamel *extension)
+{
+	GArray *value_array;
+
+	/* Zero-fill array elements when they are allocated. */
+	value_array = g_array_new (FALSE, TRUE, sizeof (GValue));
+
+	extension->priv = E_SOURCE_CAMEL_GET_PRIVATE (extension);
+	extension->priv->value_array = value_array;
+}
+
+void
+e_source_camel_register_types (void)
+{
+	GList *list, *link;
+
+	/* This implicitly takes care of provider initialization. */
+	list = camel_provider_list (TRUE);
+
+	for (link = list; link != NULL; link = g_list_next (link)) {
+		CamelProvider *provider;
+		const gchar *extension_name;
+		const gchar *type_name;
+		gint ii;
+
+		provider = (CamelProvider *) link->data;
+
+		type_name =
+			e_source_camel_get_type_name (provider->protocol);
+		extension_name =
+			e_source_camel_get_extension_name (provider->protocol);
+
+		/* This is the novel part: fabricate and register
+		 * a new ESourceCamel subclass on-the-fly
+		 * for each object type listed in the provider. */
+		for (ii = 0; ii < CAMEL_NUM_PROVIDER_TYPES; ii++) {
+			GType service_type;
+
+			service_type = provider->object_types[ii];
+
+			if (service_type == G_TYPE_INVALID)
+				continue;
+
+			source_camel_register_subtype (
+				service_type, type_name, extension_name);
+		}
+	}
+
+	g_list_free (list);
+}
+
+CamelSettings *
+e_source_camel_get_settings (ESourceCamel *extension)
+{
+	g_return_val_if_fail (E_IS_SOURCE_CAMEL (extension), NULL);
+
+	return extension->priv->settings;
+}
+
+const gchar *
+e_source_camel_get_type_name (const gchar *protocol)
+{
+	gchar *buffer;
+
+	g_return_val_if_fail (protocol != NULL, NULL);
+
+	buffer = g_alloca (strlen (protocol) + 16);
+	g_sprintf (buffer, "ESourceCamel%s", protocol);
+	buffer[12] = g_ascii_toupper (buffer[12]);
+
+	return g_intern_string (buffer);
+}
+
+const gchar *
+e_source_camel_get_extension_name (const gchar *protocol)
+{
+	gchar *buffer;
+
+	g_return_val_if_fail (protocol != NULL, NULL);
+
+	/* Use the term "backend" for consistency with other
+	 * calendar and address book backend extension names. */
+	buffer = g_alloca (strlen (protocol) + 16);
+	g_sprintf (buffer, "%s Backend", protocol);
+	buffer[0] = g_ascii_toupper (buffer[0]);
+
+	return g_intern_string (buffer);
+}
+
+void
+e_source_camel_configure_service (ESource *source,
+                                  CamelService *service)
+{
+	ESourceCamel *extension;
+	CamelProvider *provider;
+	CamelSettings *settings;
+	const gchar *extension_name;
+
+	g_return_if_fail (E_IS_SOURCE (source));
+	g_return_if_fail (CAMEL_IS_SERVICE (service));
+
+	provider = camel_service_get_provider (service);
+	g_return_if_fail (provider != NULL);
+
+	extension_name =
+		e_source_camel_get_extension_name (provider->protocol);
+	extension = e_source_get_extension (source, extension_name);
+
+	settings = e_source_camel_get_settings (extension);
+	camel_service_set_settings (service, settings);
+}
+
diff --git a/mail/e-source-camel.h b/mail/e-source-camel.h
new file mode 100644
index 0000000..f6fd3bc
--- /dev/null
+++ b/mail/e-source-camel.h
@@ -0,0 +1,83 @@
+/*
+ * e-source-camel.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_CAMEL_H
+#define E_SOURCE_CAMEL_H
+
+#include <camel/camel.h>
+#include <libedataserver/e-source-extension.h>
+
+/* Standard GObject macros */
+#define E_TYPE_SOURCE_CAMEL \
+	(e_source_camel_get_type ())
+#define E_SOURCE_CAMEL(obj) \
+	(G_TYPE_CHECK_INSTANCE_CAST \
+	((obj), E_TYPE_SOURCE_CAMEL, ESourceCamel))
+#define E_SOURCE_CAMEL_CLASS(cls) \
+	(G_TYPE_CHECK_CLASS_CAST \
+	((cls), E_TYPE_SOURCE_CAMEL, ESourceCamelClass))
+#define E_IS_SOURCE_CAMEL(obj) \
+	(G_TYPE_CHECK_INSTANCE_TYPE \
+	((obj), E_TYPE_SOURCE_CAMEL))
+#define E_IS_SOURCE_CAMEL_CLASS(cls) \
+	(G_TYPE_CHECK_CLASS_TYPE \
+	((cls), E_TYPE_SOURCE_CAMEL))
+#define E_SOURCE_CAMEL_GET_CLASS(obj) \
+	(G_TYPE_INSTANCE_GET_CLASS \
+	((obj), E_TYPE_SOURCE_CAMEL, ESourceCamelClass))
+
+G_BEGIN_DECLS
+
+typedef struct _ESourceCamel ESourceCamel;
+typedef struct _ESourceCamelClass ESourceCamelClass;
+typedef struct _ESourceCamelPrivate ESourceCamelPrivate;
+
+/**
+ * ESourceCamel:
+ *
+ * Contains only private data that should be read and manipulated using the
+ * functions below.
+ *
+ * Since: 3.4
+ **/
+struct _ESourceCamel {
+	ESourceExtension parent;
+	ESourceCamelPrivate *priv;
+};
+
+struct _ESourceCamelClass {
+	ESourceExtensionClass parent_class;
+
+	/* Same idea as in CamelServiceClass. */
+	GType settings_type;
+};
+
+GType		e_source_camel_get_type		(void);
+void		e_source_camel_register_types	(void);
+CamelSettings *
+		e_source_camel_get_settings	(ESourceCamel *extension);
+const gchar *	e_source_camel_get_type_name	(const gchar *protocol);
+const gchar *	e_source_camel_get_extension_name
+						(const gchar *protocol);
+void		e_source_camel_configure_service
+						(ESource *source,
+						 CamelService *service);
+
+G_END_DECLS
+
+#endif /* E_SOURCE_CAMEL_H */
diff --git a/mail/em-account-editor.c b/mail/em-account-editor.c
index 0d930a1..beb30a4 100644
--- a/mail/em-account-editor.c
+++ b/mail/em-account-editor.c
@@ -49,13 +49,10 @@
 #include "shell/e-shell.h"
 #include "e-util/e-util.h"
 #include "e-util/e-alert-dialog.h"
-#include "e-util/e-account-utils.h"
 #include "e-util/e-dialog-utils.h"
-#include "e-util/e-signature-list.h"
-#include "e-util/e-signature-utils.h"
 #include "e-util/e-util-private.h"
 #include "widgets/misc/e-auth-combo-box.h"
-#include "widgets/misc/e-signature-editor.h"
+#include "widgets/misc/e-mail-signature-editor.h"
 #include "widgets/misc/e-port-entry.h"
 
 #include "e-mail-backend.h"
@@ -159,8 +156,10 @@ typedef struct _EMAccountEditorService {
 struct _EMAccountEditorPrivate {
 
 	EMailBackend *backend;
+#if 0  /* ACCOUNT_MGMT */
 	EAccount *modified_account;
 	EAccount *original_account;
+#endif /* ACCOUNT_MGMT */
 	gboolean new_account;
 
 	struct _EMConfig *config;
@@ -264,6 +263,7 @@ emae_config_target_changed_cb (EMAccountEditor *emae)
 		E_CONFIG_TARGET_CHANGED_STATE);
 }
 
+#if 0  /* ACCOUNT_MGMT */
 static void
 emae_set_original_account (EMAccountEditor *emae,
                            EAccount *original_account)
@@ -310,6 +310,7 @@ emae_set_original_account (EMAccountEditor *emae,
 		emae->priv->modified_account, "changed",
 		G_CALLBACK (emae_config_target_changed_cb), emae);
 }
+#endif /* ACCOUNT_MGMT */
 
 static void
 emae_set_backend (EMAccountEditor *emae,
@@ -592,6 +593,7 @@ emae_set_property (GObject *object,
 				g_value_get_object (value));
 			return;
 
+#if 0  /* ACCOUNT_MGMT */
 		case PROP_ORIGINAL_ACCOUNT:
 			emae_set_original_account (
 				EM_ACCOUNT_EDITOR (object),
@@ -681,6 +683,7 @@ emae_set_property (GObject *object,
 				EM_ACCOUNT_EDITOR (object),
 				g_value_get_boolean (value));
 			return;
+#endif /* ACCOUNT_MGMT */
 	}
 
 	G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
@@ -700,6 +703,7 @@ emae_get_property (GObject *object,
 				EM_ACCOUNT_EDITOR (object)));
 			return;
 
+#if 0  /* ACCOUNT_MGMT */
 		case PROP_MODIFIED_ACCOUNT:
 			g_value_set_object (
 				value,
@@ -825,6 +829,7 @@ emae_get_property (GObject *object,
 				emae_get_transport_visible_user (
 				EM_ACCOUNT_EDITOR (object)));
 			return;
+#endif /* ACCOUNT_MGMT */
 	}
 
 	G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
@@ -842,6 +847,7 @@ emae_dispose (GObject *object)
 		priv->backend = NULL;
 	}
 
+#if 0  /* ACCOUNT_MGMT */
 	if (priv->modified_account != NULL) {
 		g_signal_handlers_disconnect_by_func (
 			priv->modified_account,
@@ -854,6 +860,7 @@ emae_dispose (GObject *object)
 		g_object_unref (priv->original_account);
 		priv->original_account = NULL;
 	}
+#endif /* ACCOUNT_MGMT */
 
 	if (priv->source.settings != NULL) {
 		g_signal_handlers_disconnect_by_func (
@@ -881,6 +888,7 @@ emae_finalize (GObject *object)
 	EMAccountEditor *emae = EM_ACCOUNT_EDITOR (object);
 	EMAccountEditorPrivate *priv = emae->priv;
 
+#if 0 /* ACCOUNT_MGMT */
 	if (priv->sig_added_id) {
 		ESignatureList *signatures;
 
@@ -889,6 +897,7 @@ emae_finalize (GObject *object)
 		g_signal_handler_disconnect (signatures, priv->sig_removed_id);
 		g_signal_handler_disconnect (signatures, priv->sig_changed_id);
 	}
+#endif /* ACCOUNT_MGMT */
 
 	g_list_free (priv->providers);
 
@@ -922,6 +931,7 @@ emae_class_init (GObjectClass *class)
 			G_PARAM_CONSTRUCT_ONLY |
 			G_PARAM_STATIC_STRINGS));
 
+#if 0  /* ACCOUNT_MGMT */
 	g_object_class_install_property (
 		object_class,
 		PROP_MODIFIED_ACCOUNT,
@@ -1130,6 +1140,8 @@ emae_class_init (GObjectClass *class)
 			G_PARAM_READWRITE |
 			G_PARAM_CONSTRUCT |
 			G_PARAM_STATIC_STRINGS));
+			G_PARAM_CONSTRUCT_ONLY));
+#endif /* ACCOUNT_MGMT */
 }
 
 static void
@@ -1175,6 +1187,7 @@ em_account_editor_get_type (void)
 	return type;
 }
 
+#if 0  /* ACCOUNT_MGMT */
 /**
  * em_account_editor_new:
  * @account:
@@ -1238,6 +1251,7 @@ em_account_editor_new_for_pages (EAccount *account,
 
 	return emae;
 }
+#endif /* ACCOUNT_MGMT */
 
 EMailBackend *
 em_account_editor_get_backend (EMAccountEditor *emae)
@@ -1247,6 +1261,7 @@ em_account_editor_get_backend (EMAccountEditor *emae)
 	return emae->priv->backend;
 }
 
+#if 0  /* ACCOUNT_MGMT */
 EAccount *
 em_account_editor_get_modified_account (EMAccountEditor *emae)
 {
@@ -1262,6 +1277,7 @@ em_account_editor_get_original_account (EMAccountEditor *emae)
 
 	return emae->priv->original_account;
 }
+#endif /* ACCOUNT_MGMT */
 
 /* ********************************************************************** */
 
@@ -1284,6 +1300,7 @@ static CamelURL *
 emae_account_url (EMAccountEditor *emae,
                   gint urlid)
 {
+#if 0  /* ACCOUNT_MGMT */
 	EAccount *account;
 	CamelURL *url = NULL;
 	const gchar *uri;
@@ -1300,6 +1317,9 @@ emae_account_url (EMAccountEditor *emae,
 	}
 
 	return url;
+#endif /* ACCOUNT_MGMT */
+
+	return NULL;
 }
 
 /* ********************************************************************** */
@@ -1308,6 +1328,7 @@ static void
 default_folders_clicked (GtkButton *button,
                          gpointer user_data)
 {
+#if 0  /* ACCOUNT_MGMT */
 	EMAccountEditor *emae = user_data;
 	const gchar *uri;
 
@@ -1321,6 +1342,7 @@ default_folders_clicked (GtkButton *button,
 
 	gtk_toggle_button_set_active (emae->priv->trash_folder_check, FALSE);
 	gtk_toggle_button_set_active (emae->priv->junk_folder_check, FALSE);
+#endif /* ACCOUNT_MGMT */
 }
 
 /* The camel provider auto-detect interface should be deprecated.
@@ -1338,6 +1360,7 @@ emae_auto_detect_free (gpointer key,
 static void
 emae_auto_detect (EMAccountEditor *emae)
 {
+#if 0  /* ACCOUNT_MGMT */
 	EMAccountEditorPrivate *priv = emae->priv;
 	EMAccountEditorService *service = &priv->source;
 	CamelProvider *provider;
@@ -1389,6 +1412,7 @@ emae_auto_detect (EMAccountEditor *emae)
 
 	g_hash_table_foreach (auto_detected, emae_auto_detect_free, NULL);
 	g_hash_table_destroy (auto_detected);
+#endif /* ACCOUNT_MGMT */
 }
 
 static gint
@@ -1407,6 +1431,7 @@ provider_compare (const CamelProvider *p1,
 	}
 }
 
+#if 0  /* ACCOUNT_MGMT */
 static void
 emae_signature_added (ESignatureList *signatures,
                       ESignature *sig,
@@ -1594,11 +1619,13 @@ emae_setup_signatures (EMAccountEditor *emae,
 
 	return (GtkWidget *) dropdown;
 }
+#endif /* ACCOUNT_MGMT */
 
 static void
 emae_receipt_policy_changed (GtkComboBox *dropdown,
                              EMAccountEditor *emae)
 {
+#if 0  /* ACCOUNT_MGMT */
 	EAccount *account;
 	gint id = gtk_combo_box_get_active (dropdown);
 	GtkTreeModel *model;
@@ -1614,12 +1641,14 @@ emae_receipt_policy_changed (GtkComboBox *dropdown,
 			e_account_set_int (account, E_ACCOUNT_RECEIPT_POLICY, policy);
 		}
 	}
+#endif /* ACCOUNT_MGMT */
 }
 
 static GtkWidget *
 emae_setup_receipt_policy (EMAccountEditor *emae,
                            GtkBuilder *builder)
 {
+#if 0  /* ACCOUNT_MGMT */
 	EAccount *account;
 	GtkComboBox *dropdown = (GtkComboBox *)e_builder_get_widget (builder, "receipt_policy_dropdown");
 	GtkListStore *store;
@@ -1664,12 +1693,16 @@ emae_setup_receipt_policy (EMAccountEditor *emae,
 	g_signal_connect (dropdown, "changed", G_CALLBACK(emae_receipt_policy_changed), emae);
 
 	return (GtkWidget *) dropdown;
+#endif /* ACCOUNT_MGMT */
+
+	return NULL;
 }
 
 static void
 emae_account_entry_changed (GtkEntry *entry,
                             EMAccountEditor *emae)
 {
+#if 0  /* ACCOUNT_MGMT */
 	EAccount *account;
 	gchar *text;
 	gpointer data;
@@ -1683,6 +1716,7 @@ emae_account_entry_changed (GtkEntry *entry,
 	e_account_set_string (account, GPOINTER_TO_INT (data), text);
 
 	g_free (text);
+#endif /* ACCOUNT_MGMT */
 }
 
 static GtkEntry *
@@ -1691,6 +1725,7 @@ emae_account_entry (EMAccountEditor *emae,
                     gint item,
                     GtkBuilder *builder)
 {
+#if 0  /* ACCOUNT_MGMT */
 	EAccount *account;
 	GtkEntry *entry;
 	const gchar *text;
@@ -1704,12 +1739,16 @@ emae_account_entry (EMAccountEditor *emae,
 	g_signal_connect (entry, "changed", G_CALLBACK(emae_account_entry_changed), emae);
 
 	return entry;
+#endif /* ACCOUNT_MGMT */
+
+	return NULL;
 }
 
 static void
 emae_account_toggle_changed (GtkToggleButton *toggle,
                              EMAccountEditor *emae)
 {
+#if 0  /* ACCOUNT_MGMT */
 	EAccount *account;
 	gboolean active;
 	gpointer data;
@@ -1719,6 +1758,7 @@ emae_account_toggle_changed (GtkToggleButton *toggle,
 	active = gtk_toggle_button_get_active (toggle);
 
 	e_account_set_bool (account, GPOINTER_TO_INT (data), active);
+#endif /* ACCOUNT_MGMT */
 }
 
 static void
@@ -1726,6 +1766,7 @@ emae_account_toggle_widget (EMAccountEditor *emae,
                             GtkToggleButton *toggle,
                             gint item)
 {
+#if 0  /* ACCOUNT_MGMT */
 	EAccount *account;
 	gboolean active;
 
@@ -1741,6 +1782,7 @@ emae_account_toggle_widget (EMAccountEditor *emae,
 	g_signal_connect (
 		toggle, "toggled",
 		G_CALLBACK (emae_account_toggle_changed), emae);
+#endif /* ACCOUNT_MGMT */
 }
 
 static GtkToggleButton *
@@ -1761,6 +1803,7 @@ static void
 emae_account_spinint_changed (GtkSpinButton *spin,
                               EMAccountEditor *emae)
 {
+#if 0  /* ACCOUNT_MGMT */
 	EAccount *account;
 	gpointer data;
 	gint value;
@@ -1770,6 +1813,7 @@ emae_account_spinint_changed (GtkSpinButton *spin,
 	value = gtk_spin_button_get_value (spin);
 
 	e_account_set_int (account, GPOINTER_TO_INT (data), value);
+#endif /* ACCOUNT_MGMT */
 }
 
 static void
@@ -1777,6 +1821,7 @@ emae_account_spinint_widget (EMAccountEditor *emae,
                              GtkSpinButton *spin,
                              gint item)
 {
+#if 0  /* ACCOUNT_MGMT */
 	EAccount *account;
 	gint v_int;
 
@@ -1792,8 +1837,10 @@ emae_account_spinint_widget (EMAccountEditor *emae,
 	g_signal_connect (
 		spin, "value-changed",
 		G_CALLBACK (emae_account_spinint_changed), emae);
+#endif /* ACCOUNT_MGMT */
 }
 
+#if 0
 static void
 emae_account_folder_changed (EMFolderSelectionButton *folder,
                              EMAccountEditor *emae)
@@ -1842,6 +1889,7 @@ emae_account_folder (EMAccountEditor *emae,
 
 	return folder;
 }
+#endif
 
 #if defined (HAVE_NSS) && defined (ENABLE_SMIME)
 static void
@@ -1947,6 +1995,13 @@ smime_encrypt_key_clear (GtkWidget *w,
 }
 #endif
 
+#if 1 /* ACCOUNT_MGMT - Remove this. */
+#define E_ACCOUNT_SOURCE_URL NULL
+#define E_ACCOUNT_SOURCE_SAVE_PASSWD NULL
+#define E_ACCOUNT_TRANSPORT_URL NULL
+#define E_ACCOUNT_TRANSPORT_SAVE_PASSWD NULL
+#endif
+
 /* This is used to map each of the two services in a typical account to
  * the widgets that represent each service.  i.e. the receiving (source)
  * service, and the sending (transport) service.  It is used throughout
@@ -2303,7 +2358,11 @@ emae_service_provider_changed (EMAccountEditorService *service)
 
 	em_config_target_update_settings (
 		config, target,
+#if 0  /* ACCOUNT_MGMT */
 		service->emae->priv->modified_account->id->address,
+#else
+		NULL,
+#endif /* ACCOUNT_MGMT */
 		service->emae->priv->source.protocol,
 		service->emae->priv->source.settings,
 		service->emae->priv->transport.protocol,
@@ -2481,6 +2540,7 @@ static void
 emae_check_authtype (GtkWidget *w,
                      EMAccountEditorService *service)
 {
+#if 0  /* ACCOUNT_MGMT */
 	CamelService *camel_service;
 	EMailBackend *backend;
 	EMailSession *session;
@@ -2547,6 +2607,7 @@ emae_check_authtype (GtkWidget *w,
 
 	if (editor != NULL)
 		gtk_widget_set_sensitive (editor, FALSE);
+#endif /* ACCOUNT_MGMT */
 }
 
 static void
@@ -2848,6 +2909,7 @@ emae_create_basic_assistant_page (EMAccountEditor *emae,
 }
 
 /* do not re-order these, the order is used by various code to look up emae->priv->identity_entries[] */
+#if 0  /* ACCOUNT_MGMT */
 static struct {
 	const gchar *name;
 	gint item;
@@ -2858,6 +2920,7 @@ static struct {
 	{ "identity_reply_to", E_ACCOUNT_ID_REPLY_TO },
 	{ "identity_organization", E_ACCOUNT_ID_ORGANIZATION },
 };
+#endif /* ACCOUNT_MGMT */
 
 static void
 emae_queue_widgets (EMAccountEditor *emae,
@@ -2883,6 +2946,7 @@ emae_identity_page (EConfig *ec,
                     gint position,
                     gpointer data)
 {
+#if 0  /* ACCOUNT_MGMT */
 	EMAccountEditor *emae = data;
 	EMAccountEditorPrivate *priv = emae->priv;
 	EAccount *account;
@@ -2962,6 +3026,9 @@ emae_identity_page (EConfig *ec,
 	g_object_unref (builder);
 
 	return w;
+#endif /* ACCOUNT_MGMT */
+
+	return NULL;
 }
 
 static GtkWidget *
@@ -3368,11 +3435,15 @@ emae_receive_options_item (EConfig *ec,
 
 	box = gtk_hbox_new (FALSE, 4);
 	w = gtk_check_button_new_with_mnemonic (_("Check for _new messages every"));
+#if 0  /* ACCOUNT_MGMT */
 	emae_account_toggle_widget (emae, (GtkToggleButton *) w, E_ACCOUNT_SOURCE_AUTO_CHECK);
+#endif /* ACCOUNT_MGMT */
 	gtk_box_pack_start ((GtkBox *) box, w, FALSE, FALSE, 0);
 
 	spin = gtk_spin_button_new_with_range (1.0, 1440.0, 1.0);
+#if 0  /* ACCOUNT_MGMT */
 	emae_account_spinint_widget (emae, (GtkSpinButton *) spin, E_ACCOUNT_SOURCE_AUTO_CHECK_TIME);
+#endif /* ACCOUNT_MGMT */
 	gtk_box_pack_start ((GtkBox *) box, spin, FALSE, TRUE, 0);
 
 	w = gtk_label_new_with_mnemonic (_("minu_tes"));
@@ -3394,6 +3465,7 @@ emae_receive_options_extra_item (EConfig *ec,
                                  gint position,
                                  gpointer data)
 {
+#if 0  /* ACCOUNT_MGMT */
 	EMAccountEditor *emae = data;
 	EMAccountEditorService *service;
 	struct _receive_options_item *item = (struct _receive_options_item *) eitem;
@@ -3562,6 +3634,9 @@ section:
 		gtk_widget_show (widget);
 
 	return widget;
+#endif /* ACCOUNT_MGMT */
+
+	return NULL;  /* ACCOUNT_MGMT */
 }
 
 static GtkWidget *
@@ -3640,6 +3715,7 @@ emae_real_url_toggled (GtkToggleButton *check,
 		em_folder_selection_button_set_folder_uri (button, "");
 }
 
+#if 0  /* ACCOUNT_MGMT */
 static void
 set_real_folder_path (GtkButton *folder_button,
                       CamelSettings *settings,
@@ -3721,6 +3797,7 @@ update_real_folder_cb (GtkButton *folder_button,
 	g_object_set (G_OBJECT (settings), prop_name, path, NULL);
 	g_free (path);
 }
+#endif /* ACCOUNT_MGMT */
 
 static GtkWidget *
 emae_defaults_page (EConfig *ec,
@@ -3730,6 +3807,7 @@ emae_defaults_page (EConfig *ec,
                     gint position,
                     gpointer data)
 {
+#if 0  /* ACCOUNT_MGMT */
 	EMAccountEditor *emae = data;
 	EMAccountEditorPrivate *priv = emae->priv;
 	EMFolderSelectionButton *button;
@@ -3922,12 +4000,16 @@ emae_defaults_page (EConfig *ec,
 	g_object_unref (builder);
 
 	return widget;
+#endif /* ACCOUNT_MGMT */
+
+	return NULL;
 }
 
 static void
 emae_account_hash_algo_combo_changed_cb (GtkComboBox *combobox,
                                          EMAccountEditor *emae)
 {
+#if 0  /* ACCOUNT_MGMT */
 	EAccount *account;
 	gpointer data;
 	const gchar *text = NULL;
@@ -3949,6 +4031,7 @@ emae_account_hash_algo_combo_changed_cb (GtkComboBox *combobox,
 	}
 
 	e_account_set_string (account, GPOINTER_TO_INT (data), text);
+#endif /* ACCOUNT_MGMT */
 }
 
 static GtkComboBox *
@@ -3957,6 +4040,7 @@ emae_account_hash_algo_combo (EMAccountEditor *emae,
                               gint item,
                               GtkBuilder *builder)
 {
+#if 0  /* ACCOUNT_MGMT */
 	EAccount *account;
 	GtkComboBox *combobox;
 	const gchar *text;
@@ -3984,6 +4068,9 @@ emae_account_hash_algo_combo (EMAccountEditor *emae,
 	g_signal_connect (combobox, "changed", G_CALLBACK (emae_account_hash_algo_combo_changed_cb), emae);
 
 	return combobox;
+#endif /* ACCOUNT_MGMT */
+
+	return NULL;
 }
 
 static GtkWidget *
@@ -4007,6 +4094,7 @@ emae_security_page (EConfig *ec,
 	builder = gtk_builder_new ();
 	e_load_ui_builder_definition (builder, "mail-config.ui");
 
+#if 0  /* ACCOUNT_MGMT */
 	/* Security */
 	emae_account_entry (emae, "pgp_key", E_ACCOUNT_PGP_KEY, builder);
 	emae_account_hash_algo_combo (emae, "pgp_hash_algo", E_ACCOUNT_PGP_HASH_ALGORITHM, builder);
@@ -4014,26 +4102,33 @@ emae_security_page (EConfig *ec,
 	emae_account_toggle (emae, "pgp_always_sign", E_ACCOUNT_PGP_ALWAYS_SIGN, builder);
 	emae_account_toggle (emae, "pgp_no_imip_sign", E_ACCOUNT_PGP_NO_IMIP_SIGN, builder);
 	emae_account_toggle (emae, "pgp_always_trust", E_ACCOUNT_PGP_ALWAYS_TRUST, builder);
+#endif /* ACCOUNT_MGMT */
 
 #if defined (HAVE_NSS) && defined (ENABLE_SMIME)
 	/* TODO: this should handle its entry separately? */
+#if 0  /* ACCOUNT_MGMT */
 	priv->smime_sign_key = emae_account_entry (emae, "smime_sign_key", E_ACCOUNT_SMIME_SIGN_KEY, builder);
+#endif /* ACCOUNT_MGMT */
 	priv->smime_sign_key_select = (GtkButton *)e_builder_get_widget (builder, "smime_sign_key_select");
 	priv->smime_sign_key_clear = (GtkButton *)e_builder_get_widget (builder, "smime_sign_key_clear");
 	g_signal_connect (priv->smime_sign_key_select, "clicked", G_CALLBACK(smime_sign_key_select), emae);
 	g_signal_connect (priv->smime_sign_key_clear, "clicked", G_CALLBACK(smime_sign_key_clear), emae);
 
+#if 0  /* ACCOUNT_MGMT */
 	emae_account_hash_algo_combo (emae, "smime_hash_algo", E_ACCOUNT_SMIME_HASH_ALGORITHM, builder);
 	priv->smime_sign_default = emae_account_toggle (emae, "smime_sign_default", E_ACCOUNT_SMIME_SIGN_DEFAULT, builder);
 
 	priv->smime_encrypt_key = emae_account_entry (emae, "smime_encrypt_key", E_ACCOUNT_SMIME_ENCRYPT_KEY, builder);
+#endif /* ACCOUNT_MGMT */
 	priv->smime_encrypt_key_select = (GtkButton *)e_builder_get_widget (builder, "smime_encrypt_key_select");
 	priv->smime_encrypt_key_clear = (GtkButton *)e_builder_get_widget (builder, "smime_encrypt_key_clear");
 	g_signal_connect (priv->smime_encrypt_key_select, "clicked", G_CALLBACK(smime_encrypt_key_select), emae);
 	g_signal_connect (priv->smime_encrypt_key_clear, "clicked", G_CALLBACK(smime_encrypt_key_clear), emae);
 
+#if 0  /* ACCOUNT_MGMT */
 	priv->smime_encrypt_default = emae_account_toggle (emae, "smime_encrypt_default", E_ACCOUNT_SMIME_ENCRYPT_DEFAULT, builder);
 	priv->smime_encrypt_to_self = emae_account_toggle (emae, "smime_encrypt_to_self", E_ACCOUNT_SMIME_ENCRYPT_TO_SELF, builder);
+#endif /* ACCOUNT_MGMT */
 	smime_changed (emae);
 #else
 	{
@@ -4320,6 +4415,7 @@ emae_check_complete (EConfig *ec,
                      const gchar *pageid,
                      gpointer data)
 {
+#if 0  /* ACCOUNT_MGMT */
 	EMAccountEditor *emae = data;
 	EAccount *account;
 	EAccount *original_account;
@@ -4542,6 +4638,9 @@ emae_check_complete (EConfig *ec,
 	}
 
 	return ok;
+#endif /* ACCOUNT_MGMT */
+
+	return FALSE;
 }
 
 gboolean
@@ -4551,6 +4650,7 @@ em_account_editor_check (EMAccountEditor *emae,
 	return emae_check_complete ((EConfig *) emae->config, page, emae);
 }
 
+#if 0  /* ACCOUNT_MGMT */
 static void
 forget_password_if_needed (EAccount *original_account,
                            EAccount *modified_account,
@@ -4589,11 +4689,13 @@ forget_password_if_needed (EAccount *original_account,
 		camel_url_free (url);
 	}
 }
+#endif /* ACCOUNT_MGMT */
 
 static void
 emae_commit (EConfig *ec,
              EMAccountEditor *emae)
 {
+#if 0  /* ACCOUNT_MGMT */
 	EAccountList *accounts = e_get_account_list ();
 	EAccount *account;
 	EAccount *modified_account;
@@ -4695,6 +4797,7 @@ emae_commit (EConfig *ec,
 		e_account_list_set_default (accounts, account);
 
 	e_account_list_save (accounts);
+#endif /* ACCOUNT_MGMT */
 }
 
 void
@@ -4708,6 +4811,7 @@ em_account_editor_construct (EMAccountEditor *emae,
                              EMAccountEditorType type,
                              const gchar *id)
 {
+#if 0  /* ACCOUNT_MGMT */
 	EMAccountEditorPrivate *priv = emae->priv;
 	gint i, index;
 	GSList *l;
@@ -4811,5 +4915,5 @@ em_account_editor_construct (EMAccountEditor *emae,
 		emae->priv->transport.protocol,
 		emae->priv->transport.settings);
 	e_config_set_target ((EConfig *) ec, (EConfigTarget *) target);
+#endif /* ACCOUNT_MGMT */
 }
-
diff --git a/mail/em-account-editor.h b/mail/em-account-editor.h
index 3416b5d..d055ac5 100644
--- a/mail/em-account-editor.h
+++ b/mail/em-account-editor.h
@@ -96,6 +96,7 @@ struct _EMAccountEditorClass {
 };
 
 GType		em_account_editor_get_type	(void);
+#if 0  /* ACCOUNT_MGMT */
 EMAccountEditor *
 		em_account_editor_new		(EAccount *account,
 						 EMAccountEditorType type,
@@ -107,11 +108,14 @@ EMAccountEditor *
 						 EMailBackend *backend,
 						 const gchar *id,
 						 GtkWidget **pages);
+#endif /* ACCOUNT_MGMT */
 EMailBackend *	em_account_editor_get_backend	(EMAccountEditor *emae);
+#if 0  /* ACCOUNT_MGMT */
 EAccount *	em_account_editor_get_modified_account
 						(EMAccountEditor *emae);
 EAccount *	em_account_editor_get_original_account
 						(EMAccountEditor *emae);
+#endif /* ACCOUNT_MGMT */
 void		em_account_editor_commit	(EMAccountEditor *emae);
 gboolean	em_account_editor_check		(EMAccountEditor *emae,
 						 const gchar *page);
diff --git a/mail/em-composer-utils.c b/mail/em-composer-utils.c
index b09d3cd..44b1318 100644
--- a/mail/em-composer-utils.c
+++ b/mail/em-composer-utils.c
@@ -28,16 +28,19 @@
 
 #include <string.h>
 #include <gtk/gtk.h>
+#include <glib/gi18n.h>
 
 #include <libedataserver/e-data-server-util.h>
-#include <glib/gi18n.h>
+#include <libedataserver/e-source-mail-account.h>
+#include <libedataserver/e-source-mail-composition.h>
+#include <libedataserver/e-source-mail-identity.h>
+#include <libedataserver/e-source-mail-submission.h>
 
 #include "mail-mt.h"
 #include "mail-ops.h"
 #include "mail-tools.h"
 #include "mail-send-recv.h"
 
-#include "e-util/e-account-utils.h"
 #include "e-util/e-alert-dialog.h"
 #include "e-util/e-alert-sink.h"
 #include "e-util/e-util.h"
@@ -361,22 +364,26 @@ finished:
 }
 
 static gboolean
-composer_presend_check_account (EMsgComposer *composer)
+composer_presend_check_identity (EMsgComposer *composer)
 {
 	EComposerHeaderTable *table;
-	EAccount *account;
-	gboolean check_passed;
+	ESourceRegistry *registry;
+	ESource *source;
+	const gchar *uid;
 
 	table = e_msg_composer_get_header_table (composer);
-	account = e_composer_header_table_get_account (table);
-	check_passed = (account != NULL && account->enabled);
+	registry = e_composer_header_table_get_registry (table);
+	uid = e_composer_header_table_get_identity_uid (table);
+	source = e_source_registry_lookup_by_uid (registry, uid);
 
-	if (!check_passed)
+	if (!em_utils_mail_identity_is_enabled (registry, source)) {
 		e_alert_submit (
 			E_ALERT_SINK (composer),
 			"mail:send-no-account-enabled", NULL);
+		return FALSE;
+	}
 
-	return check_passed;
+	return TRUE;
 }
 
 static gboolean
@@ -563,9 +570,11 @@ em_utils_composer_send_cb (EMsgComposer *composer,
                            CamelMimeMessage *message,
                            EActivity *activity)
 {
+	EShell *shell;
 	AsyncContext *context;
 	CamelSession *session;
 	GCancellable *cancellable;
+	ESourceRegistry *registry;
 
 	context = g_slice_new0 (AsyncContext);
 	context->message = g_object_ref (message);
@@ -575,8 +584,11 @@ em_utils_composer_send_cb (EMsgComposer *composer,
 	cancellable = e_activity_get_cancellable (activity);
 	session = e_msg_composer_get_session (context->composer);
 
+	shell = e_msg_composer_get_shell (context->composer);
+	registry = e_shell_get_registry (shell);
+
 	e_mail_session_send_to (
-		E_MAIL_SESSION (session), message,
+		E_MAIL_SESSION (session), registry, message,
 		G_PRIORITY_DEFAULT, cancellable, NULL, NULL,
 		(GAsyncReadyCallback) composer_send_completed,
 		context);
@@ -787,10 +799,12 @@ em_utils_composer_save_to_drafts_cb (EMsgComposer *composer,
 {
 	AsyncContext *context;
 	EComposerHeaderTable *table;
+	ESourceRegistry *registry;
+	ESource *source;
 	const gchar *drafts_folder_uri = NULL;
 	const gchar *local_drafts_folder_uri;
 	CamelSession *session;
-	EAccount *account;
+	const gchar *identity_uid;
 
 	context = g_slice_new0 (AsyncContext);
 	context->message = g_object_ref (message);
@@ -798,18 +812,28 @@ em_utils_composer_save_to_drafts_cb (EMsgComposer *composer,
 	context->activity = g_object_ref (activity);
 
 	session = e_msg_composer_get_session (composer);
+	table = e_msg_composer_get_header_table (composer);
 
-	local_drafts_folder_uri =
-		e_mail_local_get_folder_uri (E_MAIL_LOCAL_FOLDER_DRAFTS);
+	registry = e_composer_header_table_get_registry (table);
+	identity_uid = e_composer_header_table_get_identity_uid (table);
+	source = e_source_registry_lookup_by_uid (registry, identity_uid);
 
-	table = e_msg_composer_get_header_table (composer);
-	account = e_composer_header_table_get_account (table);
+	/* Get the selected identity's preferred Drafts folder. */
+	if (source != NULL) {
+		ESourceMailComposition *extension;
+		const gchar *extension_name;
+		const gchar *uri;
+
+		extension_name = E_SOURCE_EXTENSION_MAIL_COMPOSITION;
+		extension = e_source_get_extension (source, extension_name);
+		uri = e_source_mail_composition_get_drafts_folder (extension);
 
-	if (account != NULL && account->enabled)
-		drafts_folder_uri = account->drafts_folder_uri;
+		if (uri != NULL && *uri != '\0')
+			drafts_folder_uri = uri;
+	}
 
-	if (g_strcmp0 (drafts_folder_uri, local_drafts_folder_uri) == 0)
-		drafts_folder_uri = NULL;
+	local_drafts_folder_uri =
+		e_mail_local_get_folder_uri (E_MAIL_LOCAL_FOLDER_DRAFTS);
 
 	if (drafts_folder_uri == NULL) {
 		composer_save_to_drafts_append_mail (context, NULL);
@@ -922,12 +946,15 @@ create_new_composer (EShell *shell,
                      CamelFolder *folder)
 {
 	EMsgComposer *composer;
+	ESourceRegistry *registry;
 	EComposerHeaderTable *table;
-	EAccount *account = NULL;
+	ESource *source = NULL;
+	const gchar *identity = NULL;
 
 	composer = e_msg_composer_new (shell);
 
 	table = e_msg_composer_get_header_table (composer);
+	registry = e_composer_header_table_get_registry (table);
 
 	if (folder != NULL) {
 		CamelStore *store;
@@ -937,7 +964,7 @@ create_new_composer (EShell *shell,
 
 		store = camel_folder_get_parent_store (folder);
 		uid = camel_service_get_uid (CAMEL_SERVICE (store));
-		account = e_get_account_by_uid (uid);
+		source = e_source_registry_lookup_by_uid (registry, uid);
 
 		folder_uri = e_mail_folder_uri_from_folder (folder);
 
@@ -948,8 +975,17 @@ create_new_composer (EShell *shell,
 		g_free (folder_uri);
 	}
 
-	e_composer_header_table_set_account (table, account);
+	if (source != NULL) {
+		ESourceMailAccount *extension;
+		const gchar *extension_name;
+
+		extension_name = E_SOURCE_EXTENSION_MAIL_ACCOUNT;
+		extension = e_source_get_extension (source, extension_name);
+		identity = e_source_mail_account_get_identity_uid (extension);
+	}
+
 	e_composer_header_table_set_subject (table, subject);
+	e_composer_header_table_set_identity_uid (table, identity);
 
 	return composer;
 }
@@ -995,8 +1031,8 @@ em_utils_compose_new_message_with_mailto (EShell *shell,
                                           CamelFolder *folder)
 {
 	EMsgComposer *composer;
+	ESourceRegistry *registry;
 	EComposerHeaderTable *table;
-	CamelService *service = NULL;
 
 	g_return_val_if_fail (E_IS_SHELL (shell), NULL);
 
@@ -1009,25 +1045,37 @@ em_utils_compose_new_message_with_mailto (EShell *shell,
 		composer = e_msg_composer_new (shell);
 
 	table = e_msg_composer_get_header_table (composer);
+	registry = e_composer_header_table_get_registry (table);
+
+	composer_set_no_change (composer);
+
+	gtk_window_present (GTK_WINDOW (composer));
+
+	/* If a CamelFolder was given, we need to backtrack and find
+	 * the corresponding ESource with a Mail Identity extension. */
 
 	if (folder != NULL) {
+		ESource *source;
 		CamelStore *store;
+		ESourceMailAccount *extension;
+		const gchar *extension_name;
+		const gchar *uid;
 
 		store = camel_folder_get_parent_store (folder);
-		service = CAMEL_SERVICE (store);
-	}
+		uid = camel_service_get_uid (CAMEL_SERVICE (store));
+		source = e_source_registry_lookup_by_uid (registry, uid);
+		g_return_val_if_fail (source != NULL, composer);
 
-	if (service != NULL) {
-		const gchar *display_name;
+		extension_name = E_SOURCE_EXTENSION_MAIL_ACCOUNT;
+		if (e_source_has_extension (source, extension_name))
+			goto exit;
 
-		display_name = camel_service_get_display_name (service);
-		e_composer_header_table_set_account_name (table, display_name);
+		extension = e_source_get_extension (source, extension_name);
+		uid = e_source_mail_account_get_identity_uid (extension);
+		e_composer_header_table_set_identity_uid (table, uid);
 	}
 
-	composer_set_no_change (composer);
-
-	gtk_window_present (GTK_WINDOW (composer));
-
+exit:
 	return composer;
 }
 
@@ -1248,6 +1296,7 @@ em_utils_edit_message (EShell *shell,
                        const gchar *message_uid)
 {
 	EMsgComposer *composer;
+	ESourceRegistry *registry;
 	gboolean folder_is_drafts;
 	gboolean folder_is_outbox;
 	gboolean folder_is_templates;
@@ -1256,9 +1305,10 @@ em_utils_edit_message (EShell *shell,
 	g_return_val_if_fail (CAMEL_IS_FOLDER (folder), NULL);
 	g_return_val_if_fail (CAMEL_IS_MIME_MESSAGE (message), NULL);
 
-	folder_is_drafts = em_utils_folder_is_drafts (folder);
-	folder_is_outbox = em_utils_folder_is_outbox (folder);
-	folder_is_templates = em_utils_folder_is_templates (folder);
+	registry = e_shell_get_registry (shell);
+	folder_is_drafts = em_utils_folder_is_drafts (registry, folder);
+	folder_is_outbox = em_utils_folder_is_outbox (registry, folder);
+	folder_is_templates = em_utils_folder_is_templates (registry, folder);
 
 	/* Template specific code follows. */
 	if (folder_is_templates) {
@@ -1797,8 +1847,10 @@ static EMsgComposer *
 redirect_get_composer (EShell *shell,
                        CamelMimeMessage *message)
 {
+	ESourceRegistry *registry;
 	CamelMedium *medium;
-	EAccount *account;
+	ESource *source;
+	const gchar *identity_uid = NULL;
 
 	medium = CAMEL_MEDIUM (message);
 
@@ -1814,10 +1866,15 @@ redirect_get_composer (EShell *shell,
 	while (camel_medium_get_header (medium, "Resent-Bcc"))
 		camel_medium_remove_header (medium, "Resent-Bcc");
 
-	account = em_utils_guess_account_with_recipients (message, NULL);
+	registry = e_shell_get_registry (shell);
+
+	source = em_utils_guess_mail_identity_with_recipients (
+		registry, message, NULL);
+	if (source != NULL)
+		identity_uid = e_source_get_uid (source);
 
 	return e_msg_composer_new_redirect (
-		shell, message, account ? account->name : NULL, NULL);
+		shell, message, identity_uid, NULL);
 }
 
 /**
@@ -1844,76 +1901,6 @@ em_utils_redirect_message (EShell *shell,
 	composer_set_no_change (composer);
 }
 
-/* Message disposition notifications, rfc 2298 */
-void
-em_utils_handle_receipt (EMailBackend *backend,
-                         CamelFolder *folder,
-                         const gchar *message_uid,
-                         CamelMimeMessage *message)
-{
-	EAccount *account;
-	const gchar *addr;
-	CamelMessageInfo *info;
-
-	g_return_if_fail (E_IS_MAIL_BACKEND (backend));
-	g_return_if_fail (CAMEL_IS_FOLDER (folder));
-	g_return_if_fail (CAMEL_IS_MIME_MESSAGE (message));
-
-	info = camel_folder_get_message_info (folder, message_uid);
-	if (info == NULL)
-		return;
-
-	if (camel_message_info_user_flag (info, "receipt-handled")) {
-		camel_folder_free_message_info (folder, info);
-		return;
-	}
-
-	addr = camel_medium_get_header (
-		CAMEL_MEDIUM (message), "Disposition-Notification-To");
-	if (addr == NULL) {
-		camel_folder_free_message_info (folder, info);
-		return;
-	}
-
-	camel_message_info_set_user_flag (info, "receipt-handled", TRUE);
-	camel_folder_free_message_info (folder, info);
-
-	account = em_utils_guess_account_with_recipients (message, folder);
-
-	/* TODO Should probably decode/format the address,
-	 *      since it could be in rfc2047 format. */
-	if (addr == NULL) {
-		addr = "";
-	} else {
-		while (camel_mime_is_lwsp (*addr))
-			addr++;
-	}
-
-	if (account == NULL)
-		return;
-
-	if (account->receipt_policy == E_ACCOUNT_RECEIPT_NEVER)
-		return;
-
-	if (account->receipt_policy == E_ACCOUNT_RECEIPT_ASK) {
-		GtkWindow *window;
-		const gchar *subject;
-		gint response;
-
-		/* FIXME Parent window should be passed in. */
-		window = e_shell_get_active_window (NULL);
-		subject = camel_mime_message_get_subject (message);
-
-		response = e_alert_run_dialog_for_args (
-			window, "mail:ask-receipt", addr, subject, NULL);
-
-		if (response != GTK_RESPONSE_YES)
-			return;
-	}
-
-	em_utils_send_receipt (backend, folder, message);
-}
-
 static void
 em_utils_receipt_done (CamelFolder *folder,
                        GAsyncResult *result,
@@ -1926,13 +1913,13 @@ em_utils_receipt_done (CamelFolder *folder,
 	mail_send (backend);
 }
 
-void
-em_utils_send_receipt (EMailBackend *backend,
+static void
+em_utils_send_receipt (ESource *account_source,
+                       EMailBackend *backend,
                        CamelFolder *folder,
                        CamelMimeMessage *message)
 {
 	/* See RFC #3798 for a description of message receipts */
-	EAccount *account = em_utils_guess_account_with_recipients (message, folder);
 	CamelMimeMessage *receipt = camel_mime_message_new ();
 	CamelMultipart *body = camel_multipart_new ();
 	CamelMimePart *part;
@@ -1942,15 +1929,21 @@ em_utils_send_receipt (EMailBackend *backend,
 	CamelStream *stream;
 	CamelFolder *out_folder;
 	CamelMessageInfo *info;
+	ESource *identity_source;
+	ESourceExtension *extension;
 	const gchar *message_id;
 	const gchar *message_date;
 	const gchar *message_subject;
 	const gchar *receipt_address;
+	const gchar *extension_name;
+	const gchar *identity_uid;
+	const gchar *transport_uid;
+	const gchar *self_address;
+	const gchar *sent_folder_uri;
 	gchar *fake_msgid;
 	gchar *hostname;
-	gchar *self_address, *receipt_subject;
+	gchar *receipt_subject;
 	gchar *ua, *recipient;
-	gchar *transport_uid;
 	gchar *content;
 
 	message_id = camel_medium_get_header (
@@ -1964,9 +1957,6 @@ em_utils_send_receipt (EMailBackend *backend,
 	if (!receipt_address)
 		return;
 
-	/* the 'account' should be always set */
-	g_return_if_fail (account != NULL);
-
 	/* Collect information for the receipt */
 
 	/* We use camel_header_msgid_generate () to get a canonical
@@ -1974,7 +1964,29 @@ em_utils_send_receipt (EMailBackend *backend,
 	hostname = strchr ((fake_msgid = camel_header_msgid_generate ()), '@');
 	hostname++;
 
-	self_address = account->id->address;
+	extension_name = E_SOURCE_EXTENSION_MAIL_ACCOUNT;
+	extension = e_source_get_extension (account_source, extension_name);
+
+	identity_source = e_source_mail_account_get_identity (
+		E_SOURCE_MAIL_ACCOUNT (extension));
+	g_return_if_fail (identity_source != NULL);
+
+	identity_uid = e_source_get_uid (identity_source);
+
+	extension_name = E_SOURCE_EXTENSION_MAIL_IDENTITY;
+	extension = e_source_get_extension (identity_source, extension_name);
+
+	self_address = e_source_mail_identity_get_address (
+		E_SOURCE_MAIL_IDENTITY (extension));
+
+	extension_name = E_SOURCE_EXTENSION_MAIL_SUBMISSION;
+	extension = e_source_get_extension (identity_source, extension_name);
+
+	sent_folder_uri = e_source_mail_submission_get_sent_folder (
+		E_SOURCE_MAIL_SUBMISSION (extension));
+
+	transport_uid = e_source_mail_submission_get_transport_uid (
+		E_SOURCE_MAIL_SUBMISSION (extension));
 
 	if (!message_id)
 		message_id = "";
@@ -2073,15 +2085,13 @@ em_utils_send_receipt (EMailBackend *backend,
 		receipt, CAMEL_RECIPIENT_TYPE_TO, addr);
 	g_object_unref (addr);
 
-	transport_uid = g_strconcat (account->uid, "-transport", NULL);
-
 	camel_medium_set_header (
 		CAMEL_MEDIUM (receipt),
 		"Return-Path", "<>");
 	camel_medium_set_header (
 		CAMEL_MEDIUM (receipt),
-		"X-Evolution-Account",
-		account->uid);
+		"X-Evolution-Identity",
+		identity_uid);
 	camel_medium_set_header (
 		CAMEL_MEDIUM (receipt),
 		"X-Evolution-Transport",
@@ -2089,9 +2099,7 @@ em_utils_send_receipt (EMailBackend *backend,
 	camel_medium_set_header (
 		CAMEL_MEDIUM (receipt),
 		"X-Evolution-Fcc",
-		account->sent_folder_uri);
-
-	g_free (transport_uid);
+		sent_folder_uri);
 
 	/* Send the receipt */
 	info = camel_message_info_new (NULL);
@@ -2107,6 +2115,90 @@ em_utils_send_receipt (EMailBackend *backend,
 	camel_message_info_free (info);
 }
 
+/* Message disposition notifications, rfc 2298 */
+void
+em_utils_handle_receipt (EMailBackend *backend,
+                         CamelFolder *folder,
+                         const gchar *message_uid,
+                         CamelMimeMessage *message)
+{
+	EShell *shell;
+	EShellBackend *shell_backend;
+	ESource *source;
+	ESourceRegistry *registry;
+	ESourceExtension *extension;
+	EMdnRequestPolicy policy;
+	const gchar *extension_name;
+	const gchar *address;
+	CamelMessageInfo *info;
+
+	g_return_if_fail (E_IS_MAIL_BACKEND (backend));
+	g_return_if_fail (CAMEL_IS_FOLDER (folder));
+	g_return_if_fail (CAMEL_IS_MIME_MESSAGE (message));
+
+	shell_backend = E_SHELL_BACKEND (backend);
+	shell = e_shell_backend_get_shell (shell_backend);
+	registry = e_shell_get_registry (shell);
+
+	info = camel_folder_get_message_info (folder, message_uid);
+
+	if (info == NULL)
+		return;
+
+	if (camel_message_info_user_flag (info, "receipt-handled")) {
+		camel_folder_free_message_info (folder, info);
+		return;
+	}
+
+	address = camel_medium_get_header (
+		CAMEL_MEDIUM (message), "Disposition-Notification-To");
+	if (address == NULL) {
+		camel_folder_free_message_info (folder, info);
+		return;
+	}
+
+	/* TODO Should probably decode/format the address,
+	 *      since it could be in rfc2047 format. */
+	while (camel_mime_is_lwsp (*address))
+		address++;
+
+	camel_message_info_set_user_flag (info, "receipt-handled", TRUE);
+	camel_folder_free_message_info (folder, info);
+
+	source = em_utils_guess_mail_account_with_recipients (
+		registry, message, folder);
+
+	if (source == NULL)
+		return;
+
+	extension_name = E_SOURCE_EXTENSION_MAIL_ACCOUNT;
+	extension = e_source_get_extension (source, extension_name);
+
+	policy = e_source_mail_account_get_mdn_request_policy (
+		E_SOURCE_MAIL_ACCOUNT (extension));
+
+	if (policy == E_MDN_REQUEST_POLICY_NEVER)
+		return;
+
+	if (policy == E_MDN_REQUEST_POLICY_ASK) {
+		GtkWindow *window;
+		const gchar *subject;
+		gint response;
+
+		/* FIXME Parent window should be passed in. */
+		window = e_shell_get_active_window (NULL);
+		subject = camel_mime_message_get_subject (message);
+
+		response = e_alert_run_dialog_for_args (
+			window, "mail:ask-receipt", address, subject, NULL);
+
+		if (response != GTK_RESPONSE_YES)
+			return;
+	}
+
+	em_utils_send_receipt (source, backend, folder, message);
+}
+
 /* Replying to messages... */
 
 EDestination **
@@ -2147,7 +2239,7 @@ em_utils_camel_address_to_destination (CamelInternetAddress *iaddr)
 static EMsgComposer *
 reply_get_composer (EShell *shell,
                     CamelMimeMessage *message,
-                    EAccount *account,
+                    const gchar *identity_uid,
                     CamelInternetAddress *to,
                     CamelInternetAddress *cc,
                     CamelFolder *folder,
@@ -2189,9 +2281,9 @@ reply_get_composer (EShell *shell,
 	}
 
 	table = e_msg_composer_get_header_table (composer);
-	e_composer_header_table_set_account (table, account);
 	e_composer_header_table_set_subject (table, subject);
 	e_composer_header_table_set_destinations_to (table, tov);
+	e_composer_header_table_set_identity_uid (table, identity_uid);
 
 	/* Add destinations instead of setting, so we don't remove
 	 * automatic CC addresses that have already been added. */
@@ -2488,7 +2580,8 @@ concat_unique_addrs (CamelInternetAddress *dest,
 }
 
 void
-em_utils_get_reply_all (CamelMimeMessage *message,
+em_utils_get_reply_all (ESourceRegistry *registry,
+                        CamelMimeMessage *message,
                         CamelInternetAddress *to,
                         CamelInternetAddress *cc,
                         CamelNNTPAddress *postto)
@@ -2501,6 +2594,7 @@ em_utils_get_reply_all (CamelMimeMessage *message,
 	const gchar *posthdr = NULL;
 	GHashTable *rcpt_hash;
 
+	g_return_if_fail (E_IS_SOURCE_REGISTRY (registry));
 	g_return_if_fail (CAMEL_IS_MIME_MESSAGE (message));
 	g_return_if_fail (CAMEL_IS_INTERNET_ADDRESS (to));
 	g_return_if_fail (CAMEL_IS_INTERNET_ADDRESS (cc));
@@ -2517,7 +2611,7 @@ em_utils_get_reply_all (CamelMimeMessage *message,
 	if (postto != NULL && posthdr != NULL)
 		camel_address_decode (CAMEL_ADDRESS (postto), posthdr);
 
-	rcpt_hash = em_utils_generate_account_hash ();
+	rcpt_hash = em_utils_generate_account_hash (registry);
 
 	reply_to = get_reply_to (message);
 	to_addrs = camel_mime_message_get_recipients (
@@ -2904,10 +2998,12 @@ em_utils_reply_to_message (EShell *shell,
                            EMFormat *source_formatter,
                            CamelInternetAddress *address)
 {
+	ESourceRegistry *registry;
 	CamelInternetAddress *to, *cc;
 	CamelNNTPAddress *postto = NULL;
 	EMsgComposer *composer;
-	EAccount *account;
+	ESource *source;
+	const gchar *identity_uid = NULL;
 	guint32 flags;
 
 	g_return_val_if_fail (E_IS_SHELL (shell), NULL);
@@ -2916,7 +3012,11 @@ em_utils_reply_to_message (EShell *shell,
 	to = camel_internet_address_new ();
 	cc = camel_internet_address_new ();
 
-	account = em_utils_guess_account_with_recipients (message, folder);
+	registry = e_shell_get_registry (shell);
+	source = em_utils_guess_mail_identity_with_recipients (
+		registry, message, folder);
+	if (source != NULL)
+		identity_uid = e_source_get_uid (source);
 	flags = CAMEL_MESSAGE_ANSWERED | CAMEL_MESSAGE_SEEN;
 
 	switch (type) {
@@ -2948,12 +3048,12 @@ em_utils_reply_to_message (EShell *shell,
 		if (folder)
 			postto = camel_nntp_address_new ();
 
-		em_utils_get_reply_all (message, to, cc, postto);
+		em_utils_get_reply_all (registry, message, to, cc, postto);
 		break;
 	}
 
 	composer = reply_get_composer (
-		shell, message, account, to, cc, folder, postto);
+		shell, message, identity_uid, to, cc, folder, postto);
 	e_msg_composer_add_message_attachments (composer, message, TRUE);
 
 	if (postto)
@@ -3070,7 +3170,7 @@ em_configure_new_composer (EMsgComposer *composer)
 
 	g_signal_connect (
 		composer, "presend",
-		G_CALLBACK (composer_presend_check_account), NULL);
+		G_CALLBACK (composer_presend_check_identity), NULL);
 
 	g_signal_connect (
 		composer, "presend",
diff --git a/mail/em-composer-utils.h b/mail/em-composer-utils.h
index bd6eb7c..12a5fa2 100644
--- a/mail/em-composer-utils.h
+++ b/mail/em-composer-utils.h
@@ -62,9 +62,6 @@ void		em_utils_handle_receipt		(EMailBackend *backend,
 						 CamelFolder *folder,
 						 const gchar *message_uid,
 						 CamelMimeMessage *message);
-void		em_utils_send_receipt		(EMailBackend *backend,
-						 CamelFolder *folder,
-						 CamelMimeMessage *message);
 gchar *		em_utils_construct_composer_text
 						(CamelMimeMessage *message,
 						 EMFormat *source_formatter);
@@ -72,7 +69,8 @@ gboolean	em_utils_is_munged_list_message	(CamelMimeMessage *message);
 void		em_utils_get_reply_sender	(CamelMimeMessage *message,
 						 CamelInternetAddress *to,
 						 CamelNNTPAddress *postto);
-void		em_utils_get_reply_all		(CamelMimeMessage *message,
+void		em_utils_get_reply_all		(ESourceRegistry *registry,
+						 CamelMimeMessage *message,
 						 CamelInternetAddress *to,
 						 CamelInternetAddress *cc,
 						 CamelNNTPAddress *postto);
diff --git a/mail/em-config.h b/mail/em-config.h
index 24a75fb..4aec59e 100644
--- a/mail/em-config.h
+++ b/mail/em-config.h
@@ -25,7 +25,7 @@
 
 #include <camel/camel.h>
 #include <gconf/gconf-client.h>
-#include <libedataserver/e-account.h>
+#include <libedataserver/e-source.h>
 
 #include "e-util/e-config.h"
 
diff --git a/mail/em-filter-source-element.c b/mail/em-filter-source-element.c
index b95c140..3095023 100644
--- a/mail/em-filter-source-element.c
+++ b/mail/em-filter-source-element.c
@@ -33,24 +33,18 @@
 #include <camel/camel.h>
 
 #include <libedataserver/e-sexp.h>
+#include <libedataserver/e-source-mail-account.h>
+#include <libedataserver/e-source-mail-identity.h>
 
-#include <e-util/e-account-utils.h>
+#include <shell/e-shell.h>
 #include <filter/e-filter-part.h>
 
 #define EM_FILTER_SOURCE_ELEMENT_GET_PRIVATE(obj) \
 	(G_TYPE_INSTANCE_GET_PRIVATE \
 	((obj), EM_TYPE_FILTER_SOURCE_ELEMENT, EMFilterSourceElementPrivate))
 
-typedef struct _SourceInfo {
-	gchar *account_name;
-	gchar *name;
-	gchar *address;
-	gchar *uid;
-} SourceInfo;
-
 struct _EMFilterSourceElementPrivate {
 	EMailBackend *backend;
-	GList *sources;
 	gchar *active_id;
 };
 
@@ -65,16 +59,6 @@ enum {
 };
 
 static void
-source_info_free (SourceInfo *info)
-{
-	g_free (info->account_name);
-	g_free (info->name);
-	g_free (info->address);
-	g_free (info->uid);
-	g_free (info);
-}
-
-static void
 filter_source_element_source_changed (GtkComboBox *combo_box,
                                       EMFilterSourceElement *fs)
 {
@@ -87,52 +71,6 @@ filter_source_element_source_changed (GtkComboBox *combo_box,
 }
 
 static void
-filter_source_element_add_source (EMFilterSourceElement *fs,
-                                  const gchar *account_name,
-                                  const gchar *name,
-                                  const gchar *addr,
-                                  const gchar *uid)
-{
-	SourceInfo *info;
-
-	g_return_if_fail (EM_IS_FILTER_SOURCE_ELEMENT (fs));
-
-	info = g_new0 (SourceInfo, 1);
-	info->account_name = g_strdup (account_name);
-	info->name = g_strdup (name);
-	info->address = g_strdup (addr);
-	info->uid = g_strdup (uid);
-
-	fs->priv->sources = g_list_append (fs->priv->sources, info);
-}
-
-static void
-filter_source_element_get_sources (EMFilterSourceElement *fs)
-{
-	EAccountList *accounts;
-	const EAccount *account;
-	EIterator *it;
-
-	/* should this get the global object from mail? */
-	accounts = e_get_account_list ();
-
-	for (it = e_list_get_iterator ((EList *) accounts);
-	     e_iterator_is_valid (it);
-	     e_iterator_next (it)) {
-		account = (const EAccount *) e_iterator_get (it);
-
-		if (account->source == NULL)
-			continue;
-
-		filter_source_element_add_source (
-			fs, account->name, account->id->name,
-			account->id->address, account->uid);
-	}
-
-	g_object_unref (it);
-}
-
-static void
 filter_source_element_set_backend (EMFilterSourceElement *element,
                                    EMailBackend *backend)
 {
@@ -200,8 +138,6 @@ filter_source_element_finalize (GObject *object)
 
 	priv = EM_FILTER_SOURCE_ELEMENT_GET_PRIVATE (object);
 
-	g_list_foreach (priv->sources, (GFunc) source_info_free, NULL);
-	g_list_free (priv->sources);
 	g_free (priv->active_id);
 
 	/* Chain up to parent's finalize() method. */
@@ -309,7 +245,6 @@ filter_source_element_clone (EFilterElement *fe)
 	EMFilterSourceElement *fs = (EMFilterSourceElement *) fe;
 	EMFilterSourceElement *cpy;
 	EMailBackend *backend;
-	GList *i;
 
 	backend = em_filter_source_element_get_backend (fs);
 	cpy = (EMFilterSourceElement *) em_filter_source_element_new (backend);
@@ -317,13 +252,6 @@ filter_source_element_clone (EFilterElement *fe)
 
 	cpy->priv->active_id = g_strdup (fs->priv->active_id);
 
-	for (i = fs->priv->sources; i != NULL; i = g_list_next (i)) {
-		SourceInfo *info = (SourceInfo *) i->data;
-		filter_source_element_add_source (
-			cpy, info->account_name, info->name,
-			info->address, info->uid);
-	}
-
 	return (EFilterElement *) cpy;
 }
 
@@ -331,29 +259,41 @@ static GtkWidget *
 filter_source_element_get_widget (EFilterElement *fe)
 {
 	EMFilterSourceElement *fs = (EMFilterSourceElement *) fe;
+	EShell *shell;
+	EMailBackend *backend;
+	ESourceRegistry *registry;
+	GList *list, *link;
 	GtkWidget *widget;
 	GtkComboBox *combo_box;
-	GList *i;
-
-	if (fs->priv->sources == NULL)
-		filter_source_element_get_sources (fs);
+	const gchar *extension_name;
 
 	widget = gtk_combo_box_text_new ();
 	combo_box = GTK_COMBO_BOX (widget);
 
-	for (i = fs->priv->sources; i != NULL; i = g_list_next (i)) {
-		SourceInfo *info = (SourceInfo *) i->data;
+	backend = em_filter_source_element_get_backend (fs);
+	shell = e_shell_backend_get_shell (E_SHELL_BACKEND (backend));
+
+	registry = e_shell_get_registry (shell);
+	extension_name = E_SOURCE_EXTENSION_MAIL_ACCOUNT;
+	list = e_source_registry_list_sources (registry, extension_name);
+
+	for (link = list; link != NULL; link = g_list_next (link)) {
+		ESource *source = E_SOURCE (link->data);
+		ESourceMailIdentity *extension;
 		const gchar *display_name;
 		const gchar *address;
 		const gchar *name;
 		const gchar *uid;
 		gchar *label;
 
-		uid = info->uid;
-		display_name = info->account_name;
+		uid = e_source_get_uid (source);
+		display_name = e_source_get_display_name (source);
+
+		extension_name = E_SOURCE_EXTENSION_MAIL_IDENTITY;
+		extension = e_source_get_extension (source, extension_name);
 
-		name = info->name;
-		address = info->address;
+		name = e_source_mail_identity_get_name (extension);
+		address = e_source_mail_identity_get_address (extension);
 
 		if (g_strcmp0 (display_name, address) == 0)
 			label = g_strdup_printf (
@@ -369,6 +309,8 @@ filter_source_element_get_widget (EFilterElement *fe)
 		g_free (label);
 	}
 
+	g_list_free (link);
+
 	if (fs->priv->active_id != NULL) {
 		gtk_combo_box_set_active_id (combo_box, fs->priv->active_id);
 	} else {
diff --git a/mail/em-folder-tree-model.c b/mail/em-folder-tree-model.c
index e63d362..a981d1c 100644
--- a/mail/em-folder-tree-model.c
+++ b/mail/em-folder-tree-model.c
@@ -36,8 +36,12 @@
 
 #include <glib/gi18n.h>
 
+#include <libedataserver/e-source-mail-account.h>
+#include <libedataserver/e-source-mail-composition.h>
+#include <libedataserver/e-source-mail-identity.h>
+#include <libedataserver/e-source-mail-submission.h>
+
 #include "e-util/e-util.h"
-#include "e-util/e-account-utils.h"
 
 #include "mail-tools.h"
 #include "mail-mt.h"
@@ -67,7 +71,6 @@ struct _EMFolderTreeModelPrivate {
 	 * mimic the sidebar. */
 	GtkTreeSelection *selection;  /* weak reference */
 
-	EAccountList *accounts;
 	EMailBackend *backend;
 
 	/* CamelStore -> EMFolderTreeStoreInfo */
@@ -75,10 +78,6 @@ struct _EMFolderTreeModelPrivate {
 
 	/* URI -> GtkTreeRowReference */
 	GHashTable *uri_index;
-
-	gulong account_changed_id;
-	gulong account_removed_id;
-	gulong account_added_id;
 };
 
 enum {
@@ -153,6 +152,9 @@ folder_tree_model_sort (GtkTreeModel *model,
 		COL_UINT_SORTORDER, &bsortorder,
 		-1);
 
+	/* Note that 'aname' or 'bname' might be NULL.  Prefer g_strcmp0()
+	 * over strcmp() or anything else that crashes on NULL arguments. */
+
 	if (is_store) {
 		EShell *shell;
 		EShellBackend *shell_backend;
@@ -164,34 +166,49 @@ folder_tree_model_sort (GtkTreeModel *model,
 
 		if (e_shell_settings_get_boolean (
 			shell_settings, "mail-sort-accounts-alpha")) {
-			const gchar *on_this_computer = _("On This Computer");
-			const gchar *search_folders = _("Search Folders");
+			gboolean aname_is_on_this_computer;
+			gboolean bname_is_on_this_computer;
+			gboolean aname_is_search_folders;
+			gboolean bname_is_search_folders;
+			const gchar *built_in_name;
+
+			built_in_name = _("On This Computer");
+			aname_is_on_this_computer =
+				(g_strcmp0 (aname, built_in_name) == 0);
+			bname_is_on_this_computer =
+				(g_strcmp0 (bname, built_in_name) == 0);
+
+			built_in_name = _("Search Folders");
+			aname_is_search_folders =
+				(g_strcmp0 (aname, built_in_name) == 0);
+			bname_is_search_folders =
+				(g_strcmp0 (bname, built_in_name) == 0);
 
 			/* On This Computer is always first, and Search Folders
 			 * is always last. */
 			if (e_shell_get_express_mode (shell)) {
-				if (g_str_equal (aname, on_this_computer) &&
-				    g_str_equal (bname, search_folders))
+				if (aname_is_on_this_computer &&
+				    bname_is_search_folders)
 					rv = -1;
-				else if (g_str_equal (bname, on_this_computer) &&
-					 g_str_equal (aname, search_folders))
+				else if (bname_is_on_this_computer &&
+					 aname_is_search_folders)
 					rv = 1;
-				else if (g_str_equal (aname, on_this_computer))
+				else if (aname_is_on_this_computer)
 					rv = 1;
-				else if (g_str_equal (bname, on_this_computer))
+				else if (bname_is_on_this_computer)
 					rv = -1;
-				else if (g_str_equal (aname, search_folders))
+				else if (aname_is_search_folders)
 					rv = 1;
-				else if (g_str_equal (bname, search_folders))
+				else if (bname_is_search_folders)
 					rv = -1;
 			} else {
-				if (g_str_equal (aname, on_this_computer))
+				if (aname_is_on_this_computer)
 					rv = -1;
-				else if (g_str_equal (bname, on_this_computer))
+				else if (bname_is_on_this_computer)
 					rv = 1;
-				else if (g_str_equal (aname, search_folders))
+				else if (aname_is_search_folders)
 					rv = 1;
-				else if (g_str_equal (bname, search_folders))
+				else if (bname_is_search_folders)
 					rv = -1;
 			}
 		} else if (asortorder || bsortorder) {
@@ -204,9 +221,9 @@ folder_tree_model_sort (GtkTreeModel *model,
 		}
 	} else if (store == vfolder_store) {
 		/* UNMATCHED is always last. */
-		if (aname && !strcmp (aname, _("UNMATCHED")))
+		if (g_strcmp0 (aname, _("UNMATCHED")) == 0)
 			rv = 1;
-		else if (bname && !strcmp (bname, _("UNMATCHED")))
+		else if (g_strcmp0 (bname, _("UNMATCHED")) == 0)
 			rv = -1;
 	} else {
 		/* Inbox is always first. */
@@ -234,69 +251,6 @@ folder_tree_model_sort (GtkTreeModel *model,
 }
 
 static void
-account_changed_cb (EAccountList *accounts,
-                    EAccount *account,
-                    EMFolderTreeModel *model)
-{
-	EMailBackend *backend;
-	EMailSession *session;
-	CamelService *service;
-
-	backend = em_folder_tree_model_get_backend (model);
-	session = e_mail_backend_get_session (backend);
-
-	service = camel_session_get_service (
-		CAMEL_SESSION (session), account->uid);
-
-	if (!CAMEL_IS_STORE (service))
-		return;
-
-	em_folder_tree_model_remove_store (model, CAMEL_STORE (service));
-
-	/* check if store needs to be added at all*/
-	if (!account->enabled)
-		return;
-
-	em_folder_tree_model_add_store (model, CAMEL_STORE (service));
-}
-
-static void
-account_removed_cb (EAccountList *accounts,
-                    EAccount *account,
-                    EMFolderTreeModel *model)
-{
-	EMailBackend *backend;
-	EMailSession *session;
-	CamelService *service;
-
-	backend = em_folder_tree_model_get_backend (model);
-	session = e_mail_backend_get_session (backend);
-
-	service = camel_session_get_service (
-		CAMEL_SESSION (session), account->uid);
-
-	if (!CAMEL_IS_STORE (service))
-		return;
-
-	em_folder_tree_model_remove_store (model, CAMEL_STORE (service));
-}
-
-/* HACK: FIXME: the component should listen to the account object directly */
-static void
-account_added_cb (EAccountList *accounts,
-                  EAccount *account,
-                  EMFolderTreeModel *model)
-{
-	EMailBackend *backend;
-	EMailSession *session;
-
-	backend = em_folder_tree_model_get_backend (model);
-	session = e_mail_backend_get_session (backend);
-
-	e_mail_store_add_by_account (session, account);
-}
-
-static void
 folder_tree_model_sort_changed (EMFolderTreeModel *tree_model)
 {
 	GtkTreeModel *model;
@@ -508,13 +462,6 @@ folder_tree_model_finalize (GObject *object)
 	g_hash_table_destroy (priv->store_index);
 	g_hash_table_destroy (priv->uri_index);
 
-	g_signal_handler_disconnect (
-		priv->accounts, priv->account_changed_id);
-	g_signal_handler_disconnect (
-		priv->accounts, priv->account_removed_id);
-	g_signal_handler_disconnect (
-		priv->accounts, priv->account_added_id);
-
 	/* Chain up to parent's finalize() method. */
 	G_OBJECT_CLASS (parent_class)->finalize (object);
 }
@@ -522,8 +469,6 @@ folder_tree_model_finalize (GObject *object)
 static void
 folder_tree_model_constructed (GObject *object)
 {
-	EMFolderTreeModelPrivate *priv;
-
 	GType col_types[] = {
 		G_TYPE_STRING,   /* display name */
 		G_TYPE_POINTER,  /* store object */
@@ -540,8 +485,6 @@ folder_tree_model_constructed (GObject *object)
 		G_TYPE_UINT	 /* user's sortorder */
 	};
 
-	priv = EM_FOLDER_TREE_MODEL_GET_PRIVATE (object);
-
 	gtk_tree_store_set_column_types (
 		GTK_TREE_STORE (object), NUM_COLUMNS, col_types);
 	gtk_tree_sortable_set_default_sort_func (
@@ -552,17 +495,6 @@ folder_tree_model_constructed (GObject *object)
 		GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID,
 		GTK_SORT_ASCENDING);
 
-	priv->accounts = e_get_account_list ();
-	priv->account_changed_id = g_signal_connect (
-		priv->accounts, "account-changed",
-		G_CALLBACK (account_changed_cb), object);
-	priv->account_removed_id = g_signal_connect (
-		priv->accounts, "account-removed",
-		G_CALLBACK (account_removed_cb), object);
-	priv->account_added_id = g_signal_connect (
-		priv->accounts, "account-added",
-		G_CALLBACK (account_added_cb), object);
-
 	/* Chain up to parent's constructed() method. */
 	G_OBJECT_CLASS (parent_class)->constructed (object);
 }
@@ -826,9 +758,10 @@ em_folder_tree_model_set_folder_info (EMFolderTreeModel *model,
 	GtkTreeRowReference *uri_row, *path_row;
 	GtkTreeStore *tree_store;
 	MailFolderCache *folder_cache;
+	ESourceRegistry *registry;
 	EMailBackend *backend;
 	EMailSession *session;
-	EAccount *account;
+	ESource *source;
 	guint unread;
 	GtkTreePath *path;
 	GtkTreeIter sub;
@@ -853,10 +786,12 @@ em_folder_tree_model_set_folder_info (EMFolderTreeModel *model,
 
 	backend = em_folder_tree_model_get_backend (model);
 	session = e_mail_backend_get_session (backend);
+
+	registry = e_mail_session_get_registry (session);
 	folder_cache = e_mail_session_get_folder_cache (session);
 
 	uid = camel_service_get_uid (CAMEL_SERVICE (si->store));
-	account = e_get_account_by_uid (uid);
+	source = e_source_registry_lookup_by_uid (registry, uid);
 
 	if (!fully_loaded)
 		load = (fi->child == NULL) && !(fi->flags &
@@ -883,8 +818,8 @@ em_folder_tree_model_set_folder_info (EMFolderTreeModel *model,
 	unread = fi->unread;
 	if (mail_folder_cache_get_folder_from_uri (
 		folder_cache, uri, &folder) && folder) {
-		folder_is_drafts = em_utils_folder_is_drafts (folder);
-		folder_is_outbox = em_utils_folder_is_outbox (folder);
+		folder_is_drafts = em_utils_folder_is_drafts (registry, folder);
+		folder_is_outbox = em_utils_folder_is_outbox (registry, folder);
 
 		if (folder_is_drafts || folder_is_outbox) {
 			gint total;
@@ -927,17 +862,43 @@ em_folder_tree_model_set_folder_info (EMFolderTreeModel *model,
 		}
 	}
 
-	if (account != NULL && (flags & CAMEL_FOLDER_TYPE_MASK) == 0) {
-		if (!folder_is_drafts && account->drafts_folder_uri != NULL) {
+	if (source != NULL && (flags & CAMEL_FOLDER_TYPE_MASK) == 0) {
+		ESource *identity;
+		ESourceExtension *extension;
+		const gchar *extension_name;
+		const gchar *drafts_folder_uri;
+		const gchar *sent_folder_uri;
+
+		extension_name = E_SOURCE_EXTENSION_MAIL_ACCOUNT;
+		extension = e_source_get_extension (source, extension_name);
+
+		identity = e_source_mail_account_get_identity (
+			E_SOURCE_MAIL_ACCOUNT (extension));
+
+		extension_name = E_SOURCE_EXTENSION_MAIL_COMPOSITION;
+		extension = e_source_get_extension (identity, extension_name);
+
+		drafts_folder_uri =
+			e_source_mail_composition_get_drafts_folder (
+			E_SOURCE_MAIL_COMPOSITION (extension));
+
+		extension_name = E_SOURCE_EXTENSION_MAIL_SUBMISSION;
+		extension = e_source_get_extension (identity, extension_name);
+
+		sent_folder_uri =
+			e_source_mail_submission_get_sent_folder (
+			E_SOURCE_MAIL_SUBMISSION (extension));
+
+		if (!folder_is_drafts && drafts_folder_uri != NULL) {
 			folder_is_drafts = e_mail_folder_uri_equal (
-				CAMEL_SESSION (session), uri,
-				account->drafts_folder_uri);
+				CAMEL_SESSION (session),
+				uri, drafts_folder_uri);
 		}
 
-		if (account->sent_folder_uri != NULL) {
+		if (sent_folder_uri != NULL) {
 			if (e_mail_folder_uri_equal (
-				CAMEL_SESSION (session), uri,
-				account->sent_folder_uri)) {
+				CAMEL_SESSION (session),
+				uri, sent_folder_uri)) {
 				add_flags = CAMEL_FOLDER_TYPE_SENT;
 			}
 		}
diff --git a/mail/em-subscription-editor.c b/mail/em-subscription-editor.c
index d92713f..6144ac5 100644
--- a/mail/em-subscription-editor.c
+++ b/mail/em-subscription-editor.c
@@ -25,14 +25,16 @@
 #include <string.h>
 #include <glib/gi18n-lib.h>
 
+#include <libedataserver/e-source-registry.h>
+
 #include "mail-tools.h"
 #include "mail-ops.h"
 #include "mail-mt.h"
 
 #include <e-util/e-util.h>
-#include <e-util/e-account-utils.h>
 #include <e-util/e-util-private.h>
 #include <e-util/gconf-bridge.h>
+#include <shell/e-shell.h>
 
 #include "em-folder-utils.h"
 
@@ -1495,19 +1497,26 @@ subscription_editor_constructed (GObject *object)
 	/* Pick an initial store based on the default mail account, if
 	 * one wasn't already given in em_subscription_editor_new(). */
 	if (editor->priv->initial_store == NULL) {
-		EAccount *account;
+		EShell *shell;
+		ESource *source;
+		ESourceRegistry *registry;
+		EShellBackend *shell_backend;
 		CamelService *service;
 		EMailBackend *backend;
 		EMailSession *session;
 
-		account = e_get_default_account ();
-
 		backend = em_subscription_editor_get_backend (editor);
 		session = e_mail_backend_get_session (backend);
 
+		shell_backend = E_SHELL_BACKEND (backend);
+		shell = e_shell_backend_get_shell (shell_backend);
+		registry = e_shell_get_registry (shell);
+
+		source = e_source_registry_get_default_mail_account (registry);
+
 		service = camel_session_get_service (
 			CAMEL_SESSION (session),
-			account->uid);
+			e_source_get_uid (source));
 
 		if (CAMEL_IS_SUBSCRIBABLE (service))
 			editor->priv->initial_store = g_object_ref (service);
diff --git a/mail/em-utils.c b/mail/em-utils.c
index 399e512..c72a6ef 100644
--- a/mail/em-utils.c
+++ b/mail/em-utils.c
@@ -55,13 +55,18 @@
 #include "mail-tools.h"
 #include "e-mail-tag-editor.h"
 
+#include <libebook/e-source-address-book.h>
+#include <libedataserver/e-source-autocomplete.h>
+#include <libedataserver/e-source-mail-account.h>
+#include <libedataserver/e-source-mail-composition.h>
+#include <libedataserver/e-source-mail-identity.h>
+#include <libedataserver/e-source-mail-submission.h>
 #include <libedataserver/e-data-server-util.h>
 #include <libedataserver/e-flag.h>
 #include <libedataserver/e-proxy.h>
 #include "e-util/e-util.h"
 #include "e-util/e-util-private.h"
 #include "e-util/e-mktemp.h"
-#include "e-util/e-account-utils.h"
 #include "e-util/e-dialog-utils.h"
 #include "e-util/e-alert-dialog.h"
 #include "shell/e-shell.h"
@@ -219,33 +224,6 @@ em_utils_uids_free (GPtrArray *uids)
 	g_ptr_array_free (uids, TRUE);
 }
 
-/**
- * em_utils_check_user_can_send_mail:
- *
- * Returns %TRUE if the user has an account configured (to send mail)
- * or %FALSE otherwise.
- **/
-gboolean
-em_utils_check_user_can_send_mail (void)
-{
-	EAccountList *account_list;
-	EAccount *account;
-
-	account_list = e_get_account_list ();
-
-	if (e_list_length (E_LIST (account_list)) == 0)
-		return FALSE;
-
-	if (!(account = e_get_default_account ()))
-		return FALSE;
-
-	/* Check for a transport */
-	if (!account->transport->url)
-		return FALSE;
-
-	return TRUE;
-}
-
 /* Editing Filters/Search Folders... */
 
 static GtkWidget *filter_editor = NULL;
@@ -1005,6 +983,7 @@ em_utils_selection_get_urilist (GtkSelectionData *selection_data,
 
 /**
  * em_utils_folder_is_templates:
+ * @registry: an #ESourceRegistry
  * @folder: a #CamelFolder
  *
  * Decides if @folder is a Templates folder.
@@ -1013,15 +992,16 @@ em_utils_selection_get_urilist (GtkSelectionData *selection_data,
  **/
 
 gboolean
-em_utils_folder_is_templates (CamelFolder *folder)
+em_utils_folder_is_templates (ESourceRegistry *registry,
+                              CamelFolder *folder)
 {
 	CamelFolder *local_templates_folder;
 	CamelSession *session;
 	CamelStore *store;
-	EAccountList *account_list;
-	EIterator *iterator;
+	GList *list, *iter;
 	gchar *folder_uri;
 	gboolean is_templates = FALSE;
+	const gchar *extension_name;
 
 	g_return_val_if_fail (CAMEL_IS_FOLDER (folder), FALSE);
 
@@ -1036,24 +1016,29 @@ em_utils_folder_is_templates (CamelFolder *folder)
 	store = camel_folder_get_parent_store (folder);
 	session = camel_service_get_session (CAMEL_SERVICE (store));
 
-	account_list = e_get_account_list ();
-	iterator = e_list_get_iterator (E_LIST (account_list));
+	extension_name = E_SOURCE_EXTENSION_MAIL_COMPOSITION;
+	list = e_source_registry_list_sources (registry, extension_name);
+
+	for (iter = list; iter != NULL; iter = g_list_next (iter)) {
+		ESource *source = E_SOURCE (iter->data);
+		ESourceExtension *extension;
+		const gchar *templates_folder_uri;
 
-	while (!is_templates && e_iterator_is_valid (iterator)) {
-		EAccount *account;
+		extension = e_source_get_extension (source, extension_name);
 
-		/* XXX EIterator misuses const. */
-		account = (EAccount *) e_iterator_get (iterator);
+		templates_folder_uri =
+			e_source_mail_composition_get_templates_folder (
+			E_SOURCE_MAIL_COMPOSITION (extension));
 
-		if (account->templates_folder_uri != NULL)
+		if (templates_folder_uri != NULL)
 			is_templates = e_mail_folder_uri_equal (
-				session, folder_uri,
-				account->templates_folder_uri);
+				session, folder_uri, templates_folder_uri);
 
-		e_iterator_next (iterator);
+		if (is_templates)
+			break;
 	}
 
-	g_object_unref (iterator);
+	g_list_free (list);
 	g_free (folder_uri);
 
 	return is_templates;
@@ -1061,6 +1046,7 @@ em_utils_folder_is_templates (CamelFolder *folder)
 
 /**
  * em_utils_folder_is_drafts:
+ * @registry: an #ESourceRegistry
  * @folder: a #CamelFolder
  *
  * Decides if @folder is a Drafts folder.
@@ -1068,15 +1054,16 @@ em_utils_folder_is_templates (CamelFolder *folder)
  * Returns %TRUE if this is a Drafts folder or %FALSE otherwise.
  **/
 gboolean
-em_utils_folder_is_drafts (CamelFolder *folder)
+em_utils_folder_is_drafts (ESourceRegistry *registry,
+                           CamelFolder *folder)
 {
 	CamelFolder *local_drafts_folder;
 	CamelSession *session;
 	CamelStore *store;
-	EAccountList *account_list;
-	EIterator *iterator;
+	GList *list, *iter;
 	gchar *folder_uri;
 	gboolean is_drafts = FALSE;
+	const gchar *extension_name;
 
 	g_return_val_if_fail (CAMEL_IS_FOLDER (folder), FALSE);
 
@@ -1091,24 +1078,29 @@ em_utils_folder_is_drafts (CamelFolder *folder)
 	store = camel_folder_get_parent_store (folder);
 	session = camel_service_get_session (CAMEL_SERVICE (store));
 
-	account_list = e_get_account_list ();
-	iterator = e_list_get_iterator (E_LIST (account_list));
+	extension_name = E_SOURCE_EXTENSION_MAIL_COMPOSITION;
+	list = e_source_registry_list_sources (registry, extension_name);
+
+	for (iter = list; iter != NULL; iter = g_list_next (iter)) {
+		ESource *source = E_SOURCE (iter->data);
+		ESourceExtension *extension;
+		const gchar *drafts_folder_uri;
 
-	while (!is_drafts && e_iterator_is_valid (iterator)) {
-		EAccount *account;
+		extension = e_source_get_extension (source, extension_name);
 
-		/* XXX EIterator misuses const. */
-		account = (EAccount *) e_iterator_get (iterator);
+		drafts_folder_uri =
+			e_source_mail_composition_get_drafts_folder (
+			E_SOURCE_MAIL_COMPOSITION (extension));
 
-		if (account->drafts_folder_uri != NULL)
+		if (drafts_folder_uri != NULL)
 			is_drafts = e_mail_folder_uri_equal (
-				session, folder_uri,
-				account->drafts_folder_uri);
+				session, folder_uri, drafts_folder_uri);
 
-		e_iterator_next (iterator);
+		if (is_drafts)
+			break;
 	}
 
-	g_object_unref (iterator);
+	g_list_free (list);
 	g_free (folder_uri);
 
 	return is_drafts;
@@ -1116,6 +1108,7 @@ em_utils_folder_is_drafts (CamelFolder *folder)
 
 /**
  * em_utils_folder_is_sent:
+ * @registry: an #ESourceRegistry
  * @folder: a #CamelFolder
  *
  * Decides if @folder is a Sent folder.
@@ -1123,15 +1116,16 @@ em_utils_folder_is_drafts (CamelFolder *folder)
  * Returns %TRUE if this is a Sent folder or %FALSE otherwise.
  **/
 gboolean
-em_utils_folder_is_sent (CamelFolder *folder)
+em_utils_folder_is_sent (ESourceRegistry *registry,
+                         CamelFolder *folder)
 {
 	CamelFolder *local_sent_folder;
 	CamelSession *session;
 	CamelStore *store;
-	EAccountList *account_list;
-	EIterator *iterator;
+	GList *list, *iter;
 	gchar *folder_uri;
 	gboolean is_sent = FALSE;
+	const gchar *extension_name;
 
 	g_return_val_if_fail (CAMEL_IS_FOLDER (folder), FALSE);
 
@@ -1146,24 +1140,29 @@ em_utils_folder_is_sent (CamelFolder *folder)
 	store = camel_folder_get_parent_store (folder);
 	session = camel_service_get_session (CAMEL_SERVICE (store));
 
-	account_list = e_get_account_list ();
-	iterator = e_list_get_iterator (E_LIST (account_list));
+	extension_name = E_SOURCE_EXTENSION_MAIL_SUBMISSION;
+	list = e_source_registry_list_sources (registry, extension_name);
+
+	for (iter = list; iter != NULL; iter = g_list_next (iter)) {
+		ESource *source = E_SOURCE (iter->data);
+		ESourceExtension *extension;
+		const gchar *sent_folder_uri;
 
-	while (!is_sent && e_iterator_is_valid (iterator)) {
-		EAccount *account;
+		extension = e_source_get_extension (source, extension_name);
 
-		/* XXX EIterator misuses const. */
-		account = (EAccount *) e_iterator_get (iterator);
+		sent_folder_uri =
+			e_source_mail_submission_get_sent_folder (
+			E_SOURCE_MAIL_SUBMISSION (extension));
 
-		if (account->sent_folder_uri != NULL)
+		if (sent_folder_uri != NULL)
 			is_sent = e_mail_folder_uri_equal (
-				session, folder_uri,
-				account->sent_folder_uri);
+				session, folder_uri, sent_folder_uri);
 
-		e_iterator_next (iterator);
+		if (is_sent)
+			break;
 	}
 
-	g_object_unref (iterator);
+	g_list_free (list);
 	g_free (folder_uri);
 
 	return is_sent;
@@ -1171,6 +1170,7 @@ em_utils_folder_is_sent (CamelFolder *folder)
 
 /**
  * em_utils_folder_is_outbox:
+ * @registry: an #ESourceRegistry
  * @folder: a #CamelFolder
  *
  * Decides if @folder is an Outbox folder.
@@ -1178,7 +1178,8 @@ em_utils_folder_is_sent (CamelFolder *folder)
  * Returns %TRUE if this is an Outbox folder or %FALSE otherwise.
  **/
 gboolean
-em_utils_folder_is_outbox (CamelFolder *folder)
+em_utils_folder_is_outbox (ESourceRegistry *registry,
+                           CamelFolder *folder)
 {
 	CamelFolder *local_outbox_folder;
 
@@ -1325,10 +1326,17 @@ em_utils_empty_trash (GtkWidget *parent,
                       EMailBackend *backend)
 {
 	EMailSession *session;
+	ESourceRegistry *registry;
+	EShellBackend *shell_backend;
+	EShell *shell;
 	GList *list, *iter;
 
 	g_return_if_fail (E_IS_MAIL_BACKEND (backend));
 
+	shell_backend = E_SHELL_BACKEND (backend);
+	shell = e_shell_backend_get_shell (shell_backend);
+	registry = e_shell_get_registry (shell);
+
 	if (!em_utils_prompt_user ((GtkWindow *) parent,
 		"/apps/evolution/mail/prompts/empty_trash",
 		"mail:ask-empty-trash", NULL))
@@ -1338,9 +1346,9 @@ em_utils_empty_trash (GtkWidget *parent,
 	list = camel_session_list_services (CAMEL_SESSION (session));
 
 	for (iter = list; iter != NULL; iter = g_list_next (iter)) {
-		EAccount *account;
 		CamelProvider *provider;
 		CamelService *service;
+		ESource *source;
 		const gchar *uid;
 
 		service = CAMEL_SERVICE (iter->data);
@@ -1353,14 +1361,10 @@ em_utils_empty_trash (GtkWidget *parent,
 		if ((provider->flags & CAMEL_PROVIDER_IS_STORAGE) == 0)
 			continue;
 
-		account = e_get_account_by_uid (uid);
+		source = e_source_registry_lookup_by_uid (registry, uid);
 
-		/* The local store has no corresponding
-		 * EAccount, so skip the enabled check. */
-		if (account != NULL) {
-			if (!account->enabled)
-				continue;
-		}
+		if (source != NULL && !e_source_get_enabled (source))
+			continue;
 
 		mail_empty_trash (backend, CAMEL_STORE (service));
 	}
@@ -1370,19 +1374,6 @@ em_utils_empty_trash (GtkWidget *parent,
 
 /* ********************************************************************** */
 
-/* runs sync, in main thread */
-static gpointer
-emu_addr_setup (gpointer user_data)
-{
-	GError *err = NULL;
-	ESourceList **psource_list = user_data;
-
-	if (!e_book_client_get_sources (psource_list, &err))
-		g_error_free (err);
-
-	return NULL;
-}
-
 static void
 emu_addr_cancel_stop (gpointer data)
 {
@@ -1498,8 +1489,6 @@ static GHashTable *emu_books_hash = NULL;
  * broken books, which failed to open for some reason */
 static GHashTable *emu_broken_books_hash = NULL;
 
-static ESourceList *emu_books_source_list = NULL;
-
 static gboolean
 search_address_in_addressbooks (const gchar *address,
                                 gboolean local_only,
@@ -1507,24 +1496,25 @@ search_address_in_addressbooks (const gchar *address,
                                                            gpointer user_data),
                                 gpointer user_data)
 {
+	EShell *shell;
+	ESourceRegistry *registry;
+	GList *list, *link;
+	GList *addr_sources = NULL;
 	gboolean found = FALSE, stop = FALSE, found_any = FALSE;
 	gchar *lowercase_addr;
 	gpointer ptr;
 	EBookQuery *book_query;
 	gchar *query;
-	GSList *s, *g, *addr_sources = NULL;
 	GHook *hook_cancellable;
 	GCancellable *cancellable;
+	const gchar *extension_name;
 
 	if (!address || !*address)
 		return FALSE;
 
 	G_LOCK (contact_cache);
 
-	if (!emu_books_source_list) {
-		mail_call_main (
-			MAIL_CALL_p_p, (MailMainFunc)
-			emu_addr_setup, &emu_books_source_list);
+	if (emu_books_hash == NULL) {
 		emu_books_hash = g_hash_table_new_full (
 			g_str_hash, g_str_equal, g_free, g_object_unref);
 		emu_broken_books_hash = g_hash_table_new_full (
@@ -1533,11 +1523,6 @@ search_address_in_addressbooks (const gchar *address,
 			g_str_hash, g_str_equal, g_free, NULL);
 	}
 
-	if (!emu_books_source_list) {
-		G_UNLOCK (contact_cache);
-		return FALSE;
-	}
-
 	lowercase_addr = g_utf8_strdown (address, -1);
 	ptr = g_hash_table_lookup (contact_cache, lowercase_addr);
 	if (ptr != NULL && (check_contact == NULL || ptr == NOT_FOUND_BOOK)) {
@@ -1550,44 +1535,60 @@ search_address_in_addressbooks (const gchar *address,
 	query = e_book_query_to_string (book_query);
 	e_book_query_unref (book_query);
 
-	for (g = e_source_list_peek_groups (emu_books_source_list);
-			g; g = g_slist_next (g)) {
-		ESourceGroup *group = g->data;
+	/* FIXME: Pass the ESourceRegistry in. */
+	shell = e_shell_get_default ();
+	registry = e_shell_get_registry (shell);
+	extension_name = E_SOURCE_EXTENSION_ADDRESS_BOOK;
+	list = e_source_registry_list_sources (registry, extension_name);
 
-		if (!group)
-			continue;
+	for (link = list; link != NULL; link = g_list_next (link)) {
+		ESource *source = E_SOURCE (link->data);
+		ESourceExtension *extension;
+		const gchar *backend_name;
+		gboolean source_is_local;
+		gboolean autocomplete;
+
+		backend_name = e_source_get_backend_name (source);
+		source_is_local = (g_strcmp0 (backend_name, "local") == 0);
 
-		if (local_only && !(e_source_group_peek_base_uri (group) &&
-			g_str_has_prefix (
-			e_source_group_peek_base_uri (group), "local:")))
+		if (local_only && !source_is_local)
 			continue;
 
-		for (s = e_source_group_peek_sources (group); s; s = g_slist_next (s)) {
-			ESource *source = s->data;
-			const gchar *completion = e_source_get_property (source, "completion");
+		extension_name = E_SOURCE_EXTENSION_AUTOCOMPLETE;
+		extension = e_source_get_extension (source, extension_name);
 
-			if (completion && g_ascii_strcasecmp (completion, "true") == 0) {
-				addr_sources = g_slist_prepend (addr_sources, g_object_ref (source));
-			}
-		}
+		autocomplete = e_source_autocomplete_get_include_me (
+			E_SOURCE_AUTOCOMPLETE (extension));
+
+		if (!autocomplete)
+			continue;
+
+		addr_sources = g_list_prepend (
+			addr_sources, g_object_ref (source));
 	}
 
+	g_list_free (list);
+
 	cancellable = g_cancellable_new ();
 	hook_cancellable = mail_cancel_hook_add (emu_addr_cancel_cancellable, cancellable);
 
-	for (s = addr_sources; !stop && !found && s; s = g_slist_next (s)) {
-		ESource *source = s->data;
+	for (link = addr_sources; !stop && !found && link != NULL; link = g_list_next (link)) {
+		ESource *source = E_SOURCE (link->data);
 		GSList *contacts;
 		EBookClient *book_client = NULL;
 		GHook *hook_stop;
 		gboolean cached_book = FALSE;
 		GError *err = NULL;
+		const gchar *display_name;
+		const gchar *uid;
+
+		uid = e_source_get_uid (source);
+		display_name = e_source_get_display_name (source);
 
 		/* failed to load this book last time, skip it now */
-		if (g_hash_table_lookup (emu_broken_books_hash,
-				e_source_peek_uid (source)) != NULL) {
+		if (g_hash_table_lookup (emu_broken_books_hash, uid) != NULL) {
 			d(printf ("%s: skipping broken book '%s'\n",
-				G_STRFUNC, e_source_peek_name (source)));
+				G_STRFUNC, display_name));
 			continue;
 		}
 
@@ -1595,7 +1596,7 @@ search_address_in_addressbooks (const gchar *address,
 
 		hook_stop = mail_cancel_hook_add (emu_addr_cancel_stop, &stop);
 
-		book_client = g_hash_table_lookup (emu_books_hash, e_source_peek_uid (source));
+		book_client = g_hash_table_lookup (emu_books_hash, uid);
 		if (!book_client) {
 			book_client = e_book_client_new (source, &err);
 
@@ -1606,8 +1607,7 @@ search_address_in_addressbooks (const gchar *address,
 				} else if (err) {
 					gchar *source_uid;
 
-					source_uid = g_strdup (
-						e_source_peek_uid (source));
+					source_uid = g_strdup (uid);
 
 					g_hash_table_insert (
 						emu_broken_books_hash,
@@ -1616,7 +1616,7 @@ search_address_in_addressbooks (const gchar *address,
 					g_warning (
 						"%s: Unable to create addressbook '%s': %s",
 						G_STRFUNC,
-						e_source_peek_name (source),
+						display_name,
 						err->message);
 				}
 				g_clear_error (&err);
@@ -1630,8 +1630,7 @@ search_address_in_addressbooks (const gchar *address,
 				} else if (err) {
 					gchar *source_uid;
 
-					source_uid = g_strdup (
-						e_source_peek_uid (source));
+					source_uid = g_strdup (uid);
 
 					g_hash_table_insert (
 						emu_broken_books_hash,
@@ -1640,7 +1639,7 @@ search_address_in_addressbooks (const gchar *address,
 					g_warning (
 						"%s: Unable to open addressbook '%s': %s",
 						G_STRFUNC,
-						e_source_peek_name (source),
+						display_name,
 						err->message);
 				}
 				g_clear_error (&err);
@@ -1676,13 +1675,14 @@ search_address_in_addressbooks (const gchar *address,
 			    (g_error_matches (err, E_CLIENT_ERROR, E_CLIENT_ERROR_CANCELLED) ||
 			     g_error_matches (err, G_IO_ERROR, G_IO_ERROR_CANCELLED)));
 			if (err && !stop) {
-				gchar *source_uid = g_strdup (e_source_peek_uid (source));
+				gchar *source_uid = g_strdup (uid);
 
 				g_hash_table_insert (emu_broken_books_hash, source_uid, source_uid);
 
 				g_warning (
 					"%s: Can't get contacts from '%s': %s",
-					G_STRFUNC, e_source_peek_name (source),
+					G_STRFUNC,
+					display_name,
 					err->message);
 			}
 			g_clear_error (&err);
@@ -1694,16 +1694,14 @@ search_address_in_addressbooks (const gchar *address,
 			g_object_unref (book_client);
 		} else if (!stop && book_client && !cached_book) {
 			g_hash_table_insert (
-				emu_books_hash, g_strdup (
-				e_source_peek_uid (source)), book_client);
+				emu_books_hash, g_strdup (uid), book_client);
 		}
 	}
 
 	mail_cancel_hook_remove (hook_cancellable);
 	g_object_unref (cancellable);
 
-	g_slist_foreach (addr_sources, (GFunc) g_object_unref, NULL);
-	g_slist_free (addr_sources);
+	g_list_free_full (addr_sources, (GDestroyNotify) g_object_unref);
 
 	g_free (query);
 
@@ -1920,11 +1918,6 @@ emu_free_mail_cache (void)
 		emu_broken_books_hash = NULL;
 	}
 
-	if (emu_books_source_list) {
-		g_object_unref (emu_books_source_list);
-		emu_books_source_list = NULL;
-	}
-
 	if (contact_cache) {
 		g_hash_table_destroy (contact_cache);
 		contact_cache = NULL;
@@ -1943,29 +1936,6 @@ emu_free_mail_cache (void)
 	free_account_sort_order_cache ();
 }
 
-void
-em_utils_clear_get_password_canceled_accounts_flag (void)
-{
-	EAccountList *account_list;
-	EIterator *iterator;
-
-	account_list = e_get_account_list ();
-
-	for (iterator = e_list_get_iterator (E_LIST (account_list));
-	     e_iterator_is_valid (iterator);
-	     e_iterator_next (iterator)) {
-		EAccount *account = (EAccount *) e_iterator_get (iterator);
-
-		if (account && account->source)
-			account->source->get_password_canceled = FALSE;
-
-		if (account && account->transport)
-			account->transport->get_password_canceled = FALSE;
-	}
-
-	g_object_unref (iterator);
-}
-
 gchar *
 em_utils_url_unescape_amp (const gchar *url)
 {
@@ -1997,128 +1967,255 @@ em_utils_url_unescape_amp (const gchar *url)
 	return buff;
 }
 
-static EAccount *
-guess_account_from_folder (CamelFolder *folder)
+static ESource *
+guess_mail_account_from_folder (ESourceRegistry *registry,
+                                CamelFolder *folder)
 {
+	ESource *source;
 	CamelStore *store;
 	const gchar *uid;
 
+	/* Lookup an ESource by CamelStore UID. */
 	store = camel_folder_get_parent_store (folder);
 	uid = camel_service_get_uid (CAMEL_SERVICE (store));
+	source = e_source_registry_lookup_by_uid (registry, uid);
+
+	/* If we found an ESource, make sure it's a mail account. */
+	if (source != NULL) {
+		const gchar *extension_name;
+
+		extension_name = E_SOURCE_EXTENSION_MAIL_ACCOUNT;
+		if (!e_source_has_extension (source, extension_name))
+			source = NULL;
+	}
 
-	return e_get_account_by_uid (uid);
+	return source;
 }
 
-static EAccount *
-guess_account_from_message (CamelMimeMessage *message)
+static ESource *
+guess_mail_account_from_message (ESourceRegistry *registry,
+                                 CamelMimeMessage *message)
 {
+	ESource *source = NULL;
 	const gchar *uid;
 
+	/* Lookup an ESource by 'X-Evolution-Source' header. */
 	uid = camel_mime_message_get_source (message);
+	if (uid != NULL)
+		source = e_source_registry_lookup_by_uid (registry, uid);
+
+	/* If we found an ESource, make sure it's a mail account. */
+	if (source != NULL) {
+		const gchar *extension_name;
+
+		extension_name = E_SOURCE_EXTENSION_MAIL_ACCOUNT;
+		if (!e_source_has_extension (source, extension_name))
+			source = NULL;
+	}
 
-	return (uid != NULL) ? e_get_account_by_uid (uid) : NULL;
+	return source;
 }
 
 GHashTable *
-em_utils_generate_account_hash (void)
+em_utils_generate_account_hash (ESourceRegistry *registry)
 {
 	GHashTable *account_hash;
-	EAccount *account, *def;
-	EAccountList *account_list;
-	EIterator *iterator;
-
-	account_list = e_get_account_list ();
-	account_hash = g_hash_table_new (camel_strcase_hash, camel_strcase_equal);
-
-	def = e_get_default_account ();
-
-	iterator = e_list_get_iterator (E_LIST (account_list));
-
-	while (e_iterator_is_valid (iterator)) {
-		account = (EAccount *) e_iterator_get (iterator);
-
-		if (account->id->address) {
-			EAccount *acnt;
-
-			/* Accounts with identical email addresses that are
-			 * enabled take precedence over the accounts that
-			 * aren't. If all accounts with matching email
-			 * addresses are disabled, then the first one in
-			 * the list takes precedence. The default account
-			 * always takes precedence no matter what. */
-			acnt = g_hash_table_lookup (
-				account_hash, account->id->address);
-			if (acnt && acnt != def && !acnt->enabled && account->enabled) {
-				g_hash_table_remove (
-					account_hash, acnt->id->address);
-				acnt = NULL;
-			}
+	ESource *default_source;
+	GList *list, *link;
+	const gchar *extension_name;
+
+	g_return_val_if_fail (E_IS_SOURCE_REGISTRY (registry), NULL);
+
+	account_hash = g_hash_table_new_full (
+		(GHashFunc) camel_strcase_hash,
+		(GEqualFunc) camel_strcase_equal,
+		(GDestroyNotify) g_free,
+		(GDestroyNotify) g_object_unref);
+
+	default_source = e_source_registry_get_default_mail_account (registry);
+
+	extension_name = E_SOURCE_EXTENSION_MAIL_ACCOUNT;
+	list = e_source_registry_list_sources (registry, extension_name);
+
+	for (link = list; link != NULL; link = g_list_next (link)) {
+		ESource *source = E_SOURCE (link->data);
+		ESource *cached_source;
+		ESource *identity_source;
+		ESourceExtension *extension;
+		const gchar *address;
+		gboolean insert_source;
+		gboolean cached_is_default;
+		gboolean cached_is_enabled;
+		gboolean source_is_default;
+		gboolean source_is_enabled;
 
-			if (!acnt)
-				g_hash_table_insert (
-					account_hash, (gchar *)
-					account->id->address,
-					(gpointer) account);
+		source_is_default = e_source_equal (source, default_source);
+		source_is_enabled = e_source_get_enabled (source);
+
+		extension_name = E_SOURCE_EXTENSION_MAIL_ACCOUNT;
+		extension = e_source_get_extension (source, extension_name);
+
+		identity_source = e_source_mail_account_get_identity (
+			E_SOURCE_MAIL_ACCOUNT (extension));
+
+		if (identity_source == NULL)
+			continue;
+
+		extension_name = E_SOURCE_EXTENSION_MAIL_IDENTITY;
+		extension = e_source_get_extension (
+			identity_source, extension_name);
+
+		address = e_source_mail_identity_get_address (
+			E_SOURCE_MAIL_IDENTITY (extension));
+
+		if (address == NULL)
+			continue;
+
+		cached_source = g_hash_table_lookup (account_hash, address);
+
+		if (cached_source != NULL) {
+			cached_is_default = e_source_equal (
+				cached_source, default_source);
+			cached_is_enabled =
+				e_source_get_enabled (cached_source);
+		} else {
+			cached_is_default = FALSE;
+			cached_is_enabled = FALSE;
 		}
 
-		e_iterator_next (iterator);
+		/* Accounts with identical email addresses that are enabled
+		 * take precedence over disabled accounts.  If all accounts
+		 * with matching email addresses are disabled, the first
+		 * one in the list takes precedence.  The default account
+		 * always takes precedence no matter what. */
+		insert_source =
+			source_is_default ||
+			cached_source == NULL ||
+			(source_is_enabled &&
+			 !cached_is_enabled &&
+			 !cached_is_default);
+
+		if (insert_source)
+			g_hash_table_insert (
+				account_hash,
+				g_strdup (address),
+				g_object_ref (source));
 	}
 
-	g_object_unref (iterator);
-
-	/* The default account has to be there if none
-	 * of the enabled accounts are present. */
-	if (g_hash_table_size (account_hash) == 0 && def && def->id->address)
-		g_hash_table_insert (
-			account_hash, (gchar *)
-			def->id->address,
-			(gpointer) def);
+	g_list_free (list);
 
 	return account_hash;
 }
 
-EAccount *
-em_utils_guess_account (CamelMimeMessage *message,
-                        CamelFolder *folder)
+ESource *
+em_utils_guess_mail_account (ESourceRegistry *registry,
+                             CamelMimeMessage *message,
+                             CamelFolder *folder)
 {
-	EAccount *account = NULL;
+	ESource *source = NULL;
+	const gchar *newsgroups;
 
+	g_return_val_if_fail (E_IS_SOURCE_REGISTRY (registry), NULL);
 	g_return_val_if_fail (CAMEL_IS_MIME_MESSAGE (message), NULL);
 
 	if (folder != NULL)
 		g_return_val_if_fail (CAMEL_IS_FOLDER (folder), NULL);
 
 	/* check for newsgroup header */
-	if (folder != NULL
-	    && camel_medium_get_header (CAMEL_MEDIUM (message), "Newsgroups"))
-		account = guess_account_from_folder (folder);
+	newsgroups = camel_medium_get_header (
+		CAMEL_MEDIUM (message), "Newsgroups");
+	if (folder != NULL && newsgroups != NULL)
+		source = guess_mail_account_from_folder (registry, folder);
 
 	/* check for source folder */
-	if (account == NULL && folder != NULL)
-		account = guess_account_from_folder (folder);
+	if (source == NULL && folder != NULL)
+		source = guess_mail_account_from_folder (registry, folder);
 
 	/* then message source */
-	if (account == NULL)
-		account = guess_account_from_message (message);
+	if (source == NULL)
+		source = guess_mail_account_from_message (registry, message);
+
+	return source;
+}
+
+ESource *
+em_utils_guess_mail_identity (ESourceRegistry *registry,
+                              CamelMimeMessage *message,
+                              CamelFolder *folder)
+{
+	ESource *source;
+	ESourceExtension *extension;
+	const gchar *extension_name;
+
+	g_return_val_if_fail (E_IS_SOURCE_REGISTRY (registry), NULL);
+	g_return_val_if_fail (CAMEL_IS_MIME_MESSAGE (message), NULL);
+
+	if (folder != NULL)
+		g_return_val_if_fail (CAMEL_IS_FOLDER (folder), NULL);
+
+	source = em_utils_guess_mail_account (registry, message, folder);
+
+	if (source == NULL)
+		return NULL;
+
+	extension_name = E_SOURCE_EXTENSION_MAIL_ACCOUNT;
+	extension = e_source_get_extension (source, extension_name);
+
+	return e_source_mail_account_get_identity (
+		E_SOURCE_MAIL_ACCOUNT (extension));
+}
+
+static gboolean
+mail_account_in_recipients (ESourceRegistry *registry,
+                            ESource *source,
+                            GHashTable *recipients)
+{
+	ESourceExtension *extension;
+	const gchar *extension_name;
+	const gchar *address;
+
+	/* Disregard disabled mail accounts. */
+	if (!e_source_get_enabled (source))
+		return FALSE;
+
+	extension_name = E_SOURCE_EXTENSION_MAIL_ACCOUNT;
+	extension = e_source_get_extension (source, extension_name);
+
+	source = e_source_mail_account_get_identity (
+		E_SOURCE_MAIL_ACCOUNT (extension));
+
+	if (source == NULL)
+		return FALSE;
+
+	extension_name = E_SOURCE_EXTENSION_MAIL_IDENTITY;
+	extension = e_source_get_extension (source, extension_name);
 
-	return account;
+	address = e_source_mail_identity_get_address (
+		E_SOURCE_MAIL_IDENTITY (extension));
+
+	if (address == NULL)
+		return FALSE;
+
+	return (g_hash_table_lookup (recipients, address) != NULL);
 }
 
-EAccount *
-em_utils_guess_account_with_recipients (CamelMimeMessage *message,
-                                        CamelFolder *folder)
+ESource *
+em_utils_guess_mail_account_with_recipients (ESourceRegistry *registry,
+                                             CamelMimeMessage *message,
+                                             CamelFolder *folder)
 {
-	EAccount *account = NULL;
-	EAccountList *account_list;
+	ESource *source = NULL;
 	GHashTable *recipients;
-	EIterator *iterator;
 	CamelInternetAddress *addr;
+	GList *list, *iter;
+	const gchar *extension_name;
 	const gchar *type;
 	const gchar *key;
 
 	/* This policy is subject to debate and tweaking,
 	 * but please also document the rational here. */
 
+	g_return_val_if_fail (E_IS_SOURCE_REGISTRY (registry), NULL);
 	g_return_val_if_fail (CAMEL_IS_MIME_MESSAGE (message), NULL);
 
 	/* Build a set of email addresses in which to test for membership.
@@ -2148,53 +2245,128 @@ em_utils_guess_account_with_recipients (CamelMimeMessage *message,
 	}
 
 	/* First Preference: We were given a folder that maps to an
-	 * enabled account, and that account's email address appears
+	 * enabled mail account, and that account's address appears
 	 * in the list of To: or Cc: recipients. */
 
 	if (folder != NULL)
-		account = guess_account_from_folder (folder);
-
-	if (account == NULL || !account->enabled)
-		goto second_preference;
+		source = guess_mail_account_from_folder (registry, folder);
 
-	if ((key = account->id->address) == NULL)
+	if (source == NULL)
 		goto second_preference;
 
-	if (g_hash_table_lookup (recipients, key) != NULL)
+	if (mail_account_in_recipients (registry, source, recipients))
 		goto exit;
 
 second_preference:
 
-	/* Second Preference: Choose any enabled account whose email
+	/* Second Preference: Choose any enabled mail account whose
 	 * address appears in the list to To: or Cc: recipients. */
 
-	account_list = e_get_account_list ();
-	iterator = e_list_get_iterator (E_LIST (account_list));
-
-	while (e_iterator_is_valid (iterator)) {
-		account = (EAccount *) e_iterator_get (iterator);
-		e_iterator_next (iterator);
+	source = NULL;
 
-		if (account == NULL || !account->enabled)
-			continue;
+	extension_name = E_SOURCE_EXTENSION_MAIL_ACCOUNT;
+	list = e_source_registry_list_sources (registry, extension_name);
 
-		if ((key = account->id->address) == NULL)
-			continue;
+	for (iter = list; iter != NULL; iter = g_list_next (iter)) {
+		ESource *temp = E_SOURCE (iter->data);
 
-		if (g_hash_table_lookup (recipients, key) != NULL) {
-			g_object_unref (iterator);
-			goto exit;
+		if (mail_account_in_recipients (registry, temp, recipients)) {
+			source = temp;
+			break;
 		}
 	}
-	g_object_unref (iterator);
 
-	/* Last Preference: Defer to em_utils_guess_account(). */
-	account = em_utils_guess_account (message, folder);
+	g_list_free (list);
+
+	if (source != NULL)
+		goto exit;
+
+	/* Last Preference: Defer to em_utils_guess_mail_account(). */
+	source = em_utils_guess_mail_account (registry, message, folder);
 
 exit:
 	g_hash_table_destroy (recipients);
 
-	return account;
+	return source;
+}
+
+ESource *
+em_utils_guess_mail_identity_with_recipients (ESourceRegistry *registry,
+                                              CamelMimeMessage *message,
+                                              CamelFolder *folder)
+{
+	ESource *source;
+	ESourceExtension *extension;
+	const gchar *extension_name;
+
+	g_return_val_if_fail (E_IS_SOURCE_REGISTRY (registry), NULL);
+	g_return_val_if_fail (CAMEL_IS_MIME_MESSAGE (message), NULL);
+
+	source = em_utils_guess_mail_account_with_recipients (
+		registry, message, folder);
+
+	if (source == NULL)
+		return NULL;
+
+	extension_name = E_SOURCE_EXTENSION_MAIL_ACCOUNT;
+	extension = e_source_get_extension (source, extension_name);
+
+	return e_source_mail_account_get_identity (
+		E_SOURCE_MAIL_ACCOUNT (extension));
+}
+
+gboolean
+em_utils_mail_identity_is_enabled (ESourceRegistry *registry,
+                                   ESource *mail_identity_source)
+{
+	GList *list, *link;
+	const gchar *extension_name;
+	gboolean found_account = FALSE;
+	gboolean found_enabled_account = FALSE;
+
+	g_return_val_if_fail (E_IS_SOURCE_REGISTRY (registry), FALSE);
+
+	if (mail_identity_source == NULL)
+		return FALSE;
+
+	extension_name = E_SOURCE_EXTENSION_MAIL_IDENTITY;
+	if (!e_source_has_extension (mail_identity_source, extension_name))
+		return FALSE;
+
+	/* If any enabled account references the given identity, then
+	 * the identity is enabled.  If no accounts reference the given
+	 * identity, then the identity is assumed to be enabled.  So in
+	 * other words, an identity is disabled if and only if it is
+	 * referenced exclusively by disabled accounts. */
+
+	extension_name = E_SOURCE_EXTENSION_MAIL_ACCOUNT;
+	list = e_source_registry_list_sources (registry, extension_name);
+
+	for (link = list; link != NULL; link = g_list_next (link)) {
+		ESource *source = E_SOURCE (link->data);
+		ESourceMailAccount *extension;
+		gboolean enabled;
+
+		extension = e_source_get_extension (source, extension_name);
+
+		enabled = e_source_get_enabled (source);
+		source = e_source_mail_account_get_identity (extension);
+
+		if (source == NULL)
+			continue;
+
+		if (e_source_equal (source, mail_identity_source)) {
+			found_account = TRUE;
+			found_enabled_account |= enabled;
+		}
+
+		if (found_enabled_account)
+			break;
+	}
+
+	g_list_free (list);
+
+	return found_enabled_account || !found_account;
 }
 
 void
diff --git a/mail/em-utils.h b/mail/em-utils.h
index b07b74b..94bafda 100644
--- a/mail/em-utils.h
+++ b/mail/em-utils.h
@@ -27,6 +27,7 @@
 #include <sys/types.h>
 #include <camel/camel.h>
 #include <libedataserver/e-proxy.h>
+#include <libedataserver/e-source-registry.h>
 
 #include <mail/e-mail-reader.h>
 #include <mail/e-mail-session.h>
@@ -42,8 +43,6 @@ gboolean em_utils_prompt_user (GtkWindow *parent, const gchar *promptkey, const
 GPtrArray *em_utils_uids_copy (GPtrArray *uids);
 void em_utils_uids_free (GPtrArray *uids);
 
-gboolean em_utils_check_user_can_send_mail (void);
-
 void em_utils_edit_filters (GtkWidget *parent, EMailBackend *backend);
 void em_filename_make_safe (gchar *string);
 void em_utils_edit_vfolders (GtkWidget *parent);
@@ -62,10 +61,14 @@ void em_utils_selection_get_uidlist (GtkSelectionData *data, EMailSession *sessi
 void em_utils_selection_set_urilist (GtkSelectionData *data, CamelFolder *folder, GPtrArray *uids);
 void em_utils_selection_get_urilist (GtkSelectionData *data, CamelFolder *folder);
 
-gboolean	em_utils_folder_is_drafts	(CamelFolder *folder);
-gboolean	em_utils_folder_is_templates	(CamelFolder *folder);
-gboolean	em_utils_folder_is_sent		(CamelFolder *folder);
-gboolean	em_utils_folder_is_outbox	(CamelFolder *folder);
+gboolean	em_utils_folder_is_drafts	(ESourceRegistry *registry,
+						 CamelFolder *folder);
+gboolean	em_utils_folder_is_templates	(ESourceRegistry *registry,
+						 CamelFolder *folder);
+gboolean	em_utils_folder_is_sent		(ESourceRegistry *registry,
+						 CamelFolder *folder);
+gboolean	em_utils_folder_is_outbox	(ESourceRegistry *registry,
+						 CamelFolder *folder);
 
 EProxy *	em_utils_get_proxy		(void);
 
@@ -79,15 +82,27 @@ void em_utils_empty_trash (GtkWidget *parent, EMailBackend *backend);
 gboolean em_utils_in_addressbook (CamelInternetAddress *addr, gboolean local_only);
 CamelMimePart *em_utils_contact_photo (CamelInternetAddress *addr, gboolean local);
 
-/* clears flag 'get_password_canceled' at every known accounts, so if needed, get_password will show dialog */
-void em_utils_clear_get_password_canceled_accounts_flag (void);
-
 /* Unescapes &amp; back to a real & in URIs */
 gchar *em_utils_url_unescape_amp (const gchar *url);
 
-GHashTable * em_utils_generate_account_hash (void);
-struct _EAccount *em_utils_guess_account (CamelMimeMessage *message, CamelFolder *folder);
-struct _EAccount *em_utils_guess_account_with_recipients (CamelMimeMessage *message, CamelFolder *folder);
+GHashTable *	em_utils_generate_account_hash	(ESourceRegistry *registry);
+ESource *	em_utils_guess_mail_account	(ESourceRegistry *registry,
+						 CamelMimeMessage *message,
+						 CamelFolder *folder);
+ESource *	em_utils_guess_mail_account_with_recipients
+						(ESourceRegistry *registry,
+						 CamelMimeMessage *message,
+						 CamelFolder *folder);
+ESource *	em_utils_guess_mail_identity	(ESourceRegistry *registry,
+						 CamelMimeMessage *message,
+						 CamelFolder *folder);
+ESource *	em_utils_guess_mail_identity_with_recipients
+						(ESourceRegistry *registry,
+						 CamelMimeMessage *message,
+						 CamelFolder *folder);
+gboolean	em_utils_mail_identity_is_enabled
+						(ESourceRegistry *registry,
+						 ESource *mail_identity_source);
 
 void emu_remove_from_mail_cache (const GSList *addresses);
 void emu_remove_from_mail_cache_1 (const gchar *address);
diff --git a/mail/mail-config.c b/mail/mail-config.c
index 7356772..e81fd9b 100644
--- a/mail/mail-config.c
+++ b/mail/mail-config.c
@@ -28,13 +28,11 @@
 #endif
 
 #include <gtk/gtk.h>
+#include <gconf/gconf-client.h>
 
 #include <libedataserver/e-data-server-util.h>
-#include <e-util/e-util.h>
-#include "e-util/e-account-utils.h"
-#include "e-util/e-signature-utils.h"
 
-#include <gconf/gconf-client.h>
+#include <e-util/e-util.h>
 
 #include "e-mail-local.h"
 #include "e-mail-folder-utils.h"
@@ -159,27 +157,6 @@ gconf_int_value_changed (GConfClient *client,
 	}
 }
 
-void
-mail_config_write (void)
-{
-	GConfClient *client;
-	EAccountList *account_list;
-	ESignatureList *signature_list;
-
-	if (!config)
-		return;
-
-	account_list = e_get_account_list ();
-	signature_list = e_get_signature_list ();
-
-	e_account_list_save (account_list);
-	e_signature_list_save (signature_list);
-
-	client = gconf_client_get_default ();
-	gconf_client_suggest_sync (client, NULL);
-	g_object_unref (client);
-}
-
 gint
 mail_config_get_address_count (void)
 {
diff --git a/mail/mail-config.h b/mail/mail-config.h
index 2903809..c66630d 100644
--- a/mail/mail-config.h
+++ b/mail/mail-config.h
@@ -29,7 +29,6 @@ G_BEGIN_DECLS
 
 /* Configuration */
 void		mail_config_init		(EMailSession *session);
-void		mail_config_write		(void);
 
 /* General Accessor functions */
 
diff --git a/mail/mail-config.ui b/mail/mail-config.ui
index 55510b6..99bed0e 100644
--- a/mail/mail-config.ui
+++ b/mail/mail-config.ui
@@ -828,56 +828,6 @@ for display purposes only. </property>
             <property name="position">0</property>
           </packing>
         </child>
-        <child>
-          <object class="GtkVBox" id="signature-preview-section">
-            <property name="visible">True</property>
-            <property name="can_focus">False</property>
-            <property name="spacing">6</property>
-            <child>
-              <object class="GtkLabel" id="signature-preview-header">
-                <property name="visible">True</property>
-                <property name="can_focus">False</property>
-                <property name="xalign">0</property>
-                <property name="label" translatable="yes">Preview</property>
-                <attributes>
-                  <attribute name="weight" value="bold"/>
-                </attributes>
-              </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="fill">False</property>
-                <property name="position">0</property>
-              </packing>
-            </child>
-            <child>
-              <object class="GtkAlignment" id="signature-preview-alignment">
-                <property name="visible">True</property>
-                <property name="can_focus">False</property>
-                <property name="left_padding">12</property>
-                <child>
-                  <object class="GtkScrolledWindow" id="signature-preview-scrolled-window">
-                    <property name="visible">True</property>
-                    <property name="can_focus">True</property>
-                    <property name="shadow_type">in</property>
-                    <child>
-                      <placeholder/>
-                    </child>
-                  </object>
-                </child>
-              </object>
-              <packing>
-                <property name="expand">True</property>
-                <property name="fill">True</property>
-                <property name="position">1</property>
-              </packing>
-            </child>
-          </object>
-          <packing>
-            <property name="expand">True</property>
-            <property name="fill">True</property>
-            <property name="position">1</property>
-          </packing>
-        </child>
       </object>
       <packing>
         <property name="position">1</property>
diff --git a/mail/mail-folder-cache.c b/mail/mail-folder-cache.c
index 5dd215a..fe78c44 100644
--- a/mail/mail-folder-cache.c
+++ b/mail/mail-folder-cache.c
@@ -41,6 +41,7 @@
 #include <libedataserver/e-data-server-util.h>
 #include <e-util/e-marshal.h>
 #include <e-util/e-util.h>
+#include <shell/e-shell.h>
 
 #include "mail-mt.h"
 #include "mail-folder-cache.h"
@@ -255,11 +256,18 @@ update_1folder (MailFolderCache *self,
                 const gchar *msg_subject,
                 CamelFolderInfo *info)
 {
+	EShell *shell;
 	struct _folder_update *up;
+	ESourceRegistry *registry;
 	CamelFolder *folder;
 	gint unread = -1;
 	gint deleted;
 
+	/* FIXME MailFolderCache should store an EMailBackend
+	 *       so we can access the registry properly. */
+	shell = e_shell_get_default ();
+	registry = e_shell_get_registry (shell);
+
 	folder = mfi->folder;
 	if (folder) {
 		gboolean folder_is_sent;
@@ -268,9 +276,9 @@ update_1folder (MailFolderCache *self,
 		gboolean folder_is_vtrash;
 		gboolean special_case;
 
-		folder_is_sent = em_utils_folder_is_sent (folder);
-		folder_is_drafts = em_utils_folder_is_drafts (folder);
-		folder_is_outbox = em_utils_folder_is_outbox (folder);
+		folder_is_sent = em_utils_folder_is_sent (registry, folder);
+		folder_is_drafts = em_utils_folder_is_drafts (registry, folder);
+		folder_is_outbox = em_utils_folder_is_outbox (registry, folder);
 		folder_is_vtrash = CAMEL_IS_VTRASH_FOLDER (folder);
 
 		special_case =
diff --git a/mail/mail-ops.c b/mail/mail-ops.c
index 8bdb329..062a53b 100644
--- a/mail/mail-ops.c
+++ b/mail/mail-ops.c
@@ -35,7 +35,10 @@
 #include <glib/gi18n.h>
 
 #include <libedataserver/e-data-server-util.h>
-#include "e-util/e-account-utils.h"
+#include <libedataserver/e-source-mail-account.h>
+#include <libedataserver/e-source-mail-submission.h>
+
+#include <shell/e-shell.h>
 
 #include "em-filter-rule.h"
 #include "em-utils.h"
@@ -475,6 +478,49 @@ static void	report_status		(struct _send_queue_msg *m,
 					 const gchar *desc,
 					 ...);
 
+static gboolean
+get_submission_details_from_identity (EMailBackend *backend,
+                                      const gchar *identity_uid,
+                                      gchar **out_transport_uid,
+                                      gchar **out_sent_folder_uri)
+{
+	EShell *shell;
+	ESource *source;
+	ESourceRegistry *registry;
+	ESourceExtension *extension;
+	EShellBackend *shell_backend;
+	const gchar *extension_name;
+	const gchar *sent_folder_uri;
+	const gchar *transport_uid;
+
+	shell_backend = E_SHELL_BACKEND (backend);
+	shell = e_shell_backend_get_shell (shell_backend);
+	registry = e_shell_get_registry (shell);
+
+	extension_name = E_SOURCE_EXTENSION_MAIL_SUBMISSION;
+	source = e_source_registry_lookup_by_uid (registry, identity_uid);
+
+	if (source == NULL)
+		return FALSE;
+
+	if (!e_source_has_extension (source, extension_name))
+		return FALSE;
+
+	extension = e_source_get_extension (source, extension_name);
+
+	sent_folder_uri = e_source_mail_submission_get_sent_folder (
+		E_SOURCE_MAIL_SUBMISSION (extension));
+
+	transport_uid = e_source_mail_submission_get_transport_uid (
+		E_SOURCE_MAIL_SUBMISSION (extension));
+
+	*out_transport_uid = g_strdup (transport_uid);
+
+	*out_sent_folder_uri = g_strdup (sent_folder_uri);
+
+	return TRUE;
+}
+
 /* send 1 message to a specific transport */
 static void
 mail_send_message (struct _send_queue_msg *m,
@@ -485,12 +531,12 @@ mail_send_message (struct _send_queue_msg *m,
                    GCancellable *cancellable,
                    GError **error)
 {
-	EAccount *account = NULL;
+	CamelService *service;
 	EMailSession *session;
 	const CamelInternetAddress *iaddr;
 	CamelAddress *from, *recipients;
 	CamelMessageInfo *info = NULL;
-	CamelProvider *provider;
+	CamelProvider *provider = NULL;
 	gchar *transport_uid = NULL;
 	gchar *sent_folder_uri = NULL;
 	const gchar *resent_from, *tmp;
@@ -511,48 +557,33 @@ mail_send_message (struct _send_queue_msg *m,
 	err = g_string_new ("");
 	xev = mail_tool_remove_xevolution_headers (message);
 
-	session = e_mail_backend_get_session (m->backend);
-
-	tmp = camel_header_raw_find (&xev, "X-Evolution-Account", NULL);
+	tmp = camel_header_raw_find (&xev, "X-Evolution-Identity", NULL);
 	if (tmp != NULL) {
-		gchar *name;
-
-		name = g_strstrip (g_strdup (tmp));
-		if ((account = e_get_account_by_uid (name))
-		    /* 'old' x-evolution-account stored the name, how silly */
-		    || (account = e_get_account_by_name (name))) {
-			if (account->transport) {
-				CamelService *service;
-				gchar *transport_uid;
-
-				transport_uid = g_strconcat (
-					account->uid, "-transport", NULL);
-				service = camel_session_get_service (
-					CAMEL_SESSION (session),
-					transport_uid);
-				g_free (transport_uid);
-
-				if (CAMEL_IS_TRANSPORT (service))
-					transport = CAMEL_TRANSPORT (service);
-			}
+		gchar *identity_uid;
 
-			sent_folder_uri = g_strdup (account->sent_folder_uri);
-		}
-		g_free (name);
+		identity_uid = g_strstrip (g_strdup (tmp));
+		get_submission_details_from_identity (
+			m->backend, identity_uid,
+			&transport_uid, &sent_folder_uri);
+		g_free (identity_uid);
 	}
 
-	if (!account) {
-		/* default back to these headers */
-		tmp = camel_header_raw_find(&xev, "X-Evolution-Transport", NULL);
-		if (tmp)
-			transport_uid = g_strstrip (g_strdup (tmp));
+	tmp = camel_header_raw_find (&xev, "X-Evolution-Transport", NULL);
+	if (transport_uid == NULL && tmp != NULL)
+		transport_uid = g_strstrip (g_strdup (tmp));
 
-		tmp = camel_header_raw_find(&xev, "X-Evolution-Fcc", NULL);
-		if (tmp)
-			sent_folder_uri = g_strstrip (g_strdup (tmp));
-	}
+	tmp = camel_header_raw_find (&xev, "X-Evolution-Fcc", NULL);
+	if (sent_folder_uri == NULL && tmp != NULL)
+		sent_folder_uri = g_strstrip (g_strdup (tmp));
+
+	session = e_mail_backend_get_session (m->backend);
 
-	if (transport != NULL) {
+	service = camel_session_get_service (
+		CAMEL_SESSION (session), transport_uid);
+	if (service != NULL)
+		provider = camel_service_get_provider (service);
+
+	if (CAMEL_IS_TRANSPORT (service)) {
 		CamelURL *url;
 		gchar *url_string;
 		gchar *escaped;
@@ -590,12 +621,12 @@ mail_send_message (struct _send_queue_msg *m,
 
 	if (camel_address_length (recipients) > 0) {
 		if (!em_utils_connect_service_sync (
-			CAMEL_SERVICE (transport), cancellable, error))
+			service, cancellable, error))
 			goto exit;
 
 		if (!camel_transport_send_to_sync (
-			transport, message, from,
-			recipients, cancellable, error))
+			CAMEL_TRANSPORT (service), message,
+			from, recipients, cancellable, error))
 			goto exit;
 	}
 
@@ -646,8 +677,6 @@ mail_send_message (struct _send_queue_msg *m,
 		}
 	}
 
-	provider = camel_service_get_provider (CAMEL_SERVICE (transport));
-
 	if (provider == NULL
 	    || !(provider->flags & CAMEL_PROVIDER_DISABLE_SENT_FOLDER)) {
 		GError *local_error = NULL;
@@ -1333,16 +1362,23 @@ expunge_pop3_stores (CamelFolder *expunging,
                      GCancellable *cancellable,
                      GError **error)
 {
+	EShell *shell;
+	EShellBackend *shell_backend;
 	GHashTable *expunging_uids;
+	ESourceRegistry *registry;
 	EMailSession *session;
 	GPtrArray *uids;
-	EAccount *account;
-	EIterator *iter;
+	GList *list, *link;
+	const gchar *extension_name;
 	gboolean success = TRUE;
 	guint ii;
 
 	session = e_mail_backend_get_session (backend);
 
+	shell_backend = E_SHELL_BACKEND (backend);
+	shell = e_shell_backend_get_shell (shell_backend);
+	registry = e_shell_get_registry (shell);
+
 	uids = camel_folder_get_uids (expunging);
 
 	if (uids == NULL)
@@ -1402,55 +1438,74 @@ expunge_pop3_stores (CamelFolder *expunging,
 		return TRUE;
 	}
 
-	for (iter = e_list_get_iterator ((EList *) e_get_account_list ());
-	     e_iterator_is_valid (iter); e_iterator_next (iter)) {
-		account = (EAccount *) e_iterator_get (iter);
+	extension_name = E_SOURCE_EXTENSION_MAIL_ACCOUNT;
+	list = e_source_registry_list_sources (registry, extension_name);
 
-		if (account->enabled &&
-		    account->source && account->source->url &&
-		    g_str_has_prefix (account->source->url, "pop://")) {
-			CamelFolder *folder;
-			gboolean any_found = FALSE;
+	for (link = list; link != NULL; link = g_list_next (link)) {
+		ESource *source = E_SOURCE (link->data);
+		ESourceExtension *extension;
+		CamelFolder *folder;
+		CamelService *service;
+		const gchar *backend_name;
+		const gchar *source_uid;
+		gboolean any_found = FALSE;
+		gboolean enabled;
 
-			folder = e_mail_session_get_inbox_sync (
-				session, account->uid, cancellable, error);
+		source_uid = e_source_get_uid (source);
+		enabled = e_source_get_enabled (source);
+		backend_name = e_source_get_backend_name (source);
+		extension = e_source_get_extension (source, extension_name);
 
-			/* Abort the loop on error. */
-			if (folder == NULL) {
-				success = FALSE;
-				break;
-			}
+		if (!enabled || g_strcmp0 (backend_name, "pop") != 0)
+			continue;
 
-			uids = camel_folder_get_uids (folder);
-			if (uids) {
-				for (ii = 0; ii < uids->len; ii++) {
-					/* ensure the ID is from this account,
-					 * as it's generated by evolution */
-					const gchar *source_uid;
-
-					source_uid = g_hash_table_lookup (
-						expunging_uids, uids->pdata[ii]);
-					if (folder_is_from_source_uid (folder, source_uid)) {
-						any_found = TRUE;
-						camel_folder_delete_message (folder, uids->pdata[ii]);
-					}
-				}
-				camel_folder_free_uids (folder, uids);
-			}
+		service = camel_session_get_service (
+			CAMEL_SESSION (session), source_uid);
 
-			if (any_found)
-				success = camel_folder_synchronize_sync (folder, TRUE, cancellable, error);
+		folder = camel_store_get_inbox_folder_sync (
+			CAMEL_STORE (service), cancellable, error);
 
+		/* Abort the loop on error. */
+		if (folder == NULL) {
+			success = FALSE;
+			break;
+		}
+
+		uids = camel_folder_get_uids (folder);
+
+		if (uids == NULL) {
 			g_object_unref (folder);
+			continue;
+		}
 
-			/* Abort the loop on error. */
-			if (!success)
-				break;
+		for (ii = 0; ii < uids->len; ii++) {
+			/* ensure the ID is from this account,
+			 * as it's generated by evolution */
+			const gchar *source_uid;
+
+			source_uid = g_hash_table_lookup (
+				expunging_uids, uids->pdata[ii]);
+			if (folder_is_from_source_uid (folder, source_uid)) {
+				any_found = TRUE;
+				camel_folder_delete_message (
+					folder, uids->pdata[ii]);
+			}
 		}
+
+		camel_folder_free_uids (folder, uids);
+
+		if (any_found)
+			success = camel_folder_synchronize_sync (
+				folder, TRUE, cancellable, error);
+
+		g_object_unref (folder);
+
+		/* Abort the loop on error. */
+		if (!success)
+			break;
 	}
 
-	if (iter)
-		g_object_unref (iter);
+	g_list_free (list);
 
 	g_hash_table_destroy (expunging_uids);
 
diff --git a/mail/mail-send-recv.c b/mail/mail-send-recv.c
index 167b4fd..d3bb677 100644
--- a/mail/mail-send-recv.c
+++ b/mail/mail-send-recv.c
@@ -29,10 +29,7 @@
 
 #include <glib/gi18n.h>
 
-#include "libedataserver/e-account-list.h"
-
 #include "shell/e-shell.h"
-#include "e-util/e-account-utils.h"
 #include "e-util/gconf-bridge.h"
 
 #include "e-mail-folder-utils.h"
@@ -279,7 +276,9 @@ dialog_response (GtkDialog *gd,
 }
 
 static GStaticMutex status_lock = G_STATIC_MUTEX_INIT;
+#if 0  /* ACCOUNT_MGMT */
 static gchar *format_url (EAccount *account, const gchar *internal_url);
+#endif /* ACCOUNT_MGMT */
 
 static gint
 operation_status_timeout (gpointer data)
@@ -296,6 +295,7 @@ operation_status_timeout (gpointer data)
 			gtk_label_set_text (
 				GTK_LABEL (info->status_label),
 				info->what);
+#if 0  /* ACCOUNT_MGMT */
 		if (info->send_url && info->send_account_label) {
 			gchar *tmp = format_url (NULL, info->send_url);
 
@@ -308,6 +308,7 @@ operation_status_timeout (gpointer data)
 
 			g_free (tmp);
 		}
+#endif /* ACCOUNT_MGMT */
 
 		g_static_mutex_unlock (&status_lock);
 
@@ -353,6 +354,7 @@ operation_status (CamelOperation *op,
 	set_send_status (info, what, pc);
 }
 
+#if 0  /* ACCOUNT_MGMT */
 static gchar *
 format_url (EAccount *account,
             const gchar *internal_url)
@@ -395,6 +397,7 @@ format_url (EAccount *account,
 
 	return pretty_url;
 }
+#endif /* ACCOUNT_MGMT */
 
 static send_info_t
 get_receive_type (CamelURL *url)
@@ -423,6 +426,7 @@ get_receive_type (CamelURL *url)
 	return SEND_INVALID;
 }
 
+#if 0  /* ACCOUNT_MGMT */
 static struct _send_data *
 build_dialog (GtkWindow *parent,
               EMailBackend *backend,
@@ -735,6 +739,7 @@ build_dialog (GtkWindow *parent,
 
 	return data;
 }
+#endif /* ACCOUNT_MGMT */
 
 static void
 update_folders (gchar *uri,
@@ -802,9 +807,9 @@ receive_done (gpointer data)
 
 	/* if we've been called to run again - run again */
 	if (info->type == SEND_SEND && info->state == SEND_ACTIVE && info->again) {
-		EMailSession *session;
 		CamelFolder *local_outbox;
 		CamelService *service;
+		EMailSession *session;
 
 		session = e_mail_backend_get_session (info->backend);
 
@@ -1085,7 +1090,7 @@ receive_update_got_store (CamelStore *store,
 	session = e_mail_backend_get_session (info->backend);
 	folder_cache = e_mail_session_get_folder_cache (session);
 
-	if (store) {
+	if (store != NULL) {
 		mail_folder_cache_note_store (
 			folder_cache,
 			CAMEL_SESSION (session),
@@ -1101,6 +1106,7 @@ send_receive (GtkWindow *parent,
               EMailBackend *backend,
               gboolean allow_send)
 {
+#if 0  /* ACCOUNT_MGMT */
 	CamelFolder *local_outbox;
 	struct _send_data *data;
 	EMailSession *session;
@@ -1171,6 +1177,7 @@ send_receive (GtkWindow *parent,
 			break;
 		}
 	}
+#endif /* ACCOUNT_MGMT */
 
 	return send_recv_dialog;
 }
@@ -1189,15 +1196,18 @@ mail_receive (GtkWindow *parent,
 	return send_receive (parent, backend, FALSE);
 }
 
+#if 0  /* ACCOUNT_MGMT */
 struct _auto_data {
 	EAccount *account;
 	EMailBackend *backend;
 	gint period;		/* in seconds */
 	gint timeout_id;
 };
+#endif /* ACCOUNT_MGMT */
 
 static GHashTable *auto_active;
 
+#if 0  /* ACCOUNT_MGMT */
 static gboolean
 auto_timeout (gpointer data)
 {
@@ -1325,12 +1335,14 @@ auto_online (EShell *shell)
 	if (iter)
 		g_object_unref (iter);
 }
+#endif /* ACCOUNT_MGMT */
 
 /* call to setup initial, and after changes are made to the config */
 /* FIXME: Need a cleanup funciton for when object is deactivated */
 void
 mail_autoreceive_init (EMailBackend *backend)
 {
+#if 0  /* ACCOUNT_MGMT */
 	EShellBackend *shell_backend;
 	EShellSettings *shell_settings;
 	EAccountList *accounts;
@@ -1378,10 +1390,12 @@ mail_autoreceive_init (EMailBackend *backend)
 	g_signal_connect (
 		shell, "notify::online",
 		G_CALLBACK (auto_online), NULL);
+#endif /* ACCOUNT_MGMT */
 }
 
 /* We setup the download info's in a hashtable, if we later
  * need to build the gui, we insert them in to add them. */
+#if 0  /* ACCONT_MGMT */
 void
 mail_receive_account (EMailBackend *backend,
                       EAccount *account)
@@ -1469,10 +1483,12 @@ mail_receive_account (EMailBackend *backend,
 		g_return_if_reached ();
 	}
 }
+#endif /* ACCOUNT_MGMT */
 
 void
 mail_send (EMailBackend *backend)
 {
+#if 0  /* ACCOUNT_MGMT */
 	CamelFolder *local_outbox;
 	CamelService *service;
 	EMailSession *session;
@@ -1545,4 +1561,5 @@ mail_send (EMailBackend *backend)
 		receive_get_folder, info,
 		receive_status, info,
 		receive_done, info);
+#endif /* ACCOUNT_MGMT */
 }
diff --git a/mail/mail-send-recv.h b/mail/mail-send-recv.h
index f702b74..8e84e36 100644
--- a/mail/mail-send-recv.h
+++ b/mail/mail-send-recv.h
@@ -26,7 +26,6 @@
 #include <gtk/gtk.h>
 #include <camel/camel.h>
 #include <mail/e-mail-backend.h>
-#include <libedataserver/e-account.h>
 
 G_BEGIN_DECLS
 
@@ -38,8 +37,10 @@ GtkWidget *	mail_receive			(GtkWindow *parent,
 						 EMailBackend *backend);
 
 /* receive a single account */
+#if 0  /* ACCOUNT_MGMT */
 void		mail_receive_account		(EMailBackend *backend,
 						 EAccount *account);
+#endif /* ACCOUNT_MGMT */
 
 void		mail_send			(EMailBackend *backend);
 
diff --git a/mail/mail-vfolder.c b/mail/mail-vfolder.c
index 45707a7..683f1ef 100644
--- a/mail/mail-vfolder.c
+++ b/mail/mail-vfolder.c
@@ -27,12 +27,12 @@
 #include <string.h>
 
 #include <glib/gi18n.h>
-
-#include <libedataserver/e-account-list.h>
+#include <libedataserver/e-source-mail-composition.h>
+#include <libedataserver/e-source-mail-identity.h>
+#include <libedataserver/e-source-mail-submission.h>
 
 #include "e-util/e-alert-dialog.h"
 #include "e-util/e-util-private.h"
-#include "e-util/e-account-utils.h"
 
 #include "e-mail-backend.h"
 #include "e-mail-session.h"
@@ -350,11 +350,12 @@ static gint
 uri_is_ignore (EMailBackend *backend,
                const gchar *uri)
 {
+	EShell *shell;
+	ESourceRegistry *registry;
 	EMailSession *session;
 	CamelSession *camel_session;
-	EAccountList *accounts;
-	EAccount *account;
-	EIterator *iter;
+	GList *list, *link;
+	const gchar *extension_name;
 	const gchar *local_drafts_uri;
 	const gchar *local_outbox_uri;
 	const gchar *local_sent_uri;
@@ -379,27 +380,36 @@ uri_is_ignore (EMailBackend *backend,
 	if (e_mail_folder_uri_equal (camel_session, local_drafts_uri, uri))
 		return TRUE;
 
-	accounts = e_get_account_list ();
-	iter = e_list_get_iterator (E_LIST (accounts));
+	shell = e_shell_backend_get_shell (E_SHELL_BACKEND (backend));
+	registry = e_shell_get_registry (shell);
 
-	while (!found && e_iterator_is_valid (iter)) {
-		/* XXX EIterator misuses const. */
-		account = (EAccount *) e_iterator_get (iter);
+	extension_name = E_SOURCE_EXTENSION_MAIL_IDENTITY;
+	list = e_source_registry_list_sources (registry, extension_name);
 
-		if (!found && account->sent_folder_uri != NULL)
-			found = e_mail_folder_uri_equal (
-				camel_session, uri,
-				account->sent_folder_uri);
+	for (link = list; !found && link != NULL; link = g_list_next (link)) {
+		ESource *source = E_SOURCE (link->data);
+		ESourceMailComposition *mc;
+		ESourceMailSubmission *ms;
+		const gchar *folder_uri;
+
+		extension_name = E_SOURCE_EXTENSION_MAIL_COMPOSITION;
+		mc = e_source_get_extension (source, extension_name);
+		folder_uri = e_source_mail_composition_get_drafts_folder (mc);
 
-		if (!found && account->drafts_folder_uri != NULL)
+		if (!found && folder_uri != NULL)
 			found = e_mail_folder_uri_equal (
-				camel_session, uri,
-				account->drafts_folder_uri);
+				camel_session, uri, folder_uri);
 
-		e_iterator_next (iter);
+		extension_name = E_SOURCE_EXTENSION_MAIL_SUBMISSION;
+		ms = e_source_get_extension (source, extension_name);
+		folder_uri = e_source_mail_submission_get_sent_folder (ms);
+
+		if (!found && folder_uri != NULL)
+			found = e_mail_folder_uri_equal (
+				camel_session, uri, folder_uri);
 	}
 
-	g_object_unref (iter);
+	g_list_free (list);
 
 	return found;
 }
diff --git a/mail/mail.error.xml b/mail/mail.error.xml
index 006cc55..edee2e9 100644
--- a/mail/mail.error.xml
+++ b/mail/mail.error.xml
@@ -318,24 +318,6 @@ all proxy information will be deleted permanently.</_secondary>
     <button _label="_Disable" response="GTK_RESPONSE_YES"/>
   </error>
 
-  <error id="no-save-signature" type="error">
-    <_primary>Could not save signature file.</_primary>
-    <secondary xml:space="preserve">{0}.</secondary>
-  </error>
-
-  <error id="signature-notscript" type="error">
-    <_primary>Cannot set signature script "{0}".</_primary>
-    <_secondary xml:space="preserve">The script file must exist and be executable.</_secondary>
-  </error>
-
-  <error id="ask-signature-changed" type="question" default="GTK_RESPONSE_YES">
-    <_primary>Do you wish to save your changes?</_primary>
-    <_secondary xml:space="preserve">This signature has been changed, but has not been saved.</_secondary>
-    <button _label="_Discard changes" response="GTK_RESPONSE_NO"/>
-    <button stock="gtk-cancel" response="GTK_RESPONSE_CANCEL"/>
-    <button stock="gtk-save" response="GTK_RESPONSE_YES"/>
-  </error>
-
   <error id="vfolder-notexist" type="error">
     <_primary>Cannot edit Search Folder "{0}" as it does not exist.</_primary>
     <_secondary xml:space="preserve">This folder may have been added implicitly,
@@ -451,16 +433,6 @@ An mbox account will be created to preserve the old mbox folders. You can delete
     <button _label="N_ever" response="GTK_RESPONSE_CANCEL"/>
   </error>
 
-  <error id="signature-already-exists" type="error" modal="true">
-    <_primary>Signature Already Exists</_primary>
-    <_secondary>A signature already exists with the name "{0}". Please specify a different name. </_secondary>
-  </error>
-  
-  <error id="blank-signature" type="error" modal="true">
-    <_primary>Blank Signature</_primary>
-    <_secondary>Please provide an unique name to identify this signature.</_secondary>
-  </error>
-  
   <error id="send-no-account-enabled" type="warning">
     <_primary>This message cannot be sent because the account you chose to send with is not enabled</_primary>
     <_secondary xml:space="preserve">Please enable the account or send using another account.</_secondary>



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