[evolution-mapi] Bug #608885 - Allow multiple MAPI accounts



commit 9d11b97d647521a7aae3db0e068a253173bfc289
Author: Milan Crha <mcrha redhat com>
Date:   Fri Apr 9 14:30:55 2010 +0200

    Bug #608885 - Allow multiple MAPI accounts
    
    Bad news is that the server notifications are disabled, it needs changes
    on OpenChange side. Also profile names are renamed, but it should survive
    without noticing in most cases.

 .../exchange-mapi-account-listener.c               |   72 +-
 .../exchange-mapi-account-listener.h               |    3 -
 .../exchange-mapi-account-settings.c               |   74 ++-
 .../exchange-mapi-account-setup.c                  |   39 +-
 src/addressbook/e-book-backend-mapi-gal.c          |   18 +-
 src/addressbook/e-book-backend-mapi.c              |   37 +-
 src/calendar/e-cal-backend-mapi.c                  |   79 +-
 src/camel/camel-mapi-folder.c                      |   28 +-
 src/camel/camel-mapi-notifications.c               |   18 +-
 src/camel/camel-mapi-store.c                       |   82 +-
 src/camel/camel-mapi-store.h                       |    3 +
 src/camel/camel-mapi-transport.c                   |   21 +-
 src/libexchangemapi/exchange-mapi-cal-utils.c      |   58 +-
 src/libexchangemapi/exchange-mapi-cal-utils.h      |    6 +-
 src/libexchangemapi/exchange-mapi-connection.c     | 1227 +++++++++++---------
 src/libexchangemapi/exchange-mapi-connection.h     |  177 ++--
 src/libexchangemapi/exchange-mapi-folder.c         |   71 +--
 src/libexchangemapi/exchange-mapi-folder.h         |    7 +-
 src/libexchangemapi/exchange-mapi-utils.c          |   26 +-
 src/libexchangemapi/exchange-mapi-utils.h          |    5 +-
 20 files changed, 1161 insertions(+), 890 deletions(-)
---
diff --git a/src/account-setup-eplugin/exchange-mapi-account-listener.c b/src/account-setup-eplugin/exchange-mapi-account-listener.c
index 7d05206..4581298 100644
--- a/src/account-setup-eplugin/exchange-mapi-account-listener.c
+++ b/src/account-setup-eplugin/exchange-mapi-account-listener.c
@@ -126,34 +126,6 @@ exchange_mapi_account_listener_init (ExchangeMAPIAccountListener *config_listene
 	config_listener->priv = g_new0 (ExchangeMAPIAccountListenerPrivate, 1);
 }
 
-/* This is a list of folders returned by e-d-s. */
-static	GSList *folders_list = NULL;
-
-GSList *
-exchange_mapi_account_listener_peek_folder_list (void)
-{
-	if (!folders_list)
-		folders_list = exchange_mapi_peek_folder_list ();
-
-	return folders_list;
-}
-
-void
-exchange_mapi_account_listener_get_folder_list (void)
-{
-	if (folders_list)
-		return;
-
-	folders_list = exchange_mapi_peek_folder_list ();
-}
-
-void
-exchange_mapi_account_listener_free_folder_list (void)
-{
-	exchange_mapi_folder_list_free ();
-	folders_list = NULL;
-}
-
 /*determines whehter the passed in account is exchange or not by looking at source url */
 
 static gboolean
@@ -553,12 +525,25 @@ mapi_account_added (EAccountList *account_listener, EAccount *account)
 	mapi_accounts = g_list_append (mapi_accounts, info);
 
 	if (account->enabled) {
-		/* Fetch the folders into a global list for future use.*/
-		exchange_mapi_account_listener_get_folder_list ();
+		GSList *folders_list;
+		CamelURL *url;
+		ExchangeMapiConnection *conn;
+
+		url = camel_url_new (info->source_url, NULL);
+		g_return_if_fail (url != NULL);
+
+		conn = exchange_mapi_connection_find (camel_url_get_param (url, "profile"));
+		camel_url_free (url);
+		g_return_if_fail (conn != NULL);
+
+		folders_list = exchange_mapi_connection_peek_folders_list (conn);
+
+		printf ("%s: %d\n", __FUNCTION__, g_slist_length (folders_list));
 
 		add_addressbook_sources (account, folders_list);
 		add_calendar_sources (account, folders_list);
-		/*FIXME: Maybe the folders_list above should be freed */
+
+		g_object_unref (conn);
 	}
 }
 
@@ -627,8 +612,25 @@ create_profile_entry (CamelURL *url, EAccount *account)
 		}
 		g_free (key);
 
-		if (password)
-		  status = exchange_mapi_create_profile (url->user, password, camel_url_get_param (url, "domain"), url->host, NULL, NULL, NULL);
+		if (password) {
+			status = exchange_mapi_create_profile (url->user, password, camel_url_get_param (url, "domain"), url->host, NULL, NULL, NULL);
+			if (status) {
+				/* profile was created, try to connect to the server */
+				ExchangeMapiConnection *conn;
+				gchar *profname;
+
+				status = FALSE;
+				profname = exchange_mapi_util_profile_name (url->user, camel_url_get_param (url, "domain"), url->host, FALSE);
+
+				conn = exchange_mapi_connection_new (profname, password);
+				if (conn) {
+					status = exchange_mapi_connection_connected (conn);
+					g_object_unref (conn);
+				}
+
+				g_free (profname);
+			}
+		}
 
 		++attempts;
 	}
@@ -684,7 +686,7 @@ mapi_account_changed (EAccountList *account_listener, EAccount *account)
 			gchar *profname = NULL, *uri = NULL;
 			ExchangeMAPIAccountListener *config_listener = exchange_mapi_accounts_peek_config_listener();
 
-			profname = exchange_mapi_util_profile_name (new_url->user, camel_url_get_param (new_url, "domain"));
+			profname = exchange_mapi_util_profile_name (new_url->user, camel_url_get_param (new_url, "domain"), new_url->host, FALSE);
 			camel_url_set_param(new_url, "profile", profname);
 			g_free (profname);
 
@@ -717,7 +719,7 @@ mapi_account_changed (EAccountList *account_listener, EAccount *account)
 				gchar *profname = NULL, *uri = NULL;
 				ExchangeMAPIAccountListener *config_listener = exchange_mapi_accounts_peek_config_listener();
 
-				profname = exchange_mapi_util_profile_name (new_url->user, camel_url_get_param (new_url, "domain"));
+				profname = exchange_mapi_util_profile_name (new_url->user, camel_url_get_param (new_url, "domain"), new_url->host, FALSE);
 				camel_url_set_param(new_url, "profile", profname);
 				g_free (profname);
 
diff --git a/src/account-setup-eplugin/exchange-mapi-account-listener.h b/src/account-setup-eplugin/exchange-mapi-account-listener.h
index cace30a..2312188 100644
--- a/src/account-setup-eplugin/exchange-mapi-account-listener.h
+++ b/src/account-setup-eplugin/exchange-mapi-account-listener.h
@@ -49,9 +49,6 @@ struct _ExchangeMAPIAccountListenerClass {
 
 GType				exchange_mapi_account_listener_get_type (void);
 ExchangeMAPIAccountListener *	exchange_mapi_account_listener_new (void);
-GSList *			exchange_mapi_account_listener_peek_folder_list (void);
-void				exchange_mapi_account_listener_get_folder_list (void);
-void				exchange_mapi_account_listener_free_folder_list (void);
 
 G_END_DECLS
 
diff --git a/src/account-setup-eplugin/exchange-mapi-account-settings.c b/src/account-setup-eplugin/exchange-mapi-account-settings.c
index 6c45b99..aaf492e 100644
--- a/src/account-setup-eplugin/exchange-mapi-account-settings.c
+++ b/src/account-setup-eplugin/exchange-mapi-account-settings.c
@@ -55,7 +55,6 @@ gboolean  e_plugin_ui_init (GtkUIManager *ui_manager,
 			    EShellView *shell_view);
 
 GtkWidget *org_gnome_exchange_mapi_settings (EPlugin *epl, EConfigHookItemFactoryData *data);
-void mapi_settings_run_folder_size_dialog (gpointer data);
 
 enum {
 	COL_FOLDERSIZE_NAME = 0,
@@ -69,6 +68,8 @@ typedef struct
 	GtkWidget *spinner;
 	GtkWidget *spinner_label;
 	GtkBox *spinner_hbox;
+
+	gchar *profile;
 } FolderSizeDialogData;
 
 static gboolean
@@ -81,8 +82,13 @@ mapi_settings_get_folder_size (gpointer data)
 	GtkTreeIter iter;
 	GtkBox *content_area;
 	FolderSizeDialogData *dialog_data = (FolderSizeDialogData *)data;
+	GSList *folder_list;
+	ExchangeMapiConnection *conn;
 
-	GSList *folder_list = exchange_mapi_account_listener_peek_folder_list ();
+	folder_list = NULL;
+	conn = exchange_mapi_connection_find (dialog_data->profile);
+	if (conn && exchange_mapi_connection_connected (conn))
+		folder_list = exchange_mapi_connection_peek_folders_list (conn);
 
 	/* Hide progress bar. Set status*/
 	gtk_widget_destroy (dialog_data->spinner_label);
@@ -127,11 +133,14 @@ mapi_settings_get_folder_size (gpointer data)
 	content_area = (GtkBox*) gtk_dialog_get_content_area (dialog_data->dialog);
 	gtk_box_pack_start (content_area, view, TRUE, TRUE, 6);
 
+	if (conn)
+		g_object_unref (conn);
+
 	return FALSE;
 }
 
-void
-mapi_settings_run_folder_size_dialog (gpointer data)
+static void
+mapi_settings_run_folder_size_dialog (const gchar *profile, gpointer data)
 {
 	GtkBox *content_area;
 	FolderSizeDialogData *dialog_data;
@@ -159,6 +168,8 @@ mapi_settings_run_folder_size_dialog (gpointer data)
 	gtk_box_pack_start (content_area, GTK_WIDGET (dialog_data->spinner_hbox), TRUE, TRUE, 6);
 	gtk_widget_show_all (GTK_WIDGET (dialog_data->dialog));
 
+	dialog_data->profile = g_strdup (profile);
+
 	/* Fetch folder list and size information in a thread */
 	folder_list_thread = g_thread_create ((GThreadFunc)mapi_settings_get_folder_size, dialog_data, TRUE, NULL);
 
@@ -166,13 +177,26 @@ mapi_settings_run_folder_size_dialog (gpointer data)
 	gtk_dialog_run (dialog_data->dialog);
 
 	gtk_widget_destroy (GTK_WIDGET (dialog_data->dialog));
+
+	g_free (dialog_data->profile);
 	g_free (dialog_data);
 }
 
 static void
-folder_size_clicked (GtkButton *button, gpointer data)
+folder_size_clicked (GtkButton *button, EAccount *account)
 {
-	mapi_settings_run_folder_size_dialog (NULL);
+	CamelURL *url;
+
+	g_return_if_fail (account != NULL);
+	g_return_if_fail (E_IS_ACCOUNT (account));
+
+	
+	url = camel_url_new (e_account_get_string (account,  E_ACCOUNT_SOURCE_URL), NULL);
+	g_return_if_fail (url != NULL);
+
+	mapi_settings_run_folder_size_dialog (camel_url_get_param (url, "profile"), NULL);
+
+	camel_url_free (url);
 }
 
 static void
@@ -182,16 +206,50 @@ action_folder_size_cb (GtkAction *action,
 	EShellSidebar *shell_sidebar;
 	EMFolderTree *folder_tree;
 	const gchar *folder_uri;
+	GtkTreeSelection *selection;
+	gchar *profile = NULL;
 
 	/* Get hold of Folder Tree */
 	shell_sidebar = e_shell_view_get_shell_sidebar (shell_view);
 	g_object_get (shell_sidebar, "folder-tree", &folder_tree, NULL);
 	folder_uri = em_folder_tree_get_selected_uri (folder_tree);
+	selection = em_folder_tree_model_get_selection (EM_FOLDER_TREE_MODEL (gtk_tree_view_get_model (GTK_TREE_VIEW (folder_tree))));
+	if (selection) {
+		GtkTreeIter iter;
+		GtkTreeModel *model = NULL;
+
+		if (gtk_tree_selection_get_selected (selection, &model, &iter)) {
+			gboolean is_folder = FALSE;
+			CamelStore *store = NULL;
+
+			gtk_tree_model_get (model, &iter,
+				COL_BOOL_IS_FOLDER, &is_folder,
+				COL_POINTER_CAMEL_STORE, &store,
+				-1);
+
+			if (is_folder && !store) {
+				CamelFolder *folder = em_folder_tree_get_selected_folder (folder_tree);
+
+				if (folder)
+					store = camel_folder_get_parent_store (folder);
+			}
+
+			if (store && CAMEL_IS_SERVICE (store)) {
+				CamelService *service = CAMEL_SERVICE (store);
+
+				if (service->url)
+					profile = g_strdup (camel_url_get_param (service->url, "profile"));
+			}
+		}
+	}
+
 	g_object_unref (folder_tree);
 	g_return_if_fail (folder_uri != NULL);
 
 	if (g_str_has_prefix (folder_uri, "mapi://"))
-		mapi_settings_run_folder_size_dialog (NULL);
+		mapi_settings_run_folder_size_dialog (profile, NULL);
+
+	g_free (profile);
 }
 
 static void
@@ -278,7 +336,7 @@ org_gnome_exchange_mapi_settings (EPlugin *epl, EConfigHookItemFactoryData *data
 					      _("View the size of all Exchange folders"), NULL);
 	gtk_misc_set_alignment (GTK_MISC (lbl_fsize), 0, 0.5);
 	btn_fsize = (GtkButton*) g_object_new (GTK_TYPE_BUTTON, "label", _("Folders Size"), NULL);
-	g_signal_connect (btn_fsize, "clicked", G_CALLBACK (folder_size_clicked), NULL);
+	g_signal_connect (btn_fsize, "clicked", G_CALLBACK (folder_size_clicked), target_account->account);
 	gtk_table_attach_defaults (tbl_misc, GTK_WIDGET (lbl_fsize), 0, 1, 0, 1);
 	gtk_table_attach (tbl_misc, GTK_WIDGET (btn_fsize), 1, 2, 0, 1, GTK_FILL, GTK_FILL, 0, 0);
 
diff --git a/src/account-setup-eplugin/exchange-mapi-account-setup.c b/src/account-setup-eplugin/exchange-mapi-account-setup.c
index 3e6a4b5..b98a3b1 100644
--- a/src/account-setup-eplugin/exchange-mapi-account-setup.c
+++ b/src/account-setup-eplugin/exchange-mapi-account-setup.c
@@ -233,11 +233,28 @@ validate_credentials (GtkWidget *widget, EConfig *config)
 								(mapi_profile_callback_t) create_profile_callback,
 								url->user);
 		if (status) {
+			/* profile was created, try to connect to the server */
+			ExchangeMapiConnection *conn;
+			gchar *profname;
+
+			status = FALSE;
+			profname = exchange_mapi_util_profile_name (url->user, domain_name, url->host, FALSE);
+
+			conn = exchange_mapi_connection_new (profname, password);
+			if (conn) {
+				status = exchange_mapi_connection_connected (conn);
+				g_object_unref (conn);
+			}
+
+			g_free (profname);
+		}
+
+		if (status) {
 			/* Things are successful */
 			gchar *profname = NULL, *uri = NULL;
 
-			profname = exchange_mapi_util_profile_name (url->user, domain_name);
-			camel_url_set_param(url, "profile", profname);
+			profname = exchange_mapi_util_profile_name (url->user, domain_name, url->host, FALSE);
+			camel_url_set_param (url, "profile", profname);
 			g_free (profname);
 
 			uri = camel_url_to_string(url, 0);
@@ -468,18 +485,26 @@ exchange_mapi_create (EPlugin *epl, EConfigHookItemFactoryData *data)
 	GtkTreeViewColumn *tvc;
 	const gchar *acc;
 	GSList *folders;
+	ExchangeMapiConnection *conn;
 
 	uri_text = e_source_get_uri (source);
 	if (uri_text && g_ascii_strncasecmp (uri_text, MAPI_URI_PREFIX, MAPI_PREFIX_LENGTH)) {
 		return NULL;
 	}
 
-	folders = exchange_mapi_account_listener_peek_folder_list ();
+	folders = NULL;
+	conn = exchange_mapi_connection_find (e_source_get_property (source, "profile"));
+	if (conn && exchange_mapi_connection_connected (conn))
+		folders = exchange_mapi_connection_peek_folders_list (conn);
+
 	acc = e_source_group_peek_name (e_source_peek_group (source));
 	ts = gtk_tree_store_new (NUM_COLS, G_TYPE_STRING, G_TYPE_INT64, G_TYPE_POINTER);
 
 	add_folders (folders, ts);
 
+	if (conn)
+		g_object_unref (conn);
+
 	vbox = gtk_vbox_new (FALSE, 6);
 
 	if (!strcmp (data->config->id, "org.gnome.evolution.calendar.calendarProperties")) {
@@ -605,6 +630,7 @@ exchange_mapi_cal_check (EPlugin *epl, EConfigHookPageCheckData *data)
 void
 exchange_mapi_cal_commit (EPlugin *epl, EConfigTarget *target)
 {
+	ExchangeMapiConnection *conn;
 	ECalConfigTargetSource *t = (ECalConfigTargetSource *) target;
 	ESourceGroup *group;
 	ESource *source = t->source;
@@ -636,7 +662,12 @@ exchange_mapi_cal_commit (EPlugin *epl, EConfigTarget *target)
 
 	exchange_mapi_util_mapi_id_from_string (e_source_get_property (source, "parent-fid"), &pfid);
 
-	fid = exchange_mapi_create_folder (type, pfid, e_source_peek_name (source));
+	/* the profile should be already connected */
+	conn = exchange_mapi_connection_find (e_source_get_property (source, "profile"));
+	g_return_if_fail (conn != NULL);
+
+	fid = exchange_mapi_connection_create_folder (conn, type, pfid, e_source_peek_name (source));
+	g_object_unref (conn);
 
 	sfid = exchange_mapi_util_mapi_id_to_string (fid);
 	tmp = g_strconcat (";", sfid, NULL);
diff --git a/src/addressbook/e-book-backend-mapi-gal.c b/src/addressbook/e-book-backend-mapi-gal.c
index f0847de..7d66fe6 100644
--- a/src/addressbook/e-book-backend-mapi-gal.c
+++ b/src/addressbook/e-book-backend-mapi-gal.c
@@ -95,6 +95,8 @@ static gint maplen = G_N_ELEMENTS(mappings);
 struct _EBookBackendMAPIGALPrivate
 {
 	gchar *profile;
+	ExchangeMapiConnection *conn;
+
 	mapi_id_t fid;
 	gint mode;
 	gboolean marked_for_offline;
@@ -188,7 +190,7 @@ build_cache (EBookBackendMAPIGAL *ebmapi)
 		printf("Summary file name is %s\n", priv->summary_file_name);
 	}
 
-	exchange_mapi_util_get_gal (contacts_array);
+	exchange_mapi_connection_get_gal (priv->conn, contacts_array);
 
 	e_file_cache_freeze_changes (E_FILE_CACHE (priv->cache));
 
@@ -300,7 +302,13 @@ e_book_backend_mapi_gal_authenticate_user (EBookBackend *backend,
 
 	case GNOME_Evolution_Addressbook_MODE_REMOTE:
 
-		if (!exchange_mapi_connection_new (priv->profile, passwd))
+		priv->conn = exchange_mapi_connection_new (priv->profile, passwd);
+		if (!priv->conn) {
+			priv->conn = exchange_mapi_connection_find (priv->profile);
+			if (priv->conn && !exchange_mapi_connection_connected (priv->conn))
+				exchange_mapi_connection_reconnect (priv->conn, passwd);
+		}
+		if (!priv->conn)
 			return e_data_book_respond_authenticate_user (book, opid,GNOME_Evolution_Addressbook_OtherError);
 
 		if (priv->cache && priv->is_cache_ready) {
@@ -513,6 +521,10 @@ e_book_backend_mapi_gal_dispose (GObject *object)
 		g_free (priv->profile);
 		priv->profile = NULL;
 	}
+	if (priv->conn) {
+		g_object_unref (priv->conn);
+		priv->conn = NULL;
+	}
 	if (priv->uri) {
 		g_free (priv->uri);
 		priv->uri = NULL;
@@ -776,7 +788,7 @@ book_view_thread (gpointer data)
 
 	switch (priv->mode) {
 		case GNOME_Evolution_Addressbook_MODE_REMOTE:
-			if (!exchange_mapi_connection_exists ()) {
+			if (!priv->conn) {
 				e_book_backend_notify_auth_required (E_BOOK_BACKEND (backend));
 				e_data_book_view_notify_complete (book_view,
 							GNOME_Evolution_Addressbook_AuthenticationRequired);
diff --git a/src/addressbook/e-book-backend-mapi.c b/src/addressbook/e-book-backend-mapi.c
index 06f0984..4c16034 100644
--- a/src/addressbook/e-book-backend-mapi.c
+++ b/src/addressbook/e-book-backend-mapi.c
@@ -54,6 +54,8 @@ static gboolean enable_debug = TRUE;
 struct _EBookBackendMAPIPrivate
 {
 	gchar *profile;
+	ExchangeMapiConnection *conn;
+
 	mapi_id_t fid;
 	gint mode;
 	gboolean marked_for_offline;
@@ -596,7 +598,7 @@ e_book_backend_mapi_create_contact (EBookBackend *backend,
 
 	case  GNOME_Evolution_Addressbook_MODE_REMOTE :
 		contact = e_contact_new_from_vcard(vcard);
-		status = exchange_mapi_create_item (olFolderContacts, priv->fid, mapi_book_build_name_id, contact, mapi_book_build_props, contact, NULL, NULL, NULL, 0);
+		status = exchange_mapi_connection_create_item (priv->conn, olFolderContacts, priv->fid, mapi_book_build_name_id, contact, mapi_book_build_props, contact, NULL, NULL, NULL, 0);
 		if (!status) {
 			e_data_book_respond_create(book, opid, GNOME_Evolution_Addressbook_OtherError, NULL);
 			return;
@@ -652,7 +654,7 @@ e_book_backend_mapi_remove_contacts (EBookBackend *backend,
 			tmp = tmp->next;
 		}
 
-		exchange_mapi_remove_items (olFolderContacts, priv->fid, list);
+		exchange_mapi_connection_remove_items (priv->conn, olFolderContacts, priv->fid, list);
 		if (priv->marked_for_offline && priv->is_cache_ready) {
 			tmp = id_list;
 			while (tmp) {
@@ -704,7 +706,7 @@ e_book_backend_mapi_modify_contact (EBookBackend *backend,
 		exchange_mapi_util_mapi_ids_from_uid (tmp, &fid, &mid);
 		printf("modify id %s\n", tmp);
 
-		status = exchange_mapi_modify_item (olFolderContacts, priv->fid, mid, mapi_book_build_name_id, contact, mapi_book_build_props, contact, NULL, NULL, NULL, 0);
+		status = exchange_mapi_connection_modify_item (priv->conn, olFolderContacts, priv->fid, mid, mapi_book_build_name_id, contact, mapi_book_build_props, contact, NULL, NULL, NULL, 0);
 		printf("getting %d\n", status);
 		if (!status) {
 			e_data_book_respond_modify(book, opid, GNOME_Evolution_Addressbook_OtherError, NULL);
@@ -813,7 +815,7 @@ e_book_backend_mapi_get_contact (EBookBackend *backend,
 			mapi_id_t fid, mid;
 
 			exchange_mapi_util_mapi_ids_from_uid (id, &fid, &mid);
-			exchange_mapi_connection_fetch_item (priv->fid, mid,
+			exchange_mapi_connection_fetch_item (priv->conn, priv->fid, mid,
 							NULL, 0,
 							NULL, NULL,
 							create_contact_item, contact,
@@ -970,7 +972,7 @@ e_book_backend_mapi_get_contact_list (EBookBackend *backend,
 				return;
 			}
 
-			if (!exchange_mapi_connection_fetch_items (priv->fid, &res, NULL,
+			if (!exchange_mapi_connection_fetch_items (priv->conn, priv->fid, &res, NULL,
 								GetPropsList, n_GetPropsList,
 								mapi_book_build_name_id_for_getprops, NULL,
 								create_contact_list_cb, &vcard_str,
@@ -1249,7 +1251,7 @@ book_view_thread (gpointer data)
 
 	case GNOME_Evolution_Addressbook_MODE_REMOTE:
 
-		if (!exchange_mapi_connection_exists ()) {
+		if (!priv->conn || !exchange_mapi_connection_connected (priv->conn)) {
 			e_book_backend_notify_auth_required (E_BOOK_BACKEND (backend));
 			e_data_book_view_notify_complete (book_view,
 						GNOME_Evolution_Addressbook_AuthenticationRequired);
@@ -1306,7 +1308,7 @@ book_view_thread (gpointer data)
 			}
 
 			//FIXME: We need to fetch only the query from the server live and not everything.
-			if (!exchange_mapi_connection_fetch_items (priv->fid, &res, NULL,
+			if (!exchange_mapi_connection_fetch_items (priv->conn, priv->fid, &res, NULL,
 							   GetPropsList, n_GetPropsList,
 							   mapi_book_build_name_id_for_getprops, NULL,
 							   create_contact_cb, book_view,
@@ -1322,7 +1324,7 @@ book_view_thread (gpointer data)
 				return;
 			}
 		} else {
-			if (!exchange_mapi_connection_fetch_items (priv->fid, NULL, NULL,
+			if (!exchange_mapi_connection_fetch_items (priv->conn, priv->fid, NULL, NULL,
 							NULL, 0,
 							NULL, NULL,
 							create_contact_cb, book_view,
@@ -1429,7 +1431,7 @@ build_cache (EBookBackendMAPI *ebmapi)
 
 	e_file_cache_freeze_changes (E_FILE_CACHE (priv->cache));
 
-	if (!exchange_mapi_connection_fetch_items (priv->fid, NULL, NULL,
+	if (!exchange_mapi_connection_fetch_items (priv->conn, priv->fid, NULL, NULL,
 						NULL, 0,
 						NULL, NULL,
 						cache_contact_cb, ebmapi,
@@ -1474,7 +1476,7 @@ update_cache (EBookBackendMAPI *ebmapi)
 
 	e_file_cache_freeze_changes (E_FILE_CACHE (priv->cache));
 
-	if (!exchange_mapi_connection_fetch_items ( priv->fid, &res, NULL,
+	if (!exchange_mapi_connection_fetch_items (priv->conn, priv->fid, &res, NULL,
 						NULL, 0,
 						NULL, NULL,
 						cache_contact_cb, ebmapi,
@@ -1516,7 +1518,14 @@ e_book_backend_mapi_authenticate_user (EBookBackend *backend,
 
 	case GNOME_Evolution_Addressbook_MODE_REMOTE:
 
-		if (!exchange_mapi_connection_new (priv->profile, passwd))
+		priv->conn = exchange_mapi_connection_new (priv->profile, passwd);
+		if (!priv->conn) {
+			priv->conn = exchange_mapi_connection_find (priv->profile);
+			if (priv->conn && !exchange_mapi_connection_connected (priv->conn))
+				exchange_mapi_connection_reconnect (priv->conn, passwd);
+		}
+
+		if (!priv->conn)
 			return e_data_book_respond_authenticate_user (book, opid,GNOME_Evolution_Addressbook_OtherError);
 
 		if (priv->cache && priv->is_cache_ready) {
@@ -1625,7 +1634,7 @@ e_book_backend_mapi_remove (EBookBackend *backend,
 
 	case GNOME_Evolution_Addressbook_MODE_REMOTE:
 
-		status = exchange_mapi_remove_folder (olFolderContacts, priv->fid);
+		status = exchange_mapi_connection_remove_folder (priv->conn, priv->fid);
 		if (!status) {
 			e_data_book_respond_remove (book, opid, GNOME_Evolution_Addressbook_OtherError);
 			return;
@@ -1701,6 +1710,10 @@ e_book_backend_mapi_dispose (GObject *object)
 		g_free (priv->profile);
 		priv->profile = NULL;
 	}
+	if (priv->conn) {
+		g_object_unref (priv->conn);
+		priv->conn = NULL;
+	}
 	if (priv->uri) {
 		g_free (priv->uri);
 		priv->uri = NULL;
diff --git a/src/calendar/e-cal-backend-mapi.c b/src/calendar/e-cal-backend-mapi.c
index 93b1fe9..d8956d8 100644
--- a/src/calendar/e-cal-backend-mapi.c
+++ b/src/calendar/e-cal-backend-mapi.c
@@ -62,6 +62,7 @@ struct _ECalBackendMAPIPrivate {
 	mapi_id_t		fid;
 	uint32_t		olFolder;
 	gchar			*profile;
+	ExchangeMapiConnection  *conn;
 
 	/* These fields are entirely for access rights */
 	gchar			*owner_name;
@@ -96,7 +97,6 @@ static ECalBackendClass *parent_class = NULL;
 
 #define CACHE_REFRESH_INTERVAL 600000
 
-static gboolean authenticated = FALSE;
 static GStaticMutex auth_mutex = G_STATIC_MUTEX_INIT;
 
 static ECalBackendSyncStatus
@@ -108,11 +108,19 @@ e_cal_backend_mapi_authenticate (ECalBackend *backend)
 	cbmapi = E_CAL_BACKEND_MAPI (backend);
 	priv = cbmapi->priv;
 
-	if (authenticated || exchange_mapi_connection_exists () || exchange_mapi_connection_new (priv->profile, priv->password)) {
-		authenticated = TRUE;
+	if (priv->conn)
+		g_object_unref (priv->conn);
+
+	priv->conn = exchange_mapi_connection_new (priv->profile, priv->password);
+	if (!priv->conn) {
+		priv->conn = exchange_mapi_connection_find (priv->profile);
+		if (priv->conn && !exchange_mapi_connection_connected (priv->conn))
+			exchange_mapi_connection_reconnect (priv->conn, priv->password);
+	}
+
+	if (priv->conn && exchange_mapi_connection_connected (priv->conn)) {
 		return GNOME_Evolution_Calendar_Success;
 	} else {
-		authenticated = FALSE;
 		e_cal_backend_notify_error (E_CAL_BACKEND (cbmapi), _("Authentication failed"));
 		return GNOME_Evolution_Calendar_AuthenticationFailed;
 	}
@@ -226,6 +234,11 @@ e_cal_backend_mapi_finalize (GObject *object)
 		priv->default_zone = NULL;
 	}
 
+	if (priv->conn) {
+		g_object_unref (priv->conn);
+		priv->conn = NULL;
+	}
+
 	g_free (priv);
 	cbmapi->priv = NULL;
 
@@ -329,20 +342,10 @@ e_cal_backend_mapi_remove (ECalBackendSync *backend, EDataCal *cal)
 	cbmapi = E_CAL_BACKEND_MAPI (backend);
 	priv = cbmapi->priv;
 
-	if (priv->mode == CAL_MODE_LOCAL)
+	if (priv->mode == CAL_MODE_LOCAL || !priv->conn || !exchange_mapi_connection_connected (priv->conn))
 		return GNOME_Evolution_Calendar_RepositoryOffline;
 
-	/* FIXME: check for return status and respond */
-	if (!authenticated) {
-		g_static_mutex_lock (&auth_mutex);
-		e_cal_backend_mapi_authenticate (E_CAL_BACKEND (cbmapi));
-		g_static_mutex_unlock (&auth_mutex);
-	}
-
-	if (!authenticated)
-		return GNOME_Evolution_Calendar_AuthenticationFailed;
-
-	status = exchange_mapi_remove_folder (priv->olFolder, priv->fid);
+	status = exchange_mapi_connection_remove_folder (priv->conn, priv->fid);
 	if (!status)
 		return GNOME_Evolution_Calendar_OtherError;
 
@@ -428,7 +431,7 @@ mapi_cal_get_changes_cb (FetchItemsCallbackData *item_data, gpointer data)
 	cache_comp = e_cal_backend_cache_get_component (priv->cache, tmp, NULL);
 
 	if (cache_comp == NULL) {
-		ECalComponent *comp = exchange_mapi_cal_util_mapi_props_to_comp (kind, tmp, array,
+		ECalComponent *comp = exchange_mapi_cal_util_mapi_props_to_comp (item_data->conn, kind, tmp, array,
 									streams, recipients, attachments,
 									priv->local_attachments_store, priv->default_zone);
 
@@ -461,7 +464,7 @@ mapi_cal_get_changes_cb (FetchItemsCallbackData *item_data, gpointer data)
 				e_cal_component_commit_sequence (cache_comp);
 				cache_comp_str = e_cal_component_get_as_string (cache_comp);
 
-				comp = exchange_mapi_cal_util_mapi_props_to_comp (kind, tmp, array,
+				comp = exchange_mapi_cal_util_mapi_props_to_comp (item_data->conn, kind, tmp, array,
 									streams, recipients, attachments,
 									priv->local_attachments_store, priv->default_zone);
 
@@ -615,7 +618,7 @@ get_deltas (gpointer handle)
 //	e_file_cache_freeze_changes (E_FILE_CACHE (priv->cache));
 	/* FIXME: GetProps does not seem to work for tasks :-( */
 	if (kind == ICAL_VTODO_COMPONENT) {
-		if (!exchange_mapi_connection_fetch_items (priv->fid, use_restriction ? &res : NULL, NULL,
+		if (!exchange_mapi_connection_fetch_items (priv->conn, priv->fid, use_restriction ? &res : NULL, NULL,
 						NULL, 0, NULL, NULL,
 						mapi_cal_get_changes_cb, cbmapi,
 						MAPI_OPTIONS_FETCH_ALL)) {
@@ -625,7 +628,7 @@ get_deltas (gpointer handle)
 			g_static_mutex_unlock (&updating);
 			return FALSE;
 		}
-	} else if (!exchange_mapi_connection_fetch_items (priv->fid, use_restriction ? &res : NULL, NULL,
+	} else if (!exchange_mapi_connection_fetch_items (priv->conn, priv->fid, use_restriction ? &res : NULL, NULL,
 						cal_GetPropsList, G_N_ELEMENTS (cal_GetPropsList),
 						exchange_mapi_cal_util_build_name_id, GINT_TO_POINTER(kind),
 						mapi_cal_get_changes_cb, cbmapi,
@@ -653,7 +656,7 @@ get_deltas (gpointer handle)
 	did.cbmapi = cbmapi;
 	did.cache_keys = e_cal_backend_cache_get_keys (priv->cache);
 	did.unknown_mids = NULL;
-	if (!exchange_mapi_connection_fetch_items (priv->fid, NULL, NULL,
+	if (!exchange_mapi_connection_fetch_items (priv->conn, priv->fid, NULL, NULL,
 						cal_IDList, G_N_ELEMENTS (cal_IDList),
 						NULL, NULL,
 						handle_deleted_items_cb, &did,
@@ -717,7 +720,7 @@ get_deltas (gpointer handle)
 		g_slist_free (did.unknown_mids);
 
 		if (kind == ICAL_VTODO_COMPONENT) {
-			if (!exchange_mapi_connection_fetch_items (priv->fid, &res, NULL,
+			if (!exchange_mapi_connection_fetch_items (priv->conn, priv->fid, &res, NULL,
 						NULL, 0, NULL, NULL,
 						mapi_cal_get_changes_cb, cbmapi,
 						MAPI_OPTIONS_FETCH_ALL)) {
@@ -726,7 +729,7 @@ get_deltas (gpointer handle)
 				g_free (or_res);
 				return FALSE;
 			}
-		} else if (!exchange_mapi_connection_fetch_items (priv->fid, &res, NULL,
+		} else if (!exchange_mapi_connection_fetch_items (priv->conn, priv->fid, &res, NULL,
 						cal_GetPropsList, G_N_ELEMENTS (cal_GetPropsList),
 						exchange_mapi_cal_util_build_name_id, GINT_TO_POINTER(kind),
 						mapi_cal_get_changes_cb, cbmapi,
@@ -1002,7 +1005,7 @@ mapi_cal_cache_create_cb (FetchItemsCallbackData *item_data, gpointer data)
 	}
 
 	tmp = exchange_mapi_util_mapi_id_to_string (mid);
-	comp = exchange_mapi_cal_util_mapi_props_to_comp (kind, tmp, properties,
+	comp = exchange_mapi_cal_util_mapi_props_to_comp (item_data->conn, kind, tmp, properties,
 							streams, recipients, attachments,
 							priv->local_attachments_store, priv->default_zone);
 	g_free (tmp);
@@ -1054,7 +1057,7 @@ populate_cache (ECalBackendMAPI *cbmapi)
 //	e_file_cache_freeze_changes (E_FILE_CACHE (priv->cache));
 	/* FIXME: GetProps does not seem to work for tasks :-( */
 	if (kind == ICAL_VTODO_COMPONENT) {
-		if (!exchange_mapi_connection_fetch_items (priv->fid, NULL, NULL,
+		if (!exchange_mapi_connection_fetch_items (priv->conn, priv->fid, NULL, NULL,
 						NULL, 0, NULL, NULL,
 						mapi_cal_cache_create_cb, cbmapi,
 						MAPI_OPTIONS_FETCH_ALL)) {
@@ -1063,7 +1066,7 @@ populate_cache (ECalBackendMAPI *cbmapi)
 			g_mutex_unlock (priv->mutex);
 			return GNOME_Evolution_Calendar_OtherError;
 		}
-	} else if (!exchange_mapi_connection_fetch_items (priv->fid, NULL, NULL,
+	} else if (!exchange_mapi_connection_fetch_items (priv->conn, priv->fid, NULL, NULL,
 						cal_GetPropsList, G_N_ELEMENTS (cal_GetPropsList),
 						exchange_mapi_cal_util_build_name_id, GINT_TO_POINTER(kind),
 						mapi_cal_cache_create_cb, cbmapi,
@@ -1137,7 +1140,7 @@ e_cal_backend_mapi_connect (ECalBackendMAPI *cbmapi)
 
 	source = e_cal_backend_get_source (E_CAL_BACKEND (cbmapi));
 
-	if (!authenticated) {
+	if (!priv->conn || !exchange_mapi_connection_connected (priv->conn)) {
 		e_cal_backend_notify_error (E_CAL_BACKEND (cbmapi), _("Authentication failed"));
 		return GNOME_Evolution_Calendar_AuthenticationFailed;
 	}
@@ -1349,7 +1352,7 @@ get_server_data (ECalBackendMAPI *cbmapi, icalcomponent *comp, struct cbdata *cb
 
 	uid = icalcomponent_get_uid (comp);
 	exchange_mapi_util_mapi_id_from_string (uid, &mid);
-	if (exchange_mapi_connection_fetch_item (priv->fid, mid,
+	if (exchange_mapi_connection_fetch_item (priv->conn, priv->fid, mid,
 					NULL, 0,
 					NULL, NULL,
 					capture_req_props, cbdata,
@@ -1357,7 +1360,7 @@ get_server_data (ECalBackendMAPI *cbmapi, icalcomponent *comp, struct cbdata *cb
 
 		return;
 
-	array = exchange_mapi_util_resolve_named_prop (priv->olFolder, priv->fid, 0x0023, PSETID_Meeting);
+	array = exchange_mapi_connection_resolve_named_prop (priv->conn, priv->olFolder, priv->fid, 0x0023, PSETID_Meeting);
 	proptag = array->aulPropTag[0];
 
 	res.rt = RES_PROPERTY;
@@ -1369,7 +1372,7 @@ get_server_data (ECalBackendMAPI *cbmapi, icalcomponent *comp, struct cbdata *cb
 	set_SPropValue_proptag (&sprop, proptag, (gconstpointer ) &sb);
 	cast_mapi_SPropValue (&(res.res.resProperty.lpProp), &sprop);
 
-	exchange_mapi_connection_fetch_items (priv->fid, &res, NULL,
+	exchange_mapi_connection_fetch_items (priv->conn, priv->fid, &res, NULL,
 					NULL, 0,
 					NULL, NULL,
 					capture_req_props, cbdata,
@@ -1430,7 +1433,7 @@ e_cal_backend_mapi_create_object (ECalBackendSync *backend, EDataCal *cal, gchar
 			struct SPropTagArray *tag_array;
 			ExchangeMAPIStream *stream = g_new0 (ExchangeMAPIStream, 1);
 			stream->value = ba;
-			tag_array = exchange_mapi_util_resolve_named_prop (priv->olFolder, priv->fid, 0x8216, PSETID_Appointment);
+			tag_array = exchange_mapi_connection_resolve_named_prop (priv->conn, priv->olFolder, priv->fid, 0x8216, PSETID_Appointment);
 			if (tag_array) {
 				stream->proptag = tag_array->aulPropTag[0];
 				streams = g_slist_append (streams, stream);
@@ -1467,14 +1470,14 @@ e_cal_backend_mapi_create_object (ECalBackendSync *backend, EDataCal *cal, gchar
 			cbdata.msgflags = MSGFLAG_READ;
 			cbdata.meeting_type = (recipients != NULL) ? MEETING_OBJECT : NOT_A_MEETING;
 			cbdata.resp = (recipients != NULL) ? olResponseOrganized : olResponseNone;
-			cbdata.appt_id = exchange_mapi_cal_util_get_new_appt_id (priv->fid);
+			cbdata.appt_id = exchange_mapi_cal_util_get_new_appt_id (priv->conn, priv->fid);
 			cbdata.appt_seq = 0;
 			e_cal_component_get_uid (comp, &compuid);
 			exchange_mapi_cal_util_generate_globalobjectid (TRUE, compuid, &globalid);
 			cbdata.globalid = &globalid;
 			cbdata.cleanglobalid = &globalid;
 
-			mid = exchange_mapi_create_item (priv->olFolder, priv->fid,
+			mid = exchange_mapi_connection_create_item (priv->conn, priv->olFolder, priv->fid,
 							exchange_mapi_cal_util_build_name_id, GINT_TO_POINTER(kind),
 							exchange_mapi_cal_util_build_props, &cbdata,
 							recipients, attachments, streams, MAPI_OPTIONS_DONT_SUBMIT);
@@ -1637,7 +1640,7 @@ e_cal_backend_mapi_modify_object (ECalBackendSync *backend, EDataCal *cal, const
 			struct SPropTagArray *tag_array;
 			ExchangeMAPIStream *stream = g_new0 (ExchangeMAPIStream, 1);
 			stream->value = ba;
-			tag_array = exchange_mapi_util_resolve_named_prop (priv->olFolder, priv->fid, 0x8216, PSETID_Appointment);
+			tag_array = exchange_mapi_connection_resolve_named_prop (priv->conn, priv->olFolder, priv->fid, 0x8216, PSETID_Appointment);
 			if (tag_array) {
 				stream->proptag = tag_array->aulPropTag[0];
 				streams = g_slist_append (streams, stream);
@@ -1698,7 +1701,7 @@ e_cal_backend_mapi_modify_object (ECalBackendSync *backend, EDataCal *cal, const
 			cbdata.meeting_type = (recipients != NULL) ? MEETING_OBJECT_RCVD : NOT_A_MEETING;
 		}
 
-		status = exchange_mapi_modify_item (priv->olFolder, priv->fid, mid,
+		status = exchange_mapi_connection_modify_item (priv->conn, priv->olFolder, priv->fid, mid,
 						exchange_mapi_cal_util_build_name_id, GINT_TO_POINTER(kind),
 						exchange_mapi_cal_util_build_props, &cbdata,
 						recipients, attachments, streams, MAPI_OPTIONS_DONT_SUBMIT);
@@ -1796,7 +1799,7 @@ e_cal_backend_mapi_remove_object (ECalBackendSync *backend, EDataCal *cal,
 				list = g_slist_prepend (list, (gpointer) data);
 //			}
 
-			if (exchange_mapi_remove_items (priv->olFolder, priv->fid, list)) {
+			if (exchange_mapi_connection_remove_items (priv->conn, priv->olFolder, priv->fid, list)) {
 				for (l = comp_list; l; l = l->next) {
 					ECalComponent *comp = E_CAL_COMPONENT (l->data);
 					ECalComponentId *id = e_cal_component_get_id (comp);
@@ -1885,7 +1888,7 @@ e_cal_backend_mapi_send_objects (ECalBackendSync *backend, EDataCal *cal, const
 					struct SPropTagArray *tag_array;
 					ExchangeMAPIStream *stream = g_new0 (ExchangeMAPIStream, 1);
 					stream->value = ba;
-					tag_array = exchange_mapi_util_resolve_named_prop (priv->olFolder, priv->fid, 0x8216, PSETID_Appointment);
+					tag_array = exchange_mapi_connection_resolve_named_prop (priv->conn, priv->olFolder, priv->fid, 0x8216, PSETID_Appointment);
 					if (tag_array) {
 						stream->proptag = tag_array->aulPropTag[0];
 						streams = g_slist_append (streams, stream);
@@ -1945,7 +1948,7 @@ e_cal_backend_mapi_send_objects (ECalBackendSync *backend, EDataCal *cal, const
 			cbdata.globalid = &globalid;
 			cbdata.cleanglobalid = &globalid;
 
-			mid = exchange_mapi_create_item (olFolderSentMail, 0,
+			mid = exchange_mapi_connection_create_item (priv->conn, olFolderSentMail, 0,
 							exchange_mapi_cal_util_build_name_id, GINT_TO_POINTER(kind),
 							exchange_mapi_cal_util_build_props, &cbdata,
 							recipients, attachments, streams, MAPI_OPTIONS_DELETE_ON_SUBMIT_FAILURE);
diff --git a/src/camel/camel-mapi-folder.c b/src/camel/camel-mapi-folder.c
index fb8dca2..9cc64f6 100644
--- a/src/camel/camel-mapi-folder.c
+++ b/src/camel/camel-mapi-folder.c
@@ -593,7 +593,7 @@ mapi_update_cache (CamelFolder *folder, GSList *list, CamelFolderChangeInfo **ch
 
 			if ((item->header.from_type != NULL) && !g_utf8_collate (item->header.from_type, "EX")) {
 				CAMEL_SERVICE_REC_LOCK (mapi_store, connect_lock);
-				from_email = exchange_mapi_util_ex_to_smtp (item->header.from_email);
+				from_email = exchange_mapi_connection_ex_to_smtp (camel_mapi_store_get_exchange_connection (mapi_store), item->header.from_email);
 				CAMEL_SERVICE_REC_UNLOCK (mapi_store, connect_lock);
 
 				g_free (item->header.from_email);
@@ -715,7 +715,7 @@ mapi_sync_deleted (CamelSession *session, CamelSessionThreadMsg *msg)
 	CAMEL_SERVICE_REC_LOCK (mapi_store, connect_lock);
 
 	/*Get the UID list from server.*/
-	exchange_mapi_connection_fetch_items  (m->folder_id, NULL, NULL,
+	exchange_mapi_connection_fetch_items  (camel_mapi_store_get_exchange_connection (mapi_store), m->folder_id, NULL, NULL,
 					       prop_list, G_N_ELEMENTS (prop_list),
 					       NULL, NULL,
 					       deleted_items_sync_cb, &server_uid_list,
@@ -922,7 +922,7 @@ mapi_sync (CamelFolder *folder, gboolean expunge, CamelException *ex)
 
 	if (read_items) {
 		CAMEL_SERVICE_REC_LOCK (mapi_store, connect_lock);
-		exchange_mapi_set_flags (0, fid, read_items, 0, options);
+		exchange_mapi_connection_set_flags (camel_mapi_store_get_exchange_connection (mapi_store), 0, fid, read_items, 0, options);
 		CAMEL_SERVICE_REC_UNLOCK (mapi_store, connect_lock);
 		g_slist_free (read_items);
 	}
@@ -931,10 +931,10 @@ mapi_sync (CamelFolder *folder, gboolean expunge, CamelException *ex)
 	if (deleted_items) {
 		CAMEL_SERVICE_REC_LOCK (mapi_store, connect_lock);
 		if ((mapi_folder->type & CAMEL_FOLDER_TYPE_MASK) == CAMEL_FOLDER_TYPE_TRASH) {
-			exchange_mapi_remove_items (0, fid, deleted_items);
+			exchange_mapi_connection_remove_items (camel_mapi_store_get_exchange_connection (mapi_store), 0, fid, deleted_items);
 		} else {
 			exchange_mapi_util_mapi_id_from_string (camel_mapi_store_system_folder_fid (mapi_store, olFolderDeletedItems), &deleted_items_fid);
-			exchange_mapi_move_items(fid, deleted_items_fid, deleted_items);
+			exchange_mapi_connection_move_items (camel_mapi_store_get_exchange_connection (mapi_store), fid, deleted_items_fid, deleted_items);
 		}
 
 		CAMEL_SERVICE_REC_UNLOCK (mapi_store, connect_lock);
@@ -1007,7 +1007,7 @@ camel_mapi_folder_fetch_summary (CamelStore *store, const mapi_id_t fid, struct
 
 	CAMEL_SERVICE_REC_LOCK (mapi_store, connect_lock);
 
-	status = exchange_mapi_connection_fetch_items  (fid, res, sort, summary_prop_list,
+	status = exchange_mapi_connection_fetch_items  (camel_mapi_store_get_exchange_connection (mapi_store), fid, res, sort, summary_prop_list,
 							G_N_ELEMENTS (summary_prop_list),
 							NULL, NULL, fetch_items_summary_cb,
 							fetch_data, options);
@@ -1352,7 +1352,7 @@ fetch_item_cb (FetchItemsCallbackData *item_data, gpointer data)
 
 	item->is_cal = FALSE;
 	if (g_str_has_prefix (msg_class, IPM_SCHEDULE_MEETING_PREFIX)) {
-		guint8 *appointment_body_str = (guint8 *) exchange_mapi_cal_util_camel_helper (item_data->properties,
+		guint8 *appointment_body_str = (guint8 *) exchange_mapi_cal_util_camel_helper (item_data->conn, item_data->properties,
 											     item_data->streams,
 											     item_data->recipients, item_data->attachments);
 
@@ -1525,7 +1525,7 @@ mapi_mime_set_msg_headers (CamelFolder *folder, CamelMimeMessage *msg, MapiItem
 	if (item->header.from) {
 		if ((item->header.from_type != NULL) && !g_utf8_collate (item->header.from_type, "EX")) {
 			CAMEL_SERVICE_REC_LOCK (mapi_store, connect_lock);
-			from_email = exchange_mapi_util_ex_to_smtp (item->header.from_email);
+			from_email = exchange_mapi_connection_ex_to_smtp (camel_mapi_store_get_exchange_connection (mapi_store), item->header.from_email);
 			CAMEL_SERVICE_REC_UNLOCK (mapi_store, connect_lock);
 			g_free (item->header.from_email);
 			item->header.from_email = g_strdup (from_email);
@@ -1899,7 +1899,7 @@ mapi_folder_get_message( CamelFolder *folder, const gchar *uid, CamelException *
 	}
 
 	CAMEL_SERVICE_REC_LOCK (mapi_store, connect_lock);
-	exchange_mapi_connection_fetch_item (id_folder, id_message,
+	exchange_mapi_connection_fetch_item (camel_mapi_store_get_exchange_connection (mapi_store), id_folder, id_message,
 					camel_GetPropsList, G_N_ELEMENTS (camel_GetPropsList),
 					camel_build_name_id, NULL,
 					fetch_item_cb, &item,
@@ -2028,7 +2028,7 @@ mapi_expunge (CamelFolder *folder, CamelException *ex)
 
 	if ((mapi_folder->type & CAMEL_FOLDER_TYPE_MASK) == CAMEL_FOLDER_TYPE_TRASH) {
 		CAMEL_SERVICE_REC_LOCK (mapi_store, connect_lock);
-		status = exchange_mapi_empty_folder (fid);
+		status = exchange_mapi_connection_empty_folder (camel_mapi_store_get_exchange_connection (mapi_store), fid);
 		CAMEL_SERVICE_REC_UNLOCK (mapi_store, connect_lock);
 
 		if (status) {
@@ -2072,7 +2072,7 @@ mapi_expunge (CamelFolder *folder, CamelException *ex)
 	if (deleted_items) {
 		CAMEL_SERVICE_REC_LOCK (mapi_store, connect_lock);
 
-		status = exchange_mapi_remove_items(0, fid, deleted_items);
+		status = exchange_mapi_connection_remove_items (camel_mapi_store_get_exchange_connection (mapi_store), 0, fid, deleted_items);
 
 		CAMEL_SERVICE_REC_UNLOCK (mapi_store, connect_lock);
 
@@ -2136,7 +2136,7 @@ mapi_transfer_messages_to (CamelFolder *source, GPtrArray *uids,
 	}
 
 	if (delete_originals) {
-		if (!exchange_mapi_move_items (src_fid, dest_fid, src_msg_ids)) {
+		if (!exchange_mapi_connection_move_items (camel_mapi_store_get_exchange_connection (mapi_store), src_fid, dest_fid, src_msg_ids)) {
 			//TODO : Set exception.
 		} else {
 			changes = camel_folder_change_info_new ();
@@ -2150,7 +2150,7 @@ mapi_transfer_messages_to (CamelFolder *source, GPtrArray *uids,
 
 		}
 	} else {
-		if (!exchange_mapi_copy_items (src_fid, dest_fid, src_msg_ids)) {
+		if (!exchange_mapi_connection_copy_items (camel_mapi_store_get_exchange_connection (mapi_store), src_fid, dest_fid, src_msg_ids)) {
 			//TODO : Set exception.
 		}
 	}
@@ -2222,7 +2222,7 @@ mapi_append_message (CamelFolder *folder, CamelMimeMessage *message,
 
 	item = camel_mapi_utils_mime_to_item (message, from, ex);
 
-	mid = exchange_mapi_create_item (-1, fid, NULL, NULL,
+	mid = exchange_mapi_connection_create_item (camel_mapi_store_get_exchange_connection (mapi_store), -1, fid, NULL, NULL,
 					 camel_mapi_utils_create_item_build_props, item,
 					 item->recipients, item->attachments,
 					 item->generic_streams, 0);
diff --git a/src/camel/camel-mapi-notifications.c b/src/camel/camel-mapi-notifications.c
index aa57c43..503fd9e 100644
--- a/src/camel/camel-mapi-notifications.c
+++ b/src/camel/camel-mapi-notifications.c
@@ -208,6 +208,7 @@ mapi_push_notification_listener_thread (gpointer data)
 	struct mapi_push_notification_data *thread_data = data;
 	CamelMapiStore *mapi_store = (CamelMapiStore *) thread_data->event_data;
 	struct mapi_notify_continue_callback_data *cb_data = g_new0 (struct mapi_notify_continue_callback_data, 1);
+	ExchangeMapiConnection *conn;
 
 	g_return_val_if_fail (data != NULL, NULL);
 
@@ -221,18 +222,27 @@ mapi_push_notification_listener_thread (gpointer data)
 
 	CAMEL_SERVICE_REC_LOCK (mapi_store, connect_lock);
 
-	if (exchange_mapi_events_init ()) {
-		exchange_mapi_events_subscribe (thread_data->event_options, thread_data->event_mask,
+	conn = camel_mapi_store_get_exchange_connection (mapi_store);
+	if (!conn) {
+		CAMEL_SERVICE_REC_UNLOCK (mapi_store, connect_lock);
+		g_return_val_if_reached (NULL);
+	}
+
+	g_object_ref (conn);
+
+	if (exchange_mapi_connection_events_init (camel_mapi_store_get_exchange_connection (mapi_store))) {
+		exchange_mapi_connection_events_subscribe (conn, thread_data->event_options, thread_data->event_mask,
 						&thread_data->connection, mapi_notifications_filter,
 						thread_data->event_data);
 
 		CAMEL_SERVICE_REC_UNLOCK (mapi_store, connect_lock);
-		exchange_mapi_events_monitor (cb_data); /*Blocking call. Don't hold locks here*/
-		exchange_mapi_events_unsubscribe (thread_data->connection);
+		exchange_mapi_connection_events_monitor (conn, cb_data); /*Blocking call. Don't hold locks here*/
+		exchange_mapi_connection_events_unsubscribe (conn, thread_data->connection);
 	} else
 		CAMEL_SERVICE_REC_UNLOCK (mapi_store, connect_lock);
 
 	g_free (cb_data);
+	g_object_unref (conn);
 
 	return NULL;
 }
diff --git a/src/camel/camel-mapi-store.c b/src/camel/camel-mapi-store.c
index ed17ccd..c4113ef 100644
--- a/src/camel/camel-mapi-store.c
+++ b/src/camel/camel-mapi-store.c
@@ -60,8 +60,9 @@
 #define d(x) printf("%s:%s:%s \n", G_STRLOC, G_STRFUNC, x)
 
 struct _CamelMapiStorePrivate {
-	gchar *user;
-	const gchar *profile;
+	gchar *profile;
+	ExchangeMapiConnection *conn;
+
 	gchar *base_url;
 	gchar *storage_path;
 
@@ -218,6 +219,7 @@ static void camel_mapi_store_init(CamelMapiStore *store, CamelMapiStoreClass *kl
 
 	mapi_store->summary = NULL;
 
+	priv->conn = NULL;
 	priv->storage_path = NULL;
 	priv->base_url = NULL;
 	priv->folders_synced = FALSE;
@@ -229,6 +231,41 @@ static void camel_mapi_store_init(CamelMapiStore *store, CamelMapiStoreClass *kl
 
 static void camel_mapi_store_finalize(CamelObject *object)
 {
+	CamelMapiStore *mapi_store = CAMEL_MAPI_STORE (object);
+
+	if (mapi_store && mapi_store->priv) {
+		CamelMapiStorePrivate *priv = mapi_store->priv;
+
+		#define freeStr(x)		\
+			if (x) {		\
+				g_free (x);	\
+				x = NULL;	\
+			}
+		#define destroyHash(h)				\
+			if (h) {				\
+				g_hash_table_destroy (h);	\
+				h = NULL;			\
+			}
+
+		freeStr (priv->profile);
+		freeStr (priv->storage_path);
+		freeStr (priv->base_url);
+		destroyHash (priv->id_hash);
+		destroyHash (priv->name_hash);
+		destroyHash (priv->parent_hash);
+		destroyHash (priv->default_folders);
+
+		if (priv->conn) {
+			g_object_unref (priv->conn);
+			priv->conn = NULL;
+		}
+
+		#undef freeStr
+		#undef destroyHash
+
+		g_free (mapi_store->priv);
+		mapi_store->priv = NULL;
+	}
 }
 
 /* service methods */
@@ -267,7 +304,6 @@ static void mapi_construct(CamelService *service, CamelSession *session,
 	camel_store_summary_load ((CamelStoreSummary *) mapi_store->summary);
 
 	/*user and profile*/
-	priv->user = g_strdup (url->user);
 	priv->profile = g_strdup (camel_url_get_param(url, "profile"));
 
 	/*base url*/
@@ -309,14 +345,15 @@ static char
 static gboolean
 check_for_connection (CamelService *service, CamelException *ex)
 {
-	/*Fixme : What happens when the network connection drops.
-	  will mapi subsystem handle that ?*/
-	return exchange_mapi_connection_exists ();
+	CamelMapiStore *store = CAMEL_MAPI_STORE (service);
+
+	return store && store->priv->conn && exchange_mapi_connection_connected (store->priv->conn);
 }
 
 static gboolean
 mapi_auth_loop (CamelService *service, CamelException *ex)
 {
+	CamelMapiStore *store = CAMEL_MAPI_STORE (service);
 	CamelSession *session = camel_service_get_session (service);
 
 	gchar *errbuf = NULL;
@@ -357,9 +394,8 @@ mapi_auth_loop (CamelService *service, CamelException *ex)
 			}
 		}
 
-		exchange_mapi_connection_new (NULL,service->url->passwd);
-
-		if (!exchange_mapi_connection_exists ()) {
+		store->priv->conn = exchange_mapi_connection_new (store->priv->profile, service->url->passwd);
+		if (!store->priv->conn || !exchange_mapi_connection_connected (store->priv->conn)) {
 			errbuf = g_strdup_printf (_("Unable to authenticate to Exchange MAPI server."));
 
 			camel_exception_clear (ex);
@@ -440,8 +476,11 @@ mapi_disconnect(CamelService *service, gboolean clean, CamelException *ex)
 		store->priv->notification_data = NULL;
 	}
 
-	/* Close the mapi subsystem */
-	exchange_mapi_connection_close ();
+	if (store->priv->conn) {
+		/* Close the mapi subsystem */
+		g_object_unref (store->priv->conn);
+		store->priv->conn = NULL;
+	}
 
 	store->priv->folders_synced = FALSE;
 
@@ -557,7 +596,7 @@ mapi_create_folder(CamelStore *store, const gchar *parent_name, const gchar *fol
 	CAMEL_SERVICE_REC_LOCK (store, connect_lock);
 
 	exchange_mapi_util_mapi_id_from_string (parent_id, &parent_fid);
-	new_folder_id = exchange_mapi_create_folder(olFolderInbox, parent_fid, folder_name);
+	new_folder_id = exchange_mapi_connection_create_folder (priv->conn, olFolderInbox, parent_fid, folder_name);
 	if (new_folder_id != 0) {
 		CamelMapiStoreInfo *si;
 		gchar *fid = g_strdup_printf ("%016" G_GINT64_MODIFIER "X", new_folder_id);
@@ -633,7 +672,7 @@ mapi_delete_folder(CamelStore *store, const gchar *folder_name, CamelException *
 
 	folder_id = g_hash_table_lookup (priv->name_hash, folder_name);
 	exchange_mapi_util_mapi_id_from_string (folder_id, &folder_fid);
-	status = exchange_mapi_remove_folder (0, folder_fid);
+	status = exchange_mapi_connection_remove_folder (priv->conn, folder_fid);
 
 	if (status) {
 		/* Fixme ??  */
@@ -720,7 +759,7 @@ mapi_rename_folder(CamelStore *store, const gchar *old_name, const gchar *new_na
 		gchar *folder_id;
 
 		/* renaming in the same folder, thus no MoveFolder necessary */
-		if (!exchange_mapi_rename_folder (old_fid, tmp ? tmp : new_name)) {
+		if (!exchange_mapi_connection_rename_folder (priv->conn, old_fid, tmp ? tmp : new_name)) {
 			/*To translators : '%s to %s' is current name of the folder  and
 			new name of the folder.*/
 			camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
@@ -771,7 +810,7 @@ mapi_rename_folder(CamelStore *store, const gchar *old_name, const gchar *new_na
 		} else if (!old_parent_fid_str || !new_parent_fid_str ||
 			   !exchange_mapi_util_mapi_id_from_string (old_parent_fid_str, &old_parent_fid) ||
 			   !exchange_mapi_util_mapi_id_from_string (new_parent_fid_str, &new_parent_fid) ||
-			   !exchange_mapi_move_folder (old_fid, old_parent_fid, new_parent_fid, tmp)) {
+			   !exchange_mapi_connection_move_folder (priv->conn, old_fid, old_parent_fid, new_parent_fid, tmp)) {
 			CAMEL_SERVICE_REC_UNLOCK (mapi_store, connect_lock);
 			camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, _("Cannot rename MAPI folder `%s' to `%s'"), old_name, new_name);
 			g_free (old_parent);
@@ -1351,7 +1390,7 @@ mapi_folders_sync (CamelMapiStore *store, const gchar *top, guint32 flags, Camel
 		return;
 	}
 
-	status = exchange_mapi_get_folders_list (&folder_list);
+	status = exchange_mapi_connection_get_folders_list (priv->conn, &folder_list);
 
 	if (!status) {
 		g_warning ("Could not get folder list..\n");
@@ -1380,7 +1419,7 @@ mapi_folders_sync (CamelMapiStore *store, const gchar *top, guint32 flags, Camel
 		parent_id = (top) ? g_strdup (camel_mapi_store_folder_id_lookup_offline (store, top)) : NULL;
 		exchange_mapi_util_mapi_id_from_string (parent_id, &pid);
 
-		status = exchange_mapi_get_pf_folders_list (&folder_list, pid);
+		status = exchange_mapi_connection_get_pf_folders_list (priv->conn, &folder_list, pid);
 
 		if (!status)
 			g_warning ("Could not get Public folder list..\n");
@@ -1700,3 +1739,12 @@ mapi_noop(CamelStore *store, CamelException *ex)
 
 }
 
+ExchangeMapiConnection *
+camel_mapi_store_get_exchange_connection (CamelMapiStore *mapi_store)
+{
+	g_return_val_if_fail (mapi_store != NULL, NULL);
+	g_return_val_if_fail (CAMEL_IS_MAPI_STORE (mapi_store), NULL);
+	g_return_val_if_fail (mapi_store->priv != NULL, NULL);
+
+	return mapi_store->priv->conn;
+}
diff --git a/src/camel/camel-mapi-store.h b/src/camel/camel-mapi-store.h
index d2cde6e..67137a0 100644
--- a/src/camel/camel-mapi-store.h
+++ b/src/camel/camel-mapi-store.h
@@ -28,6 +28,7 @@
 
 #include <camel/camel.h>
 
+#include <exchange-mapi-connection.h>
 #include <exchange-mapi-folder.h>
 
 #define CAMEL_MAPI_STORE_TYPE     (camel_mapi_store_get_type ())
@@ -94,6 +95,8 @@ const gchar * mapi_folders_hash_table_name_lookup (CamelMapiStore *store, const
 
 void camel_mapi_store_unset_notification_data (CamelMapiStore *mstore);
 
+ExchangeMapiConnection *camel_mapi_store_get_exchange_connection (CamelMapiStore *mapi_store);
+
 __END_DECLS
 
 #endif /* __CAMEL_OPENCHANGE_STORE_H__ */
diff --git a/src/camel/camel-mapi-transport.c b/src/camel/camel-mapi-transport.c
index fb7ae46..cec9f11 100644
--- a/src/camel/camel-mapi-transport.c
+++ b/src/camel/camel-mapi-transport.c
@@ -55,12 +55,12 @@ void	set_store(CamelStore *);
 
 /*CreateItem would return the MID of the new message or '0' if we fail.*/
 static mapi_id_t
-mapi_message_item_send (MapiItem *item)
+mapi_message_item_send (ExchangeMapiConnection *conn, MapiItem *item)
 {
 	guint64 fid = 0;
 	mapi_id_t mid = 0;
 
-	mid = exchange_mapi_create_item (olFolderSentMail, fid, NULL, NULL,
+	mid = exchange_mapi_connection_create_item (conn, olFolderSentMail, fid, NULL, NULL,
 					 camel_mapi_utils_create_item_build_props,
 					 item, item->recipients,
 					 item->attachments, item->generic_streams, MAPI_OPTIONS_DELETE_ON_SUBMIT_FAILURE);
@@ -72,20 +72,35 @@ static gboolean
 mapi_send_to (CamelTransport *transport, CamelMimeMessage *message,
 	      CamelAddress *from, CamelAddress *recipients, CamelException *ex)
 {
+	ExchangeMapiConnection *conn;
 	MapiItem *item = NULL;
 	const gchar *namep;
 	const gchar *addressp;
 	mapi_id_t st = 0;
+	CamelURL *url;
 
 	if (!camel_internet_address_get((CamelInternetAddress *)from, 0, &namep, &addressp)) {
 		return (FALSE);
 	}
 
+	g_return_val_if_fail (CAMEL_IS_SERVICE (transport), FALSE);
+
+	url = CAMEL_SERVICE (transport)->url;
+	g_return_val_if_fail (url != NULL, FALSE);
+
+	conn = exchange_mapi_connection_find (camel_url_get_param (url, "profile"));
+	if (!conn) {
+		camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE, _("Could not send message."));
+		return FALSE;
+	}
+
 	/* Convert MIME to MAPIItem, attacment lists and recipient list.*/
 	item = camel_mapi_utils_mime_to_item (message, from, ex);
 
 	/* send */
-	st = mapi_message_item_send(item);
+	st = mapi_message_item_send (conn, item);
+
+	g_object_unref (conn);
 
 	if (st == 0) {
 		/*Fixme : Set a better error message. Would be helful in troubleshooting. */
diff --git a/src/libexchangemapi/exchange-mapi-cal-utils.c b/src/libexchangemapi/exchange-mapi-cal-utils.c
index a7089b1..e0e8e76 100644
--- a/src/libexchangemapi/exchange-mapi-cal-utils.c
+++ b/src/libexchangemapi/exchange-mapi-cal-utils.c
@@ -669,7 +669,7 @@ id_to_string (GByteArray *ba)
 }
 
 ECalComponent *
-exchange_mapi_cal_util_mapi_props_to_comp (icalcomponent_kind kind, const gchar *mid, struct mapi_SPropValue_array *properties,
+exchange_mapi_cal_util_mapi_props_to_comp (ExchangeMapiConnection *conn, icalcomponent_kind kind, const gchar *mid, struct mapi_SPropValue_array *properties,
 					   GSList *streams, GSList *recipients, GSList *attachments,
 					   const gchar *local_store_uri, const icaltimezone *default_zone)
 {
@@ -823,9 +823,9 @@ exchange_mapi_cal_util_mapi_props_to_comp (icalcomponent_kind kind, const gchar
 				const gchar *sent_email = (const gchar *) exchange_mapi_util_find_array_propval (properties, PR_SENT_REPRESENTING_EMAIL_ADDRESS);
 
 				if (!g_utf8_collate (sender_email_type, "EX"))
-					sender_email = exchange_mapi_util_ex_to_smtp (sender_email);
+					sender_email = exchange_mapi_connection_ex_to_smtp (conn, sender_email);
 				if (!g_utf8_collate (sent_email_type, "EX"))
-					sent_email = exchange_mapi_util_ex_to_smtp (sent_email);
+					sent_email = exchange_mapi_connection_ex_to_smtp (conn, sent_email);
 
 				val = g_strdup_printf ("MAILTO:%s", sent_email);
 				prop = icalproperty_new_organizer (val);
@@ -1019,7 +1019,7 @@ fetch_server_data_cb (FetchItemsCallbackData *item_data, gpointer data)
 	gchar *filename = g_build_filename (g_get_home_dir (), TEMP_ATTACH_STORE, NULL);
 	gchar *fileuri = g_filename_to_uri (filename, NULL, NULL);
 	gchar *smid = exchange_mapi_util_mapi_id_to_string (mid);
-	ECalComponent *comp = exchange_mapi_cal_util_mapi_props_to_comp (kind, smid, properties, streams, recipients, attachments, fileuri, NULL);
+	ECalComponent *comp = exchange_mapi_cal_util_mapi_props_to_comp (item_data->conn, kind, smid, properties, streams, recipients, attachments, fileuri, NULL);
 	struct cbdata *cbdata = (struct cbdata *)(data);
 	const uint32_t *ui32;
 
@@ -1046,14 +1046,14 @@ fetch_server_data_cb (FetchItemsCallbackData *item_data, gpointer data)
 }
 
 static void
-fetch_server_data (mapi_id_t mid, struct cbdata *cbd)
+fetch_server_data (ExchangeMapiConnection *conn, mapi_id_t mid, struct cbdata *cbd)
 {
 	icalcomponent_kind kind = ICAL_VEVENT_COMPONENT;
 	mapi_id_t fid;
 
-	fid = exchange_mapi_get_default_folder_id (olFolderCalendar);
+	fid = exchange_mapi_connection_get_default_folder_id (conn, olFolderCalendar);
 
-	exchange_mapi_connection_fetch_item (fid, mid,
+	exchange_mapi_connection_fetch_item (conn, fid, mid,
 					cal_GetPropsList, G_N_ELEMENTS (cal_GetPropsList),
 					exchange_mapi_cal_util_build_name_id, GINT_TO_POINTER (kind),
 					fetch_server_data_cb, cbd,
@@ -1062,7 +1062,7 @@ fetch_server_data (mapi_id_t mid, struct cbdata *cbd)
 }
 
 static ECalComponent *
-update_attendee_status (struct mapi_SPropValue_array *properties, mapi_id_t mid)
+update_attendee_status (ExchangeMapiConnection *conn, struct mapi_SPropValue_array *properties, mapi_id_t mid)
 {
 	const gchar *att, *att_sentby, *addrtype;
 	icalparameter_partstat partstat = ICAL_PARTSTAT_NONE;
@@ -1084,17 +1084,17 @@ update_attendee_status (struct mapi_SPropValue_array *properties, mapi_id_t mid)
 	else
 		return NULL;
 
-	fetch_server_data (mid, &cbdata);
+	fetch_server_data (conn, mid, &cbdata);
 
 	att = exchange_mapi_util_find_array_propval (properties, PR_SENT_REPRESENTING_EMAIL_ADDRESS);
 	addrtype = exchange_mapi_util_find_array_propval (properties, PR_SENT_REPRESENTING_ADDRTYPE);
 	if (addrtype && !g_ascii_strcasecmp (addrtype, "EX"))
-		att = exchange_mapi_util_ex_to_smtp (att);
+		att = exchange_mapi_connection_ex_to_smtp (conn, att);
 
 	att_sentby = exchange_mapi_util_find_array_propval (properties, PR_SENDER_EMAIL_ADDRESS);
 	addrtype = exchange_mapi_util_find_array_propval (properties, PR_SENDER_ADDRTYPE);
 	if (addrtype && !g_ascii_strcasecmp (addrtype, "EX"))
-		att_sentby = exchange_mapi_util_ex_to_smtp (att_sentby);
+		att_sentby = exchange_mapi_connection_ex_to_smtp (conn, att_sentby);
 
 	matt = g_strdup_printf ("MAILTO:%s", att);
 	matt_sentby = g_strdup_printf ("MAILTO:%s", att_sentby);
@@ -1130,7 +1130,7 @@ update_attendee_status (struct mapi_SPropValue_array *properties, mapi_id_t mid)
 		cbdata.get_timezone = NULL;
 		cbdata.get_tz_data = NULL;
 
-		status = exchange_mapi_modify_item (olFolderCalendar, fid, mid,
+		status = exchange_mapi_modify_item (conn, olFolderCalendar, fid, mid,
 				exchange_mapi_cal_util_build_name_id, GINT_TO_POINTER (kind),
 				exchange_mapi_cal_util_build_props, &cbdata,
 				recipients, attachments, streams, MAPI_OPTIONS_DONT_SUBMIT);
@@ -1157,21 +1157,21 @@ update_attendee_status (struct mapi_SPropValue_array *properties, mapi_id_t mid)
 }
 
 static void
-update_server_object (struct mapi_SPropValue_array *properties, GSList *attachments, ECalComponent *comp, mapi_id_t *mid)
+update_server_object (ExchangeMapiConnection *conn, struct mapi_SPropValue_array *properties, GSList *attachments, ECalComponent *comp, mapi_id_t *mid)
 {
 	const uint32_t *ui32 = NULL;
 	uint32_t cur_seq;
 	mapi_id_t fid;
 	gboolean create_new = TRUE;
 
-	fid = exchange_mapi_get_default_folder_id (olFolderCalendar);
+	fid = exchange_mapi_connection_get_default_folder_id (conn, olFolderCalendar);
 
 	ui32 = (const uint32_t *) find_mapi_SPropValue_data(properties, PROP_TAG(PT_LONG, 0x8201));
 	cur_seq = ui32 ? *ui32 : 0;
 
 	if (*mid) {
 		struct cbdata server_cbd = {0};
-		fetch_server_data (*mid, &server_cbd);
+		fetch_server_data (conn, *mid, &server_cbd);
 
 		if (cur_seq > server_cbd.appt_seq) {
 			struct id_list idlist;
@@ -1180,7 +1180,7 @@ update_server_object (struct mapi_SPropValue_array *properties, GSList *attachme
 			idlist.id = *mid;
 			ids = g_slist_append (ids, &idlist);
 
-			exchange_mapi_remove_items (olFolderCalendar, fid, ids);
+			exchange_mapi_connection_remove_items (conn, olFolderCalendar, fid, ids);
 			g_slist_free (ids);
 		} else
 			create_new = FALSE;
@@ -1216,7 +1216,7 @@ update_server_object (struct mapi_SPropValue_array *properties, GSList *attachme
 
 		exchange_mapi_cal_util_fetch_recipients (comp, &myrecipients);
 		myattachments = attachments;
-		*mid = exchange_mapi_create_item (olFolderCalendar, 0,
+		*mid = exchange_mapi_connection_create_item (conn, olFolderCalendar, 0,
 					exchange_mapi_cal_util_build_name_id, GINT_TO_POINTER(kind),
 					exchange_mapi_cal_util_build_props, &cbdata,
 					myrecipients, myattachments, NULL, MAPI_OPTIONS_DONT_SUBMIT);
@@ -1226,7 +1226,7 @@ update_server_object (struct mapi_SPropValue_array *properties, GSList *attachme
 }
 
 static void
-check_server_for_object (struct mapi_SPropValue_array *properties, mapi_id_t *mid)
+check_server_for_object (ExchangeMapiConnection *conn, struct mapi_SPropValue_array *properties, mapi_id_t *mid)
 {
 	struct mapi_SRestriction res;
 	struct SPropValue sprop;
@@ -1238,9 +1238,9 @@ check_server_for_object (struct mapi_SPropValue_array *properties, mapi_id_t *mi
 
 	*mid = 0;
 
-	fid = exchange_mapi_get_default_folder_id (olFolderCalendar);
+	fid = exchange_mapi_connection_get_default_folder_id (conn, olFolderCalendar);
 
-	array = exchange_mapi_util_resolve_named_prop (olFolderCalendar, fid, 0x0023, PSETID_Meeting);
+	array = exchange_mapi_connection_resolve_named_prop (conn, olFolderCalendar, fid, 0x0023, PSETID_Meeting);
 	proptag = array->aulPropTag[0];
 
 	res.rt = RES_PROPERTY;
@@ -1252,7 +1252,7 @@ check_server_for_object (struct mapi_SPropValue_array *properties, mapi_id_t *mi
 	set_SPropValue_proptag (&sprop, proptag, (gconstpointer ) sb);
 	cast_mapi_SPropValue (&(res.res.resProperty.lpProp), &sprop);
 
-	ids = exchange_mapi_util_check_restriction (fid, &res);
+	ids = exchange_mapi_connection_check_restriction (conn, fid, &res);
 
 	if (ids && g_slist_length(ids) == 1) {
 		struct id_list *idlist = (struct id_list *)(ids->data);
@@ -1267,7 +1267,7 @@ check_server_for_object (struct mapi_SPropValue_array *properties, mapi_id_t *mi
 }
 
 gchar *
-exchange_mapi_cal_util_camel_helper (struct mapi_SPropValue_array *properties,
+exchange_mapi_cal_util_camel_helper (ExchangeMapiConnection *conn, struct mapi_SPropValue_array *properties,
 				   GSList *streams, GSList *recipients, GSList *attachments)
 {
 	ECalComponent *comp = NULL;
@@ -1295,17 +1295,17 @@ exchange_mapi_cal_util_camel_helper (struct mapi_SPropValue_array *properties,
 	filename = g_build_filename (g_get_home_dir (), TEMP_ATTACH_STORE, NULL);
 	fileuri = g_filename_to_uri (filename, NULL, NULL);
 
-	check_server_for_object (properties, &mid);
+	check_server_for_object (conn, properties, &mid);
 
 	if (method == ICAL_METHOD_REPLY) {
 		if (mid) {
-			comp = update_attendee_status (properties, mid);
+			comp = update_attendee_status (conn, properties, mid);
 			set_attachments_to_cal_component (comp, attachments, fileuri);
 		}
 	} else if (method == ICAL_METHOD_CANCEL) {
 		if (mid) {
 			struct cbdata server_cbd = { 0 };
-			fetch_server_data (mid, &server_cbd);
+			fetch_server_data (conn, mid, &server_cbd);
 			comp = server_cbd.comp;
 			set_attachments_to_cal_component (comp, attachments, fileuri);
 
@@ -1317,12 +1317,12 @@ exchange_mapi_cal_util_camel_helper (struct mapi_SPropValue_array *properties,
 		else
 			smid = e_cal_component_gen_uid();
 
-		comp = exchange_mapi_cal_util_mapi_props_to_comp (kind, smid,
+		comp = exchange_mapi_cal_util_mapi_props_to_comp (conn, kind, smid,
 							properties, streams, recipients,
 							NULL, NULL, NULL);
 		set_attachments_to_cal_component (comp, attachments, fileuri);
 
-		update_server_object (properties, attachments, comp, &mid);
+		update_server_object (conn, properties, attachments, comp, &mid);
 
 		tmp = exchange_mapi_util_mapi_id_to_string (mid);
 		e_cal_component_set_uid (comp, tmp);
@@ -2142,7 +2142,7 @@ exchange_mapi_cal_util_build_props (struct SPropValue **value, struct SPropTagAr
 }
 
 uint32_t
-exchange_mapi_cal_util_get_new_appt_id (mapi_id_t fid)
+exchange_mapi_cal_util_get_new_appt_id (ExchangeMapiConnection *conn, mapi_id_t fid)
 {
 	struct mapi_SRestriction res;
 	struct SPropValue sprop;
@@ -2159,7 +2159,7 @@ exchange_mapi_cal_util_get_new_appt_id (mapi_id_t fid)
 			GSList *ids = NULL;
 			set_SPropValue_proptag (&sprop, PR_OWNER_APPT_ID, (gconstpointer ) &id);
 			cast_mapi_SPropValue (&(res.res.resProperty.lpProp), &sprop);
-			ids = exchange_mapi_util_check_restriction (fid, &res);
+			ids = exchange_mapi_connection_check_restriction (conn, fid, &res);
 			if (ids) {
 				GSList *l;
 				for (l = ids; l; l = l->next)
diff --git a/src/libexchangemapi/exchange-mapi-cal-utils.h b/src/libexchangemapi/exchange-mapi-cal-utils.h
index cd09f25..06148c3 100644
--- a/src/libexchangemapi/exchange-mapi-cal-utils.h
+++ b/src/libexchangemapi/exchange-mapi-cal-utils.h
@@ -82,7 +82,7 @@ void
 exchange_mapi_cal_util_fetch_attachments (ECalComponent *comp, GSList **attach_list, const gchar *local_store_uri);
 
 ECalComponent *
-exchange_mapi_cal_util_mapi_props_to_comp (icalcomponent_kind kind, const gchar *mid, struct mapi_SPropValue_array *properties,
+exchange_mapi_cal_util_mapi_props_to_comp (ExchangeMapiConnection *conn, icalcomponent_kind kind, const gchar *mid, struct mapi_SPropValue_array *properties,
 					   GSList *streams, GSList *recipients, GSList *attachments,
 					   const gchar *local_store_uri, const icaltimezone *default_zone);
 gboolean
@@ -95,11 +95,11 @@ void
 exchange_mapi_cal_util_generate_globalobjectid (gboolean is_clean, const gchar *uid, struct Binary_r *sb);
 
 gchar *
-exchange_mapi_cal_util_camel_helper (struct mapi_SPropValue_array *properties,
+exchange_mapi_cal_util_camel_helper (ExchangeMapiConnection *conn, struct mapi_SPropValue_array *properties,
 				   GSList *streams, GSList *recipients, GSList *attachments);
 
 uint32_t
-exchange_mapi_cal_util_get_new_appt_id (mapi_id_t fid);
+exchange_mapi_cal_util_get_new_appt_id (ExchangeMapiConnection *conn, mapi_id_t fid);
 
 static const uint32_t cal_GetPropsList[] = {
 	PR_FID,
diff --git a/src/libexchangemapi/exchange-mapi-connection.c b/src/libexchangemapi/exchange-mapi-connection.c
index 7e1fb11..aadcc0e 100644
--- a/src/libexchangemapi/exchange-mapi-connection.c
+++ b/src/libexchangemapi/exchange-mapi-connection.c
@@ -33,192 +33,320 @@
 
 #define DEFAULT_PROF_PATH ".evolution/mapi-profiles.ldb"
 
-static struct mapi_session *global_mapi_session= NULL;
-static GStaticRecMutex connect_lock = G_STATIC_REC_MUTEX_INIT;
+static void register_connection (ExchangeMapiConnection *conn);
+static void unregister_connection (ExchangeMapiConnection *conn);
+static struct mapi_session *mapi_profile_load (const gchar *profname, const gchar *password);
 
-#define LOCK()		g_debug("%s: %s: lock(connect_lock)", G_STRLOC, G_STRFUNC);g_static_rec_mutex_lock(&connect_lock);
-#define UNLOCK()	g_debug("%s: %s: unlock(connect_lock)", G_STRLOC, G_STRFUNC);g_static_rec_mutex_unlock(&connect_lock);
+/* GObject foo - begin */
 
-#if 0
-#define LOGALL()	lp_set_cmdline(global_mapi_ctx->lp_ctx, "log level", "10"); global_mapi_ctx->dumpdata = TRUE;
-#define LOGNONE()	lp_set_cmdline(global_mapi_ctx->lp_ctx, "log level", "0"); global_mapi_ctx->dumpdata = FALSE;
+G_DEFINE_TYPE (ExchangeMapiConnection, exchange_mapi_connection, G_TYPE_OBJECT)
 
-#define ENABLE_VERBOSE_LOG()	global_mapi_ctx->dumpdata = TRUE;
-#define DISABLE_VERBOSE_LOG()	global_mapi_ctx->dumpdata = FALSE;
-#endif
+#define EXCHANGE_MAPI_CONNECTION_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), EXCHANGE_TYPE_MAPI_CONNECTION, ExchangeMapiConnectionPrivate))
 
-//#if 0
-#define LOGALL()
-#define LOGNONE()
+/* These two macros require 'priv' variable of type ExchangeMapiConnectionPrivate */
+#define LOCK()		g_debug ("%s: %s: lock(session_lock)", G_STRLOC, G_STRFUNC); g_static_rec_mutex_lock (&priv->session_lock);
+#define UNLOCK()	g_debug ("%s: %s: unlock(session_lock)", G_STRLOC, G_STRFUNC); g_static_rec_mutex_unlock (&priv->session_lock);
 
-#define ENABLE_VERBOSE_LOG()
-#define DISABLE_VERBOSE_LOG()
-//#endif
+typedef struct _ExchangeMapiConnectionPrivate ExchangeMapiConnectionPrivate;
 
-/* Specifies READ/WRITE sizes to be used while handling normal streams */
-#define STREAM_MAX_READ_SIZE    0x1000
-#define STREAM_MAX_WRITE_SIZE   0x1000
-#define STREAM_ACCESS_READ      0x0000
-#define STREAM_ACCESS_WRITE     0x0001
-#define STREAM_ACCESS_READWRITE 0x0002
+struct _ExchangeMapiConnectionPrivate {
+	struct mapi_session *session;
+	GStaticRecMutex session_lock;
 
-static
-void mapi_debug_logger (const gchar * domain, GLogLevelFlags level,
-			const gchar * message, gpointer data)
-{
-	g_print ("[DEBUG] %s\n", message);
-}
+	gchar *profile;			/* profile name, where the session is connected to */
+	mapi_object_t msg_store;	/* valid only when session != NULL */
+
+	gboolean has_public_store;	/* whether is 'public_store' filled */
+	mapi_object_t public_store;
+
+	GSList *folders;		/* list of ExchangeMapiFolder pointers */
+};
 
-static
-void mapi_debug_logger_muted (const gchar * domain, GLogLevelFlags level,
-			      const gchar * message, gpointer data)
+/* should have session_lock locked already, when calling this function */
+static void
+disconnect (ExchangeMapiConnectionPrivate *priv)
 {
-	/*Nothing here. Just a dummy function*/
+	g_return_if_fail (priv != NULL);
+
+	if (!priv->session)
+		return;
+
+	if (priv->folders)
+		exchange_mapi_folder_free_list (priv->folders);
+
+	if (priv->has_public_store)
+		mapi_object_release (&priv->public_store);
+	Logoff (&priv->msg_store);
+	mapi_object_release (&priv->msg_store);
+
+	priv->session = NULL;
+	priv->has_public_store = FALSE;
+	priv->folders = NULL;
 }
 
+/* should have session_lock locked already, when calling this function */
 static gboolean
-ensure_mapi_init_called (void)
+ensure_public_store (ExchangeMapiConnectionPrivate *priv)
 {
-	static gboolean called = FALSE;
-	gchar *profpath;
-	enum MAPISTATUS status;
-
-	LOCK ();
-	if (called) {
-		UNLOCK ();
-		return TRUE;
-	}
+	g_return_val_if_fail (priv != NULL, FALSE);
 
-	profpath = g_build_filename (g_get_home_dir (), DEFAULT_PROF_PATH, NULL);
+	if (!priv->session)
+		return FALSE;
 
-	if (!g_file_test (profpath, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR)) {
-		/* Create a ProfileStore */
-		status = CreateProfileStore (profpath, LIBMAPI_LDIF_DIR);
-		if (status != MAPI_E_SUCCESS && (status != MAPI_E_NO_ACCESS || !g_file_test (profpath, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR))) {
-			mapi_errstr ("CreateProfileStore", GetLastError());
-			g_free (profpath);
+	if (!priv->has_public_store) {
+		mapi_object_init (&priv->public_store);
 
-			UNLOCK ();
-			return FALSE;
+		if (OpenPublicFolder (priv->session, &priv->public_store) == MAPI_E_SUCCESS) {
+			priv->has_public_store = TRUE;
+		} else {
+			mapi_errstr ("OpenPublicFolder", GetLastError());
 		}
 	}
 
-	status = MAPIInitialize (profpath);
-	if (status == MAPI_E_SESSION_LIMIT) {
-		/* do nothing, the profile store is already initialized */
-		/* but this shouldn't happen */
-		mapi_errstr ("MAPIInitialize", GetLastError());
-	} else if (status != MAPI_E_SUCCESS) {
-		mapi_errstr ("MAPIInitialize", GetLastError());
-		g_free (profpath);
+	return priv->has_public_store;
+}
+
+static void
+exchange_mapi_connection_finalize (GObject *object)
+{
+	ExchangeMapiConnectionPrivate *priv;
+
+	unregister_connection (EXCHANGE_MAPI_CONNECTION (object));
+
+	priv = EXCHANGE_MAPI_CONNECTION_GET_PRIVATE (object);
+
+	if (priv) {
+		LOCK ();
+		disconnect (priv);
+		g_free (priv->profile);
+		priv->profile = NULL;
 
 		UNLOCK ();
-		return FALSE;
+		g_static_rec_mutex_free (&priv->session_lock);
 	}
 
-	g_free (profpath);
+	if (G_OBJECT_CLASS (exchange_mapi_connection_parent_class)->finalize)
+		G_OBJECT_CLASS (exchange_mapi_connection_parent_class)->finalize (object);
+}
 
-	called = TRUE;
-	UNLOCK ();
+static void
+exchange_mapi_connection_class_init (ExchangeMapiConnectionClass *klass)
+{
+	GObjectClass *object_class;
 
-	return TRUE;
+	g_type_class_add_private (klass, sizeof (ExchangeMapiConnectionPrivate));
+
+	object_class = G_OBJECT_CLASS (klass);
+	object_class->finalize = exchange_mapi_connection_finalize;
 }
 
-static struct mapi_session *
-mapi_profile_load (const gchar *profname, const gchar *password)
+static void
+exchange_mapi_connection_init (ExchangeMapiConnection *conn)
 {
-	enum MAPISTATUS	retval = MAPI_E_SUCCESS;
-	struct mapi_session *session = NULL;
-	gchar *default_profile_name = NULL;
-	const gchar *profile = NULL;
-	guint32 debug_log_level = 0;
+	ExchangeMapiConnectionPrivate *priv;
 
-	/* Initialize libexchangemapi logger*/
-	if (g_getenv ("EXCHANGEMAPI_DEBUG")) {
-		g_log_set_handler (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, mapi_debug_logger, NULL);
-	} else
-		g_log_set_handler (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, mapi_debug_logger_muted, NULL);
+	priv = EXCHANGE_MAPI_CONNECTION_GET_PRIVATE (conn);
+	g_return_if_fail (priv != NULL);
 
-	g_debug("%s: Entering %s ", G_STRLOC, G_STRFUNC);
+	priv->session = NULL;
+	priv->profile = NULL;
+	priv->has_public_store = FALSE;
 
-	if (!ensure_mapi_init_called ())
-		goto cleanup;
+	register_connection (conn);
+}
 
-	/* Initialize libmapi logger*/
-	if (g_getenv ("MAPI_DEBUG")) {
-		debug_log_level = atoi (g_getenv ("MAPI_DEBUG"));
-		SetMAPIDumpData(TRUE);
-		SetMAPIDebugLevel(debug_log_level);
-	}
+/* GObject foo - end */
 
-	if (profname)
-		profile = profname;
-	else {
-		retval = GetDefaultProfile (&default_profile_name);
-		if (retval != MAPI_E_SUCCESS) {
-			mapi_errstr("GetDefaultProfile", GetLastError());
-			goto cleanup;
-		}
-		profile = default_profile_name;
+/* tracking alive connections - begin  */
+
+static GSList *known_connections = NULL;
+G_LOCK_DEFINE_STATIC (known_connections);
+
+static void
+register_connection (ExchangeMapiConnection *conn)
+{
+	g_return_if_fail (conn != NULL);
+	g_return_if_fail (EXCHANGE_IS_MAPI_CONNECTION (conn));
+
+	G_LOCK (known_connections);
+	/* append to prefer older connections when searching with exchange_mapi_connection_find() */
+	known_connections = g_slist_append (known_connections, conn);
+	G_UNLOCK (known_connections);
+}
+
+static void
+unregister_connection (ExchangeMapiConnection *conn)
+{
+	g_return_if_fail (conn != NULL);
+	g_return_if_fail (EXCHANGE_IS_MAPI_CONNECTION (conn));
+
+	G_LOCK (known_connections);
+	if (!g_slist_find (known_connections, conn)) {
+		G_UNLOCK (known_connections);
+		g_return_if_reached ();
 	}
-	g_debug("Loading profile %s ", profile);
 
-	retval = MapiLogonEx(&session, profile, password);
-	if (retval != MAPI_E_SUCCESS) {
-		mapi_errstr("MapiLogonEx", GetLastError());
-		goto cleanup;
+	known_connections = g_slist_remove (known_connections, conn);
+	G_UNLOCK (known_connections);
+}
+
+/* Tries to find a connection associated with the 'profile'.
+   If there are more, then the first created is returned.
+   Note if it doesn't return NULL, then the returned pointer
+   should be g_object_unref-ed, when done with it.
+*/
+ExchangeMapiConnection *
+exchange_mapi_connection_find (const gchar *profile)
+{
+	GSList *l;
+	ExchangeMapiConnection *res = NULL;
+
+	g_return_val_if_fail (profile != NULL, NULL);
+
+	G_LOCK (known_connections);
+	for (l = known_connections; l != NULL && res == NULL; l = l->next) {
+		ExchangeMapiConnection *conn = EXCHANGE_MAPI_CONNECTION (l->data);
+		ExchangeMapiConnectionPrivate *priv = EXCHANGE_MAPI_CONNECTION_GET_PRIVATE (conn);
+
+		if (priv && priv->profile && g_str_equal (profile, priv->profile))
+			res = conn;
 	}
 
-cleanup:
-	g_debug("%s: Leaving %s ", G_STRLOC, G_STRFUNC);
+	if (res)
+		g_object_ref (res);
 
-	return session;
+	G_UNLOCK (known_connections);
+
+	return res;
 }
 
-gboolean
-exchange_mapi_connection_exists ()
+/* tracking alive connections - end  */
+
+
+/* Specifies READ/WRITE sizes to be used while handling normal streams */
+#define STREAM_MAX_READ_SIZE    0x1000
+#define STREAM_MAX_WRITE_SIZE   0x1000
+#define STREAM_ACCESS_READ      0x0000
+#define STREAM_ACCESS_WRITE     0x0001
+#define STREAM_ACCESS_READWRITE 0x0002
+
+#define CHECK_CORRECT_CONN_AND_GET_PRIV(_conn, _val)				\
+	ExchangeMapiConnectionPrivate *priv;					\
+										\
+	g_return_val_if_fail (_conn != NULL, _val);				\
+	g_return_val_if_fail (EXCHANGE_IS_MAPI_CONNECTION (_conn), _val);	\
+										\
+	priv = EXCHANGE_MAPI_CONNECTION_GET_PRIVATE (_conn);			\
+	g_return_val_if_fail (priv != NULL, _val);
+
+/* Creates a new connection object and connects to a server as defined in 'profile' */
+ExchangeMapiConnection *
+exchange_mapi_connection_new (const gchar *profile, const gchar *password)
 {
-	return global_mapi_session != NULL;
+	ExchangeMapiConnection *conn;
+	ExchangeMapiConnectionPrivate *priv;
+	struct mapi_session *session;
+
+	g_return_val_if_fail (profile != NULL, NULL);
+
+	session = mapi_profile_load (profile, password);
+	if (!session) {
+		g_debug ("%s: %s: Login failed ", G_STRLOC, G_STRFUNC);
+		return NULL;
+	}
+
+	conn = g_object_new (EXCHANGE_TYPE_MAPI_CONNECTION, NULL);
+	priv = EXCHANGE_MAPI_CONNECTION_GET_PRIVATE (conn);
+	g_return_val_if_fail (priv != NULL, conn);
+
+	LOCK ();
+	mapi_object_init (&priv->msg_store);
+	priv->session = session;
+
+	/* Open the message store and keep it opened for all the life-time for this connection */
+	if (OpenMsgStore (priv->session, &priv->msg_store) != MAPI_E_SUCCESS) {
+		mapi_errstr ("OpenMsgStore", GetLastError());
+
+		/* how to close and free session without store? */
+		priv->session = NULL;
+
+		UNLOCK ();
+		g_object_unref (conn);
+		return NULL;
+	}
+
+	priv->profile = g_strdup (profile);
+	priv->has_public_store = FALSE;
+	UNLOCK ();
+
+	g_debug ("%s: %s: Connected ", G_STRLOC, G_STRFUNC);
+
+	return conn;
 }
 
 gboolean
-exchange_mapi_connection_new (const gchar *profile, const gchar *password)
+exchange_mapi_connection_close (ExchangeMapiConnection *conn)
 {
-	LOCK();
-	if (!global_mapi_session)
-		global_mapi_session = mapi_profile_load (profile, password);
-	UNLOCK();
+	gboolean res = FALSE;
 
-	if (!global_mapi_session)
-		g_debug ("%s: %s: Login failed ", G_STRLOC, G_STRFUNC);
-	else
-		g_debug ("%s: %s: Connected ", G_STRLOC, G_STRFUNC);
+	CHECK_CORRECT_CONN_AND_GET_PRIV (conn, FALSE);
+
+	LOCK ();
+
+	res = priv->session != NULL;
+	disconnect (priv);
+
+	UNLOCK ();
 
-	return global_mapi_session != NULL;
+	return res;
 }
 
-void
-exchange_mapi_connection_close (void)
+gboolean
+exchange_mapi_connection_reconnect (ExchangeMapiConnection *conn, const gchar *password)
 {
-	LOCK();
+	CHECK_CORRECT_CONN_AND_GET_PRIV (conn, FALSE);
 
-	if (global_mapi_session) {
-		mapi_object_t obj_store;
-		enum MAPISTATUS status;
+	g_return_val_if_fail (priv->profile != NULL, FALSE);
 
-		mapi_object_init (&obj_store);
+	LOCK ();
+	if (priv->session)
+		exchange_mapi_connection_close (conn);
 
-		/* Open the message store */
-		status = OpenMsgStore (global_mapi_session, &obj_store);
-		if (status != MAPI_E_SUCCESS) {
-			mapi_errstr ("OpenMsgStore", GetLastError());
-		} else {
-			Logoff (&obj_store);
-		}
+	priv->session = mapi_profile_load (priv->profile, password);
+	if (!priv->session) {
+		g_debug ("%s: %s: Login failed ", G_STRLOC, G_STRFUNC);
+		UNLOCK ();
+		return FALSE;
 	}
-	global_mapi_session = NULL;
 
-	UNLOCK();
+	mapi_object_init (&priv->msg_store);
+
+	/* Open the message store and keep it opened for all the life-time for this connection */
+	if (OpenMsgStore (priv->session, &priv->msg_store) != MAPI_E_SUCCESS) {
+		mapi_errstr ("OpenMsgStore", GetLastError());
+
+		/* how to close and free session without store? */
+		priv->session = NULL;
+
+		UNLOCK ();
+		return FALSE;
+	}
+
+	priv->has_public_store = FALSE;
+
+	UNLOCK ();
+
+	g_debug ("%s: %s: Connected ", G_STRLOC, G_STRFUNC);
+
+	return priv->session != NULL;
+}
+
+gboolean
+exchange_mapi_connection_connected (ExchangeMapiConnection *conn)
+{
+	CHECK_CORRECT_CONN_AND_GET_PRIV (conn, FALSE);
+
+	return priv->session != NULL;
 }
 
 static gboolean
@@ -797,7 +925,7 @@ mapidump_PAB_gal_entry (struct SRow *aRow)
 }
 
 gboolean
-exchange_mapi_util_get_gal (GPtrArray *contacts_array)
+exchange_mapi_connection_get_gal (ExchangeMapiConnection *conn, GPtrArray *contacts_array)
 {
 	struct SPropTagArray	*SPropTagArray;
 	struct SRowSet		*SRowSet;
@@ -807,6 +935,8 @@ exchange_mapi_util_get_gal (GPtrArray *contacts_array)
 	uint8_t			ulFlags;
 	TALLOC_CTX *mem_ctx;
 
+	CHECK_CORRECT_CONN_AND_GET_PRIV (conn, FALSE);
+
 	mem_ctx = talloc_init ("ExchangeMAPI_GetGAL");
 
 	LOCK ();
@@ -830,7 +960,7 @@ exchange_mapi_util_get_gal (GPtrArray *contacts_array)
 	do {
 		count += 0x2;
 		SRowSet = NULL;
-		retval = GetGALTable(global_mapi_session, SPropTagArray, &SRowSet, count, ulFlags);
+		retval = GetGALTable (priv->session, SPropTagArray, &SRowSet, count, ulFlags);
 		if ((!SRowSet) || (!(SRowSet->aRow)) || retval != MAPI_E_SUCCESS) {
 			UNLOCK ();
 			MAPIFreeBuffer (SPropTagArray);
@@ -942,8 +1072,8 @@ set_recipient_properties (TALLOC_CTX *mem_ctx, struct SRow *aRow, ExchangeMAPIRe
 		SRow_addprop (aRow, recipient->in.req_lpProps[i]);
 }
 
-static void
-exchange_mapi_util_modify_recipients (TALLOC_CTX *mem_ctx, mapi_object_t *obj_message , GSList *recipients, gboolean remove_existing)
+static gboolean
+exchange_mapi_util_modify_recipients (ExchangeMapiConnection *conn, TALLOC_CTX *mem_ctx, mapi_object_t *obj_message , GSList *recipients, gboolean remove_existing)
 {
 	enum MAPISTATUS	retval;
 	struct SPropTagArray	*SPropTagArray = NULL;
@@ -953,6 +1083,9 @@ exchange_mapi_util_modify_recipients (TALLOC_CTX *mem_ctx, mapi_object_t *obj_me
 	const gchar		**users = NULL;
 	uint32_t		i, j, count = 0;
 
+	CHECK_CORRECT_CONN_AND_GET_PRIV (conn, FALSE);
+	g_return_val_if_fail (priv->session != NULL, FALSE);
+
 	g_debug("%s: Entering %s ", G_STRLOC, G_STRFUNC);
 
 	SPropTagArray = set_SPropTagArray(mem_ctx, 0xA,
@@ -977,7 +1110,7 @@ exchange_mapi_util_modify_recipients (TALLOC_CTX *mem_ctx, mapi_object_t *obj_me
 
 	/* Attempt to resolve names from the server */
 	LOCK ();
-	retval = ResolveNames (global_mapi_session, users, SPropTagArray, &SRowSet, &FlagList, MAPI_UNICODE);
+	retval = ResolveNames (priv->session, users, SPropTagArray, &SRowSet, &FlagList, MAPI_UNICODE);
 	UNLOCK ();
 	if (retval != MAPI_E_SUCCESS) {
 		mapi_errstr("ResolveNames", GetLastError());
@@ -1030,14 +1163,15 @@ cleanup:
 	g_free (users);
 
 	g_debug("%s: Leaving %s ", G_STRLOC, G_STRFUNC);
+
+	return TRUE;
 }
 
 GSList *
-exchange_mapi_util_check_restriction (mapi_id_t fid, struct mapi_SRestriction *res)
+exchange_mapi_connection_check_restriction (ExchangeMapiConnection *conn, mapi_id_t fid, struct mapi_SRestriction *res)
 {
 	enum MAPISTATUS retval;
 	TALLOC_CTX *mem_ctx;
-	mapi_object_t obj_store;
 	mapi_object_t obj_folder;
 	mapi_object_t obj_table;
 	struct SPropTagArray *SPropTagArray, *GetPropsTagArray;
@@ -1045,24 +1179,18 @@ exchange_mapi_util_check_restriction (mapi_id_t fid, struct mapi_SRestriction *r
 	uint32_t count, i;
 	GSList *mids = NULL;
 
+	CHECK_CORRECT_CONN_AND_GET_PRIV (conn, NULL);
+	g_return_val_if_fail (priv->session != NULL, NULL);
+
 	g_debug("%s: Entering %s: folder-id %016" G_GINT64_MODIFIER "X ", G_STRLOC, G_STRFUNC, fid);
 
-	LOCK();
-	LOGALL();
+	LOCK ();
 	mem_ctx = talloc_init("ExchangeMAPI_CheckRestriction");
-	mapi_object_init(&obj_store);
 	mapi_object_init(&obj_folder);
 	mapi_object_init(&obj_table);
 
-	/* Open the message store */
-	retval = OpenMsgStore(global_mapi_session, &obj_store);
-	if (retval != MAPI_E_SUCCESS) {
-		mapi_errstr("OpenMsgStore", GetLastError());
-		goto cleanup;
-	}
-
 	/* Attempt to open the folder */
-	retval = OpenFolder(&obj_store, fid, &obj_folder);
+	retval = OpenFolder(&priv->msg_store, fid, &obj_folder);
 	if (retval != MAPI_E_SUCCESS) {
 		mapi_errstr("OpenFolder", GetLastError());
 		goto cleanup;
@@ -1132,9 +1260,7 @@ exchange_mapi_util_check_restriction (mapi_id_t fid, struct mapi_SRestriction *r
 cleanup:
 	mapi_object_release(&obj_folder);
 	mapi_object_release(&obj_table);
-	mapi_object_release(&obj_store);
 	talloc_free (mem_ctx);
-	LOGNONE();
 	UNLOCK();
 
 	g_debug("%s: Leaving %s ", G_STRLOC, G_STRFUNC);
@@ -1143,7 +1269,7 @@ cleanup:
 }
 
 gboolean
-exchange_mapi_connection_fetch_items   (mapi_id_t fid,
+exchange_mapi_connection_fetch_items   (ExchangeMapiConnection *conn, mapi_id_t fid,
 					struct mapi_SRestriction *res, struct SSortOrderSet *sort_order,
 					const uint32_t *GetPropsList, const uint16_t cn_props,
 					BuildNameID build_name_id, gpointer build_name_data,
@@ -1152,7 +1278,6 @@ exchange_mapi_connection_fetch_items   (mapi_id_t fid,
 {
 	enum MAPISTATUS retval;
 	TALLOC_CTX *mem_ctx;
-	mapi_object_t obj_store;
 	mapi_object_t obj_folder;
 	mapi_object_t obj_table;
 	struct SPropTagArray *SPropTagArray, *GetPropsTagArray = NULL;
@@ -1160,25 +1285,23 @@ exchange_mapi_connection_fetch_items   (mapi_id_t fid,
 	uint32_t count, i, cursor_pos = 0;
 	gboolean result = FALSE;
 
+	CHECK_CORRECT_CONN_AND_GET_PRIV (conn, FALSE);
+	g_return_val_if_fail (priv->session != NULL, FALSE);
+
 	g_debug("%s: Entering %s: folder-id %016" G_GINT64_MODIFIER "X ", G_STRLOC, G_STRFUNC, fid);
 
-	LOCK();
-	LOGALL();
+	LOCK ();
 	mem_ctx = talloc_init("ExchangeMAPI_FetchItems");
-	mapi_object_init(&obj_store);
 	mapi_object_init(&obj_folder);
 	mapi_object_init(&obj_table);
 
-	/* Open the message store */
-	retval = ((options & MAPI_OPTIONS_USE_PFSTORE) ?
-		  OpenPublicFolder(global_mapi_session, &obj_store) : OpenMsgStore(global_mapi_session, &obj_store));
-	if (retval != MAPI_E_SUCCESS) {
-		mapi_errstr("OpenMsgStore / OpenPublicFolder", GetLastError());
-		goto cleanup;
+	if ((options & MAPI_OPTIONS_USE_PFSTORE) != 0) {
+		if (!ensure_public_store (priv))
+			goto cleanup;
 	}
 
 	/* Attempt to open the folder */
-	retval = OpenFolder(&obj_store, fid, &obj_folder);
+	retval = OpenFolder (((options & MAPI_OPTIONS_USE_PFSTORE) != 0 ? &priv->public_store : &priv->msg_store), fid, &obj_folder);
 	if (retval != MAPI_E_SUCCESS) {
 		mapi_errstr("OpenFolder", GetLastError());
 		goto cleanup;
@@ -1245,7 +1368,7 @@ exchange_mapi_connection_fetch_items   (mapi_id_t fid,
 			}
 		}
 
-GetProps_cleanup:
+ GetProps_cleanup:
 		for (m = 0; m < NamedPropsTagArray->cValues; m++) {
 			if (G_UNLIKELY (!GetPropsTagArray))
 				GetPropsTagArray = set_SPropTagArray (mem_ctx, 0x1,
@@ -1319,8 +1442,6 @@ GetProps_cleanup:
 			if (options & MAPI_OPTIONS_FETCH_RECIPIENTS)
 				exchange_mapi_util_get_recipients (&obj_message, &recip_list);
 
-//			exchange_mapi_util_get_gal (contacts_array);
-
 			/* get the main body stream no matter what */
 			if (options & MAPI_OPTIONS_FETCH_BODY_STREAM)
 				exchange_mapi_util_read_body_stream (&obj_message, &stream_list,
@@ -1365,6 +1486,7 @@ GetProps_cleanup:
 				/* NOTE: stream_list, recipient_list and attach_list
 				   should be freed by the callback */
 				item_data = g_new0 (FetchItemsCallbackData, 1);
+				item_data->conn = conn;
 				item_data->fid = *pfid;
 				item_data->mid = *pmid;
 				item_data->properties = &properties_array;
@@ -1397,15 +1519,13 @@ GetProps_cleanup:
 
 	result = TRUE;
 
-cleanup:
+ cleanup:
 	if (GetPropsTagArray)
 		MAPIFreeBuffer (GetPropsTagArray);
 	mapi_object_release(&obj_folder);
 	mapi_object_release(&obj_table);
-	mapi_object_release(&obj_store);
 	talloc_free (mem_ctx);
-	LOGNONE();
-	UNLOCK();
+	UNLOCK ();
 
 	g_debug("%s: Leaving %s: folder-id %016" G_GINT64_MODIFIER "X ", G_STRLOC, G_STRFUNC, fid);
 
@@ -1413,7 +1533,7 @@ cleanup:
 }
 
 gboolean
-exchange_mapi_connection_fetch_item (mapi_id_t fid, mapi_id_t mid,
+exchange_mapi_connection_fetch_item (ExchangeMapiConnection *conn, mapi_id_t fid, mapi_id_t mid,
 				     const uint32_t *GetPropsList, const uint16_t cn_props,
 				     BuildNameID build_name_id, gpointer build_name_data,
 				     FetchCallback cb, gpointer data,
@@ -1421,7 +1541,6 @@ exchange_mapi_connection_fetch_item (mapi_id_t fid, mapi_id_t mid,
 {
 	enum MAPISTATUS retval;
 	TALLOC_CTX *mem_ctx;
-	mapi_object_t obj_store;
 	mapi_object_t obj_folder;
 	mapi_object_t obj_message;
 	struct mapi_SPropValue_array properties_array;
@@ -1431,26 +1550,24 @@ exchange_mapi_connection_fetch_item (mapi_id_t fid, mapi_id_t mid,
 	GSList *stream_list = NULL;
 	gboolean result = FALSE;
 
+	CHECK_CORRECT_CONN_AND_GET_PRIV (conn, FALSE);
+	g_return_val_if_fail (priv->session != NULL, FALSE);
+
 	g_debug("%s: Entering %s: folder-id %016" G_GINT64_MODIFIER "X message-id %016" G_GINT64_MODIFIER "X",
 				G_STRLOC, G_STRFUNC, fid, mid);
 
-	LOCK();
-	LOGALL();
+	LOCK ();
 	mem_ctx = talloc_init("ExchangeMAPI_FetchItem");
-	mapi_object_init(&obj_store);
 	mapi_object_init(&obj_folder);
 	mapi_object_init(&obj_message);
 
-	/* Open the message store */
-	retval = ((options & MAPI_OPTIONS_USE_PFSTORE) ?
-		  OpenPublicFolder(global_mapi_session, &obj_store) : OpenMsgStore(global_mapi_session, &obj_store));
-	if (retval != MAPI_E_SUCCESS) {
-		mapi_errstr("OpenMsgStore", GetLastError());
-		goto cleanup;
+	if ((options & MAPI_OPTIONS_USE_PFSTORE) != 0) {
+		if (!ensure_public_store (priv))
+			goto cleanup;
 	}
 
 	/* Attempt to open the folder */
-	retval = OpenFolder(&obj_store, fid, &obj_folder);
+	retval = OpenFolder (((options & MAPI_OPTIONS_USE_PFSTORE) != 0 ? &priv->public_store : &priv->msg_store), fid, &obj_folder);
 	if (retval != MAPI_E_SUCCESS) {
 		mapi_errstr("OpenFolder", GetLastError());
 		goto cleanup;
@@ -1482,8 +1599,8 @@ exchange_mapi_connection_fetch_item (mapi_id_t fid, mapi_id_t mid,
 			}
 		}
 
-		GetPropsTagArray->cValues = (cn_props + NamedPropsTagArray->cValues);
-		GetPropsTagArray->aulPropTag = talloc_array(mem_ctx, uint32_t, (cn_props + NamedPropsTagArray->cValues));
+		GetPropsTagArray->cValues = (uint32_t) (cn_props + NamedPropsTagArray->cValues);
+		GetPropsTagArray->aulPropTag = talloc_zero_array (mem_ctx, uint32_t, GetPropsTagArray->cValues + 1);
 
 		for (m = 0; m < NamedPropsTagArray->cValues; m++, n++)
 			GetPropsTagArray->aulPropTag[n] = NamedPropsTagArray->aulPropTag[m];
@@ -1546,10 +1663,10 @@ exchange_mapi_connection_fetch_item (mapi_id_t fid, mapi_id_t mid,
 	/* Release the objects so that the callback may use the store. */
 	mapi_object_release(&obj_message);
 	mapi_object_release(&obj_folder);
-	mapi_object_release(&obj_store);
 
 	if (retval == MAPI_E_SUCCESS) {
 		FetchItemsCallbackData *item_data = g_new0 (FetchItemsCallbackData, 1);
+		item_data->conn = conn;
 		item_data->fid = fid;
 		item_data->mid = mid;
 		item_data->properties = &properties_array;
@@ -1576,11 +1693,9 @@ cleanup:
 	if (!result) {
 		mapi_object_release(&obj_message);
 		mapi_object_release(&obj_folder);
-		mapi_object_release(&obj_store);
 	}
 	talloc_free (mem_ctx);
-	LOGNONE();
-	UNLOCK();
+	UNLOCK ();
 
 	g_debug("%s: Leaving %s ", G_STRLOC, G_STRFUNC);
 
@@ -1588,32 +1703,26 @@ cleanup:
 }
 
 mapi_id_t
-exchange_mapi_create_folder (uint32_t olFolder, mapi_id_t pfid, const gchar *name)
+exchange_mapi_connection_create_folder (ExchangeMapiConnection *conn, uint32_t olFolder, mapi_id_t pfid, const gchar *name)
 {
 	enum MAPISTATUS retval;
-	mapi_object_t obj_store;
 	mapi_object_t obj_folder;
 	mapi_object_t obj_top;
 	struct SPropValue vals[1];
 	const gchar *type;
 	mapi_id_t fid = 0;
 
+	CHECK_CORRECT_CONN_AND_GET_PRIV (conn, 0);
+	g_return_val_if_fail (priv->session != NULL, 0);
+
 	g_debug("%s: Entering %s ", G_STRLOC, G_STRFUNC);
 
-	LOCK();
-	LOGALL();
-	mapi_object_init(&obj_store);
+	LOCK ();
 	mapi_object_init(&obj_top);
 	mapi_object_init(&obj_folder);
 
-	retval = OpenMsgStore(global_mapi_session, &obj_store);
-	if (retval != MAPI_E_SUCCESS) {
-		mapi_errstr("OpenMsgStore", GetLastError());
-		goto cleanup;
-	}
-
 	/* We now open the top/parent folder */
-	retval = OpenFolder(&obj_store, pfid, &obj_top);
+	retval = OpenFolder (&priv->msg_store, pfid, &obj_top);
 	if (retval != MAPI_E_SUCCESS) {
 		mapi_errstr("OpenFolder", GetLastError());
 		goto cleanup;
@@ -1661,9 +1770,8 @@ exchange_mapi_create_folder (uint32_t olFolder, mapi_id_t pfid, const gchar *nam
 cleanup:
 	mapi_object_release(&obj_folder);
 	mapi_object_release(&obj_top);
-	mapi_object_release(&obj_store);
-	LOGNONE();
-	UNLOCK();
+
+	UNLOCK ();
 
 	g_debug("%s: Leaving %s ", G_STRLOC, G_STRFUNC);
 
@@ -1672,28 +1780,22 @@ cleanup:
 }
 
 gboolean
-exchange_mapi_empty_folder (mapi_id_t fid)
+exchange_mapi_connection_empty_folder (ExchangeMapiConnection *conn, mapi_id_t fid)
 {
 	enum MAPISTATUS retval;
-	mapi_object_t obj_store;
 	mapi_object_t obj_folder;
 	gboolean result = FALSE;
 
-	g_debug("%s: Entering %s ", G_STRLOC, G_STRFUNC);
+	CHECK_CORRECT_CONN_AND_GET_PRIV (conn, FALSE);
+	g_return_val_if_fail (priv->session != NULL, FALSE);
 
-	LOCK();
-	LOGALL();
-	mapi_object_init(&obj_store);
-	mapi_object_init(&obj_folder);
+	g_debug("%s: Entering %s ", G_STRLOC, G_STRFUNC);
 
-	retval = OpenMsgStore(global_mapi_session, &obj_store);
-	if (retval != MAPI_E_SUCCESS) {
-		mapi_errstr("OpenMsgStore", GetLastError());
-		goto cleanup;
-	}
+	LOCK ();
+	mapi_object_init (&obj_folder);
 
 	/* Attempt to open the folder to be emptied */
-	retval = OpenFolder(&obj_store, fid, &obj_folder);
+	retval = OpenFolder(&priv->msg_store, fid, &obj_folder);
 	if (retval != MAPI_E_SUCCESS) {
 		mapi_errstr("OpenFolder", GetLastError());
 		goto cleanup;
@@ -1712,49 +1814,48 @@ exchange_mapi_empty_folder (mapi_id_t fid)
 
 cleanup:
 	mapi_object_release(&obj_folder);
-	mapi_object_release(&obj_store);
-	LOGNONE();
-	UNLOCK();
+	UNLOCK ();
 
 	g_debug("%s: Leaving %s ", G_STRLOC, G_STRFUNC);
 
 	return result;
 }
 
-/* FIXME: param olFolder is never used in the routine. Remove it and cleanup at the backends */
 gboolean
-exchange_mapi_remove_folder (uint32_t olFolder, mapi_id_t fid)
+exchange_mapi_connection_remove_folder (ExchangeMapiConnection *conn, mapi_id_t fid)
 {
 	enum MAPISTATUS retval;
-	mapi_object_t obj_store;
 	mapi_object_t obj_top;
 	mapi_object_t obj_folder;
 	ExchangeMAPIFolder *folder;
 	gboolean result = FALSE;
+	GSList *l;
+
+	CHECK_CORRECT_CONN_AND_GET_PRIV (conn, FALSE);
+	g_return_val_if_fail (priv->session != NULL, FALSE);
 
 	g_debug("%s: Entering %s ", G_STRLOC, G_STRFUNC);
 
-	folder = exchange_mapi_folder_get_folder (fid);
+	folder = NULL;
+	for (l = exchange_mapi_connection_peek_folders_list (conn); l && !folder; l = l->next) {
+		folder = l->data;
+
+		if (!folder || !folder->folder_id)
+			folder = NULL;
+	}
+
 	g_return_val_if_fail (folder != NULL, FALSE);
 
-	LOCK();
-	LOGALL();
-	mapi_object_init(&obj_store);
+	LOCK ();
 	mapi_object_init(&obj_top);
 	mapi_object_init(&obj_folder);
 
-	retval = OpenMsgStore(global_mapi_session, &obj_store);
-	if (retval != MAPI_E_SUCCESS) {
-		mapi_errstr("OpenMsgStore", GetLastError());
-		goto cleanup;
-	}
-
 	/* FIXME: If the folder has sub-folders, open each of them in turn, empty them and delete them.
 	 * Note that this has to be done recursively, for the sub-folders as well.
 	 */
 
 	/* Attempt to open the folder to be removed */
-	retval = OpenFolder(&obj_store, fid, &obj_folder);
+	retval = OpenFolder(&priv->msg_store, fid, &obj_folder);
 	if (retval != MAPI_E_SUCCESS) {
 		mapi_errstr("OpenFolder", GetLastError());
 		goto cleanup;
@@ -1770,7 +1871,7 @@ exchange_mapi_remove_folder (uint32_t olFolder, mapi_id_t fid)
 	g_debug("Folder with id %016" G_GINT64_MODIFIER "X was emptied ", fid);
 
 	/* Attempt to open the top/parent folder */
-	retval = OpenFolder(&obj_store, folder->parent_folder_id, &obj_top);
+	retval = OpenFolder (&priv->msg_store, folder->parent_folder_id, &obj_top);
 	if (retval != MAPI_E_SUCCESS) {
 		mapi_errstr("OpenFolder", GetLastError());
 		goto cleanup;
@@ -1790,9 +1891,11 @@ exchange_mapi_remove_folder (uint32_t olFolder, mapi_id_t fid)
 cleanup:
 	mapi_object_release(&obj_folder);
 	mapi_object_release(&obj_top);
-	mapi_object_release(&obj_store);
-	LOGNONE();
-	UNLOCK();
+
+	priv->folders = g_slist_remove (priv->folders, folder);
+	exchange_mapi_folder_free (folder);
+
+	UNLOCK ();
 
 	g_debug("%s: Leaving %s ", G_STRLOC, G_STRFUNC);
 
@@ -1800,31 +1903,25 @@ cleanup:
 }
 
 gboolean
-exchange_mapi_rename_folder (mapi_id_t fid, const gchar *new_name)
+exchange_mapi_connection_rename_folder (ExchangeMapiConnection *conn, mapi_id_t fid, const gchar *new_name)
 {
 	enum MAPISTATUS retval;
-	mapi_object_t obj_store;
 	mapi_object_t obj_folder;
 	struct SPropValue *props = NULL;
 	TALLOC_CTX *mem_ctx;
 	gboolean result = FALSE;
 
+	CHECK_CORRECT_CONN_AND_GET_PRIV (conn, FALSE);
+	g_return_val_if_fail (priv->session != NULL, FALSE);
+
 	g_debug("%s: Entering %s ", G_STRLOC, G_STRFUNC);
 
-	LOCK();
-	LOGALL();
+	LOCK ();
 	mem_ctx = talloc_init("ExchangeMAPI_RenameFolder");
-	mapi_object_init(&obj_store);
 	mapi_object_init(&obj_folder);
 
-	retval = OpenMsgStore(global_mapi_session, &obj_store);
-	if (retval != MAPI_E_SUCCESS) {
-		mapi_errstr("OpenMsgStore", GetLastError());
-		goto cleanup;
-	}
-
 	/* Open the folder to be renamed */
-	retval = OpenFolder(&obj_store, fid, &obj_folder);
+	retval = OpenFolder (&priv->msg_store, fid, &obj_folder);
 	if (retval != MAPI_E_SUCCESS) {
 		mapi_errstr("OpenFolder", GetLastError());
 		goto cleanup;
@@ -1843,10 +1940,8 @@ exchange_mapi_rename_folder (mapi_id_t fid, const gchar *new_name)
 
 cleanup:
 	mapi_object_release(&obj_folder);
-	mapi_object_release(&obj_store);
 	talloc_free(mem_ctx);
-	LOGNONE();
-	UNLOCK();
+	UNLOCK ();
 
 	g_debug("%s: Leaving %s ", G_STRLOC, G_STRFUNC);
 
@@ -1856,13 +1951,15 @@ cleanup:
 /* moves folder 'src_fid' to folder 'des_fid' under name 'new_name' (no path in a new_name),
    'src_parent_fid' is folder ID of a parent of the src_fid */
 gboolean
-exchange_mapi_move_folder (mapi_id_t src_fid, mapi_id_t src_parent_fid, mapi_id_t des_fid, const gchar *new_name)
+exchange_mapi_connection_move_folder (ExchangeMapiConnection *conn, mapi_id_t src_fid, mapi_id_t src_parent_fid, mapi_id_t des_fid, const gchar *new_name)
 {
 	enum MAPISTATUS retval;
-	mapi_object_t obj_store;
 	mapi_object_t obj_src, obj_src_parent, obj_des;
 	gboolean result = FALSE;
 
+	CHECK_CORRECT_CONN_AND_GET_PRIV (conn, FALSE);
+	g_return_val_if_fail (priv->session != NULL, FALSE);
+
 	g_return_val_if_fail (src_fid != 0, FALSE);
 	g_return_val_if_fail (src_parent_fid != 0, FALSE);
 	g_return_val_if_fail (des_fid != 0, FALSE);
@@ -1870,32 +1967,24 @@ exchange_mapi_move_folder (mapi_id_t src_fid, mapi_id_t src_parent_fid, mapi_id_
 	g_return_val_if_fail (strchr (new_name, '/') == NULL, FALSE);
 
 	LOCK ();
-	LOGALL ();
 
-	mapi_object_init (&obj_store);
 	mapi_object_init (&obj_src);
 	mapi_object_init (&obj_src_parent);
 	mapi_object_init (&obj_des);
 
-	retval = OpenMsgStore (global_mapi_session, &obj_store);
-	if (retval != MAPI_E_SUCCESS) {
-		mapi_errstr ("OpenMsgStore", GetLastError());
-		goto cleanup;
-	}
-
-	retval = OpenFolder (&obj_store, src_fid, &obj_src);
+	retval = OpenFolder (&priv->msg_store, src_fid, &obj_src);
 	if (retval != MAPI_E_SUCCESS) {
 		mapi_errstr ("OpenFolder src_fid", GetLastError());
 		goto cleanup;
 	}
 
-	retval = OpenFolder (&obj_store, src_parent_fid, &obj_src_parent);
+	retval = OpenFolder (&priv->msg_store, src_parent_fid, &obj_src_parent);
 	if (retval != MAPI_E_SUCCESS) {
 		mapi_errstr ("OpenFolder src_parent_fid", GetLastError());
 		goto cleanup;
 	}
 
-	retval = OpenFolder (&obj_store, des_fid, &obj_des);
+	retval = OpenFolder (&priv->msg_store, des_fid, &obj_des);
 	if (retval != MAPI_E_SUCCESS) {
 		mapi_errstr ("OpenFolder des_fid", GetLastError());
 		goto cleanup;
@@ -1913,47 +2002,38 @@ cleanup:
 	mapi_object_release (&obj_des);
 	mapi_object_release (&obj_src_parent);
 	mapi_object_release (&obj_src);
-	mapi_object_release (&obj_store);
 
-	LOGNONE ();
 	UNLOCK ();
 
 	return result;
 }
 
 struct SPropTagArray *
-exchange_mapi_util_resolve_named_props (uint32_t olFolder, mapi_id_t fid,
+exchange_mapi_connection_resolve_named_props (ExchangeMapiConnection *conn, uint32_t olFolder, mapi_id_t fid,
 					BuildNameID build_name_id, gpointer ni_data)
 {
 	enum MAPISTATUS retval;
 	TALLOC_CTX *mem_ctx;
-	mapi_object_t obj_store;
 	mapi_object_t obj_folder;
 	struct mapi_nameid *nameid;
 	struct SPropTagArray *SPropTagArray, *ret_array = NULL;
 	uint32_t i;
 
+	CHECK_CORRECT_CONN_AND_GET_PRIV (conn, NULL);
+	g_return_val_if_fail (priv->session != NULL, NULL);
+
 	g_debug("%s: Entering %s ", G_STRLOC, G_STRFUNC);
 
-	LOCK();
-	LOGALL();
+	LOCK ();
 	mem_ctx = talloc_init("ExchangeMAPI_ResolveNamedProps");
-	mapi_object_init(&obj_store);
 	mapi_object_init(&obj_folder);
 
 	nameid = mapi_nameid_new(mem_ctx);
 	SPropTagArray = talloc_zero(mem_ctx, struct SPropTagArray);
 
-	/* Open the message store */
-	retval = OpenMsgStore(global_mapi_session, &obj_store);
-	if (retval != MAPI_E_SUCCESS) {
-		mapi_errstr("OpenMsgStore", GetLastError());
-		goto cleanup;
-	}
-
 	/* If fid not present then we'll use olFolder. Document this in API doc. */
 	if (fid == 0) {
-		retval = GetDefaultFolder(&obj_store, &fid, olFolder);
+		retval = GetDefaultFolder (&priv->msg_store, &fid, olFolder);
 		if (retval != MAPI_E_SUCCESS) {
 			mapi_errstr("GetDefaultFolder", GetLastError());
 			goto cleanup;
@@ -1961,7 +2041,7 @@ exchange_mapi_util_resolve_named_props (uint32_t olFolder, mapi_id_t fid,
 	}
 
 	/* Attempt to open the folder */
-	retval = OpenFolder(&obj_store, fid, &obj_folder);
+	retval = OpenFolder (&priv->msg_store, fid, &obj_folder);
 	if (retval != MAPI_E_SUCCESS) {
 		mapi_errstr("OpenFolder", GetLastError());
 		goto cleanup;
@@ -1989,10 +2069,9 @@ exchange_mapi_util_resolve_named_props (uint32_t olFolder, mapi_id_t fid,
 
 cleanup:
 	mapi_object_release(&obj_folder);
-	mapi_object_release(&obj_store);
 	talloc_free(mem_ctx);
-	LOGNONE();
-	UNLOCK();
+
+	UNLOCK ();
 
 	g_debug("%s: Leaving %s ", G_STRLOC, G_STRFUNC);
 
@@ -2000,37 +2079,31 @@ cleanup:
 }
 
 struct SPropTagArray *
-exchange_mapi_util_resolve_named_prop (uint32_t olFolder, mapi_id_t fid, uint16_t lid, const gchar *OLEGUID)
+exchange_mapi_connection_resolve_named_prop (ExchangeMapiConnection *conn, uint32_t olFolder, mapi_id_t fid, uint16_t lid, const gchar *OLEGUID)
 {
 	enum MAPISTATUS retval;
 	TALLOC_CTX *mem_ctx;
-	mapi_object_t obj_store;
 	mapi_object_t obj_folder;
 	struct mapi_nameid *nameid;
 	struct SPropTagArray *SPropTagArray, *ret_array = NULL;
 	uint32_t i;
 
+	CHECK_CORRECT_CONN_AND_GET_PRIV (conn, NULL);
+	g_return_val_if_fail (priv->session != NULL, NULL);
+
 	g_debug("%s: Entering %s ", G_STRLOC, G_STRFUNC);
 
-	LOCK();
-	LOGALL();
+	LOCK ();
+
 	mem_ctx = talloc_init("ExchangeMAPI_ResolveNamedProp");
-	mapi_object_init(&obj_store);
 	mapi_object_init(&obj_folder);
 
 	nameid = mapi_nameid_new(mem_ctx);
 	SPropTagArray = talloc_zero(mem_ctx, struct SPropTagArray);
 
-	/* Open the message store */
-	retval = OpenMsgStore(global_mapi_session, &obj_store);
-	if (retval != MAPI_E_SUCCESS) {
-		mapi_errstr("OpenMsgStore", GetLastError());
-		goto cleanup;
-	}
-
 	/* If fid not present then we'll use olFolder. Document this in API doc. */
 	if (fid == 0) {
-		retval = GetDefaultFolder(&obj_store, &fid, olFolder);
+		retval = GetDefaultFolder (&priv->msg_store, &fid, olFolder);
 		if (retval != MAPI_E_SUCCESS) {
 			mapi_errstr("GetDefaultFolder", GetLastError());
 			goto cleanup;
@@ -2038,7 +2111,7 @@ exchange_mapi_util_resolve_named_prop (uint32_t olFolder, mapi_id_t fid, uint16_
 	}
 
 	/* Attempt to open the folder */
-	retval = OpenFolder(&obj_store, fid, &obj_folder);
+	retval = OpenFolder (&priv->msg_store, fid, &obj_folder);
 	if (retval != MAPI_E_SUCCESS) {
 		mapi_errstr("OpenFolder", GetLastError());
 		goto cleanup;
@@ -2060,10 +2133,9 @@ exchange_mapi_util_resolve_named_prop (uint32_t olFolder, mapi_id_t fid, uint16_
 
 cleanup:
 	mapi_object_release(&obj_folder);
-	mapi_object_release(&obj_store);
 	talloc_free(mem_ctx);
-	LOGNONE();
-	UNLOCK();
+
+	UNLOCK ();
 
 	g_debug("%s: Leaving %s ", G_STRLOC, G_STRFUNC);
 
@@ -2071,25 +2143,25 @@ cleanup:
 }
 
 uint32_t
-exchange_mapi_util_create_named_prop (uint32_t olFolder, mapi_id_t fid,
+exchange_mapi_connection_create_named_prop (ExchangeMapiConnection *conn, uint32_t olFolder, mapi_id_t fid,
 				      const gchar *named_prop_name, uint32_t ptype)
 {
 	enum MAPISTATUS retval;
 	TALLOC_CTX *mem_ctx;
-	mapi_object_t obj_store;
 	mapi_object_t obj_folder;
 	struct GUID guid;
 	struct MAPINAMEID *nameid;
 	struct SPropTagArray *SPropTagArray;
 	uint32_t propID = 0x00000000;
 
+	CHECK_CORRECT_CONN_AND_GET_PRIV (conn, propID);
+	g_return_val_if_fail (priv->session != NULL, propID);
+
 	g_debug("%s: Entering %s ", G_STRLOC, G_STRFUNC);
 
-	LOCK();
-	LOGALL();
-	mem_ctx = talloc_init("ExchangeMAPI_CreateNamedProp");
+	LOCK ();
 
-	mapi_object_init(&obj_store);
+	mem_ctx = talloc_init("ExchangeMAPI_CreateNamedProp");
 	mapi_object_init(&obj_folder);
 
 	GUID_from_string(PS_INTERNET_HEADERS, &guid);
@@ -2100,16 +2172,9 @@ exchange_mapi_util_create_named_prop (uint32_t olFolder, mapi_id_t fid,
 	nameid[0].ulKind = MNID_STRING;
 	nameid[0].kind.lpwstr.Name = named_prop_name;
 
-	/* Open the message store */
-	retval = OpenMsgStore(global_mapi_session, &obj_store);
-	if (retval != MAPI_E_SUCCESS) {
-		mapi_errstr("OpenMsgStore", GetLastError());
-		goto cleanup;
-	}
-
 	/* If fid not present then we'll use olFolder. Document this in API doc. */
 	if (fid == 0) {
-		retval = GetDefaultFolder(&obj_store, &fid, olFolder);
+		retval = GetDefaultFolder (&priv->msg_store, &fid, olFolder);
 		if (retval != MAPI_E_SUCCESS) {
 			mapi_errstr("GetDefaultFolder", GetLastError());
 			goto cleanup;
@@ -2117,7 +2182,7 @@ exchange_mapi_util_create_named_prop (uint32_t olFolder, mapi_id_t fid,
 	}
 
 	/* Attempt to open the folder */
-	retval = OpenFolder(&obj_store, fid, &obj_folder);
+	retval = OpenFolder (&priv->msg_store, fid, &obj_folder);
 	if (retval != MAPI_E_SUCCESS) {
 		mapi_errstr("OpenFolder", GetLastError());
 		goto cleanup;
@@ -2134,10 +2199,9 @@ exchange_mapi_util_create_named_prop (uint32_t olFolder, mapi_id_t fid,
 
 cleanup:
 	mapi_object_release(&obj_folder);
-	mapi_object_release(&obj_store);
 	talloc_free(mem_ctx);
-	LOGNONE();
-	UNLOCK();
+
+	UNLOCK ();
 
 	g_debug("%s: Leaving %s ", G_STRLOC, G_STRFUNC);
 
@@ -2145,35 +2209,26 @@ cleanup:
 }
 
 mapi_id_t
-exchange_mapi_get_default_folder_id (uint32_t olFolder)
+exchange_mapi_connection_get_default_folder_id (ExchangeMapiConnection *conn, uint32_t olFolder)
 {
 	enum MAPISTATUS retval;
-	mapi_object_t obj_store;
 	mapi_id_t fid = 0;
 
-	g_debug("%s: Entering %s ", G_STRLOC, G_STRFUNC);
+	CHECK_CORRECT_CONN_AND_GET_PRIV (conn, 0);
+	g_return_val_if_fail (priv->session != NULL, 0);
 
-	LOCK();
-	LOGALL();
-	mapi_object_init(&obj_store);
+	g_debug("%s: Entering %s ", G_STRLOC, G_STRFUNC);
 
-	/* Open the message store */
-	retval = OpenMsgStore(global_mapi_session, &obj_store);
-	if (retval != MAPI_E_SUCCESS) {
-		mapi_errstr("OpenMsgStore", GetLastError());
-		goto cleanup;
-	}
+	LOCK ();
 
-	retval = GetDefaultFolder(&obj_store, &fid, olFolder);
+	retval = GetDefaultFolder (&priv->msg_store, &fid, olFolder);
 	if (retval != MAPI_E_SUCCESS) {
 		mapi_errstr("GetDefaultFolder", GetLastError());
 		goto cleanup;
 	}
 
 cleanup:
-	mapi_object_release(&obj_store);
-	LOGNONE();
-	UNLOCK();
+	UNLOCK ();
 
 	g_debug("%s: Leaving %s ", G_STRLOC, G_STRFUNC);
 
@@ -2181,7 +2236,7 @@ cleanup:
 }
 
 mapi_id_t
-exchange_mapi_create_item (uint32_t olFolder, mapi_id_t fid,
+exchange_mapi_connection_create_item (ExchangeMapiConnection *conn, uint32_t olFolder, mapi_id_t fid,
 			   BuildNameID build_name_id, gpointer ni_data,
 			   BuildProps build_props, gpointer p_data,
 			   GSList *recipients, GSList *attachments, GSList *generic_streams,
@@ -2189,7 +2244,6 @@ exchange_mapi_create_item (uint32_t olFolder, mapi_id_t fid,
 {
 	enum MAPISTATUS retval;
 	TALLOC_CTX *mem_ctx;
-	mapi_object_t obj_store;
 	mapi_object_t obj_folder;
 	mapi_object_t obj_message;
 	struct mapi_nameid *nameid;
@@ -2198,28 +2252,23 @@ exchange_mapi_create_item (uint32_t olFolder, mapi_id_t fid,
 	gint propslen = 0;
 	mapi_id_t mid = 0;
 
+	CHECK_CORRECT_CONN_AND_GET_PRIV (conn, 0);
+	g_return_val_if_fail (priv->session != NULL, 0);
+
 	g_debug("%s: Entering %s ", G_STRLOC, G_STRFUNC);
 
-	LOCK();
-	LOGALL();
+	LOCK ();
+
 	mem_ctx = talloc_init("ExchangeMAPI_CreateItem");
-	mapi_object_init(&obj_store);
 	mapi_object_init(&obj_folder);
 	mapi_object_init(&obj_message);
 
 	nameid = mapi_nameid_new(mem_ctx);
 	SPropTagArray = talloc_zero(mem_ctx, struct SPropTagArray);
 
-	/* Open the message store */
-	retval = OpenMsgStore(global_mapi_session, &obj_store);
-	if (retval != MAPI_E_SUCCESS) {
-		mapi_errstr("OpenMsgStore", GetLastError());
-		goto cleanup;
-	}
-
 	/* If fid not present then we'll use olFolder. Document this in API doc. */
 	if (fid == 0) {
-		retval = GetDefaultFolder(&obj_store, &fid, olFolder);
+		retval = GetDefaultFolder (&priv->msg_store, &fid, olFolder);
 		if (retval != MAPI_E_SUCCESS) {
 			mapi_errstr("GetDefaultFolder", GetLastError());
 			goto cleanup;
@@ -2227,7 +2276,7 @@ exchange_mapi_create_item (uint32_t olFolder, mapi_id_t fid,
 	}
 
 	/* Attempt to open the folder */
-	retval = OpenFolder(&obj_store, fid, &obj_folder);
+	retval = OpenFolder (&priv->msg_store, fid, &obj_folder);
 	if (retval != MAPI_E_SUCCESS) {
 		mapi_errstr("OpenFolder", GetLastError());
 		goto cleanup;
@@ -2283,7 +2332,7 @@ exchange_mapi_create_item (uint32_t olFolder, mapi_id_t fid,
 
 	/* Set recipients if any */
 	if (recipients) {
-		exchange_mapi_util_modify_recipients (mem_ctx, &obj_message, recipients, FALSE);
+		exchange_mapi_util_modify_recipients (conn, mem_ctx, &obj_message, recipients, FALSE);
 	}
 
 	/* Finally, save all changes */
@@ -2331,10 +2380,9 @@ exchange_mapi_create_item (uint32_t olFolder, mapi_id_t fid,
 cleanup:
 	mapi_object_release(&obj_message);
 	mapi_object_release(&obj_folder);
-	mapi_object_release(&obj_store);
 	talloc_free(mem_ctx);
-	LOGNONE();
-	UNLOCK();
+
+	UNLOCK ();
 
 	g_debug("%s: Leaving %s ", G_STRLOC, G_STRFUNC);
 
@@ -2342,7 +2390,7 @@ cleanup:
 }
 
 gboolean
-exchange_mapi_modify_item (uint32_t olFolder, mapi_id_t fid, mapi_id_t mid,
+exchange_mapi_connection_modify_item (ExchangeMapiConnection *conn, uint32_t olFolder, mapi_id_t fid, mapi_id_t mid,
 			   BuildNameID build_name_id, gpointer ni_data,
 			   BuildProps build_props, gpointer p_data,
 			   GSList *recipients, GSList *attachments, GSList *generic_streams,
@@ -2350,7 +2398,6 @@ exchange_mapi_modify_item (uint32_t olFolder, mapi_id_t fid, mapi_id_t mid,
 {
 	enum MAPISTATUS retval;
 	TALLOC_CTX *mem_ctx;
-	mapi_object_t obj_store;
 	mapi_object_t obj_folder;
 	mapi_object_t obj_message;
 	struct mapi_nameid *nameid;
@@ -2359,28 +2406,23 @@ exchange_mapi_modify_item (uint32_t olFolder, mapi_id_t fid, mapi_id_t mid,
 	gint propslen = 0;
 	gboolean result = FALSE;
 
+	CHECK_CORRECT_CONN_AND_GET_PRIV (conn, FALSE);
+	g_return_val_if_fail (priv->session != NULL, FALSE);
+
 	g_debug("%s: Entering %s ", G_STRLOC, G_STRFUNC);
 
-	LOCK();
-	LOGALL();
+	LOCK ();
+
 	mem_ctx = talloc_init("ExchangeMAPI_ModifyItem");
-	mapi_object_init(&obj_store);
 	mapi_object_init(&obj_folder);
 	mapi_object_init(&obj_message);
 
 	nameid = mapi_nameid_new(mem_ctx);
 	SPropTagArray = talloc_zero(mem_ctx, struct SPropTagArray);
 
-	/* Open the message store */
-	retval = OpenMsgStore(global_mapi_session, &obj_store);
-	if (retval != MAPI_E_SUCCESS) {
-		mapi_errstr("OpenMsgStore", GetLastError());
-		goto cleanup;
-	}
-
 	/* If fid not present then we'll use olFolder. Document this in API doc. */
 	if (fid == 0) {
-		retval = GetDefaultFolder(&obj_store, &fid, olFolder);
+		retval = GetDefaultFolder (&priv->msg_store, &fid, olFolder);
 		if (retval != MAPI_E_SUCCESS) {
 			mapi_errstr("GetDefaultFolder", GetLastError());
 			goto cleanup;
@@ -2388,7 +2430,7 @@ exchange_mapi_modify_item (uint32_t olFolder, mapi_id_t fid, mapi_id_t mid,
 	}
 
 	/* Attempt to open the folder */
-	retval = OpenFolder(&obj_store, fid, &obj_folder);
+	retval = OpenFolder (&priv->msg_store, fid, &obj_folder);
 	if (retval != MAPI_E_SUCCESS) {
 		mapi_errstr("OpenFolder", GetLastError());
 		goto cleanup;
@@ -2447,7 +2489,7 @@ exchange_mapi_modify_item (uint32_t olFolder, mapi_id_t fid, mapi_id_t mid,
 
 	/* Set recipients if any */
 	if (recipients) {
-		exchange_mapi_util_modify_recipients (mem_ctx, &obj_message, recipients, TRUE);
+		exchange_mapi_util_modify_recipients (conn, mem_ctx, &obj_message, recipients, TRUE);
 	}
 
 	/* Finally, save all changes */
@@ -2471,10 +2513,9 @@ exchange_mapi_modify_item (uint32_t olFolder, mapi_id_t fid, mapi_id_t mid,
 cleanup:
 	mapi_object_release(&obj_message);
 	mapi_object_release(&obj_folder);
-	mapi_object_release(&obj_store);
 	talloc_free(mem_ctx);
-	LOGNONE();
-	UNLOCK();
+
+	UNLOCK ();
 
 	g_debug("%s: Leaving %s ", G_STRLOC, G_STRFUNC);
 
@@ -2482,39 +2523,36 @@ cleanup:
 }
 
 gboolean
-exchange_mapi_set_flags (uint32_t olFolder, mapi_id_t fid, GSList *mids, uint32_t flag, guint32 options)
+exchange_mapi_connection_set_flags (ExchangeMapiConnection *conn, uint32_t olFolder, mapi_id_t fid, GSList *mids, uint32_t flag, guint32 options)
 {
 	enum MAPISTATUS retval;
 	TALLOC_CTX *mem_ctx;
-	mapi_object_t obj_store;
 	mapi_object_t obj_folder;
 	uint32_t i;
 	mapi_id_t *id_messages;
 	GSList *tmp = mids;
 	gboolean result = FALSE;
 
+	CHECK_CORRECT_CONN_AND_GET_PRIV (conn, FALSE);
+	g_return_val_if_fail (priv->session != NULL, FALSE);
+
 	g_debug("%s: Entering %s ", G_STRLOC, G_STRFUNC);
 
-	LOCK();
-	LOGALL();
+	LOCK ();
 	mem_ctx = talloc_init("ExchangeMAPI_SetFlags");
-	mapi_object_init(&obj_store);
 	mapi_object_init(&obj_folder);
 
 	id_messages = talloc_array(mem_ctx, mapi_id_t, g_slist_length (mids));
 	for (i=0; tmp; tmp=tmp->next, i++)
 		id_messages[i] = *((mapi_id_t *)tmp->data);
 
-	/* Open the message store */
-	retval = ((options & MAPI_OPTIONS_USE_PFSTORE) ?
-		  OpenPublicFolder(global_mapi_session, &obj_store) : OpenMsgStore(global_mapi_session, &obj_store));
-	if (retval != MAPI_E_SUCCESS) {
-		mapi_errstr("OpenMsgStore / OpenPublicFolder", GetLastError());
-		goto cleanup;
+	if ((options & MAPI_OPTIONS_USE_PFSTORE) != 0) {
+		if (!ensure_public_store (priv))
+			goto cleanup;
 	}
 
 	/* Attempt to open the folder */
-	retval = OpenFolder(&obj_store, fid, &obj_folder);
+	retval = OpenFolder (((options & MAPI_OPTIONS_USE_PFSTORE) != 0 ? &priv->public_store : &priv->msg_store), fid, &obj_folder);
 	if (retval != MAPI_E_SUCCESS) {
 		mapi_errstr("OpenFolder", GetLastError());
 		goto cleanup;
@@ -2530,10 +2568,9 @@ exchange_mapi_set_flags (uint32_t olFolder, mapi_id_t fid, GSList *mids, uint32_
 
 cleanup:
 	mapi_object_release(&obj_folder);
-	mapi_object_release(&obj_store);
 	talloc_free(mem_ctx);
-	LOGNONE();
-	UNLOCK();
+
+	UNLOCK ();
 
 	g_debug("%s: Leaving %s ", G_STRLOC, G_STRFUNC);
 
@@ -2541,17 +2578,17 @@ cleanup:
 }
 
 static gboolean
-mapi_move_items (mapi_id_t src_fid, mapi_id_t dest_fid, GSList *mid_list, gboolean do_copy)
+mapi_move_items (mapi_object_t *msg_store, mapi_id_t src_fid, mapi_id_t dest_fid, GSList *mid_list, gboolean do_copy)
 {
 	enum MAPISTATUS	retval;
-	mapi_object_t obj_store;
 	mapi_object_t obj_folder_src;
 	mapi_object_t obj_folder_dst;
 	mapi_id_array_t msg_id_array;
 	GSList *l;
 	gboolean result = FALSE;
 
-	mapi_object_init(&obj_store);
+	g_return_val_if_fail (msg_store != NULL, FALSE);
+
 	mapi_object_init(&obj_folder_src);
 	mapi_object_init(&obj_folder_dst);
 	mapi_id_array_init(&msg_id_array);
@@ -2559,19 +2596,13 @@ mapi_move_items (mapi_id_t src_fid, mapi_id_t dest_fid, GSList *mid_list, gboole
 	for (l = mid_list; l != NULL; l = g_slist_next (l))
 		mapi_id_array_add_id (&msg_id_array, *((mapi_id_t *)l->data));
 
-	retval = OpenMsgStore(global_mapi_session, &obj_store);
-	if (retval != MAPI_E_SUCCESS) {
-		mapi_errstr("OpenMsgStore", GetLastError());
-		goto cleanup;
-	}
-
-	retval = OpenFolder(&obj_store, src_fid, &obj_folder_src);
+	retval = OpenFolder (msg_store, src_fid, &obj_folder_src);
 	if (retval != MAPI_E_SUCCESS) {
 		mapi_errstr("OpenFolder - source folder", GetLastError());
 		goto cleanup;
 	}
 
-	retval = OpenFolder(&obj_store, dest_fid, &obj_folder_dst);
+	retval = OpenFolder (msg_store, dest_fid, &obj_folder_dst);
 	if (retval != MAPI_E_SUCCESS) {
 		mapi_errstr("OpenFolder - destination folder", GetLastError());
 		goto cleanup;
@@ -2589,23 +2620,23 @@ cleanup:
 	mapi_id_array_release(&msg_id_array);
 	mapi_object_release(&obj_folder_dst);
 	mapi_object_release(&obj_folder_src);
-	mapi_object_release(&obj_store);
 
 	return result;
 }
 
 gboolean
-exchange_mapi_copy_items (mapi_id_t src_fid, mapi_id_t dest_fid, GSList *mids)
+exchange_mapi_connection_copy_items (ExchangeMapiConnection *conn, mapi_id_t src_fid, mapi_id_t dest_fid, GSList *mids)
 {
 	gboolean result = FALSE;
 
+	CHECK_CORRECT_CONN_AND_GET_PRIV (conn, FALSE);
+	g_return_val_if_fail (priv->session != NULL, FALSE);
+
 	g_debug("%s: Entering %s ", G_STRLOC, G_STRFUNC);
 
-	LOCK();
-	LOGALL();
-	result = mapi_move_items (src_fid, dest_fid, mids, TRUE);
-	LOGNONE();
-	UNLOCK();
+	LOCK ();
+	result = mapi_move_items (&priv->msg_store, src_fid, dest_fid, mids, TRUE);
+	UNLOCK ();
 
 	g_debug("%s: Leaving %s ", G_STRLOC, G_STRFUNC);
 
@@ -2613,17 +2644,18 @@ exchange_mapi_copy_items (mapi_id_t src_fid, mapi_id_t dest_fid, GSList *mids)
 }
 
 gboolean
-exchange_mapi_move_items (mapi_id_t src_fid, mapi_id_t dest_fid, GSList *mids)
+exchange_mapi_connection_move_items (ExchangeMapiConnection *conn, mapi_id_t src_fid, mapi_id_t dest_fid, GSList *mids)
 {
 	gboolean result = FALSE;
 
+	CHECK_CORRECT_CONN_AND_GET_PRIV (conn, FALSE);
+	g_return_val_if_fail (priv->session != NULL, FALSE);
+
 	g_debug("%s: Entering %s ", G_STRLOC, G_STRFUNC);
 
-	LOCK();
-	LOGALL();
-	result = mapi_move_items (src_fid, dest_fid, mids, FALSE);
-	LOGNONE();
-	UNLOCK();
+	LOCK ();
+	result = mapi_move_items (&priv->msg_store, src_fid, dest_fid, mids, FALSE);
+	UNLOCK ();
 
 	g_debug("%s: Leaving %s ", G_STRLOC, G_STRFUNC);
 
@@ -2631,23 +2663,24 @@ exchange_mapi_move_items (mapi_id_t src_fid, mapi_id_t dest_fid, GSList *mids)
 }
 
 gboolean
-exchange_mapi_remove_items (uint32_t olFolder, mapi_id_t fid, GSList *mids)
+exchange_mapi_connection_remove_items (ExchangeMapiConnection *conn, uint32_t olFolder, mapi_id_t fid, GSList *mids)
 {
 	enum MAPISTATUS retval;
 	TALLOC_CTX *mem_ctx;
-	mapi_object_t obj_store;
 	mapi_object_t obj_folder;
 	uint32_t i;
 	mapi_id_t *id_messages;
 	GSList *tmp = mids;
 	gboolean result = FALSE;
 
+	CHECK_CORRECT_CONN_AND_GET_PRIV (conn, FALSE);
+	g_return_val_if_fail (priv->session != NULL, FALSE);
+
 	g_debug("%s: Entering %s ", G_STRLOC, G_STRFUNC);
 
-	LOCK();
-	LOGALL();
+	LOCK ();
+
 	mem_ctx = talloc_init("ExchangeMAPI_RemoveItems");
-	mapi_object_init(&obj_store);
 	mapi_object_init(&obj_folder);
 
 	id_messages = talloc_array(mem_ctx, mapi_id_t, g_slist_length (mids));
@@ -2656,16 +2689,9 @@ exchange_mapi_remove_items (uint32_t olFolder, mapi_id_t fid, GSList *mids)
 		id_messages[i] = data->id;
 	}
 
-	/* Open the message store */
-	retval = OpenMsgStore(global_mapi_session, &obj_store);
-	if (retval != MAPI_E_SUCCESS) {
-		mapi_errstr("OpenMsgStore", GetLastError());
-		goto cleanup;
-	}
-
 	/* If fid not present then we'll use olFolder. Document this in API doc. */
 	if (fid == 0) {
-		retval = GetDefaultFolder(&obj_store, &fid, olFolder);
+		retval = GetDefaultFolder (&priv->msg_store, &fid, olFolder);
 		if (retval != MAPI_E_SUCCESS) {
 			mapi_errstr("GetDefaultFolder", GetLastError());
 			goto cleanup;
@@ -2673,7 +2699,7 @@ exchange_mapi_remove_items (uint32_t olFolder, mapi_id_t fid, GSList *mids)
 	}
 
 	/* Attempt to open the folder */
-	retval = OpenFolder(&obj_store, fid, &obj_folder);
+	retval = OpenFolder (&priv->msg_store, fid, &obj_folder);
 	if (retval != MAPI_E_SUCCESS) {
 		mapi_errstr("OpenFolder", GetLastError());
 		goto cleanup;
@@ -2690,10 +2716,9 @@ exchange_mapi_remove_items (uint32_t olFolder, mapi_id_t fid, GSList *mids)
 
 cleanup:
 	mapi_object_release(&obj_folder);
-	mapi_object_release(&obj_store);
 	talloc_free(mem_ctx);
-	LOGNONE();
-	UNLOCK();
+
+	UNLOCK ();
 
 	g_debug("%s: Leaving %s ", G_STRLOC, G_STRFUNC);
 
@@ -2935,11 +2960,10 @@ set_user_name (gpointer data, gpointer user_data)
 }
 
 gboolean
-exchange_mapi_get_folders_list (GSList **mapi_folders)
+exchange_mapi_connection_get_folders_list (ExchangeMapiConnection *conn, GSList **mapi_folders)
 {
 	enum MAPISTATUS	retval;
 	TALLOC_CTX		*mem_ctx;
-	mapi_object_t		obj_store;
 	struct SPropTagArray	*SPropTagArray;
 	struct SPropValue	*lpProps;
 	struct SRow		aRow;
@@ -2953,29 +2977,24 @@ exchange_mapi_get_folders_list (GSList **mapi_folders)
 	const gchar		*mailbox_user_name = NULL;
 	const uint32_t          *mailbox_size = NULL;
 
+	CHECK_CORRECT_CONN_AND_GET_PRIV (conn, FALSE);
+	g_return_val_if_fail (priv->session != NULL, FALSE);
+
 	g_debug("%s: Entering %s ", G_STRLOC, G_STRFUNC);
 
-	LOCK();
-	LOGALL();
-	mem_ctx = talloc_init("ExchangeMAPI_GetFoldersList");
-	mapi_object_init(&obj_store);
+	LOCK ();
 
-	/* Open the message store */
-	retval = OpenMsgStore(global_mapi_session, &obj_store);
-	if (retval != MAPI_E_SUCCESS) {
-		mapi_errstr("OpenMsgStore", GetLastError());
-		goto cleanup;
-	}
+	mem_ctx = talloc_init("ExchangeMAPI_GetFoldersList");
 
 	/* Build the array of Mailbox properties we want to fetch */
 	SPropTagArray = set_SPropTagArray(mem_ctx, 0x4,
-					  PR_DISPLAY_NAME,
-					  PR_MAILBOX_OWNER_NAME,
+					  PR_DISPLAY_NAME_UNICODE,
+					  PR_MAILBOX_OWNER_NAME_UNICODE,
 					  PR_MESSAGE_SIZE,
-					  PR_USER_NAME);
+					  PR_USER_NAME_UNICODE);
 
 	lpProps = talloc_zero(mem_ctx, struct SPropValue);
-	retval = GetProps (&obj_store, SPropTagArray, &lpProps, &count);
+	retval = GetProps (&priv->msg_store, SPropTagArray, &lpProps, &count);
 	MAPIFreeBuffer(SPropTagArray);
 
 	if (retval != MAPI_E_SUCCESS) {
@@ -2989,13 +3008,13 @@ exchange_mapi_get_folders_list (GSList **mapi_folders)
 	aRow.lpProps = lpProps;
 
 	/* betting that these will never fail */
-	mailbox_name = (const gchar *) find_SPropValue_data(&aRow, PR_DISPLAY_NAME);
-	mailbox_owner_name = (const gchar *) find_SPropValue_data(&aRow, PR_MAILBOX_OWNER_NAME);
-	mailbox_user_name = (const gchar *) find_SPropValue_data(&aRow, PR_USER_NAME);
+	mailbox_name = (const gchar *) find_SPropValue_data(&aRow, PR_DISPLAY_NAME_UNICODE);
+	mailbox_owner_name = (const gchar *) find_SPropValue_data(&aRow, PR_MAILBOX_OWNER_NAME_UNICODE);
+	mailbox_user_name = (const gchar *) find_SPropValue_data(&aRow, PR_USER_NAME_UNICODE);
 	mailbox_size = (const uint32_t *)find_SPropValue_data (&aRow, PR_MESSAGE_SIZE);
 
 	/* Prepare the directory listing */
-	retval = GetDefaultFolder(&obj_store, &mailbox_id, olFolderTopInformationStore);
+	retval = GetDefaultFolder(&priv->msg_store, &mailbox_id, olFolderTopInformationStore);
 	if (retval != MAPI_E_SUCCESS) {
 		mapi_errstr("GetDefaultFolder", GetLastError());
 		goto cleanup;
@@ -3013,23 +3032,22 @@ exchange_mapi_get_folders_list (GSList **mapi_folders)
 	*mapi_folders = g_slist_prepend (*mapi_folders, folder);
 
 	/* FIXME: check status of get_child_folders */
-	get_child_folders (mem_ctx, MAPI_PERSONAL_FOLDER, &obj_store, mailbox_id, mapi_folders, -1);
+	get_child_folders (mem_ctx, MAPI_PERSONAL_FOLDER, &priv->msg_store, mailbox_id, mapi_folders, -1);
 
 	g_free(utf8_mailbox_name);
 
 	*mapi_folders = g_slist_reverse (*mapi_folders);
 
-	set_default_folders (&obj_store, mapi_folders);
+	set_default_folders (&priv->msg_store, mapi_folders);
 	g_slist_foreach (*mapi_folders, (GFunc) set_owner_name, (gpointer) mailbox_owner_name);
 	g_slist_foreach (*mapi_folders, (GFunc) set_user_name, (gpointer) mailbox_user_name);
 
 	result = TRUE;
 
 cleanup:
-	mapi_object_release(&obj_store);
 	talloc_free (mem_ctx);
-	LOGNONE();
-	UNLOCK();
+
+	UNLOCK ();
 
 	g_debug("%s: Leaving %s ", G_STRLOC, G_STRFUNC);
 
@@ -3037,41 +3055,37 @@ cleanup:
 }
 
 gboolean
-exchange_mapi_get_pf_folders_list (GSList **mapi_folders, mapi_id_t parent_fid)
+exchange_mapi_connection_get_pf_folders_list (ExchangeMapiConnection *conn, GSList **mapi_folders, mapi_id_t parent_fid)
 {
 	enum MAPISTATUS		retval;
 	TALLOC_CTX		*mem_ctx;
-	mapi_object_t		obj_store;
 	gboolean		result = FALSE;
 	mapi_id_t		mailbox_id;
 	ExchangeMAPIFolder	*folder;
 	mapi_object_t obj_parent_folder;
 
+	CHECK_CORRECT_CONN_AND_GET_PRIV (conn, FALSE);
+	g_return_val_if_fail (priv->session != NULL, FALSE);
+
 	g_debug("%s: Entering %s ", G_STRLOC, G_STRFUNC);
 
-	LOCK();
-	LOGALL();
+	LOCK ();
 	mem_ctx = talloc_init("ExchangeMAPI_PF_GetFoldersList");
-	mapi_object_init(&obj_store);
 
-	/* Open the PF message store */
-	retval = OpenPublicFolder(global_mapi_session, &obj_store);
-	if (retval != MAPI_E_SUCCESS) {
-		mapi_errstr("OpenPublicFolder", GetLastError());
+	if (!ensure_public_store (priv))
 		goto cleanup;
-	}
 
 	/* Open the folder if parent_fid is given. */
 	if (parent_fid) {
 		mapi_object_init(&obj_parent_folder);
 
-		retval = OpenFolder(&obj_store, parent_fid, &obj_parent_folder);
+		retval = OpenFolder (&priv->public_store, parent_fid, &obj_parent_folder);
 		if (retval != MAPI_E_SUCCESS) {
 			mapi_errstr("OpenFolder", GetLastError());
 			goto cleanup;
 		}
 	} else {
-		retval = GetDefaultPublicFolder(&obj_store, &mailbox_id, olFolderPublicIPMSubtree);
+		retval = GetDefaultPublicFolder (&priv->public_store, &mailbox_id, olFolderPublicIPMSubtree);
 		if (retval != MAPI_E_SUCCESS) {
 			mapi_errstr("GetDefaultPublicFolder", GetLastError());
 			goto cleanup;
@@ -3086,32 +3100,37 @@ exchange_mapi_get_pf_folders_list (GSList **mapi_folders, mapi_id_t parent_fid)
 	*mapi_folders = g_slist_prepend (*mapi_folders, folder);
 
 	/* FIXME: check status of get_child_folders */
-	get_child_folders (mem_ctx, MAPI_FAVOURITE_FOLDER, parent_fid ? &obj_parent_folder : &obj_store,
+	get_child_folders (mem_ctx, MAPI_FAVOURITE_FOLDER, parent_fid ? &obj_parent_folder : &priv->public_store,
 			   parent_fid ? parent_fid : mailbox_id, mapi_folders, 1);
 
 	result = TRUE;
 
 cleanup:
-	mapi_object_release(&obj_store);
 	talloc_free (mem_ctx);
-	LOGNONE();
-	UNLOCK();
+
+	UNLOCK ();
 
 	g_debug("%s: Leaving %s ", G_STRLOC, G_STRFUNC);
 
 	return result;
 }
 
-/**
-   This function has temporarily been moved here for convenient
-   purposes. This is the only routine outside exchange-mapi-connection
-   using libmapi calls whih require to have a pointer on MAPI session.
+GSList *
+exchange_mapi_connection_peek_folders_list (ExchangeMapiConnection *conn)
+{
+	CHECK_CORRECT_CONN_AND_GET_PRIV (conn, FALSE);
+	g_return_val_if_fail (priv->session != NULL, FALSE);
+
+	LOCK ();
+	if (!priv->folders)
+		exchange_mapi_connection_get_folders_list (conn, &priv->folders);
+	UNLOCK ();
+
+	return priv->folders;
+}
 
-   The function will be moved back to its original location when the
-   session context is fixed.
- */
 const gchar *
-exchange_mapi_util_ex_to_smtp (const gchar *ex_address)
+exchange_mapi_connection_ex_to_smtp (ExchangeMapiConnection *conn, const gchar *ex_address)
 {
 	enum MAPISTATUS	retval;
 	TALLOC_CTX		*mem_ctx;
@@ -3121,6 +3140,9 @@ exchange_mapi_util_ex_to_smtp (const gchar *ex_address)
 	const gchar		*str_array[2];
 	const gchar		*smtp_addr = NULL;
 
+	CHECK_CORRECT_CONN_AND_GET_PRIV (conn, FALSE);
+	g_return_val_if_fail (priv->session != NULL, FALSE);
+
 	g_return_val_if_fail (ex_address != NULL, NULL);
 
 	str_array[0] = ex_address;
@@ -3128,13 +3150,15 @@ exchange_mapi_util_ex_to_smtp (const gchar *ex_address)
 
 	mem_ctx = talloc_init("ExchangeMAPI_EXtoSMTP");
 
+	LOCK ();
+
 	SPropTagArray = set_SPropTagArray(mem_ctx, 0x2,
 					  PR_SMTP_ADDRESS,
 					  PR_SMTP_ADDRESS_UNICODE);
 
-	retval = ResolveNames(global_mapi_session, (const gchar **)str_array, SPropTagArray, &SRowSet, &flaglist, 0);
+	retval = ResolveNames (priv->session, (const gchar **)str_array, SPropTagArray, &SRowSet, &flaglist, 0);
 	if (retval != MAPI_E_SUCCESS)
-		retval = ResolveNames(global_mapi_session, (const gchar **)str_array, SPropTagArray, &SRowSet, &flaglist, MAPI_UNICODE);
+		retval = ResolveNames (priv->session, (const gchar **)str_array, SPropTagArray, &SRowSet, &flaglist, MAPI_UNICODE);
 
 	if (retval == MAPI_E_SUCCESS && SRowSet && SRowSet->cRows == 1) {
 		smtp_addr = (const gchar *) find_SPropValue_data(SRowSet->aRow, PR_SMTP_ADDRESS);
@@ -3144,67 +3168,69 @@ exchange_mapi_util_ex_to_smtp (const gchar *ex_address)
 
 	talloc_free (mem_ctx);
 
+	UNLOCK ();
+
 	return smtp_addr;
 }
 
 gboolean
-exchange_mapi_events_init ()
+exchange_mapi_connection_events_init (ExchangeMapiConnection *conn)
 {
-	enum MAPISTATUS retval;
+	gboolean retval;
 
-	retval = RegisterNotification(0);
+	CHECK_CORRECT_CONN_AND_GET_PRIV (conn, FALSE);
+	g_return_val_if_fail (priv->session != NULL, FALSE);
 
-	return (retval == MAPI_E_SUCCESS);
+	LOCK ();
+	/* TODO: This requires a context, like session, from OpenChange, thus disabling until added */
+	retval = FALSE /*RegisterNotification(0) == MAPI_E_SUCCESS */;
+	UNLOCK ();
+
+	return retval;
 }
 
 gboolean
-exchange_mapi_events_subscribe (guint32 options,
-				guint16 event_mask, guint32 *connection,
+exchange_mapi_connection_events_subscribe (ExchangeMapiConnection *conn, guint32 options,
+				guint16 event_mask, guint32 *events_conn_id,
 				mapi_notify_callback_t callback, gpointer data)
 {
-	enum MAPISTATUS	retval;
-	mapi_object_t obj_target;
+	enum MAPISTATUS	retval = MAPI_E_CALL_FAILED;
 	gboolean use_store = ((options & MAPI_EVENTS_USE_STORE) ||
 			      (options & MAPI_EVENTS_USE_PF_STORE));
 
-	mapi_object_init(&obj_target);
+	CHECK_CORRECT_CONN_AND_GET_PRIV (conn, FALSE);
+	g_return_val_if_fail (priv->session != NULL, FALSE);
 
 	LOCK ();
 
 	if (options & MAPI_EVENTS_USE_STORE) {
-		retval = OpenMsgStore(global_mapi_session, &obj_target);
-		if (retval != MAPI_E_SUCCESS) {
-			mapi_errstr("OpenMsgStore", GetLastError());
+		retval = Subscribe (&priv->msg_store, events_conn_id, event_mask, use_store, (mapi_notify_callback_t) callback, data);
+	} else if (options & MAPI_EVENTS_USE_PF_STORE) {
+		if (!ensure_public_store (priv)) {
 			UNLOCK ();
 			return FALSE;
 		}
-	} else if (options & MAPI_EVENTS_USE_PF_STORE) {
-		/* TODO */
+
+		retval = Subscribe (&priv->public_store, events_conn_id, event_mask, use_store, (mapi_notify_callback_t) callback, data);
 	} else if (options & MAPI_EVENTS_FOLDER) {
 		/* TODO */
 	}
 
-	retval = Subscribe(&obj_target, connection, event_mask, use_store,
-			   (mapi_notify_callback_t) callback, data);
-
 	UNLOCK ();
 
 	return (retval == MAPI_E_SUCCESS);
 }
 
 gboolean
-exchange_mapi_events_unsubscribe (guint32 connection)
+exchange_mapi_connection_events_unsubscribe (ExchangeMapiConnection *conn, guint32 events_conn_id)
 {
 	enum MAPISTATUS	retval;
 
-	LOCK ();
-	if (!global_mapi_session) {
-		UNLOCK ();
-		return FALSE;
-	}
-
-	retval = Unsubscribe (global_mapi_session, connection);
+	CHECK_CORRECT_CONN_AND_GET_PRIV (conn, FALSE);
+	g_return_val_if_fail (priv->session != NULL, FALSE);
 
+	LOCK ();
+	retval = Unsubscribe (priv->session, events_conn_id);
 	UNLOCK ();
 
 	return (retval == MAPI_E_SUCCESS);
@@ -3212,10 +3238,15 @@ exchange_mapi_events_unsubscribe (guint32 connection)
 
 /* Note : Blocking infinite loop. */
 gboolean
-exchange_mapi_events_monitor (struct mapi_notify_continue_callback_data *cb_data)
+exchange_mapi_connection_events_monitor (ExchangeMapiConnection *conn, struct mapi_notify_continue_callback_data *cb_data)
 {
 	enum MAPISTATUS	retval;
-	retval = MonitorNotification (global_mapi_session, NULL, cb_data);
+
+	CHECK_CORRECT_CONN_AND_GET_PRIV (conn, FALSE);
+	g_return_val_if_fail (priv->session != NULL, FALSE);
+
+	retval = MonitorNotification (priv->session, NULL, cb_data);
+
 	return retval;
 }
 
@@ -3237,6 +3268,116 @@ manage_mapi_error (const gchar *context, uint32_t error_id, gchar **error_msg)
 	}
 }
 
+/* profile related functions - begin */
+
+static void
+mapi_debug_logger (const gchar * domain, GLogLevelFlags level, const gchar * message, gpointer data)
+{
+	g_print ("[DEBUG] %s\n", message);
+}
+
+static void
+mapi_debug_logger_muted (const gchar * domain, GLogLevelFlags level, const gchar * message, gpointer data)
+{
+	/*Nothing here. Just a dummy function*/
+}
+
+static gboolean
+ensure_mapi_init_called (void)
+{
+	static gboolean called = FALSE;
+	static GStaticMutex mutex = G_STATIC_MUTEX_INIT;
+	gchar *profpath;
+	enum MAPISTATUS status;
+
+	g_static_mutex_lock (&mutex);
+	if (called) {
+		g_static_mutex_unlock (&mutex);
+		return TRUE;
+	}
+
+	profpath = g_build_filename (g_get_home_dir (), DEFAULT_PROF_PATH, NULL);
+
+	if (!g_file_test (profpath, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR)) {
+		/* Create a ProfileStore */
+		status = CreateProfileStore (profpath, LIBMAPI_LDIF_DIR);
+		if (status != MAPI_E_SUCCESS && (status != MAPI_E_NO_ACCESS || !g_file_test (profpath, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR))) {
+			mapi_errstr ("CreateProfileStore", GetLastError());
+			g_free (profpath);
+
+			g_static_mutex_unlock (&mutex);
+			return FALSE;
+		}
+	}
+
+	status = MAPIInitialize (profpath);
+	if (status == MAPI_E_SESSION_LIMIT) {
+		/* do nothing, the profile store is already initialized */
+		/* but this shouldn't happen */
+		mapi_errstr ("MAPIInitialize", GetLastError());
+	} else if (status != MAPI_E_SUCCESS) {
+		mapi_errstr ("MAPIInitialize", GetLastError());
+		g_free (profpath);
+
+		g_static_mutex_unlock (&mutex);
+		return FALSE;
+	}
+
+	g_free (profpath);
+
+	called = TRUE;
+	g_static_mutex_unlock (&mutex);
+
+	return TRUE;
+}
+
+/* used when dealing with profiles */
+static GStaticMutex profile_mutex = G_STATIC_MUTEX_INIT;
+
+static struct mapi_session *
+mapi_profile_load (const gchar *profname, const gchar *password)
+{
+	enum MAPISTATUS	retval = MAPI_E_SUCCESS;
+	struct mapi_session *session = NULL;
+	guint32 debug_log_level = 0;
+
+	g_return_val_if_fail (profname != NULL, NULL);
+
+	g_static_mutex_lock (&profile_mutex);
+
+	/* Initialize libexchangemapi logger*/
+	if (g_getenv ("EXCHANGEMAPI_DEBUG")) {
+		g_log_set_handler (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, mapi_debug_logger, NULL);
+	} else
+		g_log_set_handler (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, mapi_debug_logger_muted, NULL);
+
+	g_debug("%s: Entering %s ", G_STRLOC, G_STRFUNC);
+
+	if (!ensure_mapi_init_called ())
+		goto cleanup;
+
+	/* Initialize libmapi logger*/
+	if (g_getenv ("MAPI_DEBUG")) {
+		debug_log_level = atoi (g_getenv ("MAPI_DEBUG"));
+		SetMAPIDumpData(TRUE);
+		SetMAPIDebugLevel(debug_log_level);
+	}
+
+	g_debug("Loading profile %s ", profname);
+
+	retval = MapiLogonEx (&session, profname, password);
+	if (retval != MAPI_E_SUCCESS) {
+		mapi_errstr("MapiLogonEx", GetLastError());
+		goto cleanup;
+	}
+
+ cleanup:
+	g_static_mutex_unlock (&profile_mutex);
+	g_debug ("%s: Leaving %s ", G_STRLOC, G_STRFUNC);
+
+	return session;
+}
+
 gboolean
 exchange_mapi_create_profile (const gchar *username, const gchar *password, const gchar *domain,
 			      const gchar *server, gchar **error_msg,
@@ -3252,19 +3393,19 @@ exchange_mapi_create_profile (const gchar *username, const gchar *password, cons
 	g_return_val_if_fail (username && *username && password && *password &&
 			      domain && *domain && server && *server, FALSE);
 
-	g_debug ("Create profile with %s %s %s\n", username, domain, server);
-
-	LOCK ();
+	g_static_mutex_lock (&profile_mutex);
 
-	profname = exchange_mapi_util_profile_name (username, domain);
+	g_debug ("Create profile with %s %s %s\n", username, domain, server);
 
 	if (!ensure_mapi_init_called ()) {
-		UNLOCK ();
+		g_static_mutex_unlock (&profile_mutex);
 		return FALSE;
 	}
 
+	profname = exchange_mapi_util_profile_name (username, domain, server, TRUE);
+
 	/* Delete any existing profiles with the same profilename */
-	retval = DeleteProfile(profname);
+	retval = DeleteProfile (profname);
 	/* don't bother to check error - it would be valid if we got an error */
 
 	retval = CreateProfile(profname, username, password, OC_PROFILE_NOPASSWORD);
@@ -3300,32 +3441,32 @@ exchange_mapi_create_profile (const gchar *username, const gchar *password, cons
 		manage_mapi_error ("ProcessNetworkProfile", GetLastError(), error_msg);
 		g_debug ("Deleting profile %s ", profname);
 		DeleteProfile(profname);
-		goto exit;
-	}
-	g_debug("ProcessNetworkProfile : succeeded \n");
-
-	/* Set it as the default profile. Is this needed? */
-	retval = SetDefaultProfile(profname);
-	if (retval != MAPI_E_SUCCESS) {
-		manage_mapi_error ("SetDefaultProfile", GetLastError(), error_msg);
 		goto cleanup;
 	}
+	g_debug("ProcessNetworkProfile : succeeded \n");
 
-	/* Close the connection, so that we can login with what we created */
-	exchange_mapi_connection_close ();
-
-	/* Initialize a global connection */
-	if (exchange_mapi_connection_new (profname, password)) {
-		result = TRUE;
-		exchange_mapi_peek_folder_list ();
-	} else
-		goto exit;
+	result = TRUE;
 
  cleanup:
- exit:
 	g_free (profname);
 
-	UNLOCK ();
+	/* this is causing segfault in openchange */
+	/*if (session && result) {
+		mapi_object_t msg_store;
+
+		mapi_object_init (&msg_store);
+
+		if (OpenMsgStore (session, &msg_store) == MAPI_E_SUCCESS) {
+			Logoff (&msg_store);
+		} else {
+			/ * how to close and free session without store? * /
+			mapi_errstr ("OpenMsgStore", GetLastError());
+		}
+
+		mapi_object_release (&msg_store);
+	}*/
+
+	g_static_mutex_unlock (&profile_mutex);
 
 	return result;
 }
@@ -3333,27 +3474,23 @@ exchange_mapi_create_profile (const gchar *username, const gchar *password, cons
 gboolean
 exchange_mapi_delete_profile (const gchar *profile)
 {
-	enum MAPISTATUS	retval;
 	gboolean result = FALSE;
 
-	LOCK ();
+	g_static_mutex_lock (&profile_mutex);
 
-	if (!ensure_mapi_init_called ()) {
-		goto cleanup;
-	}
+	if (ensure_mapi_init_called ()) {
+		g_debug ("Deleting profile %s ", profile);
 
-	g_debug ("Deleting profile %s ", profile);
-	retval = DeleteProfile(profile);
-	if (retval != MAPI_E_SUCCESS) {
-		mapi_errstr("DeleteProfile", GetLastError());
-		goto cleanup;
+		if (DeleteProfile (profile) == MAPI_E_SUCCESS) {
+			result = TRUE;
+		} else {
+			mapi_errstr ("DeleteProfile", GetLastError());
+		}
 	}
 
-	exchange_mapi_connection_close ();
-	result = TRUE;
-
-cleanup:
-	UNLOCK ();
+	g_static_mutex_unlock (&profile_mutex);
 
 	return result;
 }
+
+/* profile related functions - end */
diff --git a/src/libexchangemapi/exchange-mapi-connection.h b/src/libexchangemapi/exchange-mapi-connection.h
index bbc5227..d55d435 100644
--- a/src/libexchangemapi/exchange-mapi-connection.h
+++ b/src/libexchangemapi/exchange-mapi-connection.h
@@ -26,9 +26,23 @@
 #define EXCHANGE_MAPI_CONNECTION_H 
 
 #include <glib.h>
+#include <glib-object.h>
 
 #include <libmapi/libmapi.h>
 
+/* Standard GObject macros */
+#define EXCHANGE_TYPE_MAPI_CONNECTION (exchange_mapi_connection_get_type ())
+#define EXCHANGE_MAPI_CONNECTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EXCHANGE_TYPE_MAPI_CONNECTION, ExchangeMapiConnection))
+#define EXCHANGE_MAPI_CONNECTION_CLASS(cls) (G_TYPE_CHECK_CLASS_CAST ((cls), EXCHANGE_TYPE_MAPI_CONNECTION, ExchangeMapiConnectionClass))
+#define EXCHANGE_IS_MAPI_CONNECTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EXCHANGE_TYPE_MAPI_CONNECTION))
+#define EXCHANGE_IS_MAPI_CONNECTION_CLASS(cls) (G_TYPE_CHECK_CLASS_TYPE ((cls), EXCHANGE_TYPE_MAPI_CONNECTION))
+#define EXCHANGE_MAPI_CONNECTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EXCHANGE_TYPE_MAPI_CONNECTION, ExchangeMapiConnectionClass))
+
+G_BEGIN_DECLS
+
+typedef struct _ExchangeMapiConnection ExchangeMapiConnection;
+typedef struct _ExchangeMapiConnectionClass ExchangeMapiConnectionClass;
+
 typedef enum {
 	MAPI_OPTIONS_FETCH_ATTACHMENTS = 1<<0,
 	MAPI_OPTIONS_FETCH_RECIPIENTS = 1<<1,
@@ -102,6 +116,7 @@ typedef struct {
 } ExchangeMAPIAttachment;
 
 typedef struct {
+	ExchangeMapiConnection *conn;
 	struct mapi_SPropValue_array *properties;
 	mapi_id_t fid;
 	mapi_id_t mid;
@@ -121,113 +136,99 @@ typedef gboolean (*FetchCallback)	(FetchItemsCallbackData *item_data, gpointer d
 typedef gboolean (*BuildNameID)	(struct mapi_nameid *nameid, gpointer data);
 typedef gint	 (*BuildProps)		(struct SPropValue **, struct SPropTagArray *, gpointer data);
 
-gboolean
-exchange_mapi_connection_new (const gchar *profile, const gchar *password);
 
-void
-exchange_mapi_connection_close (void);
+struct _ExchangeMapiConnection {
+	GObject parent;
+};
 
-gboolean
-exchange_mapi_connection_exists (void);
+struct _ExchangeMapiConnectionClass {
+	GObjectClass parent_class;
 
-gboolean
-exchange_mapi_connection_fetch_item (mapi_id_t fid, mapi_id_t mid,
-				     const uint32_t *GetPropsList, const uint16_t cn_props,
-				     BuildNameID build_name_id, gpointer build_name_data,
-				     FetchCallback cb, gpointer data,
-				     guint32 options);
-gboolean
-exchange_mapi_connection_fetch_items   (mapi_id_t fid,
-					struct mapi_SRestriction *res,struct SSortOrderSet *sort_order,
+	/* signals */
+};
+
+GType			exchange_mapi_connection_get_type (void);
+ExchangeMapiConnection *exchange_mapi_connection_new (const gchar *profile, const gchar *password);
+ExchangeMapiConnection *exchange_mapi_connection_find (const gchar *profile);
+gboolean		exchange_mapi_connection_reconnect (ExchangeMapiConnection *conn, const gchar *password);
+gboolean		exchange_mapi_connection_close (ExchangeMapiConnection *conn);
+gboolean		exchange_mapi_connection_connected (ExchangeMapiConnection *conn);
+gboolean		exchange_mapi_connection_fetch_item (ExchangeMapiConnection *conn, mapi_id_t fid, mapi_id_t mid,
 					const uint32_t *GetPropsList, const uint16_t cn_props,
 					BuildNameID build_name_id, gpointer build_name_data,
 					FetchCallback cb, gpointer data,
 					guint32 options);
 
-gboolean
-exchange_mapi_util_get_gal (GPtrArray *contacts_array);
-
-mapi_id_t
-exchange_mapi_create_folder (uint32_t olFolder, mapi_id_t pfid, const gchar *name);
-
-gboolean
-exchange_mapi_remove_folder (uint32_t olFolder, mapi_id_t fid);
-
-gboolean
-exchange_mapi_empty_folder (mapi_id_t fid);
-
-gboolean
-exchange_mapi_rename_folder (mapi_id_t fid, const gchar *new_name);
-
-gboolean
-exchange_mapi_move_folder (mapi_id_t src_fid, mapi_id_t src_parent_fid, mapi_id_t des_fid, const gchar *new_name);
-
-GSList *
-exchange_mapi_util_check_restriction (mapi_id_t fid, struct mapi_SRestriction *res);
-
-mapi_id_t
-exchange_mapi_get_default_folder_id (uint32_t olFolder);
+gboolean		exchange_mapi_connection_fetch_items (ExchangeMapiConnection *conn, mapi_id_t fid,
+					struct mapi_SRestriction *res,struct SSortOrderSet *sort_order,
+					const uint32_t *GetPropsList, const uint16_t cn_props,
+					BuildNameID build_name_id, gpointer build_name_data,
+					FetchCallback cb, gpointer data,
+					guint32 options);
 
-mapi_id_t
-exchange_mapi_create_item (uint32_t olFolder, mapi_id_t fid,
-			   BuildNameID build_name_id, gpointer ni_data,
-			   BuildProps build_props, gpointer p_data,
-			   GSList *recipients, GSList *attachments, GSList *generic_streams,
-			   uint32_t options);
-gboolean
-exchange_mapi_modify_item (uint32_t olFolder, mapi_id_t fid, mapi_id_t mid,
-			   BuildNameID build_name_id, gpointer ni_data,
-			   BuildProps build_props, gpointer p_data,
-			   GSList *recipients, GSList *attachments, GSList *generic_streams,
-			   uint32_t options);
+gboolean		exchange_mapi_connection_get_gal (ExchangeMapiConnection *conn, GPtrArray *contacts_array);
+mapi_id_t		exchange_mapi_connection_create_folder (ExchangeMapiConnection *conn, uint32_t olFolder, mapi_id_t pfid, const gchar *name);
+gboolean		exchange_mapi_connection_remove_folder (ExchangeMapiConnection *conn, mapi_id_t fid);
+gboolean		exchange_mapi_connection_empty_folder (ExchangeMapiConnection *conn, mapi_id_t fid);
+gboolean		exchange_mapi_connection_rename_folder (ExchangeMapiConnection *conn, mapi_id_t fid, const gchar *new_name);
+gboolean		exchange_mapi_connection_move_folder (ExchangeMapiConnection *conn, mapi_id_t src_fid, mapi_id_t src_parent_fid, mapi_id_t des_fid, const gchar *new_name);
+GSList *		exchange_mapi_connection_check_restriction (ExchangeMapiConnection *conn, mapi_id_t fid, struct mapi_SRestriction *res);
+mapi_id_t		exchange_mapi_connection_get_default_folder_id (ExchangeMapiConnection *conn, uint32_t olFolder);
+mapi_id_t		exchange_mapi_connection_create_item (ExchangeMapiConnection *conn, uint32_t olFolder, mapi_id_t fid,
+					BuildNameID build_name_id, gpointer ni_data,
+					BuildProps build_props, gpointer p_data,
+					GSList *recipients, GSList *attachments, GSList *generic_streams,
+					uint32_t options);
+
+gboolean		exchange_mapi_connection_modify_item (ExchangeMapiConnection *conn, uint32_t olFolder, mapi_id_t fid, mapi_id_t mid,
+					BuildNameID build_name_id, gpointer ni_data,
+					BuildProps build_props, gpointer p_data,
+					GSList *recipients, GSList *attachments, GSList *generic_streams,
+					uint32_t options);
+
+gboolean		exchange_mapi_connection_set_flags (ExchangeMapiConnection *conn, uint32_t olFolder, mapi_id_t fid, GSList *mid_list, uint32_t flag, guint32 options);
+gboolean		exchange_mapi_connection_remove_items (ExchangeMapiConnection *conn, uint32_t olFolder, mapi_id_t fid, GSList *mids);
+gboolean		exchange_mapi_connection_copy_items (ExchangeMapiConnection *conn, mapi_id_t src_fid, mapi_id_t dest_fid, GSList *mids);
+gboolean		exchange_mapi_connection_move_items (ExchangeMapiConnection *conn, mapi_id_t src_fid, mapi_id_t dest_fid, GSList *mids);
+gboolean 		exchange_mapi_connection_get_folders_list (ExchangeMapiConnection *conn, GSList **mapi_folders);
+gboolean		exchange_mapi_connection_get_pf_folders_list (ExchangeMapiConnection *conn, GSList **mapi_folders, mapi_id_t parent_id);
+GSList *		exchange_mapi_connection_peek_folders_list (ExchangeMapiConnection *conn);
+struct SPropTagArray *	exchange_mapi_connection_resolve_named_props (ExchangeMapiConnection *conn, uint32_t olFolder, mapi_id_t fid,
+					BuildNameID build_name_id, gpointer ni_data);
+
+struct SPropTagArray *	exchange_mapi_connection_resolve_named_prop (ExchangeMapiConnection *conn, uint32_t olFolder, mapi_id_t fid,
+					uint16_t lid, const gchar *OLEGUID);
+
+uint32_t		exchange_mapi_connection_create_named_prop (ExchangeMapiConnection *conn, uint32_t olFolder, mapi_id_t fid,
+					const gchar *named_prop_name, uint32_t ptype);
+
+const gchar *		exchange_mapi_connection_ex_to_smtp (ExchangeMapiConnection *conn, const gchar *ex_address);
 
-gboolean
-exchange_mapi_set_flags (uint32_t olFolder, mapi_id_t fid, GSList *mid_list, uint32_t flag, guint32 options);
+/* Push notifications APIs */
+typedef gboolean (*exchange_check_continue) (void);
 
-gboolean
-exchange_mapi_remove_items (uint32_t olFolder, mapi_id_t fid, GSList *mids);
+gboolean		exchange_mapi_connection_events_init (ExchangeMapiConnection *conn);
+gboolean		exchange_mapi_connection_events_monitor (ExchangeMapiConnection *conn, struct mapi_notify_continue_callback_data *cb_data);
 
-gboolean
-exchange_mapi_copy_items ( mapi_id_t src_fid, mapi_id_t dest_fid, GSList *mids);
+gboolean		exchange_mapi_connection_events_subscribe (ExchangeMapiConnection *conn, guint32 options,
+					guint16 event_mask, guint32 *events_conn_id,
+					mapi_notify_callback_t callback, gpointer data);
 
-gboolean
-exchange_mapi_move_items ( mapi_id_t src_fid, mapi_id_t dest_fid, GSList *mids);
+gboolean		exchange_mapi_connection_events_subscribe_and_monitor (ExchangeMapiConnection *conn, mapi_id_t *obj_id, guint32 options,
+					guint16 event_mask, guint32 *events_conn_id,
+					gboolean use_store, mapi_notify_callback_t callback,
+					gpointer data);
 
-gboolean exchange_mapi_get_folders_list (GSList **mapi_folders);
-gboolean exchange_mapi_get_pf_folders_list (GSList **mapi_folders, mapi_id_t parent_id);
+gboolean		exchange_mapi_connection_events_unsubscribe (ExchangeMapiConnection *conn, guint32 events_conn_id);
 
-struct SPropTagArray *
-exchange_mapi_util_resolve_named_props (uint32_t olFolder, mapi_id_t fid,
-				   BuildNameID build_name_id, gpointer ni_data);
-struct SPropTagArray *
-exchange_mapi_util_resolve_named_prop (uint32_t olFolder, mapi_id_t fid,
-				       uint16_t lid, const gchar *OLEGUID);
-uint32_t
-exchange_mapi_util_create_named_prop (uint32_t olFolder, mapi_id_t fid,
-				      const gchar *named_prop_name, uint32_t ptype);
+/* profile functions */
 
-gboolean exchange_mapi_create_profile (const gchar *username, const gchar *password,
+gboolean		exchange_mapi_create_profile (const gchar *username, const gchar *password,
 				       const gchar *domain, const gchar *server,
 				       gchar **error_msg, mapi_profile_callback_t cb, gpointer data);
-gboolean exchange_mapi_delete_profile (const gchar *profile);
-
-/* Push notifications APIs */
-typedef gboolean (*exchange_check_continue) (void);
-
-gboolean exchange_mapi_events_init ();
-
-gboolean exchange_mapi_events_monitor (struct mapi_notify_continue_callback_data *cb_data);
-
-gboolean exchange_mapi_events_subscribe (guint32 options,
-					 guint16 event_mask, guint32 *connection,
-					 mapi_notify_callback_t callback, gpointer data);
 
-gboolean exchange_mapi_events_unsubscribe (guint32 connection);
+gboolean		exchange_mapi_delete_profile (const gchar *profile);
 
-gboolean
-exchange_mapi_events_subscribe_and_monitor (mapi_id_t *obj_id, guint32 options,
-					    guint16 event_mask, guint32 *connection,
-					    gboolean use_store, mapi_notify_callback_t callback,
-					    gpointer data);
+G_END_DECLS
 
 #endif
diff --git a/src/libexchangemapi/exchange-mapi-folder.c b/src/libexchangemapi/exchange-mapi-folder.c
index a9cde99..d2efc9d 100644
--- a/src/libexchangemapi/exchange-mapi-folder.c
+++ b/src/libexchangemapi/exchange-mapi-folder.c
@@ -28,13 +28,6 @@
 #include "exchange-mapi-connection.h"
 #include "exchange-mapi-folder.h"
 
-static GSList *folder_list = NULL;
-
-/* we use a static mutex - even the same thread *may not* use the static vars concurrently */
-static GStaticMutex folder_lock = G_STATIC_MUTEX_INIT;
-
-#define LOCK()		g_message("%s: %s: lock(folder_lock)", G_STRLOC, G_STRFUNC);g_static_mutex_lock(&folder_lock)
-#define UNLOCK()	g_message("%s: %s: unlock(folder_lock)", G_STRLOC, G_STRFUNC);g_static_mutex_unlock(&folder_lock)
 #define d(x) x
 
 static ExchangeMAPIFolderType
@@ -137,71 +130,9 @@ exchange_mapi_folder_get_total_count (ExchangeMAPIFolder *folder)
 	return folder->total;
 }
 
-GSList *
-exchange_mapi_peek_folder_list (void)
-{
-	LOCK ();
-	if (!folder_list)
-		exchange_mapi_get_folders_list (&folder_list);
-	if (!folder_list)
-		g_warning ("Get folders list call failed \n");
-	UNLOCK ();
-
-	return folder_list;
-}
-
-ExchangeMAPIFolder *
-exchange_mapi_folder_get_folder (mapi_id_t fid)
-{
-	GSList *tmp = folder_list;
-
-	if (!folder_list)
-		exchange_mapi_peek_folder_list ();
-
-	tmp = folder_list;
-	while (tmp) {
-		ExchangeMAPIFolder * folder = tmp->data;
-		g_print ("%016" G_GINT64_MODIFIER "X %016" G_GINT64_MODIFIER "X\n", folder->folder_id, fid);
-		if (folder->folder_id == fid)
-			return folder;
-		tmp=tmp->next;
-	}
-
-	return NULL;
-}
-
 void
-exchange_mapi_folder_list_free (void)
+exchange_mapi_folder_free_list (GSList *folder_list)
 {
-	LOCK ();
 	g_slist_foreach (folder_list, (GFunc) exchange_mapi_folder_free, NULL);
 	g_slist_free (folder_list);
-
-	folder_list = NULL;
-	UNLOCK ();
-
-	d(g_print("Folder list freed\n"));
-}
-
-void
-exchange_mapi_folder_list_add (ExchangeMAPIFolder *folder)
-{
-	GSList *tmp = folder_list;
-	LOCK ();
-	while (tmp) {
-		ExchangeMAPIFolder *data = tmp->data;
-		if (data->folder_id == folder->parent_folder_id) {
-			/* Insert it here */
-			d(g_print ("Inserted below the parent\n"));
-			folder_list = g_slist_insert_before (folder_list, tmp->next, folder);
-			UNLOCK ();
-			return;
-		}
-		tmp = tmp->next;
-	}
-
-	/* Append at the end */
-	folder_list = g_slist_append (folder_list, folder);
-	UNLOCK ();
-	d(g_print("Appended folder at the end\n"));
 }
diff --git a/src/libexchangemapi/exchange-mapi-folder.h b/src/libexchangemapi/exchange-mapi-folder.h
index 0867337..a8ee366 100644
--- a/src/libexchangemapi/exchange-mapi-folder.h
+++ b/src/libexchangemapi/exchange-mapi-folder.h
@@ -86,11 +86,8 @@ guint64 exchange_mapi_folder_get_parent_id (ExchangeMAPIFolder *folder);
 ExchangeMAPIFolderType exchange_mapi_folder_get_type (ExchangeMAPIFolder *folder);
 guint32 exchange_mapi_folder_get_unread_count (ExchangeMAPIFolder *folder);
 guint32 exchange_mapi_folder_get_total_count (ExchangeMAPIFolder *folder);
-
 gboolean exchange_mapi_folder_is_root (ExchangeMAPIFolder *folder);
-GSList * exchange_mapi_peek_folder_list (void);
-void exchange_mapi_folder_list_free (void);
-ExchangeMAPIFolder * exchange_mapi_folder_get_folder (mapi_id_t fid);
-void exchange_mapi_folder_list_add (ExchangeMAPIFolder *folder);
+
+void exchange_mapi_folder_free_list (GSList *folder_list);
 
 #endif
diff --git a/src/libexchangemapi/exchange-mapi-utils.c b/src/libexchangemapi/exchange-mapi-utils.c
index c4e57d9..0a69b41 100644
--- a/src/libexchangemapi/exchange-mapi-utils.c
+++ b/src/libexchangemapi/exchange-mapi-utils.c
@@ -601,16 +601,32 @@ exchange_crlf_to_lf (const gchar *in)
  * exchange_mapi_util_profile_name:
  * @username: User name of the profile
  * @domain: Domain name of the profile
+ * @hostname: Server host name
+ * @migrate: whether migrate old profile name to a new one
  *
- * Constructs profile name from given @username and @domain and
- * returns it as a newly allocated string.
+ * Constructs profile name from given parameters and
+ * returns it as a newly allocated string. It can also
+ * rename old profile name string to a new name, if requested. 
  **/
 gchar *
-exchange_mapi_util_profile_name (const gchar *username, const gchar *domain)
+exchange_mapi_util_profile_name (const gchar *username, const gchar *domain, const gchar *hostname, gboolean migrate)
 {
 	gchar *res;
 
-	res = g_strdup_printf ("%s %s", username, domain);
+	res = g_strdup_printf ("%s %s@%s", username, domain, hostname);
+	res = g_strcanon (res, "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789  -", '_');
 
-	return g_strcanon (res, "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789@", '_');
+	if (migrate) {
+		/* expects MAPIInitialize already called! */
+		gchar *old_name;
+
+		old_name = g_strdup_printf ("%s %s", username, domain);
+		old_name = g_strcanon (old_name, "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789@", '_');
+
+		RenameProfile (old_name, res);
+
+		g_free (old_name);
+	}
+
+	return res;
 }
diff --git a/src/libexchangemapi/exchange-mapi-utils.h b/src/libexchangemapi/exchange-mapi-utils.h
index 2885d2a..48cbad8 100644
--- a/src/libexchangemapi/exchange-mapi-utils.h
+++ b/src/libexchangemapi/exchange-mapi-utils.h
@@ -56,9 +56,6 @@ exchange_mapi_util_free_recipient_list (GSList **recip_list);
 void
 exchange_mapi_util_free_stream_list (GSList **stream_list);
 
-const gchar *
-exchange_mapi_util_ex_to_smtp (const gchar *ex_address);
-
 void
 exchange_mapi_debug_property_dump (struct mapi_SPropValue_array *properties);
 
@@ -72,7 +69,7 @@ exchange_lf_to_crlf (const gchar *in);
 gchar *
 exchange_crlf_to_lf (const gchar *in);
 
-gchar *exchange_mapi_util_profile_name (const gchar *username, const gchar *domain);
+gchar *exchange_mapi_util_profile_name (const gchar *username, const gchar *domain, const gchar *hostname, gboolean migrate);
 
 #endif
 



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