[evolution-exchange] Bug #456240 - Move exchange plugin to exchange package



commit d0236a993c6ea6c7d9427143b48c591e21e4ab5b
Author: Milan Crha <mcrha redhat com>
Date:   Fri Oct 2 15:08:53 2009 +0200

    Bug #456240 - Move exchange plugin to exchange package

 Makefile.am                                     |    1 +
 configure.ac                                    |   20 +-
 eplugin/ChangeLog                               | 1874 +++++++++++++++++++++++
 eplugin/Makefile.am                             |   77 +
 eplugin/exchange-account-setup.c                | 1150 ++++++++++++++
 eplugin/exchange-calendar.c                     |  539 +++++++
 eplugin/exchange-change-password.c              |  194 +++
 eplugin/exchange-change-password.h              |   33 +
 eplugin/exchange-config-listener.c              | 1520 ++++++++++++++++++
 eplugin/exchange-config-listener.h              |   84 +
 eplugin/exchange-contacts.c                     |  548 +++++++
 eplugin/exchange-delegates-user.c               |  628 ++++++++
 eplugin/exchange-delegates-user.h               |   81 +
 eplugin/exchange-delegates.c                    | 1027 +++++++++++++
 eplugin/exchange-delegates.h                    |   34 +
 eplugin/exchange-folder-permission.c            |  527 +++++++
 eplugin/exchange-folder-size-display.c          |  170 ++
 eplugin/exchange-folder-size-display.h          |   33 +
 eplugin/exchange-folder-subscription.c          |  380 +++++
 eplugin/exchange-folder-subscription.h          |   34 +
 eplugin/exchange-folder.c                       |  420 +++++
 eplugin/exchange-mail-send-options.c            |  196 +++
 eplugin/exchange-operations.c                   |  305 ++++
 eplugin/exchange-operations.h                   |   56 +
 eplugin/exchange-permissions-dialog.c           |  984 ++++++++++++
 eplugin/exchange-permissions-dialog.h           |   56 +
 eplugin/exchange-send-options.c                 |  621 ++++++++
 eplugin/exchange-send-options.h                 |   83 +
 eplugin/exchange-user-dialog.c                  |  285 ++++
 eplugin/exchange-user-dialog.h                  |   56 +
 eplugin/org-gnome-exchange-operations.eplug     |  114 ++
 eplugin/org-gnome-exchange-operations.eplug.xml |  120 ++
 eplugin/org-gnome-exchange-operations.error     |  262 ++++
 eplugin/org-gnome-exchange-operations.error.xml |  263 ++++
 34 files changed, 12771 insertions(+), 4 deletions(-)
---
diff --git a/Makefile.am b/Makefile.am
index 31f991e..c584ad1 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1,4 +1,5 @@
 SUBDIRS = \
+	eplugin \
 	tools \
 	camel \
 	addressbook \
diff --git a/configure.ac b/configure.ac
index e7003c0..1fbe5f8 100644
--- a/configure.ac
+++ b/configure.ac
@@ -11,6 +11,7 @@ AM_INIT_AUTOMAKE(AC_PACKAGE_NAME, AC_PACKAGE_VERSION)
 m4_define([glib_minimum_version], [2.16.0])
 m4_define([gtk_minimum_version], [2.10.0])
 m4_define([eds_minimum_version], [eex_version])
+m4_define([evo_minimum_version], [eex_version])
 m4_define([gconf_minimum_version], [2.0.0])             # XXX Just a Guess
 m4_define([libbonobo_minimum_version], [2.20.3])
 m4_define([libxml_minimum_version], [2.0.0])            # XXX Just a Guess
@@ -192,6 +193,12 @@ if test "x$EXCHANGE_PACKAGE" != "x"; then
 	exit 1
 fi
 
+plugindir=`$PKG_CONFIG --variable=plugindir evolution-plugin`
+AC_SUBST(plugindir)
+
+EVOLUTION_PLUGIN_errordir="`pkg-config --variable=errordir evolution-plugin`"
+AC_SUBST(EVOLUTION_PLUGIN_errordir)
+
 extensiondir="`pkg-config --variable=extensiondir evolution-data-server-$EDS_API_VERSION`"
 AC_SUBST(extensiondir)
 
@@ -207,9 +214,6 @@ AC_SUBST(EVOLUTION_privlibdir)
 EVOLUTION_privlibexecdir="`pkg-config --variable=privlibexecdir evolution-shell`"
 AC_SUBST(EVOLUTION_privlibexecdir)
 
-EVOLUTION_privdatadir="`pkg-config --variable=privdatadir evolution-shell`"
-AC_SUBST(EVOLUTION_privdatadir)
-
 EVOLUTION_imagesdir="`pkg-config --variable=imagesdir evolution-shell`"
 AC_SUBST(EVOLUTION_imagesdir)
 
@@ -230,7 +234,7 @@ AC_SUBST(CAMEL_CFLAGS)
 PKG_CHECK_MODULES(MAIL, libecal-$EDS_API_VERSION)
 AC_SUBST(MAIL_CFLAGS)
 
-PKG_CHECK_MODULES(EXCHANGE_STORAGE, evolution-shell evolution-plugin libedataserverui-$EDS_API_VERSION libedata-book-$EDS_API_VERSION libedata-cal-$EDS_API_VERSION libsoup-2.4 libxml-2.0 camel-provider-$EDS_API_VERSION)
+PKG_CHECK_MODULES(EXCHANGE_STORAGE, libedataserverui-$EDS_API_VERSION libedata-book-$EDS_API_VERSION libedata-cal-$EDS_API_VERSION libsoup-2.4 libxml-2.0 camel-provider-$EDS_API_VERSION)
 AC_SUBST(EXCHANGE_STORAGE_CFLAGS)
 AC_SUBST(EXCHANGE_STORAGE_LIBS)
 
@@ -238,6 +242,13 @@ PKG_CHECK_MODULES(LIBEXCHANGE, libsoup-2.4 evolution-shell libedataserverui-$EDS
 AC_SUBST(LIBEXCHANGE_CFLAGS)
 AC_SUBST(LIBEXCHANGE_LIBS)
 
+dnl ****************************
+dnl Check for evolution plugins 
+dnl ****************************
+PKG_CHECK_MODULES(EVOLUTION_PLUGIN, evolution-plugin >= evo_minimum_version)
+AC_SUBST(EVOLUTION_PLUGIN_CFLAGS)
+AC_SUBST(EVOLUTION_PLUGIN_LIBS)
+
 dnl *********************
 dnl Pilot license support
 dnl *********************
@@ -374,6 +385,7 @@ dnl ******************************
 AC_OUTPUT([
 Makefile
 evolution-exchange-zip
+eplugin/Makefile
 camel/Makefile
 addressbook/Makefile
 calendar/Makefile
diff --git a/eplugin/ChangeLog b/eplugin/ChangeLog
new file mode 100644
index 0000000..91a2e01
--- /dev/null
+++ b/eplugin/ChangeLog
@@ -0,0 +1,1874 @@
+2009-04-24  Milan Crha  <mcrha redhat com>
+
+	** Fix for bug #572348
+
+	* exchange-delegates.glade:
+	* e-foreign-folder-dialog.glade:
+	* exchange-folder-subscription.c:
+	* exchange-delegates-user.c:
+	Remove deprecated Gtk+ symbols.
+
+2009-02-26  Andre Klapper  <a9016009 gmx de>
+
+	* exchange-permissions-dialog.c:
+	remove deprecated and commented code.
+
+2008-12-08  Bharath Acharya  <abharath novell com>
+
+	** Fix for bug #558498
+
+	* exchange-account-setup.c: (org_gnome_exchange_settings),
+	(destroy_oof_data), (org_gnome_exchange_commit):
+	* org-gnome-exchange-operations.error.xml:Check for the offline status
+	before setting up the Exchange settings.
+
+2008-12-02  Milan Crha  <mcrha redhat com>
+
+	** Part of fix for bug #562228
+
+	* exchange-account-setup.c: (want_mailbox_toggled),
+	(org_gnome_exchange_owa_url):
+	Make it clearer the mailbox entry is optional.
+
+2008-10-22  Bharath Acharya  <abharath novell com>
+
+	** Fix for bug #557246
+
+	* exchange-folder.c: (org_gnome_exchange_check_inbox_subscribed): Pop 
+	up the "Unsubscribe Folder" option only for the subscribed folders and 
+	not to the Other's folder hierarchy.
+
+2008-10-08  Milan Crha  <mcrha redhat com>
+
+	** Fix for bug #530606
+
+	* exchange-contacts.c: (e_exchange_contacts_get_contacts),
+	(e_exchange_contacts_pcontacts_on_change),
+	(e_exchange_contacts_pcontacts), (e_exchange_contacts_check),
+	(e_exchange_contacts_commit):
+	* exchange-account-setup.c: (btn_chpass_clicked), (btn_dass_clicked),
+	(btn_fsize_clicked), (org_gnome_exchange_show_folder_size_factory):
+	* exchange-calendar.c: (e_exchange_calendar_get_calendars),
+	(e_exchange_calendar_pcalendar_on_change),
+	(e_exchange_calendar_pcalendar), (e_exchange_calendar_check),
+	(e_exchange_calendar_commit):
+	Check validity of returned pointer before using it.
+
+2008-10-03  Sankar P  <psankar novell com>
+
+License Changes
+
+	* exchange-account-setup.c:
+	* exchange-contacts.c:
+	* exchange-operations.c:
+	* exchange-operations.h:
+
+2008-09-24  Sankar P  <psankar novell com>
+
+License Changes
+
+	* exchange-delegates-user.c:
+
+2008-09-23  Milan Crha  <mcrha redhat com>
+
+	** Part of fix for bug #553273
+
+	* exchange-config-listener.c: (exchange_config_listener_authenticate):
+	Always end e_error_run/e_error_new calls with NULL parameter.
+
+2008-09-16  Sankar P  <psankar novell com>
+
+License Changes
+
+	* exchange-user-dialog.c:
+
+2008-09-04  Sankar P  <psankar novell com>
+
+License Changes
+
+	* exchange-calendar.c:
+
+2008-09-02  Sankar P  <psankar novell com>
+
+License Changes
+
+	* exchange-config-listener.c:
+	* exchange-delegates.c:
+	* exchange-folder-size-display.c:
+	* exchange-folder.c:
+	* exchange-mail-send-options.c:
+	* exchange-permissions-dialog.c:
+	* exchange-permissions-dialog.h:
+	* exchange-send-options.c:
+	* exchange-user-dialog.h:
+
+2008-08-28  Matthew Barnes  <mbarnes redhat com>
+
+	** Fixes bug #458512
+
+	* exchange-send-options.glade:
+	Delete the accessibility tag from the User button.
+
+2008-08-27  Sankar P  <psankar novell com>
+
+License Changes
+
+	* exchange-change-password.c:
+	* exchange-change-password.h:
+	* exchange-config-listener.h:
+	* exchange-delegates-user.h:
+	* exchange-delegates.h:
+	* exchange-folder-permission.c:
+	* exchange-folder-size-display.h:
+	* exchange-folder-subscription.c:
+	* exchange-folder-subscription.h:
+	* exchange-send-options.h:
+
+2008-08-14  Matthew Barnes  <mbarnes redhat com>
+
+	* exchange-send-options.c:
+	Use e_display_help() for displaying help.
+
+2008-08-06  Milan Crha  <mcrha redhat com>
+
+	** Fix for bug #435969
+
+	* org-gnome-exchange-operations.eplug.xml:
+	Show authentication section in an account druid too.
+
+2008-07-31  Matthew Barnes  <mbarnes redhat com>
+
+	** Fixes part of bug #545568
+
+	* org-gnome-exchange-operations.eplug.xml:
+	Add "system_plugin=true" so it's not shown in the Plugin Manager.
+	This plugin is not designed to be disabled by the user.
+
+2008-07-30  Milan Crha  <mcrha redhat com>
+
+	** Part of fix for bug #500389
+
+	* exchange-account-setup.c: (gal_auth_to_string),
+	(owa_authenticate_user): Use default authentication for GAL.
+
+2008-07-11  Bharath Acharya  <abharath novell com>
+
+	** Fix for bug #542149
+
+	* exchange-folder-subscription.c: (subscribe_to_folder): Display an 
+	error message to restart if user tries to subscribe to other's mailbox.
+	* org-gnome-exchange-operations.error.xml: Added the corresponding 
+	error message.
+
+2008-06-16  Milan Crha  <mcrha redhat com>
+
+	** Fix for bug #273627
+
+	* exchange-account-setup.c: (owa_authenticate_user),
+	(update_mailbox_param_in_url), (mailbox_editor_entry_changed),
+	(org_gnome_exchange_owa_url): New entry to enter mailbox name in case
+	it differs from the username. The entry is updated after a validation
+	and shows the mailbox name as was used for validation.
+
+2008-06-05  Matthew Barnes  <mbarnes redhat com>
+
+	* exchange-permissions-dialog.c:
+	Here too.
+
+2008-06-04  Matthew Barnes  <mbarnes redhat com>
+
+	* exchange-delegates-user.c:
+	Don't undef DISABLE_DEPRECATED macros in source code.
+	That's just evil.
+
+2008-06-02  Jacob Brown  <jeblinux gmail com>
+
+	** Fix for bug #529464
+
+	* org-gnome-exchange-operations.eplug.xml: Do not use "handle"
+
+2008-05-27  Bharath Acharya  <abharath novell com>
+
+	* Fixes bnc #394441
+
+	* exchange-contacts.c: (e_exchange_contacts_commit): Fixes a double
+	free
+
+2008-05-22  Matthew Barnes  <mbarnes redhat com>
+
+	** Fixes part of bug #534360
+
+	* exchange-account-setup.c:
+	* exchange-send-options.h:
+	Migrate from deprecated GtkObject symbols to GObject equivalents.
+
+2008-04-21  Bharath Acharya  <abharath novell com>
+
+	Fixes bnc #378203
+
+	* exchange-folder-permission.c: 
+	(org_gnome_exchange_folder_permissions): Return sanely if the path 
+	value is corrupted.
+
+2008-04-02  Matthew Barnes  <mbarnes redhat com>
+
+	* Makefile.am:
+	Add EVOLUTION_MAIL_CFLAGS and EVOLUTION_MAIL_LIBS.
+
+	* exchange-mail-send-options.c (append_to_header),
+	(org_gnome_exchange_send_options):
+	Adapt to streamlined EMsgComposer API.
+
+2008-04-02  Ross Burton  <ross openedhand com>
+
+	** Fix for bug #522764
+
+	* exchange-account-setup.c:
+	* exchange-folder-subscription.c:
+	* exchange-folder-permission.c: Remove unused include.
+
+2008-03-18  Milan Crha  <mcrha redhat com>
+
+	** Part of fix for bug #511952
+
+	* exchange-folder-subscription.c: (setup_name_selector):
+	* exchange-send-options.c: (exchange_sendoptions_dialog_run):
+	Marking text for translation.
+
+2008-02-18  Srinivasa Ragavan  <sragavan novell com>
+
+	* Fix for bug #339266 
+
+	* exchange-account-setup.c:
+	(org_gnome_exchange_show_folder_size_factory): Upstreamed OpenSUSE
+	patch.
+
+2008-02-18  Srinivasa Ragavan  <sragavan novell com>
+
+	** Fix for bug #294999
+
+	* exchange-folder-subscription.c: (subscribe_to_folder): Upstreamed
+	OpenSUSE patch.
+
+2008-02-18  Srinivasa Ragavan  <sragavan novell com>
+
+	** Patch from OpenSUSE.
+
+	* exchange-delegates-user.c: Warnings.
+
+2008-02-18  Srinivasa Ragavan  <sragavan novell com>
+
+	* exchange-folder-subscription.c: (subscribe_to_folder),
+	(create_folder_subscription_dialog): Pushing  a downstream patch from
+	OpenSUSE.
+
+2008-02-02  Jeff Cai <jeff cai sun com>
+
+	** Fixes bug #513395
+
+	* exchange-account-setup.c: (owa_authenticate_user),
+	(owa_editor_entry_changed), (org_gnome_exchange_owa_url),
+	(org_gnome_exchange_check_options), (org_gnome_exchange_commit):
+	Check parameters before calling camel_url_new
+
+2008-01-28  Srinivasa Ragavan  <sragavan novell com>
+
+	* exchange-calendar.c: (e_exchange_calendar_commit): Fixes a double
+	free.
+
+2007-12-31  Sushma Rai  <rsushma novell com>
+
+	** Fixes bug #327965
+
+	* exchange-calendar.c (e_exchange_calendar_commit): 
+	* exchange-contacts.c (e_exchange_contacts_commit): Setting the 
+	e-source property username with domain if the domain is specified.
+
+2007-12-20  Matthew Barnes  <mbarnes redhat com>
+
+	** Fixes part of bug #362638
+
+	* exchange_folder.c:
+	Use the new MailMsg API for messages.
+
+2007-12-13  Tobias Mueller  <tobiasmue svn gnome org>
+	Patch by evilninjasquirrel hotbrev com
+	
+	** Fixes bug 474043
+	* plugins/exchange-operations/exchange-operations.c:
+	* plugins/exchange-operations/exchange-operations.h
+	Prevent buffer overflows, by introducing a fourth parameter to
+	exchange_operations_tokenize_string - a max size to copy
+
+2007-12-04  David Turner  <cillian64 googlemail com>
+
+	** Fix for bug #466241
+
+	* exchange-account-setup.c: (org_gnome_exchange_auth_section):
+	Added a mnemonic to the Authentication Type label/dropdown
+
+2007-11-27  Matthew Barnes  <mbarnes redhat com>
+
+	** Fixes part of bug #495123
+
+	* exchange-mail-send-options.c (append_to_header):
+	Use e_msg_composer_hdrs_get_from_account() to obtain the EAccount.
+
+2007-11-23  Milan Crha  <mcrha redhat com>
+
+	** Fix for bug #479081
+
+	* exchange-account-setup.c: (org_gnome_exchange_owa_url):
+	Check for input validity immediately after creating setup widgets.
+
+2007-11-14  Matthew Barnes  <mbarnes redhat com>
+
+	* exchange-folder.c (ex_create_folder_info):
+	Call camel_folder_info_new() instead of g_new0().
+
+2007-10-26  Kjartan Maraas  <kmaraas gnome org>
+
+	* exchange-account-setup.c: (org_gnome_exchange_settings),
+	(print_error), (set_oof_info), (destroy_oof_data):
+	* exchange-delegates-user.c: (exchange_delegates_user_edit):
+	* exchange-mail-send-options.c: (append_to_header):
+	Warning fixes:
+	- mark some code static
+	- use non-deprecated GSignal apis
+	- rename shadowing variable
+
+2007-10-09  Matthew Barnes  <mbarnes redhat com>
+
+	** Fixes part of bug #437579
+
+	* exchange-user-dialog.c:
+	Fix various compiler warnings.  Patch from Milan Crha.
+
+2007-10-02  Matthew Barnes  <mbarnes redhat com>
+
+	** Fixes part of bug #469657
+
+	* exchange-folder-size-display.c:
+	Use destroy functions in GHashTables to simplify memory management.
+
+2007-09-27  Matthew Barnes  <mbarnes redhat com>
+
+	** Fixes part of bug #477045
+
+	* exchange-folder-permission.c:
+	* exchange-folder.c:
+	Use standard icon names where applicable.
+
+2007-09-10  Srinivasa Ragavan  <sragavan novell com>
+
+	** Fix for bug #301044  (Novell Bugzilla)
+
+	* exchange-user-dialog.c: (e2k_user_dialog_get_user_list): Dont append
+	the comma from the Nameselector.
+
+2007-09-07  Milan Crha  <mcrha redhat com>
+
+	** Fix for bug #473903
+
+	* exchange-delegates.c: (email_look_up):
+	* exchange-mail-send-options.c: (append_to_header):
+	* exchange-delegates-user.c: (exchange_delegates_user_edit):
+	Fixes serious compiler warnings.
+
+2007-08-24  Srinivasa Ragavan  <sragavan novell com>
+
+	* org-gnome-exchange-cal-subscription.xml: Fix for empty menu in the
+	UI.
+
+2007-08-20  Matthew Barnes  <mbarnes redhat com>
+
+	* Makefile.am: Fix a distcheck error.
+
+2007-08-16  Milan Crha  <mcrha redhat com>
+
+	** Fix for bug #466548
+
+	* exchange-mail-send-options.c: (org_gnome_exchange_send_options):
+	e_msg_composer_get_preferred_account can return NULL, so test for it.
+
+2007-08-10  Milan Crha  <mcrha redhat com>
+
+	** Fix for bug #327977
+
+	* exchange-account-setup.c: (owa_authenticate_user):
+	Pass parent window to call of e2k_validate_user.
+
+2007-07-31  Veerapuram Varadhan  <vvaradhan novell com>
+
+	* exchange-delegates-user.c: (exchange_delegates_user_edit):
+	Generate HTML content for permission-summary mail, instead of
+	ascii-text content.  This is required to align strings in a table.
+
+	Committing on behalf of Bharath Acharya <abharath novell com>
+	
+2007-07-30  Andre Klapper  <a9016009 gmx de>
+
+	* exchange-permissions-dialog.glade:
+	remove "window1" string from translation
+
+2007-07-30  Chenthill Palanisamy  <pchenthill novell com>
+
+	* exchange-delegates-user.c: (map_to_full_role_name),
+	(exchange_delegates_user_edit): Added the translation comments
+	
+	Committing on behalf of Bharath Acharya <abharath novell com>	
+
+2007-07-26  Hiroyuki Ikezoe  <poincare ikezoe net>
+
+	** Fix for bug #458511
+
+	* exchange-delegates-user.c: (exchange_delegates_user_edit): each
+	message is enclosed with double quotes line by line.
+
+2007-07-12  Matthew Barnes  <mbarnes redhat com>
+
+	* exchange-delegates-user.c:
+	Fix a bunch of new implicit function declarations.
+
+2007-07-09  Chenthill Palanisamy  <pchenthill novell com>
+
+	reviewed by: Veerapuram Varadhan <vvaradhan novell com>
+
+	* exchange-delegates-user.c: (map_to_full_role_name),
+	(em_utils_delegates_done), (exchange_delegates_user_edit):
+	* exchange-delegates-user.h:
+	* exchange-delegates.c: (add_button_clicked_cb),
+	(edit_button_clicked_cb), (email_look_up), (table_click_cb):
+	* exchange-delegates.glade:
+	* exchange-delegates.h:
+	* exchange-mail-send-options.c: (append_to_header):
+	* exchange-send-options.c:
+	(exchange_send_options_get_widgets_data), (get_widgets),
+	(exchange_send_options_fill_widgets_with_data),
+	(exchange_send_options_cb), (delegate_option_toggled),
+	(addressbook_dialog_response), (addressbook_entry_changed),
+	(address_button_clicked), (exchange_sendoptions_dialog_run),
+	(exchange_sendoptions_dialog_init):
+	* exchange-send-options.glade:
+	* exchange-send-options.h:
+	* org-gnome-exchange-operations.error.xml: Added the exchange
+	delegation support.								     
+
+	Committing on behalf of Bharath Acharya <abharath novell com>	
+							  
+2007-07-03  Srinivasa Ragavan  <sragavan novell com>
+
+	* exchange-account-setup.c: (owa_authenticate_user): Form the password
+	url same as what is used every where else, so that the query can be
+	avoided.
+
+2007-06-07  Gilles Dartiguelongue  <dartigug esiee fr>
+
+	* exchange-mail-send-options.c: (org_gnome_exchange_send_options):
+	more compilation warnings cleanup, completes bug #437584 fixes
+
+2007-06-11  Milan Crha  <mcrha redhat com>
+
+	** Fix for bug #325882
+
+	* exchange-folder-tree.glade:
+	* exchange-oof.glade:
+	* e-foreign-folder-dialog.glade:
+	* exchange-passwd-expiry.glade:
+	Changed GTK_WIN_POS_NONE to GTK_WIN_POS_CENTER_ON_PARENT.
+
+2007-06-03  Srinivasa Ragavan  <sragavan novell com>
+
+	** Fix for bug #386503 from Matthew Barnes
+	
+	* exchange-send-options.c: (exchange_send_options_cb):
+
+2007-05-25  Matthew Barnes  <mbarnes redhat com>
+
+	* exchange-config-listener.c (exchange_add_autocompletion_folders):
+	Don't assume the absolute URI is non-NULL (#427232).
+
+2007-05-11  Gilles Dartiguelongue  <dartigug esiee fr>
+
+	* exchange-folder.c: (org_gnome_exchange_folder_inbox_unsubscribe):
+	Fixes unhandled cases in switch, fixes part of bug #437584.
+
+2007-05-25  Veerapuram Varadhan  <vvaradhan novell com>
+
+	* Makefile.am: Distcheck fixes.
+	
+2007-04-10  Elizabeth Greene <nerdygirl_ellie yahoo com>
+
+	** Fixes #426481
+	* exchange-account-setup.c: Fix Typo Assitant
+
+2007-04-05  Matthew Barnes  <mbarnes redhat com>
+
+	* exchange-config-listener.c (class_init):
+	* exchange-delegates-user.c (class_init):
+	Use GLib marshallers wherever possible.
+
+2007-03-27  Matthew Barnes  <mbarnes redhat com>
+
+	* exchange-account-setup.c:
+	* exchange-calendar.c:
+	* exchange-config-listener.c:
+	* exchange-contacts.c:
+	Don't mix declarations and code (#405495).
+
+2007-03-20  Matthew Barnes  <mbarnes redhat com>
+
+	** Fixes part of bug #419524
+
+	* Include <glib/gi18n.h> instead of <libgnome/gnome-i18n.h>.
+
+2007-01-27  Nickolay V. Shmyrev  <nshmyrev yandex ru>
+
+	* exchange-account-setup.c:
+	(org_gnome_exchange_show_folder_size_factory):
+	* exchange-contacts.c: (e_exchange_contacts_pcontacts):
+	mark strings as translatable. See bug #399381 for details.
+
+2006-01-18  Raghavendran R <raghavguru7 gmail com>
+
+	* exchange-send-options.glade :Glade file for 
+	  exchange send options .
+	* org-gnome-exchange-operations.eplug.xml :Added a
+	  hook for implementing send options .
+	* exchange-mail-send-options.c :Contains code for invoking
+	  the dialog and processing the data received and destroying
+	  the dialog .
+	* exchange-send-options.[c,h] :Contains the GType for exchange
+	  send options dialog . 
+
+2006-12-18  Veerapuram Varadhan <vvaradhan novell com>
+
+	Fixes bnc #208395
+
+	* exchange-folder-permission.c:
+	(org_gnome_exchange_folder_permissions): Decode the derived path
+	using camel_url_decode_path(), as path may contain encoded
+	characters.
+	
+2006-12-04  Matthew Barnes  <mbarnes redhat com>
+
+	Fixes bug #357970
+
+	* exchange-config-listener.c: Don't call deprecated GLib / GDK
+	functions.
+
+2006-10-23  Priit Laes  <amd store20 com>
+
+	* org-gnome-default-source.eplug.xml: Fixed typo in plugin 
+	description. Fixes bug 363999.
+
+2006-08-07  Sushma Rai  <rsushma novell com>
+
+	* org-gnome-exchange-operations.error.xml: Corrected a spelling 
+	mistake in the error message. Fixes #350231.
+
+2006-07-24  Sushma Rai  <rsushma novell com>
+
+	* exchange-folder-subscription.c (subscribe_to_folder): Handling the 
+	errors EXCHANGE_ACCOUNT_FOLDER_GC_NOTREACHABLE and 
+	EXCHANGE_ACCOUNT_FOLDER_NO_SUCH_USER.
+
+	* org-gnome-exchange-operations.error.xml: Added an error code 
+	folder-no-gc-error and corresponding error string. Fixes #234359. 
+
+2006-07-22  Sushma Rai  <rsushma novell com>
+
+	* exchange-folder-subscription.c (subscribe_to_folder): Checking if a 
+	user is subscribing to his own folder. Fixes #311322.
+	Patch submitted by "Vandana Shenoy .B  <shvandana novell com>"
+
+2006-07-18  Andre Klapper  <a9016009 gmx de>
+
+	* exchange-change-password.glade:
+	remove "*" from translation. Fixes bug #331147.
+
+2006-07-13  Andre Klapper  <a9016009 gmx de>
+
+	* exchange-permissions-dialog.glade: remove empty strings from 
+	translation
+
+2006-07-07  Hiroyuki Ikezoe  <poincare ikezoe net>
+
+	** Fixes bug #341369
+	* exchange-calendar.c:
+	* exchange-contacts.c: fixing a memory leak.
+
+2006-06-15  Sushma Rai  <rsushma novell com>
+
+	* Makefile.am: Added exchange-oof.glade to the list of glade files.
+
+	* exchange-config-listener.c (exchange_config_listener_authenticate):
+	On successful connection, checking if the OOF state is set in the 
+	server, and if it is set, asking the user if he wants to change it
+	to in-office during login. Fixes #344650.
+
+2006-06-13  Sushma Rai  <rsushma novell com>
+
+	* org-gnome-exchange-operations.error.xml: defined a new error code and
+	error string, for displaying in offline state.
+	
+	* exchange-folder.c (org_gnome_exchange_folder_ab_unsubscribe): Display
+	proper error in offline mode.
+	(org_gnome_exchange_folder_unsubscribe): Similar.
+	(org_gnome_exchange_folder_subscription): Similar. 
+	Fixes #344270.
+
+2006-06-07  Sushma Rai  <rsushma novell com>
+
+	* exchange-folder-subscription.c (create_folder_subscription_dialog): 
+	Disabling the OK button and added a callback to change the sensitivity.
+	(user_name_entry_changed_callback): Call-back to enable OK button, on
+	entering username. Fixes #317025.
+
+2006-05-11  Sankar P  <psankar novell com>
+
+	* exchange-account-setup.c: (btn_chpass_clicked):
+	Do not print the password in the terminal.
+	
+2006-05-10  Sushma Rai  <rsushma novell com>
+	
+	* exchange-config-listener.c (account_changed): Using the HIGified
+	notification message. 
+
+	* org-gnome-exchange-operations.error.xml: Similar,
+	Fixes #302825.
+
+2006-05-10  Sushma Rai  <rsushma novell com>
+
+	* exchange-account-setup.c (owa_authenticate_user): Display error
+	message only in case of authentication failure and not on cancelling
+	authentication operation. Fixes #332131
+
+2006-04-19  Sushma Rai  <rsushma novell com>
+
+	* exchange-contacts.c (e_exchange_contacts_commit): Setting the
+	e-source properties on both successful creation and rename of a folder.
+	
+	* exchange-calendar.c (e_exchange_calendar_commit): Similar.
+	Fixes #338876 and #328578.
+
+2006-04-19  Sushma Rai  <rsushma novell com>
+
+	* exchange-account-setup.c (owa_authenticate_user): Changed the 
+	function signature. Fixes #329371.
+
+2006-04-17  Sushma Rai  <rsushma novell com>
+
+	* exchange-contacts.c (e_exchange_contacts_check): Return TRUE in case
+	of non-exchange accounts.
+
+	* exchange-calendar.c (e_exchange_calendar_check): Similar. 
+	Fixes #338198.
+
+2006-04-10  Sushma Rai  <rsushma novell com>
+
+	* exchange-operations.[ch] (is_exchange_personal_folder): Added new to
+	check if a folder is a personal folder or not.
+
+	* exchange-contacts.c (e_exchange_contacts_pcontacts): Printing the
+	folder size only for the personal folders, in properties window.
+	(e_exchange_contacts_check): Returning FALSE in case of rename of
+	non-personal folders.
+	(e_exchange_contacts_commit): Renaming only the personal folders.
+
+	* exchange-calendar.c (e_exchange_calendar_pcalendar)
+	(e_exchange_calendar_check)(e_exchange_calendar_commit): Similar.
+	Fixes #328813 and #315522.
+
+2006-04-06  Sushma Rai  <rsushma novell com>
+
+	* exchange-operations.c (exchange_operations_update_child_esources):
+	Checking for ruri NULL.
+
+	* exchange-folder.c (org_gnome_exchange_check_address_book_subscribed):
+	Freeing uri.
+
+	* exchange-contacts.c (e_exchange_contacts_get_contacts): Defined as 
+	static. 
+	(e_exchange_contacts_pcontacts): Setting contacts_src_exists for GAL 
+	folder. 
+	(e_exchange_contacts_check): Checking for new folder creation and also 
+	not allowing rename of GAL and Contacts folders.
+	(e_exchange_contacts_commit): Corrected the way relative URI was being
+	constructed during rename operation. Handling the return value of the
+	rename operation.
+
+	* exchange-calendar.c (e_exchange_calendar_get_calendars): Defined as a
+	static function.
+	(e_exchange_calendar_check): Not allowing the rename of standard 
+	calendar and tasks folders.
+	(e_exchange_calendar_commit): Corrected the way relative URI was being
+	formed during rename operation. Also, handling the return value of the
+	rename folder operation.
+	Fixes #310433.
+
+2006-03-06  Sushma Rai  <rsushma novell com>
+
+	* exchange-config-listener.c 
+	(exchange_config_listener_get_offline_status): Freeing GConfValue.
+	See #329251.
+
+2006-03-06  Sushma Rai  <rsushma novell com>
+
+	* exchange-config-listener.c (account_removed): Not unrefing the 
+	account passed to the signal handler. Fixes #332129.
+
+2006-02-27  Sushma Rai  <rsushma novell com>
+
+	* exchange-calendar.c (e_exchange_calendar_pcalendar): fixed a typo.
+
+2006-02-27  Sushma Rai  <rsushma novell com>
+
+	* exchange-contacts.c (e_exchange_contacts_pcontacts): Check for NULL
+	account.
+
+	* exchange-calendar.c (e_exchange_calendar_pcalendar): Similar.
+	Fixes #332185.
+
+2006-02-27  Sushma Rai  <rsushma novell com>
+
+	* exchange-folder-permission.c 
+	(org_gnome_exchange_calendar_permissions): Trying to get the exchange
+	account only if one tries to see the folder permissions for the 
+	exchange account. Also, not showing the folder permissions dialog if 
+	the account is in offline mode.
+	(org_gnome_exchange_addressbook_permissions): Similar.
+	(org_gnome_exchange_folder_permissions): similar.
+	(org_gnome_exchange_menu_folder_permissions): Similar.
+	(org_gnome_exchange_menu_cal_permissions): Similar.
+	(org_gnome_exchange_menu_tasks_permissions): Similar.
+	(org_gnome_exchange_menu_ab_permissions): Similar.
+	See #332514.
+
+2006-02-27  Sushma Rai  <rsushma novell com>
+
+	* exchange-config-listener.c (add_defaults_for_account): Not trying to
+	set autocompletion folders here, which is done somewhere else.
+	(account_added): Invoking add_defaults_for_account() always on 
+	"connected" signal, not only if the account is marked as default 
+	folder, as we need to set them even if the account is not an default
+	account.
+	(set_special_mail_folder): Fomring the URIs for sent items and drafts 
+	folders, by removing the ";" from the physical URIs.
+	Fixes #324693, #324694.
+
+2006-02-25  Sushma Rai  <rsushma novell com>
+
+	* exchange-contacts.c (e_exchange_contacts_get_contacts): Freeing 
+	folder array.
+
+	* exchange-calendar.c (e_exchange_calendar_get_calendars): Similar.
+	See #329251.
+
+2006-02-18  Irene Huang <Irene Huang sun com>
+
+	Fixes bug #331635
+
+	* exchange-account-setup.c: (org_gnome_exchange_settings):
+	Add NULL as the last parameter in g_object_new to mark the
+	the end of parameter list.
+
+2006-02-10  Sushma Rai  <rsushma novell com>
+
+	* exchange-contacts.c (e_exchange_contacts_pcontacts): Checking if the
+	folder selected is GAL folder and in case of GAL folder, returning
+	after checking for offline status.
+	(e_exchange_contacts_check): Handling GAL folder also.
+	Fixes #329623 #328571 and #329624
+
+2006-02-10  Sushma Rai  <rsushma novell com>
+
+	* exchange-contacts.c (e_exchange_contacts_commit): Freeing uri_text.
+	See #329251.
+
+2006-02-06  Sushma Rai  <rsushma novell com>
+
+	* exchange-permissions-dialog.c (exchange_permissions_dialog_new): 
+	Initializing nresults to zero and freeing E2kResult.
+
+	* exchange-calendar.c (e_exchange_calendar_commit): Freeing authtype.
+
+	* exchange-contacts.c (e_exchange_contacts_commit): Similar.
+	See #329251.
+
+2006-02-05  Karsten Bräckelmann  <guenther rudersport de>
+
+	* exchange-user-dialog.c (e2k_user_dialog_construct): 
+	Correcting "Addressbook" to properly read "Address Book".
+	Fixes bug #326256.
+
+2006-02-03  Sushma Rai  <rsushma novell com>
+
+	* exchange-permissions-dialog.c (exchange_permissions_dialog_new): 
+	Freeing E2kResult.
+
+	* exchange-calendar.c (e_exchange_calendar_commit): Freeing authtype.
+
+	* exchange-contacts.c (e_exchange_contacts_commit): similar. 
+	See #329251.
+
+2006-02-03  Sushma Rai  <rsushma novell com>
+
+	* exchange-folder.c (org_gnome_exchange_folder_subscription): Moved
+	discovering the shared folder, opening that folder and error handling
+	out to create_folder_subscription_dialog().
+	
+	* exchange-folder-subscription.c (create_folder_subscription_dialog):
+	Pass all the data to subscirbe_to_folder() callback. 
+	(subscribe_to_folder): On pressing OK, extracting the dtails like user's
+	email id, folder name, finding the shared folder and opening that 
+	folder. 
+	(destroy_subscription_info): Cleanup function.
+	Fixes #328554.
+
+2006-01-27  Sushma Rai  <rsushma novell com>
+
+	* exchange-calendar.c (e_exchange_calendar_commit): Freeing uri_text 
+	in case of OFFLINE mode.
+	Instead of terminating memory allocated string tmpruri and using it,
+	forming the URI string from the EUri and appending the path.
+
+	* exchange-contacts.c (e_exchange_contacts_commit): Similar.
+	Fixes #328304.
+
+2006-01-24  Sushma Rai  <rsushma novell com>
+
+	* exchange-config-listener.c (exchange_config_listener_authenticate):
+	Not using e_error_run(), to avoid modal error dialogs. Fixes #328385.
+
+	* exchange-operations.c (exchange_operations_report_error): Similar.
+	Also displaying the current quota usage instead of the quota limit.
+
+2006-01-23  Sushma Rai  <rsushma novell com>
+
+	* exchange-operations.c 
+	(exchange_operations_cta_select_node_from_tree): Checking for the NULL
+	URI, Fixes #328282.
+
+2006-01-23  Sushma Rai  <rsushma novell com>
+
+	* exchange-account-setup.c (camel_exchange_ntlm): Setting the authproto
+	value to NTLM, which is used later. 
+	(org_gnome_exchange_auth_section): Reading the auth type from 
+	ExchangeAccount and setting it in URL if the url doesn't contain the
+	auth mechanism value. Since the auth mechanism is not set using the 
+	authentication type tab in druid during account setup, when the editor
+	is invoked, it doesn't get set in the account URI. Fixes #327284.
+
+2006-01-19  Andre Klapper <a9016009 gmx de>
+
+	* org-gnome-exchange-operations.error.xml:
+	changed "mails" to "mail" or "messages", removed duplicated
+	whitespaces. Fixes bug 325569.
+
+2006-01-18  Sushma Rai  <rsushma novell com>
+
+	* exchange-contacts.c (e_exchange_contacts_pcontacts): Displaying the
+	offline message for both Exchange personal and GAL folders. 
+	Fixes #327483.
+
+2006-01-16  Harish Krishnaswamy  <kharish novell com>
+
+	* org-gnome-exchange-operations.error.xml:
+	Fixed a minor typo in error string. (#327053).
+
+2006-01-16  Harish Krishnaswamy  <kharish novell com>
+
+	* exchange-config-listener.c: (display_passwd_expiry_message):
+	Fix a grammar error in translatable string. (#327155)
+
+2006-01-13  Sushma Rai  <rsushma novell com>
+
+	* exchange-config-listener.c (exchange_config_listener_authenticate):
+	Set the "save-passwd" parameter value EAccount. Fixes #326842.
+
+2006-01-13  Sushma Rai  <rsushma novell com>
+
+	* exchange-config-listener.c: Added krb5 checks while invoking
+	change_passwd_cb() and exchange_config_listener_authenticate().
+
+2006-01-11  Chenthill Palanisamy  <pchenthill novell com>
+
+	Fixes #271546
+	* exchange-folder.c: (org_gnome_exchange_calendar_subscription),
+	(org_gnome_exchange_addressbook_subscription),
+	(org_gnome_exchange_tasks_subscription),
+	(org_gnome_exchange_inbox_subscription): Mark the string for completion.
+
+2006-01-12  Sushma Rai  <rsushma novell com>
+
+	* exchange-config-listener.c (exchange_config_listener_authenticate): 
+	Checking for the password expired error code during connect and if the
+	password is expired, showing the error message, prompting for resetting
+	the password and trying to connect again with the new password.
+	Checking  if the password will expire in next a few days, which is 
+	specified by the user during account creation, and if yes, showing
+	the corresponding error message to the user, which allows him to change
+	his password. 
+	Fixes #326060.
+	Also, Checking for the quota related error codes and displaying the
+	corresponding error/warning messages to the user. Fixes #326087.
+
+	* org-gnome-exchange-operations.error.xml: Added a space.
+
+	* exchange-passwd-expiry.glade: Added new.
+
+	* Makefile.am: Added exchange-passwd-expiry.glade.
+
+2006-01-11  Srinivasa Ragavan  <sragavan novell com>
+
+	** Fixes bug #316100
+	
+	* org-gnome-exchange-ab-subscription.xml:
+	* org-gnome-exchange-tasks-subscription.xml:
+	* org-gnome-folder-permissions.xml:
+	* org-gnome-folder-subscription.xml:
+	Removed empty menu entry which was pointing to Tools menu.
+
+2006-01-09  Sushma Rai  <rsushma novell com>
+
+	* exchange-folder-subscription.c (create_folder_subscription_dialog):
+	Instead of gtk_dialog_run(), calling gtk_widget_show().
+	(dialog_destroy): Added callback to do the cleanup on closing the 
+	window. Fixes #314748. 
+
+2006-01-06  Simon Zheng <simon zheng sun com>
+
+	* exchange-account-setup.c:
+	* exchange-calendar.c:
+	* exchange-config-listener.h:
+	* exchange-contacts.c:
+	use libedataserver/e-account-list.h instead of e-util/e-account-list.h.
+	use libedataserver/e-account.h instead of e-util/e-account.h.
+
+2006-01-05  Sushma Rai  <rsushma novell com>
+
+	* exchange-calendar.c (e_exchange_calendar_commit): Setting the
+	username, authtype, auth-domain and auth properties on the esource
+	created, so that corresponding folder will be authenticated and loaded
+	after the folder creation. Also fixed memory leak in case of no any 
+	changes condition.
+
+	* exchange-config-listener.c (remove_selected_non_offline_esources):
+	Not freeing the non allocated string offline_mode.
+
+2006-01-02  Sushma Rai  <rsushma novell com>
+
+	* exchange-folder-permission.c (org_gnome_exchange_folder_permissions):
+	Proceed only with the exchange account folders.
+	
+	* exchange-folder.c (org_gnome_exchange_check_inbox_subscribe): 
+	Similar. Fixes #325491.
+
+2005-12-30  Andre Klapper <a9016009 gmx de>
+
+	* evolution/plugins/exchange-operations/org-gnome-exchange-operations.error.xml:
+ 	 Fixing several typos and harmonizing
+	 capital/small letters. Partially fixes bug 306117.
+
+2005-12-30  Andre Klapper <a9016009 gmx de>
+
+	* evolution/plugins/exchange-operations/exchange-account-setup.c:
+	  harmonized "URL", "Url" and "url". Fixes bug 325125.
+
+2005-12-25  Funda Wang  <fundawang linux net cn>
+
+	* Makefile.am: Mark this plugin as translatable (bug#301149).
+
+2005-12-21  Sushma Rai  <rsushma novell com>
+
+	* exchange-contacts.c (e_exchange_contacts_commit): Setting the 
+	username, authtype, auth-domain and auth properties on the esource
+	created, so that corresponding folder will be authenticated and loaded
+	after the folder creation. Fixes #324678. 
+	Also fixed memory leak in case of no any changes condition.
+
+2005-12-20  Sushma Rai  <rsushma novell com>
+
+	* exchange-folder-subscription.c (create_folder_subscription_dialog): 
+	Setting the correct title. Fixes #324580.
+
+2005-12-19  Sushma Rai  <rsushma novell com>
+
+	* exchange-delegates-user.c (exchange_delegates_user_edit): Using the
+	window title as "Delegates Permissions". Label "Permissions for <user>"
+	was repeated twice.
+
+	* exchange-delegates.glade: Added translator comments. Fixes #313545.
+
+2005-12-19  Sushma Rai  <rsushma novell com>
+
+	* exchange-account-setup.c (owa_authenticate_user): Adding the 
+	parameter "save-passwd" to CamelURL, during account creation, which can
+	be used to see if the user has remembered password or password is
+	temporarily remembered so that password is not prompted second time at
+	the end of account creation.
+	
+	* exchange-config-listener.c (exchange_config_listener_authenticate): 
+	Using the flag E_PASSWORDS_REMEMBER_FOREVER instead of 
+	E_PASSWORDS_REMEMBER_SESSION. Reading the save-passwd URL parameter to
+	see if the password was remembered by the user or remembered 
+	temporarily by the plugin and foget it in case of remembered by the
+	plugin. Also free CamelURL.
+	(account_added): Calling exchange_config_listener_authenticate().
+	
+	Fixes #324485
+
+2005-12-19  Sushma Rai  <rsushma novell com>
+
+	* exchange-account-setup.c (org_gnome_exchange_settings)
+	(owa_editor_entry_changed)(org_gnome_exchange_owa_url)
+	(org_gnome_exchange_commit): free CamelURL.
+	(owa_authenticate_user): free CamelURL and exchange_params.
+	Fixes #324483.
+
+2005-12-19  Sushma Rai  <rsushma novell com>
+
+	* exchange-folder-permission.c: Corrected include path of header files
+	which was breaking the build.
+	
+	* exchange-change-password.[ch]: Similar.
+
+	* exchange-folder-subscription.c: Similar.
+
+2005-12-12  Sushma Rai  <rsushma novell com>
+
+	* exchange-account-setup.c (print_error): Passing the support URL to
+	e_error_run(), so that hardcoded URL won't be marked for translation.
+	See #272514.
+	* org-gnome-exchange-operations.error.xml: Uisng the correct error code
+	"connect-exchange-error". Changed the primary message to more 
+	appropriate one. Also removed hard coded URL.
+
+2005-12-12  Harish Krishnaswamy  <kharish novell com>
+
+	* Makefile.am: Add primary CLEANFILES,
+	fix BUILT_SOURCES, make-clean issues.
+
+2005-12-07  Funda Wang  <fundawang linux net cn>
+
+	* org-gnome-exchange-operations.eplug.in: i18nlized.
+
+2005-11-24  Sushma Rai  <rsushma novell com>
+
+	* exchange-account-setup.c (org_gnome_exchange_settings): Initialize
+	OOF state and check for the OOF state and message only of the account
+	is valid. Fixes the problem of printing OOF error message in case
+	of authentication failure.
+	(set_oof_info): Similar.
+	Fixes #314583, #315331.
+
+2005-10-03  Shakti Sen <shprasad novell com>
+
+	* exchange-folder-permission.c (org_gnome_exchange_folder_permissions),
+	(org_gnome_exchange_menu_folder_permission): Constructing the path
+	properly to get the efolder.
+	* exchange-folder.c (org_gnome_exchange_folder_inbox_unsubscribe),
+	(exchange_get_folder), (org_gnome_exchange_check_inbox_subscribed),
+	(unsubscribe_dialog_ab_response), (unsubscribe_dialog_response): 
+	Creating proper path.
+	
+	The above modifications will now allow the user to do the operations
+	like unsubscribed to Inbox and giving permission to a folder.
+		-
+
+2005-09-30  Shakti Sen <shprasad novell com>
+
+	* exchange-folder-subscription.c (setup_folder_name_combo): Sets the
+	corresponding 'Folder name'.
+	(create_folder_subscription_dialog): Sets the cursor to User's entry
+	text field.
+	* exchange-folder-subscription.h: Added one more argument to function
+	create_folder_subscription_dialog() to set the window title.
+	* exchange-folder.c (org_gnome_exchange_inbox_subscription),
+	(org_gnome_exchange_addressbook_subscription),
+	(org_gnome_exchange_calendar_subscription),
+	(org_gnome_exchange_tasks_subscription): Added newly.
+	* org-gnome-exchange-operations.eplug.in: Changed the activate callback
+	function names so that it can show appropriate window title.
+
+	Fixes bug #317019, #317023.
+	
+2005-09-28  Sarfraaz Ahmed <asarfraaz novell com>
+
+	* exchange-account-setup.c (owa_authenticate_user) : Propogate the
+	authentication mechanism to the backend.
+	* exchange-calendar.c
+	* exchange-contacts.c
+	* exchange-folder.c : Parse the new account uri.
+
+2005-09-28  Tor Lillqvist  <tml novell com>
+
+	* Makefile.am (INCLUDES, LIBADD): Use just CAMEL_EXCHANGE_CFLAGS
+	and _LIBS, they now includes all necessary (see top-level
+	ChangeLog).
+	(LDFLAGS): Use NO_UNDEFINED.
+
+	* org-gnome-exchange-operations.eplug.in: Use SOEXT.
+
+2005-09-22  Praveen Kumar  <kpraveen novell com>
+
+	** Fixes bug 312849
+
+	* exchange-calendar.c
+	(e_exchange_calendar_pcalendar): Populate the folder hierarchy only 
+	if Evolution is online.
+	(e_exchange_calendar_check): Disable the "OK" button if Evolution 
+	is offline.
+	(e_exchange_calendar_commit): Don't do anything if Evolution is 
+	offline.
+
+	* exchange-contacts.c
+	(e_exchange_contacts_pcontacts): Populate the folder hierarchy only 
+	if Evolution is online.
+	(e_exchange_contacts_check): Disable the "OK" button if Evolution 
+	is offline.
+	(e_exchange_contacts_commit): Don't do anything if Evolution is 
+	offline.
+
+2005-09-15  Arunprakash  <arunp novell com>
+
+	* exchange-account-setup.c
+	(org_gnome_exchange_show_folder_size_factory) : Now checks for the
+	camel provider type, and does nothing for non exchange providers.
+	** Fixes #312886.
+
+2005-09-14  Irene Huang <Irene Huang sun com>
+
+	Fix for #316274
+
+	* exchange-account-setup.c: (btn_chpass_clicked),
+	(org_gnome_exchange_settings): Enable change password function only 
+	when built with kerberos5.  
+
+2005-08-29  Praveen Kumar  <kpraveen novell com>
+
+	** Fixes bug 314762
+	
+	* exchange-config-listener.c (remove_selected_non_offline_esources) :
+	Fixing a nasty infinite loop by swapping an if and while block.
+	
+2005-08-26  Shakti Sen <shprasad novell com>
+
+	* exchange-folder.c (org_gnome_exchange_folder_unsubscribe): Fixes the
+	'Label disappears' problem in Tasks, Calendar and Contacts.
+
+	Fixes bug #311959.
+
+2005-08-25  Arunprakash  <arunp novell com>
+
+	* exchange-config-listener.c (account_added) : Need to set the
+	account's linestatus to online as there is no way to get the
+	linestatus in plugin. Also moved the authentication code to
+	exchange_operations_get_exchange_account as it is not needed here.
+	* exchange-operations.c (exchange_operations_get_exchange_account) :
+	Updated to return the account in offline mode.
+
+2005-08-25  Shakti Sen  <shprasad novell com>
+
+	* exchange-folder.c (exchange_refresh_folder_tree, exchange_get_folder,
+	org_gnome_exchange_folder_inbox_unsubscribe): Added support for
+	Unsubscribe to other user's Inbox.
+
+	Fixes bug #313310.
+
+2005-08-24  Shakti Sen <shprasad novell com>
+
+	* exchange-permissions-dialog.c (add_clicked): Getting list of mail-ids
+	instead of a single mail-id.
+	* exchange-user-dialog.[c/h] (e2k_user_dialog_get_user_list): Added
+	support for adding multiple IDs.
+
+	Fixes bug #313919.
+
+2005-08-24  Praveen Kumar  <kpraveen novell com>
+
+	* plugins/exchange-operations/exchange-account-setup.c:
+	* plugins/exchange-operations/exchange-calendar.c:
+	* plugins/exchange-operations/exchange-config-listener.c:
+	* plugins/exchange-operations/exchange-contacts.c:
+	* plugins/exchange-operations/exchange-delegates-user.c:
+	* plugins/exchange-operations/exchange-folder-size-display.c:
+	* plugins/exchange-operations/exchange-folder.c:
+	* plugins/exchange-operations/exchange-operations.c:
+	Removed the warning that are generated when compiled with GCC 4.
+
+	* plugins/exchange-operations/exchange-calendar.c:
+	Fixed a build break due to the modification of the 'source_type'
+	field in the ECalConfigTargetSource class.
+
+2005-08-22  Sarfraaz Ahmed <asarfraaz novell com>
+
+	* exchange-account-setup.c (btn_fsize_clicked)
+	(set_oof_info) : Use exchange_operations_get_exchange_account.
+	* exchange-config-listener.c (exchange_config_listener_authenticate) :
+	Fetch the password and connect. Added new
+	* exchange-config-listener.h : Similar.
+	* exchange-operations.c (exchange_operations_get_exchange_account) :
+	Try authenticating if account is not found.
+
+2005-09-12  Praveen Kumar  <kpraveen novell com>
+
+	* exchange-config-listener.c
+	(remove_selected_non_offline_esources): Added new
+	(add_account_esources): Don't add the calendars and tasks in the 
+	selected list
+	(account_added): If starting in offline mode remove the non-offline
+	calendars and tasks from the selected list so that it doesn't
+	throws an error
+
+	Fixes the bug 273272.
+	
+2005-08-11  Praveen Kumar  <kpraveen novell com>
+
+	* exchange-config-listener.c
+	(exchange_camel_urls_is_equal): Added new
+	(exchange_config_listener_modify_esource_group_name): Added new
+	(account_changed): Handle most of the account parameter changes
+	without restart. This fixes bug 272784 and partially bug 220168
+	(account_removed): Removed the message dialog that says that the
+	changes will be reflected after restart. This partially fixes the
+	bug 220168
+	
+2005-08-08  Arunprakash <arunp novell com>
+
+	* exchange-folder-size-display.c: Included glib/gi18n.h file for
+	translation. 
+	* exchange-operations.c: Same.
+
+2005-08-05  Arunprakash <arunp novell com>
+
+	* exchange-folder-size-display.c (exchange_folder_size_display) :
+	Marked strings for translation that were left out.
+	* exchange-operations.c (exchange_operations_cta_add_node_to_tree)
+	(exchange_operations_cta_select_node_from) : Same.
+	
+2005-08-03  Shakti Sen <shprasad blr novell com>
+
+	* exchange-folder.c (org_gnome_exchange_folder_ab_unsubscribe)
+	(org_gnome_exchange_folder_unsubscribe)
+	(org_gnome_exchange_folder_subscription): Added offline/online support
+	and removed some warning messages.
+	* exchange-operations.c: Added a new function exchange_is_offline().
+	* exchange-operations.h: Included a prototype.
+	* exchange-config-listener.c
+	(exchange_config_listener_get_offline_status): Added newly to get the
+	online/offline status.
+	* exchange-config-listener.h: Added the prototype for
+	exchange_config_listener_get_offline_status().
+
+	Fixes bug #311324.
+
+2005-08-03  Sarfraaz Ahmed <asarfraaz novell com>
+
+	* exchange-folder.c : Fixed a build break. A typo.
+
+2005-08-02  Shakti Sen <shprasad blr novell com>
+
+	* Makefile.am: Included 'calendar' in INCLUDES and some .la in
+	'liborg_gnome_exchange_operations_la_LIBADD'
+	* exchange-folder-permission.c: Added the functionality for
+	'File->Permissions' menu-item for Calendar, Tasks and Contacts.
+	* exchange-permissions-dialog.c (exchange_permissions_dialog_new):
+	Takes care of 'folder' is not-null.
+
+	Fixes bug #231968.
+	
+2005-08-02  Sarfraaz Ahmed <asarfraaz novell com>
+
+	* exchange-calendar.c : Check for NULL target
+	* exchange-contacts.c : Similar
+	* exchange-folder-permission.c : Similar
+	* exchange-folder.c : Similar
+
+2005-08-01  Praveen Kumar  <kpraveen novell com>
+
+	* exchnage-config-listener.c 
+	(exchange_add_autocompletion_folders) : Added new
+	(add_defaults_for_account) : Added a call to the newly added function
+	to select GAL for autocompletion by default. Fixes bug 303998
+	
+2005-07-27  Praveen Kumar <kpraveen novell com>
+
+	* exchange-folder.c (org_gnome_exchange_folder_subscription) : Handle
+	error conditions if folder subscription fails. Fixes bug 311712
+	
+2005-07-27  Harry Lu  <harry lu sun com>
+
+	Only show the unsubscribe menu if it is an exchange folder.
+	* exchange-folder.c:
+	(org_gnome_exchange_check_address_book_subscribed),
+	(org_gnome_exchange_check_subscribed):
+
+2005-07-25  Shakti Sen <shprasad novell com>
+
+	* org-gnome-exchange-operations.eplug.in: Fixed a small typo.
+	The file name is org-gnome-exchange-tasks-subscription.xml, not
+	org-gnome-exchange-task-subscription.xml.
+
+2005-07-25  Sarfraaz Ahmed <asarfraaz novell com>
+
+	* exchange-calendar.c (e_exchange_calendar_pcalendar) : Add the size
+	label only if the calendar exists.
+	* exchange-contacts.c (e_exchange_contacts_pcontacts) : Add the size
+	label only if the addressbook exists.
+
+2005-07-25  Shakti Sen <shprasad novell com>
+
+	* Makefile.am: Added EVOLUTION_CALENDAR_CFLAGS and widgets in 'INCLUDES'.
+	* org-gnome-exchange-operations.eplug.in: Added the hooks for Calendar,
+	Tasks and Contacts.
+	* exchange-folder-permission.c: Added new functions to support 
+	'File->Permissions' for all the components.
+	* org-gnome-folder-permissions.xml: Changed the placeholder from 'Folder'
+	to 'File' menu for 'Permissions' menu-item.
+	
+	Fixes bug #231968 (Partly).
+
+2005-07-25  Sarfraaz Ahmed <asarfraaz novell com>
+
+	* exchange-account-setup.c 
+	(org_gnome_exchange_show_folder_size_factory): Takes care of displaying
+	the folder size for mail folders.
+	* exchange-calendar.c (e_exchange_calendar_pcalendar): Now also adds
+	the calendar size in the properties page
+	* exchange-contacts.c (e_exchange_contacts_pcontacts): Now also adds 
+	the addressbook size in the properties page.
+	* exchange-folder-size-display.c (exchange_folder_size_get_val) : Fetch
+	the folder size of a particular exchange folder.
+	* exchange-folder-size-display.h : Similar
+	* org-gnome-exchange-operations.eplug.in : Added the hook for the mail
+	properties page.
+
+2005-07-25  Arunprakash <arunp novell com>
+
+	* exchange-delegates.c (get_folder_security) (add_button_clicked_cb)
+	(delegates_apply) : Changed the e_notice calls to e_error_run calls.
+	* exchange-folder-permission.c (create_folder_subscription_dialog) :
+	Same.
+	* exchange-calendar.c (e_exchange_calendar_commit) : Same.
+	* exchange-contacts.c (e_exchange_contacts_commit) : Same.
+	* exchange-folder-subscription.c (create_folder_subscription_dialog) :
+	 Same
+	* exchange-permissions-dialog.c (exchange_permissions_dialog_new)
+	(dialog_response) (add_clicked): Same.
+	* exchange-operations.c (exchange_operations_report_error) : Modified
+	to report the quota value to the user.
+	* org-gnome-exchange-operations.error.xml : Added few more
+	error descriptions needed for the above changes.
+
+2005-07-25  Shakti Sen <shprasad novell com>
+
+	* exchange-permissions-dialog.c (add_clicked): Creating the dialog
+	and getting the user.
+
+	Fixes bug #311096.
+
+2005-07-20  Shakti Sen <shprasad novell com>
+
+	* Makefile.am: Included files org-gnome-exchange-ab-subscription.xml,
+	org-gnome-exchange-tasks-subscription.xml and
+	org-gnome-exchange-cal-subscription.xml.
+	* org-gnome-exchange-ab-subscription.xml: Added newly to add
+	"Subscribe to Other User's Contacts' menu-item in 'File' menu for
+	address book.
+	* org-gnome-exchange-tasks-subscription.xml: Same for 'Tasks'.
+	* org-gnome-exchange-cal-subscription.xml: Same for 'Calendar'.
+
+	Fixes bug #310985.
+
+2005-07-22  Praveen Kumar <kpraveen novell com>
+
+	* exchange-calendar.c : Handling the rename of calendars. This
+	addresses the bug 310433
+	* exchange-config-listener.c : Removed the functions
+	add_folder_esource and remove_folder_esource
+	* exchange-contacts.c : Handling the rename of addressbooks. Also 
+	modified the way of Exchange addressbook ESource URI handling to be 
+	the same way as calendar ESource URI handling
+	* exchange-operations.c (exchange_operations_update_child_esources) :
+	Added new to handle the rename of the ESources of all child folders 
+	in the case of parent folder being renamed.
+	* exchange-operations.h : Added prototype for the new function
+	
+2005-07-21  Sarfraaz Ahmed <asarfraaz novell com>
+
+	* exchange-calendar.c (e_exchange_calendar_get_calendars): Rescan the
+	tree before fetching the folder list.
+	* exchange-contacts.c (e_exchange_contacts_get_contacts): Similar
+	* exchange-config-listener.c (account_added): Dont add the sources here
+	now. Its now taken care while the folders are being created in e-d-s.
+	* exchange-folder.c (org_gnome_exchange_folder_subscription): Dont add
+	the esources here.
+
+2005-07-19  Shakti Sen <shprasad novell com>
+
+	* exchange-permissions-dialog.c (display_role, get_widgets):
+	Added a label named 'Custom' to show appropriate role in the 'Role:'
+	combo box.
+
+	Fixes bug#310837
+
+2005-07-18  Sarfraaz Ahmed <asarfraaz novell com>
+
+	* exchange-folder-size-display.c (parent_destroyed) : This is no longer
+	needed. gtk_widget_destroy will take care of destroying it. 
+	Fixes #310699
+	* exchange-account-setup.c (org_gnome_exchange_settings) : Fixed a 
+	warning. Alignment cannot be set for a radio button
+
+2005-07-15  Shakti Sen <shprasad novell com>
+
+	* exchange-folder-permission.c: Added the functions 
+	org_gnome_exchange_calendar_permissions() and
+	org_gnome_exchange_addressbook_permissions() to support 
+	'Folder Permissions' for 'Calendar', 'Tasks' and 'Contacts' components.
+	Also taken care of a bug #310493.
+	* org-gnome-exchange-operations.eplug.in: Added the class hooks.
+
+	Fixes bug#310479.
+	Fixes bug#310493 as well.
+
+2005-07-18  Praveen Kumar <kpraveen novell com>
+
+	* exchange-account-setup.c (btn_chpass_clicked) : Handle the case
+	of user clicking "Cancel" button in "Change Password" dialog. Fixes
+	bug 310356.
+	(org_gnome_exchange_setting) : Removed the duplicate signal handler
+	registered for "Change Password" button.
+	
+2005-07-16  Sarfraaz Ahmed <asarfraaz novell com>
+
+	* exchange-ask-password.c : Removed. Is no longer being used
+
+2005-07-15  Shakti Sen <shprasad novell com>
+
+	* Makefile.am: Included the e-foreign-folder-dialog.glade file.
+	* e-foreign-folder-dialog.glade: Added newly.
+
+	Fixes bug #310369.
+
+2005-07-14  Sarfraaz Ahmed <asarfraaz novell com>
+
+	* exchange-account-setup.c :
+	* exchange-calendar.c :
+	* exchange-folder-size-display.c :
+	* exchange-permissions-dialog.c : Fixed some compile time warnings
+
+2005-07-13  Shakti Sen <shprasad novell com>
+
+	* exchange-operations.c: Checked for if the exchange account
+	exist/configured.
+	* exchange-folder-permission.c: Replaced all the occurences of function
+	exchange_config_listener_get_accounts() with
+	exchange_operations_get_exchange_account() and returns if it doesn't 
+	exist. Also took care to avoid some compile time warnings.
+	* exchange-folder.c: Same. Also took care to avoid some compile time
+	warnings.
+	* exchange-folder-subscription.c: Included 
+	exchange-folder-subscription.h file to avoid compilation warning.
+
+	Fixes bug #310233.
+
+2005-07-13  Praveen Kumar <kpraveen novell com>
+
+	* org-gnome-exchange-operations.eplug.in : Modified the eplug file to 
+	add the "commit" code for folder hierarchy plugins for calendar and 
+	contacts
+	
+2005-07-11  Sarfraaz Ahmed <asarfraaz novell com>
+
+	* exchange-operations.c (exchange_operations_report_error) : Check that
+	the result is not a success and only then print the error
+	* exchange-account-setup.c (btn_chpass_clicked) : Call the error 
+	reporting routine only if there is a failure.
+	* exchange-config-listener.c (account_added) : Similar
+
+2005-07-11  Sarfraaz Ahmed <asarfraaz novell com>
+
+	Patch submitted by ArunPrakash <arunp novell com>
+	* exchange-operations.c (exchange_operations_report_error) : Newly 
+	added, to report errors using e_error_run. Also a list of error-ids is 
+	added.
+	* exchange-config-listener.c (account_added) (account_removed) :
+	Modified the usage of e_notice to e_error_run. Also the error from
+	exchange_account_connect is reported using 
+	exchange_operations_report_error.
+	* exchange-account-setup.c (btn_chpass_clicked) 
+	(org_gnome_exchange_settings) (print_error) (set_oof_info): Changed to 
+	use exchange_operations_report_error and e_error_run functions.
+	* org-gnome-exchange-operations.error.xml : Newly added, defines
+	the list of error messages used in the plugin.
+	* Makefile.am : Modified for org-gnome-exchange-operations.error.xml
+
+2005-07-11  Shakti Sen <shprasad novell com>
+
+	* Makefile.am: Included files exchange-folder-subscription.c,
+	exchange-folder-subscription.h, exchange-folder.c and 
+	org-gnome-folder-subscription.xml 
+	* exchange-folder.c: Renamed all the function names starting with
+	org_gnome_* to org_gnome_exchnage* to resolve name space collision.
+	* org-gnome-exchange-operations.eplug.in: Added the hook class for
+	'Subscribe/Unsubscribe Folder'.
+
+2005-07-08  Praveen Kumar <kpraveen novell com>
+
+	* Makefile.am : Added entries for the files providing the delegation
+	assistant feature
+	* exchange-user-dialog.c : Added new 
+	* exchange-user-dialog.h : Added new
+	* exchange-account-setup.c (btn_dass_clicked) : Enabled the code for
+	for invoking the delegation assistant window
+	* exchange-delegates-user.c : Modified to include the header files 
+	from include path instead of the local directory
+	* exchange-permissions-dialog.c : Modified an occurence to include
+	the file exchange-user-dialog.c instead of e2k-folder-dialog.c
+
+2005-07-08  Shakti Sen <shprasad novell com>
+
+	* Makefile.am: Included files exchange-permissions-dialog.c,
+	  exchange-permissions-dialog.h, exchange-folder-permission.c,
+	  org-gnome-folder-permissions.xml & exchange-permissions-dialog.glade
+	* exchange-folder-permission.c: Renamed the function name 
+	  org_gnome_menu_folder_permissions to 
+	  org_gnome_exchnage_menu_folder_permissions
+	* org-gnome-exchange-operations.eplug.in: Added the hook class for 
+	  Folder Permissions.
+
+2005-07-08  Shakti Sen <shprasad novell com>
+
+	* exchange-folder-permission.c: Added new file for Folder Permissions.
+	* exchange-permissions-dialog.c: Added new file for Folder Permissions.
+	* exchange-permissions-dialog.h: Added new file for Folder Permissions.
+	* exchange-permissions-dialog.glade: Added newly for Folder Permissions 
+	  support.
+	* org-gnome-folder-permissions.xml: Added new file for Folder 
+	  Permissions support.
+	* exchange-folder-subscription.c: Added new file for Folder 
+	  Subscribe/Unsubcribe support.
+	* exchange-folder-subscription.h: Added new file for Folder 
+	  Subscribe/Unsubcribe support.
+	* exchange-folder.c: Added new file for Folder Subscribe/Unsubcribe
+	  support.
+	* org-gnome-folder-subscription.xml:  Added new file for Folder 
+	  Subscribe/Unsubcribe support.
+
+2005-07-07  Sarfraaz Ahmed <asarfraaz novell com>
+
+	* exchange-account-setup.c : Include exchange-folder-size-display.h
+	* exchange-folder-size-display.c : Similar
+
+2005-07-07  Sarfraaz Ahmed <asarfraaz novell com>
+
+	* exchange-account-setup.c (btn_fsize_clicked) : Implemented new to
+	invoke the folder size table.
+	(org_gnome_exchange_settings) : Minor re-ordering
+	* exchange-folder-size-display.c : Newly added to handle the UI code
+	for folder size display
+	* exchange-folder-size-display.h : Similar
+	* exchange-folder-size.[ch] : Removed
+	* Makefile.am : Include exchange-folder-size-display.[ch]
+
+2005-07-05  Sarfraaz Ahmed <asarfraaz novell com>
+
+	* exchange-config-listener.c (add_new_sources) : Newly added. This adds
+	the esources for all the folders only if the esource doesnt already
+	exist.
+	(account_added) : Invoke add_new_sources after connect.
+
+2005-07-01  Praveen Kumar <kpraveen novell com>
+
+	* Makefile.am : Added new file entries for calendar , contacts
+	  and change-password
+	* exchange-account-setup.c (btn_chpass_clicked) : enabled the code
+	* exchange-operations.c (exchange_operations_cta_add_node_to_tree) : 
+	  This now stores the relative uri of the node to the model
+	 (exchange_operations_cta_select_node_from_tree) : Added new. This 
+	 selects the node for a given relative uri.
+	* exchange-operations.h : Similar
+	* org-gnome-exchange-operations.eplug.in : Added commit hook action
+	  for calendar and contacts
+	* exchange-change-password.c : Added new
+	* exchange-calendar.c : Added new
+	* exchange-contacts.c : Added new
+
+2005-07-01  Sarfraaz Ahmed <asarfraaz novell com>
+
+	* exchange-account-setup.c(print_error) : Added new. This prints the
+	validation error string.
+	(owa_authenticate_user) : Fetch the error code from validate and handle
+	the printing of error strings in the plugin.
+	* exchange-config-listener.c (account_added) : For now add the sources 
+	before connect to avoid multiple esources. Should be fixed more 
+	elegantly.
+
+2005-06-27  Sarfraaz Ahmed <asarfraaz novell com>
+	
+	* Makefile.am : Added the header files as part of SOURCES so that they
+	get disted as well.
+
+2005-06-22  Sarfraaz Ahmed <asarfraaz novell com>
+
+	* exchange-account-setup.c : We no longer should be declaring the
+	global_config_listener as a static variable here. Also, added some
+	NULL checks to avoid crashes.
+
+2005-06-15  Sushma Rai  <rsushma novell com>
+
+	* exchange-account-setup.c (org_gnome_exchange_settings): Trying to 
+	get the exchange account, after checking the account selected in 
+	an exchange account or not. It fixes a crash, when trying to edit an
+	non-exchange account, where e-d-s and evolution are built with exchange
+	support, but exchange account is not configured.
+
+2005-06-14  Sarfaaz Ahmed <asarfraaz novell com>
+
+	* exchange-account-setup.c : Fixed some warnings
+	* exchange-config-listener.c : Similar
+
+2005-06-12  Sarfraaz Ahmed <asarfraaz novell com>
+
+	* Initial commit to rename Exchange-account-setup as Exchange 
+	Operations.
+
+2005-06-10  Sarfraaz Ahmed <asarfraaz novell com>
+
+	* exchange-account-setup.c (e_plugin_lib_enable)
+	(free_exchange_listener)(e_plugin_lib_enable) : Added new to 
+	initialise the config listener.
+	(update_state) : Now updates the state directly from the server and not
+	from the file as earlier.
+	(owa_authenticate_user) : Authenticates and validates directly from
+	the server instead of using the camel APIs as earlier.
+	(set_oof_info) : Sets the state directly on the server
+	* Makefile.am : Use CAMEL_EXCHANGE CFLAGS and LIBS
+
+2005-05-21  Sarfraaz Ahmed <asarfraaz novell com>
+
+	Added a bunch of files to create exchange plugins for UI changes
+	* exchange-change-password.[ch]/.glade
+	* exchange-delegates.[ch]/.glade
+	* exchange-delegate-user.[ch]
+	* exchange-folder-size.[ch]
+	* exchange-folder-tree.glade
+
+2005-05-16  Not Zed  <NotZed Ximian com>
+
+	* exchange-account-setup.c: moved e-error to e-util
+
+2005-03-18  Sushma Rai  <rsushma novell com>
+
+	* exchange-account-setup.c (org_gnome_exchange_owa_url): When the 
+	Exchange account doesn't contain OWA url parameter, setting the OWA 
+	url value in the receive page and saving it.
+	(construct_owa_url): Forming OWA url, from the existing parameters for
+	hostname, ssl, OWA path and mailbox name.
+	see #73627
+
+2005-03-17  Sushma Rai  <rsushma novell com>
+
+	* exchange-account-setup.c (exchange_authtype_changed): Setting the 
+	authentication mechanism to both transport and source urls.
+
+2005-03-05  Sushma Rai  <rsushma novell com>
+
+	* org-gnome-exchange-account-setup.eplug.in: Added the commit function
+	to save OOF data. This got missed in the previous commit. Also removed 
+	duplicate accountWizard definition.
+
+2005-02-28  JP Rosevear  <jpr novell com>
+
+	* org-gnome-exchange-account-setup.eplug.in: add account wizard item
+
+2005-02-27  Sushma Rai  <rsushma novell com>
+
+	* exchange-account-setup.c (org_gnome_exchange_settings): Storing the 
+	oof data enterted by user to a file, displaying the existing data on
+	this page.
+	(toggled_state): Signal hander for radiobutton, that sets the oof state.
+	(update_state): Signal handler that reads the oof message entered. 
+	(org_gnome_exchange_commit): Stores the oof data and does cleanup.
+	(store_oof_info): Checks for the oof information file, writes the 
+	oof state and message to the file. 
+	(destroy_oof_data): Frees OOFData. 
+	
+2005-02-26  Sushma Rai  <rsushma novell com>
+
+        * exchange-account-setup.c (org_gnome_exchange_check_options):
+        Returning FALSE on NULL host name or set to "" for receive page, 
+	so that one can proceed with the account creation only after 
+	hostname is retrived and set by validate().
+
+2005-02-24  Björn Torkelsson  <torkel acc umu se>
+
+	* org-gnome-exchange-account-setup.eplug.in: Added author and
+	fixed description.
+	
+2005-02-21  Not Zed  <NotZed Ximian com>
+
+	* exchange-account-setup.c (org_gnome_exchange_owa_url): if the
+	host is null in the url, set it to "", so it has a non-null value.
+
+2005-02-07  Sushma Rai  <rsushma novell com>
+	
+	* org-gnome-exchange-account-setup.eplug.in: Added plugin for adding 
+	auth type section to editor.
+
+	* exchange-account-setup.c (org_gnome_exchange_auth_section): Adding
+	and handling authentication type for exchange account. 
+
+2005-01-28  Not Zed  <NotZed Ximian com>
+
+	** related to bug #71520.
+
+	* exchange-account-setup.c: All but re-written.
+	  Fixed the license of the file.
+	  Fixed a translation string.
+	  Modified return condition check.
+	  Fixed problem over writing current account with the old data.
+	  Removed duplicated code.
+	  Removed the hack for handling NULL hostname, now using 
+	  CAMEL_URL_HIDDEN_HOST url flag in the provider.
+	  Using E_ACCOUNT_SOURCE_SAVE_PASSWD for remember password.
+	  Removed the way owa url entry was added to table in config section,
+	  Now econfig supports tables. 
+
+	* exchange-ask-password.c: removed, functionality moved to
+	exchange-account-setup.c.
+
+2005-01-25  Sushma Rai  <rsushma novell com>
+
+	* exchange-account-setup.c (create_page): Fixed empty
+	string being marked for translation problem. #71644
+
+2005-01-23  Sushma Rai  <rsushma novell com>
+	
+	* org-gnome-exchange-account-setup.eplug.in: Added plugins 
+	for handling hiding auth type section in druid.
+
+	* exchange-account-setup.c (add_owa_entry_to_editor): Changed the 
+	button label to "Authenticate" from OK
+
+	* exchange-ask-password.c (add_owa_entry): Changed the button label
+	to Authenticate.
+	(org_gnome_exchange_handle_auth): Hiding Auth section in receive page.
+	(org_gnome_exchange_handle_send_auth_option): Hiding the Auth section
+	in send page
+
+2005-01-22  Sushma Rai  <rsushma novell com>
+
+	* org-gnome-exchange-account-setup.eplug.in: Added 
+	org_gnome_exchange_check_options plugin.
+
+	* exchange-ask-password.c (org_gnome_exchange_check_options): 
+	Reads OWA URL value and sets use_ssl and owa_url values for source 
+	account url.
+
+	* exchange-account-setup.c (org_gnome_exchange_set_url)
+	(add_owa_entry_to_editor): Reading owa url value from gconf and setting
+	owa url value in the account editor. Fixes #71378 
+
+2005-01-19  Sushma Rai  <rsushma novell com>
+
+	* exchange-ask-password.c (validate_exchange_user): Fix for remembering
+	password if user has selected that option, while creating the account. 
+
+2005-01-18  Sushma Rai  <rsushma novell com>
+
+	* exchange-ask-password.c (validate_exchange_user): Reading the return
+	value of user validation function. Fixes #71385
+
+2005-01-18  Sushma Rai  <rsushma novell com>
+
+	* exchange-ask-password.c (validate_exchange_user): Filling up
+	user name so that page check doesn't fail. Fixes #71384 
+
+2005-01-18  Sushma Rai  <rsushma novell com>
+
+	* exchange-ask-password.c (org_gnome_exchange_read_url):
+	Setting dummy host name, which will be reset to proper
+	hostname once the user is authenticated.
+
+2005-01-18  Sushma Rai  <rsushma novell com>
+
+	* org-gnome-exchange-account-setup.eplug.in: Moved two account
+	editor plugins unser same hook class. 
+
+	* exchange-ask-password.c: Reorganized the code. 
+	Used accessor functions to read and set EAccount values. 
+	Removed editor specific factory function add_owa_entry_to_editor()
+	from here.
+	
+	* exchange-account-setup.c: Reorganized the code.
+	Moved add_owa_entry_to_editor() and it's sub functions into this file.
+	(org_gnome_exchange_account_setup): Reading source url and transport
+	url values stored in gconf and filling up the EAccount structure.
+	This fixes the problem of page check failure, as improper source url 
+	and transport url values, as we don't read host name in the editor.
+	(org_gnome_exchange_set_url): Similar.
+	
+2005-01-17  Sushma Rai  <rsushma novell com>
+
+	* Makefile.am: Linking to camel libs. Fixes plugin loading problem 
+	due to undefined camel symbol, during evolution startup. 
+
+2005-01-13  Sushma Rai  <rsushma novell com>
+
+	* org-gnome-exchange-account-setup.eplug.in: Combined
+	all the plugins into one. 
+
+2005-01-12  Sushma Rai  <rsushma novell com>
+
+	* exchange-ask-password.c: (validate_exchange_user):
+	Added one more error condition check.
+
+2005-01-12  Sushma Rai  <rsushma novell com>
+
+	* org-gnome-exchange-account-setup.eplug.in: Factory
+	method to add owa url entry to account editor. 
+
+	* exchange-ask-password.c: (org_gnome_exchange_set_url)
+	(add_owa_entry_to_editor): Adds owa url entry to the 
+	account editor for Exchange account.
+	(validate_exchange_user): Using the CamelProvider private
+	function defined by Exchange camel provider.
+ 
+2005-01-11  Sushma Rai  <rsushma novell com>
+
+	* org-gnome-exchange-account-setup.eplug.in: Removed page check plugin
+
+	* exchange-ask-password.c: Added a button to prompt for password
+	instead of listening on page next signal
+
+2005-01-11  Not Zed  <NotZed Ximian com>
+
+	* Makefile.am: fix LDFLAGS variable name.
+
+2005-01-10  Sushma Rai <rsushma novell com>
+
+	* exchange-ask-password.c: (validate_exchange_user):
+	Corrected argument order.
+
+2005-01-10  Sushma Rai <rsushma novell com>
+	
+	* org-gnome-exchange-account-setup.eplug.in: Added plugin to read
+	OWA url entry to the account set up druid.
+
+	* exchange-ask-password.c: Create a entry for OWA URL and reads the
+	URL value.
+
+2005-01-09  Sushma Rai <rsushma novell com>
+	
+	* exchange-ask-password.c: Pops up password dialog and validates
+	user credentials once owa url and user name are entered.
+
+	* org-gnome-exchange-account-setup.eplug.in: Added page check plugin.
+
+2005-01-09  Sushma Rai <rsushma novell com>
+
+	* Intial ckeckin, Plugin for Exchange account specific settings
diff --git a/eplugin/Makefile.am b/eplugin/Makefile.am
new file mode 100644
index 0000000..116b449
--- /dev/null
+++ b/eplugin/Makefile.am
@@ -0,0 +1,77 @@
+### EVO_PLUGIN_RULE ### begin ###
+
+%.eplug: %.eplug.in
+	sed -e 's|\ PLUGINDIR\@|$(plugindir)|'		\
+	-e 's|\ SOEXT\@|$(SOEXT)|'			\
+	-e 's|\ GETTEXT_PACKAGE\@|$(GETTEXT_PACKAGE)|'	\
+	-e 's|\ LOCALEDIR\@|$(localedir)|' $< > $@
+
+%.eplug.in: %.eplug.xml
+	LC_ALL=C $(INTLTOOL_MERGE) -x -u /tmp $< $@
+
+%.error: %.error.xml
+	LC_ALL=C $(INTLTOOL_MERGE) -x -u /tmp $< $@
+
+### EVO_PLUGIN_RULE ### end ###
+
+
+plugin_DATA = org-gnome-exchange-operations.eplug
+
+plugin_LTLIBRARIES = liborg-gnome-exchange-operations.la
+
+liborg_gnome_exchange_operations_la_SOURCES = 		\
+	exchange-operations.c				\
+	exchange-operations.h				\
+	exchange-config-listener.c			\
+	exchange-config-listener.h			\
+	exchange-calendar.c				\
+	exchange-contacts.c				\
+	exchange-change-password.c			\
+	exchange-change-password.h			\
+	exchange-delegates-user.c			\
+	exchange-delegates-user.h			\
+	exchange-delegates.c				\
+	exchange-delegates.h				\
+	exchange-user-dialog.c				\
+	exchange-user-dialog.h				\
+	exchange-folder-size-display.c			\
+	exchange-folder-size-display.h			\
+	exchange-account-setup.c			\
+	exchange-permissions-dialog.c			\
+	exchange-permissions-dialog.h			\
+	exchange-folder-permission.c			\
+	exchange-folder-subscription.c			\
+	exchange-folder-subscription.h			\
+	exchange-folder.c				\
+	exchange-mail-send-options.c			\
+	exchange-send-options.c				\
+	exchange-send-options.h
+
+liborg_gnome_exchange_operations_la_CPPFLAGS =	\
+	$(AM_CPPFLAGS)				\
+	-I .					\
+	$(EVOLUTION_DATA_SERVER_CFLAGS)		\
+	$(EVOLUTION_PLUGIN_CFLAGS)		\
+	$(CAMEL_EXCHANGE_CFLAGS)		\
+	$(EVOLUTION_MAIL_CFLAGS)
+
+liborg_gnome_exchange_operations_la_LIBADD =	\
+	$(EVOLUTION_DATA_SERVER_LIBS)		\
+	$(EVOLUTION_PLUGIN_LIBS)		\
+	$(CAMEL_EXCHANGE_LIBS)			\
+	$(EVOLUTION_MAIL_LIBS)
+
+liborg_gnome_exchange_operations_la_LDFLAGS = -module -avoid-version $(NO_UNDEFINED)
+
+error_DATA = org-gnome-exchange-operations.error
+errordir = $(EVOLUTION_PLUGIN_errordir)
+
+EXTRA_DIST = 							\
+	org-gnome-exchange-operations.eplug.xml			\
+	org-gnome-exchange-operations.error.xml
+
+BUILT_SOURCES = $(error_DATA) org-gnome-exchange-operations.eplug 
+
+CLEANFILES = $(BUILT_SOURCES)
+
+-include $(top_srcdir)/git.mk
diff --git a/eplugin/exchange-account-setup.c b/eplugin/exchange-account-setup.c
new file mode 100644
index 0000000..f1b64d3
--- /dev/null
+++ b/eplugin/exchange-account-setup.c
@@ -0,0 +1,1150 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ *		Sushma Rai <rsushma novell com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "libedataserver/e-account.h"
+#include "e-util/e-error.h"
+
+#include <string.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include <gtk/gtk.h>
+#include <glib/gi18n.h>
+#include <gconf/gconf-client.h>
+#include <camel/camel-provider.h>
+#include <camel/camel-url.h>
+#include <camel/camel-service.h>
+#include <camel/camel-folder.h>
+#include <e-util/e-dialog-utils.h>
+#include <e2k-validate.h>
+#include <exchange-oof.h>
+#include <exchange-account.h>
+#include "exchange-config-listener.h"
+#include "exchange-operations.h"
+#include "exchange-folder-size-display.h"
+#include "mail/em-account-editor.h"
+#include "mail/em-config.h"
+#include "exchange-delegates.h"
+#include "exchange-change-password.h"
+#include "exchange-folder-size-display.h"
+
+GtkWidget* org_gnome_exchange_settings(EPlugin *epl, EConfigHookItemFactoryData *data);
+GtkWidget *org_gnome_exchange_owa_url(EPlugin *epl, EConfigHookItemFactoryData *data);
+gboolean org_gnome_exchange_check_options(EPlugin *epl, EConfigHookPageCheckData *data);
+GtkWidget *org_gnome_exchange_auth_section (EPlugin *epl, EConfigHookItemFactoryData *data);
+void org_gnome_exchange_commit (EPlugin *epl, EConfigHookItemFactoryData *data);
+GtkWidget* org_gnome_exchange_show_folder_size_factory (EPlugin *epl, EConfigHookItemFactoryData *data);
+
+CamelServiceAuthType camel_exchange_ntlm_authtype = {
+	/* i18n: "Secure Password Authentication" is an Outlookism */
+	(gchar *) N_("Secure Password"),
+
+	/* i18n: "NTLM" probably doesn't translate */
+	(gchar *) N_("This option will connect to the Exchange server "
+	"using secure password (NTLM) authentication."),
+
+	(gchar *) "NTLM",
+	TRUE
+};
+
+CamelServiceAuthType camel_exchange_password_authtype = {
+	(gchar *) N_("Plaintext Password"),
+
+	(gchar *) N_("This option will connect to the Exchange server "
+	"using standard plaintext password authentication."),
+
+	(gchar *) "Basic",
+	TRUE
+};
+
+typedef struct {
+	gboolean state;
+	gchar *message;
+	GtkWidget *text_view;
+}OOFData;
+
+static OOFData *oof_data;
+
+static void
+update_state (GtkTextBuffer *buffer, gpointer data)
+{
+	if (gtk_text_buffer_get_modified (buffer)) {
+		GtkTextIter start, end;
+		if (oof_data->message)
+			g_free (oof_data->message);
+		gtk_text_buffer_get_bounds (buffer, &start, &end);
+		oof_data->message =  gtk_text_buffer_get_text (buffer, &start,
+							       &end, FALSE);
+		gtk_text_buffer_set_modified (buffer, FALSE);
+	}
+}
+
+static void
+toggled_state (GtkToggleButton *button, gpointer data)
+{
+	gboolean current_oof_state = gtk_toggle_button_get_active (button);
+
+	if (current_oof_state == oof_data->state)
+		return;
+	oof_data->state = current_oof_state;
+	gtk_widget_set_sensitive (oof_data->text_view, current_oof_state);
+}
+
+#ifdef HAVE_KRB5
+static void
+btn_chpass_clicked (GtkButton *button, gpointer data)
+{
+	ExchangeAccount *account;
+	gchar *old_password, *new_password;
+	ExchangeAccountResult result;
+
+	account = exchange_operations_get_exchange_account ();
+	if (!account)
+		return;
+
+	old_password = exchange_account_get_password (account);
+	if (!old_password) {
+		g_print ("Could not fetch old password\n");
+		return;
+	}
+	new_password = exchange_get_new_password (old_password, TRUE);
+	if (!new_password) {
+		/* "Cacel" button was hit */
+		return;
+	}
+	/* g_print ("Current password is \"%s\"\n", old_password); */
+	result = exchange_account_set_password (account, old_password, new_password);
+	if (result != EXCHANGE_ACCOUNT_CONNECT_SUCCESS)
+		exchange_operations_report_error (account, result);
+
+	g_free (old_password);
+	g_free (new_password);
+}
+#endif
+
+static void
+btn_dass_clicked (GtkButton *button, gpointer data)
+{
+	ExchangeAccount *account;
+	account = exchange_operations_get_exchange_account ();
+	if (!account)
+		return;
+	exchange_delegates (account, gtk_widget_get_ancestor (GTK_WIDGET (button), GTK_TYPE_WINDOW));
+}
+
+static void
+btn_fsize_clicked (GtkButton *button, gpointer data)
+{
+	ExchangeAccount *account;
+	GtkListStore *model;
+
+	account = exchange_operations_get_exchange_account ();
+	if (!account)
+		return;
+
+	model = exchange_account_folder_size_get_model (account);
+	if (model)
+		exchange_folder_size_display (model, GTK_WIDGET (button));
+}
+
+/* only used in editor */
+GtkWidget *
+org_gnome_exchange_settings(EPlugin *epl, EConfigHookItemFactoryData *data)
+{
+	EMConfigTargetAccount *target_account;
+	ExchangeAccount *account = NULL;
+	CamelURL *url;
+	const gchar *source_url;
+	gchar *message = NULL, *txt = NULL, *oof_message;
+	gboolean oof_state = FALSE;
+	gint offline_status;
+
+	GtkVBox *vbox_settings;
+
+	/* OOF fields */
+	GtkFrame *frm_oof;
+	GtkVBox *vbox_oof;
+	GtkLabel *lbl_oof_desc;
+	GtkTable *tbl_oof_status;
+	GtkLabel *lbl_status;
+	GtkRadioButton *radio_iof, *radio_oof;
+	GtkScrolledWindow *scrwnd_oof;
+	GtkTextView *txtview_oof;
+
+	/* Authentication settings */
+	GtkFrame *frm_auth;
+	GtkVBox *vbox_auth;
+	GtkTable *tbl_auth;
+#ifdef HAVE_KRB5
+	GtkLabel *lbl_chpass;
+	GtkButton *btn_chpass;
+#endif
+	GtkLabel *lbl_dass;
+	GtkButton *btn_dass;
+
+	/* Miscelleneous setting */
+	GtkFrame *frm_misc;
+	GtkVBox *vbox_misc;
+	GtkTable *tbl_misc;
+	GtkLabel *lbl_fsize;
+	GtkButton *btn_fsize;
+
+	GtkTextBuffer *buffer;
+	GtkTextIter start, end;
+
+	target_account = (EMConfigTargetAccount *)data->config->target;
+	source_url = e_account_get_string (target_account->account,  E_ACCOUNT_SOURCE_URL);
+	url = camel_url_new(source_url, NULL);
+	if (url == NULL
+	    || strcmp(url->protocol, "exchange") != 0) {
+		if (url)
+			camel_url_free(url);
+		return NULL;
+	}
+
+	if (data->old) {
+		camel_url_free(url);
+		return data->old;
+	}
+	if (url)
+		camel_url_free (url);
+
+	account = exchange_operations_get_exchange_account ();
+
+	exchange_config_listener_get_offline_status (exchange_global_config_listener,
+								    &offline_status);
+	if (offline_status == OFFLINE_MODE) {
+		e_error_run (NULL, ERROR_DOMAIN ":exchange-settings-offline", NULL);
+
+		return NULL;
+	}
+
+	oof_data = g_new0 (OOFData, 1);
+
+	oof_data->state = FALSE;
+	oof_data->message = NULL;
+	oof_data->text_view = NULL;
+
+	/* See if oof info found already */
+
+	if (account && !exchange_oof_get (account, &oof_state, &message)) {
+
+		e_error_run (NULL, ERROR_DOMAIN ":state-read-error", NULL);
+
+                return NULL;
+        }
+
+	if (message && *message)
+		oof_data->message = g_strdup (message);
+	else
+		oof_data->message = NULL;
+	oof_data->state = oof_state;
+
+	/* construct page */
+
+	vbox_settings = (GtkVBox*) g_object_new (GTK_TYPE_VBOX, "homogeneous", FALSE, "spacing", 6, NULL);
+	gtk_container_set_border_width (GTK_CONTAINER (vbox_settings), 12);
+
+	frm_oof = (GtkFrame*) g_object_new (GTK_TYPE_FRAME, "label", _("Out Of Office"), NULL);
+	gtk_box_pack_start (GTK_BOX (vbox_settings), GTK_WIDGET (frm_oof), FALSE, FALSE, 0);
+
+	vbox_oof = (GtkVBox*) g_object_new (GTK_TYPE_VBOX, NULL, "homogeneous", FALSE, "spacing", 12, NULL);
+	gtk_container_set_border_width (GTK_CONTAINER (vbox_oof), 6);
+	gtk_container_add (GTK_CONTAINER (frm_oof), GTK_WIDGET (vbox_oof));
+
+	lbl_oof_desc = (GtkLabel*) g_object_new (GTK_TYPE_LABEL, "label", _("The message specified below will be automatically sent to \neach person who sends mail to you while you are out of the office."), "justify", GTK_JUSTIFY_LEFT, NULL);
+	gtk_misc_set_alignment (GTK_MISC (lbl_oof_desc), 0, 0.5);
+	gtk_box_pack_start (GTK_BOX (vbox_oof), GTK_WIDGET (lbl_oof_desc), FALSE, FALSE, 0);
+
+	tbl_oof_status = (GtkTable*) g_object_new (GTK_TYPE_TABLE, "n-rows", 2, "n-columns", 2, "homogeneous", FALSE, "row-spacing", 6, "column-spacing", 6, NULL);
+	txt = g_strdup_printf ("<b>%s</b>", _("Status:"));
+	lbl_status = (GtkLabel*) g_object_new (GTK_TYPE_LABEL, "label", txt, "use-markup", TRUE, NULL);
+	g_free (txt);
+	gtk_misc_set_alignment (GTK_MISC (lbl_status), 0, 0.5);
+	gtk_misc_set_padding (GTK_MISC (lbl_status), 0, 0);
+
+	if (oof_data->state) {
+		radio_oof = (GtkRadioButton*) g_object_new (GTK_TYPE_RADIO_BUTTON, "label", _("I am out of the office"), NULL);
+		radio_iof = (GtkRadioButton*) g_object_new (GTK_TYPE_RADIO_BUTTON, "label", _("I am in the office"), "group", radio_oof, NULL);
+	}
+	else {
+		radio_iof = (GtkRadioButton*) g_object_new (GTK_TYPE_RADIO_BUTTON, "label", _("I am in the office"), NULL);
+		radio_oof = (GtkRadioButton*) g_object_new (GTK_TYPE_RADIO_BUTTON, "label", _("I am out of the office"), "group", radio_iof, NULL);
+	}
+	g_signal_connect (radio_oof, "toggled", G_CALLBACK (toggled_state), NULL);
+
+	gtk_table_attach (tbl_oof_status, GTK_WIDGET (lbl_status), 0, 1, 0, 1, GTK_FILL, GTK_FILL, 0, 0);
+	gtk_table_attach (tbl_oof_status, GTK_WIDGET (radio_iof), 1, 2, 0, 1, GTK_FILL, GTK_FILL, 0, 0);
+	gtk_table_attach (tbl_oof_status, GTK_WIDGET (radio_oof), 1, 2, 1, 2, GTK_FILL, GTK_FILL, 0, 0);
+
+	gtk_box_pack_start (GTK_BOX (vbox_oof), GTK_WIDGET (tbl_oof_status), FALSE, FALSE, 0);
+
+	scrwnd_oof = (GtkScrolledWindow*) g_object_new (GTK_TYPE_SCROLLED_WINDOW, "hscrollbar-policy", GTK_POLICY_AUTOMATIC, "vscrollbar-policy", GTK_POLICY_AUTOMATIC, "shadow-type", GTK_SHADOW_IN, NULL);
+	gtk_box_pack_start (GTK_BOX (vbox_oof), GTK_WIDGET (scrwnd_oof), FALSE, FALSE, 0);
+	txtview_oof = (GtkTextView*) g_object_new (GTK_TYPE_TEXT_VIEW, "justification", GTK_JUSTIFY_LEFT, "wrap-mode", GTK_WRAP_WORD, "editable", TRUE, NULL);
+	buffer = gtk_text_view_get_buffer (txtview_oof);
+	gtk_text_buffer_get_bounds (buffer, &start, &end);
+	oof_message = gtk_text_buffer_get_text (buffer, &start, &end, FALSE);
+	if (oof_message && *oof_message) {
+		/* Will this ever happen? */
+		oof_data->message = oof_message;
+	}
+	if (oof_data->message) {
+		/* previuosly set message */
+		gtk_text_buffer_set_text (buffer, oof_data->message, -1);
+		gtk_text_view_set_buffer (txtview_oof, buffer);
+
+	}
+	gtk_text_buffer_set_modified (buffer, FALSE);
+	if (!oof_data->state)
+		gtk_widget_set_sensitive (GTK_WIDGET (txtview_oof), FALSE);
+	oof_data->text_view = GTK_WIDGET (txtview_oof);
+	g_signal_connect (buffer, "changed", G_CALLBACK (update_state), NULL);
+	gtk_container_add (GTK_CONTAINER (scrwnd_oof), GTK_WIDGET (txtview_oof));
+
+	/* Security settings */
+	frm_auth = (GtkFrame*) g_object_new (GTK_TYPE_FRAME, "label", _("Security"), NULL);
+	gtk_box_pack_start (GTK_BOX (vbox_settings), GTK_WIDGET (frm_auth), FALSE, FALSE, 0);
+
+	vbox_auth = (GtkVBox*) g_object_new (GTK_TYPE_VBOX, "homogeneous", FALSE, "spacing", 6, NULL);
+	gtk_container_set_border_width (GTK_CONTAINER (vbox_auth), 6);
+	gtk_container_add (GTK_CONTAINER (frm_auth), GTK_WIDGET (vbox_auth));
+
+	tbl_auth = (GtkTable*) g_object_new (GTK_TYPE_TABLE, "n-rows", 2, "n-columns", 2, "homogeneous", FALSE, "row-spacing", 6, "column-spacing", 6, NULL);
+
+#ifdef HAVE_KRB5
+	/* Change Password */
+	lbl_chpass = (GtkLabel*) g_object_new (GTK_TYPE_LABEL, "label", _("Change the password for Exchange account"), NULL);
+	gtk_misc_set_alignment (GTK_MISC (lbl_chpass), 0, 0.5);
+	btn_chpass = (GtkButton*) g_object_new (GTK_TYPE_BUTTON, "label", _("Change Password"), NULL);
+	g_signal_connect (GTK_OBJECT (btn_chpass), "clicked", G_CALLBACK (btn_chpass_clicked), NULL);
+#endif
+
+	/* Delegation Assistant */
+	lbl_dass = (GtkLabel*) g_object_new (GTK_TYPE_LABEL, "label", _("Manage the delegate settings for Exchange account"), NULL);
+	gtk_misc_set_alignment (GTK_MISC (lbl_dass), 0, 0.5);
+	btn_dass = (GtkButton*) g_object_new (GTK_TYPE_BUTTON, "label", _("Delegation Assistant"), NULL);
+	g_signal_connect (btn_dass, "clicked", G_CALLBACK (btn_dass_clicked), NULL);
+	/* Add items to the table */
+#ifdef HAVE_KRB5
+	gtk_table_attach_defaults (tbl_auth, GTK_WIDGET (lbl_chpass), 0, 1, 0, 1);
+	gtk_table_attach (tbl_auth, GTK_WIDGET (btn_chpass), 1, 2, 0, 1, GTK_FILL, GTK_FILL, 0, 0);
+#endif
+	gtk_table_attach_defaults (tbl_auth, GTK_WIDGET (lbl_dass), 0, 1, 1, 2);
+	gtk_table_attach (tbl_auth, GTK_WIDGET (btn_dass), 1, 2, 1, 2, GTK_FILL, GTK_FILL, 0, 0);
+	gtk_box_pack_start (GTK_BOX (vbox_auth), GTK_WIDGET (tbl_auth), FALSE, FALSE, 0);
+
+	/* Miscelleneous settings */
+	frm_misc = (GtkFrame*) g_object_new (GTK_TYPE_FRAME, "label", _("Miscelleneous"), NULL);
+	gtk_box_pack_start (GTK_BOX (vbox_settings), GTK_WIDGET (frm_misc), FALSE, FALSE, 0);
+
+	vbox_misc = (GtkVBox*) g_object_new (GTK_TYPE_VBOX, "homogeneous", FALSE, "spacing", 6, NULL);
+	gtk_container_set_border_width (GTK_CONTAINER (vbox_misc), 6);
+	gtk_container_add (GTK_CONTAINER (frm_misc), GTK_WIDGET (vbox_misc));
+
+	tbl_misc = (GtkTable*) g_object_new (GTK_TYPE_TABLE, "n-rows", 1, "n-columns", 1, "homogeneous", FALSE, "row-spacing", 6, "column-spacing", 6, NULL);
+
+	/* Folder Size */
+	lbl_fsize = (GtkLabel*) g_object_new (GTK_TYPE_LABEL, "label", _("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 (btn_fsize_clicked), NULL);
+	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);
+	gtk_box_pack_start (GTK_BOX (vbox_misc), GTK_WIDGET (tbl_misc), FALSE, FALSE, 0);
+
+	gtk_widget_show_all (GTK_WIDGET (vbox_settings));
+	gtk_notebook_insert_page (GTK_NOTEBOOK (data->parent), GTK_WIDGET (vbox_settings), gtk_label_new(_("Exchange Settings")), 4);
+	return GTK_WIDGET (vbox_settings);
+
+}
+
+static void
+print_error (const gchar *owa_url, E2kAutoconfigResult result)
+{
+	switch (result) {
+
+		case E2K_AUTOCONFIG_CANT_CONNECT:
+			e_error_run (NULL, ERROR_DOMAIN ":account-connect-error", "", NULL);
+			break;
+
+		case E2K_AUTOCONFIG_CANT_RESOLVE:
+			e_error_run (NULL, ERROR_DOMAIN ":account-resolve-error", "", NULL);
+			break;
+
+		case E2K_AUTOCONFIG_AUTH_ERROR:
+		case E2K_AUTOCONFIG_AUTH_ERROR_TRY_NTLM:
+		case E2K_AUTOCONFIG_AUTH_ERROR_TRY_BASIC:
+			e_error_run (NULL, ERROR_DOMAIN ":password-incorrect", NULL);
+			break;
+
+		case E2K_AUTOCONFIG_AUTH_ERROR_TRY_DOMAIN:
+			e_error_run (NULL, ERROR_DOMAIN ":account-domain-error", NULL);
+			break;
+
+		case E2K_AUTOCONFIG_NO_OWA:
+		case E2K_AUTOCONFIG_NOT_EXCHANGE:
+			e_error_run (NULL, ERROR_DOMAIN ":account-wss-error", NULL);
+			break;
+
+		case E2K_AUTOCONFIG_CANT_BPROPFIND:
+			e_error_run (NULL, ERROR_DOMAIN ":connect-exchange-error",
+				     "http://support.novell.com/cgi-bin/search/searchtid.cgi?/ximian/ximian328.html";,
+				     NULL);
+			break;
+
+		case E2K_AUTOCONFIG_EXCHANGE_5_5:
+			e_error_run (NULL, ERROR_DOMAIN ":account-version-error", NULL);
+			break;
+
+		default:
+			e_error_run (NULL, ERROR_DOMAIN ":configure-error", NULL);
+			break;
+
+	}
+}
+
+static const gchar *
+gal_auth_to_string (E2kAutoconfigGalAuthPref ad_auth)
+{
+	switch (ad_auth) {
+	case E2K_AUTOCONFIG_USE_GAL_DEFAULT: return "default";
+	case E2K_AUTOCONFIG_USE_GAL_BASIC:   return "basic";
+	case E2K_AUTOCONFIG_USE_GAL_NTLM:    return "ntlm";
+	}
+
+	return "default";
+}
+
+static void
+owa_authenticate_user(GtkWidget *button, EConfig *config)
+{
+	EMConfigTargetAccount *target_account = (EMConfigTargetAccount *)config->target;
+	E2kAutoconfigResult result;
+	CamelURL *url=NULL;
+	gboolean remember_password;
+	gchar *url_string, *key;
+	const gchar *source_url, *id_name, *owa_url;
+	gchar *at, *user;
+	gboolean valid = FALSE;
+	ExchangeParams *exchange_params;
+	GtkWidget *mailbox_entry = g_object_get_data (G_OBJECT (button), "mailbox-entry");
+
+	exchange_params = g_new0 (ExchangeParams, 1);
+	exchange_params->host = NULL;
+	exchange_params->ad_server = NULL;
+	exchange_params->ad_auth = E2K_AUTOCONFIG_USE_GAL_DEFAULT;
+	exchange_params->mailbox = NULL;
+	exchange_params->owa_path = NULL;
+	exchange_params->is_ntlm = TRUE;
+
+	source_url = e_account_get_string (target_account->account, E_ACCOUNT_SOURCE_URL);
+
+	if (source_url && source_url[0] != '\0')
+		url = camel_url_new(source_url, NULL);
+	if (url && url->user == NULL) {
+		id_name = e_account_get_string (target_account->account, E_ACCOUNT_ID_ADDRESS);
+		if (id_name) {
+			at = strchr(id_name, '@');
+			user = g_alloca(at-id_name+1);
+			memcpy(user, id_name, at-id_name);
+			user[at-id_name] = 0;
+			camel_url_set_user (url, user);
+		}
+	}
+
+	/* validate_user() CALLS GTK!!!
+
+	   THIS IS TOTALLY UNNACCEPTABLE!!!!!!!!
+
+	   It must use camel_session_ask_password, and it should return an exception for any problem,
+	   which should then be shown using e-error */
+
+	owa_url = camel_url_get_param (url, "owa_url");
+	if (camel_url_get_param (url, "authmech"))
+		exchange_params->is_ntlm = TRUE;
+	else
+		exchange_params->is_ntlm = FALSE;
+	camel_url_set_authmech (url, exchange_params->is_ntlm ? "NTLM" : "Basic");
+
+	key = camel_url_to_string (url, CAMEL_URL_HIDE_PASSWORD | CAMEL_URL_HIDE_PARAMS);
+	/* Supress the trailing slash */
+	key [strlen(key) -1] = 0;
+
+	/* set the mailbox before function call to let it use our, not create one */
+	exchange_params->mailbox = g_strdup (camel_url_get_param (url, "mailbox"));
+
+	valid =  e2k_validate_user (owa_url, key, &url->user, exchange_params,
+						&remember_password, &result,
+						GTK_WINDOW (gtk_widget_get_toplevel (button)));
+	g_free (key);
+
+	if (!valid && result != E2K_AUTOCONFIG_CANCELLED)
+		print_error (owa_url, result);
+
+	camel_url_set_host (url, valid ? exchange_params->host : "");
+
+	if (valid)
+		camel_url_set_param (url, "save-passwd", remember_password? "true" : "false");
+
+	camel_url_set_param (url, "ad_server", valid ? exchange_params->ad_server: NULL);
+	camel_url_set_param (url, "mailbox", valid ? exchange_params->mailbox : NULL);
+	camel_url_set_param (url, "owa_path", valid ? exchange_params->owa_path : NULL);
+	camel_url_set_param (url, "ad_auth", valid ? gal_auth_to_string (exchange_params->ad_auth) : NULL);
+
+	if (mailbox_entry) {
+		const gchar *par = camel_url_get_param (url, "mailbox");
+
+		gtk_entry_set_text (GTK_ENTRY (mailbox_entry), par ? par : "");
+	}
+
+	g_free (exchange_params->owa_path);
+	g_free (exchange_params->mailbox);
+	g_free (exchange_params->host);
+	g_free (exchange_params->ad_server);
+	g_free (exchange_params);
+
+	if (valid) {
+		url_string = camel_url_to_string (url, 0);
+		e_account_set_string (target_account->account, E_ACCOUNT_SOURCE_URL, url_string);
+		e_account_set_string (target_account->account, E_ACCOUNT_TRANSPORT_URL, url_string);
+		e_account_set_bool (target_account->account, E_ACCOUNT_SOURCE_SAVE_PASSWD, remember_password);
+		g_free (url_string);
+	}
+	camel_url_free (url);
+}
+
+static void
+owa_editor_entry_changed(GtkWidget *entry, EConfig *config)
+{
+	const gchar *uri, *ssl = NULL;
+	CamelURL *url, *owaurl = NULL;
+	gchar *url_string;
+	EMConfigTargetAccount *target = (EMConfigTargetAccount *)config->target;
+	GtkWidget *button = g_object_get_data((GObject *)entry, "authenticate-button");
+	gint active = FALSE;
+
+	/* NB: we set the button active only if we have a parsable uri entered */
+
+	const gchar * target_url = e_account_get_string(target->account, E_ACCOUNT_SOURCE_URL);
+	if (target_url && target_url[0] != '\0')
+		url = camel_url_new(target_url, NULL);
+	else url = NULL;
+	uri = gtk_entry_get_text((GtkEntry *)entry);
+	if (uri && uri[0]) {
+		camel_url_set_param(url, "owa_url", uri);
+		owaurl = camel_url_new(uri, NULL);
+		if (owaurl) {
+			active = TRUE;
+
+			/* Reading the owa url and setting use_ssl paramemter */
+			if (!strcmp(owaurl->protocol, "https"))
+				ssl = "always";
+			camel_url_free(owaurl);
+		}
+	} else {
+		camel_url_set_param(url, "owa_url", NULL);
+	}
+
+	camel_url_set_param(url, "use_ssl", ssl);
+	gtk_widget_set_sensitive(button, active);
+
+	url_string = camel_url_to_string(url, 0);
+	e_account_set_string(target->account, E_ACCOUNT_SOURCE_URL, url_string);
+	g_free(url_string);
+	camel_url_free (url);
+}
+
+static void
+update_mailbox_param_in_url (EAccount *account, e_account_item_t item, const gchar *mailbox)
+{
+	CamelURL *url;
+	gchar *url_string;
+	const gchar *target_url;
+
+	if (!account)
+		return;
+
+	target_url = e_account_get_string (account, item);
+	if (target_url && target_url[0] != '\0')
+		url = camel_url_new (target_url, NULL);
+	else
+		return;
+
+	if (mailbox && *mailbox)
+		camel_url_set_param (url, "mailbox", mailbox);
+	else
+		camel_url_set_param (url, "mailbox", NULL);
+
+	url_string = camel_url_to_string (url, 0);
+	e_account_set_string (account, item, url_string);
+	g_free (url_string);
+	camel_url_free (url);
+}
+
+static void
+mailbox_editor_entry_changed (GtkWidget *entry, EConfig *config)
+{
+	EMConfigTargetAccount *target;
+	const gchar *mailbox;
+
+	target = (EMConfigTargetAccount *)config->target;
+	mailbox = gtk_entry_get_text (GTK_ENTRY (entry));
+
+	update_mailbox_param_in_url (target->account, E_ACCOUNT_SOURCE_URL, mailbox);
+	update_mailbox_param_in_url (target->account, E_ACCOUNT_TRANSPORT_URL, mailbox);
+}
+
+static void
+want_mailbox_toggled (GtkWidget *toggle, EConfig *config)
+{
+	GtkWidget *entry;
+
+	g_return_if_fail (toggle != NULL);
+	g_return_if_fail (config != NULL);
+
+	entry = g_object_get_data (G_OBJECT (toggle), "mailbox-entry");
+	if (entry) {
+		gboolean is_active = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (toggle));
+		EMConfigTargetAccount *target;
+		const gchar *mailbox;
+
+		gtk_widget_set_sensitive (entry, is_active);
+
+		target = (EMConfigTargetAccount *)config->target;
+		mailbox = gtk_entry_get_text (GTK_ENTRY (entry));
+
+		update_mailbox_param_in_url (target->account, E_ACCOUNT_SOURCE_URL, is_active ? mailbox : NULL);
+		update_mailbox_param_in_url (target->account, E_ACCOUNT_TRANSPORT_URL, is_active ? mailbox : NULL);
+	}
+}
+
+static gchar *
+construct_owa_url (CamelURL *url)
+{
+	const gchar *owa_path, *use_ssl = NULL;
+	const gchar *protocol = "http", *mailbox_name;
+	gchar *owa_url;
+
+	use_ssl = camel_url_get_param (url, "use_ssl");
+	if (use_ssl) {
+		if (!strcmp (use_ssl, "always"))
+			protocol = "https";
+	}
+
+	owa_path = camel_url_get_param (url, "owa_path");
+	if (!owa_path)
+		owa_path = "/exchange";
+	mailbox_name = camel_url_get_param (url, "mailbox");
+
+	if (mailbox_name)
+		owa_url = g_strdup_printf("%s://%s%s/%s", protocol, url->host, owa_path, mailbox_name);
+	else
+		owa_url = g_strdup_printf("%s://%s%s", protocol, url->host, owa_path );
+
+	return owa_url;
+}
+
+/* used by editor and assistant - same code */
+GtkWidget *
+org_gnome_exchange_owa_url(EPlugin *epl, EConfigHookItemFactoryData *data)
+{
+	EMConfigTargetAccount *target_account;
+	const gchar *source_url;
+	gchar *owa_url = NULL, *mailbox_name, *username;
+	GtkWidget *owa_entry, *mailbox_entry, *want_mailbox_check;
+	CamelURL *url;
+	gint row;
+	GtkWidget *hbox, *label, *button;
+
+	target_account = (EMConfigTargetAccount *)data->config->target;
+	source_url = e_account_get_string (target_account->account,  E_ACCOUNT_SOURCE_URL);
+	if (source_url && source_url[0] != '\0')
+		url = camel_url_new(source_url, NULL);
+	else
+		url = NULL;
+	if (url == NULL
+	    || strcmp(url->protocol, "exchange") != 0) {
+		if (url)
+			camel_url_free(url);
+
+		if (data->old
+		    && (label = g_object_get_data((GObject *)data->old, "authenticate-label")))
+			gtk_widget_destroy(label);
+
+		/* TODO: we could remove 'owa-url' from the url,
+		   but that will lose it if we come back.  Maybe a commit callback could do it */
+
+		return NULL;
+	}
+
+	if (data->old) {
+		camel_url_free(url);
+		return data->old;
+	}
+
+	owa_url = g_strdup (camel_url_get_param(url, "owa_url"));
+	mailbox_name = g_strdup (camel_url_get_param (url, "mailbox"));
+	username = g_strdup (url->user);
+
+	/* if the host is null, then user+other info is dropped silently, force it to be kept */
+	if (url->host == NULL) {
+		gchar *uri;
+
+		camel_url_set_host(url, "");
+		uri = camel_url_to_string(url, 0);
+		e_account_set_string(target_account->account,  E_ACCOUNT_SOURCE_URL, uri);
+		g_free(uri);
+	}
+
+	row = ((GtkTable *)data->parent)->nrows;
+
+	hbox = gtk_hbox_new (FALSE, 6);
+	label = gtk_label_new_with_mnemonic(_("_OWA URL:"));
+	gtk_widget_show(label);
+
+	owa_entry = gtk_entry_new();
+
+	if (!owa_url) {
+		if (url->host[0] != 0) {
+			gchar *uri;
+
+			/* url has hostname but not owa_url.
+			 * Account has been created using x-c-s or evo is upgraded to 2.2
+			 * When invoked from assistant, hostname will get set after validation,
+			 * so this condition will never be true during account creation.
+			 */
+			owa_url = construct_owa_url (url);
+			camel_url_set_param (url, "owa_url", owa_url);
+			uri = camel_url_to_string(url, 0);
+			e_account_set_string(target_account->account,  E_ACCOUNT_SOURCE_URL, uri);
+			g_free(uri);
+		}
+	}
+	camel_url_free (url);
+	if (owa_url)
+		gtk_entry_set_text(GTK_ENTRY (owa_entry), owa_url);
+	gtk_label_set_mnemonic_widget((GtkLabel *)label, owa_entry);
+
+	button = gtk_button_new_with_mnemonic (_("A_uthenticate"));
+	gtk_widget_set_sensitive (button, owa_url && owa_url[0]);
+
+	gtk_box_pack_start (GTK_BOX (hbox), owa_entry, TRUE, TRUE, 0);
+	gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 0);
+	gtk_widget_show_all(hbox);
+
+	gtk_table_attach (GTK_TABLE (data->parent), label, 0, 1, row, row+1, 0, 0, 0, 0);
+	gtk_table_attach (GTK_TABLE (data->parent), hbox, 1, 2, row, row+1, GTK_FILL|GTK_EXPAND, GTK_FILL, 0, 0);
+
+	g_signal_connect (owa_entry, "changed", G_CALLBACK(owa_editor_entry_changed), data->config);
+	g_object_set_data((GObject *)owa_entry, "authenticate-button", button);
+	g_signal_connect (button, "clicked", G_CALLBACK(owa_authenticate_user), data->config);
+
+	/* Track the authenticate label, so we can destroy it if e-config is to destroy the hbox */
+	g_object_set_data((GObject *)hbox, "authenticate-label", label);
+
+	/* check for correctness of the input in the owa_entry */
+	owa_editor_entry_changed (owa_entry, data->config);
+
+	row++;
+	want_mailbox_check = gtk_check_button_new_with_mnemonic (
+		_("Mailbox name is _different than user name"));
+	gtk_widget_show (want_mailbox_check);
+	gtk_table_attach (GTK_TABLE (data->parent), want_mailbox_check, 1, 2, row, row+1, GTK_FILL, GTK_FILL, 0, 0);
+	if (!username || !*username || !mailbox_name || !*mailbox_name ||
+	    g_ascii_strcasecmp (username, mailbox_name) == 0 ||
+	    (strchr (username, '/') && g_ascii_strcasecmp (strchr (username, '/') + 1, mailbox_name) == 0)) {
+		gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (want_mailbox_check), FALSE);
+	} else {
+		gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (want_mailbox_check), TRUE);
+	}
+	g_signal_connect (want_mailbox_check, "toggled", G_CALLBACK (want_mailbox_toggled), data->config);
+
+	row++;
+	label = gtk_label_new_with_mnemonic (_("_Mailbox:"));
+	gtk_widget_show (label);
+
+	mailbox_entry = gtk_entry_new ();
+	gtk_widget_show (mailbox_entry);
+	if (mailbox_name)
+		gtk_entry_set_text (GTK_ENTRY (mailbox_entry), mailbox_name);
+
+	gtk_label_set_mnemonic_widget (GTK_LABEL (label), mailbox_entry);
+
+	gtk_widget_set_sensitive (mailbox_entry, gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (want_mailbox_check)));
+
+	g_signal_connect (mailbox_entry, "changed", G_CALLBACK (mailbox_editor_entry_changed), data->config);
+	g_object_set_data (G_OBJECT (button), "mailbox-entry", mailbox_entry);
+	g_object_set_data (G_OBJECT (want_mailbox_check), "mailbox-entry", mailbox_entry);
+
+	gtk_table_attach (GTK_TABLE (data->parent), label, 0, 1, row, row+1, 0, 0, 0, 0);
+	gtk_table_attach (GTK_TABLE (data->parent), mailbox_entry, 1, 2, row, row+1, GTK_FILL|GTK_EXPAND, GTK_FILL, 0, 0);
+
+	g_free (owa_url);
+	g_free (mailbox_name);
+	g_free (username);
+
+	return hbox;
+}
+
+gboolean
+org_gnome_exchange_check_options(EPlugin *epl, EConfigHookPageCheckData *data)
+{
+	EMConfigTargetAccount *target = (EMConfigTargetAccount *)data->config->target;
+	gint status = TRUE;
+
+	/* We assume that if the host is set, then the setting is valid.
+	   The host gets set when the provider validate() call is made */
+	/* We do this check for receive page also, so that user can
+	 * proceed with the account set up only after user is validated,
+	 * and host name is reset by validate() call
+	 */
+	if (data->pageid == NULL ||
+	    strcmp (data->pageid, "10.receive") == 0 ||
+	    strcmp (data->pageid, "20.receive_options") == 0) {
+		CamelURL *url;
+
+		const gchar * target_url = e_account_get_string(target->account,  E_ACCOUNT_SOURCE_URL);
+		if (target_url && target_url[0] != '\0')
+			url = camel_url_new(target_url, NULL);
+		else
+			url = NULL;
+		/* Note: we only care about exchange url's, we WILL get called on all other url's too. */
+		if (url != NULL
+		    && strcmp(url->protocol, "exchange") == 0
+		    && (url->host == NULL || url->host[0] == 0))
+			status = FALSE;
+
+		if (url)
+			camel_url_free(url);
+	}
+
+	return status;
+}
+
+static void
+set_oof_info (void)
+{
+	ExchangeAccount *account;
+
+	account = exchange_operations_get_exchange_account ();
+
+	if (account && !exchange_oof_set (account, oof_data->state, oof_data->message)) {
+
+		e_error_run (NULL, ERROR_DOMAIN ":state-update-error", NULL);
+	}
+}
+
+static void
+destroy_oof_data (void)
+{
+	if (oof_data->message)
+		g_free (oof_data->message);
+	if (oof_data)
+		g_free (oof_data);
+}
+
+void
+org_gnome_exchange_commit (EPlugin *epl, EConfigHookItemFactoryData *data)
+{
+	EMConfigTargetAccount *target_account;
+	const gchar *source_url;
+	CamelURL *url;
+	gint offline_status;
+
+	target_account = (EMConfigTargetAccount *)data->config->target;
+	source_url = e_account_get_string (target_account->account,  E_ACCOUNT_SOURCE_URL);
+	if (source_url && source_url[0] != '\0')
+		url = camel_url_new (source_url, NULL);
+	else
+		url = NULL;
+	if (url == NULL
+	    || strcmp (url->protocol, "exchange") != 0) {
+		if (url)
+			camel_url_free (url);
+
+		return;
+	}
+	if (data->old) {
+		camel_url_free(url);
+		return;
+	}
+
+	camel_url_free (url);
+
+	exchange_config_listener_get_offline_status (exchange_global_config_listener,
+								    &offline_status);
+
+	if (offline_status == OFFLINE_MODE) {
+                return;
+	}
+
+	/* Set oof data in exchange account */
+	set_oof_info ();
+	destroy_oof_data ();
+	return;
+}
+
+static void
+exchange_check_authtype (GtkWidget *w, EConfig *config)
+{
+	return;
+}
+
+static void
+exchange_authtype_changed (GtkComboBox *dropdown, EConfig *config)
+{
+	EMConfigTargetAccount *target = (EMConfigTargetAccount *)config->target;
+	gint id = gtk_combo_box_get_active(dropdown);
+	GtkTreeModel *model;
+	GtkTreeIter iter;
+	CamelServiceAuthType *authtype;
+	CamelURL *url_source, *url_transport;
+	const gchar *source_url, *transport_url;
+	gchar *source_url_string, *transport_url_string;
+
+	source_url = e_account_get_string (target->account,
+					   E_ACCOUNT_SOURCE_URL);
+	if (id == -1)
+		return;
+
+	url_source = camel_url_new (source_url, NULL);
+
+	transport_url = e_account_get_string (target->account,
+					      E_ACCOUNT_TRANSPORT_URL);
+	url_transport = camel_url_new (transport_url, NULL);
+
+	model = gtk_combo_box_get_model(dropdown);
+	if (gtk_tree_model_iter_nth_child(model, &iter, NULL, id)) {
+		gtk_tree_model_get(model, &iter, 1, &authtype, -1);
+		if (authtype) {
+			camel_url_set_authmech(url_source, authtype->authproto);
+			camel_url_set_authmech(url_transport, authtype->authproto);
+		}
+		else {
+			camel_url_set_authmech(url_source, NULL);
+			camel_url_set_authmech(url_transport, NULL);
+		}
+
+		source_url_string = camel_url_to_string(url_source, 0);
+		transport_url_string = camel_url_to_string(url_transport, 0);
+		e_account_set_string(target->account, E_ACCOUNT_SOURCE_URL, source_url_string);
+		e_account_set_string(target->account, E_ACCOUNT_TRANSPORT_URL, transport_url_string);
+		g_free(source_url_string);
+		g_free(transport_url_string);
+	}
+	camel_url_free(url_source);
+	camel_url_free(url_transport);
+}
+
+GtkWidget *
+org_gnome_exchange_auth_section (EPlugin *epl, EConfigHookItemFactoryData *data)
+{
+	EMConfigTargetAccount *target_account;
+	const gchar *source_url;
+	gchar *label_text, *exchange_account_authtype = NULL;
+	CamelURL *url;
+	GtkWidget *hbox, *button, *auth_label, *vbox, *label_hide;
+	GtkComboBox *dropdown;
+	GtkTreeIter iter;
+	GtkListStore *store;
+	gint i, active=0, auth_changed_id = 0;
+	GList *authtypes, *l, *ll;
+	ExchangeAccount *account;
+
+	target_account = (EMConfigTargetAccount *)data->config->target;
+	source_url = e_account_get_string (target_account->account,
+					   E_ACCOUNT_SOURCE_URL);
+	url = camel_url_new (source_url, NULL);
+	if (url == NULL
+	    || strcmp (url->protocol, "exchange") != 0) {
+		if (url)
+			camel_url_free (url);
+
+		return NULL;
+	}
+
+	if (data->old) {
+		camel_url_free(url);
+		return data->old;
+	}
+
+	account = exchange_operations_get_exchange_account ();
+	if (account)
+		exchange_account_authtype = exchange_account_get_authtype (account);
+
+	vbox = gtk_vbox_new (FALSE, 6);
+
+	label_text = g_strdup_printf("<b>%s</b>", _("_Authentication Type"));
+	auth_label = gtk_label_new_with_mnemonic (label_text);
+	g_free (label_text);
+	gtk_label_set_justify (GTK_LABEL (auth_label), GTK_JUSTIFY_LEFT);
+	gtk_misc_set_alignment (GTK_MISC (auth_label), 0, 0.5);
+	gtk_misc_set_padding (GTK_MISC (auth_label), 0, 0);
+	gtk_label_set_use_markup (GTK_LABEL (auth_label), TRUE);
+
+	label_hide = gtk_label_new("\n");
+
+	hbox = gtk_hbox_new (FALSE, 6);
+	dropdown = (GtkComboBox * )gtk_combo_box_new ();
+	gtk_label_set_mnemonic_widget (GTK_LABEL (auth_label), GTK_WIDGET (dropdown));
+
+	button = gtk_button_new_with_mnemonic (_("Ch_eck for Supported Types"));
+
+	authtypes = g_list_prepend (g_list_prepend (NULL, &camel_exchange_password_authtype),
+				    &camel_exchange_ntlm_authtype);
+	store = gtk_list_store_new(3, G_TYPE_STRING, G_TYPE_POINTER, G_TYPE_BOOLEAN);
+
+	for (i=0, l=authtypes; l; l=l->next, i++) {
+		CamelServiceAuthType *authtype = l->data;
+		gint avail = TRUE;
+
+		if (authtypes) {
+			for (ll = authtypes; ll; ll = g_list_next(ll))
+				if (!strcmp(authtype->authproto,
+					((CamelServiceAuthType *)ll->data)->authproto))
+					break;
+			avail = ll != NULL;
+		}
+		gtk_list_store_append (store, &iter);
+		gtk_list_store_set (store, &iter, 0, authtype->name, 1,
+				    authtype, 2, !avail, -1);
+
+		if (url && url->authmech && !strcmp(url->authmech, authtype->authproto)) {
+			active = i;
+		}
+		else if (url && exchange_account_authtype &&
+			 !strcmp (exchange_account_authtype, authtype->authproto)) {
+			/* if the url doesn't contain authmech, read the value from
+			 * exchange account and set the tab selection and
+			 * also set the authmech back to url
+			 */
+			camel_url_set_authmech (url, exchange_account_authtype);
+			active = i;
+		}
+	}
+
+	gtk_combo_box_set_model (dropdown, (GtkTreeModel *)store);
+	gtk_combo_box_set_active (dropdown, -1);
+
+	if (auth_changed_id == 0) {
+		GtkCellRenderer *cell = gtk_cell_renderer_text_new();
+
+		gtk_cell_layout_pack_start ((GtkCellLayout *)dropdown, cell, TRUE);
+		gtk_cell_layout_set_attributes ((GtkCellLayout *)dropdown, cell,
+						"text", 0, "strikethrough", 2, NULL);
+
+		auth_changed_id = g_signal_connect (dropdown,
+						    "changed",
+						    G_CALLBACK (exchange_authtype_changed),
+						    data->config);
+		g_signal_connect (button,
+				  "clicked",
+				  G_CALLBACK(exchange_check_authtype),
+				  data->config);
+	}
+
+	gtk_combo_box_set_active(dropdown, active);
+
+	gtk_box_pack_start (GTK_BOX (hbox), GTK_WIDGET (dropdown), FALSE, FALSE, 0);
+	gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 0);
+
+	gtk_box_pack_start (GTK_BOX (vbox), auth_label, TRUE, TRUE, 0);
+	gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
+	gtk_box_pack_start (GTK_BOX (vbox), label_hide, TRUE, TRUE, 0);
+	gtk_widget_show_all (vbox);
+
+	gtk_box_pack_start (GTK_BOX (data->parent), vbox, TRUE, TRUE, 0);
+
+	if (url)
+		camel_url_free(url);
+	g_list_free (authtypes);
+	g_free (exchange_account_authtype);
+
+	return vbox;
+}
+
+GtkWidget *
+org_gnome_exchange_show_folder_size_factory (EPlugin *epl, EConfigHookItemFactoryData *data)
+{
+	EMConfigTargetFolder *target=  (EMConfigTargetFolder *)data->config->target;
+	CamelFolder *cml_folder = target->folder;
+	CamelService *service;
+	CamelProvider *provider;
+	ExchangeAccount *account;
+	GtkWidget *lbl_size, *lbl_size_val;
+	GtkListStore *model;
+	GtkVBox *vbx;
+	GtkHBox *hbx_size;
+	gchar *folder_name, *folder_size;
+	gint mode;
+
+	service = CAMEL_SERVICE (camel_folder_get_parent_store (cml_folder));
+	if (!service)
+		return NULL;
+
+	provider = camel_service_get_provider (service);
+	if (!provider)
+		return NULL;
+
+	if (g_ascii_strcasecmp (provider->protocol, "exchange"))
+		return NULL;
+
+	account = exchange_operations_get_exchange_account ();
+	if (!account)
+		return NULL;
+
+	exchange_account_is_offline (account, &mode);
+	if (mode == OFFLINE_MODE)
+		return NULL;
+
+	folder_name = (gchar *) camel_folder_get_name (cml_folder);
+	if (!folder_name)
+		folder_name = g_strdup ("name");
+
+	model = exchange_account_folder_size_get_model (account);
+	if (model)
+		folder_size = g_strdup_printf (_("%s KB"), exchange_folder_size_get_val (model, folder_name));
+	else
+		folder_size = g_strdup (_("0 KB"));
+
+	hbx_size = (GtkHBox*) gtk_hbox_new (FALSE, 0);
+	vbx = (GtkVBox *)gtk_notebook_get_nth_page (GTK_NOTEBOOK (data->parent), 0);
+
+	lbl_size = gtk_label_new_with_mnemonic (_("Size:"));
+	lbl_size_val = gtk_label_new_with_mnemonic (_(folder_size));
+	gtk_widget_show (lbl_size);
+	gtk_widget_show (lbl_size_val);
+	gtk_misc_set_alignment (GTK_MISC (lbl_size), 0.0, 0.5);
+	gtk_misc_set_alignment (GTK_MISC (lbl_size_val), 0.0, 0.5);
+	gtk_box_pack_start (GTK_BOX (hbx_size), lbl_size, FALSE, TRUE, 12);
+	gtk_box_pack_start (GTK_BOX (hbx_size), lbl_size_val, FALSE, TRUE, 10);
+	gtk_widget_show_all (GTK_WIDGET (hbx_size));
+
+	gtk_box_pack_start (GTK_BOX (vbx), GTK_WIDGET (hbx_size), FALSE, FALSE, 0);
+	g_free (folder_size);
+
+	return GTK_WIDGET (hbx_size);
+}
diff --git a/eplugin/exchange-calendar.c b/eplugin/exchange-calendar.c
new file mode 100644
index 0000000..f9f7bd7
--- /dev/null
+++ b/eplugin/exchange-calendar.c
@@ -0,0 +1,539 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ *		Praveen Kumar <kpraveen novell com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#include <string.h>
+#include <gtk/gtk.h>
+#include <e-util/e-config.h>
+#include <calendar/gui/e-cal-config.h>
+#include <libedataserver/e-source.h>
+#include <libedataserver/e-url.h>
+#include <e-folder.h>
+#include <exchange-account.h>
+#include <libecal/e-cal.h>
+
+#include "calendar/gui/dialogs/calendar-setup.h"
+#include "mail/em-account-editor.h"
+#include "mail/em-config.h"
+#include "libedataserver/e-account.h"
+#include "e-util/e-error.h"
+
+#include "exchange-operations.h"
+#include "exchange-folder-size-display.h"
+
+enum {
+	CALENDARNAME_COL,
+	CALENDARRURI_COL,
+	NUM_COLS
+};
+
+gboolean calendar_src_exists = FALSE;
+gchar *calendar_old_source_uri = NULL;
+
+static GPtrArray *e_exchange_calendar_get_calendars (ECalSourceType ftype);
+void e_exchange_calendar_pcalendar_on_change (GtkTreeView *treeview, ESource *source);
+GtkWidget *e_exchange_calendar_pcalendar (EPlugin *epl, EConfigHookItemFactoryData *data);
+gboolean e_exchange_calendar_check (EPlugin *epl, EConfigHookPageCheckData *data);
+void e_exchange_calendar_commit (EPlugin *epl, EConfigTarget *target);
+
+/* FIXME: Reconsider the prototype of this function */
+static GPtrArray *
+e_exchange_calendar_get_calendars (ECalSourceType ftype)
+{
+	ExchangeAccount *account;
+	GPtrArray *folder_array;
+	GPtrArray *calendar_list;
+	EFolder *folder;
+	gint i, prefix_len;
+	gchar *type;
+	gchar *uri_prefix;
+	gchar *tmp, *ruri;
+	gchar *tstring;
+
+	/* FIXME: Compiler warns here; review needed */
+	if (ftype == E_CAL_SOURCE_TYPE_EVENT) { /* Calendars */
+		tstring = g_strdup ("calendar");
+	}
+	else if (ftype == E_CAL_SOURCE_TYPE_TODO) { /* Tasks */
+		tstring = g_strdup ("tasks");
+	}
+	else {
+		/* FIXME: Would this ever happen? If so, handle it wisely */
+		tstring = NULL;
+	}
+
+	account = exchange_operations_get_exchange_account ();
+	if (!account)
+		return NULL;
+
+	/* FIXME: Reconsider this hardcoding */
+	uri_prefix = g_strconcat ("exchange://", account->account_filename, "/;", NULL);
+	prefix_len = strlen (uri_prefix);
+
+	calendar_list = g_ptr_array_new ();
+
+	exchange_account_rescan_tree (account);
+	folder_array = exchange_account_get_folders (account);
+
+	for (i=0; i<folder_array->len; ++i) {
+		folder = g_ptr_array_index (folder_array, i);
+		type = (gchar *)e_folder_get_type_string (folder);
+
+		if (!strcmp (type, tstring)) {
+			tmp = (gchar *)e_folder_get_physical_uri (folder);
+			if (g_str_has_prefix (tmp, uri_prefix)) {
+				ruri = g_strdup (tmp+prefix_len);
+				g_ptr_array_add (calendar_list, ruri);
+			}
+		}
+	}
+
+	if (folder_array)
+		g_ptr_array_free (folder_array, TRUE);
+	g_free (uri_prefix);
+	g_free (tstring);
+	return calendar_list;
+}
+
+void
+e_exchange_calendar_pcalendar_on_change (GtkTreeView *treeview, ESource *source)
+{
+	GtkTreeSelection *selection;
+	GtkTreeModel     *model;
+	GtkTreeIter       iter;
+	ExchangeAccount *account;
+	gchar *es_ruri, *ruri;
+
+	account = exchange_operations_get_exchange_account ();
+	if (!account)
+		return;
+
+	selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview));
+	gtk_tree_selection_get_selected(selection, &model, &iter);
+
+	gtk_tree_model_get (model, &iter, CALENDARRURI_COL, &ruri, -1);
+	es_ruri = g_strconcat (account->account_filename, "/;", ruri, NULL);
+	e_source_set_relative_uri (source, es_ruri);
+	g_free (ruri);
+	g_free (es_ruri);
+}
+
+GtkWidget *
+e_exchange_calendar_pcalendar (EPlugin *epl, EConfigHookItemFactoryData *data)
+{
+	static GtkWidget *lbl_pcalendar, *scrw_pcalendar, *tv_pcalendar, *lbl_size, *lbl_size_val;
+	static GtkWidget *hidden = NULL;
+	GtkWidget *parent;
+	GtkTreeStore *ts_pcalendar;
+	GtkCellRenderer *cr_calendar;
+	GtkTreeViewColumn *tvc_calendar;
+	GtkListStore *model;
+	GPtrArray *callist;
+	ECalConfigTargetSource *t = (ECalConfigTargetSource *) data->target;
+	ESource *source = t->source;
+	EUri *uri;
+	ExchangeAccount *account;
+	gchar *ruri;
+	gchar *account_name;
+        gchar *uri_text;
+	gchar *cal_name;
+	gchar *folder_size;
+	const gchar *rel_uri;
+	gint row, i;
+	gint offline_status;
+	gchar *offline_msg;
+	GtkWidget *lbl_offline_msg;
+	gboolean is_personal;
+
+	if (!hidden)
+		hidden = gtk_label_new ("");
+
+	if (data->old) {
+		/* FIXME: Review this */
+		gtk_widget_destroy (lbl_pcalendar);
+		gtk_widget_destroy (scrw_pcalendar);
+		gtk_widget_destroy (tv_pcalendar);
+	}
+
+	uri_text = e_source_get_uri (t->source);
+	uri = e_uri_new (uri_text);
+
+	if (uri && strcmp (uri->protocol, "exchange")) {
+		e_uri_free (uri);
+                g_free (uri_text);
+		return hidden;
+	}
+
+	e_uri_free (uri);
+
+	parent = data->parent;
+	row = ((GtkTable*)parent)->nrows;
+
+	exchange_config_listener_get_offline_status (exchange_global_config_listener,
+								    &offline_status);
+	if (offline_status == OFFLINE_MODE) {
+		/* Evolution is in offline mode; we will not be able to create
+		   new folders or modify existing folders. */
+		offline_msg = g_markup_printf_escaped ("<b>%s</b>",
+						       _("Evolution is in offline mode. You cannot create or modify folders now.\nPlease switch to online mode for such operations."));
+		lbl_offline_msg = gtk_label_new ("");
+		gtk_label_set_markup (GTK_LABEL (lbl_offline_msg), offline_msg);
+		g_free (offline_msg);
+		gtk_widget_show (lbl_offline_msg);
+		gtk_table_attach (GTK_TABLE (parent), lbl_offline_msg, 0, 2, row, row+1, GTK_FILL|GTK_EXPAND, 0, 0, 0);
+		g_free (uri_text);
+		return lbl_offline_msg;
+	}
+
+	rel_uri = e_source_peek_relative_uri (t->source);
+	if (rel_uri && strlen (rel_uri)) {
+		calendar_src_exists = TRUE;
+		g_free (calendar_old_source_uri);
+		calendar_old_source_uri = g_strdup (rel_uri);
+	}
+	else {
+		calendar_src_exists = FALSE;
+	}
+
+	/* REVIEW: Should this handle be freed? - Attn: surf */
+	account = exchange_operations_get_exchange_account ();
+	if (!account) {
+		g_free (calendar_old_source_uri);
+		g_free (uri_text);
+		return NULL;
+	}
+	account_name = account->account_name;
+	is_personal = is_exchange_personal_folder (account, uri_text);
+	g_free (uri_text);
+
+	if (calendar_src_exists && is_personal) {
+		cal_name = (gchar *) e_source_peek_name (source);
+		model = exchange_account_folder_size_get_model (account);
+		if (model)
+			folder_size = g_strdup_printf ("%s KB", exchange_folder_size_get_val (model, cal_name));
+		else
+			folder_size = g_strdup ("0 KB");
+
+		/* FIXME: Take care of i18n */
+		lbl_size = gtk_label_new_with_mnemonic (_("Size:"));
+		lbl_size_val = gtk_label_new_with_mnemonic (_(folder_size));
+		gtk_widget_show (lbl_size);
+		gtk_widget_show (lbl_size_val);
+		gtk_misc_set_alignment (GTK_MISC (lbl_size), 0.0, 0.5);
+		gtk_misc_set_alignment (GTK_MISC (lbl_size_val), 0.0, 0.5);
+		gtk_table_attach (GTK_TABLE (parent), lbl_size, 0, 2, row, row+1, GTK_FILL|GTK_EXPAND, 0, 0, 0);
+		gtk_table_attach (GTK_TABLE (parent), lbl_size_val, 1, 3, row, row+1, GTK_FILL|GTK_EXPAND, 0, 0, 0);
+		g_free (folder_size);
+	}
+
+	lbl_pcalendar = gtk_label_new_with_mnemonic (_("_Location:"));
+	gtk_widget_show (lbl_pcalendar);
+	gtk_misc_set_alignment (GTK_MISC (lbl_pcalendar), 0.0, 0.5);
+	gtk_table_attach (GTK_TABLE (parent), lbl_pcalendar, 0, 2, row+1, row+2, GTK_FILL|GTK_EXPAND, 0, 0, 0);
+
+	ts_pcalendar = gtk_tree_store_new (NUM_COLS, G_TYPE_STRING, G_TYPE_STRING);
+
+	callist = e_exchange_calendar_get_calendars (t->source_type);
+
+	if (callist) {
+		for (i = 0; i < callist->len; i++) {
+			ruri = g_ptr_array_index (callist, i);
+			exchange_operations_cta_add_node_to_tree (ts_pcalendar, NULL, ruri);
+		}
+		g_ptr_array_free (callist, TRUE);
+	}
+
+	cr_calendar = gtk_cell_renderer_text_new ();
+	tvc_calendar = gtk_tree_view_column_new_with_attributes (account_name, cr_calendar, "text", CALENDARNAME_COL, NULL);
+	tv_pcalendar = gtk_tree_view_new_with_model (GTK_TREE_MODEL (ts_pcalendar));
+	gtk_tree_view_append_column (GTK_TREE_VIEW (tv_pcalendar), tvc_calendar);
+	g_object_set (tv_pcalendar, "expander-column", tvc_calendar, "headers-visible", TRUE, NULL);
+	gtk_tree_view_expand_all (GTK_TREE_VIEW (tv_pcalendar));
+
+	scrw_pcalendar = gtk_scrolled_window_new (NULL, NULL);
+	gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrw_pcalendar), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+	gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrw_pcalendar), GTK_SHADOW_IN);
+	g_object_set (scrw_pcalendar, "height-request", 150, NULL);
+	gtk_container_add (GTK_CONTAINER (scrw_pcalendar), tv_pcalendar);
+	gtk_label_set_mnemonic_widget (GTK_LABEL (lbl_pcalendar), tv_pcalendar);
+	g_signal_connect (G_OBJECT (tv_pcalendar), "cursor-changed", G_CALLBACK (e_exchange_calendar_pcalendar_on_change), t->source);
+
+	gtk_table_attach (GTK_TABLE (parent), scrw_pcalendar, 0, 2, row+2, row+3, GTK_EXPAND|GTK_FILL, 0, 0, 0);
+	gtk_widget_show_all (scrw_pcalendar);
+
+	if (calendar_src_exists) {
+		gchar *uri_prefix, *sruri, *tmpruri;
+		gint prefix_len;
+		GtkTreeSelection *selection;
+
+		uri_prefix = g_strconcat (account->account_filename, "/;", NULL);
+		prefix_len = strlen (uri_prefix);
+
+		tmpruri = (gchar *) rel_uri;
+
+		if (g_str_has_prefix (tmpruri, uri_prefix)) {
+			sruri = g_strdup (tmpruri+prefix_len);
+		}
+		else {
+			sruri = NULL;
+		}
+
+		selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (tv_pcalendar));
+		exchange_operations_cta_select_node_from_tree (ts_pcalendar, NULL, sruri, sruri, selection);
+		gtk_widget_set_sensitive (tv_pcalendar, FALSE);
+		g_free (uri_prefix);
+		g_free (sruri);
+	}
+
+	g_object_unref (ts_pcalendar);
+	return tv_pcalendar;
+}
+
+gboolean
+e_exchange_calendar_check (EPlugin *epl, EConfigHookPageCheckData *data)
+{
+	/* FIXME - check pageid */
+	ECalConfigTargetSource *t = (ECalConfigTargetSource *) data->target;
+	ESourceGroup *group;
+	const gchar *base_uri;
+	const gchar *rel_uri;
+	gint offline_status;
+	ExchangeAccount *account;
+	EUri *euri;
+	gint uri_len;
+	gchar *uri_text, *uri_string, *path, *folder_name;
+	gboolean is_personal;
+
+	rel_uri = e_source_peek_relative_uri (t->source);
+	group = e_source_peek_group (t->source);
+	base_uri = e_source_group_peek_base_uri (group);
+	exchange_config_listener_get_offline_status (exchange_global_config_listener,
+						     &offline_status);
+	if (base_uri && !strncmp (base_uri, "exchange", 8)) {
+		if (offline_status == OFFLINE_MODE)
+			return FALSE;
+		if (rel_uri && !strlen (rel_uri))
+			return FALSE;
+	}
+	else {
+		return TRUE;
+	}
+
+	if (!calendar_src_exists) {
+		/* new folder */
+                return TRUE;
+        }
+
+	account = exchange_operations_get_exchange_account ();
+	if (!account)
+		return FALSE;
+
+	uri_text = e_source_get_uri (t->source);
+	euri = e_uri_new (uri_text);
+	uri_string = e_uri_to_string (euri, FALSE);
+	e_uri_free (euri);
+
+	is_personal = is_exchange_personal_folder (account, uri_text);
+
+	uri_len = strlen (uri_string) + 1;
+	g_free (uri_string);
+	path = g_build_filename ("/", uri_text + uri_len, NULL);
+	g_free (uri_text);
+	folder_name = g_strdup (g_strrstr (path, "/") +1);
+	g_free (path);
+
+	if (strcmp (folder_name, e_source_peek_name (t->source))) {
+		/* rename */
+		if (exchange_account_get_standard_uri (account, folder_name) ||
+		    !is_personal) {
+			/* rename of standard/non-personal folder */
+			g_free (folder_name);
+			return FALSE;
+		}
+	}
+	g_free (folder_name);
+
+	return TRUE;
+}
+
+void
+e_exchange_calendar_commit (EPlugin *epl, EConfigTarget *target)
+{
+	ECalConfigTargetSource *t = (ECalConfigTargetSource *) target;
+	ESource *source = t->source;
+	gchar *uri_text, *gruri, *gname, *ruri, *ftype, *path, *path_prefix, *oldpath=NULL;
+	gchar *username, *windows_domain, *authtype;
+	gint prefix_len;
+	ExchangeAccount *account;
+	ExchangeAccountFolderResult result;
+	ExchangeConfigListenerStatus status;
+	gint offline_status;
+	gboolean rename = FALSE;
+
+	uri_text = e_source_get_uri (source);
+	if (uri_text && strncmp (uri_text, "exchange", 8)) {
+		g_free (uri_text);
+		return;
+	}
+
+	status = exchange_is_offline (&offline_status);
+	if (offline_status == OFFLINE_MODE || status != CONFIG_LISTENER_STATUS_OK) {
+		g_free (uri_text);
+		return;
+	}
+
+	account = exchange_operations_get_exchange_account ();
+	if (!account || !is_exchange_personal_folder (account, uri_text))
+		return;
+
+	windows_domain = exchange_account_get_windows_domain (account);
+	if (windows_domain)
+		username = g_strdup_printf ("%s\\%s", windows_domain,
+					    exchange_account_get_username (account));
+	else
+		username = g_strdup (exchange_account_get_username (account));
+
+	authtype = exchange_account_get_authtype (account);
+
+	path_prefix = g_strconcat (account->account_filename, "/;", NULL);
+	prefix_len = strlen (path_prefix);
+	g_free (path_prefix);
+
+	/* FIXME: Compiler gives a warning here; review needed */
+	if (t->source_type == E_CAL_SOURCE_TYPE_EVENT) {
+		ftype = g_strdup ("calendar");
+	}
+	else if (t->source_type == E_CAL_SOURCE_TYPE_TODO) {
+		ftype = g_strdup ("tasks");
+	}
+	else {
+		/* FIXME: This one would ever occur? */
+		ftype = g_strdup ("mail");
+	}
+
+	gname = (gchar *) e_source_peek_name (source);
+	gruri = (gchar *) e_source_peek_relative_uri (source);
+
+	if (calendar_src_exists) {
+		gchar *tmpruri, *uri_string, *temp_path, *prefix;
+		EUri *euri;
+		gint uri_len;
+
+		/* sample uri_string: exchange://user;auth=NTLM host/ */
+		/* sample uri_text: exchange://user;auth=NTLM host/;personal/Calendar */
+
+		euri = e_uri_new (uri_text);
+		uri_string = e_uri_to_string (euri, FALSE);
+		e_uri_free (euri);
+
+		/* sample gruri: user;auth=NTLM host/;personal/Calendar */
+		/* sample ruri: user;auth=NTLM host/personal/Calendar */
+		/* sample path: /personal/Calendar */
+
+		uri_len = strlen (uri_string) + 1;
+		tmpruri = g_strdup (uri_string + strlen ("exchange://"));
+		temp_path = g_build_filename ("/", uri_text + uri_len, NULL);
+		prefix  = g_strndup (temp_path, strlen (temp_path) - strlen (g_strrstr (temp_path, "/")));
+		g_free (temp_path);
+		path = g_build_filename (prefix, "/", gname, NULL);
+		ruri = g_strconcat (tmpruri, ";", path+1, NULL);
+		oldpath = g_build_filename ("/", calendar_old_source_uri + prefix_len, NULL);
+		g_free (prefix);
+		g_free (uri_string);
+		g_free (tmpruri);
+	}
+	else {
+		/* new folder */
+		ruri = g_strconcat (gruri, "/", gname, NULL);
+		path = g_build_filename ("/", ruri+prefix_len, NULL);
+	}
+
+	if (!calendar_src_exists) {
+		/* Create the new folder */
+		result = exchange_account_create_folder (account, path, ftype);
+	}
+	else if (gruri && strcmp (path, oldpath)) {
+		/* Rename the folder */
+		rename = TRUE;
+		result = exchange_account_xfer_folder (account, oldpath, path, TRUE);
+	}
+	else {
+		/* Nothing happened specific to exchange; just return */
+		goto done;
+	}
+
+	switch (result) {
+	case EXCHANGE_ACCOUNT_FOLDER_OK:
+		if (result == EXCHANGE_ACCOUNT_FOLDER_OK) {
+			e_source_set_name (source, gname);
+			e_source_set_relative_uri (source, ruri);
+			e_source_set_property (source, "username", username);
+			e_source_set_property (source, "auth-domain", "Exchange");
+			if (authtype) {
+				e_source_set_property (source, "auth-type", authtype);
+				g_free (authtype);
+				authtype=NULL;
+			}
+			e_source_set_property (source, "auth", "1");
+			if (rename) {
+				exchange_operations_update_child_esources (source,
+							   calendar_old_source_uri,
+							   ruri);
+			}
+		}
+		break;
+	case EXCHANGE_ACCOUNT_FOLDER_ALREADY_EXISTS:
+		e_error_run (NULL, ERROR_DOMAIN ":folder-exists-error", NULL);
+		break;
+	case EXCHANGE_ACCOUNT_FOLDER_DOES_NOT_EXIST:
+		e_error_run (NULL, ERROR_DOMAIN ":folder-doesnt-exist-error", NULL);
+		break;
+	case EXCHANGE_ACCOUNT_FOLDER_UNKNOWN_TYPE:
+		e_error_run (NULL, ERROR_DOMAIN ":folder-unknown-type", NULL);
+		break;
+	case EXCHANGE_ACCOUNT_FOLDER_PERMISSION_DENIED:
+		e_error_run (NULL, ERROR_DOMAIN ":folder-perm-error", NULL);
+		break;
+	case EXCHANGE_ACCOUNT_FOLDER_OFFLINE:
+		e_error_run (NULL, ERROR_DOMAIN ":folder-offline-error", NULL);
+		break;
+	case EXCHANGE_ACCOUNT_FOLDER_UNSUPPORTED_OPERATION:
+		e_error_run (NULL, ERROR_DOMAIN ":folder-unsupported-error", NULL);
+		break;
+	case EXCHANGE_ACCOUNT_FOLDER_GENERIC_ERROR:
+		e_error_run (NULL, ERROR_DOMAIN ":folder-generic-error", NULL);
+		break;
+	default:
+		break;
+	}
+
+done:
+	g_free (uri_text);
+	g_free (username);
+	if (authtype)
+		g_free (authtype);
+	g_free (ruri);
+	g_free (path);
+	g_free (ftype);
+	g_free (oldpath);
+	g_free (calendar_old_source_uri);
+	calendar_old_source_uri = NULL;
+}
diff --git a/eplugin/exchange-change-password.c b/eplugin/exchange-change-password.c
new file mode 100644
index 0000000..68e93ab
--- /dev/null
+++ b/eplugin/exchange-change-password.c
@@ -0,0 +1,194 @@
+/*
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+/* exchange-change-password: Change Password code */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "exchange-change-password.h"
+
+#include <exchange-account.h>
+#include <e2k-utils.h>
+
+#include <gtk/gtk.h>
+
+static void
+entry_changed (GtkEntry *entry, gpointer user_data)
+{
+	GtkEntry *new_entry, *confirm_entry;
+	GtkDialog *pass_dialog;
+	const gchar *text;
+
+        new_entry = GTK_ENTRY (entry);
+        confirm_entry = GTK_ENTRY (user_data);
+	pass_dialog = GTK_DIALOG (g_object_get_data (G_OBJECT (new_entry), "pass_dialog"));
+
+	text = gtk_entry_get_text (new_entry);
+	if (!text || !*text) {
+		gtk_dialog_set_response_sensitive (pass_dialog, GTK_RESPONSE_OK, FALSE);
+		return;
+	}
+
+	text = gtk_entry_get_text (confirm_entry);
+	if (!text || !*text) {
+		gtk_dialog_set_response_sensitive (pass_dialog, GTK_RESPONSE_OK, FALSE);
+		return;
+	}
+
+	gtk_dialog_set_response_sensitive (pass_dialog, GTK_RESPONSE_OK, TRUE);
+}
+
+/**
+ * exchange_get_new_password:
+ * @existing_password: The user's current password
+ * @voluntary: %TRUE if the user has chosen "Change Password",
+ * %FALSE if their old password has expired.
+ *
+ * Prompt the user for a new password.
+ */
+gchar *
+exchange_get_new_password (const gchar *existing_password, gboolean voluntary)
+{
+	GtkResponseType response;
+	gchar *new_pass;
+	GtkWidget *pass_dialog;
+	GtkWidget *dialog_vbox1;
+	GtkWidget *pass_label;
+	GtkWidget *table1;
+	GtkWidget *current_pass_label;
+	GtkWidget *new_pass_label;
+	GtkWidget *confirm_pass_label;
+	GtkWidget *current_pass_entry;
+	GtkWidget *new_pass_entry;
+	GtkWidget *confirm_pass_entry;
+
+	pass_dialog = gtk_dialog_new_with_buttons (
+		_("Change Password"),
+		NULL,
+		GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
+		GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+		GTK_STOCK_OK, GTK_RESPONSE_OK,
+		NULL);
+
+	dialog_vbox1 = gtk_dialog_get_content_area (GTK_DIALOG (pass_dialog));
+	gtk_widget_show (dialog_vbox1);
+
+	pass_label = gtk_label_new (_("Your current password has expired. Please change your password now."));
+	gtk_widget_show (pass_label);
+	gtk_box_pack_start (GTK_BOX (dialog_vbox1), pass_label, FALSE, FALSE, 0);
+	gtk_label_set_justify (GTK_LABEL (pass_label), GTK_JUSTIFY_CENTER);
+	gtk_label_set_line_wrap (GTK_LABEL (pass_label), TRUE);
+	gtk_misc_set_alignment (GTK_MISC (pass_label), 0.52, 0.5);
+	gtk_misc_set_padding (GTK_MISC (pass_label), 0, 6);
+
+	table1 = gtk_table_new (3, 2, FALSE);
+	gtk_widget_show (table1);
+	gtk_box_pack_start (GTK_BOX (dialog_vbox1), table1, TRUE, TRUE, 0);
+	gtk_container_set_border_width (GTK_CONTAINER (table1), 6);
+	gtk_table_set_row_spacings (GTK_TABLE (table1), 6);
+	gtk_table_set_col_spacings (GTK_TABLE (table1), 6);
+
+	current_pass_label = gtk_label_new_with_mnemonic (_("Current _Password:"));
+	gtk_widget_show (current_pass_label);
+	gtk_table_attach (GTK_TABLE (table1), current_pass_label, 0, 1, 0, 1,
+			  (GtkAttachOptions) (GTK_FILL),
+			  (GtkAttachOptions) (0), 0, 0);
+	gtk_misc_set_alignment (GTK_MISC (current_pass_label), 0, 0.5);
+
+	new_pass_label = gtk_label_new_with_mnemonic (_("_New Password:"));
+	gtk_widget_show (new_pass_label);
+	gtk_table_attach (GTK_TABLE (table1), new_pass_label, 0, 1, 1, 2,
+			  (GtkAttachOptions) (GTK_FILL),
+			  (GtkAttachOptions) (0), 0, 0);
+	gtk_misc_set_alignment (GTK_MISC (new_pass_label), 0, 0.5);
+
+	confirm_pass_label = gtk_label_new_with_mnemonic (_("_Confirm Password:"));
+	gtk_widget_show (confirm_pass_label);
+	gtk_table_attach (GTK_TABLE (table1), confirm_pass_label, 0, 1, 2, 3,
+			  (GtkAttachOptions) (GTK_FILL),
+			  (GtkAttachOptions) (0), 0, 0);
+	gtk_misc_set_alignment (GTK_MISC (confirm_pass_label), 0, 0.5);
+
+	new_pass_entry = gtk_entry_new ();
+	gtk_widget_show (new_pass_entry);
+	gtk_table_attach (GTK_TABLE (table1), new_pass_entry, 1, 2, 1, 2,
+			  (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
+			  (GtkAttachOptions) (0), 0, 0);
+	gtk_entry_set_visibility (GTK_ENTRY (new_pass_entry), FALSE);
+
+	confirm_pass_entry = gtk_entry_new ();
+	gtk_widget_show (confirm_pass_entry);
+	gtk_table_attach (GTK_TABLE (table1), confirm_pass_entry, 1, 2, 2, 3,
+			  (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
+			  (GtkAttachOptions) (0), 0, 0);
+	gtk_entry_set_visibility (GTK_ENTRY (confirm_pass_entry), FALSE);
+
+	current_pass_entry = gtk_entry_new ();
+	gtk_widget_show (current_pass_entry);
+	gtk_table_attach (GTK_TABLE (table1), current_pass_entry, 1, 2, 0, 1,
+			  (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
+			  (GtkAttachOptions) (0), 0, 12);
+	gtk_entry_set_visibility (GTK_ENTRY (current_pass_entry), FALSE);
+
+	g_object_set_data (G_OBJECT (new_pass_entry), "pass_dialog", pass_dialog);
+	g_object_set_data (G_OBJECT (confirm_pass_entry), "pass_dialog", pass_dialog);
+	g_signal_connect (new_pass_entry, "changed", G_CALLBACK (entry_changed), confirm_pass_entry);
+	g_signal_connect (confirm_pass_entry, "changed", G_CALLBACK (entry_changed), new_pass_entry);
+	entry_changed (GTK_ENTRY (new_pass_entry), confirm_pass_entry);
+
+	if (voluntary)
+		gtk_widget_hide (GTK_WIDGET (pass_label));
+
+run_dialog_again:
+	response = gtk_dialog_run (GTK_DIALOG (pass_dialog));
+	if (response == GTK_RESPONSE_OK) {
+		const gchar *cur_pass, *new_pass1, *new_pass2;
+
+		cur_pass = gtk_entry_get_text (GTK_ENTRY (current_pass_entry));
+		new_pass1 = gtk_entry_get_text (GTK_ENTRY (new_pass_entry));
+		new_pass2 = gtk_entry_get_text (GTK_ENTRY (confirm_pass_entry));
+
+		if (existing_password) {
+			if (strcmp (cur_pass, existing_password) != 0) {
+				/* User entered a wrong existing
+				 * password. Prompt him again.
+				 */
+				gtk_label_set_text (GTK_LABEL (pass_label), _("The current password does not match the existing password for your account. Please enter the correct password"));
+				gtk_widget_show (pass_label);
+				goto run_dialog_again;
+			}
+		}
+
+		if (strcmp (new_pass1, new_pass2) != 0) {
+			gtk_label_set_text (GTK_LABEL (pass_label), _("The two passwords do not match. Please re-enter the passwords."));
+			gtk_widget_show (pass_label);
+			goto run_dialog_again;
+		}
+
+		new_pass = g_strdup (new_pass1);
+	} else
+		new_pass = NULL;
+
+	gtk_widget_destroy (pass_dialog);
+
+	return new_pass;
+}
diff --git a/eplugin/exchange-change-password.h b/eplugin/exchange-change-password.h
new file mode 100644
index 0000000..c33a887
--- /dev/null
+++ b/eplugin/exchange-change-password.h
@@ -0,0 +1,33 @@
+/*
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifndef __EXCHANGE_CHANGE_PASSWORD_H__
+#define __EXCHANGE_CHANGE_PASSWORD_H__
+
+#include <exchange-types.h>
+
+G_BEGIN_DECLS
+
+gchar *exchange_get_new_password (const gchar *existing_password,
+				 gboolean    voluntary);
+
+G_END_DECLS
+
+#endif /* __EXCHANGE_CHANGE_PASSWORD_H__ */
diff --git a/eplugin/exchange-config-listener.c b/eplugin/exchange-config-listener.c
new file mode 100644
index 0000000..dc6582b
--- /dev/null
+++ b/eplugin/exchange-config-listener.c
@@ -0,0 +1,1520 @@
+/*
+ * ExchangeConfigListener: a class that listens to the config database
+ * and handles creating the ExchangeAccount object and making sure that
+ * default folders are updated as needed.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <gtk/gtk.h>
+#include <gdk/gdkkeysyms.h>
+
+#include "exchange-config-listener.h"
+#include "exchange-operations.h"
+#include "exchange-change-password.h"
+
+#include <exchange-constants.h>
+#include <exchange-hierarchy.h>
+#include <exchange-oof.h>
+#include <e-folder-exchange.h>
+#include <e2k-marshal.h>
+#include <e2k-uri.h>
+#include <camel/camel-url.h>
+
+#include <e-util/e-error.h>
+
+#include <libedataserver/e-source.h>
+#include <libedataserver/e-source-list.h>
+#include <libedataserver/e-source-group.h>
+#include <libedataserverui/e-passwords.h>
+
+#include <stdlib.h>
+#include <string.h>
+
+struct _ExchangeConfigListenerPrivate {
+	GConfClient *gconf;
+	guint idle_id;
+
+	gchar *configured_uri, *configured_name;
+	EAccount *configured_account;
+
+	ExchangeAccount *exchange_account;
+};
+
+typedef struct {
+	const gchar *name;
+	const gchar *uri;
+	gint type;
+}FolderInfo;
+
+enum {
+	EXCHANGE_ACCOUNT_CREATED,
+	EXCHANGE_ACCOUNT_REMOVED,
+	LAST_SIGNAL
+};
+
+static guint signals [LAST_SIGNAL] = { 0 };
+
+#define PARENT_TYPE E_TYPE_ACCOUNT_LIST
+
+#define CONF_KEY_SELECTED_CAL_SOURCES "/apps/evolution/calendar/display/selected_calendars"
+#define CONF_KEY_SELECTED_TASKS_SOURCES "/apps/evolution/calendar/tasks/selected_tasks"
+
+static EAccountListClass *parent_class = NULL;
+
+static void dispose (GObject *object);
+static void finalize (GObject *object);
+
+static void account_added   (EAccountList *account_listener,
+			     EAccount     *account);
+static void account_changed (EAccountList *account_listener,
+			     EAccount     *account);
+static void account_removed (EAccountList *account_listener,
+			     EAccount     *account);
+#ifdef LDEAD
+static void exchange_add_autocompletion_folders (GConfClient *gc_client,
+						 ExchangeAccount *account);
+#endif
+static gboolean exchange_camel_urls_is_equal (const gchar *url1,
+					      const gchar *url2);
+static void remove_selected_non_offline_esources (ExchangeAccount *account,
+						  const gchar *gconf_key);
+static void
+class_init (GObjectClass *object_class)
+{
+	EAccountListClass *e_account_list_class =
+		E_ACCOUNT_LIST_CLASS (object_class);
+
+	parent_class = g_type_class_ref (PARENT_TYPE);
+
+	/* virtual method override */
+	object_class->dispose = dispose;
+	object_class->finalize = finalize;
+
+	e_account_list_class->account_added   = account_added;
+	e_account_list_class->account_changed = account_changed;
+	e_account_list_class->account_removed = account_removed;
+
+	/* signals */
+	signals[EXCHANGE_ACCOUNT_CREATED] =
+		g_signal_new ("exchange_account_created",
+			      G_OBJECT_CLASS_TYPE (object_class),
+			      G_SIGNAL_RUN_LAST,
+			      G_STRUCT_OFFSET (ExchangeConfigListenerClass, exchange_account_created),
+			      NULL, NULL,
+			      g_cclosure_marshal_VOID__POINTER,
+			      G_TYPE_NONE, 1,
+			      G_TYPE_POINTER);
+	signals[EXCHANGE_ACCOUNT_REMOVED] =
+		g_signal_new ("exchange_account_removed",
+			      G_OBJECT_CLASS_TYPE (object_class),
+			      G_SIGNAL_RUN_LAST,
+			      G_STRUCT_OFFSET (ExchangeConfigListenerClass, exchange_account_removed),
+			      NULL, NULL,
+			      g_cclosure_marshal_VOID__POINTER,
+			      G_TYPE_NONE, 1,
+			      G_TYPE_POINTER);
+}
+
+static void
+init (GObject *object)
+{
+	ExchangeConfigListener *config_listener =
+		EXCHANGE_CONFIG_LISTENER (object);
+
+	config_listener->priv = g_new0 (ExchangeConfigListenerPrivate, 1);
+}
+
+static void
+dispose (GObject *object)
+{
+	ExchangeConfigListener *config_listener =
+		EXCHANGE_CONFIG_LISTENER (object);
+
+	if (config_listener->priv->idle_id) {
+		g_source_remove (config_listener->priv->idle_id);
+		config_listener->priv->idle_id = 0;
+	}
+
+	if (config_listener->priv->gconf) {
+		g_object_unref (config_listener->priv->gconf);
+		config_listener->priv->gconf = NULL;
+	}
+
+	G_OBJECT_CLASS (parent_class)->dispose (object);
+}
+
+static void
+finalize (GObject *object)
+{
+	ExchangeConfigListener *config_listener =
+		EXCHANGE_CONFIG_LISTENER (object);
+
+	g_free (config_listener->priv->configured_name);
+	g_free (config_listener->priv->configured_uri);
+	g_free (config_listener->priv);
+
+	G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+E2K_MAKE_TYPE (exchange_config_listener, ExchangeConfigListener, class_init, init, PARENT_TYPE)
+
+#define EVOLUTION_URI_PREFIX     "evolution:/"
+#define EVOLUTION_URI_PREFIX_LEN (sizeof (EVOLUTION_URI_PREFIX) - 1)
+
+static EFolder *
+standard_folder (ExchangeAccount *account, const gchar *folder_type)
+{
+	const gchar *uri;
+
+	uri = exchange_account_get_standard_uri (account, folder_type);
+	if (!uri)
+		return NULL;
+	return exchange_account_get_folder (account, uri);
+}
+
+static void
+set_special_mail_folder (ExchangeAccount *account, const gchar *folder_type,
+			 gchar **folder_uri)
+{
+	EFolder *folder;
+	const gchar *physical_uri;
+	gchar *url_string, *path;
+	CamelURL *camel_url;
+	gint uri_len;
+
+	folder = standard_folder (account, folder_type);
+	if (!folder)
+		return;
+	physical_uri = e_folder_get_physical_uri (folder);
+
+	/* remove; form the uri */
+	camel_url = camel_url_new (physical_uri, NULL);
+	url_string = camel_url_to_string (camel_url, CAMEL_URL_HIDE_ALL);
+	camel_url_free (camel_url);
+	/* sample physical uri: exchange://pnayak;auth=NTLM 164 99 168 136/;personal/Drafts */
+	/* sample url_string: exchange://pnayak;auth=NTLM 164 99 168 136/ */
+	/* sample path:  personal/Drafts */
+	uri_len = strlen (url_string) + 1;
+	path = g_build_filename (physical_uri + uri_len, NULL);
+	*folder_uri = g_strconcat (url_string, path, NULL);
+	g_free (path);
+	g_free (url_string);
+}
+
+static void
+add_defaults_for_account (ExchangeConfigListener *config_listener,
+			  E2kContext *ctx,
+			  ExchangeAccount *account)
+{
+	EAccount *eaccount;
+	gboolean save = FALSE;
+
+#ifdef LDEAD
+	exchange_add_autocompletion_folders (config_listener->priv->gconf, account);
+#endif
+
+	/* FIXME: set exchange account's sent items and drafts folders, by default */
+	eaccount = config_listener->priv->configured_account;
+	if (!e_account_get_string (eaccount, E_ACCOUNT_DRAFTS_FOLDER_URI)) {
+		set_special_mail_folder (account, "drafts",
+					 &eaccount->drafts_folder_uri);
+		save = TRUE;
+	}
+	if (!e_account_get_string (eaccount, E_ACCOUNT_SENT_FOLDER_URI)) {
+		set_special_mail_folder (account, "sentitems",
+					 &eaccount->sent_folder_uri);
+		save = TRUE;
+	}
+	if (save) {
+		e_account_list_change (E_ACCOUNT_LIST (config_listener), eaccount);
+		e_account_list_save (E_ACCOUNT_LIST (config_listener));
+	}
+}
+
+static gboolean
+is_active_exchange_account (EAccount *account)
+{
+	if (!account->enabled)
+		return FALSE;
+	if (!account->source || !account->source->url)
+		return FALSE;
+	return (strncmp (account->source->url, EXCHANGE_URI_PREFIX, 11) == 0);
+}
+
+#if 0 /* Not using the following code anywhere for the moment */
+static void
+add_account_esources (ExchangeAccount *account,
+		      GSList *folders)
+{
+	ESource *source = NULL;
+	ESourceGroup *cal_source_group = NULL;
+	ESourceGroup *tasks_source_group = NULL;
+	ESourceGroup *contacts_source_group = NULL;
+	gchar *relative_uri = NULL, *username = NULL;
+#if 0
+	GSList *ids;
+#endif
+	GConfClient *client;
+	gint mode;
+	ESourceList *cal_source_list, *tasks_source_list, *contacts_source_list;
+	FolderInfo *folder=NULL;
+	gboolean offline_mode = FALSE;
+
+	client = gconf_client_get_default ();
+
+	cal_source_list = e_source_list_new_for_gconf ( client, CONF_KEY_CAL);
+	tasks_source_list = e_source_list_new_for_gconf ( client, CONF_KEY_TASKS);
+	contacts_source_list = e_source_list_new_for_gconf ( client, CONF_KEY_CONTACTS);
+
+	exchange_account_is_offline_sync_set (account, &mode);
+	if (mode == OFFLINE_MODE) {
+		/* If account is marked for offline sync during account
+		 * creation, mark all the folders for offline sync
+		 */
+		offline_mode = TRUE;
+	}
+
+	username = exchange_account_get_username (account);
+
+	/* For each component create a source group */
+
+	cal_source_group = e_source_group_new (account->account_name,
+					       EXCHANGE_URI_PREFIX);
+	tasks_source_group = e_source_group_new (account->account_name,
+						 EXCHANGE_URI_PREFIX);
+	contacts_source_group = e_source_group_new (account->account_name,
+						    EXCHANGE_URI_PREFIX);
+
+	if (!e_source_list_add_group (contacts_source_list, contacts_source_group, -1) ||
+	    !e_source_list_add_group (cal_source_list, cal_source_group, -1) ||
+	    !e_source_list_add_group (tasks_source_list, tasks_source_group, -1)) {
+		goto done;
+	}
+	for (; folders != NULL; folders = g_slist_next (folders)) {
+		/* Create source for each folder and add to the group */
+
+		folder = folders->data;
+		if (folder->type == EXCHANGE_CONTACTS_FOLDER) {
+			source = e_source_new_with_absolute_uri (folder->name,
+								 folder->uri);
+			if (offline_mode)
+				e_source_set_property (source, "offline_sync", "1");
+			if (username)
+				e_source_set_property (source, "username", username);
+			e_source_set_property (source, "auth", "1");
+			e_source_set_property (source, "auth-domain", "Exchange");
+			e_source_group_add_source (contacts_source_group,
+						   source, -1);
+			g_object_unref (source);
+		}
+		else if (folder->type == EXCHANGE_CALENDAR_FOLDER) {
+			relative_uri = g_strdup (folder->uri +
+						 strlen (EXCHANGE_URI_PREFIX));
+			source = e_source_new (folder->name, relative_uri);
+			if (offline_mode)
+				e_source_set_property (source, "offline_sync", "1");
+			if (username)
+				e_source_set_property (source, "username", username);
+			e_source_set_property (source, "auth", "1");
+			e_source_set_property (source, "auth-domain", "Exchange");
+			e_source_group_add_source (cal_source_group,
+						   source, -1);
+#if 0
+			ids = gconf_client_get_list (client,
+						     CONF_KEY_SELECTED_CAL_SOURCES,
+						     GCONF_VALUE_STRING, NULL);
+			ids = g_slist_append (ids,
+					      g_strdup (e_source_peek_uid (source)));
+			gconf_client_set_list (client,
+					       CONF_KEY_SELECTED_CAL_SOURCES,
+					       GCONF_VALUE_STRING, ids, NULL);
+			g_slist_foreach (ids, (GFunc) g_free, NULL);
+			g_slist_free (ids);
+#endif
+			g_object_unref (source);
+			g_free (relative_uri);
+
+		}
+		else if (folder->type == EXCHANGE_TASKS_FOLDER) {
+			relative_uri = g_strdup (folder->uri +
+						 strlen (EXCHANGE_URI_PREFIX));
+			source = e_source_new (folder->name, relative_uri);
+			if (offline_mode == ONLINE_MODE)
+				e_source_set_property (source, "offline_sync", "1");
+			if (username)
+				e_source_set_property (source, "username", username);
+			e_source_set_property (source, "auth", "1");
+			e_source_set_property (source, "auth-domain", "Exchange");
+			e_source_group_add_source (tasks_source_group,
+						   source, -1);
+#if 0
+			ids = gconf_client_get_list (client,
+						     CONF_KEY_SELECTED_TASKS_SOURCES,
+						     GCONF_VALUE_STRING, NULL);
+			ids = g_slist_append (ids,
+					      g_strdup (e_source_peek_uid (source)));
+			gconf_client_set_list (client,
+					       CONF_KEY_SELECTED_TASKS_SOURCES,
+					       GCONF_VALUE_STRING, ids, NULL);
+			g_slist_foreach (ids, (GFunc) g_free, NULL);
+			g_slist_free (ids);
+#endif
+			g_object_unref (source);
+			g_free (relative_uri);
+		}
+	}
+
+	e_source_list_sync (cal_source_list, NULL);
+	e_source_list_sync (tasks_source_list, NULL);
+	e_source_list_sync (contacts_source_list, NULL);
+
+done:
+	g_object_unref (cal_source_group);
+	g_object_unref (tasks_source_group);
+	g_object_unref (contacts_source_group);
+
+	g_object_unref (cal_source_list);
+	g_object_unref (tasks_source_list);
+	g_object_unref (contacts_source_list);
+
+	g_object_unref (client);
+}
+
+static void
+add_new_sources (ExchangeAccount *account)
+{
+	GPtrArray *exchange_folders;
+
+	exchange_folders = exchange_account_get_folders (account);
+        if (exchange_folders && exchange_folders->len > 0) {
+		gint i;
+		const gchar *folder_type;
+		const gchar *folder_name;
+		const gchar *folder_uri;
+		gint type;
+		EFolder *folder;
+		ExchangeHierarchy *hier;
+		gboolean create_esource = FALSE;
+
+		for (i = 0; i < exchange_folders->len; i++) {
+
+			folder = exchange_folders->pdata[i];
+			hier = e_folder_exchange_get_hierarchy (folder);
+			if (hier->type != EXCHANGE_HIERARCHY_PUBLIC) {
+				folder_name = e_folder_get_name (folder);
+				folder_uri = e_folder_get_physical_uri (folder);
+				folder_type = e_folder_get_type_string (folder);
+
+				if (!(strcmp (folder_type, "calendar")) ||
+				    !(strcmp (folder_type, "calendar/public"))) {
+						type = EXCHANGE_CALENDAR_FOLDER;
+						create_esource = TRUE;
+				}
+				else if (!(strcmp (folder_type, "tasks")) ||
+					 !(strcmp (folder_type, "tasks/public"))) {
+						type = EXCHANGE_TASKS_FOLDER;
+						create_esource = TRUE;
+				}
+				else if (!(strcmp (folder_type, "contacts")) ||
+					 !(strcmp (folder_type, "contacts/public")) ||
+					 !(strcmp (folder_type, "contacts/ldap"))) {
+						type = EXCHANGE_CONTACTS_FOLDER;
+						create_esource = TRUE;
+				}
+				else {
+					create_esource = FALSE;
+				}
+
+				if (create_esource)
+					add_folder_esource (account, type,
+							folder_name, folder_uri);
+			} /* End hierarchy type check */
+		} /* End for loop */
+        } /* End check for a list of folders */
+}
+
+static void
+add_sources (ExchangeAccount *account)
+{
+	GPtrArray *exchange_folders;
+
+	exchange_folders = exchange_account_get_folders (account);
+        if (exchange_folders && exchange_folders->len > 0) {
+		gint i;
+		const gchar *folder_type;
+		EFolder *folder;
+		GSList *folders = NULL;
+
+		for (i = 0; i < exchange_folders->len; i++) {
+			FolderInfo *folder_info = g_new0 (FolderInfo, 1);
+
+			folder = exchange_folders->pdata[i];
+			folder_type = e_folder_get_type_string (folder);
+
+			if (!(strcmp (folder_type, "calendar")) ||
+			    !(strcmp (folder_type, "calendar/public"))) {
+				folder_info->name = e_folder_get_name (folder);
+				folder_info->uri = e_folder_get_physical_uri (folder);
+				folder_info->type = EXCHANGE_CALENDAR_FOLDER;
+				folders = g_slist_append (folders, folder_info);
+			}
+			else if (!(strcmp (folder_type, "tasks")) ||
+				 !(strcmp (folder_type, "tasks/public"))) {
+				folder_info->name = e_folder_get_name (folder);
+				folder_info->uri = e_folder_get_physical_uri (folder);
+				folder_info->type = EXCHANGE_TASKS_FOLDER;
+				folders = g_slist_append (folders, folder_info);
+			}
+			else if (!(strcmp (folder_type, "contacts")) ||
+				 !(strcmp (folder_type, "contacts/public")) ||
+				 !(strcmp (folder_type, "contacts/ldap"))) {
+				folder_info->name = e_folder_get_name (folder);
+				folder_info->uri = e_folder_get_physical_uri (folder);
+				folder_info->type = EXCHANGE_CONTACTS_FOLDER;
+				folders = g_slist_append (folders, folder_info);
+			}
+			else
+				g_free (folder_info);
+		}
+		/* Add e-sources for all the folders */
+		add_account_esources (account, folders);
+		g_slist_foreach (folders, (GFunc) g_free, NULL);
+		g_slist_free (folders);
+        }
+}
+#endif
+
+static void
+remove_account_esource (ExchangeAccount *account,
+			FolderType folder_type)
+{
+	ESourceGroup *group;
+	ESource *source = NULL;
+	GSList *groups;
+	GSList *sources;
+	GSList *ids, *node_to_be_deleted;
+	gboolean found_group;
+	const gchar *source_uid;
+	GConfClient *client;
+	ESourceList *source_list = NULL;
+
+	/* Remove the ESource group, to remove all the folders in a component */
+
+	client = gconf_client_get_default ();
+
+	if (folder_type == EXCHANGE_CONTACTS_FOLDER)
+		source_list = e_source_list_new_for_gconf ( client,
+							CONF_KEY_CONTACTS);
+	else if (folder_type == EXCHANGE_CALENDAR_FOLDER)
+		source_list = e_source_list_new_for_gconf ( client,
+							CONF_KEY_CAL);
+	else if (folder_type == EXCHANGE_TASKS_FOLDER)
+		source_list = e_source_list_new_for_gconf ( client,
+							CONF_KEY_TASKS);
+
+	groups = e_source_list_peek_groups (source_list);
+	found_group = FALSE;
+
+	for (; groups != NULL && !found_group; groups = g_slist_next (groups)) {
+		group = E_SOURCE_GROUP (groups->data);
+
+		if (strcmp (e_source_group_peek_name (group), account->account_name) == 0
+                    &&
+                    strcmp (e_source_group_peek_base_uri (group), EXCHANGE_URI_PREFIX) == 0) {
+			sources = e_source_group_peek_sources (group);
+
+			for (; sources != NULL; sources = g_slist_next (sources)) {
+				source = E_SOURCE (sources->data);
+				source_uid = e_source_peek_uid (source);
+
+				/* Remove from the selected folders */
+				if (folder_type == EXCHANGE_CALENDAR_FOLDER) {
+					ids = gconf_client_get_list (
+							client,
+							CONF_KEY_SELECTED_CAL_SOURCES ,
+							GCONF_VALUE_STRING, NULL);
+					if (ids) {
+						node_to_be_deleted = g_slist_find_custom (
+									ids,
+									source_uid,
+									(GCompareFunc) strcmp);
+						if (node_to_be_deleted) {
+							g_free (node_to_be_deleted->data);
+							ids = g_slist_delete_link (ids,
+									node_to_be_deleted);
+							gconf_client_set_list (client,
+								CONF_KEY_SELECTED_CAL_SOURCES,
+								GCONF_VALUE_STRING, ids, NULL);
+						}
+						g_slist_foreach (ids, (GFunc) g_free, NULL);
+						g_slist_free (ids);
+					}
+				}
+				else if (folder_type == EXCHANGE_TASKS_FOLDER) {
+					ids = gconf_client_get_list (client,
+								CONF_KEY_SELECTED_TASKS_SOURCES ,
+								GCONF_VALUE_STRING, NULL);
+					if (ids) {
+						node_to_be_deleted = g_slist_find_custom (
+									ids,
+									source_uid,
+									(GCompareFunc) strcmp);
+						if (node_to_be_deleted) {
+							g_free (node_to_be_deleted->data);
+							ids = g_slist_delete_link (ids,
+									node_to_be_deleted);
+							gconf_client_set_list (client,
+								CONF_KEY_SELECTED_TASKS_SOURCES,
+								GCONF_VALUE_STRING, ids, NULL);
+						}
+						g_slist_foreach (ids, (GFunc) g_free, NULL);
+						g_slist_free (ids);
+					}
+				}
+			}
+			e_source_list_remove_group (source_list, group);
+			e_source_list_sync (source_list, NULL);
+			found_group = TRUE;
+		}
+	}
+	g_object_unref (source_list);
+	g_object_unref (client);
+}
+
+static void
+remove_account_esources (ExchangeAccount *account)
+{
+	/* Remove ESources for all the folders in all the components */
+
+	remove_account_esource (account, EXCHANGE_CALENDAR_FOLDER);
+	remove_account_esource (account, EXCHANGE_TASKS_FOLDER);
+	remove_account_esource (account, EXCHANGE_CONTACTS_FOLDER);
+}
+
+#ifdef HAVE_KRB5
+static gchar *
+get_new_exchange_password (ExchangeAccount *account)
+{
+	gchar *old_password, *new_password;
+
+	old_password = exchange_account_get_password (account);
+	new_password = exchange_get_new_password (old_password, 0);
+
+	if (new_password) {
+		exchange_account_set_password (account,
+					       old_password,
+					       new_password);
+		g_free (old_password);
+		return new_password;
+	}
+	g_free (old_password);
+	return NULL;
+}
+#endif
+
+#ifdef HAVE_KRB5
+static void
+change_passwd_cb (GtkWidget *button, ExchangeAccount *account)
+{
+	gchar *current_passwd, *new_passwd;
+
+	gtk_widget_hide (gtk_widget_get_toplevel(button));
+	current_passwd = exchange_account_get_password (account);
+	new_passwd = exchange_get_new_password (current_passwd, TRUE);
+	exchange_account_set_password (account, current_passwd, new_passwd);
+	g_free (current_passwd);
+	g_free (new_passwd);
+}
+#endif
+
+static void
+display_passwd_expiry_message (gint max_passwd_age, ExchangeAccount *account)
+{
+	GtkResponseType response;
+	GtkWidget *passwd_exp_dialog;
+	GtkWidget *dialog_vbox1;
+	GtkWidget *dialog_action_area1;
+	GtkWidget *change_passwd_button;
+	GtkWidget *warning_msg_label;
+	GtkWidget *ok_button;
+	AtkObject *atko;
+	gchar *passwd_expiry_msg =
+		g_strdup_printf (_("Your password will expire in the next %d days"), max_passwd_age);
+
+
+	passwd_exp_dialog = gtk_dialog_new ();
+	gtk_window_set_title (GTK_WINDOW (passwd_exp_dialog), _("Password Expiry Warning..."));
+	gtk_window_set_position (GTK_WINDOW (passwd_exp_dialog), GTK_WIN_POS_CENTER_ON_PARENT);
+	gtk_window_set_type_hint (GTK_WINDOW (passwd_exp_dialog), GDK_WINDOW_TYPE_HINT_DIALOG);
+
+	dialog_vbox1 = gtk_dialog_get_content_area (GTK_DIALOG (passwd_exp_dialog));
+	gtk_widget_show (dialog_vbox1);
+
+	warning_msg_label = gtk_label_new (passwd_expiry_msg);
+	gtk_widget_show (warning_msg_label);
+	gtk_box_pack_start (GTK_BOX (dialog_vbox1), warning_msg_label, FALSE, FALSE, 0);
+	gtk_label_set_justify (GTK_LABEL (warning_msg_label), GTK_JUSTIFY_CENTER);
+	gtk_misc_set_padding (GTK_MISC (warning_msg_label), 0, 20);
+
+	dialog_action_area1 = gtk_dialog_get_action_area (GTK_DIALOG (passwd_exp_dialog));
+	gtk_widget_show (dialog_action_area1);
+	gtk_button_box_set_layout (GTK_BUTTON_BOX (dialog_action_area1), GTK_BUTTONBOX_END);
+
+	change_passwd_button = gtk_button_new_with_mnemonic (_("_Change Password"));
+	gtk_widget_show (change_passwd_button);
+	gtk_dialog_add_action_widget (GTK_DIALOG (passwd_exp_dialog), change_passwd_button, 0);
+	GTK_WIDGET_SET_FLAGS (change_passwd_button, GTK_CAN_DEFAULT);
+
+	ok_button = gtk_button_new_from_stock ("gtk-ok");
+	gtk_widget_show (ok_button);
+	gtk_dialog_add_action_widget (GTK_DIALOG (passwd_exp_dialog), ok_button, GTK_RESPONSE_OK);
+	GTK_WIDGET_SET_FLAGS (ok_button, GTK_CAN_DEFAULT);
+
+	atko = gtk_widget_get_accessible (ok_button);
+	atk_object_set_name (atko, "ok_button");
+
+	gtk_widget_grab_focus (change_passwd_button);
+	gtk_widget_grab_default (change_passwd_button);
+
+	gtk_widget_set_sensitive (change_passwd_button, TRUE);
+#ifdef HAVE_KRB5
+	g_signal_connect (change_passwd_button,
+			  "clicked",
+			  G_CALLBACK (change_passwd_cb),
+			  account);
+#endif
+	response = gtk_dialog_run (GTK_DIALOG (passwd_exp_dialog));
+
+	gtk_widget_destroy (passwd_exp_dialog);
+	g_free (passwd_expiry_msg);
+}
+
+static gint
+run_oof_dialog (void)
+{
+	GtkWidget *oof_dialog;
+	GtkWidget *dialog_vbox1;
+	GtkWidget *hbox9;
+	GtkWidget *image3;
+	GtkWidget *label7;
+	GtkWidget *dialog_action_area1;
+	GtkWidget *button3;
+	GtkWidget *alignment3;
+	GtkWidget *hbox6;
+	GtkWidget *image7;
+	GtkWidget *label10;
+	GtkWidget *button4;
+	GtkWidget *alignment4;
+	GtkWidget *hbox7;
+	GtkWidget *image8;
+	GtkWidget *label11;
+	gchar *tmp_str;
+	gint res;
+
+	oof_dialog = gtk_dialog_new ();
+	gtk_container_set_border_width (GTK_CONTAINER (oof_dialog), 6);
+	gtk_window_set_title (GTK_WINDOW (oof_dialog), _("Out of Office Assistant"));
+	gtk_window_set_position (GTK_WINDOW (oof_dialog), GTK_WIN_POS_CENTER_ON_PARENT);
+	gtk_window_set_resizable (GTK_WINDOW (oof_dialog), FALSE);
+	gtk_window_set_type_hint (GTK_WINDOW (oof_dialog), GDK_WINDOW_TYPE_HINT_DIALOG);
+
+	dialog_vbox1 = gtk_dialog_get_content_area (GTK_DIALOG (oof_dialog));
+	gtk_widget_show (dialog_vbox1);
+
+	hbox9 = gtk_hbox_new (FALSE, 6);
+	gtk_widget_show (hbox9);
+	gtk_box_pack_start (GTK_BOX (dialog_vbox1), hbox9, TRUE, TRUE, 0);
+	gtk_container_set_border_width (GTK_CONTAINER (hbox9), 6);
+
+	image3 = gtk_image_new_from_stock ("gtk-dialog-question", GTK_ICON_SIZE_DIALOG);
+	gtk_widget_show (image3);
+	gtk_box_pack_start (GTK_BOX (hbox9), image3, FALSE, TRUE, 0);
+
+	tmp_str = g_strconcat ("<b>", _("Currently, your status is \"Out of the Office\"."), "</b>\n\n", _("Would you like to change your status to \"In the Office\"?"), NULL);
+	label7 = gtk_label_new (tmp_str);
+	g_free (tmp_str);
+	gtk_widget_show (label7);
+	gtk_box_pack_start (GTK_BOX (hbox9), label7, TRUE, TRUE, 0);
+	gtk_label_set_use_markup (GTK_LABEL (label7), TRUE);
+	gtk_misc_set_alignment (GTK_MISC (label7), 0, 0.5);
+
+	dialog_action_area1 = gtk_dialog_get_action_area (GTK_DIALOG (oof_dialog));
+	gtk_widget_show (dialog_action_area1);
+	gtk_button_box_set_layout (GTK_BUTTON_BOX (dialog_action_area1), GTK_BUTTONBOX_END);
+
+	button3 = gtk_button_new ();
+	gtk_widget_show (button3);
+	gtk_dialog_add_action_widget (GTK_DIALOG (oof_dialog), button3, GTK_RESPONSE_NO);
+	GTK_WIDGET_SET_FLAGS (button3, GTK_CAN_DEFAULT);
+
+	alignment3 = gtk_alignment_new (0.5, 0.5, 0, 0);
+	gtk_widget_show (alignment3);
+	gtk_container_add (GTK_CONTAINER (button3), alignment3);
+
+	hbox6 = gtk_hbox_new (FALSE, 2);
+	gtk_widget_show (hbox6);
+	gtk_container_add (GTK_CONTAINER (alignment3), hbox6);
+
+	image7 = gtk_image_new_from_stock ("gtk-no", GTK_ICON_SIZE_BUTTON);
+	gtk_widget_show (image7);
+	gtk_box_pack_start (GTK_BOX (hbox6), image7, FALSE, FALSE, 0);
+
+	label10 = gtk_label_new_with_mnemonic (_("_No, Don't Change Status"));
+	gtk_widget_show (label10);
+	gtk_box_pack_start (GTK_BOX (hbox6), label10, FALSE, FALSE, 0);
+
+	button4 = gtk_button_new ();
+	gtk_widget_show (button4);
+	gtk_dialog_add_action_widget (GTK_DIALOG (oof_dialog), button4, GTK_RESPONSE_YES);
+	GTK_WIDGET_SET_FLAGS (button4, GTK_CAN_DEFAULT);
+
+	alignment4 = gtk_alignment_new (0.5, 0.5, 0, 0);
+	gtk_widget_show (alignment4);
+	gtk_container_add (GTK_CONTAINER (button4), alignment4);
+
+	hbox7 = gtk_hbox_new (FALSE, 2);
+	gtk_widget_show (hbox7);
+	gtk_container_add (GTK_CONTAINER (alignment4), hbox7);
+
+	image8 = gtk_image_new_from_stock ("gtk-yes", GTK_ICON_SIZE_BUTTON);
+	gtk_widget_show (image8);
+	gtk_box_pack_start (GTK_BOX (hbox7), image8, FALSE, FALSE, 0);
+
+	label11 = gtk_label_new_with_mnemonic (_("_Yes, Change Status"));
+	gtk_widget_show (label11);
+	gtk_box_pack_start (GTK_BOX (hbox7), label11, FALSE, FALSE, 0);
+
+	res = gtk_dialog_run (GTK_DIALOG (oof_dialog));
+	gtk_widget_destroy (oof_dialog);
+
+	return res;
+}
+
+ExchangeAccountResult
+exchange_config_listener_authenticate (ExchangeConfigListener *ex_conf_listener, ExchangeAccount *account)
+{
+	ExchangeConfigListenerPrivate *priv;
+	ExchangeAccountResult result;
+	gchar *key, *password, *title, *url_string;
+#ifdef HAVE_KRB5
+	gchar *new_password;
+#endif
+	gboolean oldremember, remember = FALSE;
+	CamelURL *camel_url;
+	const gchar *remember_password;
+
+	g_return_val_if_fail (EXCHANGE_IS_CONFIG_LISTENER (ex_conf_listener), EXCHANGE_ACCOUNT_CONFIG_ERROR);
+	priv = ex_conf_listener->priv;
+
+	camel_url = camel_url_new (priv->configured_uri, NULL);
+	key = camel_url_to_string (camel_url, CAMEL_URL_HIDE_PASSWORD | CAMEL_URL_HIDE_PARAMS);
+	remember_password = camel_url_get_param (camel_url, "save-passwd");
+	password = e_passwords_get_password ("Exchange", key);
+	if (!password) {
+		oldremember = remember = exchange_account_is_save_password (account);
+		title = g_strdup_printf (_("Enter Password for %s"), account->account_name);
+		password = e_passwords_ask_password (title, "Exchange", key, title,
+						     E_PASSWORDS_REMEMBER_FOREVER|E_PASSWORDS_SECRET,
+						     &remember, NULL);
+		if (remember != oldremember) {
+			exchange_account_set_save_password (account, remember);
+			camel_url_set_param (camel_url, "save-passwd", remember? "true" : "false");
+			url_string = camel_url_to_string (camel_url, 0);
+			e_account_set_string (ex_conf_listener->priv->configured_account, E_ACCOUNT_SOURCE_URL, url_string);
+			e_account_set_string (ex_conf_listener->priv->configured_account, E_ACCOUNT_TRANSPORT_URL, url_string);
+			e_account_set_bool (ex_conf_listener->priv->configured_account, E_ACCOUNT_SOURCE_SAVE_PASSWD, remember);
+			e_account_list_change (E_ACCOUNT_LIST (ex_conf_listener), ex_conf_listener->priv->configured_account);
+			e_account_list_save (E_ACCOUNT_LIST (ex_conf_listener));
+			g_free (url_string);
+		}
+		g_free (title);
+	}
+	else if (remember_password && !g_ascii_strcasecmp (remember_password, "false")) {
+		/* get_password returns the password cached but user has not
+		 * selected remember password option, forget this password
+		 * whis is stored temporarily by e2k_validate_user(), to avoid
+		 * asking for password again, at the end of account creation.
+		 */
+		e_passwords_forget_password ("Exchange", key);
+		exchange_account_set_save_password (account, FALSE);
+	}
+
+	exchange_account_connect (account, password, &result);
+
+	g_free (password);
+	g_free (key);
+	camel_url_free (camel_url);
+
+	if (result == EXCHANGE_ACCOUNT_PASSWORD_EXPIRED) {
+#ifdef HAVE_KRB5
+		new_password = get_new_exchange_password (account);
+		if (new_password) {
+			/* try connecting with new password */
+			exchange_account_connect (account, new_password, &result);
+			g_free (new_password);
+		}
+#endif
+	}
+	else if (result == EXCHANGE_ACCOUNT_QUOTA_RECIEVE_ERROR ||
+		 result == EXCHANGE_ACCOUNT_QUOTA_SEND_ERROR ||
+		 result == EXCHANGE_ACCOUNT_QUOTA_WARN) {
+		gchar *current_quota_usage = NULL;
+		const gchar *error_code = NULL;
+		GtkWidget *widget;
+
+		switch (result) {
+			case EXCHANGE_ACCOUNT_QUOTA_RECIEVE_ERROR:
+				current_quota_usage = g_strdup_printf ("%.2f",
+							account->mbox_size);
+				error_code = "org-gnome-exchange-operations:account-quota-error";
+				break;
+			case EXCHANGE_ACCOUNT_QUOTA_SEND_ERROR:
+				current_quota_usage = g_strdup_printf ("%.2f",
+							account->mbox_size);
+				error_code = "org-gnome-exchange-operations:account-quota-send-error";
+				break;
+			case EXCHANGE_ACCOUNT_QUOTA_WARN:
+				current_quota_usage = g_strdup_printf ("%.2f",
+							account->mbox_size);
+				error_code = "org-gnome-exchange-operations:account-quota-warn";
+				break;
+			default:
+				break;
+		}
+
+		if (current_quota_usage) {
+			widget = e_error_new (NULL, error_code, current_quota_usage, NULL);
+			g_signal_connect ((GtkDialog *)widget, "response",
+					  G_CALLBACK (gtk_widget_destroy), widget);
+			gtk_widget_show (widget);
+			g_free (current_quota_usage);
+		}
+
+		/* reset result, so that we check if the password
+		 * expiry warning period
+		 */
+		result = EXCHANGE_ACCOUNT_CONNECT_SUCCESS;
+	}
+	if (result == EXCHANGE_ACCOUNT_CONNECT_SUCCESS) {
+		gint max_pwd_age_days;
+		gboolean oof;
+
+		/* check for password expiry warning */
+		max_pwd_age_days = exchange_account_check_password_expiry (account);
+		if (max_pwd_age_days >= 0) {
+			display_passwd_expiry_message (max_pwd_age_days, account);
+		}
+
+		/* check for oof state */
+		if (exchange_oof_get (account, &oof, NULL)) {
+			if (oof) {
+				/* OOF state is set, check if user wants to set it back to in-office */
+				if (run_oof_dialog () == GTK_RESPONSE_YES)
+					if (!exchange_oof_set (account, FALSE, NULL))
+						e_error_run (NULL, "org-gnome-exchange-operations:state-update-error", NULL);
+			}
+		}
+	}
+	return result;
+}
+
+static void
+account_added (EAccountList *account_list, EAccount *account)
+{
+	ExchangeConfigListener *config_listener;
+	ExchangeAccount *exchange_account;
+	gint is_offline;
+
+	if (!is_active_exchange_account (account))
+		return;
+
+	config_listener = EXCHANGE_CONFIG_LISTENER (account_list);
+	if (config_listener->priv->configured_account) {
+		/* Multiple accounts configured. */
+		e_error_run (NULL, "org-gnome-exchange-operations:single-account-error", NULL);
+		return;
+	}
+
+	/* New account! Yippee! */
+	exchange_account = exchange_account_new (account_list, account);
+	if (!exchange_account) {
+		g_warning ("Could not parse exchange uri '%s'",
+			   account->source->url);
+		return;
+	}
+
+	config_listener->priv->exchange_account = exchange_account;
+	config_listener->priv->configured_account = account;
+
+	g_free (config_listener->priv->configured_uri);
+	config_listener->priv->configured_uri = g_strdup (account->source->url);
+	g_free (config_listener->priv->configured_name);
+	config_listener->priv->configured_name = g_strdup (account->name);
+
+	g_signal_connect_swapped (config_listener->priv->exchange_account,
+				  "connected",
+				  G_CALLBACK (add_defaults_for_account),
+				  config_listener);
+
+	g_signal_emit (config_listener, signals[EXCHANGE_ACCOUNT_CREATED], 0,
+		       exchange_account);
+/*	add_sources (exchange_account); */
+
+	exchange_config_listener_get_offline_status (config_listener, &is_offline);
+
+	if (is_offline == OFFLINE_MODE) {
+		remove_selected_non_offline_esources (exchange_account, CONF_KEY_CAL);
+		remove_selected_non_offline_esources (exchange_account, CONF_KEY_TASKS);
+		return;
+	}
+	exchange_account_set_online (exchange_account);
+	exchange_config_listener_authenticate (config_listener, exchange_account);
+	exchange_account_set_online (exchange_account);
+}
+
+struct account_update_data {
+	EAccountList *account_list;
+	EAccount *account;
+};
+
+static void
+configured_account_destroyed (gpointer user_data, GObject *where_account_was)
+{
+	struct account_update_data *aud = user_data;
+
+	if (!EXCHANGE_CONFIG_LISTENER (aud->account_list)->priv->configured_account)
+		account_added (aud->account_list, aud->account);
+
+	g_object_unref (aud->account_list);
+	g_object_unref (aud->account);
+	g_free (aud);
+}
+
+static gboolean
+requires_relogin (gchar *current_url, gchar *new_url)
+{
+	E2kUri *current_uri, *new_uri;
+	const gchar *current_param_val, *new_param_val;
+	const gchar *params [] = { "owa_url", "ad_server", "use_ssl" };
+	const gint n_params = G_N_ELEMENTS (params);
+	gint i;
+	gboolean relogin = FALSE;
+
+	current_uri = e2k_uri_new (current_url);
+	new_uri = e2k_uri_new (new_url);
+
+	if (strcmp (current_uri->user, new_uri->user) ||
+	    strcmp (current_uri->host, new_uri->host)) {
+		relogin = TRUE;
+		goto end;
+	}
+
+	if (current_uri->authmech || new_uri->authmech) {
+		if (current_uri->authmech && new_uri->authmech) {
+			if (strcmp (current_uri->authmech, new_uri->authmech)) {
+				/* Auth mechanism has changed */
+				relogin = TRUE;
+				goto end;
+			}
+		}
+		else {
+			/* Auth mechanism is set for the first time */
+			relogin = TRUE;
+			goto end;
+		}
+	}
+
+	for (i=0; i<n_params; i++) {
+		current_param_val = e2k_uri_get_param (current_uri, params[i]);
+		new_param_val = e2k_uri_get_param (new_uri, params[i]);
+
+		if (current_param_val && new_param_val) {
+			/* both the urls have params to be compared */
+			if (strcmp (current_param_val, new_param_val)) {
+				relogin = TRUE;
+				break;
+			}
+		}
+		else if (current_param_val || new_param_val) {
+			/* check for added or deleted parameter */
+			relogin = TRUE;
+			break;
+		}
+	}
+end:
+	e2k_uri_free (new_uri);
+	e2k_uri_free (current_uri);
+	return relogin;
+}
+
+static void
+account_changed (EAccountList *account_list, EAccount *account)
+{
+	ExchangeConfigListener *config_listener =
+		EXCHANGE_CONFIG_LISTENER (account_list);
+	ExchangeConfigListenerPrivate *priv = config_listener->priv;
+
+	if (account != config_listener->priv->configured_account) {
+		if (!is_active_exchange_account (account))
+			return;
+
+		/* The user has converted an existing non-Exchange
+		 * account to an Exchange account, so treat it like an
+		 * add.
+		 */
+		account_added (account_list, account);
+		return;
+	} else if (!is_active_exchange_account (account)) {
+		/* The user has disabled the Exchange account or
+		 * converted it to non-Exchange, so treat it like a
+		 * remove.
+		 */
+		account_removed (account_list, account);
+		return;
+	}
+
+	/* FIXME: The order of the parameters in the Camel URL string is not in
+	 * order for the two given strings. So, we will not be able to use
+	 * plain string comparison. Instead compare the parameters one by one.
+	 */
+	if (exchange_camel_urls_is_equal (config_listener->priv->configured_uri,
+					  account->source->url) &&
+	    !strcmp (config_listener->priv->configured_name, account->name)) {
+		/* The user changed something we don't care about. */
+		return;
+	}
+
+	/* OK, so he modified the active account in a way we care
+	 * about. If the user hasn't connected yet, we're still ok.
+	 */
+	if (!exchange_account_get_context (config_listener->priv->exchange_account)) {
+		/* Good. Remove the current account, and wait for it
+		 * to actually go away (which may not happen immediately
+		 * since there may be a function higher up on the stack
+		 * still holding a ref on it). Then create the new one.
+		 * (We have to wait for it to go away because the new
+		 * storage probably still has the same name as the old
+		 * one, so trying to create it before the old one is
+		 * removed would fail.)
+		 */
+		struct account_update_data *aud;
+
+		aud = g_new (struct account_update_data, 1);
+		aud->account = g_object_ref (account);
+		aud->account_list = g_object_ref (account_list);
+		g_object_weak_ref (G_OBJECT (config_listener->priv->exchange_account), configured_account_destroyed, aud);
+
+		account_removed (account_list, account);
+		return;
+	}
+
+	/* If account name has changed, or the url value has changed, which
+	 * could be due to change in hostname or some parameter value,
+	 * remove old e-sources
+	 */
+	if (requires_relogin (config_listener->priv->configured_uri,
+			      account->source->url)) {
+		remove_account_esources (priv->exchange_account);
+		exchange_account_forget_password (priv->exchange_account);
+	} else if (strcmp (config_listener->priv->configured_name, account->name)) {
+/*		remove_account_esources (priv->exchange_account); */
+		exchange_config_listener_modify_esource_group_name (config_listener,
+								    config_listener->priv->configured_name,
+								    account->name);
+		g_free (config_listener->priv->configured_name);
+		config_listener->priv->configured_name = g_strdup (account->name);
+		return;
+	} else {
+		/* FIXME: Do ESources need to be modified? */
+		return;
+	}
+
+	/* Nope. Let the user know we're ignoring him. */
+	e_error_run (NULL, "org-gnome-exchange-operations:apply-restart",
+		     priv->configured_name, NULL);
+
+	/* But note the new URI so if he changes something else, we
+	 * only warn again if he changes again.
+	 */
+	g_free (config_listener->priv->configured_uri);
+	config_listener->priv->configured_uri = g_strdup (account->source->url);
+}
+
+static void
+account_removed (EAccountList *account_list, EAccount *account)
+{
+	ExchangeConfigListener *config_listener =
+		EXCHANGE_CONFIG_LISTENER (account_list);
+	ExchangeConfigListenerPrivate *priv = config_listener->priv;
+
+	if (account != priv->configured_account)
+		return;
+
+	/* Remove all ESources */
+	remove_account_esources (priv->exchange_account);
+
+	exchange_account_forget_password (priv->exchange_account);
+
+	if (!exchange_account_get_context (priv->exchange_account)) {
+		/* The account isn't connected yet, so we can destroy
+		 * it without problems.
+		 */
+		g_signal_emit (config_listener,
+			       signals[EXCHANGE_ACCOUNT_REMOVED], 0,
+			       priv->exchange_account);
+
+		priv->configured_account = NULL;
+		g_free (priv->configured_uri);
+		priv->configured_uri = NULL;
+		g_free (priv->configured_name);
+		priv->configured_name = NULL;
+	}
+}
+
+static gboolean
+idle_construct (gpointer data)
+{
+	ExchangeConfigListener *config_listener = data;
+
+	config_listener->priv->idle_id = 0;
+	e_account_list_construct (E_ACCOUNT_LIST (config_listener),
+				  config_listener->priv->gconf);
+	return FALSE;
+}
+
+ExchangeConfigListenerStatus
+exchange_config_listener_get_offline_status (ExchangeConfigListener *excl,
+					     gint *mode)
+{
+	ExchangeConfigListenerPrivate *priv;
+	GConfValue *value;
+	ExchangeConfigListenerStatus status = CONFIG_LISTENER_STATUS_OK;
+	gboolean offline = FALSE;
+
+	g_return_val_if_fail (excl != NULL, CONFIG_LISTENER_STATUS_NOT_FOUND);
+
+	priv = excl->priv;
+	value = gconf_client_get (priv->gconf,
+					"/apps/evolution/shell/start_offline", NULL);
+	if (value)
+		offline = gconf_value_get_bool (value);
+
+	if (offline)
+		*mode = OFFLINE_MODE;
+	else
+		*mode = ONLINE_MODE;
+
+	gconf_value_free (value);
+	return status;
+
+}
+
+/**
+ * exchange_config_listener_new:
+ *
+ * This creates and returns a new #ExchangeConfigListener, which
+ * monitors GConf and creates and (theoretically) destroys accounts
+ * accordingly. It will emit an %account_created signal when a new
+ * account is created (or shortly after the listener itself is created
+ * if an account already exists).
+ *
+ * Due to various constraints, the user is currently limited to a
+ * single account, and it is not possible to destroy an existing
+ * account. Thus, the %account_created signal will never be emitted
+ * more than once currently.
+ *
+ * Return value: the new config listener.
+ **/
+ExchangeConfigListener *
+exchange_config_listener_new (void)
+{
+	ExchangeConfigListener *config_listener;
+
+	config_listener = g_object_new (EXCHANGE_TYPE_CONFIG_LISTENER, NULL);
+	config_listener->priv->gconf = gconf_client_get_default ();
+
+	config_listener->priv->idle_id =
+		g_idle_add (idle_construct, config_listener);
+
+	return config_listener;
+}
+
+GSList *
+exchange_config_listener_get_accounts (ExchangeConfigListener *config_listener)
+{
+	g_return_val_if_fail (EXCHANGE_IS_CONFIG_LISTENER (config_listener), NULL);
+
+	if (config_listener->priv->exchange_account)
+		return g_slist_append (NULL, config_listener->priv->exchange_account);
+	else
+		return NULL;
+}
+
+/**
+ * exchange_config_listener_modify_esource_group_name
+ *
+ * @excl: Handle for Exchange Config Listener
+ * @old_name: Old name of the ESourceGroup
+ * @new_name: New name of the ESourceGroup
+ *
+ * This function modifies the old source group name to the specified new
+ * source group name
+ **/
+void
+exchange_config_listener_modify_esource_group_name (ExchangeConfigListener *excl,
+							 const gchar *old_name,
+							 const gchar *new_name)
+{
+	GConfClient *client;
+	ESourceGroup *group;
+	GSList *groups;
+	ESourceList *c_source_list = NULL, *t_source_list = NULL,
+		*a_source_list = NULL;
+
+	client = excl->priv->gconf;
+
+	c_source_list = e_source_list_new_for_gconf ( client, CONF_KEY_CAL);
+	t_source_list = e_source_list_new_for_gconf ( client, CONF_KEY_TASKS);
+	a_source_list = e_source_list_new_for_gconf ( client, CONF_KEY_CONTACTS);
+
+	groups = e_source_list_peek_groups (c_source_list);
+
+	for (; groups != NULL; groups = g_slist_next (groups)) {
+		group = E_SOURCE_GROUP (groups->data);
+		if (!strcmp (e_source_group_peek_name (group), old_name)) {
+			e_source_group_set_name (group, new_name);
+			break;
+		}
+	}
+
+	groups = e_source_list_peek_groups (t_source_list);
+
+	for (; groups != NULL; groups = g_slist_next (groups)) {
+		group = E_SOURCE_GROUP (groups->data);
+		if (!strcmp (e_source_group_peek_name (group), old_name)) {
+			e_source_group_set_name (group, new_name);
+			break;
+		}
+	}
+
+	groups = e_source_list_peek_groups (a_source_list);
+
+	for (; groups != NULL; groups = g_slist_next (groups)) {
+		group = E_SOURCE_GROUP (groups->data);
+		if (!strcmp (e_source_group_peek_name (group), old_name)) {
+			e_source_group_set_name (group, new_name);
+			break;
+		}
+	}
+
+	e_source_list_sync (c_source_list, NULL);
+	e_source_list_sync (t_source_list, NULL);
+	e_source_list_sync (a_source_list, NULL);
+
+	g_object_unref (c_source_list);
+	g_object_unref (t_source_list);
+	g_object_unref (a_source_list);
+}
+
+#ifdef LDEAD
+/**
+ * exchange_add_autocompletion_folders:
+ *
+ * @gc_client: GConfClient handle
+ * @account: ExchangeAccount handle
+ *
+ * This function adds the GAL of the Exchange account to the autocompletion list
+ * while configuring a new Exchange account
+ *
+ **/
+static void
+exchange_add_autocompletion_folders (GConfClient *gc_client, ExchangeAccount *account)
+{
+	ESourceList *sl=NULL;
+	ESource *source;
+	GSList *groups;
+	gboolean found_group=FALSE;
+
+	sl = e_source_list_new_for_gconf (gc_client, CONF_KEY_CONTACTS);
+	groups = e_source_list_peek_groups (sl);
+
+	for (; groups != NULL && !found_group; groups = g_slist_next (groups)) {
+		ESourceGroup *group = E_SOURCE_GROUP (groups->data);
+
+		if (strcmp (e_source_group_peek_name (group), account->account_name) == 0
+                    &&
+		    strcmp (e_source_group_peek_base_uri (group), EXCHANGE_URI_PREFIX) == 0) {
+			GSList *sources = e_source_group_peek_sources (group);
+
+			for (; sources != NULL; sources = g_slist_next (sources)) {
+				ESource *source = E_SOURCE (sources->data);
+				const gchar *absolute_uri;
+
+				absolute_uri = e_source_peek_absolute_uri (source);
+				if (absolute_uri == NULL)
+					continue;
+				if (g_str_has_prefix (absolute_uri, "gal://")) {
+					/* Set autocompletion on GAL alone by default */
+					e_source_set_property (source, "completion", "true");
+					break;
+				}
+			}
+			found_group = TRUE;
+		}
+	}
+
+	g_object_unref (sl);
+}
+#endif
+
+/**
+ * exchange_camel_urls_is_equal
+ *
+ * @url1: CAMEL URL string 1
+ * @url2: CAMEL URL string 2
+ *
+ * This function checks if the parameters present in two given CAMEL URLS are
+ * identical and returns the result.
+ *
+ * Return Value: Boolean result of the comparision.
+ *
+ **/
+static gboolean
+exchange_camel_urls_is_equal (const gchar *url1, const gchar *url2)
+{
+	CamelURL *curl1, *curl2;
+	gchar *param1, *param2;
+	const gchar *params[] = {
+		"auth",
+		"owa_url",
+		"owa_path",
+		"mailbox",
+		"ad_server",
+	};
+	const gint n_params = 5;
+	gint i;
+
+	curl1 = camel_url_new (url1, NULL);
+	curl2 = camel_url_new (url2, NULL);
+
+	for (i = 0; i < n_params; ++i) {
+		param1 = (gchar *) camel_url_get_param (curl1, params[i]);
+		param2 = (gchar *) camel_url_get_param (curl2, params[i]);
+		if ((param1 && !param2) || (!param1 && param2) || /* Missing */
+		    (param1 && param2 && strcmp (param1, param2))) { /* Differing */
+			g_free (param1);
+			g_free (param2);
+			g_free (curl1);
+			g_free (curl2);
+			return FALSE;
+		}
+		g_free (param1);
+		g_free (param2);
+	}
+	g_free (curl1);
+	g_free (curl2);
+	return TRUE;
+}
+
+/**
+ * remove_selected_non_offline_esources
+ *
+ * @account: Handle for Exchange Account
+ * @gconf_key: GConf key of the calendar or tasks
+ *
+ * This function removes the non-offline calendars and taks list from the
+ * selection list
+ **/
+static void
+remove_selected_non_offline_esources (ExchangeAccount *account, const gchar *gconf_key)
+{
+	ESourceGroup *group;
+	ESource *source = NULL;
+	GSList *groups;
+	GSList *sources;
+	GSList *ids, *node_to_be_deleted;
+	gboolean found_group;
+	const gchar *source_uid;
+	GConfClient *client;
+	ESourceList *source_list = NULL;
+	const gchar *offline_mode=NULL;
+	gchar *selected_gconf_key;
+
+	if (gconf_key && !strcmp (gconf_key, CONF_KEY_CAL)) {
+		selected_gconf_key = g_strdup (CONF_KEY_SELECTED_CAL_SOURCES);
+	} else if (gconf_key && !strcmp (gconf_key, CONF_KEY_TASKS)) {
+		selected_gconf_key = g_strdup (CONF_KEY_SELECTED_TASKS_SOURCES);
+	}
+	else {
+		return;
+	}
+
+	client = gconf_client_get_default ();
+	source_list = e_source_list_new_for_gconf ( client, gconf_key);
+
+	groups = e_source_list_peek_groups (source_list);
+	found_group = FALSE;
+
+	for (; groups != NULL && !found_group; groups = g_slist_next (groups)) {
+		group = E_SOURCE_GROUP (groups->data);
+
+		if (strcmp (e_source_group_peek_name (group), account->account_name) == 0
+                    &&
+                    strcmp (e_source_group_peek_base_uri (group), EXCHANGE_URI_PREFIX) == 0) {
+			sources = e_source_group_peek_sources (group);
+
+			for (; sources != NULL; sources = g_slist_next (sources)) {
+				source = E_SOURCE (sources->data);
+				source_uid = e_source_peek_uid (source);
+
+				/* Remove from the selected folders */
+				ids = gconf_client_get_list (client,
+							     selected_gconf_key,
+							     GCONF_VALUE_STRING, NULL);
+				if (ids) {
+					offline_mode = e_source_get_property (source, "offline_sync");
+					if (!offline_mode ||
+					    (offline_mode && strcmp (offline_mode, "1"))) {
+						while ((node_to_be_deleted =
+							g_slist_find_custom (ids,
+									     source_uid,
+									     (GCompareFunc) strcmp))) {
+							g_free (node_to_be_deleted->data);
+							ids = g_slist_delete_link (ids,
+										   node_to_be_deleted);
+							gconf_client_set_list (client,
+									       selected_gconf_key,
+									       GCONF_VALUE_STRING, ids, NULL);
+						}
+					}
+					g_slist_foreach (ids, (GFunc) g_free, NULL);
+					g_slist_free (ids);
+				}
+			}
+			found_group = TRUE;
+			e_source_list_sync (source_list, NULL);
+		}
+	}
+
+	g_free (selected_gconf_key);
+	g_object_unref (source_list);
+	g_object_unref (client);
+}
diff --git a/eplugin/exchange-config-listener.h b/eplugin/exchange-config-listener.h
new file mode 100644
index 0000000..07051bc
--- /dev/null
+++ b/eplugin/exchange-config-listener.h
@@ -0,0 +1,84 @@
+/*
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifndef __EXCHANGE_CONFIG_LISTENER_H__
+#define __EXCHANGE_CONFIG_LISTENER_H__
+
+#include <exchange-constants.h>
+#include <exchange-account.h>
+
+#include "exchange-types.h"
+#include "libedataserver/e-account-list.h"
+#include <libedataserver/e-source-list.h>
+#include <libedataserver/e-source-group.h>
+
+G_BEGIN_DECLS
+
+typedef enum {
+	CONFIG_LISTENER_STATUS_OK,
+	CONFIG_LISTENER_STATUS_NOT_FOUND
+} ExchangeConfigListenerStatus;
+
+#define EXCHANGE_TYPE_CONFIG_LISTENER            (exchange_config_listener_get_type ())
+#define EXCHANGE_CONFIG_LISTENER(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), EXCHANGE_TYPE_CONFIG_LISTENER, ExchangeConfigListener))
+#define EXCHANGE_CONFIG_LISTENER_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), EXCHANGE_TYPE_CONFIG_LISTENER, ExchangeConfigListenerClass))
+#define EXCHANGE_IS_CONFIG_LISTENER(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EXCHANGE_TYPE_CONFIG_LISTENER))
+#define EXCHANGE_IS_CONFIG_LISTENER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), EXCHANGE_TYPE_CONFIG_LISTENER))
+
+struct _ExchangeConfigListener {
+	EAccountList parent;
+
+	ExchangeConfigListenerPrivate *priv;
+};
+
+struct _ExchangeConfigListenerClass {
+	EAccountListClass parent_class;
+
+	/* signals */
+	void (*exchange_account_created) (ExchangeConfigListener *,
+					  ExchangeAccount *);
+	void (*exchange_account_removed) (ExchangeConfigListener *,
+					  ExchangeAccount *);
+};
+
+#define CONF_KEY_CAL "/apps/evolution/calendar/sources"
+#define CONF_KEY_TASKS "/apps/evolution/tasks/sources"
+#define CONF_KEY_CONTACTS "/apps/evolution/addressbook/sources"
+#define EXCHANGE_URI_PREFIX "exchange://"
+
+GType                   exchange_config_listener_get_type (void);
+ExchangeConfigListener *exchange_config_listener_new      (void);
+
+GSList                 *exchange_config_listener_get_accounts (ExchangeConfigListener *config_listener);
+
+void			add_folder_esource (ExchangeAccount *account, FolderType folder_type, const gchar *folder_name, const gchar *physical_uri);
+void			remove_folder_esource (ExchangeAccount *account, FolderType folder_type, const gchar *physical_uri);
+ExchangeConfigListenerStatus exchange_config_listener_get_offline_status (ExchangeConfigListener *excl, gint *mode);
+
+void exchange_config_listener_modify_esource_group_name (ExchangeConfigListener *excl,
+							 const gchar *old_name,
+							 const gchar *new_name);
+
+ExchangeAccountResult exchange_config_listener_authenticate (ExchangeConfigListener *excl,
+							ExchangeAccount *account);
+
+G_END_DECLS
+
+#endif /* __EXCHANGE_CONFIG_LISTENER_H__ */
diff --git a/eplugin/exchange-contacts.c b/eplugin/exchange-contacts.c
new file mode 100644
index 0000000..7fb9f85
--- /dev/null
+++ b/eplugin/exchange-contacts.c
@@ -0,0 +1,548 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ *		Praveen Kumar <kpraveen novell com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#include <string.h>
+#include <gtk/gtk.h>
+#include <e-util/e-config.h>
+#include <calendar/gui/e-cal-config.h>
+#include <libedataserver/e-source.h>
+#include <libedataserver/e-source-list.h>
+#include <libedataserver/e-url.h>
+#include <e-folder.h>
+#include <exchange-account.h>
+
+#include <libebook/e-book.h>
+#include <libecal/e-cal.h>
+#include <addressbook/gui/widgets/eab-config.h>
+
+#include "mail/em-account-editor.h"
+#include "mail/em-config.h"
+#include "libedataserver/e-account.h"
+#include "e-util/e-error.h"
+
+#include "exchange-operations.h"
+#include "exchange-folder-size-display.h"
+
+enum {
+	CONTACTSNAME_COL,
+	CONTACTSRURI_COL,
+	NUM_COLS
+};
+
+gboolean contacts_src_exists = FALSE;
+gchar *contacts_old_src_uri = NULL;
+
+static GPtrArray *e_exchange_contacts_get_contacts (void);
+void e_exchange_contacts_pcontacts_on_change (GtkTreeView *treeview, ESource *source);
+GtkWidget *e_exchange_contacts_pcontacts (EPlugin *epl, EConfigHookItemFactoryData *data);
+gboolean e_exchange_contacts_check (EPlugin *epl, EConfigHookPageCheckData *data);
+void e_exchange_contacts_commit (EPlugin *epl, EConfigTarget *target);
+
+/* FIXME: Reconsider the prototype of this function */
+static GPtrArray *
+e_exchange_contacts_get_contacts (void)
+{
+	ExchangeAccount *account;
+	GPtrArray *folder_array;
+	GPtrArray *contacts_list;
+	EFolder *folder;
+
+	gint i, prefix_len;
+	gchar *uri_prefix, *ruri;
+
+	account = exchange_operations_get_exchange_account ();
+	if (!account)
+		return NULL;
+
+	uri_prefix = g_strconcat ("exchange://", account->account_filename, "/;", NULL);
+	prefix_len = strlen (uri_prefix);
+
+	contacts_list = g_ptr_array_new ();
+	exchange_account_rescan_tree (account);
+	folder_array = exchange_account_get_folders (account);
+
+	for (i=0; i<folder_array->len; ++i) {
+		gchar *type, *tmp;
+		folder = g_ptr_array_index (folder_array, i);
+		type = (gchar *) e_folder_get_type_string (folder);
+		if (!strcmp (type, "contacts")) {
+			tmp = (gchar *) e_folder_get_physical_uri (folder);
+			if (g_str_has_prefix (tmp, uri_prefix)) {
+				ruri = g_strdup (tmp+prefix_len);
+				g_ptr_array_add (contacts_list, ruri);
+			}
+		}
+	}
+
+	g_free (uri_prefix);
+	if (folder_array)
+		g_ptr_array_free (folder_array, TRUE);
+	return contacts_list;
+}
+
+void
+e_exchange_contacts_pcontacts_on_change (GtkTreeView *treeview, ESource *source)
+{
+	GtkTreeSelection *selection;
+	GtkTreeModel     *model;
+	GtkTreeIter       iter;
+	ExchangeAccount *account;
+	gchar *es_ruri;
+	gchar *ruri;
+
+	account = exchange_operations_get_exchange_account ();
+	if (!account)
+		return;
+
+	selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview));
+	gtk_tree_selection_get_selected(selection, &model, &iter);
+
+	gtk_tree_model_get (model, &iter, CONTACTSRURI_COL, &ruri, -1);
+	es_ruri = g_strconcat (account->account_filename, "/;", ruri, NULL);
+	e_source_set_relative_uri (source, es_ruri);
+
+	g_free (ruri);
+	g_free (es_ruri);
+}
+
+GtkWidget *
+e_exchange_contacts_pcontacts (EPlugin *epl, EConfigHookItemFactoryData *data)
+{
+	static GtkWidget *lbl_pcontacts, *scrw_pcontacts, *tv_pcontacts, *vb_pcontacts, *lbl_size, *lbl_size_val, *hbx_size;
+	GtkTreeStore *ts_pcontacts;
+	GtkCellRenderer *cr_contacts;
+	GtkTreeViewColumn *tvc_contacts;
+	GtkListStore *model;
+	GPtrArray *conlist;
+	gchar *ruri, *account_name, *uri_text;
+	ExchangeAccount *account;
+	gint i;
+	gchar *folder_size, *abook_name;
+	const gchar *rel_uri;
+	const gchar *uid;
+	EABConfigTargetSource *t = (EABConfigTargetSource *) data->target;
+	ESource *source = t->source;
+	GtkWidget *lbl_offline_msg, *vb_offline_msg;
+	gchar *offline_msg;
+	gint offline_status;
+	gboolean gal_folder = FALSE, is_personal;
+
+	if (data->old) {
+		gtk_widget_destroy (vb_pcontacts);
+	}
+
+	uri_text = e_source_get_uri (source);
+	if (uri_text && g_ascii_strncasecmp (uri_text, "exchange", 8)) {
+		if (g_ascii_strncasecmp (uri_text, "gal", 3)) {
+			g_free (uri_text);
+			return NULL;
+		}
+		else {
+			gal_folder = TRUE;
+		}
+	}
+
+	exchange_config_listener_get_offline_status (exchange_global_config_listener,
+								    &offline_status);
+	if (offline_status == OFFLINE_MODE) {
+		/* Evolution is in offline mode; we will not be able to create
+		   new folders or modify existing folders. */
+		offline_msg = g_markup_printf_escaped ("<b>%s</b>",
+						       _("Evolution is in offline mode. You cannot create or modify folders now.\nPlease switch to online mode for such operations."));
+		vb_offline_msg = gtk_vbox_new (FALSE, 6);
+		gtk_container_add (GTK_CONTAINER (data->parent), vb_offline_msg);
+		lbl_offline_msg = gtk_label_new ("");
+		gtk_label_set_markup (GTK_LABEL (lbl_offline_msg), offline_msg);
+		g_free (offline_msg);
+		gtk_box_pack_start (GTK_BOX (vb_offline_msg), lbl_offline_msg, FALSE, FALSE, 0);
+		gtk_widget_show_all (vb_offline_msg);
+		g_free (uri_text);
+		return vb_offline_msg;
+	}
+
+	if (gal_folder) {
+		contacts_src_exists = TRUE;
+		g_free (uri_text);
+		return NULL;
+	}
+
+	rel_uri = e_source_peek_relative_uri (source);
+	uid = e_source_peek_uid (source);
+	if (rel_uri && uid && (strcmp (rel_uri, uid))) {
+		contacts_src_exists = TRUE;
+		g_free (contacts_old_src_uri);
+		contacts_old_src_uri = g_strdup (rel_uri);
+	}
+	else {
+		/* new folder */
+		contacts_src_exists = FALSE;
+		e_source_set_relative_uri (source, ""); /* FIXME: Nasty hack */
+	}
+
+	account = exchange_operations_get_exchange_account ();
+	if (!account) {
+		g_free (contacts_old_src_uri);
+		g_free (uri_text);
+		return NULL;
+	}
+	account_name = account->account_name;
+	hbx_size = NULL;
+
+	is_personal = is_exchange_personal_folder (account, uri_text);
+	g_free (uri_text);
+
+	if (contacts_src_exists && is_personal ) {
+		abook_name = (gchar *)e_source_peek_name (source);
+		model = exchange_account_folder_size_get_model (account);
+		if (model)
+			folder_size = g_strdup_printf (_("%s KB"), exchange_folder_size_get_val (model, abook_name));
+		else
+			folder_size = g_strdup_printf (_("0 KB"));
+
+		/* FIXME: Take care of i18n */
+		lbl_size = gtk_label_new_with_mnemonic (_("Size:"));
+		lbl_size_val = gtk_label_new_with_mnemonic (_(folder_size));
+		hbx_size = gtk_hbox_new (FALSE, 0);
+		gtk_box_pack_start (GTK_BOX (hbx_size), lbl_size, FALSE, TRUE, 0);
+		gtk_box_pack_start (GTK_BOX (hbx_size), lbl_size_val, FALSE, TRUE, 10);
+		gtk_widget_show (lbl_size);
+		gtk_widget_show (lbl_size_val);
+		gtk_misc_set_alignment (GTK_MISC (lbl_size), 0.0, 0.5);
+		gtk_misc_set_alignment (GTK_MISC (lbl_size_val), 0.0, 0.5);
+		g_free (folder_size);
+	}
+	vb_pcontacts = gtk_vbox_new (FALSE, 6);
+	gtk_container_add (GTK_CONTAINER (data->parent), vb_pcontacts);
+
+	if (hbx_size)
+		gtk_box_pack_start (GTK_BOX (vb_pcontacts), hbx_size, FALSE, FALSE, 0);
+
+	lbl_pcontacts = gtk_label_new_with_mnemonic (_("_Location:"));
+	gtk_widget_show (lbl_pcontacts);
+	gtk_misc_set_alignment (GTK_MISC (lbl_pcontacts), 0.0, 0.5);
+	gtk_box_pack_start (GTK_BOX (vb_pcontacts), lbl_pcontacts, FALSE, FALSE, 0);
+
+	ts_pcontacts = gtk_tree_store_new (NUM_COLS, G_TYPE_STRING, G_TYPE_STRING);
+
+	conlist = e_exchange_contacts_get_contacts ();
+
+	if (conlist) {
+		for (i = 0; i < conlist->len; i++) {
+			ruri = g_ptr_array_index (conlist, i);
+			exchange_operations_cta_add_node_to_tree (ts_pcontacts, NULL, ruri);
+		}
+		g_ptr_array_free (conlist, TRUE);
+	}
+
+	cr_contacts = gtk_cell_renderer_text_new ();
+	tvc_contacts = gtk_tree_view_column_new_with_attributes (account_name, cr_contacts, "text", CONTACTSNAME_COL, NULL);
+	tv_pcontacts = gtk_tree_view_new_with_model (GTK_TREE_MODEL (ts_pcontacts));
+	gtk_tree_view_append_column (GTK_TREE_VIEW (tv_pcontacts), tvc_contacts);
+	g_object_set (tv_pcontacts,"expander-column", tvc_contacts, "headers-visible", TRUE, NULL);
+	gtk_tree_view_expand_all (GTK_TREE_VIEW (tv_pcontacts));
+
+	scrw_pcontacts = gtk_scrolled_window_new (NULL, NULL);
+	gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrw_pcontacts), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+	gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrw_pcontacts), GTK_SHADOW_IN);
+	g_object_set (scrw_pcontacts, "height-request", 150, NULL);
+	gtk_container_add (GTK_CONTAINER (scrw_pcontacts), tv_pcontacts);
+	gtk_label_set_mnemonic_widget (GTK_LABEL (lbl_pcontacts), tv_pcontacts);
+	g_signal_connect (G_OBJECT (tv_pcontacts), "cursor-changed", G_CALLBACK (e_exchange_contacts_pcontacts_on_change), t->source);
+	gtk_widget_show_all (scrw_pcontacts);
+
+	gtk_box_pack_start (GTK_BOX (vb_pcontacts), scrw_pcontacts, FALSE, FALSE, 0);
+	gtk_widget_show_all (vb_pcontacts);
+
+	if (contacts_src_exists) {
+		gchar *uri_prefix, *sruri, *tmpruri;
+		gint prefix_len;
+		GtkTreeSelection *selection;
+
+		tmpruri = (gchar *) rel_uri;
+		uri_prefix = g_strconcat (account->account_filename, "/;", NULL);
+		prefix_len = strlen (uri_prefix);
+
+		if (g_str_has_prefix (tmpruri, uri_prefix)) {
+			sruri = g_strdup (tmpruri+prefix_len);
+		}
+		else {
+			sruri = NULL;
+		}
+
+		selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (tv_pcontacts));
+		exchange_operations_cta_select_node_from_tree (ts_pcontacts,
+							       NULL,
+							       sruri,
+							       sruri,
+							       selection);
+		gtk_widget_set_sensitive (tv_pcontacts, FALSE);
+
+		g_free (uri_prefix);
+		g_free (sruri);
+	}
+
+	g_object_unref (ts_pcontacts);
+	return vb_pcontacts;
+}
+
+gboolean
+e_exchange_contacts_check (EPlugin *epl, EConfigHookPageCheckData *data)
+{
+	/* FIXME - check pageid */
+	EABConfigTargetSource *t = (EABConfigTargetSource *) data->target;
+	ESourceGroup *group;
+	const gchar *base_uri;
+	const gchar *rel_uri;
+	gint offline_status;
+	ExchangeAccount *account;
+
+	rel_uri = e_source_peek_relative_uri (t->source);
+	group = e_source_peek_group (t->source);
+	base_uri = e_source_group_peek_base_uri (group);
+	exchange_config_listener_get_offline_status (exchange_global_config_listener,
+								    &offline_status);
+	if (base_uri && !g_ascii_strncasecmp (base_uri, "exchange", 8)) {
+		if (offline_status == OFFLINE_MODE)
+			return FALSE;
+		if (rel_uri && !strlen (rel_uri))
+			return FALSE;
+	}
+	else {
+		return TRUE;
+	}
+
+	if (!contacts_src_exists) {
+		return TRUE;
+	}
+
+	account = exchange_operations_get_exchange_account ();
+	if (!account)
+		return FALSE;
+
+	if (!rel_uri) {
+		GConfClient *client;
+		ESourceList *source_list = NULL;
+		ESourceGroup *source_group = NULL;
+		ESource *source;
+		EAccount *eaccount;
+
+		/* GAL folder */
+		client = gconf_client_get_default ();
+		source_list = e_source_list_new_for_gconf ( client, CONF_KEY_CONTACTS);
+		g_object_unref (client);
+
+		eaccount = exchange_account_fetch (account);
+		g_return_val_if_fail (eaccount != NULL, FALSE);
+		g_return_val_if_fail (eaccount->uid != NULL, FALSE);
+
+		if ((source_group = e_source_list_peek_group_by_properties (source_list, "account-uid", eaccount->uid, NULL))) {
+			source =  e_source_group_peek_source_by_name (source_group, e_source_peek_name (t->source));
+			if (e_source_group_peek_source_by_name (source_group,
+							e_source_peek_name (t->source))) {
+				/* not a rename of GAL */
+				g_object_unref (source_list);
+				return TRUE;
+			}
+			else {
+				g_object_unref (source_list);
+				return FALSE;
+			}
+		}
+		else {
+			g_object_unref (source_list);
+			return FALSE;
+		}
+	}
+	else {
+		EUri *euri;
+		gint uri_len;
+		gchar *uri_text, *uri_string, *path, *folder_name;
+		gboolean is_personal;
+
+		uri_text = e_source_get_uri (t->source);
+		euri = e_uri_new (uri_text);
+		uri_string = e_uri_to_string (euri, FALSE);
+		e_uri_free (euri);
+
+		is_personal = is_exchange_personal_folder (account, uri_text);
+
+		uri_len = strlen (uri_string) + 1;
+		g_free (uri_string);
+		path = g_build_filename ("/", uri_text + uri_len, NULL);
+		g_free (uri_text);
+		folder_name = g_strdup (g_strrstr (path, "/") +1);
+		g_free (path);
+
+		if (strcmp (folder_name, e_source_peek_name (t->source))) {
+			/* rename */
+			if (exchange_account_get_standard_uri (account, folder_name) ||
+			    !is_personal) {
+				/* rename of standard/non-personal folder */
+				g_free (folder_name);
+				return FALSE;
+			}
+			g_free (folder_name);
+		}
+	}
+	return TRUE;
+}
+
+void
+e_exchange_contacts_commit (EPlugin *epl, EConfigTarget *target)
+{
+	EABConfigTargetSource *t = (EABConfigTargetSource *) target;
+	ESource *source = t->source;
+	gchar *uri_text, *gname, *gruri, *ruri = NULL, *path = NULL, *path_prefix, *oldpath=NULL;
+	gchar *username, *windows_domain, *authtype;
+	gint prefix_len;
+	ExchangeAccount *account;
+	ExchangeAccountFolderResult result;
+	gint offline_status;
+	gboolean rename = FALSE;
+
+	uri_text = e_source_get_uri (source);
+	if (uri_text && strncmp (uri_text, "exchange", 8)) {
+		/* here no need of checking for gal */
+		g_free (uri_text);
+		return;
+	}
+
+	exchange_config_listener_get_offline_status (exchange_global_config_listener,
+								    &offline_status);
+	if (offline_status == OFFLINE_MODE) {
+		g_free (uri_text);
+		return;
+	}
+
+	account = exchange_operations_get_exchange_account ();
+	if (!account || !is_exchange_personal_folder (account, uri_text))
+		return;
+
+	windows_domain = exchange_account_get_windows_domain (account);
+	if (windows_domain)
+		username = g_strdup_printf ("%s\\%s", windows_domain,
+					    exchange_account_get_username (account));
+	else
+		username = g_strdup (exchange_account_get_username (account));
+
+	authtype = exchange_account_get_authtype (account);
+
+	path_prefix = g_strconcat (account->account_filename, "/;", NULL);
+	prefix_len = strlen (path_prefix);
+	g_free (path_prefix);
+
+	gname = (gchar *) e_source_peek_name (source);
+	gruri = (gchar *) e_source_peek_relative_uri (source);
+
+	if (contacts_src_exists) {
+		gchar *tmpruri, *uri_string, *temp_path, *prefix;
+		EUri *euri;
+		gint uri_len;
+
+		euri = e_uri_new (uri_text);
+		uri_string = e_uri_to_string (euri, FALSE);
+		e_uri_free (euri);
+
+		uri_len = strlen (uri_string) + 1;
+		tmpruri = g_strdup (uri_string + strlen ("exchange://"));
+		temp_path = g_build_filename ("/", uri_text + uri_len, NULL);
+		prefix	= g_strndup (temp_path, strlen (temp_path) - strlen (g_strrstr (temp_path, "/")));
+		g_free (temp_path);
+		path = g_build_filename (prefix, "/", gname, NULL);
+		ruri = g_strconcat (tmpruri, ";", path+1, NULL);
+		oldpath = g_build_filename ("/", contacts_old_src_uri + prefix_len, NULL);
+		g_free (prefix);
+		g_free (uri_string);
+		g_free (tmpruri);
+	}
+	else {
+		/* new folder */
+		ruri = g_strconcat (gruri, "/", gname, NULL);
+		path = g_build_filename ("/", ruri+prefix_len, NULL);
+	}
+
+	if (!contacts_src_exists) {
+		/* Create the new folder */
+		result = exchange_account_create_folder (account, path, "contacts");
+	}
+	else if (gruri && strcmp (path, oldpath )) {
+		/* Rename the folder */
+		rename = TRUE;
+		result = exchange_account_xfer_folder (account, oldpath, path, TRUE);
+	}
+	else {
+		/* Nothing happened specific to exchange; just return */
+		goto done;
+	}
+	switch (result) {
+	case EXCHANGE_ACCOUNT_FOLDER_OK:
+		e_source_set_name (source, gname);
+		e_source_set_relative_uri (source, ruri);
+		e_source_set_property (source, "username", username);
+		e_source_set_property (source, "auth-domain", "Exchange");
+		if (authtype) {
+			e_source_set_property (source, "auth-type", authtype);
+			g_free (authtype);
+			authtype=NULL;
+		}
+		e_source_set_property (source, "auth", "plain/password");
+		if (rename) {
+			exchange_operations_update_child_esources (source,
+							contacts_old_src_uri,
+							ruri);
+		}
+		break;
+	case EXCHANGE_ACCOUNT_FOLDER_ALREADY_EXISTS:
+		e_error_run (NULL, ERROR_DOMAIN ":folder-exists-error", NULL);
+		break;
+	case EXCHANGE_ACCOUNT_FOLDER_DOES_NOT_EXIST:
+		e_error_run (NULL, ERROR_DOMAIN ":folder-doesnt-exist-error", NULL);
+		break;
+	case EXCHANGE_ACCOUNT_FOLDER_UNKNOWN_TYPE:
+		e_error_run (NULL, ERROR_DOMAIN ":folder-unknown-type", NULL);
+		break;
+	case EXCHANGE_ACCOUNT_FOLDER_PERMISSION_DENIED:
+		e_error_run (NULL, ERROR_DOMAIN ":folder-perm-error", NULL);
+		break;
+	case EXCHANGE_ACCOUNT_FOLDER_OFFLINE:
+		e_error_run (NULL, ERROR_DOMAIN ":folder-offline-error", NULL);
+		break;
+	case EXCHANGE_ACCOUNT_FOLDER_UNSUPPORTED_OPERATION:
+		e_error_run (NULL, ERROR_DOMAIN ":folder-unsupported-error", NULL);
+		break;
+	case EXCHANGE_ACCOUNT_FOLDER_GENERIC_ERROR:
+		e_error_run (NULL, ERROR_DOMAIN ":folder-generic-error", NULL);
+		break;
+	default:
+		break;
+	}
+done:
+	g_free (ruri);
+	g_free (username);
+	if (authtype)
+		g_free (authtype);
+	g_free (path);
+	g_free (oldpath);
+	g_free (contacts_old_src_uri);
+	g_free (uri_text);
+	contacts_old_src_uri = NULL;
+}
diff --git a/eplugin/exchange-delegates-user.c b/eplugin/exchange-delegates-user.c
new file mode 100644
index 0000000..7c1101f
--- /dev/null
+++ b/eplugin/exchange-delegates-user.c
@@ -0,0 +1,628 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+/* ExchangeDelegatesUser: A single delegate */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "exchange-delegates.h"
+#include "exchange-delegates-user.h"
+
+#include <mail/mail-ops.h>
+#include <mail/mail-send-recv.h>
+#include <mail/e-mail-local.h>
+#include <camel/camel-multipart.h>
+#include <camel/camel-mime-utils.h>
+#include <camel/camel-stream-mem.h>
+#include <exchange-account.h>
+#include "exchange-delegates.h"
+#include <exchange/exchange-account.h>
+#include <e2k-global-catalog.h>
+#include <e2k-marshal.h>
+#include <e2k-sid.h>
+#include <e2k-utils.h>
+
+#include <e-util/e-dialog-utils.h>
+#include <e-util/e-dialog-widgets.h>
+
+#include <string.h>
+
+#define EXCHANGE_DELEGATES_USER_CUSTOM    -3
+/* Can't use E2K_PERMISSIONS_ROLE_CUSTOM, because it's -1, which
+ * means "end of list" to e_dialog_combo_box_get/set
+ */
+
+static const gint exchange_perm_map[] = {
+	E2K_PERMISSIONS_ROLE_NONE,
+	E2K_PERMISSIONS_ROLE_REVIEWER,
+	E2K_PERMISSIONS_ROLE_AUTHOR,
+	E2K_PERMISSIONS_ROLE_EDITOR,
+
+	EXCHANGE_DELEGATES_USER_CUSTOM,
+
+	-1
+};
+
+const gchar *exchange_delegates_user_folder_names[] = {
+	"calendar", "tasks", "inbox", "contacts"
+};
+
+/* To translators: The folder names to be displayed in the message being
+   sent to the delegatee.
+*/
+static const gchar *folder_names_for_display[] = {
+	N_("Calendar"), N_("Tasks"), N_("Inbox"), N_("Contacts")
+};
+
+enum {
+	EDITED,
+	LAST_SIGNAL
+};
+
+static guint signals [LAST_SIGNAL] = { 0 };
+
+#define PARENT_TYPE G_TYPE_OBJECT
+static GObjectClass *parent_class = NULL;
+
+static void
+finalize (GObject *object)
+{
+	ExchangeDelegatesUser *user = EXCHANGE_DELEGATES_USER (object);
+
+	if (user->display_name)
+		g_free (user->display_name);
+	if (user->dn)
+		g_free (user->dn);
+	if (user->entryid)
+		g_byte_array_free (user->entryid, TRUE);
+	if (user->sid)
+		g_object_unref (user->sid);
+
+	G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+static void
+class_init (GObjectClass *object_class)
+{
+	parent_class = g_type_class_ref (PARENT_TYPE);
+
+	object_class->finalize = finalize;
+
+	/* signals */
+	signals[EDITED] =
+		g_signal_new ("edited",
+			      G_OBJECT_CLASS_TYPE (object_class),
+			      G_SIGNAL_RUN_LAST,
+			      G_STRUCT_OFFSET (ExchangeDelegatesUserClass, edited),
+			      NULL, NULL,
+			      g_cclosure_marshal_VOID__VOID,
+			      G_TYPE_NONE, 0);
+}
+
+E2K_MAKE_TYPE (exchange_delegates_user, ExchangeDelegatesUser, class_init, NULL, PARENT_TYPE)
+
+static inline gboolean
+is_delegate_role (E2kPermissionsRole role)
+{
+	return (role == E2K_PERMISSIONS_ROLE_NONE ||
+		role == E2K_PERMISSIONS_ROLE_REVIEWER ||
+		role == E2K_PERMISSIONS_ROLE_AUTHOR ||
+		role == E2K_PERMISSIONS_ROLE_EDITOR);
+}
+
+static void
+set_perms (GtkWidget *combobox, E2kPermissionsRole role)
+{
+	if (!is_delegate_role (role)) {
+		gtk_combo_box_append_text (GTK_COMBO_BOX (combobox), _("Custom"));
+		role = EXCHANGE_DELEGATES_USER_CUSTOM;
+	}
+
+	e_dialog_combo_box_set (combobox, role, exchange_perm_map);
+}
+
+static void
+parent_window_destroyed (gpointer dialog, GObject *where_parent_window_was)
+{
+	gtk_dialog_response (dialog, GTK_RESPONSE_CANCEL);
+}
+
+/* Maps the role_nam parameter to their corresponding Full role name
+*/
+static const gchar *
+map_to_full_role_name (E2kPermissionsRole role_nam)
+{
+	const gchar *role_name;
+
+	switch (role_nam)
+	{
+	/* To translators: The following are the various types of permissions that can
+	   assigned by an user to his folders.
+	*/
+		case E2K_PERMISSIONS_ROLE_EDITOR: role_name = g_strdup (
+							_("Editor (read, create, edit)"));
+						  break;
+
+		case E2K_PERMISSIONS_ROLE_AUTHOR: role_name = g_strdup (
+							_("Author (read, create)"));
+						  break;
+
+		case E2K_PERMISSIONS_ROLE_REVIEWER: role_name = g_strdup (
+							_("Reviewer (read-only)"));
+						    break;
+
+		default: role_name = g_strdup (_("None"));
+			 break;
+	}
+
+	return role_name;
+}
+
+static void
+em_utils_delegates_done (CamelFolder *folder, CamelMimeMessage *msg, CamelMessageInfo *info,
+		       gint queued, const gchar *appended_uid, gpointer data)
+{
+	camel_message_info_free (info);
+	mail_send ();
+}
+
+/**
+ * exchange_delegates_user_edit:
+ * @user: a delegate
+ * @parent_window: parent window for the editor dialog
+ *
+ * Brings up a dialog to edit @user's permissions as a delegate.
+ * An %edited signal will be emitted if anything changed.
+ *
+ * Return value: %TRUE for "OK", %FALSE for "Cancel".
+ **/
+gboolean
+exchange_delegates_user_edit (ExchangeAccount *account,
+			     ExchangeDelegatesUser *user,
+			     GtkWidget *parent_window)
+{
+	gchar *title;
+	gint button, i;
+	E2kPermissionsRole role;
+	gboolean modified;
+	GtkWidget *delegate_permissions;
+	GtkWidget *dialog_vbox1;
+	GtkWidget *vbox3;
+	GtkWidget *delegate_label;
+	GtkWidget *folders_table;
+	GtkWidget *calendar_label;
+	GtkWidget *task_label;
+	GtkWidget *inbox_label;
+	GtkWidget *contact_label;
+	GtkWidget *calendar_perms_combobox;
+	GtkWidget *task_perms_combobox;
+	GtkWidget *inbox_perms_combobox;
+	GtkWidget *contact_perms_combobox;
+	GtkWidget *delegate_mail;
+	GtkWidget *see_private_checkbox;
+	GtkWidget *combobox, *comboboxes[EXCHANGE_DELEGATES_LAST];
+
+	g_return_val_if_fail (EXCHANGE_IS_DELEGATES_USER (user), FALSE);
+	g_return_val_if_fail (E2K_IS_SID (user->sid), FALSE);
+
+	delegate_permissions = gtk_dialog_new_with_buttons (
+		_("Delegate Permissions"),
+		NULL,
+		GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_NO_SEPARATOR,
+		GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+		GTK_STOCK_OK, GTK_RESPONSE_OK,
+		NULL);
+
+	if (parent_window)
+		gtk_window_set_transient_for (GTK_WINDOW (delegate_permissions), GTK_WINDOW (parent_window));
+
+	dialog_vbox1 = gtk_dialog_get_content_area (GTK_DIALOG (delegate_permissions));
+	gtk_widget_show (dialog_vbox1);
+
+	vbox3 = gtk_vbox_new (FALSE, 12);
+	gtk_widget_show (vbox3);
+	gtk_box_pack_start (GTK_BOX (dialog_vbox1), vbox3, TRUE, TRUE, 0);
+	gtk_container_set_border_width (GTK_CONTAINER (vbox3), 12);
+
+	delegate_label = gtk_label_new (_("Permissions for"));
+	gtk_widget_show (delegate_label);
+	gtk_box_pack_start (GTK_BOX (vbox3), delegate_label, FALSE, FALSE, 0);
+	gtk_label_set_justify (GTK_LABEL (delegate_label), GTK_JUSTIFY_CENTER);
+
+	folders_table = gtk_table_new (4, 2, FALSE);
+	gtk_widget_show (folders_table);
+	gtk_box_pack_start (GTK_BOX (vbox3), folders_table, FALSE, FALSE, 0);
+	gtk_table_set_row_spacings (GTK_TABLE (folders_table), 6);
+	gtk_table_set_col_spacings (GTK_TABLE (folders_table), 6);
+
+	/* Translators: This is used for permissions for <user> for the folder Calendar. */
+	calendar_label = gtk_label_new_with_mnemonic (_("C_alendar:"));
+	gtk_widget_show (calendar_label);
+	gtk_table_attach (GTK_TABLE (folders_table), calendar_label, 0, 1, 0, 1,
+			  (GtkAttachOptions) (GTK_FILL),
+			  (GtkAttachOptions) (0), 0, 0);
+	gtk_label_set_justify (GTK_LABEL (calendar_label), GTK_JUSTIFY_CENTER);
+	gtk_misc_set_alignment (GTK_MISC (calendar_label), 0, 0.5);
+
+	/* Translators: This is used for permissions for <user> for the folder Tasks. */
+	task_label = gtk_label_new_with_mnemonic (_("_Tasks:"));
+	gtk_widget_show (task_label);
+	gtk_table_attach (GTK_TABLE (folders_table), task_label, 0, 1, 1, 2,
+			  (GtkAttachOptions) (GTK_FILL),
+			  (GtkAttachOptions) (0), 0, 0);
+	gtk_label_set_justify (GTK_LABEL (task_label), GTK_JUSTIFY_CENTER);
+	gtk_misc_set_alignment (GTK_MISC (task_label), 0, 0.5);
+
+	/* Translators: This is used for permissions for <user> for the folder Inbox. */
+	inbox_label = gtk_label_new_with_mnemonic (_("_Inbox:"));
+	gtk_widget_show (inbox_label);
+	gtk_table_attach (GTK_TABLE (folders_table), inbox_label, 0, 1, 2, 3,
+			  (GtkAttachOptions) (GTK_FILL),
+			  (GtkAttachOptions) (0), 0, 0);
+	gtk_label_set_justify (GTK_LABEL (inbox_label), GTK_JUSTIFY_CENTER);
+	gtk_misc_set_alignment (GTK_MISC (inbox_label), 0, 0.5);
+
+	/* Translators: This is used for permissions for <user> for the folder Contacts. */
+	contact_label = gtk_label_new_with_mnemonic (_("Co_ntacts:"));
+	gtk_widget_show (contact_label);
+	gtk_table_attach (GTK_TABLE (folders_table), contact_label, 0, 1, 3, 4,
+			  (GtkAttachOptions) (GTK_FILL),
+			  (GtkAttachOptions) (0), 0, 0);
+	gtk_label_set_justify (GTK_LABEL (contact_label), GTK_JUSTIFY_CENTER);
+	gtk_misc_set_alignment (GTK_MISC (contact_label), 0, 0.5);
+
+	calendar_perms_combobox = gtk_combo_box_new_text ();
+	gtk_widget_show (calendar_perms_combobox);
+	gtk_table_attach (GTK_TABLE (folders_table), calendar_perms_combobox, 1, 2, 0, 1,
+			  (GtkAttachOptions) (GTK_FILL),
+			  (GtkAttachOptions) (GTK_FILL), 0, 0);
+	gtk_combo_box_append_text (GTK_COMBO_BOX (calendar_perms_combobox), _("None"));
+	gtk_combo_box_append_text (GTK_COMBO_BOX (calendar_perms_combobox), _("Reviewer (read-only)"));
+	gtk_combo_box_append_text (GTK_COMBO_BOX (calendar_perms_combobox), _("Author (read, create)"));
+	gtk_combo_box_append_text (GTK_COMBO_BOX (calendar_perms_combobox), _("Editor (read, create, edit)"));
+
+	task_perms_combobox = gtk_combo_box_new_text ();
+	gtk_widget_show (task_perms_combobox);
+	gtk_table_attach (GTK_TABLE (folders_table), task_perms_combobox, 1, 2, 1, 2,
+			  (GtkAttachOptions) (GTK_FILL),
+			  (GtkAttachOptions) (GTK_FILL), 0, 0);
+	gtk_combo_box_append_text (GTK_COMBO_BOX (task_perms_combobox), _("None"));
+	gtk_combo_box_append_text (GTK_COMBO_BOX (task_perms_combobox), _("Reviewer (read-only)"));
+	gtk_combo_box_append_text (GTK_COMBO_BOX (task_perms_combobox), _("Author (read, create)"));
+	gtk_combo_box_append_text (GTK_COMBO_BOX (task_perms_combobox), _("Editor (read, create, edit)"));
+
+	inbox_perms_combobox = gtk_combo_box_new_text ();
+	gtk_widget_show (inbox_perms_combobox);
+	gtk_table_attach (GTK_TABLE (folders_table), inbox_perms_combobox, 1, 2, 2, 3,
+			  (GtkAttachOptions) (GTK_FILL),
+			  (GtkAttachOptions) (GTK_FILL), 0, 0);
+	gtk_combo_box_append_text (GTK_COMBO_BOX (inbox_perms_combobox), _("None"));
+	gtk_combo_box_append_text (GTK_COMBO_BOX (inbox_perms_combobox), _("Reviewer (read-only)"));
+	gtk_combo_box_append_text (GTK_COMBO_BOX (inbox_perms_combobox), _("Author (read, create)"));
+	gtk_combo_box_append_text (GTK_COMBO_BOX (inbox_perms_combobox), _("Editor (read, create, edit)"));
+
+	contact_perms_combobox = gtk_combo_box_new_text ();
+	gtk_widget_show (contact_perms_combobox);
+	gtk_table_attach (GTK_TABLE (folders_table), contact_perms_combobox, 1, 2, 3, 4,
+			  (GtkAttachOptions) (GTK_FILL),
+			  (GtkAttachOptions) (GTK_FILL), 0, 0);
+	gtk_combo_box_append_text (GTK_COMBO_BOX (contact_perms_combobox), _("None"));
+	gtk_combo_box_append_text (GTK_COMBO_BOX (contact_perms_combobox), _("Reviewer (read-only)"));
+	gtk_combo_box_append_text (GTK_COMBO_BOX (contact_perms_combobox), _("Author (read, create)"));
+	gtk_combo_box_append_text (GTK_COMBO_BOX (contact_perms_combobox), _("Editor (read, create, edit)"));
+
+	delegate_mail = gtk_check_button_new_with_mnemonic (_("_Summarize permissions"));
+	gtk_widget_show (delegate_mail);
+	gtk_box_pack_start (GTK_BOX (vbox3), delegate_mail, FALSE, FALSE, 0);
+
+	see_private_checkbox = gtk_check_button_new_with_mnemonic (_("_Delegate can see private items"));
+	gtk_widget_show (see_private_checkbox);
+	gtk_box_pack_start (GTK_BOX (vbox3), see_private_checkbox, FALSE, FALSE, 0);
+
+	gtk_box_set_spacing (GTK_BOX (dialog_vbox1), 6);
+
+	title = g_strdup_printf (_("Permissions for %s"), user->display_name);
+	gtk_label_set_text (GTK_LABEL (delegate_label), title);
+	g_free (title);
+
+	comboboxes[0] = calendar_perms_combobox;
+	comboboxes[1] = task_perms_combobox;
+	comboboxes[2] = inbox_perms_combobox;
+	comboboxes[3] = contact_perms_combobox;
+
+	/* Set up the permissions */
+	for (i = 0; i < EXCHANGE_DELEGATES_LAST; i++) {
+		combobox = comboboxes[i];
+		set_perms (combobox, user->role[i]);
+	}
+
+	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (see_private_checkbox),
+				      user->see_private);
+
+	/* Run the dialog, while watching its parent. */
+	g_object_weak_ref (G_OBJECT (parent_window),
+			   parent_window_destroyed, delegate_permissions);
+	g_object_add_weak_pointer (G_OBJECT (parent_window),
+				   (gpointer*)&parent_window);
+	button = gtk_dialog_run (GTK_DIALOG (delegate_permissions));
+	if (parent_window) {
+		g_object_remove_weak_pointer (G_OBJECT (parent_window),
+					      (gpointer *)&parent_window);
+		g_object_weak_unref (G_OBJECT (parent_window),
+				     parent_window_destroyed, delegate_permissions);
+	}
+
+	if (button != GTK_RESPONSE_OK) {
+		gtk_widget_destroy (delegate_permissions);
+		return FALSE;
+	}
+
+	/* And update */
+	modified = FALSE;
+	for (i = 0; i < EXCHANGE_DELEGATES_LAST; i++) {
+		combobox = comboboxes[i];
+		role = e_dialog_combo_box_get (combobox, exchange_perm_map);
+
+		if (is_delegate_role (user->role[i]) &&
+		    user->role[i] != role) {
+			user->role[i] = role;
+			modified = TRUE;
+		}
+	}
+
+	/* The following piece of code is used to construct a mail message to be sent to a Delegate
+	   summarizing all the permissions set for him on the user's various folders.
+	*/
+	if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (delegate_mail)) == TRUE) {
+		if (button == GTK_RESPONSE_OK) {
+
+			EAccount *eaccount;
+			CamelMimeMessage *delegate_mail = camel_mime_message_new ();
+			CamelMultipart *body = camel_multipart_new ();
+			CamelMimePart *part;
+			CamelDataWrapper *delegate_mail_text, *delegate_mail_data;
+			CamelContentType *type;
+			CamelInternetAddress *addr;
+			CamelStream *stream;
+			CamelFolder *out_folder;
+			CamelMessageInfo *info;
+			gchar *self_address, *delegate_mail_subject;
+			gchar *role_name;
+			GString *role_name_final;
+
+			const gchar *recipient_address;
+			const gchar *delegate_exchange_dn;
+			const gchar *msg_part1 = NULL, *msg_part2 = NULL;
+
+			role_name_final = g_string_new ("");
+
+			self_address = g_strdup (exchange_account_get_email_id (account));
+
+			/* Create toplevel container */
+			camel_data_wrapper_set_mime_type (CAMEL_DATA_WRAPPER (body),
+					"multipart/alternative;");
+			camel_multipart_set_boundary (body, NULL);
+
+			/* Create textual receipt */
+			delegate_mail_text = camel_data_wrapper_new ();
+			type = camel_content_type_new ("text", "html");
+			camel_content_type_set_param (type, "format", "flowed");
+			camel_data_wrapper_set_mime_type_field (delegate_mail_text, type);
+			camel_content_type_unref (type);
+			stream = camel_stream_mem_new ();
+
+			/* To translators: This is a part of the message to be sent to the delegatee
+			   summarizing the permissions assigned to him.
+			*/
+			msg_part1 = _("This message was sent automatically by Evolution to inform you that you have been "
+					"designated as a delegate. You can now send messages on my behalf.");
+
+			/* To translators: Another chunk of the same message.
+			*/
+			msg_part2 = _("You have been given the following permissions on my folders:");
+
+			camel_stream_printf (stream,
+				"<html><body><p>%s<br><br>%s</p><table border = 0 width=\"40%%\">", msg_part1, msg_part2);
+			for (i = 0; i < EXCHANGE_DELEGATES_LAST; i++) {
+				combobox = comboboxes[i];
+				role = e_dialog_combo_box_get (combobox, exchange_perm_map);
+				role_name = g_strdup (map_to_full_role_name(role));
+				g_string_append_printf (
+					role_name_final,
+					"<tr><td>%s:</td><td>%s</td></tr>",
+					folder_names_for_display[i], role_name);
+			}
+
+			camel_stream_printf (stream, "%s</table>", role_name_final->str);
+
+			if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (see_private_checkbox)) == TRUE) {
+				/* To translators: This message is included if the delegatee has been given access
+				   to the private items.
+				*/
+				camel_stream_printf (stream, "<br>%s", _("You are also permitted "
+							"to see my private items."));
+			}
+			else
+				/* To translators: This message is included if the delegatee has not been given access
+				   to the private items.
+				*/
+				camel_stream_printf (stream, "<br>%s", _("However you are not permitted "
+							 "to see my private items."));
+			camel_data_wrapper_construct_from_stream (delegate_mail_text, stream);
+			g_free (role_name);
+			g_string_free (role_name_final, TRUE);
+			camel_object_unref (stream);
+
+			part = camel_mime_part_new ();
+			camel_medium_set_content_object (CAMEL_MEDIUM (part), delegate_mail_text);
+			camel_object_unref (delegate_mail_text);
+			camel_multipart_add_part (body, part);
+			camel_object_unref (part);
+
+			/* Create the machine-readable receipt */
+			delegate_mail_data = camel_data_wrapper_new ();
+			type = camel_content_type_new ("message", "disposition-notification");
+			camel_data_wrapper_set_mime_type_field (delegate_mail_data, type);
+			camel_content_type_unref (type);
+			stream = camel_stream_mem_new ();
+			part = camel_mime_part_new ();
+
+			camel_data_wrapper_construct_from_stream (delegate_mail_data, stream);
+			camel_object_unref (stream);
+			camel_medium_set_content_object (CAMEL_MEDIUM (part), delegate_mail_data);
+			camel_object_unref (delegate_mail_data);
+			camel_multipart_add_part (body, part);
+			camel_object_unref (part);
+
+			/* Finish creating the message */
+			camel_medium_set_content_object (CAMEL_MEDIUM (delegate_mail), CAMEL_DATA_WRAPPER (body));
+			camel_object_unref (body);
+
+			delegate_mail_subject = g_strdup_printf (_("You have been designated "
+						"as a delegate for %s"), exchange_account_get_username (account));
+			camel_mime_message_set_subject (delegate_mail, delegate_mail_subject);
+			g_free (delegate_mail_subject);
+
+			addr = camel_internet_address_new ();
+			camel_address_decode (CAMEL_ADDRESS (addr), self_address);
+			camel_mime_message_set_from (delegate_mail, addr);
+			g_free (self_address);
+			camel_object_unref (addr);
+
+			delegate_exchange_dn = e2k_entryid_to_dn (user->entryid);
+			recipient_address = email_look_up (delegate_exchange_dn,account);
+
+			if (recipient_address) {
+				addr = camel_internet_address_new ();
+				camel_address_decode (CAMEL_ADDRESS (addr), recipient_address);
+				camel_mime_message_set_recipients (delegate_mail, CAMEL_RECIPIENT_TYPE_TO, addr);
+				camel_object_unref (addr);
+			}
+
+			eaccount = exchange_account_fetch (account);
+			if (eaccount) {
+				camel_medium_set_header (CAMEL_MEDIUM (delegate_mail),
+							 "X-Evolution-Account", eaccount->uid);
+				camel_medium_set_header (CAMEL_MEDIUM (delegate_mail),
+							 "X-Evolution-Transport", eaccount->transport->url);
+				camel_medium_set_header (CAMEL_MEDIUM (delegate_mail),
+							 "X-Evolution-Fcc", eaccount->sent_folder_uri);
+			}
+
+			/* Send the permissions summarizing mail */
+			out_folder = e_mail_local_get_folder (E_MAIL_FOLDER_OUTBOX);
+			info = camel_message_info_new (NULL);
+			camel_message_info_set_flags (info, CAMEL_MESSAGE_SEEN, CAMEL_MESSAGE_SEEN);
+			mail_append_mail (out_folder, delegate_mail, info, em_utils_delegates_done, NULL);
+
+		}
+
+	}
+
+	if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (see_private_checkbox)) !=
+	    user->see_private) {
+		user->see_private = !user->see_private;
+		modified = TRUE;
+	}
+
+	gtk_widget_destroy (delegate_permissions);
+
+	if (modified)
+		g_signal_emit (user, signals[EDITED], 0);
+
+	return TRUE;
+}
+
+/**
+ * exchange_delegates_user_new:
+ * @display_name: the delegate's (UTF8) display name
+ *
+ * Return value: a new delegate user with default permissions (but
+ * with most of the internal data blank).
+ **/
+ExchangeDelegatesUser *
+exchange_delegates_user_new (const gchar *display_name)
+{
+	ExchangeDelegatesUser *user;
+	gint i;
+
+	user = g_object_new (EXCHANGE_TYPE_DELEGATES_USER, NULL);
+	user->display_name = g_strdup (display_name);
+
+	for (i = 0; i < EXCHANGE_DELEGATES_LAST; i++) {
+		if (i == EXCHANGE_DELEGATES_CALENDAR ||
+		    i == EXCHANGE_DELEGATES_TASKS)
+			user->role[i] = E2K_PERMISSIONS_ROLE_EDITOR;
+		else
+			user->role[i] = E2K_PERMISSIONS_ROLE_NONE;
+	}
+
+	return user;
+}
+
+/**
+ * exchange_delegates_user_new_from_gc:
+ * @gc: the global catalog object
+ * @email: email address of the new delegate
+ * @creator_entryid: The value of the PR_CREATOR_ENTRYID property
+ * on the LocalFreebusy file.
+ *
+ * Return value: a new delegate user with default permissions and
+ * internal data filled in from the global catalog.
+ **/
+ExchangeDelegatesUser *
+exchange_delegates_user_new_from_gc (E2kGlobalCatalog *gc,
+				    const gchar *email,
+				    GByteArray *creator_entryid)
+{
+	E2kGlobalCatalogStatus status;
+	E2kGlobalCatalogEntry *entry;
+	ExchangeDelegatesUser *user;
+	guint8 *p;
+
+	status = e2k_global_catalog_lookup (
+		gc, NULL, /* FIXME: cancellable */
+		E2K_GLOBAL_CATALOG_LOOKUP_BY_EMAIL, email,
+		(E2K_GLOBAL_CATALOG_LOOKUP_SID |
+		 E2K_GLOBAL_CATALOG_LOOKUP_LEGACY_EXCHANGE_DN),
+		&entry);
+	if (status != E2K_GLOBAL_CATALOG_OK)
+		return NULL;
+
+	user = exchange_delegates_user_new (e2k_sid_get_display_name (entry->sid));
+	user->dn = g_strdup (entry->dn);
+	user->sid = entry->sid;
+	g_object_ref (user->sid);
+
+	user->entryid = g_byte_array_new ();
+	p = creator_entryid->data + creator_entryid->len - 2;
+	while (p > creator_entryid->data && *p)
+		p--;
+	g_byte_array_append (user->entryid, creator_entryid->data,
+			     p - creator_entryid->data + 1);
+	g_byte_array_append (user->entryid, (guint8*)entry->legacy_exchange_dn,
+			     strlen (entry->legacy_exchange_dn));
+	g_byte_array_append (user->entryid, (guint8*)"", 1);
+
+	return user;
+}
diff --git a/eplugin/exchange-delegates-user.h b/eplugin/exchange-delegates-user.h
new file mode 100644
index 0000000..3d886d7
--- /dev/null
+++ b/eplugin/exchange-delegates-user.h
@@ -0,0 +1,81 @@
+/*
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifndef __EXCHANGE_DELEGATES_USER_H__
+#define __EXCHANGE_DELEGATES_USER_H__
+
+#include <exchange-types.h>
+#include <e2k-security-descriptor.h>
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+#define EXCHANGE_TYPE_DELEGATES_USER			(exchange_delegates_user_get_type ())
+#define EXCHANGE_DELEGATES_USER(obj)			(G_TYPE_CHECK_INSTANCE_CAST ((obj), EXCHANGE_TYPE_DELEGATES_USER, ExchangeDelegatesUser))
+#define EXCHANGE_DELEGATES_USER_CLASS(klass)		(G_TYPE_CHECK_CLASS_CAST ((klass), EXCHANGE_TYPE_DELEGATES_USER, ExchangeDelegatesUserClass))
+#define EXCHANGE_IS_DELEGATES_USER(obj)			(G_TYPE_CHECK_INSTANCE_TYPE ((obj), EXCHANGE_TYPE_DELEGATES_USER))
+#define EXCHANGE_IS_DELEGATES_USER_CLASS(klass)		(G_TYPE_CHECK_CLASS_TYPE ((obj), EXCHANGE_TYPE_DELEGATES_USER))
+
+
+typedef struct _ExchangeDelegatesUser        ExchangeDelegatesUser;
+typedef struct _ExchangeDelegatesUserPrivate ExchangeDelegatesUserPrivate;
+typedef struct _ExchangeDelegatesUserClass   ExchangeDelegatesUserClass;
+
+enum {
+	EXCHANGE_DELEGATES_CALENDAR,
+	EXCHANGE_DELEGATES_TASKS,
+	EXCHANGE_DELEGATES_INBOX,
+	EXCHANGE_DELEGATES_CONTACTS,
+	EXCHANGE_DELEGATES_LAST
+};
+
+struct _ExchangeDelegatesUser {
+	GObject parent;
+
+	gchar *display_name, *dn;
+	GByteArray *entryid;
+
+	E2kSid *sid;
+	E2kPermissionsRole role[EXCHANGE_DELEGATES_LAST];
+	gboolean see_private;
+};
+
+struct _ExchangeDelegatesUserClass {
+	GObjectClass parent_class;
+
+	/* signals */
+	void (*edited) (ExchangeDelegatesUser *, gpointer);
+};
+
+
+
+GType    exchange_delegates_user_get_type (void);
+
+ExchangeDelegatesUser *exchange_delegates_user_new         (const gchar            *display_name);
+ExchangeDelegatesUser *exchange_delegates_user_new_from_gc (E2kGlobalCatalog      *gc,
+							    const gchar            *email,
+							    GByteArray            *creator_entryid);
+
+gboolean  exchange_delegates_user_edit (ExchangeAccount  *account, ExchangeDelegatesUser *user,
+					GtkWidget *parent_window);
+
+G_END_DECLS
+
+#endif /* __EXCHANGE_DELEGATES_USER_H__ */
diff --git a/eplugin/exchange-delegates.c b/eplugin/exchange-delegates.c
new file mode 100644
index 0000000..89da03e
--- /dev/null
+++ b/eplugin/exchange-delegates.c
@@ -0,0 +1,1027 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+/* ExchangeDelegates: Exchange delegate handling.
+ *
+ * FIXME: make this instant-apply
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <string.h>
+
+#include "exchange-delegates.h"
+#include "exchange-delegates-user.h"
+#include "exchange-user-dialog.h"
+#include "exchange-operations.h"
+
+#include <exchange-account.h>
+#include <e2k-propnames.h>
+#include <e2k-security-descriptor.h>
+#include <e2k-sid.h>
+#include <e2k-uri.h>
+#include <e2k-utils.h>
+
+#include <e-util/e-dialog-utils.h>
+#include <e-util/e-error.h>
+
+typedef struct {
+	const gchar *uri;
+	E2kSecurityDescriptor *sd;
+	gboolean changed;
+} ExchangeDelegatesFolder;
+
+typedef struct {
+	ExchangeAccount *account;
+	gchar *self_dn;
+
+	GtkWidget *dialog, *parent;
+
+	GtkListStore *model;
+	GtkWidget *table;
+
+	GByteArray *creator_entryid;
+	GPtrArray *users, *added_users, *removed_users;
+	gboolean loaded_folders;
+	ExchangeDelegatesFolder folder[EXCHANGE_DELEGATES_LAST];
+	ExchangeDelegatesFolder freebusy_folder;
+} ExchangeDelegates;
+
+extern const gchar *exchange_delegates_user_folder_names[];
+
+const gchar *exchange_localfreebusy_path = "NON_IPM_SUBTREE/Freebusy%20Data/LocalFreebusy.EML";
+
+static void set_perms_for_user (ExchangeDelegatesUser *user, gpointer user_data);
+
+static void
+set_sd_for_href (ExchangeDelegates *delegates,
+		 const gchar *href,
+		 E2kSecurityDescriptor *sd)
+{
+	gint i;
+
+	for (i = 0; i < EXCHANGE_DELEGATES_LAST; i++) {
+		if (!delegates->folder[i].uri)
+			continue;
+
+		if (!strcmp (href, delegates->folder[i].uri)) {
+			delegates->folder[i].sd = sd;
+			return;
+		}
+	}
+
+	/* else, it's the freebusy folder */
+	delegates->freebusy_folder.uri = g_strdup (href);
+	delegates->freebusy_folder.sd = sd;
+}
+
+/* Given an array of ExchangeDelegatesUser containing display names
+ * and entryids, and an array of E2kSecurityDescriptors containing
+ * SIDs (which contain display names), add SIDs to the delegates. In
+ * the easy case, we can just match the SIDs up with their
+ * corresponding user by display name. However, there are two things
+ * that can go wrong:
+ *
+ *   1. Some users may have been removed from the SDs
+ *   2. Two users may have the same display name
+ *
+ * In both cases, we fall back to using the GC.
+ */
+static gboolean
+fill_in_sids (ExchangeDelegates *delegates)
+{
+	gint u, u2, sd, needed_sids;
+	ExchangeDelegatesUser *user, *user2;
+	GList *sids, *s;
+	E2kSid *sid;
+	E2kGlobalCatalog *gc;
+	E2kGlobalCatalogStatus status;
+	E2kGlobalCatalogEntry *entry;
+	gboolean ok = TRUE;
+
+	needed_sids = 0;
+
+	/* Mark users with duplicate names and count the number of
+	 * non-duplicate names.
+	 */
+	for (u = 0; u < delegates->users->len; u++) {
+		user = delegates->users->pdata[u];
+		if (user->sid == (E2kSid *)-1)
+			continue;
+		for (u2 = u + 1; u2 < delegates->users->len; u2++) {
+			user2 = delegates->users->pdata[u2];
+			if (!strcmp (user->display_name, user2->display_name))
+				user->sid = user2->sid = (E2kSid *)-1;
+		}
+		if (!user->sid)
+			needed_sids++;
+	}
+
+	/* Scan security descriptors trying to match SIDs until we're
+	 * not expecting to find any more.
+	 */
+	for (sd = 0; sd < EXCHANGE_DELEGATES_LAST && needed_sids; sd++) {
+		sids = e2k_security_descriptor_get_sids (delegates->folder[sd].sd);
+		for (s = sids; s && needed_sids; s = s->next) {
+			sid = s->data;
+			for (u = 0; u < delegates->users->len; u++) {
+				user = delegates->users->pdata[u];
+				if (user->sid)
+					continue;
+				if (!strcmp (user->display_name,
+					     e2k_sid_get_display_name (sid))) {
+					user->sid = sid;
+					g_object_ref (sid);
+					needed_sids--;
+				}
+			}
+		}
+		g_list_free (sids);
+	}
+
+	/* Now for each user whose SID hasn't yet been found, look it up. */
+	gc = exchange_account_get_global_catalog (delegates->account);
+	for (u = 0; u < delegates->users->len; u++) {
+		user = delegates->users->pdata[u];
+		if (user->sid && user->sid != (E2kSid *)-1)
+			continue;
+
+		status = e2k_global_catalog_lookup (
+			gc, NULL, /* FIXME: cancellable */
+			E2K_GLOBAL_CATALOG_LOOKUP_BY_LEGACY_EXCHANGE_DN,
+			e2k_entryid_to_dn (user->entryid),
+			E2K_GLOBAL_CATALOG_LOOKUP_SID, &entry);
+		if (status != E2K_GLOBAL_CATALOG_OK) {
+			user->sid = NULL;
+			ok = FALSE;
+			continue;
+		}
+		user->sid = entry->sid;
+		g_object_ref (user->sid);
+		e2k_global_catalog_entry_free (gc, entry);
+	}
+
+	return ok;
+}
+
+static const gchar *sd_props[] = {
+	E2K_PR_EXCHANGE_SD_BINARY,
+	E2K_PR_EXCHANGE_SD_XML
+};
+static const gint n_sd_props = sizeof (sd_props) / sizeof (sd_props[0]);
+
+/* Read the folder security descriptors and match them up with the
+ * list of delegates.
+ */
+static gboolean
+get_folder_security (ExchangeDelegates *delegates)
+{
+	GPtrArray *hrefs;
+	E2kContext *ctx;
+	E2kHTTPStatus status;
+	E2kResultIter *iter;
+	E2kResult *result;
+	xmlNode *xml_form;
+	GByteArray *binary_form;
+	ExchangeDelegatesUser *user;
+	guint32 perms;
+	gint i, u;
+
+	/* If we've been here before, just return the success or
+	 * failure result from last time.
+	 */
+	if (delegates->freebusy_folder.uri)
+		return delegates->loaded_folders;
+
+	if (!exchange_account_get_global_catalog (delegates->account)) {
+		e_error_run (GTK_WINDOW (delegates->table), ERROR_DOMAIN ":delegates-no-gcs-error",
+			     NULL);
+		return FALSE;
+	}
+
+	ctx = exchange_account_get_context (delegates->account);
+
+	hrefs = g_ptr_array_new ();
+	for (i = 0; i < EXCHANGE_DELEGATES_LAST; i++) {
+		delegates->folder[i].uri = exchange_account_get_standard_uri (
+			delegates->account, exchange_delegates_user_folder_names[i]);
+		if (delegates->folder[i].uri) {
+			g_ptr_array_add (hrefs, (gchar *)e2k_uri_relative (
+						 delegates->account->home_uri,
+						 delegates->folder[i].uri));
+		}
+	}
+	g_ptr_array_add (hrefs, (gchar *)exchange_localfreebusy_path);
+
+	iter = e2k_context_bpropfind_start (
+		ctx, NULL, delegates->account->home_uri,
+		(const gchar **)hrefs->pdata, hrefs->len,
+		sd_props, n_sd_props);
+	g_ptr_array_free (hrefs, TRUE);
+
+	while ((result = e2k_result_iter_next (iter))) {
+		xml_form = e2k_properties_get_prop (result->props,
+						    E2K_PR_EXCHANGE_SD_XML);
+		binary_form = e2k_properties_get_prop (result->props,
+						       E2K_PR_EXCHANGE_SD_BINARY);
+
+		if (xml_form && binary_form) {
+			set_sd_for_href (delegates, result->href,
+					 e2k_security_descriptor_new (xml_form, binary_form));
+		}
+	}
+	status = e2k_result_iter_free (iter);
+
+	if (!E2K_HTTP_STATUS_IS_SUCCESSFUL (status)) {
+		e_error_run (GTK_WINDOW (delegates->table), ERROR_DOMAIN ":delegates-perm-read-error",
+			     NULL);
+		return FALSE;
+	}
+
+	if (!fill_in_sids (delegates)) {
+		delegates->loaded_folders = FALSE;
+		e_error_run (GTK_WINDOW (delegates->table), ERROR_DOMAIN ":perm-deter-error", NULL);
+		return FALSE;
+	}
+
+	/* Fill in delegate structures from the security descriptors */
+	for (i = 0; i < EXCHANGE_DELEGATES_LAST; i++) {
+		for (u = 0; u < delegates->users->len; u++) {
+			user = delegates->users->pdata[u];
+			perms = e2k_security_descriptor_get_permissions (
+				delegates->folder[i].sd, user->sid);
+			user->role[i] = e2k_permissions_role_find (perms);
+		}
+	}
+
+	delegates->loaded_folders = TRUE;
+	return TRUE;
+}
+
+static const gchar *delegation_props[] = {
+	PR_DELEGATES_DISPLAY_NAMES,
+	PR_DELEGATES_ENTRYIDS,
+	PR_DELEGATES_SEE_PRIVATE,
+	PR_CREATOR_ENTRYID
+};
+static const gint n_delegation_props = sizeof (delegation_props) / sizeof (delegation_props[0]);
+
+/* Fetch the list of delegates from the freebusy message. */
+static gboolean
+get_user_list (ExchangeDelegates *delegates)
+{
+	E2kContext *ctx;
+	E2kResultIter *iter;
+	E2kResult *result;
+	GPtrArray *display_names, *entryids, *privflags;
+	GByteArray *entryid;
+	ExchangeDelegatesUser *user;
+	gint i;
+
+	ctx = exchange_account_get_context (delegates->account);
+	iter = e2k_context_bpropfind_start (ctx, NULL,
+					    delegates->account->home_uri,
+					    &exchange_localfreebusy_path, 1,
+					    delegation_props, n_delegation_props);
+	result = e2k_result_iter_next (iter);
+	if (!result || !E2K_HTTP_STATUS_IS_SUCCESSFUL (result->status)) {
+		e2k_result_iter_free (iter);
+		return FALSE;
+	}
+
+	delegates->users = g_ptr_array_new ();
+	delegates->added_users = g_ptr_array_new ();
+	delegates->removed_users = g_ptr_array_new ();
+
+	display_names = e2k_properties_get_prop (result->props, PR_DELEGATES_DISPLAY_NAMES);
+	entryids      = e2k_properties_get_prop (result->props, PR_DELEGATES_ENTRYIDS);
+	privflags     = e2k_properties_get_prop (result->props, PR_DELEGATES_SEE_PRIVATE);
+
+	entryid       = e2k_properties_get_prop (result->props, PR_CREATOR_ENTRYID);
+	delegates->creator_entryid = g_byte_array_new ();
+	g_byte_array_append (delegates->creator_entryid, entryid->data, entryid->len);
+
+	if (!display_names || !entryids || !privflags) {
+		e2k_result_iter_free (iter);
+		return TRUE;
+	}
+
+	for (i = 0; i < display_names->len && i < entryids->len && i < privflags->len; i++) {
+		user = exchange_delegates_user_new (display_names->pdata[i]);
+		user->see_private  = privflags->pdata[i] && atoi (privflags->pdata[i]);
+		entryid            = entryids->pdata[i];
+		user->entryid      = g_byte_array_new ();
+		g_byte_array_append (user->entryid, entryid->data, entryid->len);
+
+		g_signal_connect (user, "edited", G_CALLBACK (set_perms_for_user), delegates);
+
+		g_ptr_array_add (delegates->users, user);
+	}
+
+	e2k_result_iter_free (iter);
+	return TRUE;
+}
+
+/* Add or remove a delegate. Everyone must be in one of three states:
+ *   1. only in users (because they started and ended there)
+ *   2. in users and added_users (because they weren't in
+ *      users to begin with, but got added)
+ *   3. only in removed_users (because they were in users to
+ *      begin with and got removed).
+ * If you're added and then removed, or removed and then added, you have
+ * to end up in state 1. That's what this is for.
+ */
+static void
+add_remove_user (ExchangeDelegatesUser *user,
+		 GPtrArray *to_array, GPtrArray *from_array)
+{
+	ExchangeDelegatesUser *match;
+	gint i;
+
+	for (i = 0; i < from_array->len; i++) {
+		match = from_array->pdata[i];
+		if (e2k_sid_binary_sid_equal (e2k_sid_get_binary_sid (match->sid),
+					      e2k_sid_get_binary_sid (user->sid))) {
+			g_ptr_array_remove_index_fast (from_array, i);
+			g_object_unref (match);
+			return;
+		}
+	}
+
+	g_ptr_array_add (to_array, user);
+	g_object_ref (user);
+}
+
+static void
+set_perms_for_user (ExchangeDelegatesUser *user, gpointer user_data)
+{
+	ExchangeDelegates *delegates = user_data;
+	gint i, role;
+	guint32 perms;
+
+	for (i = 0; i < EXCHANGE_DELEGATES_LAST; i++) {
+		perms = e2k_permissions_role_get_perms (user->role[i]);
+		e2k_security_descriptor_set_permissions (delegates->folder[i].sd,
+							 user->sid, perms);
+	}
+	role = user->role[EXCHANGE_DELEGATES_CALENDAR];
+	if (role == E2K_PERMISSIONS_ROLE_AUTHOR)
+		role = E2K_PERMISSIONS_ROLE_EDITOR;
+	perms = e2k_permissions_role_get_perms (role);
+	e2k_security_descriptor_set_permissions (delegates->freebusy_folder.sd,
+						 user->sid, perms);
+}
+
+static void
+add_button_clicked_cb (GtkWidget *widget, gpointer data)
+{
+	ExchangeDelegates *delegates = data;
+	E2kGlobalCatalog *gc;
+	GtkWidget *dialog, *parent_window;
+	const gchar *delegate_exchange_dn;
+	gchar *email;
+	ExchangeDelegatesUser *user, *match;
+	gint response, u;
+	GtkTreeIter iter;
+
+	if (!get_folder_security (delegates))
+		return;
+
+	gc = exchange_account_get_global_catalog (delegates->account);
+
+	parent_window = gtk_widget_get_ancestor (widget, GTK_TYPE_WINDOW);
+	dialog = e2k_user_dialog_new (parent_window,
+				      _("Delegate To:"), _("Delegate To"));
+	response = gtk_dialog_run (GTK_DIALOG (dialog));
+	if (response != GTK_RESPONSE_OK) {
+		gtk_widget_destroy (dialog);
+		return;
+	}
+	email = e2k_user_dialog_get_user (E2K_USER_DIALOG (dialog));
+	gtk_widget_destroy (dialog);
+
+	if (email == NULL)
+		return;
+
+	user = exchange_delegates_user_new_from_gc (gc, email,
+						    delegates->creator_entryid);
+	if (!user) {
+		e_error_run (GTK_WINDOW (parent_window), ERROR_DOMAIN ":delegate-error", email, NULL);
+		g_free (email);
+		return;
+	}
+	g_free (email);
+
+	delegate_exchange_dn = e2k_entryid_to_dn (user->entryid);
+	if (delegate_exchange_dn && !g_ascii_strcasecmp (delegate_exchange_dn, delegates->account->legacy_exchange_dn)) {
+		g_object_unref (user);
+		e_error_run (GTK_WINDOW (parent_window), ERROR_DOMAIN ":delegate-own-error", NULL);
+		return;
+	}
+
+	for (u = 0; u < delegates->users->len; u++) {
+		match = delegates->users->pdata[u];
+		if (e2k_sid_binary_sid_equal (e2k_sid_get_binary_sid (user->sid),
+					      e2k_sid_get_binary_sid (match->sid))) {
+			e_error_run (GTK_WINDOW (parent_window), ERROR_DOMAIN ":delegate-existing",
+				     user->display_name, NULL);
+			g_object_unref (user);
+			exchange_delegates_user_edit (delegates->account, match, parent_window);
+			return;
+		}
+	}
+
+	if (!exchange_delegates_user_edit (delegates->account, user, parent_window)) {
+		g_object_unref (user);
+		return;
+	}
+	set_perms_for_user (user, delegates);
+	g_signal_connect (user, "edited",
+			  G_CALLBACK (set_perms_for_user), delegates);
+
+	add_remove_user (user, delegates->added_users, delegates->removed_users);
+	g_ptr_array_add (delegates->users, user);
+
+	/* Add the user to the table */
+	gtk_list_store_append (delegates->model, &iter);
+	gtk_list_store_set (delegates->model, &iter,
+			    0, user->display_name,
+			    -1);
+}
+
+static gint
+get_selected_row (GtkWidget *tree_view, GtkTreeIter *iter)
+{
+	GtkTreeSelection *selection;
+	GtkTreeModel *model;
+	GtkTreePath *path;
+	gint *indices, row;
+
+	selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (tree_view));
+	if (!gtk_tree_selection_get_selected (selection, &model, iter))
+		return -1;
+
+	path = gtk_tree_model_get_path (model, iter);
+	indices = gtk_tree_path_get_indices (path);
+	row = indices[0];
+	gtk_tree_path_free (path);
+
+	return row;
+}
+
+static void
+edit_button_clicked_cb (GtkWidget *widget, gpointer data)
+{
+	ExchangeDelegates *delegates = data;
+	GtkWidget *parent_window;
+	GtkTreeIter iter;
+	gint row;
+
+	if (!get_folder_security (delegates))
+		return;
+
+	row = get_selected_row (delegates->table, &iter);
+	g_return_if_fail (row >= 0 && row < delegates->users->len);
+
+	parent_window = gtk_widget_get_ancestor (widget, GTK_TYPE_WINDOW);
+
+	exchange_delegates_user_edit (delegates->account, delegates->users->pdata[row],
+				      parent_window);
+}
+
+const gchar *
+email_look_up (const gchar *delegate_legacy, ExchangeAccount *account)
+{
+	E2kGlobalCatalog *gc;
+	E2kGlobalCatalogEntry *entry;
+	E2kGlobalCatalogStatus status;
+
+	const gchar *email_id;
+
+	gc = exchange_account_get_global_catalog (account);
+
+	if (!gc)
+		return NULL;
+
+	status = e2k_global_catalog_lookup (
+			gc, NULL, E2K_GLOBAL_CATALOG_LOOKUP_BY_LEGACY_EXCHANGE_DN,
+			delegate_legacy, 0, &entry);
+
+	email_id = g_strdup (entry->email);
+	e2k_global_catalog_entry_free (gc, entry);
+	return email_id;
+}
+
+static gboolean
+table_click_cb (GtkWidget *widget, GdkEventButton *event, gpointer data)
+{
+	ExchangeDelegates *delegates = data;
+	GtkWidget *parent_window;
+	GtkTreeIter iter;
+	gint row;
+
+	if (event->type != GDK_2BUTTON_PRESS)
+		return FALSE;
+
+	row = get_selected_row (delegates->table, &iter);
+	if (row < 0 || row >= delegates->users->len)
+		return FALSE;
+
+	if (!get_folder_security (delegates))
+		return FALSE;
+
+	parent_window = gtk_widget_get_ancestor (widget, GTK_TYPE_WINDOW);
+	exchange_delegates_user_edit (delegates->account, delegates->users->pdata[row],
+				      parent_window);
+	return TRUE;
+}
+
+static void
+remove_button_clicked_cb (GtkWidget *widget, gpointer data)
+{
+	ExchangeDelegates *delegates = data;
+	ExchangeDelegatesUser *user;
+	GtkWidget *dialog;
+	gint row, btn, i;
+	GtkTreeIter iter;
+
+	if (!get_folder_security (delegates))
+		return;
+
+	row = get_selected_row (delegates->table, &iter);
+	g_return_if_fail (row >= 0 && row < delegates->users->len);
+
+	user = delegates->users->pdata[row];
+
+	dialog = gtk_message_dialog_new (NULL, GTK_DIALOG_MODAL,
+					 GTK_MESSAGE_QUESTION,
+					 GTK_BUTTONS_YES_NO,
+					 _("Remove the delegate %s?"),
+					 user->display_name);
+	gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (gtk_widget_get_toplevel (widget)));
+
+	btn = gtk_dialog_run (GTK_DIALOG (dialog));
+	gtk_widget_destroy (dialog);
+	if (btn != GTK_RESPONSE_YES)
+		return;
+
+	add_remove_user (user, delegates->removed_users, delegates->added_users);
+
+	for (i = 0; i < EXCHANGE_DELEGATES_LAST; i++) {
+		e2k_security_descriptor_remove_sid (delegates->folder[i].sd,
+						    user->sid);
+	}
+	e2k_security_descriptor_remove_sid (delegates->freebusy_folder.sd,
+					    user->sid);
+
+	/* Remove the user from the table */
+	gtk_list_store_remove (delegates->model, &iter);
+	g_ptr_array_remove_index (delegates->users, row);
+	g_object_unref (user);
+}
+
+static gboolean
+proppatch_sd (E2kContext *ctx, ExchangeDelegatesFolder *folder)
+{
+	GByteArray *binsd;
+	E2kProperties *props;
+	const gchar *href = "";
+	E2kResultIter *iter;
+	E2kResult *result;
+	E2kHTTPStatus status;
+
+	binsd = e2k_security_descriptor_to_binary (folder->sd);
+	if (!binsd)
+		return FALSE;
+
+	props = e2k_properties_new ();
+	e2k_properties_set_binary (props, E2K_PR_EXCHANGE_SD_BINARY, binsd);
+
+	iter = e2k_context_bproppatch_start (ctx, NULL, folder->uri,
+					     &href, 1, props, FALSE);
+	e2k_properties_free (props);
+
+	result = e2k_result_iter_next (iter);
+	if (result) {
+		status = result->status;
+		e2k_result_iter_free (iter);
+	} else
+		status = e2k_result_iter_free (iter);
+
+	return E2K_HTTP_STATUS_IS_SUCCESSFUL (status);
+}
+
+static gboolean
+get_user_dn (E2kGlobalCatalog *gc, ExchangeDelegatesUser *user)
+{
+	E2kGlobalCatalogEntry *entry;
+	E2kGlobalCatalogStatus status;
+	const gchar *exchange_dn;
+
+	exchange_dn = e2k_entryid_to_dn (user->entryid);
+	status = e2k_global_catalog_lookup (
+		gc, NULL, /* FIXME: cancellable */
+		E2K_GLOBAL_CATALOG_LOOKUP_BY_LEGACY_EXCHANGE_DN,
+		exchange_dn, 0, &entry);
+	if (status != E2K_GLOBAL_CATALOG_OK)
+		return FALSE;
+
+	user->dn = g_strdup (entry->dn);
+	e2k_global_catalog_entry_free (gc, entry);
+	return TRUE;
+}
+
+static void
+delegates_apply (ExchangeDelegates *delegates)
+{
+	ExchangeDelegatesUser *user;
+	E2kGlobalCatalog *gc;
+	E2kContext *ctx;
+	GPtrArray *display_names, *entryids, *privflags;
+	GByteArray *entryid_dup;
+	gchar *error = NULL;
+	E2kProperties *props;
+	gint i;
+	E2kGlobalCatalogStatus status;
+
+	if (!delegates->loaded_folders)
+		return;
+
+	/* We can't do this atomically/transactionally, so we need to
+	 * make sure that if we fail at any step, things are still in
+	 * a semi-consistent state. So we do:
+	 *
+	 *   1. Remove old delegates from AD
+	 *   2. Update LocalFreebusy.EML (the canonical list of delegates)
+	 *   3. Add new delegates to AD
+	 *   4. Update security descriptors
+	 *
+	 * If step 1 fails, nothing is changed.
+	 *
+	 * If step 2 fails, delegates who should have been removed
+	 * will have been removed from AD but nothing else, so they
+	 * will still show up as being delegates and the user can try
+	 * to remove them again later.
+	 *
+	 * If step 3 fails, delegates who should have been added will
+	 * not be in AD, but will be listed as delegates, so the user
+	 * can remove them and try adding them again later.
+	 *
+	 * If step 4 fails, the user can still correct the folder
+	 * permissions by hand.
+	 */
+
+	gc = exchange_account_get_global_catalog (delegates->account);
+	if (!gc) {
+		error = g_strdup (_("Could not access Active Directory"));
+		goto done;
+	}
+
+	if ((delegates->removed_users || delegates->added_users) && !delegates->self_dn) {
+		E2kGlobalCatalogEntry *entry;
+
+		status = e2k_global_catalog_lookup (
+			gc, NULL, /* FIXME: cancellable */
+			E2K_GLOBAL_CATALOG_LOOKUP_BY_LEGACY_EXCHANGE_DN,
+			delegates->account->legacy_exchange_dn, 0, &entry);
+		if (status != E2K_GLOBAL_CATALOG_OK) {
+			error = g_strdup (_("Could not find self in Active Directory"));
+			goto done;
+		}
+
+		delegates->self_dn = g_strdup (entry->dn);
+		e2k_global_catalog_entry_free (gc, entry);
+	}
+
+	/* 1. Remove old delegates from AD */
+	while (delegates->removed_users && delegates->removed_users->len) {
+		user = delegates->removed_users->pdata[0];
+		if (!user->dn && !get_user_dn (gc, user)) {
+			error = g_strdup_printf (
+				_("Could not find delegate %s in Active Directory"),
+				user->display_name);
+			goto done;
+		}
+
+		/* FIXME: cancellable */
+		status = e2k_global_catalog_remove_delegate (gc, NULL,
+							     delegates->self_dn,
+							     user->dn);
+		if (status != E2K_GLOBAL_CATALOG_OK &&
+		    status != E2K_GLOBAL_CATALOG_NO_DATA) {
+			error = g_strdup_printf (
+				_("Could not remove delegate %s"),
+				user->display_name);
+			goto done;
+		}
+
+		g_object_unref (user);
+		g_ptr_array_remove_index_fast (delegates->removed_users, 0);
+	}
+
+	/* 2. Update LocalFreebusy.EML */
+	ctx = exchange_account_get_context (delegates->account);
+
+	if (delegates->users->len) {
+		display_names = g_ptr_array_new ();
+		entryids = g_ptr_array_new ();
+		privflags = g_ptr_array_new ();
+
+		for (i = 0; i < delegates->users->len; i++) {
+			user = delegates->users->pdata[i];
+			g_ptr_array_add (display_names, g_strdup (user->display_name));
+			entryid_dup = g_byte_array_new ();
+			g_byte_array_append (entryid_dup, user->entryid->data,
+					     user->entryid->len);
+			g_ptr_array_add (entryids, entryid_dup);
+			g_ptr_array_add (privflags, g_strdup_printf ("%d", user->see_private));
+		}
+
+		props = e2k_properties_new ();
+		e2k_properties_set_string_array (
+			props, PR_DELEGATES_DISPLAY_NAMES, display_names);
+		e2k_properties_set_binary_array (
+			props, PR_DELEGATES_ENTRYIDS, entryids);
+		e2k_properties_set_int_array (
+			props, PR_DELEGATES_SEE_PRIVATE, privflags);
+	} else if (delegates->removed_users) {
+		props = e2k_properties_new ();
+		e2k_properties_remove (props, PR_DELEGATES_DISPLAY_NAMES);
+		e2k_properties_remove (props, PR_DELEGATES_ENTRYIDS);
+		e2k_properties_remove (props, PR_DELEGATES_SEE_PRIVATE);
+	} else
+		props = NULL;
+
+	if (props) {
+		E2kResultIter *iter;
+		E2kResult *result;
+
+		iter = e2k_context_bproppatch_start (
+			ctx, NULL, delegates->account->home_uri,
+			&exchange_localfreebusy_path, 1,
+			props, FALSE);
+		e2k_properties_free (props);
+
+		result = e2k_result_iter_next (iter);
+		if (result) {
+			status = result->status;
+			e2k_result_iter_free (iter);
+		} else
+			status = e2k_result_iter_free (iter);
+
+		if (!E2K_HTTP_STATUS_IS_SUCCESSFUL (status)) {
+			error = g_strdup (_("Could not update list of delegates."));
+			goto done;
+		}
+	}
+
+	/* 3. Add new delegates to AD */
+	while (delegates->added_users && delegates->added_users->len) {
+		user = delegates->added_users->pdata[0];
+		/* An added user must have come from the GC so
+		 * we know user->dn is set.
+		 */
+		/* FIXME: cancellable */
+		status = e2k_global_catalog_add_delegate (gc, NULL,
+							  delegates->self_dn,
+							  user->dn);
+		if (status != E2K_GLOBAL_CATALOG_OK &&
+		    status != E2K_GLOBAL_CATALOG_EXISTS) {
+			error = g_strdup_printf (
+				_("Could not add delegate %s"),
+				user->display_name);
+			goto done;
+		}
+		g_ptr_array_remove_index_fast (delegates->added_users, 0);
+		g_object_unref (user);
+	}
+
+	/* 4. Update security descriptors */
+	for (i = 0; i < EXCHANGE_DELEGATES_LAST; i++)
+		proppatch_sd (ctx, &delegates->folder[i]);
+	proppatch_sd (ctx, &delegates->freebusy_folder);
+
+ done:
+	if (error) {
+		e_error_run (GTK_WINDOW (delegates->table), ERROR_DOMAIN ":delegate-fail-error", error, NULL);
+		g_free (error);
+	}
+}
+
+static void parent_destroyed (gpointer user_data, GObject *ex_parent);
+
+static void
+delegates_destroy (ExchangeDelegates *delegates)
+{
+	gint i;
+
+	g_object_unref (delegates->account);
+
+	if (delegates->parent) {
+		g_object_weak_unref (G_OBJECT (delegates->parent),
+				     parent_destroyed, delegates);
+	}
+	if (delegates->dialog)
+		gtk_widget_destroy (delegates->dialog);
+
+	if (delegates->model)
+		g_object_unref (delegates->model);
+
+	if (delegates->self_dn)
+		g_free (delegates->self_dn);
+	if (delegates->creator_entryid)
+		g_byte_array_free (delegates->creator_entryid, TRUE);
+
+	if (delegates->users) {
+		for (i = 0; i < delegates->users->len; i++)
+			g_object_unref (delegates->users->pdata[i]);
+		g_ptr_array_free (delegates->users, TRUE);
+	}
+	if (delegates->added_users) {
+		for (i = 0; i < delegates->added_users->len; i++)
+			g_object_unref (delegates->added_users->pdata[i]);
+		g_ptr_array_free (delegates->added_users, TRUE);
+	}
+	if (delegates->removed_users) {
+		for (i = 0; i < delegates->removed_users->len; i++)
+			g_object_unref (delegates->removed_users->pdata[i]);
+		g_ptr_array_free (delegates->removed_users, TRUE);
+	}
+
+	for (i = 0; i < EXCHANGE_DELEGATES_LAST; i++) {
+		if (delegates->folder[i].sd)
+			g_object_unref (delegates->folder[i].sd);
+	}
+	if (delegates->freebusy_folder.sd)
+		g_object_unref (delegates->freebusy_folder.sd);
+	if (delegates->freebusy_folder.uri)
+		g_free ((gchar *)delegates->freebusy_folder.uri);
+
+	g_free (delegates);
+}
+
+static void
+dialog_response (GtkDialog *dialog, gint response, gpointer user_data)
+{
+	ExchangeDelegates *delegates = user_data;
+
+	if (response == GTK_RESPONSE_OK)
+		delegates_apply (delegates);
+	delegates_destroy (delegates);
+}
+
+static void
+parent_destroyed (gpointer user_data, GObject *ex_parent)
+{
+	ExchangeDelegates *delegates = user_data;
+
+	gtk_widget_destroy (delegates->dialog);
+	delegates_destroy (delegates);
+}
+
+void
+exchange_delegates (ExchangeAccount *account, GtkWidget *parent)
+{
+	GtkWidget *dialog_vbox1;
+	GtkWidget *vbox2;
+	GtkWidget *label3;
+	GtkWidget *delegate_hbox;
+	GtkWidget *delegates_table;
+	GtkWidget *vbuttonbox1;
+	GtkWidget *add_button;
+	GtkWidget *edit_button;
+	GtkWidget *remove_button;
+	ExchangeDelegates *delegates;
+	ExchangeDelegatesUser *user;
+	GtkTreeViewColumn *column;
+	GtkTreeIter iter;
+	gint i;
+
+	g_return_if_fail (GTK_IS_WIDGET (parent));
+	g_return_if_fail (EXCHANGE_IS_ACCOUNT (account));
+
+	delegates = g_new0 (ExchangeDelegates, 1);
+	delegates->account = g_object_ref (account);
+
+	delegates->dialog = gtk_dialog_new_with_buttons (
+		_("Delegates"),
+		NULL,
+		GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_NO_SEPARATOR,
+		GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+		GTK_STOCK_OK, GTK_RESPONSE_OK,
+		NULL);
+
+	dialog_vbox1 = gtk_dialog_get_content_area (GTK_DIALOG (delegates->dialog));
+	gtk_widget_show (dialog_vbox1);
+
+	vbox2 = gtk_vbox_new (FALSE, 6);
+	gtk_widget_show (vbox2);
+	gtk_box_pack_start (GTK_BOX (dialog_vbox1), vbox2, TRUE, TRUE, 0);
+	gtk_container_set_border_width (GTK_CONTAINER (vbox2), 6);
+
+	label3 = gtk_label_new (_("These users will be able to send mail on your behalf\nand access your folders with the permissions you give them."));
+	gtk_widget_show (label3);
+	gtk_box_pack_start (GTK_BOX (vbox2), label3, FALSE, FALSE, 0);
+
+	delegate_hbox = gtk_hbox_new (FALSE, 6);
+	gtk_widget_show (delegate_hbox);
+	gtk_box_pack_start (GTK_BOX (vbox2), delegate_hbox, TRUE, TRUE, 0);
+
+	delegates_table = gtk_tree_view_new ();
+	gtk_widget_show (delegates_table);
+	gtk_box_pack_start (GTK_BOX (delegate_hbox), delegates_table, TRUE, TRUE, 0);
+	gtk_tree_view_set_enable_search (GTK_TREE_VIEW (delegates_table), FALSE);
+
+	vbuttonbox1 = gtk_vbutton_box_new ();
+	gtk_widget_show (vbuttonbox1);
+	gtk_box_pack_end (GTK_BOX (delegate_hbox), vbuttonbox1, FALSE, TRUE, 0);
+	gtk_button_box_set_layout (GTK_BUTTON_BOX (vbuttonbox1), GTK_BUTTONBOX_START);
+	gtk_box_set_spacing (GTK_BOX (vbuttonbox1), 6);
+
+	add_button = gtk_button_new_from_stock ("gtk-add");
+	gtk_widget_show (add_button);
+	gtk_container_add (GTK_CONTAINER (vbuttonbox1), add_button);
+	GTK_WIDGET_SET_FLAGS (add_button, GTK_CAN_DEFAULT);
+
+	edit_button = gtk_button_new_with_mnemonic (_("_Edit"));
+	gtk_widget_show (edit_button);
+	gtk_container_add (GTK_CONTAINER (vbuttonbox1), edit_button);
+	GTK_WIDGET_SET_FLAGS (edit_button, GTK_CAN_DEFAULT);
+
+	remove_button = gtk_button_new_from_stock ("gtk-remove");
+	gtk_widget_show (remove_button);
+	gtk_container_add (GTK_CONTAINER (vbuttonbox1), remove_button);
+	GTK_WIDGET_SET_FLAGS (remove_button, GTK_CAN_DEFAULT);
+
+	g_signal_connect (delegates->dialog, "response",
+			  G_CALLBACK (dialog_response), delegates);
+
+	if (parent)
+		gtk_window_set_transient_for (GTK_WINDOW (delegates->dialog), GTK_WINDOW (parent));
+	delegates->parent = parent;
+	g_object_weak_ref (G_OBJECT (parent), parent_destroyed, delegates);
+
+	/* Set up the buttons */
+	g_signal_connect (add_button, "clicked",
+			  G_CALLBACK (add_button_clicked_cb), delegates);
+	g_signal_connect (edit_button, "clicked",
+			  G_CALLBACK (edit_button_clicked_cb), delegates);
+	g_signal_connect (remove_button, "clicked",
+			  G_CALLBACK (remove_button_clicked_cb), delegates);
+
+	/* Set up the table */
+	delegates->model = gtk_list_store_new (1, G_TYPE_STRING);
+	delegates->table = delegates_table;
+	column = gtk_tree_view_column_new_with_attributes (
+		_("Name"), gtk_cell_renderer_text_new (), "text", 0, NULL);
+	gtk_tree_view_append_column (GTK_TREE_VIEW (delegates->table),
+				     column);
+	gtk_tree_view_set_model (GTK_TREE_VIEW (delegates->table),
+				 GTK_TREE_MODEL (delegates->model));
+
+	/* Get list of delegate users */
+	if (get_user_list (delegates)) {
+		for (i = 0; i < delegates->users->len; i++) {
+			user = delegates->users->pdata[i];
+
+			gtk_list_store_append (delegates->model, &iter);
+			gtk_list_store_set (delegates->model, &iter,
+					    0, user->display_name,
+					    -1);
+		}
+		g_signal_connect (delegates->table,
+				  "button_press_event",
+				  G_CALLBACK (table_click_cb), delegates);
+	} else {
+		gtk_widget_set_sensitive (add_button, FALSE);
+		gtk_widget_set_sensitive (edit_button, FALSE);
+		gtk_widget_set_sensitive (remove_button, FALSE);
+
+		gtk_list_store_append (delegates->model, &iter);
+		gtk_list_store_set (delegates->model, &iter,
+				    0, _("Error reading delegates list."),
+				    -1);
+	}
+
+	gtk_widget_show (delegates->dialog);
+}
diff --git a/eplugin/exchange-delegates.h b/eplugin/exchange-delegates.h
new file mode 100644
index 0000000..ae89047
--- /dev/null
+++ b/eplugin/exchange-delegates.h
@@ -0,0 +1,34 @@
+/*
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifndef __EXCHANGE_DELEGATES_H__
+#define __EXCHANGE_DELEGATES_H__
+
+#include <exchange-types.h>
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+void exchange_delegates (ExchangeAccount *account, GtkWidget *parent);
+const gchar *email_look_up (const gchar *delegate_legacy, ExchangeAccount *account);
+
+G_END_DECLS
+
+#endif /* __EXCHANGE_DELEGATES_CONTROL_H__ */
diff --git a/eplugin/exchange-folder-permission.c b/eplugin/exchange-folder-permission.c
new file mode 100644
index 0000000..200eea8
--- /dev/null
+++ b/eplugin/exchange-folder-permission.c
@@ -0,0 +1,527 @@
+/*
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ *		Shakti Sen <shprasad novell com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <glib/gi18n.h>
+#include <gtk/gtk.h>
+#include <gconf/gconf-client.h>
+
+#include <libedataserverui/e-source-selector.h>
+#include <libebook/e-book.h>
+#include <camel/camel-url.h>
+
+#include <exchange-account.h>
+
+#include <e-util/e-dialog-utils.h>
+#include <calendar/gui/e-cal-model.h>
+
+#include <shell/e-shell-view.h>
+#include <shell/e-shell-window.h>
+
+#include <mail/em-folder-tree.h>
+#include <mail/em-folder-tree-model.h>
+
+#include "exchange-config-listener.h"
+#include "exchange-folder-subscription.h"
+#include "exchange-operations.h"
+#include "exchange-permissions-dialog.h"
+
+#define d(x)
+
+gboolean eex_ui_mail_init (GtkUIManager *ui_manager, EShellView *shell_view);
+gboolean eex_ui_calendar_permissions (GtkUIManager *ui_manager, EShellView *shell_view);
+gboolean eex_ui_tasks_permissions (GtkUIManager *ui_manager, EShellView *shell_view);
+gboolean eex_ui_addressbook_permissions (GtkUIManager *ui_manager, EShellView *shell_view);
+
+static gboolean
+is_subscribed_folder (const gchar *uri)
+{
+	const gchar *path;
+	ExchangeAccount *account;
+	gint offset;
+
+	g_return_val_if_fail (uri != NULL, FALSE);
+
+	account = exchange_operations_get_exchange_account ();
+	g_return_val_if_fail (account != NULL, FALSE);
+	g_return_val_if_fail (account->account_filename != NULL, FALSE);
+
+	offset = strlen ("exchange://") + strlen (account->account_filename) + strlen ("/;");
+	g_return_val_if_fail (strlen (uri) >= offset, FALSE);
+
+	path = uri + offset;
+
+	return strchr (path, '@') != NULL;
+}
+
+static void
+call_folder_permissions (const gchar *uri)
+{
+	ExchangeAccount *account = NULL;
+	EFolder *folder = NULL;
+
+	g_return_if_fail (uri != NULL);
+
+	account = exchange_operations_get_exchange_account ();
+	if (!account)
+		return;
+
+	folder = exchange_account_get_folder (account, uri);
+	if (folder)
+		exchange_permissions_dialog_new (account, folder, NULL);
+}
+
+static gboolean
+is_eex_folder_selected (EShellView *shell_view, gchar **puri)
+{
+	ExchangeAccount *account = NULL;
+	gint mode;
+	EShellSidebar *shell_sidebar;
+	EMFolderTree *folder_tree = NULL;
+	GtkTreeSelection *selection;
+	GtkTreeModel *model = NULL;
+	GtkTreeIter iter;
+	gboolean is_store = FALSE, res;
+	gchar *uri = NULL;
+
+	g_return_val_if_fail (shell_view != NULL, FALSE);
+
+	account = exchange_operations_get_exchange_account ();
+	if (!account)
+		return FALSE;
+
+	exchange_account_is_offline (account, &mode);
+	if (mode == OFFLINE_MODE)
+		return FALSE;
+
+	shell_sidebar = e_shell_view_get_shell_sidebar (shell_view);
+	g_object_get (shell_sidebar, "folder-tree", &folder_tree, NULL);
+	g_return_val_if_fail (folder_tree != NULL, FALSE);
+
+	selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_tree));
+	g_return_val_if_fail (selection != NULL, FALSE);
+
+	if (!gtk_tree_selection_get_selected (selection, &model, &iter))
+		return FALSE;
+
+	gtk_tree_model_get (model, &iter,
+		COL_STRING_URI, &uri,
+		COL_BOOL_IS_STORE, &is_store,
+		-1);
+
+	res = !is_store && uri && g_ascii_strncasecmp (uri, "exchange://", 11) == 0;
+
+	if (res) {
+		const gchar *path;
+
+		path = uri + strlen ("exchange://") + strlen (account->account_filename);
+		res = path && *path;
+
+		if (res) {
+			if (puri)
+				*puri = g_strdup (uri);
+		}
+	}
+
+	g_free (uri);
+
+	return res;
+}
+
+static void
+eex_mail_folder_permissions_cb (GtkAction *action, EShellView *shell_view)
+{
+	gchar *uri = NULL;
+
+	if (is_eex_folder_selected (shell_view, &uri))
+		call_folder_permissions (uri);
+
+	g_free (uri);
+}
+
+static void
+eex_folder_subscribe_cb (GtkAction *action, EShellView *shell_view)
+{
+	const gchar *name;
+
+	name = gtk_action_get_name (action);
+	g_return_if_fail (name != NULL);
+
+	name = strrchr (name, '-');
+	g_return_if_fail (name != NULL && *name == '-');
+
+	call_folder_subscribe (name + 1);
+}
+
+static void
+eex_mail_folder_inbox_unsubscribe_cb (GtkAction *action, EShellView *shell_view)
+{
+	gchar *uri = NULL;
+
+	if (is_eex_folder_selected (shell_view, &uri))
+		call_folder_unsubscribe ("Inbox", uri, NULL);
+
+	g_free (uri);
+}
+
+/* Beware, depends on the order */
+static GtkActionEntry mail_entries[] = {
+	{ "eex-mail-folder-permissions",
+	  "folder-new",
+	  N_("Permissions..."),
+	  NULL,
+	  N_("Check folder permissions"),
+	  G_CALLBACK (eex_mail_folder_permissions_cb) },
+
+	{ "eex-folder-subscribe-Inbox",
+	  NULL,
+	  N_("Subscribe to Other User's Folder..."),
+	  NULL,
+	  N_("Subscribe to Other User's Folder"),
+	  G_CALLBACK (eex_folder_subscribe_cb) },
+
+	{ "eex-mail-folder-inbox-unsubscribe",
+	  "folder-new",
+	  N_("Unsubscribe Folder..."),
+	  NULL,
+	  NULL,
+	  G_CALLBACK (eex_mail_folder_inbox_unsubscribe_cb) }
+};
+
+static void
+update_mail_entries_cb (EShellView *shell_view, gpointer user_data)
+{
+	GtkActionGroup *action_group;
+	EShellWindow *shell_window;
+	GtkAction *action;
+	gboolean is_eex;
+	gchar *uri = NULL;
+	gint i;
+
+	g_return_if_fail (E_IS_SHELL_VIEW (shell_view));
+
+	is_eex = is_eex_folder_selected (shell_view, &uri);
+	shell_window = e_shell_view_get_shell_window (shell_view);
+	action_group = e_shell_window_get_action_group (shell_window, "mail");
+
+	for (i = 0; i < G_N_ELEMENTS (mail_entries); i++) {
+		gboolean visible = is_eex;
+
+		action = gtk_action_group_get_action (action_group, mail_entries[i].name);
+		g_return_if_fail (action != NULL);
+
+		if (visible && i == 2) {
+			/* it's an unsubscribe, check if this is public and show/hide based on that */
+			visible = uri && is_subscribed_folder (uri);
+		}
+
+		gtk_action_set_visible (action, visible);
+	}
+
+	g_free (uri);
+}
+
+gboolean
+eex_ui_mail_init (GtkUIManager *ui_manager, EShellView *shell_view)
+{
+	EShellWindow *shell_window;
+
+	shell_window = e_shell_view_get_shell_window (shell_view);
+
+	gtk_action_group_add_actions (
+		e_shell_window_get_action_group (shell_window, "mail"),
+		mail_entries, G_N_ELEMENTS (mail_entries), shell_view);
+
+	g_signal_connect (shell_view, "update-actions", G_CALLBACK (update_mail_entries_cb), NULL);
+
+	return TRUE;
+}
+
+static gboolean
+is_eex_source_selected (EShellView *shell_view, gchar **puri)
+{
+	gint mode;
+	ExchangeAccount *account = NULL;
+	ESource *source = NULL;
+	gchar *uri = NULL;
+	EShellSidebar *shell_sidebar;
+	ESourceSelector *selector = NULL;
+
+	shell_sidebar = e_shell_view_get_shell_sidebar (shell_view);
+	g_return_val_if_fail (shell_sidebar != NULL, FALSE);
+
+	g_object_get (shell_sidebar, "selector", &selector, NULL);
+	g_return_val_if_fail (selector != NULL, FALSE);
+
+	source = e_source_selector_peek_primary_selection (selector);
+	uri = e_source_get_uri (source);
+
+	g_object_unref (selector);
+
+	if (uri && !g_strrstr (uri, "exchange://")) {
+		g_free (uri);
+		return FALSE;
+	}
+
+	account = exchange_operations_get_exchange_account ();
+	if (!account) {
+		g_free (uri);
+		return FALSE;
+	}
+
+	exchange_account_is_offline (account, &mode);
+	if (mode == OFFLINE_MODE) {
+		g_free (uri);
+		return FALSE;
+	}
+
+	if (!exchange_account_get_folder (account, uri)) {
+		g_free (uri);
+		return FALSE;
+	}
+
+	if (puri)
+		*puri = uri;
+	else
+		g_free (uri);
+
+	return TRUE;
+}
+
+#define NUM_ENTRIES 3
+
+static void
+update_source_entries_cb (EShellView *shell_view, GtkActionEntry *entries)
+{
+	GtkActionGroup *action_group;
+	EShellWindow *shell_window;
+	GtkAction *action;
+	const gchar *group;
+	gchar *uri = NULL;
+	gboolean is_eex;
+	gint i;
+
+	g_return_if_fail (E_IS_SHELL_VIEW (shell_view));
+	g_return_if_fail (entries != NULL);
+
+	if (strstr (entries->name, "calendar"))
+		group = "calendar";
+	else if (strstr (entries->name, "tasks"))
+		group = "tasks";
+	else
+		group = "addressbook";
+
+	is_eex = is_eex_source_selected (shell_view, &uri);
+	shell_window = e_shell_view_get_shell_window (shell_view);
+	action_group = e_shell_window_get_action_group (shell_window, group);
+
+	for (i = 0; i < NUM_ENTRIES; i++) {
+		gboolean visible = is_eex;
+
+		action = gtk_action_group_get_action (action_group, entries->name);
+		g_return_if_fail (action != NULL);
+
+		if (visible && i == 2) {
+			/* it's an unsubscribe, check if this is public and show/hide based on that */
+			visible = uri && is_subscribed_folder (uri);
+		}
+
+		gtk_action_set_visible (action, visible);
+
+	}
+
+	g_free (uri);
+}
+
+static void
+setup_source_actions (EShellView *shell_view, GtkActionEntry *entries)
+{
+	EShellWindow *shell_window;
+	const gchar *group;
+
+	g_return_if_fail (shell_view != NULL);
+	g_return_if_fail (entries != NULL);
+
+	if (strstr (entries->name, "calendar"))
+		group = "calendar";
+	else if (strstr (entries->name, "tasks"))
+		group = "tasks";
+	else
+		group = "addressbook";
+
+	shell_window = e_shell_view_get_shell_window (shell_view);
+
+	gtk_action_group_add_actions (
+		e_shell_window_get_action_group (shell_window, group),
+		entries, NUM_ENTRIES, shell_view);
+
+	g_signal_connect (shell_view, "update-actions", G_CALLBACK (update_source_entries_cb), entries);
+}
+
+static void
+source_permissions_cb (GtkAction *action, EShellView *shell_view)
+{
+	gchar *uri = NULL;
+
+	g_return_if_fail (shell_view != NULL);
+
+	if (is_eex_source_selected (shell_view, &uri))
+		call_folder_permissions (uri);
+
+	g_free (uri);
+}
+
+static void
+eex_folder_unsubscribe_cb (GtkAction *action, EShellView *shell_view)
+{
+	gchar *uri = NULL;
+	const gchar *name;
+
+	g_return_if_fail (shell_view != NULL);
+
+	name = gtk_action_get_name (action);
+	g_return_if_fail (name != NULL);
+
+	name = strrchr (name, '-');
+	g_return_if_fail (name != NULL && *name == '-');
+
+	if (is_eex_source_selected (shell_view, &uri)) {
+		EShellSidebar *shell_sidebar;
+		ESourceSelector *selector = NULL;
+
+		shell_sidebar = e_shell_view_get_shell_sidebar (shell_view);
+		g_return_if_fail (shell_sidebar != NULL);
+
+		g_object_get (shell_sidebar, "selector", &selector, NULL);
+		g_return_if_fail (selector != NULL);
+
+		call_folder_unsubscribe (name + 1, uri, e_source_selector_peek_primary_selection (selector));
+	}
+
+	g_free (uri);
+}
+
+/* Beware, depends on count and order */
+static GtkActionEntry calendar_entries[] = {
+	{ "eex-calendar-permissions",
+	  "folder-new",
+	  N_("Permissions..."),
+	  NULL,
+	  N_("Check calendar permissions"),
+	  G_CALLBACK (source_permissions_cb) },
+
+	{ "eex-folder-subscribe-Calendar",
+	  NULL,
+	  N_("Subscribe to Other User's Folder..."),
+	  NULL,
+	  N_("Subscribe to Other User's Folder"),
+	  G_CALLBACK (eex_folder_subscribe_cb) },
+
+	{ "eex-folder-unsubscribe-Calendar",
+	  "folder-new",
+	  N_("Unsubscribe Folder..."),
+	  NULL,
+	  NULL,
+	  G_CALLBACK (eex_folder_unsubscribe_cb) }
+};
+
+gboolean
+eex_ui_calendar_permissions (GtkUIManager *ui_manager, EShellView *shell_view)
+{
+	g_return_val_if_fail (G_N_ELEMENTS (calendar_entries) != NUM_ENTRIES, FALSE);
+
+	setup_source_actions (shell_view, calendar_entries);
+
+	return TRUE;
+}
+
+/* Beware, depends on count and order */
+static GtkActionEntry tasks_entries[] = {
+	{ "eex-tasks-permissions",
+	  "folder-new",
+	  N_("Permissions..."),
+	  NULL,
+	  N_("Check tasks permissions"),
+	  G_CALLBACK (source_permissions_cb) },
+
+	{ "eex-folder-subscribe-Tasks",
+	  NULL,
+	  N_("Subscribe to Other User's Folder..."),
+	  NULL,
+	  N_("Subscribe to Other User's Folder"),
+	  G_CALLBACK (eex_folder_subscribe_cb) },
+
+	{ "eex-folder-unsubscribe-Tasks",
+	  "folder-new",
+	  N_("Unsubscribe Folder..."),
+	  NULL,
+	  NULL,
+	  G_CALLBACK (eex_folder_unsubscribe_cb) }
+};
+
+gboolean
+eex_ui_tasks_permissions (GtkUIManager *ui_manager, EShellView *shell_view)
+{
+	g_return_val_if_fail (G_N_ELEMENTS (tasks_entries) != NUM_ENTRIES, FALSE);
+
+	setup_source_actions (shell_view, tasks_entries);
+
+	return TRUE;
+}
+
+/* Beware, depends on count and order */
+static GtkActionEntry addressbook_entries[] = {
+	{ "eex-addressbook-permissions",
+	  "folder-new",
+	  N_("Permissions..."),
+	  NULL,
+	  N_("Check addressbook permissions"),
+	  G_CALLBACK (source_permissions_cb) },
+
+	{ "eex-folder-subscribe-Contacts",
+	  NULL,
+	  N_("Subscribe to Other User's Folder..."),
+	  NULL,
+	  N_("Subscribe to Other User's Folder"),
+	  G_CALLBACK (eex_folder_subscribe_cb) },
+
+	{ "eex-folder-unsubscribe-Contacts",
+	  "folder-new",
+	  N_("Unsubscribe Folder..."),
+	  NULL,
+	  NULL,
+	  G_CALLBACK (eex_folder_unsubscribe_cb) }
+};
+
+gboolean
+eex_ui_addressbook_permissions (GtkUIManager *ui_manager, EShellView *shell_view)
+{
+	g_return_val_if_fail (G_N_ELEMENTS (addressbook_entries) != NUM_ENTRIES, FALSE);
+
+	setup_source_actions (shell_view, addressbook_entries);
+
+	return TRUE;
+}
diff --git a/eplugin/exchange-folder-size-display.c b/eplugin/exchange-folder-size-display.c
new file mode 100644
index 0000000..325483f
--- /dev/null
+++ b/eplugin/exchange-folder-size-display.c
@@ -0,0 +1,170 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+/* ExchangeFolderSize: Display the folder tree with the folder sizes */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <string.h>
+
+#include <glib/gi18n.h>
+#include <e-util/e-dialog-utils.h>
+#include "exchange-folder-size-display.h"
+
+enum {
+        COLUMN_NAME,
+        COLUMN_SIZE,
+        NUM_COLUMNS
+};
+
+static gboolean
+get_folder_size_func (GtkTreeModel *model,
+		  GtkTreePath	    *path,
+                  GtkTreeIter       *iter,
+                 gpointer           user_data)
+{
+	GHashTable *info = (GHashTable *) user_data;
+	gdouble folder_size;
+	gchar *folder_name;
+
+	gtk_tree_model_get(model, iter, COLUMN_SIZE, &folder_size, COLUMN_NAME, &folder_name, -1);
+
+	g_hash_table_insert (info, g_strdup (folder_name), g_strdup_printf ("%.2f", folder_size));
+	return FALSE;
+}
+
+gchar *
+exchange_folder_size_get_val (GtkListStore *model, const gchar *folder_name)
+{
+	GHashTable *finfo;
+	gchar *folder_size, *fsize;
+
+	finfo = g_hash_table_new_full (
+		g_str_hash, g_str_equal,
+		(GDestroyNotify) g_free,
+		(GDestroyNotify) g_free);
+
+	gtk_tree_model_foreach (GTK_TREE_MODEL (model), get_folder_size_func, finfo);
+
+	if ((fsize = g_hash_table_lookup (finfo, folder_name)) != NULL)
+		folder_size = g_strdup (fsize);
+	else
+		folder_size = g_strdup ("0");
+
+	g_hash_table_destroy (finfo);
+
+	return folder_size;
+}
+
+static void
+format_size_func (GtkTreeViewColumn *col,
+                  GtkCellRenderer   *renderer,
+                  GtkTreeModel      *model,
+                  GtkTreeIter       *iter,
+                 gpointer           user_data)
+{
+	GtkCellRendererText *cell = (GtkCellRendererText *)renderer;
+	gdouble folder_size;
+	gchar * new_text;
+
+	gtk_tree_model_get(model, iter, COLUMN_SIZE, &folder_size, -1);
+
+	if (folder_size)
+		new_text = g_strdup_printf ("%.2f", folder_size);
+	else
+		new_text = g_strdup ("0");
+
+	g_object_set (cell, "text", new_text, NULL);
+	g_free (new_text);
+}
+
+void
+exchange_folder_size_display (GtkListStore *model, GtkWidget *parent)
+{
+        GtkTreeViewColumn *column;
+	GtkTreeSortable *sortable;
+	GtkCellRenderer *cell;
+	GtkWidget *folder_tree;
+	GtkWidget *dialog_vbox1;
+	GtkWidget *folder_tree_hbox;
+	GtkWidget *scrolledwindow1;
+	GtkWidget *folder_treeview;
+	GList *l;
+	gchar *col_name;
+
+        g_return_if_fail (GTK_IS_WIDGET (parent));
+
+	folder_tree = gtk_dialog_new_with_buttons (
+		_("Exchange Folder Tree"),
+		NULL,
+		GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_NO_SEPARATOR,
+		GTK_STOCK_OK, GTK_RESPONSE_OK,
+		NULL);
+	gtk_window_set_position (GTK_WINDOW (folder_tree), GTK_WIN_POS_CENTER_ON_PARENT);
+	gtk_window_set_default_size (GTK_WINDOW (folder_tree), 250, 300);
+	if (parent)
+		gtk_window_set_transient_for (GTK_WINDOW (folder_tree), GTK_WINDOW (parent));
+
+	dialog_vbox1 = gtk_dialog_get_content_area (GTK_DIALOG (folder_tree));
+	gtk_widget_show (dialog_vbox1);
+
+	folder_tree_hbox = gtk_hbox_new (FALSE, 0);
+	gtk_widget_show (folder_tree_hbox);
+	gtk_box_pack_start (GTK_BOX (dialog_vbox1), folder_tree_hbox, TRUE, TRUE, 0);
+
+	scrolledwindow1 = gtk_scrolled_window_new (NULL, NULL);
+	gtk_widget_show (scrolledwindow1);
+	gtk_box_pack_start (GTK_BOX (folder_tree_hbox), scrolledwindow1, TRUE, TRUE, 0);
+
+	folder_treeview = gtk_tree_view_new ();
+	gtk_widget_show (folder_treeview);
+	gtk_container_add (GTK_CONTAINER (scrolledwindow1), folder_treeview);
+
+	/* fsize->parent = parent; */
+
+        /* Set up the table */
+	sortable = GTK_TREE_SORTABLE (model);
+	gtk_tree_sortable_set_sort_column_id (sortable, COLUMN_SIZE, GTK_SORT_DESCENDING);
+
+        column = gtk_tree_view_column_new_with_attributes (
+                _("Folder Name"), gtk_cell_renderer_text_new (), "text", COLUMN_NAME, NULL);
+        gtk_tree_view_append_column (GTK_TREE_VIEW (folder_treeview),
+                                     column);
+
+	col_name = g_strdup_printf ("%s (KB)", _("Folder Size"));
+        column = gtk_tree_view_column_new_with_attributes (
+                col_name, gtk_cell_renderer_text_new (), "text", COLUMN_SIZE, NULL);
+	g_free (col_name);
+
+	l = gtk_cell_layout_get_cells (GTK_CELL_LAYOUT (column));
+	cell = (GtkCellRenderer *)l->data;
+	gtk_tree_view_column_set_cell_data_func (column, cell, format_size_func, NULL, NULL );
+	g_list_free (l);
+
+        gtk_tree_view_append_column (GTK_TREE_VIEW (folder_treeview),
+                                     column);
+        gtk_tree_view_set_model (GTK_TREE_VIEW (folder_treeview),
+                                 GTK_TREE_MODEL (model));
+	gtk_dialog_run (GTK_DIALOG (folder_tree));
+        gtk_widget_destroy (folder_tree);
+}
diff --git a/eplugin/exchange-folder-size-display.h b/eplugin/exchange-folder-size-display.h
new file mode 100644
index 0000000..13d112c
--- /dev/null
+++ b/eplugin/exchange-folder-size-display.h
@@ -0,0 +1,33 @@
+/*
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifndef __EXCHANGE_FOLDER_SIZE_DISPLAY_H__
+#define __EXCHANGE_FOLDER_SIZE_DISPLAY_H__
+
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+void exchange_folder_size_display (GtkListStore *model, GtkWidget *parent);
+gchar * exchange_folder_size_get_val (GtkListStore *model, const gchar *folder_name);
+
+G_END_DECLS
+
+#endif /* __EXCHANGE_FOLDER_SIZE_DISPLAY_H__ */
diff --git a/eplugin/exchange-folder-subscription.c b/eplugin/exchange-folder-subscription.c
new file mode 100644
index 0000000..63d2fb2
--- /dev/null
+++ b/eplugin/exchange-folder-subscription.c
@@ -0,0 +1,380 @@
+/*
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ *		Shakti Sen <shprasad novell com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gtk/gtk.h>
+#include <e-util/e-error.h>
+#include <e-folder.h>
+#include <exchange-account.h>
+#include <exchange-hierarchy.h>
+#include "exchange-hierarchy-foreign.h"
+#include <e2k-types.h>
+#include <exchange-types.h>
+#include <e2k-propnames.h>
+#include <libedataserverui/e-name-selector.h>
+#include "exchange-config-listener.h"
+#include "exchange-folder-subscription.h"
+#include "exchange-operations.h"
+
+static void
+user_response (ENameSelectorDialog *name_selector_dialog, gint response, gpointer data)
+{
+	gtk_widget_hide (GTK_WIDGET (name_selector_dialog));
+}
+
+static void
+user_clicked (GtkWidget *button, ENameSelector *name_selector)
+{
+	ENameSelectorDialog *name_selector_dialog;
+
+	name_selector_dialog = e_name_selector_peek_dialog (name_selector);
+	gtk_window_set_modal (GTK_WINDOW (name_selector_dialog), TRUE);
+	gtk_widget_show (GTK_WIDGET (name_selector_dialog));
+}
+
+static GtkWidget *
+setup_name_selector (GtkWidget *placeholder, GtkWidget *button_user, ENameSelector **name_selector_ret)
+{
+	ENameSelector *name_selector;
+	ENameSelectorModel *name_selector_model;
+	ENameSelectorDialog *name_selector_dialog;
+	GtkWidget *widget;
+
+	g_assert (GTK_IS_CONTAINER (placeholder));
+
+	name_selector = e_name_selector_new ();
+
+	name_selector_model = e_name_selector_peek_model (name_selector);
+	/* FIXME Limit to one user */
+	e_name_selector_model_add_section (name_selector_model, "User", _("User"), NULL);
+
+	/* Listen for responses whenever the dialog is shown */
+	name_selector_dialog = e_name_selector_peek_dialog (name_selector);
+	g_signal_connect (name_selector_dialog, "response",
+			  G_CALLBACK (user_response), name_selector);
+
+	widget = GTK_WIDGET (e_name_selector_peek_section_entry (name_selector, "User"));
+	gtk_widget_show (widget);
+
+	g_signal_connect (button_user, "clicked", G_CALLBACK (user_clicked), name_selector);
+	gtk_box_pack_start (GTK_BOX (placeholder), widget, TRUE, TRUE, 6);
+	*name_selector_ret = name_selector;
+
+	return widget;
+}
+
+static void
+setup_folder_name_combo (GtkWidget *widget, const gchar *fname)
+{
+	GtkComboBox *combo;
+	const gchar *strings[] = {
+		"Calendar",
+		"Inbox",
+		"Contacts",
+		"Tasks",
+		NULL
+		/* FIXME: Should these be translated?  */
+	};
+	gint i;
+
+	combo = GTK_COMBO_BOX (widget);
+	g_assert (GTK_IS_COMBO_BOX_ENTRY (combo));
+
+	gtk_list_store_clear (GTK_LIST_STORE (gtk_combo_box_get_model (combo)));
+
+	for (i = 0; strings[i] != NULL; i ++)
+		gtk_combo_box_append_text (combo, strings[i]);
+
+	gtk_entry_set_text (GTK_ENTRY (gtk_bin_get_child (GTK_BIN (combo))), fname);
+}
+
+static void
+folder_name_entry_changed_callback (GtkEditable *editable,
+                                    gpointer data)
+{
+	GtkDialog *dialog = GTK_DIALOG (data);
+	const gchar *folder_name_text = gtk_entry_get_text (GTK_ENTRY (editable));
+
+	if (*folder_name_text == '\0')
+		gtk_dialog_set_response_sensitive (dialog, GTK_RESPONSE_OK, FALSE);
+	else
+		gtk_dialog_set_response_sensitive (dialog, GTK_RESPONSE_OK, TRUE);
+}
+
+static void
+user_name_entry_changed_callback (GtkEditable *editable, gpointer data)
+{
+	GtkDialog *dialog = GTK_DIALOG (data);
+	const gchar *user_name_text = gtk_entry_get_text (GTK_ENTRY (editable));
+
+	if (*user_name_text == '\0')
+		gtk_dialog_set_response_sensitive (dialog, GTK_RESPONSE_OK, FALSE);
+	else
+		gtk_dialog_set_response_sensitive (dialog, GTK_RESPONSE_OK, TRUE);
+}
+
+static void
+setup_server_combobox (GtkWidget *widget, gchar *mail_account)
+{
+	g_return_if_fail (GTK_IS_COMBO_BOX (widget));
+
+	gtk_list_store_clear (GTK_LIST_STORE (gtk_combo_box_get_model (GTK_COMBO_BOX (widget))));
+
+	gtk_combo_box_append_text (GTK_COMBO_BOX (widget), mail_account);
+	gtk_combo_box_set_active (GTK_COMBO_BOX (widget), 0);
+
+	/* FIXME: Default to the current storage in the shell view.  */
+}
+
+typedef struct {
+	ExchangeAccount *account;
+	ENameSelector *name_selector;
+	GtkWidget *name_selector_widget;
+	GtkWidget *folder_name_entry;
+}SubscriptionInfo;
+
+static void
+destroy_subscription_info (SubscriptionInfo *subscription_info)
+{
+	if (subscription_info->name_selector) {
+		g_object_unref (subscription_info->name_selector);
+		subscription_info->name_selector = NULL;
+	}
+	g_free (subscription_info);
+}
+
+static void
+subscribe_to_folder (GtkWidget *dialog, gint response, gpointer data)
+{
+	SubscriptionInfo *subscription_info = data;
+	gchar *user_email_address = NULL, *folder_name = NULL, *path = NULL;
+	gchar *subscriber_email;
+	EFolder *folder = NULL;
+	EDestinationStore *destination_store;
+	GList *destinations;
+	EDestination *destination;
+	ExchangeAccountFolderResult result;
+
+	if (response == GTK_RESPONSE_CANCEL) {
+		gtk_widget_destroy (dialog);
+		destroy_subscription_info (subscription_info);
+	}
+	else if (response == GTK_RESPONSE_OK) {
+		while (TRUE) {
+			destination_store = e_name_selector_entry_peek_destination_store (
+						E_NAME_SELECTOR_ENTRY (GTK_ENTRY (subscription_info->name_selector_widget)));
+			destinations = e_destination_store_list_destinations (destination_store);
+			if (!destinations)
+				break;
+			destination = destinations->data;
+			user_email_address = g_strdup (e_destination_get_email (destination));
+			g_list_free (destinations);
+
+			if (user_email_address != NULL && *user_email_address != '\0')
+				break;
+
+			/* check if user is trying to subscribe to his own folder */
+			subscriber_email = exchange_account_get_email_id (subscription_info->account);
+			if (subscriber_email != NULL && *subscriber_email != '\0') {
+				if (g_str_equal (subscriber_email, user_email_address)) {
+					e_error_run (NULL, ERROR_DOMAIN ":folder-exists-error", NULL);
+					g_free (user_email_address);
+					gtk_widget_destroy (dialog);
+					destroy_subscription_info (subscription_info);
+					return;
+				}
+			}
+
+			/* It would be nice to insensitivize the OK button appropriately
+			instead of doing this, but unfortunately we can't do this for the
+			Bonobo control.  */
+			e_error_run (GTK_WINDOW (dialog), ERROR_DOMAIN ":select-user", NULL);
+		}
+
+		folder_name = g_strdup (gtk_entry_get_text (GTK_ENTRY (subscription_info->folder_name_entry)));
+		if (user_email_address && folder_name) {
+			result = exchange_account_discover_shared_folder (subscription_info->account,
+									  user_email_address,
+									  folder_name, &folder);
+			g_free (folder_name);
+			gtk_widget_hide (dialog);
+			switch (result) {
+				case EXCHANGE_ACCOUNT_FOLDER_OK:
+					exchange_account_rescan_tree (subscription_info->account);
+					if (!g_ascii_strcasecmp (e_folder_get_type_string (folder), "mail"))
+						e_error_run (NULL, ERROR_DOMAIN ":folder-restart-evo", NULL);
+					break;
+				case EXCHANGE_ACCOUNT_FOLDER_ALREADY_EXISTS:
+					e_error_run (NULL, ERROR_DOMAIN ":folder-exists-error", NULL);
+					break;
+				case EXCHANGE_ACCOUNT_FOLDER_DOES_NOT_EXIST:
+					e_error_run (NULL, ERROR_DOMAIN ":folder-doesnt-exist-error", NULL);
+					break;
+				case EXCHANGE_ACCOUNT_FOLDER_UNKNOWN_TYPE:
+					e_error_run (NULL, ERROR_DOMAIN ":folder-unknown-type", NULL);
+					break;
+				case EXCHANGE_ACCOUNT_FOLDER_PERMISSION_DENIED:
+					e_error_run (NULL, ERROR_DOMAIN ":folder-perm-error", NULL);
+					break;
+				case EXCHANGE_ACCOUNT_FOLDER_OFFLINE:
+					e_error_run (NULL, ERROR_DOMAIN ":folder-offline-error", NULL);
+					break;
+				case EXCHANGE_ACCOUNT_FOLDER_UNSUPPORTED_OPERATION:
+					e_error_run (NULL, ERROR_DOMAIN ":folder-unsupported-error", NULL);
+					break;
+				case EXCHANGE_ACCOUNT_FOLDER_GC_NOTREACHABLE:
+					e_error_run (NULL, ERROR_DOMAIN ":folder-no-gc-error", NULL);
+					break;
+				case EXCHANGE_ACCOUNT_FOLDER_NO_SUCH_USER:
+					e_error_run (NULL, ERROR_DOMAIN ":no-user-error", user_email_address, NULL);
+					break;
+				case EXCHANGE_ACCOUNT_FOLDER_GENERIC_ERROR:
+					e_error_run (NULL, ERROR_DOMAIN ":folder-generic-error", NULL);
+					break;
+				default:
+					break;
+			}
+		}
+
+		if (!folder) {
+			g_free (user_email_address);
+			gtk_widget_destroy (dialog);
+			return;
+		}
+
+		g_object_unref (folder);
+		path = g_strdup_printf ("/%s", user_email_address);
+		exchange_account_open_folder (subscription_info->account, path);
+		g_free (path);
+		g_free (user_email_address);
+		gtk_widget_destroy (dialog);
+		destroy_subscription_info (subscription_info);
+	}
+}
+
+gboolean
+create_folder_subscription_dialog (ExchangeAccount *account, const gchar *fname)
+{
+	ENameSelector *name_selector;
+	GtkWidget *dialog;
+	GtkWidget *dialog_vbox1;
+	GtkWidget *table1;
+	GtkWidget *label1;
+	GtkWidget *label3;
+	GtkWidget *user_picker_placeholder;
+	GtkWidget *button_user;
+	GtkWidget *folder_name_combo;
+	GtkWidget *server_combobox;
+	SubscriptionInfo *subscription_info;
+	gint mode;
+
+	exchange_account_is_offline (account, &mode);
+	if (mode == OFFLINE_MODE)
+		return FALSE;
+
+	subscription_info = g_new0 (SubscriptionInfo, 1);
+	subscription_info->account = account;
+
+	dialog = gtk_dialog_new_with_buttons (
+		_("Subscribe to Other User's Folder"),
+		NULL,
+		GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_NO_SEPARATOR,
+		GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+		GTK_STOCK_OK, GTK_RESPONSE_OK,
+		NULL);
+
+	dialog_vbox1 = gtk_dialog_get_content_area (GTK_DIALOG (dialog));
+	gtk_widget_show (dialog_vbox1);
+
+	table1 = gtk_table_new (3, 2, FALSE);
+	gtk_widget_show (table1);
+	gtk_box_pack_start (GTK_BOX (dialog_vbox1), table1, TRUE, TRUE, 2);
+	gtk_table_set_row_spacings (GTK_TABLE (table1), 3);
+	gtk_table_set_col_spacings (GTK_TABLE (table1), 3);
+
+	label1 = gtk_label_new_with_mnemonic (_("_Account:"));
+	gtk_widget_show (label1);
+	gtk_table_attach (GTK_TABLE (table1), label1, 0, 1, 0, 1,
+			  (GtkAttachOptions) (GTK_FILL),
+			  (GtkAttachOptions) (0), 0, 0);
+	gtk_label_set_justify (GTK_LABEL (label1), GTK_JUSTIFY_CENTER);
+
+	label3 = gtk_label_new_with_mnemonic (_("_Folder Name:"));
+	gtk_widget_show (label3);
+	gtk_table_attach (GTK_TABLE (table1), label3, 0, 1, 2, 3,
+			  (GtkAttachOptions) (GTK_FILL),
+			  (GtkAttachOptions) (0), 0, 0);
+	gtk_label_set_justify (GTK_LABEL (label3), GTK_JUSTIFY_CENTER);
+
+	user_picker_placeholder = gtk_hbox_new (FALSE, 0);
+	gtk_widget_show (user_picker_placeholder);
+	gtk_table_attach (GTK_TABLE (table1), user_picker_placeholder, 1, 2, 1, 2,
+			  (GtkAttachOptions) (GTK_FILL),
+			  (GtkAttachOptions) (0), 0, 0);
+
+	button_user = gtk_button_new_with_mnemonic (_("_User:"));
+	gtk_widget_show (button_user);
+	gtk_table_attach (GTK_TABLE (table1), button_user, 0, 1, 1, 2,
+			  (GtkAttachOptions) (GTK_FILL),
+			  (GtkAttachOptions) (0), 0, 0);
+
+	folder_name_combo = gtk_combo_box_entry_new_text ();
+	gtk_widget_show (folder_name_combo);
+	gtk_table_attach (GTK_TABLE (table1), folder_name_combo, 1, 2, 2, 3,
+			  (GtkAttachOptions) (GTK_FILL),
+			  (GtkAttachOptions) (GTK_FILL), 0, 0);
+
+	server_combobox = gtk_combo_box_new_text ();
+	gtk_widget_show (server_combobox);
+	gtk_table_attach (GTK_TABLE (table1), server_combobox, 1, 2, 0, 1,
+			  (GtkAttachOptions) (GTK_FILL),
+			  (GtkAttachOptions) (GTK_FILL), 0, 0);
+
+	gtk_window_set_modal (GTK_WINDOW (dialog), FALSE);
+
+	subscription_info->name_selector_widget = setup_name_selector (user_picker_placeholder, button_user, &name_selector);
+	subscription_info->name_selector = name_selector;
+	gtk_widget_grab_focus (subscription_info->name_selector_widget);
+
+	gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog), GTK_RESPONSE_OK, FALSE);
+	g_signal_connect (subscription_info->name_selector_widget, "changed",
+			  G_CALLBACK (user_name_entry_changed_callback), dialog);
+
+	setup_server_combobox (server_combobox, account->account_name);
+	setup_folder_name_combo (folder_name_combo, fname);
+	subscription_info->folder_name_entry = gtk_bin_get_child (GTK_BIN (folder_name_combo));
+	g_signal_connect (dialog, "response", G_CALLBACK (subscribe_to_folder), subscription_info);
+	gtk_widget_show (dialog);
+
+	/* Connect the callback to set the OK button insensitive when there is
+	   no text in the folder_name_entry.  Notice that we put a value there
+	   by default so the OK button is sensitive by default.  */
+	g_signal_connect (subscription_info->folder_name_entry, "changed",
+			  G_CALLBACK (folder_name_entry_changed_callback), dialog);
+
+	return TRUE;
+}
+
diff --git a/eplugin/exchange-folder-subscription.h b/eplugin/exchange-folder-subscription.h
new file mode 100644
index 0000000..942cc3a
--- /dev/null
+++ b/eplugin/exchange-folder-subscription.h
@@ -0,0 +1,34 @@
+/*
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifndef __EXCHANGE_FOLDER_SUBSCRIPTION_H__
+#define __EXCHANGE_FOLDER_SUBSCRIPTION_H__
+
+#include <glib.h>
+#include <libedataserver/e-source.h>
+#include <exchange-account.h>
+
+gboolean
+create_folder_subscription_dialog (ExchangeAccount *account, const gchar *fname);
+
+void call_folder_subscribe (const gchar *folder_name);
+void call_folder_unsubscribe (const gchar *folder_type, const gchar *uri, ESource *source);
+
+#endif
diff --git a/eplugin/exchange-folder.c b/eplugin/exchange-folder.c
new file mode 100644
index 0000000..5fe4345
--- /dev/null
+++ b/eplugin/exchange-folder.c
@@ -0,0 +1,420 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ *		Shakti Sen <shprasad novell com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <glib/gi18n.h>
+#include <gtk/gtk.h>
+#include <gconf/gconf-client.h>
+#include <e-folder-exchange.h>
+#include <exchange-hierarchy.h>
+#include <libedataserverui/e-source-selector.h>
+#include <e-util/e-error.h>
+#include <camel/camel-store.h>
+#include <camel/camel-folder.h>
+#include <mail/mail-mt.h>
+#include <mail/mail-ops.h>
+
+#include "exchange-operations.h"
+#include "exchange-folder-subscription.h"
+
+#define CONF_KEY_SELECTED_CAL_SOURCES "/apps/evolution/calendar/display/selected_calendars"
+
+static CamelFolderInfo *
+ex_create_folder_info (CamelStore *store, gchar *name, gchar *uri,
+                  gint unread_count, gint flags)
+{
+	CamelFolderInfo *info;
+	const gchar *path;
+
+	path = strstr (uri, "://");
+	if (!path)
+		return NULL;
+	path = strchr (path + 3, '/');
+	if (!path)
+		return NULL;
+
+	info = camel_folder_info_new ();
+	info->name = name;
+	info->uri = uri;
+	info->full_name = g_strdup (path + 1);
+	info->unread = unread_count;
+
+	return info;
+}
+
+static void
+exchange_get_folder (gchar *uri, CamelFolder *folder, gpointer data)
+{
+	CamelStore *store;
+	CamelException ex;
+	CamelFolderInfo *info;
+	gchar *name = NULL;
+	gchar *stored_name = NULL;
+	gchar *target_uri = (gchar *)data;
+	ExchangeAccount *account = NULL;
+
+	account = exchange_operations_get_exchange_account ();
+
+	if (!account)
+		return;
+
+	/* Get the subscribed folder name. */
+	name = target_uri + strlen ("exchange://") + strlen (account->account_filename);
+	stored_name = strrchr (name + 1, '/');
+
+	if (stored_name)
+		name[stored_name - name] = '\0';
+
+	camel_exception_init (&ex);
+	store = camel_folder_get_parent_store (folder);
+
+	/* Construct the CamelFolderInfo */
+	info = ex_create_folder_info (store, name, target_uri, -1, 0);
+	camel_object_trigger_event (CAMEL_OBJECT (store),
+				    "folder_unsubscribed", info);
+	g_free (target_uri);
+}
+
+static void
+eex_folder_inbox_unsubscribe (const gchar *uri)
+{
+	ExchangeAccount *account = NULL;
+	gchar *path = NULL;
+	gchar *stored_path = NULL;
+	const gchar *inbox_uri = NULL;
+	const gchar *inbox_physical_uri = NULL;
+	gchar *target_uri = NULL;
+	EFolder *inbox;
+	ExchangeAccountFolderResult result;
+
+	account = exchange_operations_get_exchange_account ();
+
+	if (!account)
+		return;
+
+	target_uri = g_strdup (uri);
+	path = g_strdup (uri + strlen ("exchange://") + strlen (account->account_filename));
+	/* User will be able to unsubscribe by doing a right click on
+	   any one of this two-<other user's>Inbox or the
+	   <other user's folder> tree.
+	  */
+	stored_path = strrchr (path + 1, '/');
+
+	if (stored_path)
+		path[stored_path - path] = '\0';
+
+	result = exchange_account_remove_shared_folder (account, path);
+	g_free (path);
+
+	switch (result) {
+		case EXCHANGE_ACCOUNT_FOLDER_OK:
+			break;
+		case EXCHANGE_ACCOUNT_FOLDER_ALREADY_EXISTS:
+			e_error_run (NULL, ERROR_DOMAIN ":folder-exists-error", NULL);
+			return;
+		case EXCHANGE_ACCOUNT_FOLDER_DOES_NOT_EXIST:
+			e_error_run (NULL, ERROR_DOMAIN ":folder-doesnt-exist-error", NULL);
+			return;
+		case EXCHANGE_ACCOUNT_FOLDER_UNKNOWN_TYPE:
+			e_error_run (NULL, ERROR_DOMAIN ":folder-unknown-type", NULL);
+			return;
+		case EXCHANGE_ACCOUNT_FOLDER_PERMISSION_DENIED:
+			e_error_run (NULL, ERROR_DOMAIN ":folder-perm-error", NULL);
+			return;
+		case EXCHANGE_ACCOUNT_FOLDER_OFFLINE:
+			e_error_run (NULL, ERROR_DOMAIN ":folder-offline-error", NULL);
+			return;
+		case EXCHANGE_ACCOUNT_FOLDER_UNSUPPORTED_OPERATION:
+			e_error_run (NULL, ERROR_DOMAIN ":folder-unsupported-error", NULL);
+			return;
+		case EXCHANGE_ACCOUNT_FOLDER_GENERIC_ERROR:
+			e_error_run (NULL, ERROR_DOMAIN ":folder-generic-error", NULL);
+			return;
+		case EXCHANGE_ACCOUNT_FOLDER_GC_NOTREACHABLE:
+			e_error_run (NULL, ERROR_DOMAIN ":folder-no-gc-error", NULL);
+			return;
+		case EXCHANGE_ACCOUNT_FOLDER_NO_SUCH_USER:
+			e_error_run (NULL, ERROR_DOMAIN ":no-user-error", NULL);
+			return;
+	}
+
+	/* We need to get the physical uri for the Inbox */
+	inbox_uri = exchange_account_get_standard_uri (account, "inbox");
+	inbox = exchange_account_get_folder (account, inbox_uri);
+	inbox_physical_uri = e_folder_get_physical_uri (inbox);
+
+	/* To get the CamelStore/Folder */
+	mail_get_folder (inbox_physical_uri, 0, exchange_get_folder, target_uri, mail_msg_unordered_push);
+}
+
+static void
+unsubscribe_dialog_ab_response (GtkDialog *dialog, gint response, ESource *source)
+{
+
+	if (response == GTK_RESPONSE_OK) {
+		ExchangeAccount *account = NULL;
+		gchar *path = NULL;
+		gchar *uri = NULL;
+		const gchar *source_uid = NULL;
+		ESourceGroup *source_group = NULL;
+
+		g_return_if_fail (source != NULL);
+
+		account = exchange_operations_get_exchange_account ();
+
+		if (!account)
+			return;
+
+		uri = e_source_get_uri (source);
+		path = g_strdup (uri + strlen ("exchange://") + strlen (account->account_filename));
+		source_uid = e_source_peek_uid (source);
+
+		exchange_account_remove_shared_folder (account, path);
+
+		source_group = e_source_peek_group (source);
+		e_source_group_remove_source_by_uid (source_group, source_uid);
+		g_free (path);
+		gtk_widget_destroy (GTK_WIDGET (dialog));
+	}
+	if (response == GTK_RESPONSE_CANCEL)
+		gtk_widget_destroy (GTK_WIDGET (dialog));
+	if (response == GTK_RESPONSE_DELETE_EVENT)
+		gtk_widget_destroy (GTK_WIDGET (dialog));
+}
+
+static void
+unsubscribe_dialog_response (GtkDialog *dialog, gint response, ESource *source)
+{
+
+	if (response == GTK_RESPONSE_OK) {
+		GSList *ids, *node_to_be_deleted;
+		ExchangeAccount *account = NULL;
+		gchar *path = NULL;
+		gchar *ruri = NULL;
+		const gchar *source_uid = NULL;
+		GConfClient *client;
+		ESourceGroup *source_group = NULL;
+
+		g_return_if_fail (source != NULL);
+
+		client = gconf_client_get_default ();
+
+		account = exchange_operations_get_exchange_account ();
+
+		if (!account)
+			return;
+
+		ruri = (gchar *) e_source_peek_relative_uri (source);
+		source_uid = e_source_peek_uid (source);
+
+		path = g_strdup (ruri + strlen (account->account_filename));
+		exchange_account_remove_shared_folder (account, path);
+		ids = gconf_client_get_list (client,
+					     CONF_KEY_SELECTED_CAL_SOURCES,
+					     GCONF_VALUE_STRING, NULL);
+		if (ids) {
+			node_to_be_deleted = g_slist_find_custom (
+						ids,
+						source_uid,
+						(GCompareFunc) strcmp);
+			if (node_to_be_deleted) {
+				g_free (node_to_be_deleted->data);
+				ids = g_slist_delete_link (ids,
+						node_to_be_deleted);
+				gconf_client_set_list (client,
+					CONF_KEY_SELECTED_CAL_SOURCES,
+					GCONF_VALUE_STRING, ids, NULL);
+			}
+			g_slist_foreach (ids, (GFunc) g_free, NULL);
+			g_slist_free (ids);
+		}
+
+		source_group = e_source_peek_group (source);
+		e_source_group_remove_source_by_uid (source_group, source_uid);
+		g_free (path);
+		gtk_widget_destroy (GTK_WIDGET (dialog));
+	}
+	if (response == GTK_RESPONSE_CANCEL)
+		gtk_widget_destroy (GTK_WIDGET (dialog));
+	if (response == GTK_RESPONSE_DELETE_EVENT)
+		gtk_widget_destroy (GTK_WIDGET (dialog));
+}
+
+static void
+eex_addresssbook_unsubscribe (ESource *source)
+{
+	GtkWidget *dialog = NULL;
+	ExchangeAccount *account = NULL;
+	gchar *title = NULL;
+	gchar *displayed_folder_name = NULL;
+	gint response;
+	gint mode;
+	ExchangeConfigListenerStatus status;
+
+	g_return_if_fail (source != NULL);
+
+	account = exchange_operations_get_exchange_account ();
+	if (!account)
+		return;
+
+	status = exchange_is_offline (&mode);
+	if (status != CONFIG_LISTENER_STATUS_OK) {
+		g_warning ("Config listener not found");
+		return;
+	} else if (mode == OFFLINE_MODE) {
+		e_error_run (NULL, ERROR_DOMAIN ":account-offline-generic", NULL);
+		return;
+	}
+
+	displayed_folder_name = (gchar *) e_source_peek_name (source);
+	dialog = gtk_message_dialog_new (NULL,
+					 GTK_DIALOG_MODAL,
+					 GTK_MESSAGE_QUESTION,
+					 GTK_BUTTONS_NONE,
+					 _("Really unsubscribe from folder \"%s\"?"),
+					 displayed_folder_name);
+
+	gtk_dialog_add_button (GTK_DIALOG (dialog), GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL);
+	gtk_dialog_add_button (GTK_DIALOG (dialog), GTK_STOCK_REMOVE, GTK_RESPONSE_OK);
+
+	gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
+
+	gtk_container_set_border_width (GTK_CONTAINER (dialog), 6);
+
+	gtk_box_set_spacing (GTK_BOX (GTK_DIALOG (dialog)->vbox), 6);
+
+	title = g_strdup_printf (_("Unsubscribe from \"%s\""), displayed_folder_name);
+	gtk_window_set_title (GTK_WINDOW (dialog), title);
+	response = gtk_dialog_run (GTK_DIALOG (dialog));
+	g_free (title);
+	g_free (displayed_folder_name);
+
+	gtk_widget_show (dialog);
+	unsubscribe_dialog_ab_response (GTK_DIALOG (dialog), response, source);
+}
+
+static void
+eex_calendar_unsubscribe (ESource *source)
+{
+	GtkWidget *dialog = NULL;
+	ExchangeAccount *account = NULL;
+	gchar *title = NULL;
+	const gchar *displayed_folder_name;
+	gint response;
+	gint mode;
+	ExchangeConfigListenerStatus status;
+
+	g_return_if_fail (source != NULL);
+
+	account = exchange_operations_get_exchange_account ();
+	if (!account)
+		return;
+
+	status = exchange_is_offline (&mode);
+
+	if (status != CONFIG_LISTENER_STATUS_OK) {
+		g_warning ("Config listener not found");
+		return;
+	} else if (mode == OFFLINE_MODE) {
+		e_error_run (NULL, ERROR_DOMAIN ":account-offline-generic", NULL);
+		return;
+	}
+
+	displayed_folder_name =  e_source_peek_name (source);
+	dialog = gtk_message_dialog_new (NULL,
+					 GTK_DIALOG_MODAL,
+					 GTK_MESSAGE_QUESTION,
+					 GTK_BUTTONS_NONE,
+					 _("Really unsubscribe from folder \"%s\"?"),
+					 displayed_folder_name);
+
+	gtk_dialog_add_button (GTK_DIALOG (dialog), GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL);
+	gtk_dialog_add_button (GTK_DIALOG (dialog), GTK_STOCK_REMOVE, GTK_RESPONSE_OK);
+
+	gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
+
+	gtk_container_set_border_width (GTK_CONTAINER (dialog), 6);
+
+	gtk_box_set_spacing (GTK_BOX (GTK_DIALOG (dialog)->vbox), 6);
+
+	title = g_strdup_printf (_("Unsubscribe from \"%s\""), displayed_folder_name);
+	gtk_window_set_title (GTK_WINDOW (dialog), title);
+	response = gtk_dialog_run (GTK_DIALOG (dialog));
+	g_free (title);
+
+	gtk_widget_show (dialog);
+	unsubscribe_dialog_response (GTK_DIALOG (dialog), response, source);
+}
+
+void
+call_folder_subscribe (const gchar *folder_name)
+{
+	ExchangeAccount *account = NULL;
+	gint mode;
+	ExchangeConfigListenerStatus status;
+
+	g_return_if_fail (folder_name != NULL);
+
+	account = exchange_operations_get_exchange_account ();
+	if (!account)
+		return;
+
+	status = exchange_is_offline (&mode);
+	if (status != CONFIG_LISTENER_STATUS_OK) {
+		g_warning ("Config listener not found");
+		return;
+	} else if (mode == OFFLINE_MODE) {
+		/* Translators: this error code can be used for any operation
+		 * (like subscribing to other user's folders, unsubscribing
+		 * etc,) which can not be performed in offline mode
+		 */
+		e_error_run (NULL, ERROR_DOMAIN ":account-offline-generic", NULL);
+		return;
+	}
+
+	create_folder_subscription_dialog (account, folder_name);
+}
+
+void
+call_folder_unsubscribe (const gchar *folder_type, const gchar *uri, ESource *source)
+{
+	g_return_if_fail (folder_type != NULL);
+	g_return_if_fail (uri != NULL);
+
+	if (g_str_equal (folder_type, N_("Inbox"))) {
+		eex_folder_inbox_unsubscribe (uri);
+	} else if (g_str_equal (folder_type, N_("Calendar"))) {
+		g_return_if_fail (source != NULL);
+		eex_calendar_unsubscribe (source);
+	} else if (g_str_equal (folder_type, N_("Tasks"))) {
+		g_return_if_fail (source != NULL);
+		eex_calendar_unsubscribe (source);
+	} else if (g_str_equal (folder_type, N_("Contacts"))) {
+		g_return_if_fail (source != NULL);
+		eex_addresssbook_unsubscribe (source);
+	} else {
+		g_return_if_reached ();
+	}
+}
diff --git a/eplugin/exchange-mail-send-options.c b/eplugin/exchange-mail-send-options.c
new file mode 100644
index 0000000..04065e4
--- /dev/null
+++ b/eplugin/exchange-mail-send-options.c
@@ -0,0 +1,196 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ *		R.Raghavendran <raghavguru7 gmail com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#include <string.h>
+#include <stdio.h>
+
+#include <glib.h>
+#include <glib/gi18n.h>
+
+#include <camel/camel-mime-message.h>
+#include <camel/camel-address.h>
+#include "mail/em-event.h"
+
+#include "composer/e-msg-composer.h"
+#include "libedataserver/e-account.h"
+
+#include "exchange-send-options.h"
+
+void org_gnome_exchange_send_options (EPlugin *ep, EMEventTargetComposer *t);
+
+static ExchangeSendOptionsDialog *dialog=NULL;
+
+static void
+append_to_header (ExchangeSendOptionsDialog *dialog, gint state, gpointer data)
+{
+	EMsgComposer *composer;
+	CamelAddress *sender_address;
+	const gchar *sender_id, *recipient_id;
+	struct _camel_header_address *addr;
+	struct _camel_header_address *sender_addr;
+
+	composer = (EMsgComposer *)data;
+	if (state == GTK_RESPONSE_OK) {
+		if (dialog->options->importance) {
+			switch (dialog->options->importance) {
+				case E_IMP_HIGH :
+					e_msg_composer_modify_header (composer, "Importance", "high");
+					break;
+				case E_IMP_LOW :
+					e_msg_composer_modify_header (composer, "Importance", "low");
+					break;
+				default :
+					g_print ("\nNo importance set");
+					break;
+			}
+		}
+		else
+			e_msg_composer_remove_header (composer, "Importance");
+
+		if (dialog->options->sensitivity) {
+			switch (dialog->options->sensitivity) {
+				case E_SENSITIVITY_CONFIDENTIAL :
+					e_msg_composer_modify_header (composer, "Sensitivity", "Company-Confidential");
+					break;
+				case E_SENSITIVITY_PERSONAL :
+					e_msg_composer_modify_header (composer, "Sensitivity", "Personal");
+					break;
+				case E_SENSITIVITY_PRIVATE :
+					e_msg_composer_modify_header (composer, "Sensitivity", "Private");
+					break;
+				default :
+					g_print ("\nNo importance set");
+					break;
+			}
+		}
+		else
+			e_msg_composer_remove_header (composer, "Sensitivity");
+
+		sender_address = (CamelAddress *) e_msg_composer_get_from (composer);
+		sender_id = (const gchar *) camel_address_encode (sender_address);
+
+		addr = camel_header_address_decode (dialog->options->delegate_address, NULL);
+		sender_addr = camel_header_address_decode (sender_id, NULL);
+
+		if (dialog->options->send_as_del_enabled &&
+			dialog->options->delegate_address &&
+				g_ascii_strcasecmp(addr->v.addr, sender_addr->v.addr)) {
+
+			e_msg_composer_modify_header (composer, "Sender" , sender_id);
+
+			/* This block handles the case wherein the address to be added
+			 * in the "From" field has no name associated with it.
+			 * So for cases where there is no name we append the address
+			 * (only email) within angular braces.
+			 */
+			if (!g_ascii_strcasecmp (addr->name, "")) {
+				recipient_id = g_strdup_printf ("<%s>",
+						dialog->options->delegate_address);
+				e_msg_composer_add_header (composer, "From", recipient_id);
+			}
+
+			else
+				e_msg_composer_add_header (composer, "From",
+							dialog->options->delegate_address);
+		}
+
+		else {
+			e_msg_composer_remove_header (composer, "Sender");
+			e_msg_composer_add_header (composer, "From", sender_id);
+		}
+
+		if (dialog->options->delivery_enabled) {
+			EComposerHeaderTable *table;
+			EAccount *account;
+			gchar *mdn_address;
+
+			table = e_msg_composer_get_header_table (composer);
+			account = e_composer_header_table_get_account (table);
+			mdn_address = account->id->reply_to;
+			if (!mdn_address || !*mdn_address)
+				mdn_address = account->id->address;
+			e_msg_composer_modify_header (composer, "Return-Receipt-To", mdn_address);
+		}
+		else
+			e_msg_composer_remove_header (composer, "Return-Receipt-To");
+
+		if (dialog->options->read_enabled) {
+			EComposerHeaderTable *table;
+			EAccount *account;
+			gchar *mdn_address;
+
+			table = e_msg_composer_get_header_table (composer);
+			account = e_composer_header_table_get_account (table);
+			mdn_address = account->id->reply_to;
+			if (!mdn_address || !*mdn_address)
+				mdn_address = account->id->address;
+
+			e_msg_composer_modify_header (composer, "Disposition-Notification-To", mdn_address);
+		}
+		else
+			e_msg_composer_remove_header (composer, "Disposition-Notification-To");
+	}
+}
+
+static void
+send_options_commit (EMsgComposer *comp, gpointer user_data)
+{
+	if (!user_data && !EXCHANGE_IS_SENDOPTIONS_DIALOG (user_data))
+		return;
+
+	if (dialog) {
+		g_print ("\nDialog getting unreferenced ");
+		g_object_unref (dialog);
+		dialog = NULL;
+	}
+}
+
+void
+org_gnome_exchange_send_options (EPlugin *ep, EMEventTargetComposer *target)
+{
+	EMsgComposer *composer = target->composer;
+	EComposerHeaderTable *table;
+	EAccount *account = NULL;
+	gchar *temp = NULL;
+
+	table = e_msg_composer_get_header_table (composer);
+	account = e_composer_header_table_get_account (table);
+	if (!account)
+		return;
+
+	temp = strstr (account->transport->url, "exchange");
+	if (!temp) {
+		return;
+	}
+	e_msg_composer_set_send_options (composer, TRUE);
+	/*disply the send options dialog*/
+	if (!dialog) {
+		g_print ("New dialog\n\n");
+		dialog = exchange_sendoptions_dialog_new ();
+	}
+	exchange_sendoptions_dialog_run (dialog, GTK_WIDGET (composer));
+	g_signal_connect (dialog, "sod_response", G_CALLBACK (append_to_header), GTK_WIDGET (composer));
+
+	g_signal_connect (GTK_WIDGET (composer), "destroy",
+				  G_CALLBACK (send_options_commit), dialog);
+
+}
diff --git a/eplugin/exchange-operations.c b/eplugin/exchange-operations.c
new file mode 100644
index 0000000..35ed781
--- /dev/null
+++ b/eplugin/exchange-operations.c
@@ -0,0 +1,305 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ *		Praveen Kumar <kpraveen novell com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#include <string.h>
+#include <glib/gi18n.h>
+
+#include "exchange-operations.h"
+#include <e-folder-exchange.h>
+#include <exchange-hierarchy.h>
+#include <e-util/e-error.h>
+
+ExchangeConfigListener *exchange_global_config_listener=NULL;
+
+static const gchar *error_ids[] = {
+	"config-error",
+	"password-weak-error",
+	"password-change-error",
+	"password-change-success",
+	"account-offline",
+	"password-incorrect",
+	"account-domain-error",
+	"account-mailbox-na",
+	"account-version-error",
+	"account-wss-error",
+	"account-no-mailbox",
+	"account-resolve-error",
+	"account-connect-error",
+	"password-expired",
+	"account-unknown-error",
+	"account-quota-error",
+	"account-quota-send-error",
+	"account-quota-warn"
+};
+
+static void
+free_exchange_listener (void)
+{
+	g_object_unref (exchange_global_config_listener);
+}
+
+gint
+e_plugin_lib_enable (EPlugin *eplib, gint enable)
+{
+	if (!exchange_global_config_listener) {
+		exchange_global_config_listener = exchange_config_listener_new ();
+		g_atexit (free_exchange_listener);
+	}
+	return 0;
+}
+
+ExchangeConfigListenerStatus
+exchange_is_offline (gint *mode)
+{
+	return exchange_config_listener_get_offline_status (exchange_global_config_listener, mode);
+}
+
+/* FIXME: See if a GLib variant of this function available */
+gboolean
+exchange_operations_tokenize_string (gchar **string, gchar *token, gchar delimit, guint maxsize)
+{
+	guint i=0;
+	gchar *str=*string;
+	while (*str!=delimit && *str!='\0' && i<maxsize-1) {
+		token[i++]=*str++;
+	}
+	while (*str==delimit)
+		str++;
+	token[i]='\0';
+	*string = str;
+	if (i==0)
+		return FALSE;
+	return TRUE;
+}
+
+gboolean
+exchange_operations_cta_add_node_to_tree (GtkTreeStore *store, GtkTreeIter *parent, const gchar *ruri)
+{
+	GtkTreeIter iter;
+	gchar *luri=(gchar *)ruri;
+	gchar nodename[80];
+	gchar *uri;
+	gboolean status, found;
+
+	exchange_operations_tokenize_string (&luri, nodename, '/', sizeof(nodename));
+
+	if (!nodename[0]) {
+		return TRUE;
+	}
+
+	if (!parent) {
+	  uri = g_strdup (nodename);
+	}
+	else {
+	  gchar *tmpuri;
+	  gtk_tree_model_get (GTK_TREE_MODEL (store), parent, 1, &tmpuri, -1);
+	  uri = g_strconcat (tmpuri, "/", nodename, NULL);
+	  g_free (tmpuri);
+	}
+
+	if (!strcmp (nodename, "personal") && !parent) {
+		/* FIXME: Don't hardcode this */
+		strcpy (nodename, _("Personal Folders"));
+	}
+
+	found = FALSE;
+	status = gtk_tree_model_iter_children (GTK_TREE_MODEL (store), &iter, parent);
+	while (status) {
+	  gchar *readname;
+	  gtk_tree_model_get (GTK_TREE_MODEL (store), &iter, 0, &readname, -1);
+	  if (!strcmp (nodename, readname)) {
+	    found = TRUE;
+	    exchange_operations_cta_add_node_to_tree (store, &iter, luri);
+	    g_free (readname);
+	    break;
+	  }
+	  status = gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter);
+	}
+
+	if (!found) {
+	  gtk_tree_store_append (store, &iter, parent);
+	  gtk_tree_store_set (store, &iter, 0, nodename, 1, uri, -1);
+	  exchange_operations_cta_add_node_to_tree (store, &iter, luri);
+	}
+
+	g_free (uri);
+	return TRUE;
+}
+
+void
+exchange_operations_cta_select_node_from_tree (GtkTreeStore *store, GtkTreeIter *parent, const gchar *nuri, const gchar *ruri, GtkTreeSelection *selection)
+{
+	gchar *luri=(gchar *)nuri;
+	gchar nodename[80];
+	GtkTreeIter iter;
+	gboolean status;
+
+	if (!luri)
+		return;
+
+	exchange_operations_tokenize_string (&luri, nodename, '/', sizeof(nodename));
+	if (!nodename[0]) {
+		return;
+	}
+
+	if (!strcmp (nodename, "personal") && !parent) {
+		/* FIXME: Don't hardcode this */
+		strcpy (nodename, _("Personal Folders"));
+	}
+
+	status = gtk_tree_model_iter_children (GTK_TREE_MODEL (store), &iter, parent);
+	while (status) {
+		gchar *readname;
+		gtk_tree_model_get (GTK_TREE_MODEL (store), &iter, 0, &readname, -1);
+		if (!strcmp (nodename, readname)) {
+			gchar *readruri;
+			gtk_tree_model_get (GTK_TREE_MODEL (store), &iter, 1, &readruri, -1);
+			if (!strcmp (ruri, readruri)) {
+				gtk_tree_selection_select_iter (selection, &iter);
+				return;
+			}
+			g_free (readname);
+			g_free (readruri);
+			exchange_operations_cta_select_node_from_tree (store, &iter, luri, ruri, selection);
+			break;
+		}
+		status = gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter);
+	}
+	return;
+}
+
+ExchangeAccount *
+exchange_operations_get_exchange_account (void)
+{
+	ExchangeAccount *account = NULL;
+	ExchangeAccountResult result;
+	GSList *acclist;
+	gint mode;
+
+	acclist = exchange_config_listener_get_accounts (exchange_global_config_listener);
+	/* FIXME: Need to be changed for handling multiple accounts */
+	if (acclist) {
+		account = acclist->data;
+
+		exchange_config_listener_get_offline_status (exchange_global_config_listener,
+							     &mode);
+
+		if (mode == OFFLINE_MODE) {
+			return account;
+		}
+		else if (exchange_account_get_context (account)) {
+			return account;
+		} else {
+			/* Try authenticating */
+			result = exchange_config_listener_authenticate(exchange_global_config_listener, account);
+			if (result != EXCHANGE_ACCOUNT_CONNECT_SUCCESS) {
+				exchange_operations_report_error (account, result);
+				return NULL;
+			}
+			if (exchange_account_get_context (account))
+				return account;
+		}
+	}
+
+	return NULL;
+}
+
+void
+exchange_operations_report_error (ExchangeAccount *account, ExchangeAccountResult result)
+{
+	gchar *error_string;
+	gchar *quota_value;
+	GtkWidget *widget;
+
+	g_return_if_fail (account != NULL);
+
+	if (result == EXCHANGE_ACCOUNT_CONNECT_SUCCESS)
+		return;
+
+	error_string = g_strconcat ("org-gnome-exchange-operations:", error_ids[result], NULL);
+
+	switch (result) {
+		case EXCHANGE_ACCOUNT_MAILBOX_NA:
+			widget = e_error_new (NULL, error_string, exchange_account_get_username (account), NULL);
+			break;
+		case EXCHANGE_ACCOUNT_NO_MAILBOX:
+			widget = e_error_new (NULL, error_string, exchange_account_get_username (account),
+					      account->exchange_server, NULL);
+			break;
+		case EXCHANGE_ACCOUNT_RESOLVE_ERROR:
+		case EXCHANGE_ACCOUNT_CONNECT_ERROR:
+		case EXCHANGE_ACCOUNT_UNKNOWN_ERROR:
+			widget = e_error_new (NULL, error_string, account->exchange_server, NULL);
+			break;
+		case EXCHANGE_ACCOUNT_QUOTA_RECIEVE_ERROR:
+		case EXCHANGE_ACCOUNT_QUOTA_SEND_ERROR:
+		case EXCHANGE_ACCOUNT_QUOTA_WARN:
+			quota_value = g_strdup_printf ("%.2f", account->mbox_size);
+			widget = e_error_new (NULL, error_string, quota_value, NULL);
+			g_free (quota_value);
+			break;
+		default:
+			widget = e_error_new (NULL, error_string, NULL);
+	}
+	g_signal_connect ((GtkDialog *)widget, "response", G_CALLBACK (gtk_widget_destroy), widget);
+	gtk_widget_show (widget);
+	g_free (error_string);
+}
+
+void exchange_operations_update_child_esources (ESource *source, const gchar *old_path, const gchar *new_path)
+{
+	ESourceGroup *group;
+	GSList *sources, *tsource;
+	group = e_source_peek_group (source);
+	sources = e_source_group_peek_sources (group);
+	for (tsource = sources; tsource != NULL; tsource = tsource->next) {
+		gchar *ruri;
+		ruri = (gchar *) e_source_peek_relative_uri (tsource->data);
+		if (ruri && g_strrstr (ruri, old_path)) {
+			/* This ESource points to one of the child folders */
+			gchar **tmpv, *truri;
+			/* A nasty search and replace */
+			tmpv = g_strsplit (ruri, old_path, -1);
+			truri = g_strjoinv (new_path, tmpv);
+			e_source_set_relative_uri (tsource->data, truri);
+			g_strfreev (tmpv);
+			g_free (truri);
+		}
+	}
+}
+
+gboolean
+is_exchange_personal_folder (ExchangeAccount *account, gchar *uri)
+{
+	ExchangeHierarchy *hier;
+	EFolder *folder;
+
+	folder = exchange_account_get_folder (account, uri);
+	if (folder) {
+		hier = e_folder_exchange_get_hierarchy (folder);
+		if (hier->type != EXCHANGE_HIERARCHY_PERSONAL)
+			return FALSE;
+		else
+			return TRUE;
+	}
+	return FALSE;
+}
diff --git a/eplugin/exchange-operations.h b/eplugin/exchange-operations.h
new file mode 100644
index 0000000..60c2f20
--- /dev/null
+++ b/eplugin/exchange-operations.h
@@ -0,0 +1,56 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ *		Praveen Kumar <kpraveen novell com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifndef __EXCHANGE_OPERATIONS_H__
+#define __EXCHANGE_OPERATIONS_H__
+
+#include <gtk/gtk.h>
+
+#include "e-util/e-plugin.h"
+#include "exchange-config-listener.h"
+#include <exchange-account.h>
+
+G_BEGIN_DECLS
+
+#define ERROR_DOMAIN "org-gnome-exchange-operations"
+
+extern ExchangeConfigListener *exchange_global_config_listener;
+
+gint e_plugin_lib_enable (EPlugin *eplib, gint enable);
+
+ExchangeAccount *exchange_operations_get_exchange_account (void);
+ExchangeConfigListenerStatus exchange_is_offline (gint *mode);
+
+gboolean exchange_operations_tokenize_string (gchar **string, gchar *token, gchar delimit, guint maxsize);
+
+gboolean exchange_operations_cta_add_node_to_tree (GtkTreeStore *store, GtkTreeIter *parent, const gchar *nuri);
+void exchange_operations_cta_select_node_from_tree (GtkTreeStore *store, GtkTreeIter *parent, const gchar *nuri, const gchar *ruri, GtkTreeSelection *selection);
+
+void exchange_operations_report_error (ExchangeAccount *account, ExchangeAccountResult result);
+
+void exchange_operations_update_child_esources (ESource *source, const gchar *old_path, const gchar *new_path);
+
+gboolean is_exchange_personal_folder (ExchangeAccount *account, gchar *uri);
+
+G_END_DECLS
+
+#endif
diff --git a/eplugin/exchange-permissions-dialog.c b/eplugin/exchange-permissions-dialog.c
new file mode 100644
index 0000000..20af66e
--- /dev/null
+++ b/eplugin/exchange-permissions-dialog.c
@@ -0,0 +1,984 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "exchange-permissions-dialog.h"
+#include "exchange-hierarchy.h"
+#include "exchange-user-dialog.h"
+
+#include "e2k-context.h"
+#include "e2k-global-catalog.h"
+#include "e2k-propnames.h"
+#include "e2k-sid.h"
+#include "e2k-security-descriptor.h"
+
+#include "e2k-uri.h"
+#include "e2k-utils.h"
+#include "e-folder-exchange.h"
+#include "exchange-account.h"
+#include "exchange-operations.h"
+
+#include <e-util/e-dialog-utils.h>
+#include <e-util/e-error.h>
+
+struct _ExchangePermissionsDialogPrivate {
+	ExchangeAccount *account;
+	gchar *base_uri, *folder_path;
+	E2kSecurityDescriptor *sd;
+	gboolean changed;
+	gboolean frozen;
+
+	/* The user list */
+	GtkTreeView *list_view;
+	GtkListStore *list_store;
+	GtkTreeSelection *list_selection;
+	E2kSid *selected_sid;
+
+	/* The Role menu */
+	GtkComboBox *role_optionmenu;
+
+	/* Custom label is added or not */
+	gboolean custom_added;
+
+	GtkWidget *separator, *custom;
+	E2kPermissionsRole selected_role;
+
+	/* The toggles */
+	GtkToggleButton *read_items_check, *create_items_check;
+	GtkToggleButton *create_subfolders_check, *folder_visible_check;
+	GtkToggleButton *folder_owner_check, *folder_contact_check;
+	GtkToggleButton *edit_none_radio, *edit_own_radio, *edit_all_radio;
+	GtkToggleButton *delete_none_radio, *delete_own_radio, *delete_all_radio;
+	guint32 selected_perms;
+};
+
+enum {
+	EXCHANGE_PERMISSIONS_DIALOG_NAME_COLUMN,
+	EXCHANGE_PERMISSIONS_DIALOG_ROLE_COLUMN,
+	EXCHANGE_PERMISSIONS_DIALOG_SID_COLUMN,
+
+	EXCHANGE_PERMISSIONS_DIALOG_NUM_COLUMNS
+};
+
+#define PARENT_TYPE GTK_TYPE_DIALOG
+static GtkDialogClass *parent_class = NULL;
+
+static void
+finalize (GObject *object)
+{
+	ExchangePermissionsDialog *dialog =
+		EXCHANGE_PERMISSIONS_DIALOG (object);
+
+	g_free (dialog->priv->base_uri);
+	g_free (dialog->priv->folder_path);
+
+	if (dialog->priv->sd)
+		g_object_unref (dialog->priv->sd);
+
+	g_free (dialog->priv);
+
+	G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+static void
+class_init (GObjectClass *object_class)
+{
+	parent_class = g_type_class_ref (PARENT_TYPE);
+
+	/* virtual method override */
+	object_class->finalize = finalize;
+}
+
+static void
+init (GObject *object)
+{
+	ExchangePermissionsDialog *dialog =
+		EXCHANGE_PERMISSIONS_DIALOG (object);
+
+	dialog->priv = g_new0 (ExchangePermissionsDialogPrivate, 1);
+}
+
+E2K_MAKE_TYPE (exchange_permissions_dialog, ExchangePermissionsDialog, class_init, init, PARENT_TYPE)
+
+static GtkWidget *create_permissions_vbox (ExchangePermissionsDialog *dialog);
+static void setup_user_list     (ExchangePermissionsDialog *dialog);
+static void display_permissions (ExchangePermissionsDialog *dialog);
+static void dialog_response     (ExchangePermissionsDialog *dialog,
+				 gint response, gpointer user_data);
+
+static const gchar *sd_props[] = {
+	E2K_PR_EXCHANGE_SD_BINARY,
+	E2K_PR_EXCHANGE_SD_XML
+};
+static const gint n_sd_props = sizeof (sd_props) / sizeof (sd_props[0]);
+
+/**
+ * exchange_permissions_dialog_new:
+ * @account: an account
+ * @folder: the folder whose permissions are to be editted
+ * @parent: a widget in the dialog's parent window
+ *
+ * Creates and displays a modeless permissions editor dialog for @folder.
+ **/
+void
+exchange_permissions_dialog_new (ExchangeAccount *account,
+				 EFolder *folder,
+				 GtkWidget *parent)
+{
+	ExchangePermissionsDialog *dialog;
+	const gchar *base_uri, *folder_uri, *folder_path;
+	E2kContext *ctx;
+	ExchangeHierarchy *hier;
+	GtkWidget *box;
+	gchar *title;
+	E2kHTTPStatus status;
+	E2kResult *results;
+	gint nresults = 0;
+	xmlNode *xml_form;
+	GByteArray *binary_form;
+
+	g_return_if_fail (folder);
+
+	ctx = exchange_account_get_context (account);
+	g_return_if_fail (ctx);
+
+	/* Create the dialog */
+	dialog = g_object_new (EXCHANGE_TYPE_PERMISSIONS_DIALOG, NULL);
+
+	title = g_strdup_printf (_("Permissions for %s"),
+				 e_folder_get_name (folder));
+	gtk_window_set_title (GTK_WINDOW (dialog), title);
+	g_free (title);
+
+	gtk_dialog_add_buttons (GTK_DIALOG (dialog),
+				GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+				GTK_STOCK_OK, GTK_RESPONSE_OK,
+				NULL);
+
+	g_signal_connect (dialog, "response",
+			  G_CALLBACK (dialog_response), NULL);
+
+	dialog->priv->changed = FALSE;
+
+	box = create_permissions_vbox (dialog);
+	gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog))),
+			    box, TRUE, TRUE, 0);
+
+	dialog->priv->account = account;
+	g_object_ref (account);
+
+	hier = e_folder_exchange_get_hierarchy (folder);
+	base_uri = e_folder_exchange_get_internal_uri (hier->toplevel);
+	dialog->priv->base_uri = g_strdup (base_uri);
+	folder_uri = e_folder_exchange_get_internal_uri (folder);
+	folder_path = e2k_uri_relative (dialog->priv->base_uri, folder_uri);
+	dialog->priv->folder_path = g_strdup (folder_path);
+
+	/* And fetch the security descriptor */
+	status = e2k_context_propfind (ctx, NULL, folder_uri,
+				       sd_props, n_sd_props,
+				       &results, &nresults);
+	if (!E2K_HTTP_STATUS_IS_SUCCESSFUL (status) || nresults < 1) {
+	lose:
+		e_error_run (GTK_WINDOW (parent), ERROR_DOMAIN ":perm-read-error", NULL);
+		gtk_widget_destroy (GTK_WIDGET (dialog));
+		if (nresults)
+			e2k_results_free (results, nresults);
+		return;
+	}
+
+	xml_form = e2k_properties_get_prop (results[0].props,
+					    E2K_PR_EXCHANGE_SD_XML);
+	binary_form = e2k_properties_get_prop (results[0].props,
+					       E2K_PR_EXCHANGE_SD_BINARY);
+	if (!xml_form || !binary_form)
+		goto lose;
+
+	dialog->priv->sd = e2k_security_descriptor_new (xml_form, binary_form);
+	if (!dialog->priv->sd)
+		goto lose;
+
+	setup_user_list (dialog);
+	gtk_widget_show (GTK_WIDGET (dialog));
+	if (nresults)
+		e2k_results_free (results, nresults);
+}
+
+static void
+dialog_response (ExchangePermissionsDialog *dialog, gint response,
+		 gpointer user_data)
+{
+	E2kContext *ctx;
+	GByteArray *binsd;
+	E2kProperties *props;
+	E2kResultIter *iter;
+	E2kResult *result;
+	E2kHTTPStatus status;
+
+	if (response != GTK_RESPONSE_OK || !dialog->priv->changed) {
+		gtk_widget_destroy (GTK_WIDGET (dialog));
+		return;
+	}
+
+	ctx = exchange_account_get_context (dialog->priv->account);
+	g_return_if_fail (ctx != NULL);
+
+	binsd = e2k_security_descriptor_to_binary (dialog->priv->sd);
+	if (!binsd) {
+		e_error_run (GTK_WINDOW (dialog), ERROR_DOMAIN ":perm-update-error", "", NULL);
+		return;
+	}
+
+	gtk_widget_set_sensitive (GTK_WIDGET (dialog), FALSE);
+
+	props = e2k_properties_new ();
+	e2k_properties_set_binary (props, E2K_PR_EXCHANGE_SD_BINARY, binsd);
+
+	/* We use BPROPPATCH here instead of PROPPATCH, because
+	 * PROPPATCH seems to mysteriously fail in someone else's
+	 * folder hierarchy. #29726
+	 */
+	iter = e2k_context_bproppatch_start (ctx, NULL, dialog->priv->base_uri,
+					     (const gchar **)&dialog->priv->folder_path, 1,
+					     props, FALSE);
+	e2k_properties_free (props);
+
+	result = e2k_result_iter_next (iter);
+	if (result) {
+		status = result->status;
+		e2k_result_iter_free (iter);
+	} else
+		status = e2k_result_iter_free (iter);
+
+	gtk_widget_set_sensitive (GTK_WIDGET (dialog), TRUE);
+
+	if (!E2K_HTTP_STATUS_IS_SUCCESSFUL (status)) {
+		e_error_run (GTK_WINDOW (dialog), ERROR_DOMAIN ":perm-update-error",
+			     status == E2K_HTTP_UNAUTHORIZED ?
+			     _("(Permission denied.)") : "", NULL);
+		return;
+	}
+
+	if (response == GTK_RESPONSE_OK)
+		gtk_widget_destroy (GTK_WIDGET (dialog));
+}
+
+static void
+set_permissions (ExchangePermissionsDialog *dialog, guint32 perms)
+{
+	dialog->priv->selected_perms = perms;
+	dialog->priv->selected_role = e2k_permissions_role_find (perms);
+	e2k_security_descriptor_set_permissions (dialog->priv->sd,
+						 dialog->priv->selected_sid,
+						 dialog->priv->selected_perms);
+
+	dialog->priv->changed = TRUE;
+}
+
+/* User list functions */
+
+static void
+list_view_selection_changed (GtkTreeSelection *selection, gpointer user_data)
+{
+	ExchangePermissionsDialog *dialog = user_data;
+	GtkTreeModel *model;
+	GtkTreeIter iter;
+	E2kSid *sid;
+
+	if (!gtk_tree_selection_get_selected (selection, &model, &iter))
+		return;
+	gtk_tree_model_get (model, &iter,
+			    EXCHANGE_PERMISSIONS_DIALOG_SID_COLUMN, &sid,
+			    -1);
+
+	dialog->priv->selected_sid = sid;
+	dialog->priv->selected_perms =
+		e2k_security_descriptor_get_permissions (dialog->priv->sd, sid);
+	dialog->priv->selected_role =
+		e2k_permissions_role_find (dialog->priv->selected_perms);
+
+	/* "Default" or "Anonymous" can't be a Folder contact, but any
+	 * real person can.
+	 */
+	gtk_widget_set_sensitive (GTK_WIDGET (dialog->priv->folder_contact_check),
+				  e2k_sid_get_sid_type (sid) != E2K_SID_TYPE_WELL_KNOWN_GROUP);
+
+	/* Update role menu and permissions checkboxes */
+	display_permissions (dialog);
+}
+
+static void
+add_user_to_list (ExchangePermissionsDialog *dialog, E2kSid *sid, gboolean select)
+{
+	guint32 perms;
+	E2kPermissionsRole role;
+	GtkTreeIter iter;
+
+	perms = e2k_security_descriptor_get_permissions (dialog->priv->sd,
+							 sid);
+	role = e2k_permissions_role_find (perms);
+
+	if (e2k_sid_get_sid_type (sid) == E2K_SID_TYPE_WELL_KNOWN_GROUP)
+		gtk_list_store_insert (dialog->priv->list_store, &iter, 1);
+	else
+		gtk_list_store_append (dialog->priv->list_store, &iter);
+
+	gtk_list_store_set (dialog->priv->list_store, &iter,
+			    EXCHANGE_PERMISSIONS_DIALOG_NAME_COLUMN,
+			    e2k_sid_get_display_name (sid),
+			    EXCHANGE_PERMISSIONS_DIALOG_ROLE_COLUMN,
+			    e2k_permissions_role_get_name (role),
+			    EXCHANGE_PERMISSIONS_DIALOG_SID_COLUMN,
+			    sid,
+			    -1);
+
+	if (select)
+		gtk_tree_selection_select_iter (dialog->priv->list_selection, &iter);
+}
+
+static void
+add_clicked (GtkButton *button, gpointer user_data)
+{
+	ExchangePermissionsDialog *dialog = user_data;
+	E2kGlobalCatalog *gc;
+	E2kGlobalCatalogStatus status;
+	E2kGlobalCatalogEntry *entry;
+	E2kSid *sid2;
+	GtkTreeIter iter;
+	GtkWidget *user_dialog;
+	const guint8 *bsid, *bsid2;
+	GList *email_list = NULL;
+	GList *l = NULL;
+	gchar *email = NULL;
+	gboolean valid;
+	gint result;
+
+	gc = exchange_account_get_global_catalog (dialog->priv->account);
+
+	if (!gc) {
+		e_error_run (GTK_WINDOW (dialog), ERROR_DOMAIN ":acl-no-gcs-error",
+			     NULL);
+		return;
+	}
+
+	user_dialog = e2k_user_dialog_new (GTK_WIDGET (dialog), _("Add User:"), _("Add User"));
+	result = gtk_dialog_run (GTK_DIALOG (user_dialog));
+
+	if (result == GTK_RESPONSE_OK)
+		email_list = e2k_user_dialog_get_user_list (E2K_USER_DIALOG (user_dialog));
+	gtk_widget_destroy (user_dialog);
+
+	if (email_list == NULL)
+		return;
+
+	for (l = email_list; l; l = g_list_next (l)) {
+		email = l->data;
+		status = e2k_global_catalog_lookup (
+			gc, NULL, /* FIXME: cancellable */
+			E2K_GLOBAL_CATALOG_LOOKUP_BY_EMAIL, email,
+			E2K_GLOBAL_CATALOG_LOOKUP_SID, &entry);
+		switch (status) {
+			case E2K_GLOBAL_CATALOG_OK:
+				break;
+			case E2K_GLOBAL_CATALOG_NO_SUCH_USER:
+				e_error_run (GTK_WINDOW (dialog), ERROR_DOMAIN ":no-user-error", email, NULL);
+				break;
+			case E2K_GLOBAL_CATALOG_NO_DATA:
+				e_error_run (GTK_WINDOW (dialog), ERROR_DOMAIN ":acl-add-error", email, NULL);
+				break;
+			default:
+				e_error_run (GTK_WINDOW (dialog), ERROR_DOMAIN ":perm-unknown-error", email, NULL);
+				break;
+		}
+		if (status != E2K_GLOBAL_CATALOG_OK)
+			return;
+
+		/* Make sure the user isn't already there. */
+		bsid = e2k_sid_get_binary_sid (entry->sid);
+		valid = gtk_tree_model_get_iter_first (GTK_TREE_MODEL (dialog->priv->list_store), &iter);
+		while (valid) {
+			gtk_tree_model_get (GTK_TREE_MODEL (dialog->priv->list_store), &iter,
+					    EXCHANGE_PERMISSIONS_DIALOG_SID_COLUMN, &sid2,
+					    -1);
+			bsid2 = e2k_sid_get_binary_sid (sid2);
+			if (e2k_sid_binary_sid_equal (bsid, bsid2)) {
+				e_error_run (GTK_WINDOW (dialog), ERROR_DOMAIN ":perm-existing-error",
+					     entry->display_name, NULL);
+				e2k_global_catalog_entry_free (gc, entry);
+				gtk_tree_selection_select_iter (dialog->priv->list_selection, &iter);
+				return;
+			}
+
+			valid = gtk_tree_model_iter_next (GTK_TREE_MODEL (dialog->priv->list_store), &iter);
+		}
+
+		add_user_to_list (dialog, entry->sid, TRUE);
+
+		/* Calling set_permissions will cause the sd to take a
+		 * ref on the sid, allowing us to unref it.
+		 */
+		set_permissions (dialog, 0);
+		e2k_global_catalog_entry_free (gc, entry);
+	}
+	g_list_free (email_list);
+}
+
+static void
+remove_clicked (GtkButton *button, gpointer user_data)
+{
+	ExchangePermissionsDialog *dialog = user_data;
+	E2kSid *sid;
+	GdkModifierType modifiers;
+	GtkTreeModel *model;
+	GtkTreeIter iter;
+
+	if (!gtk_tree_selection_get_selected (dialog->priv->list_selection,
+					      &model, &iter))
+		return;
+	gtk_tree_model_get (model, &iter,
+			    EXCHANGE_PERMISSIONS_DIALOG_SID_COLUMN, &sid,
+			    -1);
+	gdk_window_get_pointer (NULL, NULL, NULL, &modifiers);
+
+	if (e2k_sid_get_sid_type (sid) == E2K_SID_TYPE_WELL_KNOWN_GROUP &&
+	    !(modifiers & GDK_SHIFT_MASK)) {
+		/* You shouldn't normally delete "Default" or "Anonymous". */
+		set_permissions (dialog, 0);
+	} else {
+		gtk_list_store_remove (dialog->priv->list_store, &iter);
+		e2k_security_descriptor_remove_sid (dialog->priv->sd, sid);
+
+		if (!gtk_list_store_iter_is_valid (dialog->priv->list_store, &iter)) {
+			/* Select the new last row. Love that API... */
+			gtk_tree_model_iter_nth_child (model, &iter, NULL,
+						       gtk_tree_model_iter_n_children (model, NULL) - 1);
+		}
+		gtk_tree_selection_select_iter (dialog->priv->list_selection, &iter);
+
+		dialog->priv->changed = TRUE;
+	}
+}
+
+static void
+setup_user_list (ExchangePermissionsDialog *dialog)
+{
+	E2kSecurityDescriptor *sd = dialog->priv->sd;
+	E2kSid *default_entry;
+	GList *sids;
+
+	/* Always put "Default" first. */
+	default_entry = e2k_security_descriptor_get_default (sd);
+	add_user_to_list (dialog, default_entry, TRUE);
+
+	sids = e2k_security_descriptor_get_sids (sd);
+	while (sids) {
+		if (sids->data != default_entry)
+			add_user_to_list (dialog, sids->data, FALSE);
+		sids = sids->next;
+	}
+	g_list_free (sids);
+}
+
+/* Role option menu functions */
+
+static void
+role_changed (GtkWidget *role_combo, gpointer user_data)
+{
+	ExchangePermissionsDialog *dialog = user_data;
+	gint role;
+
+	if (dialog->priv->frozen)
+		return;
+
+	role = gtk_combo_box_get_active (GTK_COMBO_BOX (role_combo));
+	if (role == dialog->priv->selected_role)
+		return;
+	if (role >= E2K_PERMISSIONS_ROLE_NUM_ROLES) {
+		/* The user selected "Custom". Since "Custom" will
+		 * only be there to select when it's already
+		 * selected, this is a no-op.
+		 */
+		return;
+	}
+
+	set_permissions (dialog, e2k_permissions_role_get_perms (role));
+	display_permissions (dialog);
+}
+
+static void
+display_role (ExchangePermissionsDialog *dialog)
+{
+	gint role = dialog->priv->selected_role;
+	GtkTreeModel *model;
+	GtkTreeIter iter;
+
+	if (!gtk_tree_selection_get_selected (dialog->priv->list_selection,
+					      &model, &iter))
+		return;
+	gtk_list_store_set (dialog->priv->list_store, &iter,
+			    EXCHANGE_PERMISSIONS_DIALOG_ROLE_COLUMN,
+			    e2k_permissions_role_get_name (role),
+			    -1);
+
+	if (role == E2K_PERMISSIONS_ROLE_CUSTOM) {
+		if (dialog->priv->custom_added == FALSE) {
+			gtk_combo_box_append_text (GTK_COMBO_BOX (dialog->priv->role_optionmenu), _("Custom"));
+			dialog->priv->custom_added = TRUE;
+		}
+		role = E2K_PERMISSIONS_ROLE_NUM_ROLES;
+	}
+	else	{
+		if (dialog->priv->custom_added) {
+			gtk_combo_box_remove_text (GTK_COMBO_BOX (dialog->priv->role_optionmenu), E2K_PERMISSIONS_ROLE_NUM_ROLES);
+			dialog->priv->custom_added = FALSE;
+		}
+	}
+
+	gtk_combo_box_set_active (GTK_COMBO_BOX (dialog->priv->role_optionmenu), role);
+}
+
+/* Toggle buttons */
+static void
+check_toggled (GtkToggleButton *toggle, gpointer user_data)
+{
+	ExchangePermissionsDialog *dialog = user_data;
+	ExchangePermissionsDialogPrivate *priv = dialog->priv;
+	guint32 new_perms, value;
+
+	if (dialog->priv->frozen)
+		return;
+
+	value = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (toggle), "mapi_permission"));
+
+	if (gtk_toggle_button_get_active (toggle))
+		new_perms = priv->selected_perms | value;
+	else
+		new_perms = priv->selected_perms & ~value;
+
+	if (new_perms == priv->selected_perms)
+		return;
+
+	set_permissions (dialog, new_perms);
+	display_role (dialog);
+}
+
+static void
+radio_toggled (GtkToggleButton *toggle, gpointer user_data)
+{
+	ExchangePermissionsDialog *dialog = user_data;
+	ExchangePermissionsDialogPrivate *priv = dialog->priv;
+	guint32 new_perms, value, mask;
+
+	if (dialog->priv->frozen || !gtk_toggle_button_get_active (toggle))
+		return;
+
+	value = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (toggle), "mapi_permission"));
+	mask = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (toggle), "mapi_mask"));
+
+	new_perms = (priv->selected_perms & ~mask) | value;
+	if (new_perms == priv->selected_perms)
+		return;
+
+	set_permissions (dialog, new_perms);
+	display_role (dialog);
+}
+
+static void
+rv_toggle (GtkToggleButton *toggled, gpointer user_data)
+{
+	ExchangePermissionsDialog *dialog = user_data;
+	GtkToggleButton *visible = dialog->priv->folder_visible_check;
+	GtkToggleButton *read = dialog->priv->read_items_check;
+
+	if (dialog->priv->frozen)
+		return;
+
+	/* If you turn off "Folder visible", then "Read items" turns
+	 * off too. Contrariwise, if you turn on "Read items", then
+	 * "Folder visible" turns on too.
+	 */
+	if (toggled == visible && !gtk_toggle_button_get_active (toggled))
+		gtk_toggle_button_set_active (read, FALSE);
+	else if (toggled == read && gtk_toggle_button_get_active (toggled))
+		gtk_toggle_button_set_active (visible, TRUE);
+}
+
+static void
+display_permissions (ExchangePermissionsDialog *dialog)
+{
+	GtkToggleButton *radio;
+	guint32 perms = dialog->priv->selected_perms;
+
+	dialog->priv->frozen = TRUE;
+
+	/* Set up check boxes */
+	gtk_toggle_button_set_active (dialog->priv->read_items_check,
+				      perms & E2K_PERMISSION_READ_ANY);
+	gtk_toggle_button_set_active (dialog->priv->create_items_check,
+				      perms & E2K_PERMISSION_CREATE);
+	gtk_toggle_button_set_active (dialog->priv->create_subfolders_check,
+				      perms & E2K_PERMISSION_CREATE_SUBFOLDER);
+	gtk_toggle_button_set_active (dialog->priv->folder_owner_check,
+				      perms & E2K_PERMISSION_OWNER);
+	gtk_toggle_button_set_active (dialog->priv->folder_contact_check,
+				      (perms & E2K_PERMISSION_CONTACT) &&
+				      GTK_WIDGET_SENSITIVE (dialog->priv->folder_contact_check));
+	gtk_toggle_button_set_active (dialog->priv->folder_visible_check,
+				      perms & E2K_PERMISSION_FOLDER_VISIBLE);
+
+	/* Set up radio buttons */
+	if (perms & E2K_PERMISSION_EDIT_ANY)
+		radio = dialog->priv->edit_all_radio;
+	else if (perms & E2K_PERMISSION_EDIT_OWNED)
+		radio = dialog->priv->edit_own_radio;
+	else
+		radio = dialog->priv->edit_none_radio;
+	gtk_toggle_button_set_active (radio, TRUE);
+
+	if (perms & E2K_PERMISSION_DELETE_ANY)
+		radio = dialog->priv->delete_all_radio;
+	else if (perms & E2K_PERMISSION_DELETE_OWNED)
+		radio = dialog->priv->delete_own_radio;
+	else
+		radio = dialog->priv->delete_none_radio;
+	gtk_toggle_button_set_active (radio, TRUE);
+
+	/* And role menu */
+	display_role (dialog);
+
+	dialog->priv->frozen = FALSE;
+}
+
+static GtkWidget *
+exchange_permissions_role_optionmenu_new (void)
+{
+	GtkWidget *menu;
+	const gchar **roles;
+	gint role;
+
+	menu = gtk_combo_box_new_text ();
+	roles = g_new (const gchar *, E2K_PERMISSIONS_ROLE_NUM_ROLES + 1);
+	for (role = 0; role < E2K_PERMISSIONS_ROLE_NUM_ROLES; role++) {
+		roles[role] = e2k_permissions_role_get_name (role);
+		gtk_combo_box_append_text (GTK_COMBO_BOX (menu), roles[role]);
+	}
+
+	roles[role] = NULL;
+
+	g_free (roles);
+
+	gtk_widget_show (menu);
+	return menu;
+}
+
+static GtkWidget *
+create_permissions_vbox (ExchangePermissionsDialog *dialog)
+{
+	GtkWidget *permissions_vbox;
+	GtkWidget *hbox1;
+	GtkWidget *scrolledwindow1;
+	GtkWidget *list_view;
+	GtkWidget *vbuttonbox1;
+	GtkWidget *add_button;
+	GtkWidget *remove_button;
+	GtkWidget *table2;
+	GtkWidget *label6;
+	GtkWidget *label7;
+	GtkWidget *label3;
+	GtkWidget *hbox3;
+	GtkWidget *label4;
+	GtkWidget *role_optionmenu;
+	GtkWidget *hbox2;
+	GtkWidget *vbox6;
+	GtkWidget *vbox8;
+	GtkWidget *create_items_check;
+	GtkWidget *read_items_check;
+	GtkWidget *create_subfolders_check;
+	GtkWidget *vbox9;
+	GtkWidget *edit_none_radio;
+	GSList *edit_none_radio_group = NULL;
+	GtkWidget *edit_own_radio;
+	GtkWidget *edit_all_radio;
+	GtkWidget *vbox7;
+	GtkWidget *vbox10;
+	GtkWidget *folder_owner_check;
+	GtkWidget *folder_contact_check;
+	GtkWidget *folder_visible_check;
+	GtkWidget *vbox11;
+	GtkWidget *delete_none_radio;
+	GSList *delete_none_radio_group = NULL;
+	GtkWidget *delete_own_radio;
+	GtkWidget *delete_all_radio;
+	gchar *tmp_str;
+	GtkTreeViewColumn *column;
+
+	permissions_vbox = gtk_vbox_new (FALSE, 0);
+	gtk_widget_show (permissions_vbox);
+	gtk_container_set_border_width (GTK_CONTAINER (permissions_vbox), 6);
+
+	hbox1 = gtk_hbox_new (FALSE, 6);
+	gtk_widget_show (hbox1);
+	gtk_box_pack_start (GTK_BOX (permissions_vbox), hbox1, TRUE, TRUE, 0);
+	gtk_container_set_border_width (GTK_CONTAINER (hbox1), 6);
+
+	scrolledwindow1 = gtk_scrolled_window_new (NULL, NULL);
+	gtk_widget_show (scrolledwindow1);
+	gtk_box_pack_start (GTK_BOX (hbox1), scrolledwindow1, TRUE, TRUE, 0);
+	GTK_WIDGET_UNSET_FLAGS (scrolledwindow1, GTK_CAN_FOCUS);
+	gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwindow1), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
+	gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolledwindow1), GTK_SHADOW_IN);
+
+	list_view = gtk_tree_view_new ();
+	gtk_widget_show (list_view);
+	gtk_container_add (GTK_CONTAINER (scrolledwindow1), list_view);
+
+	vbuttonbox1 = gtk_vbutton_box_new ();
+	gtk_widget_show (vbuttonbox1);
+	gtk_box_pack_start (GTK_BOX (hbox1), vbuttonbox1, FALSE, TRUE, 0);
+	gtk_container_set_border_width (GTK_CONTAINER (vbuttonbox1), 4);
+	gtk_button_box_set_layout (GTK_BUTTON_BOX (vbuttonbox1), GTK_BUTTONBOX_SPREAD);
+	gtk_box_set_spacing (GTK_BOX (vbuttonbox1), 10);
+
+	add_button = gtk_button_new_from_stock ("gtk-add");
+	gtk_widget_show (add_button);
+	gtk_container_add (GTK_CONTAINER (vbuttonbox1), add_button);
+	GTK_WIDGET_SET_FLAGS (add_button, GTK_CAN_DEFAULT);
+
+	remove_button = gtk_button_new_from_stock ("gtk-remove");
+	gtk_widget_show (remove_button);
+	gtk_container_add (GTK_CONTAINER (vbuttonbox1), remove_button);
+	GTK_WIDGET_SET_FLAGS (remove_button, GTK_CAN_DEFAULT);
+
+	table2 = gtk_table_new (3, 2, FALSE);
+	gtk_widget_show (table2);
+	gtk_box_pack_start (GTK_BOX (permissions_vbox), table2, FALSE, TRUE, 0);
+	gtk_container_set_border_width (GTK_CONTAINER (table2), 6);
+	gtk_table_set_row_spacings (GTK_TABLE (table2), 6);
+
+	label6 = gtk_label_new ("    ");
+	gtk_widget_show (label6);
+	gtk_table_attach (GTK_TABLE (table2), label6, 0, 1, 1, 2,
+			  (GtkAttachOptions) (GTK_FILL),
+			  (GtkAttachOptions) (0), 0, 0);
+	gtk_misc_set_alignment (GTK_MISC (label6), 0, 0.5);
+
+	label7 = gtk_label_new ("    ");
+	gtk_widget_show (label7);
+	gtk_table_attach (GTK_TABLE (table2), label7, 0, 1, 2, 3,
+			  (GtkAttachOptions) (GTK_FILL),
+			  (GtkAttachOptions) (0), 0, 0);
+	gtk_misc_set_alignment (GTK_MISC (label7), 0, 0.5);
+
+	tmp_str = g_strconcat ("<b>", _("Permissions"), "</b>", NULL);
+	label3 = gtk_label_new (tmp_str);
+	g_free (tmp_str);
+	gtk_widget_show (label3);
+	gtk_table_attach (GTK_TABLE (table2), label3, 0, 2, 0, 1,
+			  (GtkAttachOptions) (GTK_FILL),
+			  (GtkAttachOptions) (0), 0, 0);
+	gtk_label_set_use_markup (GTK_LABEL (label3), TRUE);
+	gtk_misc_set_alignment (GTK_MISC (label3), 0, 0.5);
+
+	hbox3 = gtk_hbox_new (FALSE, 6);
+	gtk_widget_show (hbox3);
+	gtk_table_attach (GTK_TABLE (table2), hbox3, 1, 2, 1, 2,
+			  (GtkAttachOptions) (GTK_FILL),
+			  (GtkAttachOptions) (GTK_FILL), 0, 0);
+	gtk_container_set_border_width (GTK_CONTAINER (hbox3), 6);
+
+	label4 = gtk_label_new (_("Role: "));
+	gtk_widget_show (label4);
+	gtk_box_pack_start (GTK_BOX (hbox3), label4, FALSE, FALSE, 0);
+	gtk_label_set_justify (GTK_LABEL (label4), GTK_JUSTIFY_CENTER);
+
+	role_optionmenu = exchange_permissions_role_optionmenu_new ();
+	gtk_widget_show (role_optionmenu);
+	gtk_box_pack_start (GTK_BOX (hbox3), role_optionmenu, TRUE, TRUE, 0);
+	GTK_WIDGET_UNSET_FLAGS (role_optionmenu, GTK_CAN_FOCUS);
+	GTK_WIDGET_UNSET_FLAGS (role_optionmenu, GTK_CAN_DEFAULT);
+
+	hbox2 = gtk_hbox_new (TRUE, 6);
+	gtk_widget_show (hbox2);
+	gtk_table_attach (GTK_TABLE (table2), hbox2, 1, 2, 2, 3,
+			  (GtkAttachOptions) (GTK_FILL),
+			  (GtkAttachOptions) (GTK_FILL), 0, 0);
+	gtk_container_set_border_width (GTK_CONTAINER (hbox2), 6);
+
+	vbox6 = gtk_vbox_new (FALSE, 12);
+	gtk_widget_show (vbox6);
+	gtk_box_pack_start (GTK_BOX (hbox2), vbox6, TRUE, TRUE, 0);
+
+	vbox8 = gtk_vbox_new (FALSE, 6);
+	gtk_widget_show (vbox8);
+	gtk_box_pack_start (GTK_BOX (vbox6), vbox8, TRUE, TRUE, 0);
+
+	create_items_check = gtk_check_button_new_with_mnemonic (_("Create items"));
+	gtk_widget_show (create_items_check);
+	gtk_box_pack_start (GTK_BOX (vbox8), create_items_check, FALSE, FALSE, 0);
+
+	read_items_check = gtk_check_button_new_with_mnemonic (_("Read items"));
+	gtk_widget_show (read_items_check);
+	gtk_box_pack_start (GTK_BOX (vbox8), read_items_check, FALSE, FALSE, 0);
+
+	create_subfolders_check = gtk_check_button_new_with_mnemonic (_("Create subfolders"));
+	gtk_widget_show (create_subfolders_check);
+	gtk_box_pack_start (GTK_BOX (vbox8), create_subfolders_check, FALSE, FALSE, 0);
+
+	vbox9 = gtk_vbox_new (FALSE, 6);
+	gtk_widget_show (vbox9);
+	gtk_box_pack_start (GTK_BOX (vbox6), vbox9, TRUE, TRUE, 0);
+
+	edit_none_radio = gtk_radio_button_new_with_mnemonic (NULL, _("Cannot Edit"));
+	gtk_widget_show (edit_none_radio);
+	gtk_box_pack_start (GTK_BOX (vbox9), edit_none_radio, FALSE, FALSE, 0);
+	gtk_radio_button_set_group (GTK_RADIO_BUTTON (edit_none_radio), edit_none_radio_group);
+	edit_none_radio_group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (edit_none_radio));
+
+	edit_own_radio = gtk_radio_button_new_with_mnemonic (NULL, _("Edit Own Items"));
+	gtk_widget_show (edit_own_radio);
+	gtk_box_pack_start (GTK_BOX (vbox9), edit_own_radio, FALSE, FALSE, 0);
+	gtk_radio_button_set_group (GTK_RADIO_BUTTON (edit_own_radio), edit_none_radio_group);
+	edit_none_radio_group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (edit_own_radio));
+
+	edit_all_radio = gtk_radio_button_new_with_mnemonic (NULL, _("Edit Any Items"));
+	gtk_widget_show (edit_all_radio);
+	gtk_box_pack_start (GTK_BOX (vbox9), edit_all_radio, FALSE, FALSE, 0);
+	gtk_radio_button_set_group (GTK_RADIO_BUTTON (edit_all_radio), edit_none_radio_group);
+	edit_none_radio_group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (edit_all_radio));
+
+	vbox7 = gtk_vbox_new (FALSE, 12);
+	gtk_widget_show (vbox7);
+	gtk_box_pack_start (GTK_BOX (hbox2), vbox7, TRUE, TRUE, 0);
+
+	vbox10 = gtk_vbox_new (FALSE, 6);
+	gtk_widget_show (vbox10);
+	gtk_box_pack_start (GTK_BOX (vbox7), vbox10, TRUE, TRUE, 0);
+
+	folder_owner_check = gtk_check_button_new_with_mnemonic (_("Folder owner"));
+	gtk_widget_show (folder_owner_check);
+	gtk_box_pack_start (GTK_BOX (vbox10), folder_owner_check, FALSE, FALSE, 0);
+
+	folder_contact_check = gtk_check_button_new_with_mnemonic (_("Folder contact"));
+	gtk_widget_show (folder_contact_check);
+	gtk_box_pack_start (GTK_BOX (vbox10), folder_contact_check, FALSE, FALSE, 0);
+
+	folder_visible_check = gtk_check_button_new_with_mnemonic (_("Folder visible"));
+	gtk_widget_show (folder_visible_check);
+	gtk_box_pack_start (GTK_BOX (vbox10), folder_visible_check, FALSE, FALSE, 0);
+
+	vbox11 = gtk_vbox_new (FALSE, 6);
+	gtk_widget_show (vbox11);
+	gtk_box_pack_start (GTK_BOX (vbox7), vbox11, TRUE, TRUE, 0);
+
+	delete_none_radio = gtk_radio_button_new_with_mnemonic (NULL, _("Cannot Delete"));
+	gtk_widget_show (delete_none_radio);
+	gtk_box_pack_start (GTK_BOX (vbox11), delete_none_radio, FALSE, FALSE, 0);
+	gtk_radio_button_set_group (GTK_RADIO_BUTTON (delete_none_radio), delete_none_radio_group);
+	delete_none_radio_group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (delete_none_radio));
+	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (delete_none_radio), TRUE);
+
+	delete_own_radio = gtk_radio_button_new_with_mnemonic (NULL, _("Delete Own Items"));
+	gtk_widget_show (delete_own_radio);
+	gtk_box_pack_start (GTK_BOX (vbox11), delete_own_radio, FALSE, FALSE, 0);
+	gtk_radio_button_set_group (GTK_RADIO_BUTTON (delete_own_radio), delete_none_radio_group);
+	delete_none_radio_group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (delete_own_radio));
+
+	delete_all_radio = gtk_radio_button_new_with_mnemonic (NULL, _("Delete Any Items"));
+	gtk_widget_show (delete_all_radio);
+	gtk_box_pack_start (GTK_BOX (vbox11), delete_all_radio, FALSE, FALSE, 0);
+	gtk_radio_button_set_group (GTK_RADIO_BUTTON (delete_all_radio), delete_none_radio_group);
+	delete_none_radio_group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (delete_all_radio));
+
+#define GET_WIDGET(name, type) dialog->priv->name = type (name)
+
+	GET_WIDGET (list_view, GTK_TREE_VIEW);
+	column = gtk_tree_view_column_new_with_attributes (
+		_("Name"), gtk_cell_renderer_text_new (),
+		"text", EXCHANGE_PERMISSIONS_DIALOG_NAME_COLUMN, NULL);
+	gtk_tree_view_append_column (dialog->priv->list_view, column);
+	column = gtk_tree_view_column_new_with_attributes (
+		_("Role"), gtk_cell_renderer_text_new (),
+		"text", EXCHANGE_PERMISSIONS_DIALOG_ROLE_COLUMN, NULL);
+	gtk_tree_view_append_column (dialog->priv->list_view, column);
+
+	dialog->priv->list_selection = gtk_tree_view_get_selection (dialog->priv->list_view);
+	gtk_tree_selection_set_mode (dialog->priv->list_selection,
+				     GTK_SELECTION_SINGLE);
+	g_signal_connect (dialog->priv->list_selection, "changed",
+			  G_CALLBACK (list_view_selection_changed), dialog);
+
+	dialog->priv->list_store = gtk_list_store_new (
+		EXCHANGE_PERMISSIONS_DIALOG_NUM_COLUMNS,
+		G_TYPE_STRING, G_TYPE_STRING, E2K_TYPE_SID);
+	gtk_tree_view_set_model (dialog->priv->list_view,
+				 GTK_TREE_MODEL (dialog->priv->list_store));
+
+	g_signal_connect (add_button, "clicked",
+			  G_CALLBACK (add_clicked), dialog);
+	g_signal_connect (remove_button, "clicked",
+			  G_CALLBACK (remove_clicked), dialog);
+
+	GET_WIDGET (role_optionmenu, GTK_COMBO_BOX);
+	g_signal_connect (dialog->priv->role_optionmenu, "changed",
+			  G_CALLBACK (role_changed), dialog);
+
+	dialog->priv->custom_added = FALSE;
+
+#define GET_TOGGLE(name, value, callback) \
+	GET_WIDGET (name, GTK_TOGGLE_BUTTON); \
+	g_object_set_data (G_OBJECT (dialog->priv->name), \
+			   "mapi_permission", \
+			   GUINT_TO_POINTER (value)); \
+	g_signal_connect (dialog->priv->name, "toggled", \
+			  G_CALLBACK (callback), dialog)
+
+#define GET_CHECK(name, value) \
+	GET_TOGGLE (name, value, check_toggled)
+
+#define GET_RADIO(name, value, mask) \
+	GET_TOGGLE (name, value, radio_toggled); \
+	g_object_set_data (G_OBJECT (dialog->priv->name), \
+			   "mapi_mask", \
+			   GUINT_TO_POINTER (mask))
+
+	GET_CHECK (read_items_check, E2K_PERMISSION_READ_ANY);
+	GET_CHECK (create_items_check, E2K_PERMISSION_CREATE);
+	GET_RADIO (edit_none_radio, 0, E2K_PERMISSION_EDIT_MASK);
+	GET_RADIO (delete_none_radio, 0, E2K_PERMISSION_DELETE_MASK);
+	GET_RADIO (edit_own_radio, E2K_PERMISSION_EDIT_OWNED, E2K_PERMISSION_EDIT_MASK);
+	GET_RADIO (delete_own_radio, E2K_PERMISSION_DELETE_OWNED, E2K_PERMISSION_DELETE_MASK);
+	GET_RADIO (edit_all_radio, (E2K_PERMISSION_EDIT_ANY | E2K_PERMISSION_EDIT_OWNED), E2K_PERMISSION_EDIT_MASK);
+	GET_RADIO (delete_all_radio, (E2K_PERMISSION_DELETE_ANY | E2K_PERMISSION_DELETE_OWNED), E2K_PERMISSION_DELETE_MASK);
+	GET_CHECK (create_subfolders_check, E2K_PERMISSION_CREATE_SUBFOLDER);
+	GET_CHECK (folder_owner_check, E2K_PERMISSION_OWNER);
+	GET_CHECK (folder_contact_check, E2K_PERMISSION_CONTACT);
+	GET_CHECK (folder_visible_check, E2K_PERMISSION_FOLDER_VISIBLE);
+
+	g_signal_connect (dialog->priv->folder_visible_check,
+			  "toggled", G_CALLBACK (rv_toggle), dialog);
+	g_signal_connect (dialog->priv->read_items_check,
+			  "toggled", G_CALLBACK (rv_toggle), dialog);
+
+	return permissions_vbox;
+}
diff --git a/eplugin/exchange-permissions-dialog.h b/eplugin/exchange-permissions-dialog.h
new file mode 100644
index 0000000..ad2f47d
--- /dev/null
+++ b/eplugin/exchange-permissions-dialog.h
@@ -0,0 +1,56 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifndef __EXCHANGE_PERMISSIONS_DIALOG_H__
+#define __EXCHANGE_PERMISSIONS_DIALOG_H__
+
+#include <gtk/gtk.h>
+#include "e-folder.h"
+#include "exchange-types.h"
+
+G_BEGIN_DECLS
+
+#define EXCHANGE_TYPE_PERMISSIONS_DIALOG            (exchange_permissions_dialog_get_type ())
+#define EXCHANGE_PERMISSIONS_DIALOG(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), EXCHANGE_TYPE_PERMISSIONS_DIALOG, ExchangePermissionsDialog))
+#define EXCHANGE_PERMISSIONS_DIALOG_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), EXCHANGE_TYPE_PERMISSIONS_DIALOG, ExchangePermissionsDialogClass))
+#define EXCHANGE_IS_PERMISSIONS_DIALOG(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EXCHANGE_TYPE_PERMISSIONS_DIALOG))
+#define EXCHANGE_IS_PERMISSIONS_DIALOG_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), EXCHANGE_TYPE_PERMISSIONS_DIALOG))
+
+struct _ExchangePermissionsDialog {
+	GtkDialog parent;
+
+	ExchangePermissionsDialogPrivate *priv;
+};
+
+struct _ExchangePermissionsDialogClass {
+	GtkDialogClass parent_class;
+
+};
+
+GType      exchange_permissions_dialog_get_type (void);
+
+void       exchange_permissions_dialog_new      (ExchangeAccount *account,
+						 EFolder         *folder,
+						 GtkWidget       *parent);
+
+G_END_DECLS
+
+#endif /* __EXCHANGE_PERMISSIONS_DIALOG_H__ */
diff --git a/eplugin/exchange-send-options.c b/eplugin/exchange-send-options.c
new file mode 100644
index 0000000..0b8722b
--- /dev/null
+++ b/eplugin/exchange-send-options.c
@@ -0,0 +1,621 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ *		R.Raghavendran <raghavguru7 gmail com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <string.h>
+#include <libedataserverui/e-name-selector.h>
+#include <libedataserverui/e-contact-store.h>
+#include "exchange-operations.h"
+#include <e-util/e-util.h>
+#include <e-util/e-error.h>
+
+#include "exchange-send-options.h"
+
+struct _ExchangeSendOptionsDialogPrivate {
+	/*Widgets*/
+	GtkWidget *main;
+
+	/*name selector dialog*/
+	ENameSelector *proxy_name_selector;
+
+	/*Importance*/
+	GtkWidget *importance;
+
+	/*Sensitivity*/
+	GtkWidget *sensitivity;
+
+	/*Send_as_delegate_enabled*/
+	GtkWidget *delegate_enabled;
+
+	/*Read Receipt*/
+	GtkWidget *read_receipt;
+
+	/*Delivery Receipt*/
+	GtkWidget *delivery_receipt;
+
+	/*User button*/
+	GtkWidget *button_user;
+
+	/*Label Widgets*/
+	GtkWidget *importance_label;
+	GtkWidget *sensitivity_label;
+	gchar *help_section;
+};
+
+static void exchange_sendoptions_dialog_class_init (GObjectClass *object_class);
+static void exchange_sendoptions_dialog_finalize (GObject *object);
+static void exchange_sendoptions_dialog_init (GObject *object);
+static void exchange_sendoptions_dialog_dispose (GObject *object);
+
+static GObjectClass *parent_class = NULL;
+enum {
+	SOD_RESPONSE,
+	LAST_SIGNAL
+};
+
+static guint signals[LAST_SIGNAL] = {0};
+
+/* exchange_send_options_get_widgets_data(ExchangeSendOptionsDialog *sod)
+   Return Value:This function returns a -1 if an error occurs. In case of error-free operation a 1 is returned.
+*/
+static gint
+exchange_send_options_get_widgets_data (ExchangeSendOptionsDialog *sod)
+{
+	ExchangeSendOptionsDialogPrivate *priv;
+	ExchangeSendOptions *options;
+	const gchar *address, *email, *name;
+
+	guint count=0;
+	ENameSelectorEntry *name_selector_entry;
+	EDestinationStore *destination_store;
+	GList *destinations, *tmp;
+
+	priv = sod->priv;
+	options = sod->options;
+
+	/* This block helps us fetch the address of the delegator(s). If no delegator is selected or more
+	   than one delegatee has been selected then an info dialog is popped up to help the user.
+	*/
+	if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (priv->delegate_enabled))) {
+
+		name_selector_entry = e_name_selector_peek_section_entry (priv->proxy_name_selector, "Add User");
+		destination_store = e_name_selector_entry_peek_destination_store (E_NAME_SELECTOR_ENTRY									       (name_selector_entry));
+		destinations = e_destination_store_list_destinations (destination_store);
+		tmp = destinations;
+
+		email = NULL;
+
+		/* The temporary variables address, email, and name are needed to fetch the list items.
+		   Only the valid one is then copied into the storage variables. The "count" variable
+		   helps us keep a count of the exact number of items in the list. The g_list_length(GList *)
+		   produced ambiguous results. Hence count is used :)
+		*/
+		for (; tmp != NULL; tmp = g_list_next (tmp)) {
+			address = g_strdup ((gchar *) e_destination_get_address (tmp->data));
+			email = g_strdup ((gchar *) e_destination_get_email (tmp->data));
+			name = g_strdup (e_destination_get_name (tmp->data));
+			if (g_str_equal (email, ""))
+				continue;
+			count++;
+
+			options->delegate_address = address;
+			options->delegate_name = name;
+			options->delegate_email = email;
+		}
+
+		if (count == 0) {
+			e_error_run ((GtkWindow *) priv->main,
+				"org-gnome-exchange-operations:no-delegate-selected", NULL, NULL);
+			gtk_widget_grab_focus ((GtkWidget *) name_selector_entry);
+			options->delegate_address = NULL;
+			options->delegate_name = NULL;
+			options->delegate_email = NULL;
+			return -1;
+		}
+
+		if (count > 1) {
+			e_error_run ((GtkWindow *)priv->main,
+				"org-gnome-exchange-operations:more-delegates-selected", NULL, NULL);
+			gtk_widget_grab_focus ((GtkWidget *) name_selector_entry);
+			options->delegate_address = NULL;
+			options->delegate_name = NULL;
+			options->delegate_email = NULL;
+			return -1;
+		}
+	}
+
+	options->importance = gtk_combo_box_get_active ((GtkComboBox *)priv->importance);
+	options->sensitivity = gtk_combo_box_get_active ((GtkComboBox *)priv->sensitivity);
+
+	options->send_as_del_enabled = gtk_toggle_button_get_active (
+					GTK_TOGGLE_BUTTON (priv->delegate_enabled));
+
+	options->delivery_enabled = gtk_toggle_button_get_active (
+					GTK_TOGGLE_BUTTON (priv->delivery_receipt));
+
+	options->read_enabled = gtk_toggle_button_get_active (
+					GTK_TOGGLE_BUTTON (priv->read_receipt));
+
+	return 1;
+}
+
+static void
+exchange_send_options_fill_widgets_with_data (ExchangeSendOptionsDialog *sod)
+{
+	ExchangeSendOptionsDialogPrivate *priv;
+	ExchangeSendOptions *options;
+	ENameSelectorEntry *name_selector_entry;
+
+	priv = sod->priv;
+	options = sod->options;
+
+	priv->help_section = g_strdup ("usage-mail");
+
+	gtk_label_set_mnemonic_widget (GTK_LABEL (priv->importance_label), priv->importance);
+	gtk_label_set_mnemonic_widget (GTK_LABEL (priv->sensitivity_label), priv->sensitivity);
+
+	gtk_combo_box_set_active ((GtkComboBox *) priv->importance, options->importance);
+	gtk_combo_box_set_active ((GtkComboBox *) priv->sensitivity, options->sensitivity);
+
+	name_selector_entry = e_name_selector_peek_section_entry (priv->proxy_name_selector, "Add User");
+
+	if (options->send_as_del_enabled) {
+		gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->delegate_enabled), TRUE);
+		gtk_widget_set_sensitive ((GtkWidget *)name_selector_entry, TRUE);
+		gtk_widget_set_sensitive ((GtkWidget *)priv->button_user, TRUE);
+	}
+
+	else {
+		gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->delegate_enabled), FALSE);
+		gtk_widget_set_sensitive ((GtkWidget *)name_selector_entry, FALSE);
+		gtk_widget_set_sensitive ((GtkWidget *)priv->button_user, FALSE);
+	}
+
+	if (options->read_enabled)
+		gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->read_receipt), TRUE);
+	else
+		gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->read_receipt), FALSE);
+
+	if (options->delivery_enabled)
+		gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->delivery_receipt), TRUE);
+	else
+		gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->delivery_receipt), FALSE);
+}
+
+ExchangeSendOptionsDialog *
+exchange_sendoptions_dialog_new (void) {
+	ExchangeSendOptionsDialog *sod;
+
+	sod = g_object_new (EXCHANGE_TYPE_SENDOPTIONS_DIALOG, NULL);
+
+	return sod;
+}
+
+GType exchange_sendoptions_dialog_get_type (void)
+{
+  static GType type = 0;
+  if (type == 0) {
+    static const GTypeInfo info = {
+      sizeof (ExchangeSendOptionsDialogClass),
+      NULL,   /* base_init */
+      NULL,   /* base_finalize */
+      (GClassInitFunc) exchange_sendoptions_dialog_class_init,   /* class_init */
+      NULL,   /* class_finalize */
+      NULL,   /* class_data */
+      sizeof (ExchangeSendOptionsDialog),
+     0,      /* n_preallocs */
+     (GInstanceInitFunc) exchange_sendoptions_dialog_init,
+	NULL    /* instance_init */
+    };
+    type = g_type_register_static (G_TYPE_OBJECT,
+                                   "ExchangeSendOptionsDialogType",
+                                   &info, 0);
+  }
+  return type;
+}
+
+static void exchange_send_options_cb (GtkDialog *dialog, gint state, gpointer func_data)
+{
+	ExchangeSendOptionsDialogPrivate *priv;
+	ExchangeSendOptionsDialog *sod;
+
+	sod = func_data;
+        priv = sod->priv;
+
+	switch (state) {
+		case GTK_RESPONSE_OK:
+		     if (exchange_send_options_get_widgets_data (sod) < 0)
+			return;
+		case GTK_RESPONSE_CANCEL:
+			gtk_widget_hide (priv->main);
+			gtk_widget_destroy (priv->main);
+			break;
+		case GTK_RESPONSE_HELP:
+			e_display_help (
+				GTK_WINDOW (priv->main),
+				priv->help_section);
+			break;
+	}
+	g_signal_emit (G_OBJECT (func_data), signals[SOD_RESPONSE], 0, state);
+
+}
+
+/* This function acts as a listener for the toggling of "send_as_a_delegate" button. This is needed to
+   sensitize the name_selector_entry and the User Button
+*/
+static void
+delegate_option_toggled (GtkCheckButton *button, gpointer func_data)
+{
+	ExchangeSendOptionsDialogPrivate *priv;
+	ExchangeSendOptionsDialog *sod;
+	ENameSelectorEntry *name_selector_entry;
+	ExchangeSendOptions *options;
+
+	sod=func_data;
+	priv=sod->priv;
+	options=sod->options;
+
+	name_selector_entry = e_name_selector_peek_section_entry (priv->proxy_name_selector, "Add User");
+
+	if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (priv->delegate_enabled))) {
+		gtk_widget_set_sensitive ((GtkWidget *) name_selector_entry, TRUE);
+		gtk_widget_set_sensitive ((GtkWidget *) priv->button_user, TRUE);
+	}
+
+	else {
+		gtk_widget_set_sensitive ((GtkWidget *) name_selector_entry, FALSE);
+		gtk_widget_set_sensitive ((GtkWidget *) priv->button_user, FALSE);
+	}
+
+}
+
+static void
+addressbook_dialog_response (ENameSelectorDialog *name_selector_dialog, gint response, gpointer user_data)
+{
+	gtk_widget_hide (GTK_WIDGET (name_selector_dialog));
+}
+
+static void
+addressbook_entry_changed (GtkWidget *entry, gpointer user_data)
+{
+}
+
+/* This function invokes the name selector dialog
+*/
+static void
+address_button_clicked (GtkButton *button, gpointer func_data)
+{
+
+	ExchangeSendOptionsDialogPrivate *priv;
+	ExchangeSendOptionsDialog *sod;
+	ENameSelectorDialog *name_selector_dialog;
+
+	sod=func_data;
+	priv=sod->priv;
+
+	name_selector_dialog = e_name_selector_peek_dialog (priv->proxy_name_selector);
+	gtk_widget_show (GTK_WIDGET (name_selector_dialog));
+}
+
+gboolean
+exchange_sendoptions_dialog_run (ExchangeSendOptionsDialog *sod, GtkWidget *parent)
+{
+	ExchangeSendOptionsDialogPrivate *priv;
+	ExchangeSendOptions *options;
+
+	EDestinationStore *destination_store;
+	ENameSelectorDialog *name_selector_dialog;
+	ENameSelectorModel *name_selector_model;
+	ENameSelectorEntry *name_selector_entry;
+	EDestination *des;
+	GtkWidget *send_options;
+	GtkWidget *send_options_vbox;
+	GtkWidget *options_vbox;
+	GtkWidget *message_settings_vbox;
+	GtkWidget *msg_settings_label;
+	GtkWidget *msg_settings_table;
+	GtkWidget *importance_label;
+	GtkWidget *sensitivity_label;
+	GtkWidget *sensitivity_combo_box;
+	GtkWidget *imp_combo_box;
+	GtkWidget *del_enabled_check;
+	GtkWidget *hbox1;
+	GtkWidget *hbox2;
+	GtkWidget *del_name_box;
+	GtkWidget *button_user;
+	GtkWidget *track_option_vbox;
+	GtkWidget *track_options_label;
+	GtkWidget *delivery_check_button;
+	GtkWidget *read_check_button;
+	gchar *tmp_str;
+
+	g_return_val_if_fail (sod != NULL || EXCHANGE_IS_SENDOPTIONS_DIALOG (sod), FALSE);
+
+	priv = sod->priv;
+	options = sod->options;
+
+	send_options = gtk_dialog_new_with_buttons (
+		_("Exchange - Send Options"),
+		NULL,
+		GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_NO_SEPARATOR,
+		GTK_STOCK_HELP, GTK_RESPONSE_HELP,
+		GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+		GTK_STOCK_OK, GTK_RESPONSE_OK,
+		NULL);
+	gtk_window_set_type_hint (GTK_WINDOW (send_options), GDK_WINDOW_TYPE_HINT_DIALOG);
+
+	send_options_vbox = gtk_dialog_get_content_area (GTK_DIALOG (send_options));
+	gtk_widget_show (send_options_vbox);
+
+	options_vbox = gtk_vbox_new (FALSE, 0);
+	gtk_widget_show (options_vbox);
+	gtk_box_pack_start (GTK_BOX (send_options_vbox), options_vbox, TRUE, TRUE, 0);
+	gtk_container_set_border_width (GTK_CONTAINER (options_vbox), 6);
+
+	message_settings_vbox = gtk_vbox_new (FALSE, 0);
+	gtk_widget_show (message_settings_vbox);
+	gtk_box_pack_start (GTK_BOX (options_vbox), message_settings_vbox, FALSE, FALSE, 0);
+
+	tmp_str = g_strconcat ("<b>", _("Message Settings"), "</b>", NULL);
+	msg_settings_label = gtk_label_new (tmp_str);
+	g_free (tmp_str);
+	gtk_widget_show (msg_settings_label);
+	gtk_box_pack_start (GTK_BOX (message_settings_vbox), msg_settings_label, FALSE, FALSE, 0);
+	gtk_label_set_use_markup (GTK_LABEL (msg_settings_label), TRUE);
+	gtk_misc_set_alignment (GTK_MISC (msg_settings_label), 0, 0.49);
+
+	msg_settings_table = gtk_table_new (2, 2, FALSE);
+	gtk_widget_show (msg_settings_table);
+	gtk_box_pack_start (GTK_BOX (message_settings_vbox), msg_settings_table, FALSE, FALSE, 0);
+	gtk_container_set_border_width (GTK_CONTAINER (msg_settings_table), 6);
+	gtk_table_set_row_spacings (GTK_TABLE (msg_settings_table), 6);
+
+	importance_label = gtk_label_new_with_mnemonic (_("I_mportance: "));
+	gtk_widget_show (importance_label);
+	gtk_table_attach (GTK_TABLE (msg_settings_table), importance_label, 0, 1, 0, 1,
+			  (GtkAttachOptions) (GTK_FILL),
+			  (GtkAttachOptions) (0), 0, 0);
+	gtk_misc_set_alignment (GTK_MISC (importance_label), 0, 0.49);
+
+	sensitivity_label = gtk_label_new_with_mnemonic (_("_Sensitivity: "));
+	gtk_widget_show (sensitivity_label);
+	gtk_table_attach (GTK_TABLE (msg_settings_table), sensitivity_label, 0, 1, 1, 2,
+			  (GtkAttachOptions) (GTK_FILL),
+			  (GtkAttachOptions) (0), 0, 0);
+	gtk_misc_set_alignment (GTK_MISC (sensitivity_label), 0, 0.5);
+
+	sensitivity_combo_box = gtk_combo_box_new_text ();
+	gtk_widget_show (sensitivity_combo_box);
+	gtk_table_attach (GTK_TABLE (msg_settings_table), sensitivity_combo_box, 1, 2, 1, 2,
+			  (GtkAttachOptions) (GTK_FILL),
+			  (GtkAttachOptions) (GTK_FILL), 0, 0);
+	gtk_combo_box_append_text (GTK_COMBO_BOX (sensitivity_combo_box), _("Normal"));
+	gtk_combo_box_append_text (GTK_COMBO_BOX (sensitivity_combo_box), _("Personal"));
+	gtk_combo_box_append_text (GTK_COMBO_BOX (sensitivity_combo_box), _("Private"));
+	gtk_combo_box_append_text (GTK_COMBO_BOX (sensitivity_combo_box), _("Confidential"));
+
+	imp_combo_box = gtk_combo_box_new_text ();
+	gtk_widget_show (imp_combo_box);
+	gtk_table_attach (GTK_TABLE (msg_settings_table), imp_combo_box, 1, 2, 0, 1,
+			  (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
+			  (GtkAttachOptions) (GTK_FILL), 0, 0);
+	gtk_combo_box_append_text (GTK_COMBO_BOX (imp_combo_box), _("Normal"));
+	gtk_combo_box_append_text (GTK_COMBO_BOX (imp_combo_box), _("High"));
+	gtk_combo_box_append_text (GTK_COMBO_BOX (imp_combo_box), _("Low"));
+
+	del_enabled_check = gtk_check_button_new_with_mnemonic (_("Send as Delegate"));
+	gtk_widget_show (del_enabled_check);
+	gtk_box_pack_start (GTK_BOX (options_vbox), del_enabled_check, FALSE, FALSE, 0);
+	gtk_container_set_border_width (GTK_CONTAINER (del_enabled_check), 6);
+
+	hbox1 = gtk_hbox_new (FALSE, 0);
+	gtk_widget_show (hbox1);
+	gtk_box_pack_start (GTK_BOX (options_vbox), hbox1, TRUE, TRUE, 0);
+
+	hbox2 = gtk_hbox_new (FALSE, 0);
+	gtk_widget_show (hbox2);
+	gtk_box_pack_start (GTK_BOX (hbox1), hbox2, TRUE, TRUE, 0);
+
+	del_name_box = gtk_hbox_new (FALSE, 0);
+	gtk_widget_show (del_name_box);
+	gtk_box_pack_start (GTK_BOX (hbox2), del_name_box, TRUE, TRUE, 0);
+
+	button_user = gtk_button_new_with_mnemonic (_("_User"));
+	gtk_widget_show (button_user);
+	gtk_box_pack_start (GTK_BOX (hbox1), button_user, FALSE, FALSE, 0);
+
+	track_option_vbox = gtk_vbox_new (FALSE, 0);
+	gtk_widget_show (track_option_vbox);
+	gtk_box_pack_start (GTK_BOX (options_vbox), track_option_vbox, TRUE, TRUE, 0);
+
+	tmp_str = g_strconcat ("<b>", _("Tracking Options"), "</b>", NULL);
+	track_options_label = gtk_label_new (tmp_str);
+	g_free (tmp_str);
+	gtk_widget_show (track_options_label);
+	gtk_box_pack_start (GTK_BOX (track_option_vbox), track_options_label, FALSE, FALSE, 6);
+	gtk_label_set_use_markup (GTK_LABEL (track_options_label), TRUE);
+	gtk_misc_set_alignment (GTK_MISC (track_options_label), 0, 0.5);
+
+	delivery_check_button = gtk_check_button_new_with_mnemonic (_("Request a _delivery receipt for this message"));
+	gtk_widget_show (delivery_check_button);
+	gtk_box_pack_start (GTK_BOX (track_option_vbox), delivery_check_button, FALSE, FALSE, 0);
+	gtk_container_set_border_width (GTK_CONTAINER (delivery_check_button), 6);
+
+	read_check_button = gtk_check_button_new_with_mnemonic (_("Request a _read receipt for this message"));
+	gtk_widget_show (read_check_button);
+	gtk_box_pack_start (GTK_BOX (track_option_vbox), read_check_button, FALSE, FALSE, 0);
+	gtk_container_set_border_width (GTK_CONTAINER (read_check_button), 6);
+
+	priv->main = send_options;
+	priv->importance = imp_combo_box;
+	priv->sensitivity = sensitivity_combo_box;
+	priv->button_user = button_user;
+	priv->delegate_enabled = del_enabled_check;
+	priv->read_receipt = read_check_button;
+	priv->delivery_receipt = delivery_check_button;
+	priv->importance_label = importance_label;
+	priv->sensitivity_label = sensitivity_label;
+
+	send_options =  gtk_widget_get_toplevel (priv->main);
+	if (parent)
+		gtk_window_set_transient_for (GTK_WINDOW (send_options),
+				      GTK_WINDOW (parent));
+
+	priv->proxy_name_selector = e_name_selector_new ();
+	name_selector_dialog = e_name_selector_peek_dialog (priv->proxy_name_selector);
+
+	name_selector_model = e_name_selector_peek_model (priv->proxy_name_selector);
+	e_name_selector_model_add_section (name_selector_model, "Add User", _("Add User"), NULL);
+
+	exchange_send_options_fill_widgets_with_data (sod);
+
+	if (options->delegate_address) {
+		e_name_selector_model_peek_section (name_selector_model, "Add User", NULL, &destination_store);
+		des = e_destination_new ();
+		e_destination_set_email (des, options->delegate_email);
+		e_destination_set_name (des, options->delegate_name);
+		e_destination_store_append_destination (destination_store, des);
+		g_object_unref (des);
+	}
+
+	g_signal_connect ((GtkButton *) priv->button_user, "clicked",
+				G_CALLBACK (address_button_clicked), sod);
+	g_signal_connect (name_selector_dialog, "response",
+				G_CALLBACK (addressbook_dialog_response), sod);
+	g_signal_connect (GTK_DIALOG (priv->main), "response",
+				G_CALLBACK(exchange_send_options_cb), sod);
+	g_signal_connect ((GtkCheckButton *) priv->delegate_enabled, "toggled",
+				G_CALLBACK(delegate_option_toggled), sod);
+
+	name_selector_entry = e_name_selector_peek_section_entry (priv->proxy_name_selector,
+									"Add User");
+	g_signal_connect (name_selector_entry, "changed", G_CALLBACK (addressbook_entry_changed), sod);
+
+	/* The name box is just a container. The name_selector_entry is added to it. This Widget
+	   is created dynamically*/
+	gtk_container_add ((GtkContainer *) del_name_box, (GtkWidget *) name_selector_entry);
+	gtk_widget_show ((GtkWidget *) name_selector_entry);
+	gtk_widget_grab_focus ((GtkWidget *) name_selector_entry);
+
+	gtk_window_set_modal ((GtkWindow *) priv->main, TRUE);
+	gtk_widget_show (priv->main);
+
+	return TRUE;
+}
+
+static void
+exchange_sendoptions_dialog_class_init (GObjectClass *object)
+{
+	ExchangeSendOptionsDialogClass *klass;
+	GObjectClass *object_class;
+
+	klass = EXCHANGE_SENDOPTIONS_DIALOG_CLASS (object);
+	parent_class = g_type_class_peek_parent (klass);
+	object_class = G_OBJECT_CLASS (klass);
+
+	object_class->finalize = exchange_sendoptions_dialog_finalize;
+	object_class->dispose = exchange_sendoptions_dialog_dispose;
+	signals[SOD_RESPONSE] = g_signal_new ("sod_response",
+			G_TYPE_FROM_CLASS (klass),
+			G_SIGNAL_RUN_FIRST,
+			G_STRUCT_OFFSET (ExchangeSendOptionsDialogClass, esod_response),
+			NULL, NULL,
+			g_cclosure_marshal_VOID__INT,
+			G_TYPE_NONE, 1,
+			G_TYPE_INT);
+
+}
+
+static void
+exchange_sendoptions_dialog_init (GObject *object)
+{
+
+	ExchangeSendOptionsDialog *sod;
+	ExchangeSendOptionsDialogPrivate *priv;
+	ExchangeSendOptions *new;
+
+	sod = EXCHANGE_SENDOPTIONS_DIALOG (object);
+	new = g_new0 (ExchangeSendOptions, 1);
+
+	priv = g_new0 (ExchangeSendOptionsDialogPrivate, 1);
+
+	sod->priv = priv;
+	sod->options = new;
+	sod->options->send_as_del_enabled = FALSE;
+	sod->options->delivery_enabled = FALSE;
+	sod->options->read_enabled = FALSE;
+	sod->options->importance = E_IMP_NORMAL;
+	sod->options->sensitivity = E_SENSITIVITY_NORMAL;
+
+	priv->main = NULL;
+	priv->importance = NULL;
+	priv->sensitivity = NULL;
+	priv->sensitivity_label = NULL;
+	priv->importance_label = NULL;
+	priv->button_user = NULL;
+	priv->proxy_name_selector = NULL;
+	priv->read_receipt = NULL;
+	priv->delivery_receipt = NULL;
+
+}
+
+static void
+exchange_sendoptions_dialog_finalize (GObject *object)
+{
+	ExchangeSendOptionsDialog *sod = (ExchangeSendOptionsDialog *)object;
+	ExchangeSendOptionsDialogPrivate *priv;
+
+	g_return_if_fail (EXCHANGE_IS_SENDOPTIONS_DIALOG (sod));
+	priv = sod->priv;
+
+	g_free (priv->help_section);
+
+	if (sod->options) {
+		g_free (sod->options);
+		sod->options = NULL;
+	}
+
+	if (sod->priv) {
+		g_free (sod->priv);
+		sod->priv = NULL;
+	}
+
+	if (parent_class->finalize)
+		(* parent_class->finalize) (object);
+
+}
+
+static void
+exchange_sendoptions_dialog_dispose (GObject *object)
+{
+	ExchangeSendOptionsDialog *sod = (ExchangeSendOptionsDialog *) object;
+
+	g_return_if_fail (EXCHANGE_IS_SENDOPTIONS_DIALOG (sod));
+
+	if (parent_class->dispose)
+		(* parent_class->dispose) (object);
+
+}
+
diff --git a/eplugin/exchange-send-options.h b/eplugin/exchange-send-options.h
new file mode 100644
index 0000000..131fee0
--- /dev/null
+++ b/eplugin/exchange-send-options.h
@@ -0,0 +1,83 @@
+/*
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ *		Raghavendran R <raghavguru7 gmail com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifndef __EXCHANGE_SENDOPTIONS_DIALOG_H__
+#define __EXCHANGE_SENDOPTIONS_DIALOG_H__
+
+#include <gtk/gtk.h>
+
+#define EXCHANGE_TYPE_SENDOPTIONS_DIALOG       (exchange_sendoptions_dialog_get_type ())
+#define EXCHANGE_SENDOPTIONS_DIALOG(obj)       (G_TYPE_CHECK_INSTANCE_CAST ((obj), EXCHANGE_TYPE_SENDOPTIONS_DIALOG, ExchangeSendOptionsDialog))
+#define EXCHANGE_SENDOPTIONS_DIALOG_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EXCHANGE_TYPE_SENDOPTIONS_DIALOG, ExchangeSendOptionsDialogClass))
+#define EXCHANGE_IS_SENDOPTIONS_DIALOG(obj)    (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EXCHANGE_TYPE_SENDOPTIONS_DIALOG))
+#define EXCHANGE_IS_SENDOPTIONS_DIALOG_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EXCHANGE_TYPE_SENDOPTIONS_DIALOG))
+
+typedef struct _ExchangeSendOptionsDialog		ExchangeSendOptionsDialog;
+typedef struct _ExchangeSendOptionsDialogClass		ExchangeSendOptionsDialogClass;
+typedef struct _ExchangeSendOptionsDialogPrivate	ExchangeSendOptionsDialogPrivate;
+
+typedef enum {
+	E_IMP_NORMAL,
+	E_IMP_HIGH,
+	E_IMP_LOW
+} ExchangeSendOptionsImp;
+
+typedef enum {
+	E_SENSITIVITY_NORMAL,
+	E_SENSITIVITY_PERSONAL,
+	E_SENSITIVITY_PRIVATE,
+	E_SENSITIVITY_CONFIDENTIAL
+} ExchangeSendOptionsSensitivity;
+
+/* We require the delegate_email and delegate_name to store the address of the delegator selected into
+   the destination store.
+*/
+typedef struct {
+	ExchangeSendOptionsImp importance;
+	ExchangeSendOptionsSensitivity sensitivity;
+	gboolean send_as_del_enabled;
+	gboolean delivery_enabled;
+	gboolean read_enabled;
+	const gchar *delegate_name;
+	const gchar *delegate_email;
+	const gchar *delegate_address;
+} ExchangeSendOptions;
+
+struct _ExchangeSendOptionsDialog {
+	GObject object;
+
+	ExchangeSendOptions *options;
+	/* Private data */
+	ExchangeSendOptionsDialogPrivate *priv;
+};
+
+struct _ExchangeSendOptionsDialogClass {
+	GObjectClass parent_class;
+	void (* esod_response) (ExchangeSendOptionsDialog *esd, gint status);
+};
+
+GType  exchange_sendoptions_dialog_get_type     (void);
+ExchangeSendOptionsDialog *exchange_sendoptions_dialog_new (void);
+gboolean exchange_sendoptions_dialog_run (ExchangeSendOptionsDialog *sod, GtkWidget *parent);
+#endif
+
diff --git a/eplugin/exchange-user-dialog.c b/eplugin/exchange-user-dialog.c
new file mode 100644
index 0000000..908ffd3
--- /dev/null
+++ b/eplugin/exchange-user-dialog.c
@@ -0,0 +1,285 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "exchange-user-dialog.h"
+#include "e2k-types.h"
+
+#include <e-util/e-dialog-utils.h>
+#include <libedataserverui/e-name-selector.h>
+#include "e2k-xml-utils.h"
+
+struct _E2kUserDialogPrivate {
+	gchar *section_name;
+	ENameSelector *name_selector;
+	GtkWidget *entry, *parent_window;
+};
+
+#define PARENT_TYPE GTK_TYPE_DIALOG
+static GtkDialogClass *parent_class;
+
+static void parent_window_destroyed (gpointer dialog, GObject *where_parent_window_was);
+
+static void
+finalize (GObject *object)
+{
+	E2kUserDialog *dialog = E2K_USER_DIALOG (object);
+
+	g_free (dialog->priv->section_name);
+	g_free (dialog->priv);
+
+	G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+static void
+dispose (GObject *object)
+{
+	E2kUserDialog *dialog = E2K_USER_DIALOG (object);
+
+	if (dialog->priv->name_selector != NULL) {
+		g_object_unref (dialog->priv->name_selector);
+		dialog->priv->name_selector = NULL;
+	}
+
+	if (dialog->priv->parent_window) {
+		g_object_weak_unref (G_OBJECT (dialog->priv->parent_window),
+				     parent_window_destroyed, dialog);
+		dialog->priv->parent_window = NULL;
+	}
+
+	G_OBJECT_CLASS (parent_class)->dispose (object);
+}
+
+static void
+class_init (E2kUserDialogClass *class)
+{
+	GObjectClass *object_class = (GObjectClass *) class;
+
+	parent_class = g_type_class_ref (GTK_TYPE_DIALOG);
+
+	object_class->dispose = dispose;
+	object_class->finalize = finalize;
+}
+
+static void
+init (E2kUserDialog *dialog)
+{
+	dialog->priv = g_new0 (E2kUserDialogPrivate, 1);
+
+	gtk_box_set_spacing (GTK_BOX (GTK_DIALOG (dialog)->vbox), 6);
+}
+
+E2K_MAKE_TYPE (e2k_user_dialog, E2kUserDialog, class_init, init, PARENT_TYPE)
+
+static void
+parent_window_destroyed (gpointer user_data, GObject *where_parent_window_was)
+{
+	E2kUserDialog *dialog = user_data;
+
+	dialog->priv->parent_window = NULL;
+	gtk_dialog_response (GTK_DIALOG (dialog), GTK_RESPONSE_CANCEL);
+}
+
+static void
+addressbook_dialog_response (ENameSelectorDialog *name_selector_dialog, gint response, gpointer data)
+{
+	gtk_widget_hide (GTK_WIDGET (name_selector_dialog));
+}
+
+static void
+addressbook_clicked_cb (GtkWidget *widget, gpointer data)
+{
+	E2kUserDialog *dialog = data;
+	E2kUserDialogPrivate *priv;
+	ENameSelectorDialog *name_selector_dialog;
+
+	priv = dialog->priv;
+
+	name_selector_dialog = e_name_selector_peek_dialog (priv->name_selector);
+	gtk_window_set_modal (GTK_WINDOW (dialog), FALSE);
+	gtk_widget_show (GTK_WIDGET (name_selector_dialog));
+}
+
+static gboolean
+e2k_user_dialog_construct (E2kUserDialog *dialog,
+			   GtkWidget *parent_window,
+			   const gchar *label_text,
+			   const gchar *section_name)
+{
+	E2kUserDialogPrivate *priv;
+	GtkWidget *hbox, *vbox, *label, *button;
+	ENameSelectorModel *name_selector_model;
+	ENameSelectorDialog *name_selector_dialog;
+
+	gtk_window_set_title (GTK_WINDOW (dialog), _("Select User"));
+	gtk_dialog_add_buttons (GTK_DIALOG (dialog),
+				GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+				GTK_STOCK_OK, GTK_RESPONSE_OK,
+				NULL);
+
+	if (parent_window)
+		gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (parent_window));
+
+	priv = dialog->priv;
+	priv->section_name = g_strdup (section_name);
+
+	priv->parent_window = parent_window;
+	g_object_weak_ref (G_OBJECT (parent_window),
+			   parent_window_destroyed, dialog);
+
+	/* Set up the actual select names bits */
+	priv->name_selector = e_name_selector_new ();
+
+	/* Listen for responses whenever the dialog is shown */
+	name_selector_dialog = e_name_selector_peek_dialog (priv->name_selector);
+	g_signal_connect (name_selector_dialog, "response",
+			  G_CALLBACK (addressbook_dialog_response), dialog);
+
+	name_selector_model = e_name_selector_peek_model (priv->name_selector);
+	/* FIXME Limit to one user */
+	e_name_selector_model_add_section (name_selector_model, section_name, section_name, NULL);
+
+	hbox = gtk_hbox_new (FALSE, 6);
+
+	label = gtk_label_new (label_text);
+	gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 6);
+
+	/* The vbox is a workaround for bug 43315 */
+	vbox = gtk_vbox_new (FALSE, 0);
+	priv->entry = GTK_WIDGET (e_name_selector_peek_section_entry (priv->name_selector, section_name));
+	gtk_box_pack_start (GTK_BOX (vbox), priv->entry, TRUE, FALSE, 0);
+	gtk_box_pack_start (GTK_BOX (hbox), vbox, TRUE, TRUE, 6);
+
+	button = gtk_button_new_with_label (_("Address Book..."));
+	g_signal_connect (button, "clicked",
+			  G_CALLBACK (addressbook_clicked_cb),
+			  dialog);
+	gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 6);
+
+	gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), hbox,
+			    TRUE, TRUE, 6);
+	gtk_widget_show_all (hbox);
+
+	return TRUE;
+}
+
+/**
+ * e2k_user_dialog_new:
+ * @parent_window: The window invoking the dialog.
+ * @label_text: Text to label the entry in the initial dialog with
+ * @section_name: The section name for the select-names dialog
+ *
+ * Creates a new user selection dialog.
+ *
+ * Return value: A newly-created user selection dialog, or %NULL if
+ * the dialog could not be created.
+ **/
+GtkWidget *
+e2k_user_dialog_new (GtkWidget *parent_window,
+		     const gchar *label_text, const gchar *section_name)
+{
+	E2kUserDialog *dialog;
+
+	g_return_val_if_fail (GTK_IS_WINDOW (parent_window), NULL);
+	g_return_val_if_fail (label_text != NULL, NULL);
+	g_return_val_if_fail (section_name != NULL, NULL);
+
+	dialog = g_object_new (E2K_TYPE_USER_DIALOG, NULL);
+	if (!e2k_user_dialog_construct (dialog, parent_window,
+					label_text, section_name)) {
+		gtk_widget_destroy (GTK_WIDGET (dialog));
+		return NULL;
+	}
+
+	return GTK_WIDGET (dialog);
+}
+
+/**
+ * e2k_user_dialog_get_user_list:
+ * @dialog: the dialog
+ *
+ * Gets the email addresses of the selected user from the dialog.
+ *
+ * Return value: the email addresses.
+ **/
+GList *
+e2k_user_dialog_get_user_list (E2kUserDialog *dialog)
+{
+	E2kUserDialogPrivate *priv;
+	EDestinationStore *destination_store;
+	GList *destinations;
+	GList *l;
+	GList *email_list = NULL;
+	EDestination *destination;
+
+	g_return_val_if_fail (E2K_IS_USER_DIALOG (dialog), NULL);
+
+	priv = dialog->priv;
+
+	destination_store = e_name_selector_entry_peek_destination_store (E_NAME_SELECTOR_ENTRY (priv->entry));
+	destinations = e_destination_store_list_destinations (destination_store);
+	if (!destinations)
+		return NULL;
+
+	for (l = destinations; l; l = g_list_next (l)) {
+		const gchar *mail;
+		destination = l->data;
+
+		mail = e_destination_get_email (destination);
+		if (mail && *mail)
+			email_list = g_list_prepend (email_list, g_strdup (mail));
+	}
+	g_list_free (destinations);
+
+	return email_list;
+}
+
+/**
+ * e2k_user_dialog_get_user:
+ * @dialog: the dialog
+ *
+ * Gets the email address of the selected user from the dialog.
+ *
+ * Return value: the email address, which must be freed with g_free().
+ **/
+gchar *
+e2k_user_dialog_get_user (E2kUserDialog *dialog)
+{
+	E2kUserDialogPrivate *priv;
+	EDestinationStore *destination_store;
+	GList *destinations;
+	EDestination *destination;
+	gchar *result = NULL;
+
+	g_return_val_if_fail (E2K_IS_USER_DIALOG (dialog), NULL);
+
+	priv = dialog->priv;
+
+	destination_store = e_name_selector_entry_peek_destination_store (E_NAME_SELECTOR_ENTRY (priv->entry));
+	destinations = e_destination_store_list_destinations (destination_store);
+	if (!destinations)
+		return NULL;
+
+	destination = destinations->data;
+	result = g_strdup (e_destination_get_email (destination));
+	g_list_free (destinations);
+
+	return result;
+}
diff --git a/eplugin/exchange-user-dialog.h b/eplugin/exchange-user-dialog.h
new file mode 100644
index 0000000..8b6134b
--- /dev/null
+++ b/eplugin/exchange-user-dialog.h
@@ -0,0 +1,56 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifndef __E2K_USER_DIALOG_H__
+#define __E2K_USER_DIALOG_H__
+
+#include <gtk/gtk.h>
+
+#define E2K_TYPE_USER_DIALOG		(e2k_user_dialog_get_type ())
+#define E2K_USER_DIALOG(obj)		(G_TYPE_CHECK_INSTANCE_CAST ((obj), E2K_TYPE_USER_DIALOG, E2kUserDialog))
+#define E2K_USER_DIALOG_CLASS(klass)	(G_TYPE_CHECK_CLASS_CAST ((klass), E2K_TYPE_USER_DIALOG,	\
+					 E2kUserDialogClass))
+#define E2K_IS_USER_DIALOG(obj)		(G_TYPE_CHECK_INSTANCE_TYPE ((obj), E2K_TYPE_USER_DIALOG))
+#define E2K_IS_USER_DIALOG_CLASS(klass)	(G_TYPE_CHECK_CLASS_TYPE ((klass), E2K_TYPE_USER_DIALOG))
+
+typedef struct _E2kUserDialog		E2kUserDialog;
+typedef struct _E2kUserDialogClass	E2kUserDialogClass;
+typedef struct _E2kUserDialogPrivate	E2kUserDialogPrivate;
+
+struct _E2kUserDialog {
+	GtkDialog parent;
+
+	/* Private data */
+	E2kUserDialogPrivate *priv;
+};
+
+struct _E2kUserDialogClass {
+	GtkDialogClass parent_class;
+};
+
+GType      e2k_user_dialog_get_type (void);
+GtkWidget *e2k_user_dialog_new      (GtkWidget     *parent_window,
+				     const gchar    *label_text,
+				     const gchar    *section_name);
+gchar      *e2k_user_dialog_get_user (E2kUserDialog *dialog);
+GList      *e2k_user_dialog_get_user_list (E2kUserDialog *dialog);
+
+#endif /* __E2K_USER_DIALOG_H__ */
diff --git a/eplugin/org-gnome-exchange-operations.eplug b/eplugin/org-gnome-exchange-operations.eplug
new file mode 100644
index 0000000..a1a9485
--- /dev/null
+++ b/eplugin/org-gnome-exchange-operations.eplug
@@ -0,0 +1,114 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<e-plugin-list>
+  <e-plugin type="shlib" system_plugin="true" location="/build/local/lib/evolution/2.30/plugins/liborg-gnome-exchange-operations" load-on-startup="true" id="org.gnome.evolution.plugin.exchange-operations" name="Exchange Operations">
+    <author name="Sushma Rai" email="rsushma novell com"/>
+    <author name="Praveen Kumar" email="kpraveen novell com"/>
+    <author name="Shakti Sen" email="shprasad novell com"/>
+    <author name="Raghavendran R" email="raghavguru7 gmail com"/>	
+    <description>Activates the Evolution-Exchange extension package.</description>
+	
+	<hook class="org.gnome.evolution.mail.config:1.0">
+		<group target="account" id="org.gnome.evolution.mail.config.accountEditor" commit="org_gnome_exchange_commit" check="org_gnome_exchange_check_options">
+			<item type="page" path="40.oof" factory="org_gnome_exchange_settings" label="Exchange Settings"></item>
+			<item type="item_table" path="10.receive/10.config/20.owa" factory="org_gnome_exchange_owa_url"/>
+			<item type="section" path="10.receive/30.auth/00.exchange_auth" factory="org_gnome_exchange_auth_section"/>
+		</group>
+
+		<group target="account" id="org.gnome.evolution.mail.config.accountAssistant" check="org_gnome_exchange_check_options">
+			<item type="item_table" path="10.receive/10.config/20.owa" factory="org_gnome_exchange_owa_url"/>
+			<item type="section" path="10.receive/30.auth/00.exchange_auth" factory="org_gnome_exchange_auth_section"/>
+		</group>
+
+		<group target="account" id="org.gnome.evolution.mail.config.accountWizard" check="org_gnome_exchange_check_options">
+			<item type="item_table" path="10.receive/10.config/20.owa" factory="org_gnome_exchange_owa_url"/>
+		</group>
+
+		<group target="folder" id="org.gnome.evolution.mail.folderConfig" check="exchange_show_folder_size_check">
+			<item type="page" path="10.size" factory="org_gnome_exchange_show_folder_size_factory" label="Size"></item>
+		</group>
+	</hook>
+
+	<hook class="org.gnome.evolution.calendar.config:1.0">
+		<group target="source" id="org.gnome.evolution.calendar.calendarProperties" commit="e_exchange_calendar_commit" check="e_exchange_calendar_check">
+			<item type="item_table" path="00.general/00.source/40.pcalendar" factory="e_exchange_calendar_pcalendar"/>
+		</group>
+	</hook>
+
+	<hook class="org.gnome.evolution.addressbook.config:1.0">
+		<group target="source" id="com.novell.evolution.addressbook.config.accountEditor" commit="e_exchange_contacts_commit" check="e_exchange_contacts_check">
+			<item type="item" path="00.general/10.display/40.pcontacts" factory="e_exchange_contacts_pcontacts"/>
+		</group>
+	</hook>
+
+	<hook class="org.gnome.evolution.mail.events:1.0">
+		<event target="composer" id="composer.selectsendoption" handle="org_gnome_exchange_send_options" enable="sendoption"/>
+	</hook>
+
+	<hook class="org.gnome.evolution.ui:1.0">
+		<ui-manager id="org.gnome.evolution.mail" callback="eex_ui_mail_init">
+			<popup name="mail-folder-popup">
+				<placeholder name="mail-folder-popup-actions">
+					<menuitem action="eex-mail-folder-permissions"/>
+					<menuitem action="eex-mail-folder-inbox-unsubscribe"/>
+				</placeholder>
+			</popup>
+			<menubar name="main-menu">
+				<menu action="file-menu">
+					<placeholder name="file-actions">
+						<menuitem action="eex-mail-folder-permissions"/>
+						<menuitem action="eex-folder-subscribe-Inbox"/>
+					</placeholder>
+				</menu>
+			</menubar>
+		</ui-manager>
+		<ui-manager id="org.gnome.evolution.calendar" callback="eex_ui_calendar_permissions">
+			<popup name="calendar-popup">
+				<placeholder name="calendar-popup-actions">
+					<menuitem action="eex-calendar-permissions"/>
+					<menuitem action="eex-folder-unsubscribe-Calendar"/>
+				</placeholder>
+			</popup>
+			<menubar name="main-menu">
+				<menu action="file-menu">
+					<placeholder name="file-actions">
+						<menuitem action="eex-calendar-permissions"/>
+						<menuitem action="eex-folder-subscribe-Calendar"/>
+					</placeholder>
+				</menu>
+			</menubar>
+		</ui-manager>
+		<ui-manager id="org.gnome.evolution.task" callback="eex_ui_tasks_permissions">
+			<popup name="task-list-popup">
+				<placeholder name="task-list-popup-actions">
+					<menuitem action="eex-tasks-permissions"/>
+					<menuitem action="eex-folder-unsubscribe-Tasks"/>
+				</placeholder>
+			</popup>
+			<menubar name="main-menu">
+				<menu action="file-menu">
+					<placeholder name="file-actions">
+						<menuitem action="eex-tasks-permissions"/>
+						<menuitem action="eex-folder-subscribe-Tasks"/>
+					</placeholder>
+				</menu>
+			</menubar>
+		</ui-manager>
+		<ui-manager id="org.gnome.evolution.addressbook" callback="eex_ui_addressbook_permissions">
+			<popup name="address-book-popup">
+				<placeholder name="address-book-popup-actions">
+					<menuitem action="eex-addressbook-permissions"/>
+					<menuitem action="eex-folder-unsubscribe-Contacts"/>
+				</placeholder>
+			</popup>
+			<menubar name="main-menu">
+				<menu action="file-menu">
+					<placeholder name="file-actions">
+						<menuitem action="eex-addressbook-permissions"/>
+						<menuitem action="eex-folder-subscribe-Contacts"/>
+					</placeholder>
+				</menu>
+			</menubar>
+		</ui-manager>
+	</hook>
+  </e-plugin>
+</e-plugin-list>
\ No newline at end of file
diff --git a/eplugin/org-gnome-exchange-operations.eplug.xml b/eplugin/org-gnome-exchange-operations.eplug.xml
new file mode 100644
index 0000000..fcd6ff0
--- /dev/null
+++ b/eplugin/org-gnome-exchange-operations.eplug.xml
@@ -0,0 +1,120 @@
+<?xml version="1.0"?>
+<e-plugin-list>
+  <e-plugin
+    type="shlib"
+    id="org.gnome.evolution.plugin.exchange-operations"
+    location="@PLUGINDIR@/liborg-gnome-exchange-operations SOEXT@"
+    load-on-startup="true"
+    _name="Exchange Operations"
+    system_plugin="true">
+    <author name="Sushma Rai" email="rsushma novell com"/>
+    <author name="Praveen Kumar" email="kpraveen novell com"/>
+    <author name="Shakti Sen" email="shprasad novell com"/>
+    <author name="Raghavendran R" email="raghavguru7 gmail com"/>	
+    <_description>Activates the Evolution-Exchange extension package.</_description>
+	
+	<hook class="org.gnome.evolution.mail.config:1.0">
+		<group target="account" id="org.gnome.evolution.mail.config.accountEditor" check="org_gnome_exchange_check_options" commit="org_gnome_exchange_commit">
+			<item type="page" path="40.oof" _label="Exchange Settings" factory="org_gnome_exchange_settings"/>
+			<item type="item_table" path="10.receive/10.config/20.owa" factory="org_gnome_exchange_owa_url"/>
+			<item type="section" path="10.receive/30.auth/00.exchange_auth" factory="org_gnome_exchange_auth_section"/>
+		</group>
+
+		<group target="account" id="org.gnome.evolution.mail.config.accountAssistant" check="org_gnome_exchange_check_options">
+			<item type="item_table" path="10.receive/10.config/20.owa" factory="org_gnome_exchange_owa_url"/>
+			<item type="section" path="10.receive/30.auth/00.exchange_auth" factory="org_gnome_exchange_auth_section"/>
+		</group>
+
+		<group target="account" id="org.gnome.evolution.mail.config.accountWizard" check="org_gnome_exchange_check_options">
+			<item type="item_table" path="10.receive/10.config/20.owa" factory="org_gnome_exchange_owa_url"/>
+		</group>
+
+		<group id="org.gnome.evolution.mail.folderConfig" target="folder" check= "exchange_show_folder_size_check">
+			<item type="page" path="10.size" _label="Size" factory="org_gnome_exchange_show_folder_size_factory"/>
+		</group>
+	</hook>
+
+	<hook class="org.gnome.evolution.calendar.config:1.0">
+		<group target="source" id="org.gnome.evolution.calendar.calendarProperties" check="e_exchange_calendar_check" commit="e_exchange_calendar_commit">
+			<item type="item_table" path="00.general/00.source/40.pcalendar" factory="e_exchange_calendar_pcalendar"/>
+		</group>
+	</hook>
+
+	<hook class="org.gnome.evolution.addressbook.config:1.0">
+		<group target="source" id="com.novell.evolution.addressbook.config.accountEditor" check="e_exchange_contacts_check" commit="e_exchange_contacts_commit">
+			<item type="item" path="00.general/10.display/40.pcontacts" factory="e_exchange_contacts_pcontacts"/>
+		</group>
+	</hook>
+
+	<hook class="org.gnome.evolution.mail.events:1.0">
+		<event id="composer.selectsendoption" handle="org_gnome_exchange_send_options" target="composer" enable="sendoption"/>
+	</hook>
+
+	<hook class="org.gnome.evolution.ui:1.0">
+		<ui-manager id="org.gnome.evolution.mail" callback="eex_ui_mail_init">
+			<popup name="mail-folder-popup">
+				<placeholder name="mail-folder-popup-actions">
+					<menuitem action="eex-mail-folder-permissions"/>
+					<menuitem action="eex-mail-folder-inbox-unsubscribe"/>
+				</placeholder>
+			</popup>
+			<menubar name="main-menu">
+				<menu action="file-menu">
+					<placeholder name="file-actions">
+						<menuitem action="eex-mail-folder-permissions"/>
+						<menuitem action="eex-folder-subscribe-Inbox"/>
+					</placeholder>
+				</menu>
+			</menubar>
+		</ui-manager>
+		<ui-manager id="org.gnome.evolution.calendar" callback="eex_ui_calendar_permissions">
+			<popup name="calendar-popup">
+				<placeholder name="calendar-popup-actions">
+					<menuitem action="eex-calendar-permissions"/>
+					<menuitem action="eex-folder-unsubscribe-Calendar"/>
+				</placeholder>
+			</popup>
+			<menubar name="main-menu">
+				<menu action="file-menu">
+					<placeholder name="file-actions">
+						<menuitem action="eex-calendar-permissions"/>
+						<menuitem action="eex-folder-subscribe-Calendar"/>
+					</placeholder>
+				</menu>
+			</menubar>
+		</ui-manager>
+		<ui-manager id="org.gnome.evolution.task" callback="eex_ui_tasks_permissions">
+			<popup name="task-list-popup">
+				<placeholder name="task-list-popup-actions">
+					<menuitem action="eex-tasks-permissions"/>
+					<menuitem action="eex-folder-unsubscribe-Tasks"/>
+				</placeholder>
+			</popup>
+			<menubar name="main-menu">
+				<menu action="file-menu">
+					<placeholder name="file-actions">
+						<menuitem action="eex-tasks-permissions"/>
+						<menuitem action="eex-folder-subscribe-Tasks"/>
+					</placeholder>
+				</menu>
+			</menubar>
+		</ui-manager>
+		<ui-manager id="org.gnome.evolution.addressbook" callback="eex_ui_addressbook_permissions">
+			<popup name="address-book-popup">
+				<placeholder name="address-book-popup-actions">
+					<menuitem action="eex-addressbook-permissions"/>
+					<menuitem action="eex-folder-unsubscribe-Contacts"/>
+				</placeholder>
+			</popup>
+			<menubar name="main-menu">
+				<menu action="file-menu">
+					<placeholder name="file-actions">
+						<menuitem action="eex-addressbook-permissions"/>
+						<menuitem action="eex-folder-subscribe-Contacts"/>
+					</placeholder>
+				</menu>
+			</menubar>
+		</ui-manager>
+	</hook>
+  </e-plugin>
+</e-plugin-list>
diff --git a/eplugin/org-gnome-exchange-operations.error b/eplugin/org-gnome-exchange-operations.error
new file mode 100644
index 0000000..c26973c
--- /dev/null
+++ b/eplugin/org-gnome-exchange-operations.error
@@ -0,0 +1,262 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<error-list domain="org-gnome-exchange-operations">
+
+ <error type="error" id="single-account-error">
+  <primary>You may only configure a single Exchange account.</primary>
+ </error>
+
+ <error type="info" id="apply-restart">
+  <primary>Please restart Evolution for changes to take effect</primary>
+  <secondary>Changes to options for Exchange account "{0}" will only take effect after restarting Evolution.</secondary>
+ </error>
+
+ <error type="info" id="remove-quit">
+  <primary>The Exchange account will be removed when you quit Evolution</primary>
+ </error>
+
+ <error type="info" id="disable-quit">
+  <primary>The Exchange account will be disabled when you quit Evolution</primary>
+ </error>
+
+ <error type="error" id="state-read-error">
+  <primary>Could not read out-of-office state</primary>
+ </error>
+
+ <error type="error" id="state-update-error">
+  <primary>Could not update out-of-office state</primary>
+ </error>
+
+ <error type="error" id="config-error">
+  <primary>Cannot change password due to configuration problems.</primary>
+ </error>
+ 
+ <error type="error" id="password-weak-error">
+  <primary>Server rejected password because it is too weak.</primary>
+  <secondary>Try again with a different password.</secondary>
+ </error>
+
+ <error type="error" id="password-change-error">
+  <primary>Could not change password.</primary>
+ </error>
+
+ <error type="info" id="password-change-success">
+  <primary>Password successfully changed.</primary>
+ </error>
+
+ <error type="info" id="account-offline">
+  <primary>Exchange Account is offline.</primary>
+  <secondary>Cannot display folders.</secondary>
+ </error>
+
+ <error type="info" id="exchange-settings-offline">
+  <primary>Exchange Account is offline.</primary>
+  <secondary>Cannot access the "Exchange settings" tab in offline mode.</secondary>
+ </error>
+
+ <error type="info" id="account-offline-generic">
+  <primary>Exchange Account is offline.</primary>
+  <secondary>Cannot perform the operation.</secondary>
+ </error>
+
+ <error type="error" id="password-incorrect">
+  <primary>Could not authenticate to server.</primary>
+  <secondary>Make sure the username and password are correct and try again.</secondary>
+ </error>
+
+ <error type="error" id="account-domain-error">
+  <primary>Could not authenticate to server.</primary>
+  <secondary xml:space="preserve">This probably means that your server requires 
+you to specify the Windows domain name 
+as part of your username (eg, &quot;DOMAIN\user&quot;).
+
+Or you might have just typed your password wrong.</secondary>
+ </error>
+
+ <error type="error" id="account-mailbox-na">
+  <primary>Mailbox for {0} is not on this server.</primary>
+ </error>
+
+ <error type="error" id="account-version-error">
+  <primary>The Exchange server is not compatible with Exchange Connector.</primary>
+  <secondary xml:space="preserve">The server is running Exchange 5.5. Exchange Connector 
+supports Microsoft Exchange 2000 and 2003 only.</secondary>
+ </error>
+
+ <error type="error" id="account-wss-error">
+  <primary>Could not find Exchange Web Storage System.</primary>
+  <secondary>If OWA is running on a different path, you must specify that in the account configuration dialog.</secondary>
+ </error>
+
+ <error type="info" id="account-no-mailbox">
+  <primary>No mailbox for user {0} on {1}.</primary>
+ </error>
+
+ <error type="error" id="account-resolve-error">
+  <primary>Could not locate server {0}.</primary>
+  <secondary>Make sure the server name is spelled correctly and try again.</secondary>
+ </error>
+
+ <error type="error" id="account-connect-error">
+  <primary>Could not connect to server {0}.</primary>
+  <secondary>Make sure the URL is correct and try again.</secondary>
+ </error>
+
+ <error type="error" id="password-expired">
+  <primary>Your password has expired.</primary>
+ </error>
+
+ <error type="error" id="account-unknown-error">
+  <primary>Could not connect to server {0}.</primary>
+  <secondary>Unknown error.</secondary>
+ </error>
+
+ <error type="error" id="account-quota-error">
+  <primary>You have exceeded your quota for storing mail on this server.</primary>
+  <secondary>Your current usage is: {0} KB. You will not be able to either send or receive mail now.</secondary>
+ </error>
+
+ <error type="warning" id="account-quota-send-error">
+  <primary>You are nearing your quota available for storing mail on this server.</primary>
+  <secondary>Your current usage is: {0} KB. You will not be able to send mail until you clear up some space by deleting some mail.</secondary>
+ </error>
+
+ <error type="warning" id="account-quota-warn">
+  <primary>You are nearing your quota available for storing mail on this server.</primary>
+  <secondary>Your current usage is: {0} KB. Try to clear up some space by deleting some mail.</secondary>
+ </error>
+
+ <error type="error" id="connect-exchange-error">
+  <primary>Could not connect to Exchange server.</primary>
+  <secondary xml:space="preserve">Exchange Connector requires access to certain
+functionality on the Exchange Server that appears
+to be disabled or blocked. (This is usually 
+unintentional.) Your Exchange Administrator will 
+need to enable this functionality in order for 
+you to be able to use Evolution Exchange Connector.
+
+For information to provide to your Exchange 
+administrator, please follow the link below:
+
+{0}
+  </secondary>
+ </error>
+
+ <error type="error" id="configure-error">
+  <secondary xml:space="preserve">Could not configure Exchange account because 
+an unknown error occurred. Check the URL, 
+username, and password, and try again.</secondary>
+ </error>
+
+ <error type="error" id="delegates-no-gcs-error">
+  <primary>No Global Catalog server configured for this account.</primary>
+  <secondary>Unable to edit delegates.</secondary>
+ </error>
+
+ <error type="error" id="acl-no-gcs-error">
+  <primary>Unable to add user to access control list:</primary>
+  <secondary>No Global Catalog server configured for this account.</secondary>
+ </error>
+
+ <error type="error" id="delegates-perm-read-error">
+  <primary>Could not read folder permissions.</primary>
+  <secondary>Unable to edit delegates.</secondary>
+ </error>
+
+ <error type="error" id="perm-read-error">
+  <primary>Could not read folder permissions</primary>
+ </error>
+
+ <error type="error" id="perm-deter-error">
+  <primary>Unable to edit delegates.</primary>
+  <secondary>Could not determine folder permissions for delegates.</secondary>
+ </error>
+
+ <error type="error" id="delegate-error">
+  <primary>Could not make {0} a delegate</primary>
+ </error>
+
+ <error type="error" id="delegate-own-error">
+  <primary>You cannot make yourself your own delegate</primary>
+ </error>
+
+ <error type="info" id="delegate-existing">
+  <primary>{0} is already a delegate</primary>
+ </error>
+
+ <error type="error" id="delegate-fail-error">
+  <primary>Failed to update delegates:</primary>
+  <secondary>{0}</secondary>
+ </error>
+
+<error type="info" id="no-delegate-selected">
+  <primary>Please enter a Delegate's ID or deselect the Send as a Delegate option.</primary>
+ </error>
+
+<error type="info" id="more-delegates-selected">
+  <primary>You are permitted to send a message on behalf of only one delegator at a time.</primary>
+ </error>
+
+
+ <error type="info" id="select-user">
+  <primary>Please select a user.</primary>
+ </error>
+
+ <error type="error" id="perm-update-error">
+  <primary>Could not update folder permissions.</primary>
+  <secondary>{0}</secondary>
+ </error>
+
+ <error type="error" id="no-user-error">
+  <primary>No such user {0}</primary>
+ </error>
+
+ <error type="error" id="acl-add-error">
+  <primary>{0} cannot be added to an access control list</primary>
+ </error>
+
+ <error type="error" id="perm-unknown-error">
+  <primary>Unknown error looking up {0}</primary>
+ </error>
+
+ <error type="error" id="perm-existing-error">
+  <primary>{0} is already in the list</primary>
+ </error>
+
+ <error type="error" id="folder-exists-error">
+  <primary>Folder already exists</primary>
+ </error>
+
+ <error type="error" id="folder-restart-evo">
+  <primary>Evolution requires a restart to load the subscribed user's mailbox</primary>
+ </error>
+
+ <error type="error" id="folder-doesnt-exist-error">
+  <primary>Folder does not exist</primary>
+ </error>
+
+ <error type="error" id="folder-perm-error">
+  <primary>Permission denied</primary>
+ </error>
+
+ <error type="error" id="folder-unknown-type">
+  <primary>Unknown type</primary>
+ </error>
+
+ <error type="error" id="folder-offline-error">
+  <primary>Folder offline</primary>
+ </error>
+
+ <error type="error" id="folder-unsupported-error">
+  <primary>Unsupported operation</primary>
+ </error>
+
+ <error type="error" id="folder-no-gc-error">
+  <primary>Global Catalog Server is not reachable</primary>
+  <secondary>Please make sure the Global Catalog Server name is correct.</secondary> 
+ </error>
+
+ <error type="error" id="folder-generic-error">
+  <primary>Generic error</primary>
+ </error>
+
+</error-list>
\ No newline at end of file
diff --git a/eplugin/org-gnome-exchange-operations.error.xml b/eplugin/org-gnome-exchange-operations.error.xml
new file mode 100644
index 0000000..37ed0aa
--- /dev/null
+++ b/eplugin/org-gnome-exchange-operations.error.xml
@@ -0,0 +1,263 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<error-list domain="org-gnome-exchange-operations">
+
+ <error id="single-account-error" type="error">
+  <_primary>You may only configure a single Exchange account.</_primary>
+ </error>
+
+ <error id="apply-restart" type="info">
+  <_primary>Please restart Evolution for changes to take effect</_primary>
+  <_secondary>Changes to options for Exchange account "{0}" will only take effect after restarting Evolution.</_secondary>
+ </error>
+
+ <error id="remove-quit" type="info">
+  <_primary>The Exchange account will be removed when you quit Evolution</_primary>
+ </error>
+
+ <error id="disable-quit" type="info">
+  <_primary>The Exchange account will be disabled when you quit Evolution</_primary>
+ </error>
+
+ <error id="state-read-error" type="error">
+  <_primary>Could not read out-of-office state</_primary>
+ </error>
+
+ <error id="state-update-error" type="error">
+  <_primary>Could not update out-of-office state</_primary>
+ </error>
+
+ <error id="config-error" type="error">
+  <_primary>Cannot change password due to configuration problems.</_primary>
+ </error>
+ 
+ <error id="password-weak-error" type="error">
+  <_primary>Server rejected password because it is too weak.</_primary>
+  <_secondary>Try again with a different password.</_secondary>
+ </error>
+
+ <error id="password-change-error" type="error">
+  <_primary>Could not change password.</_primary>
+ </error>
+
+ <error id="password-change-success" type="info">
+  <_primary>Password successfully changed.</_primary>
+ </error>
+
+ <error id="account-offline" type="info">
+  <_primary>Exchange Account is offline.</_primary>
+  <_secondary>Cannot display folders.</_secondary>
+ </error>
+
+ <error id="exchange-settings-offline" type="info">
+  <_primary>Exchange Account is offline.</_primary>
+  <_secondary>Cannot access the "Exchange settings" tab in offline mode.</_secondary>
+ </error>
+
+ <error id="account-offline-generic" type="info">
+  <_primary>Exchange Account is offline.</_primary>
+  <_secondary>Cannot perform the operation.</_secondary>
+ </error>
+
+ <error id="password-incorrect" type="error">
+  <_primary>Could not authenticate to server.</_primary>
+  <_secondary>Make sure the username and password are correct and try again.</_secondary>
+ </error>
+
+ <error id="account-domain-error" type="error">
+  <_primary>Could not authenticate to server.</_primary>
+  <_secondary xml:space="preserve">This probably means that your server requires 
+you to specify the Windows domain name 
+as part of your username (eg, &quot;DOMAIN\user&quot;).
+
+Or you might have just typed your password wrong.</_secondary>
+ </error>
+
+ <error id="account-mailbox-na" type="error">
+  <_primary>Mailbox for {0} is not on this server.</_primary>
+ </error>
+
+ <error id="account-version-error" type="error">
+  <_primary>The Exchange server is not compatible with Exchange Connector.</_primary>
+  <_secondary xml:space="preserve">The server is running Exchange 5.5. Exchange Connector 
+supports Microsoft Exchange 2000 and 2003 only.</_secondary>
+ </error>
+
+ <error id="account-wss-error" type="error">
+  <_primary>Could not find Exchange Web Storage System.</_primary>
+  <_secondary>If OWA is running on a different path, you must specify that in the account configuration dialog.</_secondary>
+ </error>
+
+ <error id="account-no-mailbox" type="info">
+  <_primary>No mailbox for user {0} on {1}.</_primary>
+ </error>
+
+ <error id="account-resolve-error" type="error">
+  <_primary>Could not locate server {0}.</_primary>
+  <_secondary>Make sure the server name is spelled correctly and try again.</_secondary>
+ </error>
+
+ <error id="account-connect-error" type="error">
+  <_primary>Could not connect to server {0}.</_primary>
+  <_secondary>Make sure the URL is correct and try again.</_secondary>
+ </error>
+
+ <error id="password-expired" type="error">
+  <_primary>Your password has expired.</_primary>
+ </error>
+
+ <error id="account-unknown-error" type="error">
+  <_primary>Could not connect to server {0}.</_primary>
+  <_secondary>Unknown error.</_secondary>
+ </error>
+
+ <error id="account-quota-error" type="error">
+  <_primary>You have exceeded your quota for storing mail on this server.</_primary>
+  <_secondary>Your current usage is: {0} KB. You will not be able to either send or receive mail now.</_secondary>
+ </error>
+
+ <error id="account-quota-send-error" type="warning">
+  <_primary>You are nearing your quota available for storing mail on this server.</_primary>
+  <_secondary>Your current usage is: {0} KB. You will not be able to send mail until you clear up some space by deleting some mail.</_secondary>
+ </error>
+
+ <error id="account-quota-warn" type="warning">
+  <_primary>You are nearing your quota available for storing mail on this server.</_primary>
+  <_secondary>Your current usage is: {0} KB. Try to clear up some space by deleting some mail.</_secondary>
+ </error>
+
+ <error id="connect-exchange-error" type="error">
+  <_primary>Could not connect to Exchange server.</_primary>
+  <_secondary xml:space="preserve">Exchange Connector requires access to certain
+functionality on the Exchange Server that appears
+to be disabled or blocked. (This is usually 
+unintentional.) Your Exchange Administrator will 
+need to enable this functionality in order for 
+you to be able to use Evolution Exchange Connector.
+
+For information to provide to your Exchange 
+administrator, please follow the link below:
+
+{0}
+  </_secondary>
+ </error>
+
+ <error id="configure-error" type="error">
+  <_secondary xml:space="preserve">Could not configure Exchange account because 
+an unknown error occurred. Check the URL, 
+username, and password, and try again.</_secondary>
+ </error>
+
+ <error id="delegates-no-gcs-error" type="error">
+  <_primary>No Global Catalog server configured for this account.</_primary>
+  <_secondary>Unable to edit delegates.</_secondary>
+ </error>
+
+ <error id="acl-no-gcs-error" type="error">
+  <_primary>Unable to add user to access control list:</_primary>
+  <_secondary>No Global Catalog server configured for this account.</_secondary>
+ </error>
+
+ <error id="delegates-perm-read-error" type="error">
+  <_primary>Could not read folder permissions.</_primary>
+  <_secondary>Unable to edit delegates.</_secondary>
+ </error>
+
+ <error id="perm-read-error" type="error">
+  <_primary>Could not read folder permissions</_primary>
+ </error>
+
+ <error id="perm-deter-error" type="error">
+  <_primary>Unable to edit delegates.</_primary>
+  <_secondary>Could not determine folder permissions for delegates.</_secondary>
+ </error>
+
+ <error id="delegate-error" type="error">
+  <_primary>Could not make {0} a delegate</_primary>
+ </error>
+
+ <error id="delegate-own-error" type="error">
+  <_primary>You cannot make yourself your own delegate</_primary>
+ </error>
+
+ <error id="delegate-existing" type="info">
+  <_primary>{0} is already a delegate</_primary>
+ </error>
+
+ <error id="delegate-fail-error" type="error">
+  <_primary>Failed to update delegates:</_primary>
+  <_secondary>{0}</_secondary>
+ </error>
+
+<error id="no-delegate-selected" type="info">
+  <_primary>Please enter a Delegate's ID or deselect the Send as a Delegate option.</_primary>
+ </error>
+
+<error id="more-delegates-selected" type="info">
+  <_primary>You are permitted to send a message on behalf of only one delegator at a time.</_primary>
+ </error>
+
+
+ <error id="select-user" type="info">
+  <_primary>Please select a user.</_primary>
+ </error>
+
+ <error id="perm-update-error" type="error">
+  <_primary>Could not update folder permissions.</_primary>
+  <_secondary>{0}</_secondary>
+ </error>
+
+ <error id="no-user-error" type="error">
+  <_primary>No such user {0}</_primary>
+ </error>
+
+ <error id="acl-add-error" type="error">
+  <_primary>{0} cannot be added to an access control list</_primary>
+ </error>
+
+ <error id="perm-unknown-error" type="error">
+  <_primary>Unknown error looking up {0}</_primary>
+ </error>
+
+ <error id="perm-existing-error" type="error">
+  <_primary>{0} is already in the list</_primary>
+ </error>
+
+ <error id="folder-exists-error" type="error">
+  <_primary>Folder already exists</_primary>
+ </error>
+
+ <error id="folder-restart-evo" type="error">
+  <_primary>Evolution requires a restart to load the subscribed user's mailbox</_primary>
+ </error>
+
+ <error id="folder-doesnt-exist-error" type="error">
+  <_primary>Folder does not exist</_primary>
+ </error>
+
+ <error id="folder-perm-error" type="error">
+  <_primary>Permission denied</_primary>
+ </error>
+
+ <error id="folder-unknown-type" type="error">
+  <_primary>Unknown type</_primary>
+ </error>
+
+ <error id="folder-offline-error" type="error">
+  <_primary>Folder offline</_primary>
+ </error>
+
+ <error id="folder-unsupported-error" type="error">
+  <_primary>Unsupported operation</_primary>
+ </error>
+
+ <error id="folder-no-gc-error" type="error">
+  <_primary>Global Catalog Server is not reachable</_primary>
+  <_secondary>Please make sure the Global Catalog Server name is correct.</_secondary> 
+ </error>
+
+ <error id="folder-generic-error" type="error">
+  <_primary>Generic error</_primary>
+ </error>
+
+</error-list>
+



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