[evolution/kill-bonobo] Simplify EPlugin loading at startup.



commit 32f545cdf031ebe3718791f18e8fb6b6141fd081
Author: Matthew Barnes <mbarnes redhat com>
Date:   Fri Aug 28 20:21:54 2009 -0400

    Simplify EPlugin loading at startup.
    
    - Require all EPlugin and EPluginHook subtypes be registered before
      loading plugins.  This drastically simplifies the EPlugin/EPluginHook
      negotiation.
    
    - Turn most EPluginHook subtypes into GTypeModules and register their
      types from an e_module_load() function (does not include shell hooks).
    
    - Convert EPluginLib and the Mono and Python bindings to GTypeModules
      and register their types from an e_module_load() function, and kill
      EPluginTypeHook.

 addressbook/gui/widgets/eab-config.c               |   46 --
 addressbook/gui/widgets/eab-config.h               |   15 -
 calendar/gui/Makefile.am                           |    3 -
 calendar/gui/e-attachment-handler-calendar.h       |   65 --
 calendar/gui/e-cal-config.c                        |   47 --
 calendar/gui/e-cal-config.h                        |   15 -
 calendar/gui/e-cal-event.c                         |   56 --
 calendar/gui/e-cal-event.h                         |   15 -
 configure.ac                                       |   31 +-
 e-util/e-plugin.c                                  |  696 +++-----------------
 e-util/e-plugin.h                                  |  118 ----
 mail/Makefile.am                                   |    4 +-
 mail/em-config.c                                   |   82 ---
 mail/em-config.h                                   |   15 -
 mail/em-event.c                                    |   80 ---
 mail/em-event.h                                    |   15 -
 mail/em-junk-hook.c                                |  440 -------------
 mail/em-junk-hook.h                                |  102 ---
 .../python-plugin-loader.h => mail/em-junk.c       |   34 +-
 mail/em-junk.h                                     |   66 ++
 modules/Makefile.am                                |   10 +-
 modules/addressbook/Makefile.am                    |    2 +
 modules/addressbook/e-book-config-hook.c           |   67 ++
 .../addressbook/e-book-config-hook.h               |   32 +-
 modules/addressbook/e-book-shell-backend.c         |    3 -
 modules/addressbook/evolution-module-addressbook.c |    4 +
 modules/calendar/Makefile.am                       |    9 +-
 .../calendar/e-cal-attachment-handler.c            |   71 +-
 modules/calendar/e-cal-attachment-handler.h        |   67 ++
 modules/calendar/e-cal-config-hook.c               |   68 ++
 .../calendar/e-cal-config-hook.h                   |   34 +-
 modules/calendar/e-cal-event-hook.c                |   72 ++
 .../calendar/e-cal-event-hook.h                    |   32 +-
 modules/calendar/e-cal-shell-backend.c             |   13 -
 modules/calendar/evolution-module-calendar.c       |   10 +
 modules/mail/Makefile.am                           |   10 +-
 modules/mail/e-attachment-handler-mail.h           |   65 --
 ...-handler-mail.c => e-mail-attachment-handler.c} |   99 ++--
 modules/mail/e-mail-attachment-handler.h           |   67 ++
 modules/mail/e-mail-config-hook.c                  |   69 ++
 .../mail/e-mail-config-hook.h                      |   32 +-
 modules/mail/e-mail-event-hook.c                   |   93 +++
 .../mail/e-mail-event-hook.h                       |   32 +-
 modules/mail/e-mail-junk-hook.c                    |  323 +++++++++
 modules/mail/e-mail-junk-hook.h                    |   66 ++
 modules/mail/e-mail-shell-backend.c                |   31 +-
 modules/mail/em-mailer-prefs.c                     |   26 +-
 modules/mail/evolution-module-mail.c               |   12 +
 modules/plugin-lib/Makefile.am                     |   20 +
 modules/plugin-lib/e-plugin-lib.c                  |  249 +++++++
 modules/plugin-lib/e-plugin-lib.h                  |   92 +++
 .../plugin-lib/evolution-module-plugin-lib.c       |   40 +-
 {plugins/mono => modules/plugin-mono}/Camel.cs     |    0
 {plugins/mono => modules/plugin-mono}/Evolution.cs |    0
 modules/plugin-mono/Makefile.am                    |   22 +
 modules/plugin-mono/e-plugin-mono.c                |  261 ++++++++
 modules/plugin-mono/e-plugin-mono.h                |   69 ++
 .../plugin-mono/evolution-module-plugin-mono.c     |   40 +-
 modules/plugin-python/Makefile.am                  |   31 +
 modules/plugin-python/e-plugin-python.c            |  230 +++++++
 modules/plugin-python/e-plugin-python.h            |   70 ++
 .../plugin-python/evolution-module-plugin-python.c |   40 +-
 .../plugin-python}/example/Makefile.am             |    0
 .../plugin-python}/example/hello_python.py         |    0
 .../example/org-gnome-hello-python-ui.xml          |    0
 .../example/org-gnome-hello-python.eplug.xml       |    0
 plugins/Makefile.am                                |    2 +-
 plugins/attachment-reminder/attachment-reminder.c  |    4 +-
 plugins/bbdb/bbdb.c                                |    4 +-
 plugins/bogo-junk-plugin/bf-junk-filter.c          |   26 +-
 .../org-gnome-bogo-junk-plugin.eplug.xml           |   13 +-
 plugins/caldav/caldav-source.c                     |    4 +-
 plugins/calendar-weather/calendar-weather.c        |    4 +-
 plugins/email-custom-header/email-custom-header.c  |    4 +-
 plugins/exchange-operations/exchange-operations.c  |    2 +-
 plugins/google-account-setup/google-source.c       |    4 +-
 .../groupwise-account-setup.c                      |    4 +-
 plugins/hula-account-setup/hula-account-setup.c    |    4 +-
 plugins/mail-notification/mail-notification.c      |    4 +-
 plugins/mono/ChangeLog                             |   84 ---
 plugins/mono/Makefile.am                           |   22 -
 plugins/mono/mono-plugin.c                         |  240 -------
 plugins/mono/org-gnome-evolution-mono.eplug.xml    |   11 -
 plugins/prefer-plain/prefer-plain.c                |    4 +-
 plugins/pst-import/pst-importer.c                  |    4 +-
 plugins/python/ChangeLog                           |   38 --
 plugins/python/Makefile.am                         |   30 -
 .../python/org-gnome-evolution-python.eplug.xml    |   10 -
 plugins/python/python-plugin-loader.c              |  192 ------
 plugins/sa-junk-plugin/em-junk-filter.c            |   18 +-
 .../org-gnome-sa-junk-plugin.eplug.xml             |   16 +-
 plugins/tnef-attachments/tnef-plugin.c             |    4 +-
 .../webdav-account-setup/webdav-contacts-source.c  |    4 +-
 shell/main.c                                       |   40 +-
 94 files changed, 2440 insertions(+), 2884 deletions(-)
---
diff --git a/addressbook/gui/widgets/eab-config.c b/addressbook/gui/widgets/eab-config.c
index 91056e0..f47a696 100644
--- a/addressbook/gui/widgets/eab-config.c
+++ b/addressbook/gui/widgets/eab-config.c
@@ -27,7 +27,6 @@
 #include "eab-config.h"
 
 static GObjectClass *ecp_parent_class;
-static GObjectClass *ecph_parent_class;
 
 struct _EABConfigPrivate {
 	guint source_changed_id;
@@ -143,48 +142,3 @@ eab_config_target_new_source (EABConfig *ecp, struct _ESource *source)
 
 	return t;
 }
-
-static const EConfigHookTargetMask ecph_no_masks[] = {
-	{ NULL }
-};
-
-static const EConfigHookTargetMap ecph_targets[] = {
-	{ "source", EAB_CONFIG_TARGET_SOURCE, ecph_no_masks },
-	{ NULL },
-};
-
-static void
-ecph_class_init (EPluginHookClass *klass)
-{
-	gint i;
-
-	klass->id = "org.gnome.evolution.addressbook.config:1.0";
-
-	for (i = 0; ecph_targets[i].type; i++) {
-		e_config_hook_class_add_target_map ((EConfigHookClass *)klass, &ecph_targets[i]);
-	}
-
-	((EConfigHookClass *)klass)->config_class = g_type_class_ref (eab_config_get_type ());
-}
-
-GType
-eab_config_hook_get_type (void)
-{
-	static GType type = 0;
-
-	if (!type) {
-		static const GTypeInfo info = {
-			sizeof (EABConfigHookClass),
-			NULL, NULL,
-			(GClassInitFunc) ecph_class_init,
-			NULL, NULL,
-			sizeof (EABConfigHook), 0,
-			(GInstanceInitFunc) NULL
-		};
-
-		ecph_parent_class = g_type_class_ref (e_config_hook_get_type ());
-		type = g_type_register_static (e_config_hook_get_type (), "EABConfigHook", &info, 0);
-	}
-
-	return type;
-}
diff --git a/addressbook/gui/widgets/eab-config.h b/addressbook/gui/widgets/eab-config.h
index 8ecc852..fcf6b76 100644
--- a/addressbook/gui/widgets/eab-config.h
+++ b/addressbook/gui/widgets/eab-config.h
@@ -60,21 +60,6 @@ EABConfig *eab_config_new (gint type, const gchar *menuid);
 
 EABConfigTargetSource *eab_config_target_new_source (EABConfig *ecp, struct _ESource *source);
 
-/* ********************************************************************** */
-
-typedef struct _EABConfigHook EABConfigHook;
-typedef struct _EABConfigHookClass EABConfigHookClass;
-
-struct _EABConfigHook {
-	EConfigHook hook;
-};
-
-struct _EABConfigHookClass {
-	EConfigHookClass hook_class;
-};
-
-GType eab_config_hook_get_type (void);
-
 G_END_DECLS
 
 #endif
diff --git a/calendar/gui/Makefile.am b/calendar/gui/Makefile.am
index b7bf7f5..ede213e 100644
--- a/calendar/gui/Makefile.am
+++ b/calendar/gui/Makefile.am
@@ -14,7 +14,6 @@ ecalendarinclude_HEADERS =			\
 	calendar-config-keys.h			\
 	comp-util.h				\
 	e-alarm-list.h				\
-	e-attachment-handler-calendar.h		\
 	e-cal-config.h				\
 	e-cal-event.h				\
 	e-cal-model-calendar.h			\
@@ -96,8 +95,6 @@ libevolution_calendar_la_SOURCES = \
 	comp-util.h				\
 	e-alarm-list.c				\
 	e-alarm-list.h				\
-	e-attachment-handler-calendar.c		\
-	e-attachment-handler-calendar.h		\
 	e-cal-component-preview.c		\
 	e-cal-component-preview.h		\
 	e-cal-config.c				\
diff --git a/calendar/gui/e-cal-config.c b/calendar/gui/e-cal-config.c
index 33b6bc9..a8d2ad1 100644
--- a/calendar/gui/e-cal-config.c
+++ b/calendar/gui/e-cal-config.c
@@ -28,7 +28,6 @@
 #include "e-cal-config.h"
 
 static GObjectClass *ecp_parent_class;
-static GObjectClass *ecph_parent_class;
 
 struct _ECalConfigPrivate {
 	guint source_changed_id;
@@ -166,49 +165,3 @@ e_cal_config_target_new_prefs (ECalConfig *ecp, struct _GConfClient *gconf)
 
 	return t;
 }
-
-static const EConfigHookTargetMask ecph_no_masks[] = {
-	{ NULL }
-};
-
-static const EConfigHookTargetMap ecph_targets[] = {
-	{ "source", EC_CONFIG_TARGET_SOURCE, ecph_no_masks },
-	{ "prefs", EC_CONFIG_TARGET_PREFS, ecph_no_masks },
-	{ NULL },
-};
-
-static void
-ecph_class_init (EPluginHookClass *klass)
-{
-	gint i;
-
-	klass->id = "org.gnome.evolution.calendar.config:1.0";
-
-	for (i = 0; ecph_targets[i].type; i++) {
-		e_config_hook_class_add_target_map ((EConfigHookClass *)klass, &ecph_targets[i]);
-	}
-
-	((EConfigHookClass *)klass)->config_class = g_type_class_ref (e_cal_config_get_type ());
-}
-
-GType
-e_cal_config_hook_get_type (void)
-{
-	static GType type = 0;
-
-	if (!type) {
-		static const GTypeInfo info = {
-			sizeof (ECalConfigHookClass),
-			NULL, NULL,
-			(GClassInitFunc) ecph_class_init,
-			NULL, NULL,
-			sizeof (ECalConfigHook), 0,
-			(GInstanceInitFunc) NULL
-		};
-
-		ecph_parent_class = g_type_class_ref (e_config_hook_get_type ());
-		type = g_type_register_static (e_config_hook_get_type (), "ECalConfigHook", &info, 0);
-	}
-
-	return type;
-}
diff --git a/calendar/gui/e-cal-config.h b/calendar/gui/e-cal-config.h
index 52989aa..30e12bb 100644
--- a/calendar/gui/e-cal-config.h
+++ b/calendar/gui/e-cal-config.h
@@ -71,21 +71,6 @@ ECalConfig *e_cal_config_new (gint type, const gchar *menuid);
 ECalConfigTargetSource *e_cal_config_target_new_source (ECalConfig *ecp, struct _ESource *source);
 ECalConfigTargetPrefs *e_cal_config_target_new_prefs (ECalConfig *ecp, struct _GConfClient *gconf);
 
-/* ********************************************************************** */
-
-typedef struct _ECalConfigHook ECalConfigHook;
-typedef struct _ECalConfigHookClass ECalConfigHookClass;
-
-struct _ECalConfigHook {
-	EConfigHook hook;
-};
-
-struct _ECalConfigHookClass {
-	EConfigHookClass hook_class;
-};
-
-GType e_cal_config_hook_get_type (void);
-
 G_END_DECLS
 
 #endif
diff --git a/calendar/gui/e-cal-event.c b/calendar/gui/e-cal-event.c
index 5881f50..7d0a9d1 100644
--- a/calendar/gui/e-cal-event.c
+++ b/calendar/gui/e-cal-event.c
@@ -105,59 +105,3 @@ e_cal_event_target_new_module (ECalEvent *ece, EShellBackend *shell_backend, ESo
 
 	return t;
 }
-
-/* ********************************************************************** */
-
-static gpointer eceh_parent_class;
-
-static const EEventHookTargetMask eceh_module_masks[] = {
-	{ "migration", E_CAL_EVENT_MODULE_MIGRATION },
-	{ NULL },
-};
-
-static const EEventHookTargetMap eceh_targets[] = {
-	{ "module", E_CAL_EVENT_TARGET_BACKEND, eceh_module_masks },
-	{ NULL },
-};
-
-static void
-eceh_finalize (GObject *o)
-{
-	((GObjectClass *) eceh_parent_class)->finalize (o);
-}
-
-static void
-eceh_class_init (EPluginHookClass *klass)
-{
-	gint i;
-
-	((GObjectClass *)klass)->finalize = eceh_finalize;
-	((EPluginHookClass *)klass)->id = "org.gnome.evolution.calendar.events:1.0";
-
-	for (i = 0; eceh_targets[i].type; i++)
-		e_event_hook_class_add_target_map ((EEventHookClass *)klass, &eceh_targets[i]);
-
-	((EEventHookClass *)klass)->event = (EEvent *) e_cal_event_peek ();
-}
-
-GType
-e_cal_event_hook_get_type (void)
-{
-	static GType type = 0;
-
-	if (!type) {
-		static const GTypeInfo info = {
-			sizeof (ECalEventHookClass),
-			NULL, NULL,
-			(GClassInitFunc) eceh_class_init,
-			NULL, NULL,
-			sizeof (ECalEventHook), 0,
-			(GInstanceInitFunc) NULL,
-		};
-
-		eceh_parent_class = g_type_class_ref (e_event_hook_get_type ());
-		type = g_type_register_static (e_event_hook_get_type (), "ECalEventHook", &info, 0);
-	}
-
-	return type;
-}
diff --git a/calendar/gui/e-cal-event.h b/calendar/gui/e-cal-event.h
index 73d2735..8d72a93 100644
--- a/calendar/gui/e-cal-event.h
+++ b/calendar/gui/e-cal-event.h
@@ -66,21 +66,6 @@ GType                     e_cal_event_get_type (void);
 ECalEvent*                e_cal_event_peek (void);
 ECalEventTargetBackend* e_cal_event_target_new_module (ECalEvent *ece, EShellBackend *shell_backend, ESourceList *source_list, guint32 flags);
 
-/* ********************************************************************** */
-
-typedef struct _ECalEventHook ECalEventHook;
-typedef struct _ECalEventHookClass ECalEventHookClass;
-
-struct _ECalEventHook {
-	EEventHook hook;
-};
-
-struct _ECalEventHookClass {
-	EEventHookClass hook_class;
-};
-
-GType e_cal_event_hook_get_type (void);
-
 G_END_DECLS
 
 #endif /* __E_CAL_EVENT_H__ */
diff --git a/configure.ac b/configure.ac
index 8a2400a..e26fe69 100644
--- a/configure.ac
+++ b/configure.ac
@@ -956,11 +956,12 @@ AC_ARG_ENABLE([mono],
 if test "x${enable_mono}" = "xyes"; then
 	PKG_CHECK_MODULES([MONO], ["mono"])
 	AC_DEFINE(ENABLE_MONO,1,[Define if Mono embedding should be enabled])
-	MONO_PLUGIN="mono"
 fi
 AC_SUBST(MONO_CFLAGS)
 AC_SUBST(MONO_LIBS)
 
+AM_CONDITIONAL(ENABLE_MONO, [test "x$enable_mono" = "xyes"])
+
 dnl ******************************
 dnl Python hooks
 dnl This should just define python CFLAGS etc here, it is used later to turn on the python plugin or not.
@@ -988,19 +989,19 @@ if test "x${enable_python}" = "xyes"; then
 			PY_INCLUDES="-I$PY_PREFIX/include/python$PY_VERSION"
 			AC_MSG_RESULT([ok])
 			python_package="python-devel"
-			PYTHON_PLUGIN="python"
 		else
 			AC_MSG_ERROR([Can't find Python.h])
 			PY_LIBS=""
 			PY_INCLUDES=""
 			python_package=""
-			PYTHON_PLUGIN=""
 		fi
 	fi
 	AC_SUBST(PY_LIBS)
 	AC_SUBST(PY_INCLUDES)
 fi
 
+AM_CONDITIONAL(ENABLE_PYTHON, [test "x$enable_python" = "xyes"])
+
 
 dnl ********************************************************************************
 dnl security extension support (SSL and S/MIME)
@@ -1808,8 +1809,8 @@ AC_ARG_ENABLE([plugins],
 dnl Add any new plugins here
 plugins_base_always="calendar-file calendar-http $CALENDAR_WEATHER itip-formatter plugin-manager default-source addressbook-file startup-wizard mark-all-read groupwise-features groupwise-account-setup publish-calendar caldav imap-features google-account-setup webdav-account-setup"
 
-plugins_base="$plugins_base_always $SA_JUNK_PLUGIN $BF_JUNK_PLUGIN $EXCHANGE_PLUGIN $MONO_PLUGIN "
-all_plugins_base="$plugins_base_always sa-junk-plugin bogo-junk-plugin exchange-operations mono"
+plugins_base="$plugins_base_always $SA_JUNK_PLUGIN $BF_JUNK_PLUGIN $EXCHANGE_PLUGIN"
+all_plugins_base="$plugins_base_always sa-junk-plugin bogo-junk-plugin exchange-operations"
 
 plugins_standard_always="bbdb subject-thread save-calendar mail-to-task audio-inline mailing-list-actions default-mailer prefer-plain mail-notification attachment-reminder backup-restore email-custom-header templates pst-import vcard-inline"
 
@@ -1817,7 +1818,7 @@ plugins_standard="$plugins_standard_always"
 all_plugins_standard="$plugins_standard"
 
 plugins_experimental_always="face external-editor hula-account-setup"
-plugins_experimental="$plugins_experimental_always $IPOD_SYNC $TNEF_ATTACHMENTS $PYTHON_PLUGIN"
+plugins_experimental="$plugins_experimental_always $IPOD_SYNC $TNEF_ATTACHMENTS"
 all_plugins_experimental="$plugins_experimental_always ipod-sync tnef-attachments"
 
 dnl Temporary KILL-BONOBO hack
@@ -1829,9 +1830,7 @@ dnl exchange-operations
 dnl groupwise-features
 dnl ipod-sync
 dnl mailing-list-actions
-dnl mono
 dnl publish-calendar
-dnl python
 dnl save-calendar
 
 case x"$enable_plugins" in
@@ -1873,17 +1872,6 @@ x | xyes)
 	;;
 esac
 
-if test "x${enable_mono}" = "xyes"; then
-	plugins_enabled="$plugins_enabled mono"
-	msg_plugins="$msg_plugins (and mono)"
-fi
-
-
-if test "x${enable_python}" = "xyes"; then
-	plugins_enabled="$plugins_enabled python"
-	msg_plugins="$msg_plugins (and python)"
-fi
-
 AC_SUBST(plugins_enabled)
 AC_SUBST(all_plugins_base)
 AC_SUBST(all_plugins_standard)
@@ -2088,6 +2076,9 @@ modules/Makefile
 modules/addressbook/Makefile
 modules/calendar/Makefile
 modules/mail/Makefile
+modules/plugin-lib/Makefile
+modules/plugin-mono/Makefile
+modules/plugin-python/Makefile
 plugins/Makefile
 plugins/addressbook-file/Makefile
 plugins/attachment-reminder/Makefile
@@ -2116,13 +2107,11 @@ plugins/mail-notification/Makefile
 plugins/mail-to-task/Makefile
 plugins/mailing-list-actions/Makefile
 plugins/mark-all-read/Makefile
-plugins/mono/Makefile
 plugins/plugin-manager/Makefile
 plugins/prefer-plain/Makefile
 plugins/profiler/Makefile
 plugins/pst-import/Makefile
 plugins/publish-calendar/Makefile
-plugins/python/Makefile
 plugins/sa-junk-plugin/Makefile
 plugins/save-calendar/Makefile
 plugins/startup-wizard/Makefile
diff --git a/e-util/e-plugin.c b/e-util/e-plugin.c
index 3b3d5d2..5c5e55b 100644
--- a/e-util/e-plugin.c
+++ b/e-util/e-plugin.c
@@ -72,12 +72,6 @@ static GHashTable *ep_types;
 static GSList *ep_path;
 /* global table of plugins by plugin.id */
 static GHashTable *ep_plugins;
-/* a table of GSLists of plugins by hook class for hooks not loadable yet */
-static GHashTable *ep_plugins_pending_hooks;
-/* list of all cached xml docs:struct _plugin_doc's */
-static EDList ep_plugin_docs = E_DLIST_INITIALISER(ep_plugin_docs);
-/* gconf client */
-static GConfClient *ep_gconf;
 /* the list of disabled plugins from gconf */
 static GSList *ep_disabled;
 
@@ -110,6 +104,8 @@ ep_check_enabled (const gchar *id)
 static void
 ep_set_enabled (const gchar *id, gint state)
 {
+	GConfClient *client;
+
 	/* Bail out if no change to state, when expressed as a boolean: */
 	if ((state == 0) == (ep_check_enabled(id) == 0))
 		return;
@@ -126,9 +122,11 @@ ep_set_enabled (const gchar *id, gint state)
 	} else
 		ep_disabled = g_slist_prepend (ep_disabled, g_strdup (id));
 
-	gconf_client_set_list(
-		ep_gconf, "/apps/evolution/eplugin/disabled",
+	client = gconf_client_get_default ();
+	gconf_client_set_list (
+		client, "/apps/evolution/eplugin/disabled",
 		GCONF_VALUE_STRING, ep_disabled, NULL);
+	g_object_unref (client);
 }
 
 static gint
@@ -182,21 +180,6 @@ ep_construct (EPlugin *ep, xmlNodePtr root)
 				} else {
 					ep->hooks = g_slist_append(ep->hooks, hook);
 				}
-			} else {
-				gpointer l, oldclass;
-
-				if (ep_plugins_pending_hooks == NULL)
-					ep_plugins_pending_hooks = g_hash_table_new(g_str_hash, g_str_equal);
-				if (!g_hash_table_lookup_extended (ep_plugins_pending_hooks, class, &oldclass, &l)) {
-					oldclass = class;
-					l = NULL;
-				}
-				else {
-					g_free(class);
-				}
-				l = g_slist_prepend (l, ep);
-				g_hash_table_insert (ep_plugins_pending_hooks, oldclass, l);
-				ep->hooks_pending = g_slist_prepend (ep->hooks_pending, node);
 			}
 		} else if (strcmp((gchar *)node->name, "description") == 0) {
 			ep->description = e_plugin_xml_content_domain(node, ep->domain);
@@ -276,7 +259,6 @@ ep_finalize (GObject *object)
 	g_free (ep->description);
 	g_free (ep->name);
 	g_free (ep->domain);
-	g_slist_free (ep->hooks_pending);
 
 	g_slist_foreach (ep->hooks, (GFunc) g_object_unref, NULL);
 	g_slist_free (ep->hooks);
@@ -425,9 +407,7 @@ ep_load(const gchar *filename, gint load_level)
 {
 	xmlDocPtr doc;
 	xmlNodePtr root;
-	gint res = -1;
 	EPlugin *ep = NULL;
-	gint cache = FALSE;
 	struct _plugin_doc *pdoc;
 
 	doc = e_xml_parse_file (filename);
@@ -478,80 +458,12 @@ ep_load(const gchar *filename, gint load_level)
 				g_free (is_system_plugin);
 
 				pdoc->plugin_hooks = g_slist_prepend(pdoc->plugin_hooks, ep);
-				cache |= (ep->hooks_pending != NULL);
 				ep = NULL;
 			}
-			cache |= pdoc->plugins != NULL;
-		}
-	}
-
-	res = 0;
-
-	if (cache) {
-		pd(printf("Caching plugin description '%s' for unknown future hooks\n", filename));
-		e_dlist_addtail(&ep_plugin_docs, (EDListNode *)pdoc);
-	} else {
-		pd(printf("freeing plugin description '%s', nothing uses it\n", filename));
-		xmlFreeDoc(pdoc->doc);
-		g_free(pdoc->filename);
-		g_free(pdoc);
-	}
-
-	return res;
-}
-
-/* This loads a hook that was pending on a given plugin but the type wasn't registered yet */
-/* This works in conjunction with ep_construct and e_plugin_hook_register_type to make sure
-   everything works nicely together.  Apparently. */
-static gint
-ep_load_pending(EPlugin *ep, EPluginHookClass *type)
-{
-	gint res = 0;
-	GSList *l, *p;
-
-	phd(printf("New hook type registered '%s', loading pending hooks on plugin '%s'\n", type->id, ep->id));
-
-	l = ep->hooks_pending;
-	p = NULL;
-	while (l) {
-		GSList *n = l->next;
-		xmlNodePtr node = l->data;
-		gchar *class = (gchar *)xmlGetProp(node, (const guchar *)"class");
-		EPluginHook *hook;
-
-		phd(printf(" checking pending hook '%s'\n", class?class:"<unknown>"));
-
-		if (class) {
-			if (strcmp(class, type->id) == 0) {
-				hook = g_object_new(G_OBJECT_CLASS_TYPE(type), NULL);
-
-				/* Don't bother loading hooks for plugins that are not anyway enabled */
-				if (ep->enabled) {
-					res = type->construct(hook, ep, node);
-					if (res == -1) {
-						g_warning("Plugin '%s' failed to load hook '%s'", ep->name, type->id);
-						g_object_unref(hook);
-					} else {
-						ep->hooks = g_slist_append(ep->hooks, hook);
-					}
-				}
-
-				if (p)
-					p->next = n;
-				else
-					ep->hooks_pending = n;
-				g_slist_free_1(l);
-				l = p;
-			}
-
-			xmlFree(class);
 		}
-
-		p = l;
-		l = n;
 	}
 
-	return res;
+	return 0;
 }
 
 /**
@@ -574,6 +486,69 @@ e_plugin_add_load_path(const gchar *path)
 	ep_path = g_slist_append(ep_path, g_strdup(path));
 }
 
+static void
+plugin_load_subclasses (void)
+{
+	GType *children;
+	guint n_children, ii;
+
+	ep_types = g_hash_table_new (g_str_hash, g_str_equal);
+	eph_types = g_hash_table_new (g_str_hash, g_str_equal);
+	ep_plugins = g_hash_table_new (g_str_hash, g_str_equal);
+
+	/* Load EPlugin subclasses. */
+
+	children = g_type_children (E_TYPE_PLUGIN, &n_children);
+
+	for (ii = 0; ii < n_children; ii++) {
+		EPluginClass *class;
+
+		class = g_type_class_ref (children[ii]);
+		g_hash_table_insert (ep_types, (gpointer) class->type, class);
+	}
+
+	g_free (children);
+
+	/* Load EPluginHook subclasses. */
+
+	children = g_type_children (E_TYPE_PLUGIN_HOOK, &n_children);
+
+	for (ii = 0; ii < n_children; ii++) {
+		EPluginHookClass *hook_class;
+		EPluginHookClass *dupe_class;
+
+		hook_class = g_type_class_ref (children[ii]);
+
+		/* Sanity check the hook class. */
+		if (hook_class->id == NULL || *hook_class->id == '\0') {
+			g_warning (
+				"%s has no hook ID, so skipping",
+				G_OBJECT_CLASS_NAME (hook_class));
+			g_type_class_unref (hook_class);
+			continue;
+		}
+
+		/* Check for class ID collisions. */
+		dupe_class = g_hash_table_lookup (eph_types, hook_class->id);
+		if (dupe_class != NULL) {
+			g_warning (
+				"%s and %s have the same hook "
+				"ID ('%s'), so skipping %s",
+				G_OBJECT_CLASS_NAME (dupe_class),
+				G_OBJECT_CLASS_NAME (hook_class),
+				hook_class->id,
+				G_OBJECT_CLASS_NAME (hook_class));
+			g_type_class_unref (hook_class);
+			continue;
+		}
+
+		g_hash_table_insert (
+			eph_types, (gpointer) hook_class->id, hook_class);
+	}
+
+	g_free (children);
+}
+
 /**
  * e_plugin_load_plugins:
  *
@@ -585,13 +560,23 @@ e_plugin_add_load_path(const gchar *path)
 gint
 e_plugin_load_plugins(void)
 {
+	GConfClient *client;
 	GSList *l;
 	gint i;
 
-	if (ep_types == NULL) {
-		g_warning("no plugin types defined");
+	if (eph_types != NULL)
 		return 0;
-	}
+
+	/* We require that all GTypes for EPlugin and EPluginHook
+	 * subclasses be registered prior to loading any plugins.
+	 * It greatly simplifies the loading process. */
+	plugin_load_subclasses ();
+
+	client = gconf_client_get_default ();
+	ep_disabled = gconf_client_get_list (
+		client, "/apps/evolution/eplugin/disabled",
+		GCONF_VALUE_STRING, NULL);
+	g_object_unref (client);
 
 	for (i=0; i < 3; i++) {
 		for (l = ep_path;l;l = g_slist_next(l)) {
@@ -623,70 +608,6 @@ e_plugin_load_plugins(void)
 	return 0;
 }
 
-/**
- * e_plugin_register_type:
- * @type: The GObject type of the plugin loader.
- *
- * Register a new plugin type with the plugin system.  Each type must
- * subclass EPlugin and must override the type member of the
- * EPluginClass with a unique name.
- **/
-void
-e_plugin_register_type(GType type)
-{
-	EPluginClass *class;
-	struct _plugin_doc *pdoc, *ndoc;
-
-	if (ep_types == NULL) {
-		ep_types = g_hash_table_new(g_str_hash, g_str_equal);
-		ep_plugins = g_hash_table_new(g_str_hash, g_str_equal);
-		/* TODO: notify listening */
-		ep_gconf = gconf_client_get_default();
-		ep_disabled = gconf_client_get_list(ep_gconf, "/apps/evolution/eplugin/disabled", GCONF_VALUE_STRING, NULL);
-	}
-
-	class = g_type_class_ref(type);
-
-	pd(printf("register plugin type '%s'\n", class->type));
-
-	g_hash_table_insert(ep_types, (gpointer)class->type, class);
-
-	/* check for pending plugins */
-	pdoc = (struct _plugin_doc *)ep_plugin_docs.head;
-	ndoc = pdoc->next;
-	while (ndoc) {
-		if (pdoc->plugins) {
-			GSList *l, *add = NULL;
-
-			for (l=pdoc->plugins;l;l=g_slist_next(l)) {
-				xmlNodePtr root = l->data;
-				gchar *prop_type;
-
-				prop_type = (gchar *)xmlGetProp(root, (const guchar *)"type");
-				if (!strcmp(prop_type, class->type))
-					add = g_slist_append(add, l->data);
-				xmlFree(prop_type);
-			}
-
-			for (l=add;l;l=g_slist_next(l)) {
-				xmlNodePtr root = l->data;
-				EPlugin *ep;
-
-				pdoc->plugins = g_slist_remove(pdoc->plugins, root);
-				ep = ep_load_plugin(root, pdoc);
-				if (ep)
-					pdoc->plugin_hooks = g_slist_prepend(pdoc->plugin_hooks, ep);
-				/* TODO: garbage collect plugin doc? */
-			}
-
-			g_slist_free(add);
-		}
-
-		pdoc = ndoc;
-		ndoc = ndoc->next;
-	}
-}
-
 static void
 ep_list_plugin(gpointer key, gpointer val, gpointer dat)
 {
@@ -973,265 +894,6 @@ e_plugin_xml_content_domain(xmlNodePtr node, const gchar *domain)
 
 /* ********************************************************************** */
 
-static gpointer epl_parent_class;
-
-/* TODO:
-   We need some way to manage lifecycle.
-   We need some way to manage state.
-
-   Maybe just the g module init method will do, or we could add
-   another which returns context.
-
-   There is also the question of per-instance context, e.g. for config
-   pages.
-*/
-
-static GList *missing_symbols = NULL;
-
-static gint
-epl_loadmodule(EPlugin *ep, gboolean fatal)
-{
-	EPluginLib *epl = E_PLUGIN_LIB (ep);
-	EPluginLibEnableFunc enable;
-
-	if (epl->module != NULL)
-		return 0;
-
-	if ((epl->module = g_module_open(epl->location, 0)) == NULL) {
-		if (fatal)
-			g_warning("can't load plugin '%s': %s", epl->location, g_module_error());
-		else
-			missing_symbols = g_list_prepend (missing_symbols, g_object_ref (ep));
-		return -1;
-	}
-
-	if (g_module_symbol(epl->module, "e_plugin_lib_enable", (gpointer)&enable)) {
-		if (enable(epl, TRUE) != 0) {
-			ep->enabled = FALSE;
-			g_module_close(epl->module);
-			epl->module = NULL;
-			return -1;
-		}
-	}
-
-	return 0;
-}
-
-void
-e_plugin_load_plugins_with_missing_symbols (void)
-{
-	GList *list = missing_symbols;
-
-	while (list) {
-		EPlugin *ep = list->data;
-		epl_loadmodule (ep, TRUE);
-		g_object_unref (ep);
-		list = g_list_next (list);
-	}
-
-	g_list_free (missing_symbols);
-	missing_symbols = NULL;
-}
-
-static gpointer
-epl_invoke(EPlugin *ep, const gchar *name, gpointer data)
-{
-	EPluginLib *epl = E_PLUGIN_LIB (ep);
-	EPluginLibFunc cb;
-
-	if (!ep->enabled) {
-		g_warning("trying to invoke '%s' on disabled plugin '%s'", name, ep->id);
-		return NULL;
-	}
-
-	if (epl_loadmodule(ep, FALSE) != 0)
-		return NULL;
-
-	if (!g_module_symbol(epl->module, name, (gpointer)&cb)) {
-		g_warning("Cannot resolve symbol '%s' in plugin '%s' (not exported?)", name, epl->location);
-		return NULL;
-	}
-
-	return cb(epl, data);
-}
-
-static gpointer
-epl_get_symbol(EPlugin *ep, const gchar *name)
-{
-	EPluginLib *epl = E_PLUGIN_LIB (ep);
-	gpointer symbol;
-
-	if (epl_loadmodule (ep, FALSE) != 0)
-		return NULL;
-
-	if (!g_module_symbol (epl->module, name, &symbol))
-		return NULL;
-
-	return symbol;
-}
-
-static gint
-epl_construct(EPlugin *ep, xmlNodePtr root)
-{
-	EPluginLib *epl = E_PLUGIN_LIB (ep);
-
-	if (E_PLUGIN_CLASS (epl_parent_class)->construct (ep, root) == -1)
-		return -1;
-
-	epl->location = e_plugin_xml_prop(root, "location");
-
-	if (epl->location == NULL) {
-		g_warning("Library plugin '%s' has no location", ep->id);
-		return -1;
-	}
-#ifdef G_OS_WIN32
-	{
-		gchar *mapped_location =
-			e_util_replace_prefix (EVOLUTION_PREFIX,
-					       e_util_get_prefix (),
-					       epl->location);
-		g_free (epl->location);
-		epl->location = mapped_location;
-	}
-#endif
-	/* If we're enabled, check for the load-on-startup property */
-	if (ep->enabled) {
-		xmlChar *tmp;
-
-		tmp = xmlGetProp(root, (const guchar *)"load-on-startup");
-		if (tmp) {
-			if (strcmp ((const gchar *)tmp, "after-ui") == 0) {
-				missing_symbols = g_list_prepend (missing_symbols, g_object_ref (ep));
-			} else {
-				if (epl_loadmodule(ep, FALSE) != 0) {
-					xmlFree(tmp);
-					return -1;
-				}
-			}
-			xmlFree(tmp);
-		}
-	}
-
-	return 0;
-}
-
-static GtkWidget *
-epl_get_configure_widget (EPlugin *ep)
-{
-	EPluginLib *epl = E_PLUGIN_LIB (ep);
-	EPluginLibGetConfigureWidgetFunc get_configure_widget;
-
-	pd (printf ("\n epl_get_configure_widget \n"));
-
-	if (epl_loadmodule (ep, FALSE) != 0) {
-		pd (printf ("\n epl_loadmodule  \n"));
-		return NULL;
-	}
-
-	if (g_module_symbol (epl->module, "e_plugin_lib_get_configure_widget", (gpointer)&get_configure_widget)) {
-		pd (printf ("\n g_module_symbol is loaded\n"));
-		return (GtkWidget*) get_configure_widget (epl);
-	}
-	return NULL;
-}
-
-static void
-epl_enable(EPlugin *ep, gint state)
-{
-	EPluginLib *epl = E_PLUGIN_LIB (ep);
-	EPluginLibEnableFunc enable;
-
-	E_PLUGIN_CLASS (epl_parent_class)->enable (ep, state);
-
-	/* if we're disabling and it isn't loaded, nothing to do */
-	if (!state && epl->module == NULL)
-		return;
-
-	/* this will noop if we're disabling since we tested it above */
-	if (epl_loadmodule(ep, FALSE) != 0)
-		return;
-
-	if (g_module_symbol(epl->module, "e_plugin_lib_enable", (gpointer)&enable)) {
-		if (enable(epl, state) != 0)
-			return;
-	}
-#if 0
-	if (!state) {
-		g_module_close(epl->module);
-		epl->module = NULL;
-	}
-#endif
-}
-
-static void
-epl_finalize (GObject *object)
-{
-	EPluginLib *epl = E_PLUGIN_LIB (object);
-
-	g_free (epl->location);
-
-	if (epl->module)
-		g_module_close (epl->module);
-
-	/* Chain up to parent's finalize() method. */
-	G_OBJECT_CLASS (epl_parent_class)->finalize (object);
-}
-
-static void
-epl_class_init (EPluginClass *class)
-{
-	GObjectClass *object_class;
-
-	epl_parent_class = g_type_class_peek_parent (class);
-
-	object_class = G_OBJECT_CLASS (class);
-	object_class->finalize = epl_finalize;
-
-	class->construct = epl_construct;
-	class->invoke = epl_invoke;
-	class->get_symbol = epl_get_symbol;
-	class->enable = epl_enable;
-	class->get_configure_widget = epl_get_configure_widget;
-	class->type = "shlib";
-}
-
-/**
- * e_plugin_lib_get_type:
- *
- * Standard GObject function to retrieve the EPluginLib type.  Use to
- * register the type with the plugin system if you want to use shared
- * library plugins.
- *
- * Return value: The EPluginLib type.
- **/
-GType
-e_plugin_lib_get_type (void)
-{
-	static GType type = 0;
-
-	if (G_UNLIKELY (type == 0)) {
-		static const GTypeInfo type_info = {
-			sizeof (EPluginLibClass),
-			(GBaseInitFunc) NULL,
-			(GBaseFinalizeFunc) NULL,
-			(GClassInitFunc) epl_class_init,
-			(GClassFinalizeFunc) NULL,
-			NULL,  /* class_data */
-			sizeof (EPluginLib),
-			0,     /* n_preallocs */
-			(GInstanceInitFunc) NULL,
-			NULL   /* value_table */
-		};
-
-		type = g_type_register_static (
-			e_plugin_get_type (), "EPluginLib", &type_info, 0);
-	}
-
-	return type;
-}
-
-/* ********************************************************************** */
-
 static gpointer eph_parent_class;
 
 static gint
@@ -1315,83 +977,6 @@ e_plugin_hook_enable (EPluginHook *eph, gint state)
 }
 
 /**
- * e_plugin_hook_register_type:
- * @type:
- *
- * Register a new plugin hook type with the plugin system.  Each type
- * must subclass EPluginHook and must override the id member of the
- * EPluginHookClass with a unique identification string.
- **/
-void
-e_plugin_hook_register_type(GType type)
-{
-	EPluginHookClass *klass, *oldklass;
-	GSList *l;
-
-	gpointer plugins; /* GSList */
-	gpointer class;
-
-	if (eph_types == NULL)
-		eph_types = g_hash_table_new(g_str_hash, g_str_equal);
-
-	klass = g_type_class_ref(type);
-
-	oldklass = g_hash_table_lookup(eph_types, (gpointer)klass->id);
-	if (oldklass == klass) {
-		g_type_class_unref(klass);
-		return;
-	} else if (oldklass != NULL) {
-		g_warning("Trying to re-register hook type '%s'", klass->id);
-		return;
-	}
-
-	phd(printf("register plugin hook type '%s'\n", klass->id));
-	g_hash_table_insert(eph_types, (gpointer)klass->id, klass);
-
-	/* if we've already loaded a plugin that needed this hook but it didn't exist, re-load it now */
-
-	if (ep_plugins_pending_hooks
-	    && g_hash_table_lookup_extended (ep_plugins_pending_hooks, klass->id, &class, &plugins)) {
-		struct _plugin_doc *pdoc, *ndoc;
-
-		g_hash_table_remove (ep_plugins_pending_hooks, class);
-		g_free (class);
-		for (l = plugins; l; l = g_slist_next(l)) {
-			EPlugin *ep = l->data;
-
-			ep_load_pending (ep, klass);
-		}
-		g_slist_free (plugins);
-
-		/* See if we can now garbage collect the xml definition since its been fully loaded */
-
-		/* This is all because libxml doesn't refcount! */
-
-		pdoc = (struct _plugin_doc *)ep_plugin_docs.head;
-		ndoc = pdoc->next;
-		while (ndoc) {
-			if (pdoc->doc) {
-				gint cache = pdoc->plugins != NULL;
-
-				for (l=pdoc->plugin_hooks;!cache && l;l=g_slist_next(l))
-					cache |= (((EPlugin *)l->data)->hooks_pending != NULL);
-
-				if (!cache) {
-					pd(printf("Gargabe collecting plugin description '%s'\n", pdoc->filename));
-					e_dlist_remove((EDListNode *)pdoc);
-					xmlFreeDoc(pdoc->doc);
-					g_free(pdoc->filename);
-					g_free(pdoc);
-				}
-			}
-
-			pdoc = ndoc;
-			ndoc = ndoc->next;
-		}
-	}
-}
-
-/**
  * e_plugin_hook_mask:
  * @root: An XML node.
  * @map: A zero-fill terminated array of EPluginHookTargeKeys used to
@@ -1478,118 +1063,3 @@ e_plugin_hook_id(xmlNodePtr root, const struct _EPluginHookTargetKey *map, const
 
 	return ~0;
 }
-
-/* ********************************************************************** */
-/* Plugin plugin */
-
-static gpointer epth_parent_class;
-
-static gint
-epth_load_plugin(gpointer d)
-{
-	EPluginHook *eph = d;
-	EPluginTypeHook *epth = d;
-	GType type;
-
-	epth->idle = 0;
-
-	type = GPOINTER_TO_UINT(e_plugin_invoke(eph->plugin, epth->get_type, eph->plugin));
-	if (type != 0)
-		e_plugin_register_type(type);
-
-	return FALSE;
-}
-
-static gint
-epth_construct(EPluginHook *eph, EPlugin *ep, xmlNodePtr root)
-{
-	EPluginTypeHook *epth = E_PLUGIN_TYPE_HOOK (eph);
-	xmlNodePtr node;
-
-	phd(printf("loading plugin hook\n"));
-
-	if (((EPluginHookClass *)epth_parent_class)->construct(eph, ep, root) == -1)
-		return -1;
-
-	node = root->children;
-	while (node) {
-		if (strcmp((gchar *)node->name, "plugin-type") == 0) {
-			epth->get_type = e_plugin_xml_prop(node, "get-type");
-			/* We need to run this in an idle handler,
-			 * since at this point the parent EPlugin wont
-			 * be fully initialised ... darn */
-			if (epth->get_type)
-				epth->idle = g_idle_add(epth_load_plugin, epth);
-			else
-				g_warning("Plugin type plugin missing get-type callback");
-		}
-		node = node->next;
-	}
-
-	eph->plugin = ep;
-
-	return 0;
-}
-
-static void
-epth_finalize (GObject *object)
-{
-	EPluginTypeHook *epth = E_PLUGIN_TYPE_HOOK (object);
-
-	if (epth->idle != 0)
-		g_source_remove (epth->idle);
-
-	g_free (epth->get_type);
-
-	/* Chain up to parent's finalize() method. */
-	G_OBJECT_CLASS (epth_parent_class)->finalize (object);
-}
-
-static void
-epth_class_init (EPluginTypeHookClass *class)
-{
-	GObjectClass *object_class;
-	EPluginHookClass *hook_class;
-
-	epth_parent_class = g_type_class_peek_parent (class);
-
-	object_class = G_OBJECT_CLASS (class);
-	object_class->finalize = epth_finalize;
-
-	hook_class = E_PLUGIN_HOOK_CLASS (class);
-	hook_class->construct = epth_construct;
-	hook_class->id = "org.gnome.evolution.plugin.type:1.0";
-}
-
-/**
- * e_plugin_type_hook_get_type:
- *
- * Get the type for the plugin plugin hook.
- *
- * Return value: The type of the plugin type hook.
- **/
-GType
-e_plugin_type_hook_get_type(void)
-{
-	static GType type = 0;
-
-	if (G_UNLIKELY (type == 0)) {
-		static const GTypeInfo type_info = {
-			sizeof (EPluginTypeHookClass),
-			(GBaseInitFunc) NULL,
-			(GBaseFinalizeFunc) NULL,
-			(GClassInitFunc) epth_class_init,
-			(GClassFinalizeFunc) NULL,
-			NULL,  /* class_data */
-			sizeof (EPluginTypeHook),
-			0,     /* n_preallocs */
-			(GInstanceInitFunc) NULL,
-			NULL   /* value_table */
-		};
-
-		type = g_type_register_static (
-			E_TYPE_PLUGIN_HOOK, "EPluginTypeHook", &type_info, 0);
-	}
-
-	return type;
-}
diff --git a/e-util/e-plugin.h b/e-util/e-plugin.h
index 18949bf..8e24436 100644
--- a/e-util/e-plugin.h
+++ b/e-util/e-plugin.h
@@ -64,8 +64,6 @@ struct _EPluginAuthor {
  * @object: Superclass.
  * @id: Unique identifier for plugin instance.
  * @path: Filename where the xml definition resides.
- * @hooks_pending: A list hooks which can't yet be loaded.  This is
- * the xmlNodePtr to the root node of the hook definition.
  * @description: A description of the plugin's purpose.
  * @name: The name of the plugin.
  * @domain: The translation domain for this plugin.
@@ -82,7 +80,6 @@ struct _EPlugin {
 
 	gchar *id;
 	gchar *path;
-	GSList *hooks_pending;
 
 	gchar *description;
 	gchar *name;
@@ -134,11 +131,8 @@ GType e_plugin_get_type(void);
 gint e_plugin_construct(EPlugin *ep, xmlNodePtr root);
 void e_plugin_add_load_path(const gchar *);
 gint e_plugin_load_plugins(void);
-void e_plugin_load_plugins_with_missing_symbols(void);
 GSList * e_plugin_list_plugins(void);
 
-void e_plugin_register_type(GType type);
-
 gpointer e_plugin_get_symbol(EPlugin *ep, const gchar *name);
 gpointer e_plugin_invoke(EPlugin *ep, const gchar *name, gpointer data);
 void e_plugin_enable(EPlugin *eph, gint state);
@@ -154,73 +148,6 @@ gchar *e_plugin_xml_content(xmlNodePtr node);
 gchar *e_plugin_xml_content_domain(xmlNodePtr node, const gchar *domain);
 
 /* ********************************************************************** */
-#include <gmodule.h>
-
-/* Standard GObject macros */
-#define E_TYPE_PLUGIN_LIB \
-	(e_plugin_lib_get_type ())
-#define E_PLUGIN_LIB(obj) \
-	(G_TYPE_CHECK_INSTANCE_CAST \
-	((obj), E_TYPE_PLUGIN_LIB, EPluginLib))
-#define E_PLUGIN_LIB_CLASS(cls) \
-	(G_TYPE_CHECK_CLASS_CAST \
-	((cls), E_TYPE_PLUGIN_LIB, EPluginLibClass))
-#define E_IS_PLUGIN_LIB(obj) \
-	(G_TYPE_CHECK_INSTANCE_TYPE \
-	((obj), E_TYPE_PLUGIN_LIB))
-#define E_IS_PLUGIN_LIB_CLASS(cls) \
-	(G_TYPE_CHECK_CLASS_TYPE \
-	((cls), E_TYPE_PLUGIN_LIB))
-#define E_PLUGIN_LIB_GET_CLASS(obj) \
-	(G_TYPE_INSTANCE_GET_CLASS \
-	((obj), E_TYPE_PLUGIN_LIB, EPluginLibClass))
-
-typedef struct _EPluginLib EPluginLib;
-typedef struct _EPluginLibClass EPluginLibClass;
-
-/* The callback signature used for epluginlib methods */
-typedef gpointer (*EPluginLibFunc)(EPluginLib *ep, gpointer data);
-/* The setup method, this will be called when the plugin is
- * initialised.  In the future it may also be called when the plugin
- * is disabled. */
-typedef gint (*EPluginLibEnableFunc)(EPluginLib *ep, gint enable);
-typedef gpointer (*EPluginLibGetConfigureWidgetFunc)(EPluginLib *ep);
-
-/**
- * struct _EPluginLib -
- *
- * @plugin: Superclass.
- * @location: The filename of the shared object.
- * @module: The GModule once it is loaded.
- *
- * This is a concrete EPlugin class.  It loads and invokes dynamically
- * loaded libraries using GModule.  The shared object isn't loaded
- * until the first callback is invoked.
- *
- * When the plugin is loaded, and if it exists, "e_plugin_lib_enable"
- * will be invoked to initialise the
- **/
-struct _EPluginLib {
-	EPlugin plugin;
-
-	gchar *location;
-	GModule *module;
-};
-
-/**
- * struct _EPluginLibClass -
- *
- * @plugin_class: Superclass.
- *
- * The plugin library needs no additional class data.
- **/
-struct _EPluginLibClass {
-	EPluginClass plugin_class;
-};
-
-GType e_plugin_lib_get_type(void);
-
-/* ********************************************************************** */
 
 /* Standard GObject macros */
 #define E_TYPE_PLUGIN_HOOK \
@@ -323,8 +250,6 @@ struct _EPluginHookClass {
 
 GType e_plugin_hook_get_type(void);
 
-void e_plugin_hook_register_type(GType type);
-
 EPluginHook * e_plugin_hook_new(EPlugin *ep, xmlNodePtr root);
 void e_plugin_hook_enable(EPluginHook *eph, gint state);
 
@@ -332,49 +257,6 @@ void e_plugin_hook_enable(EPluginHook *eph, gint state);
 guint32 e_plugin_hook_mask(xmlNodePtr root, const struct _EPluginHookTargetKey *map, const gchar *prop);
 guint32 e_plugin_hook_id(xmlNodePtr root, const struct _EPluginHookTargetKey *map, const gchar *prop);
 
-/* ********************************************************************** */
-
-/* EPluginTypeHook lets a plugin register a new plugin type.
-  <hook class="org.gnome.evolution.plugin.type:1.0">
-   <plugin-type get-type="e_plugin_mono_get_type/>
-  </hook>
-*/
-
-/* Standard GObject macros */
-#define E_TYPE_PLUGIN_TYPE_HOOK \
-	(e_plugin_type_hook_get_type ())
-#define E_PLUGIN_TYPE_HOOK(obj) \
-	(G_TYPE_CHECK_INSTANCE_CAST \
-	((obj), E_TYPE_PLUGIN_TYPE_HOOK, EPluginTypeHook))
-#define E_PLUGIN_TYPE_HOOK_CLASS(cls) \
-	(G_TYPE_CHECK_CLASS_CAST \
-	((cls), E_TYPE_PLUGIN_TYPE_HOOK, EPluginTypeHookClass))
-#define E_IS_PLUGIN_TYPE_HOOK(obj) \
-	(G_TYPE_CHECK_INSTANCE_TYPE \
-	((obj), E_TYPE_PLUGIN_TYPE_HOOK))
-#define E_IS_PLUGIN_TYPE_HOOK_CLASS(cls) \
-	(G_TYPE_CHECK_CLASS_TYPE \
-	((cls), E_TYPE_PLUGIN_TYPE_HOOK))
-#define E_PLUGIN_TYPE_HOOK_GET_CLASS(obj) \
-	(G_TYPE_INSTANCE_GET_CLASS \
-	((obj), E_TYPE_PLUGIN_TYPE_HOOK, EPluginTypeHookClass))
-
-typedef struct _EPluginTypeHook EPluginTypeHook;
-typedef struct _EPluginTypeHookClass EPluginTypeHookClass;
-
-struct _EPluginTypeHook {
-	EPluginHook hook;
-
-	gchar *get_type;
-	guint idle;
-};
-
-struct _EPluginTypeHookClass {
-	EPluginHookClass hook_class;
-};
-
-GType e_plugin_type_hook_get_type(void);
-
 /* README: Currently there is only one flag.
    But we may need more in the future and hence makes
    sense to keep as an enum */
diff --git a/mail/Makefile.am b/mail/Makefile.am
index 63cceb4..043ffee 100644
--- a/mail/Makefile.am
+++ b/mail/Makefile.am
@@ -71,7 +71,7 @@ mailinclude_HEADERS =					\
 	em-html-stream.h				\
 	em-icon-stream.h				\
 	em-inline-filter.h				\
-	em-junk-hook.h					\
+	em-junk.h					\
 	em-search-context.h				\
 	em-subscribe-editor.h				\
 	em-sync-stream.h				\
@@ -129,7 +129,7 @@ libevolution_mail_la_SOURCES =				\
 	em-html-stream.c				\
 	em-icon-stream.c				\
 	em-inline-filter.c				\
-	em-junk-hook.c					\
+	em-junk.c					\
 	em-search-context.c				\
 	em-subscribe-editor.c				\
 	em-sync-stream.c				\
diff --git a/mail/em-config.c b/mail/em-config.c
index 357e885..dcdf9b1 100644
--- a/mail/em-config.c
+++ b/mail/em-config.c
@@ -223,85 +223,3 @@ em_config_target_new_account(EMConfig *emp, struct _EAccount *account)
 
 	return t;
 }
-
-/* ********************************************************************** */
-
-/* Popup menu plugin handler */
-
-/*
-<e-plugin
-  class="org.gnome.mail.plugin.popup:1.0"
-  id="org.gnome.mail.plugin.popup.item:1.0"
-  type="shlib"
-  location="/opt/gnome2/lib/camel/1.0/libcamelimap.so"
-  name="imap"
-  description="IMAP4 and IMAP4v1 mail store">
-  <hook class="org.gnome.mail.popupMenu:1.0"
-        handler="HandlePopup">
-  <menu id="any" target="select">
-   <item
-    type="item|toggle|radio|image|submenu|bar"
-    active
-    path="foo/bar"
-    label="label"
-    icon="foo"
-    mask="select_one"
-    activate="emp_view_emacs"/>
-  </menu>
-  </extension>
-
-*/
-
-static gpointer emph_parent_class;
-#define emph ((EMConfigHook *)eph)
-
-static const EConfigHookTargetMask emph_no_masks[] = {
-	{ NULL }
-};
-
-static const EConfigHookTargetMap emph_targets[] = {
-	{ "folder", EM_CONFIG_TARGET_FOLDER, emph_no_masks },
-	{ "prefs", EM_CONFIG_TARGET_PREFS, emph_no_masks },
-	{ "account", EM_CONFIG_TARGET_ACCOUNT, emph_no_masks },
-	{ NULL }
-};
-
-static void
-emph_finalise(GObject *o)
-{
-	/*EPluginHook *eph = (EPluginHook *)o;*/
-
-	((GObjectClass *)emph_parent_class)->finalize(o);
-}
-
-static void
-emph_class_init(EPluginHookClass *klass)
-{
-	gint i;
-
-	((GObjectClass *)klass)->finalize = emph_finalise;
-	((EPluginHookClass *)klass)->id = "org.gnome.evolution.mail.config:1.0";
-
-	for (i=0;emph_targets[i].type;i++)
-		e_config_hook_class_add_target_map((EConfigHookClass *)klass, &emph_targets[i]);
-
-	((EConfigHookClass *)klass)->config_class = g_type_class_ref(em_config_get_type());
-}
-
-GType
-em_config_hook_get_type(void)
-{
-	static GType type = 0;
-
-	if (!type) {
-		static const GTypeInfo info = {
-			sizeof(EMConfigHookClass), NULL, NULL, (GClassInitFunc) emph_class_init, NULL, NULL,
-			sizeof(EMConfigHook), 0, (GInstanceInitFunc) NULL,
-		};
-
-		emph_parent_class = g_type_class_ref(e_config_hook_get_type());
-		type = g_type_register_static(e_config_hook_get_type(), "EMConfigHook", &info, 0);
-	}
-
-	return type;
-}
diff --git a/mail/em-config.h b/mail/em-config.h
index 05401f0..62e74be 100644
--- a/mail/em-config.h
+++ b/mail/em-config.h
@@ -91,21 +91,6 @@ EMConfigTargetFolder *em_config_target_new_folder(EMConfig *emp, CamelFolder *fo
 EMConfigTargetPrefs *em_config_target_new_prefs(EMConfig *emp, GConfClient *gconf);
 EMConfigTargetAccount *em_config_target_new_account(EMConfig *emp, EAccount *account);
 
-/* ********************************************************************** */
-
-typedef struct _EMConfigHook EMConfigHook;
-typedef struct _EMConfigHookClass EMConfigHookClass;
-
-struct _EMConfigHook {
-	EConfigHook hook;
-};
-
-struct _EMConfigHookClass {
-	EConfigHookClass hook_class;
-};
-
-GType em_config_hook_get_type(void);
-
 G_END_DECLS
 
 #endif /* __EM_CONFIG_H__ */
diff --git a/mail/em-event.c b/mail/em-event.c
index 2cdbb23..de8f468 100644
--- a/mail/em-event.c
+++ b/mail/em-event.c
@@ -204,83 +204,3 @@ em_event_target_new_custom_icon(EMEvent *eme, GtkTreeStore *store, GtkTreeIter *
 
 	return t;
 }
-
-/* ********************************************************************** */
-
-static gpointer emeh_parent_class;
-#define emeh ((EMEventHook *)eph)
-
-static const EEventHookTargetMask emeh_folder_masks[] = {
-	{ "newmail", EM_EVENT_FOLDER_NEWMAIL },
-	{ NULL }
-};
-
-static const EEventHookTargetMask emeh_composer_masks[] = {
-	{ "sendoption", EM_EVENT_COMPOSER_SEND_OPTION },
-	{ NULL }
-};
-
-static const EEventHookTargetMask emeh_message_masks[] = {
-	{ "replyall", EM_EVENT_MESSAGE_REPLY_ALL },
-	{ "reply", EM_EVENT_MESSAGE_REPLY },
-	{ NULL }
-};
-
-static const EEventHookTargetMask emeh_send_receive_masks[] = {
-	{ "sendreceive", EM_EVENT_SEND_RECEIVE },
-	{ NULL }
-};
-
-static const EEventHookTargetMask emeh_custom_icon_masks[] = {
-	{ "customicon", EM_EVENT_CUSTOM_ICON },
-	{ NULL }
-};
-
-static const EEventHookTargetMap emeh_targets[] = {
-	{ "folder", EM_EVENT_TARGET_FOLDER, emeh_folder_masks },
-	{ "message", EM_EVENT_TARGET_MESSAGE, emeh_message_masks },
-	{ "composer", EM_EVENT_TARGET_COMPOSER, emeh_composer_masks},
-	{ "sendreceive", EM_EVENT_TARGET_SEND_RECEIVE, emeh_send_receive_masks},
-	{ "customicon", EM_EVENT_TARGET_CUSTOM_ICON, emeh_custom_icon_masks},
-	{ NULL }
-};
-
-static void
-emeh_finalise(GObject *o)
-{
-	/*EPluginHook *eph = (EPluginHook *)o;*/
-
-	((GObjectClass *)emeh_parent_class)->finalize(o);
-}
-
-static void
-emeh_class_init(EPluginHookClass *klass)
-{
-	gint i;
-
-	((GObjectClass *)klass)->finalize = emeh_finalise;
-	((EPluginHookClass *)klass)->id = "org.gnome.evolution.mail.events:1.0";
-
-	for (i=0;emeh_targets[i].type;i++)
-		e_event_hook_class_add_target_map((EEventHookClass *)klass, &emeh_targets[i]);
-
-	((EEventHookClass *)klass)->event = (EEvent *)em_event_peek();
-}
-
-GType
-em_event_hook_get_type(void)
-{
-	static GType type = 0;
-
-	if (!type) {
-		static const GTypeInfo info = {
-			sizeof(EMEventHookClass), NULL, NULL, (GClassInitFunc) emeh_class_init, NULL, NULL,
-			sizeof(EMEventHook), 0, (GInstanceInitFunc) NULL,
-		};
-
-		emeh_parent_class = g_type_class_ref(e_event_hook_get_type());
-		type = g_type_register_static(e_event_hook_get_type(), "EMEventHook", &info, 0);
-	}
-
-	return type;
-}
diff --git a/mail/em-event.h b/mail/em-event.h
index d653e35..6f1366a 100644
--- a/mail/em-event.h
+++ b/mail/em-event.h
@@ -141,21 +141,6 @@ EMEventTargetMessage *em_event_target_new_message(EMEvent *emp, CamelFolder *fol
 EMEventTargetSendReceive * em_event_target_new_send_receive(EMEvent *eme, GtkWidget *table, gpointer data, gint row, guint32 flags);
 EMEventTargetCustomIcon * em_event_target_new_custom_icon(EMEvent *eme, GtkTreeStore *store, GtkTreeIter *iter, const gchar *uri, guint32 flags);
 
-/* ********************************************************************** */
-
-typedef struct _EMEventHook EMEventHook;
-typedef struct _EMEventHookClass EMEventHookClass;
-
-struct _EMEventHook {
-	EEventHook hook;
-};
-
-struct _EMEventHookClass {
-	EEventHookClass hook_class;
-};
-
-GType em_event_hook_get_type(void);
-
 G_END_DECLS
 
 #endif /* __EM_EVENT_H__ */
diff --git a/plugins/python/python-plugin-loader.h b/mail/em-junk.c
similarity index 55%
copy from plugins/python/python-plugin-loader.h
copy to mail/em-junk.c
index 66bd8d5..6af215e 100644
--- a/plugins/python/python-plugin-loader.h
+++ b/mail/em-junk.c
@@ -1,4 +1,6 @@
 /*
+ * em-junk.c
+ *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
@@ -14,34 +16,16 @@
  *
  *
  * Authors:
- *		Johnny Jacob <jjohnny novell com>
+ *		Vivek Jain <jvivek novell com>
  *
  * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
  *
  */
 
-#ifndef _ORG_GNOME_EVOLUTION_PYTHON_H
-#define _ORG_GNOME_EVOLUTION_PYTHON_H
-
-#include "e-util/e-plugin.h"
-
-typedef struct _EPluginPython EPluginPython;
-typedef struct _EPluginPythonClass EPluginPythonClass;
-
-struct _EPluginPython {
-	EPlugin plugin;
-
-	struct _EPluginPythonPrivate *priv;
-
-	gchar *location;		/* location */
-	gchar *pClass;		/* handler class */
-        gchar *module_name;
-};
-
-struct _EPluginPythonClass {
-	EPluginClass plugin_class;
-};
-
-gpointer org_gnome_evolution_python_get_type(gpointer a, gpointer b);
+#include "em-junk.h"
 
-#endif /* ! _ORG_GNOME_EVOLUTION_PYTHON_H */
+GQuark
+em_junk_error_quark (void)
+{
+	return g_quark_from_static_string ("em-junk-error-quark");
+}
diff --git a/mail/em-junk.h b/mail/em-junk.h
new file mode 100644
index 0000000..79493ca
--- /dev/null
+++ b/mail/em-junk.h
@@ -0,0 +1,66 @@
+/*
+ * em-junk.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ *		Vivek Jain <jvivek novell com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifndef EM_JUNK_H
+#define EM_JUNK_H
+
+#include <e-util/e-plugin.h>
+#include <camel/camel-junk-plugin.h>
+#include <camel/camel-mime-message.h>
+
+#define EM_JUNK_ERROR (em_junk_error_quark ())
+
+G_BEGIN_DECLS
+
+typedef struct _EMJunkTarget EMJunkTarget;
+typedef struct _EMJunkInterface EMJunkInterface;
+
+typedef void (*EMJunkHookFunc) (EPlugin *plugin, EMJunkTarget *data);
+
+struct _EMJunkTarget {
+	CamelMimeMessage *m;
+	GError *error;
+};
+
+struct _EMJunkInterface {
+	CamelJunkPlugin camel;
+
+	/* The hook forwards calls from Camel to the EPlugin. */
+	EPluginHook *hook;
+
+	/* These are symbol names in the EPlugin. */
+	gchar *check_junk;
+	gchar *report_junk;
+	gchar *report_notjunk;
+	gchar *commit_reports;
+	gchar *validate_binary;
+
+	gchar *plugin_name;
+};
+
+GQuark em_junk_error_quark (void);
+
+G_END_DECLS
+
+#endif /* EM_JUNK_H */
diff --git a/modules/Makefile.am b/modules/Makefile.am
index 5030d2a..f792a4d 100644
--- a/modules/Makefile.am
+++ b/modules/Makefile.am
@@ -1,3 +1,11 @@
-SUBDIRS = addressbook calendar mail
+if ENABLE_MONO
+MONO_DIR = plugin-mono
+endif
+
+if ENABLE_PYTHON
+PYTHON_DIR = plugin-python
+endif
+
+SUBDIRS = addressbook calendar mail plugin-lib $(MONO_DIR) $(PYTHON_DIR)
 
 -include $(top_srcdir)/git.mk
diff --git a/modules/addressbook/Makefile.am b/modules/addressbook/Makefile.am
index 5ba744d..05b1698 100644
--- a/modules/addressbook/Makefile.am
+++ b/modules/addressbook/Makefile.am
@@ -34,6 +34,8 @@ libevolution_module_addressbook_la_SOURCES = \
 	autocompletion-config.h					\
 	eab-composer-util.c					\
 	eab-composer-util.h					\
+	e-book-config-hook.c					\
+	e-book-config-hook.h					\
 	e-book-shell-backend.c					\
 	e-book-shell-backend.h					\
 	e-book-shell-content.c					\
diff --git a/modules/addressbook/e-book-config-hook.c b/modules/addressbook/e-book-config-hook.c
new file mode 100644
index 0000000..d8c03a5
--- /dev/null
+++ b/modules/addressbook/e-book-config-hook.c
@@ -0,0 +1,67 @@
+/*
+ * e-book-config-hook.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#include "e-book-config-hook.h"
+
+#include "e-util/e-config.h"
+#include "addressbook/gui/widgets/eab-config.h"
+
+static const EConfigHookTargetMask no_masks[] = {
+	{ NULL }
+};
+
+static const EConfigHookTargetMap targets[] = {
+	{ "source", EAB_CONFIG_TARGET_SOURCE, no_masks },
+	{ NULL }
+};
+
+static void
+book_config_hook_class_init (EPluginHookClass *class)
+{
+	gint ii;
+
+	class->id = "org.gnome.evolution.addressbook.config:1.0";
+
+	for (ii = 0; targets[ii].type != NULL; ii++)
+		e_config_hook_class_add_target_map (
+			(EConfigHookClass *) class, &targets[ii]);
+}
+
+void
+e_book_config_hook_register_type (GTypeModule *type_module)
+{
+	const GTypeInfo type_info = {
+		sizeof (EConfigHookClass),
+		(GBaseInitFunc) NULL,
+		(GBaseFinalizeFunc) NULL,
+		(GClassInitFunc) book_config_hook_class_init,
+		(GClassFinalizeFunc) NULL,
+		NULL,  /* class_data */
+		sizeof (EConfigHook),
+		0,     /* n_preallocs */
+		(GInstanceInitFunc) NULL,
+		NULL   /* value_table */
+	};
+
+	g_type_module_register_type (
+		type_module, e_config_hook_get_type (),
+		"EBookConfigHook", &type_info, 0);
+}
diff --git a/plugins/python/python-plugin-loader.h b/modules/addressbook/e-book-config-hook.h
similarity index 54%
copy from plugins/python/python-plugin-loader.h
copy to modules/addressbook/e-book-config-hook.h
index 66bd8d5..a5d9e06 100644
--- a/plugins/python/python-plugin-loader.h
+++ b/modules/addressbook/e-book-config-hook.h
@@ -1,4 +1,6 @@
 /*
+ * e-book-config-hook.h
+ *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
@@ -13,35 +15,19 @@
  * License along with the program; if not, see <http://www.gnu.org/licenses/>
  *
  *
- * Authors:
- *		Johnny Jacob <jjohnny novell com>
- *
  * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
  *
  */
 
-#ifndef _ORG_GNOME_EVOLUTION_PYTHON_H
-#define _ORG_GNOME_EVOLUTION_PYTHON_H
-
-#include "e-util/e-plugin.h"
-
-typedef struct _EPluginPython EPluginPython;
-typedef struct _EPluginPythonClass EPluginPythonClass;
-
-struct _EPluginPython {
-	EPlugin plugin;
+#ifndef E_BOOK_CONFIG_HOOK_H
+#define E_BOOK_CONFIG_HOOK_H
 
-	struct _EPluginPythonPrivate *priv;
+#include <glib-object.h>
 
-	gchar *location;		/* location */
-	gchar *pClass;		/* handler class */
-        gchar *module_name;
-};
+G_BEGIN_DECLS
 
-struct _EPluginPythonClass {
-	EPluginClass plugin_class;
-};
+void e_book_config_hook_register_type (GTypeModule *type_module);
 
-gpointer org_gnome_evolution_python_get_type(gpointer a, gpointer b);
+G_END_DECLS
 
-#endif /* ! _ORG_GNOME_EVOLUTION_PYTHON_H */
+#endif /* E_BOOK_CONFIG_HOOK_H */
diff --git a/modules/addressbook/e-book-shell-backend.c b/modules/addressbook/e-book-shell-backend.c
index 87ac638..f96cb0d 100644
--- a/modules/addressbook/e-book-shell-backend.c
+++ b/modules/addressbook/e-book-shell-backend.c
@@ -39,7 +39,6 @@
 #include "addressbook/gui/contact-list-editor/e-contact-list-editor.h"
 #include "addressbook/importers/evolution-addressbook-importers.h"
 
-#include "eab-config.h"
 #include "addressbook-config.h"
 #include "autocompletion-config.h"
 
@@ -498,8 +497,6 @@ book_shell_backend_constructed (GObject *object)
 	book_shell_backend_init_importers ();
 	book_shell_backend_ensure_sources (shell_backend);
 
-	e_plugin_hook_register_type (eab_config_get_type ());
-
 	g_signal_connect_swapped (
 		shell, "handle-uri",
 		G_CALLBACK (book_shell_backend_handle_uri_cb),
diff --git a/modules/addressbook/evolution-module-addressbook.c b/modules/addressbook/evolution-module-addressbook.c
index 3089133..73b3634 100644
--- a/modules/addressbook/evolution-module-addressbook.c
+++ b/modules/addressbook/evolution-module-addressbook.c
@@ -19,6 +19,8 @@
  *
  */
 
+#include "e-book-config-hook.h"
+
 #include "e-book-shell-backend.h"
 #include "e-book-shell-content.h"
 #include "e-book-shell-sidebar.h"
@@ -33,6 +35,8 @@ e_module_load (GTypeModule *type_module)
 {
 	/* Register dynamically loaded types. */
 
+	e_book_config_hook_register_type (type_module);
+
 	e_book_shell_backend_register_type (type_module);
 	e_book_shell_content_register_type (type_module);
 	e_book_shell_sidebar_register_type (type_module);
diff --git a/modules/calendar/Makefile.am b/modules/calendar/Makefile.am
index 8f77116..490d42a 100644
--- a/modules/calendar/Makefile.am
+++ b/modules/calendar/Makefile.am
@@ -10,6 +10,12 @@ module_LTLIBRARIES =					\
 
 libevolution_module_calendar_la_SOURCES =		\
 	evolution-module-calendar.c			\
+	e-cal-attachment-handler.c			\
+	e-cal-attachment-handler.h			\
+	e-cal-config-hook.c				\
+	e-cal-config-hook.h				\
+	e-cal-event-hook.c				\
+	e-cal-event-hook.h				\
 	e-cal-shell-backend.c				\
 	e-cal-shell-backend.h				\
 	e-cal-shell-content.c				\
@@ -57,9 +63,6 @@ libevolution_module_calendar_la_SOURCES =		\
 	e-task-shell-view-private.c			\
 	e-task-shell-view-private.h
 
-# Removed from all three
-#	$(top_builddir)/a11y/calendar/libevolution-calendar-a11y.la
-
 libevolution_module_calendar_la_LIBADD =		\
 	$(top_builddir)/shell/libeshell.la		\
 	$(top_builddir)/calendar/gui/libevolution-calendar.la	\
diff --git a/calendar/gui/e-attachment-handler-calendar.c b/modules/calendar/e-cal-attachment-handler.c
similarity index 89%
rename from calendar/gui/e-attachment-handler-calendar.c
rename to modules/calendar/e-cal-attachment-handler.c
index 601d1f5..dd95cc5 100644
--- a/calendar/gui/e-attachment-handler-calendar.c
+++ b/modules/calendar/e-cal-attachment-handler.c
@@ -1,5 +1,5 @@
 /*
- * e-attachment-handler-calendar.c
+ * e-cal-attachment-handler.c
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -19,7 +19,7 @@
  *
  */
 
-#include "e-attachment-handler-calendar.h"
+#include "e-cal-attachment-handler.h"
 
 #include <glib/gi18n.h>
 #include <libical/ical.h>
@@ -29,13 +29,13 @@
 
 #include "calendar/common/authentication.h"
 
-#define E_ATTACHMENT_HANDLER_CALENDAR_GET_PRIVATE(obj) \
+#define E_CAL_ATTACHMENT_HANDLER_GET_PRIVATE(obj) \
 	(G_TYPE_INSTANCE_GET_PRIVATE \
-	((obj), E_TYPE_ATTACHMENT_HANDLER_CALENDAR, EAttachmentHandlerCalendarPrivate))
+	((obj), E_TYPE_CAL_ATTACHMENT_HANDLER, ECalAttachmentHandlerPrivate))
 
 typedef struct _ImportContext ImportContext;
 
-struct _EAttachmentHandlerCalendarPrivate {
+struct _ECalAttachmentHandlerPrivate {
 	gint placeholder;
 };
 
@@ -46,6 +46,7 @@ struct _ImportContext {
 };
 
 static gpointer parent_class;
+static GType cal_attachment_handler_type;
 
 static const gchar *ui =
 "<ui>"
@@ -388,7 +389,7 @@ static GtkActionEntry standard_entries[] = {
 };
 
 static void
-attachment_handler_calendar_update_actions (EAttachmentView *view)
+cal_attachment_handler_update_actions (EAttachmentView *view)
 {
 	EAttachment *attachment;
 	GtkAction *action;
@@ -431,7 +432,7 @@ exit:
 }
 
 static void
-attachment_handler_calendar_constructed (GObject *object)
+cal_attachment_handler_constructed (GObject *object)
 {
 	EAttachmentHandler *handler;
 	EAttachmentView *view;
@@ -461,51 +462,51 @@ attachment_handler_calendar_constructed (GObject *object)
 
 	g_signal_connect (
 		view, "update_actions",
-		G_CALLBACK (attachment_handler_calendar_update_actions),
+		G_CALLBACK (cal_attachment_handler_update_actions),
 		NULL);
 }
 
 static void
-attachment_handler_calendar_class_init (EAttachmentHandlerCalendarClass *class)
+cal_attachment_handler_class_init (ECalAttachmentHandlerClass *class)
 {
 	GObjectClass *object_class;
 
 	parent_class = g_type_class_peek_parent (class);
-	g_type_class_add_private (class, sizeof (EAttachmentHandlerCalendarPrivate));
+	g_type_class_add_private (class, sizeof (ECalAttachmentHandlerPrivate));
 
 	object_class = G_OBJECT_CLASS (class);
-	object_class->constructed = attachment_handler_calendar_constructed;
+	object_class->constructed = cal_attachment_handler_constructed;
 }
 
 static void
-attachment_handler_calendar_init (EAttachmentHandlerCalendar *handler)
+cal_attachment_handler_init (ECalAttachmentHandler *handler)
 {
-	handler->priv = E_ATTACHMENT_HANDLER_CALENDAR_GET_PRIVATE (handler);
+	handler->priv = E_CAL_ATTACHMENT_HANDLER_GET_PRIVATE (handler);
 }
 
 GType
-e_attachment_handler_calendar_get_type (void)
+e_cal_attachment_handler_get_type (void)
 {
-	static GType type = 0;
-
-	if (G_UNLIKELY (type == 0)) {
-		static const GTypeInfo type_info = {
-			sizeof (EAttachmentHandlerCalendarClass),
-			(GBaseInitFunc) NULL,
-			(GBaseFinalizeFunc) NULL,
-			(GClassInitFunc) attachment_handler_calendar_class_init,
-			(GClassFinalizeFunc) NULL,
-			NULL,  /* class_data */
-			sizeof (EAttachmentHandlerCalendar),
-			0,     /* n_preallocs */
-			(GInstanceInitFunc) attachment_handler_calendar_init,
-			NULL   /* value_table */
-		};
-
-		type = g_type_register_static (
-			E_TYPE_ATTACHMENT_HANDLER,
-			"EAttachmentHandlerCalendar", &type_info, 0);
-	}
+	return cal_attachment_handler_type;
+}
 
-	return type;
+void
+e_cal_attachment_handler_register_type (GTypeModule *type_module)
+{
+	static const GTypeInfo type_info = {
+		sizeof (ECalAttachmentHandlerClass),
+		(GBaseInitFunc) NULL,
+		(GBaseFinalizeFunc) NULL,
+		(GClassInitFunc) cal_attachment_handler_class_init,
+		(GClassFinalizeFunc) NULL,
+		NULL,  /* class_data */
+		sizeof (ECalAttachmentHandler),
+		0,     /* n_preallocs */
+		(GInstanceInitFunc) cal_attachment_handler_init,
+		NULL   /* value_table */
+	};
+
+	cal_attachment_handler_type = g_type_module_register_type (
+		type_module, E_TYPE_ATTACHMENT_HANDLER,
+		"ECalAttachmentHandler", &type_info, 0);
 }
diff --git a/modules/calendar/e-cal-attachment-handler.h b/modules/calendar/e-cal-attachment-handler.h
new file mode 100644
index 0000000..b792fbf
--- /dev/null
+++ b/modules/calendar/e-cal-attachment-handler.h
@@ -0,0 +1,67 @@
+/*
+ * e-cal-attachment-handler.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifndef E_CAL_ATTACHMENT_HANDLER_H
+#define E_CAL_ATTACHMENT_HANDLER_H
+
+#include <misc/e-attachment-handler.h>
+
+/* Standard GObject macros */
+#define E_TYPE_CAL_ATTACHMENT_HANDLER \
+	(e_cal_attachment_handler_get_type ())
+#define E_CAL_ATTACHMENT_HANDLER(obj) \
+	(G_TYPE_CHECK_INSTANCE_CAST \
+	((obj), E_TYPE_CAL_ATTACHMENT_HANDLER, ECalAttachmentHandler))
+#define E_CAL_ATTACHMENT_HANDLER_CLASS(cls) \
+	(G_TYPE_CHECK_CLASS_CAST \
+	((cls), E_TYPE_CAL_ATTACHMENT_HANDLER, ECalAttachmentHandlerClass))
+#define E_IS_CAL_ATTACHMENT_HANDLER(obj) \
+	(G_TYPE_CHECK_INSTANCE_TYPE \
+	((obj), E_TYPE_CAL_ATTACHMENT_HANDLER))
+#define E_IS_CAL_ATTACHMENT_HANDLER_CLASS(cls) \
+	(G_TYPE_CHECK_CLASS_TYPE \
+	((cls), E_TYPE_CAL_ATTACHMENT_HANDLER))
+#define E_CAL_ATTACHMENT_HANDLER_GET_CLASS(obj) \
+	(G_TYPE_INSTANCE_GET_CLASS \
+	((obj), E_TYPE_CAL_ATTACHMENT_HANDLER, ECalAttachmentHandlerClass))
+
+G_BEGIN_DECLS
+
+typedef struct _ECalAttachmentHandler ECalAttachmentHandler;
+typedef struct _ECalAttachmentHandlerClass ECalAttachmentHandlerClass;
+typedef struct _ECalAttachmentHandlerPrivate ECalAttachmentHandlerPrivate;
+
+struct _ECalAttachmentHandler {
+	EAttachmentHandler parent;
+	ECalAttachmentHandlerPrivate *priv;
+};
+
+struct _ECalAttachmentHandlerClass {
+	EAttachmentHandlerClass parent_class;
+};
+
+GType		e_cal_attachment_handler_get_type	(void);
+void		e_cal_attachment_handler_register_type
+						(GTypeModule *type_module);
+
+G_END_DECLS
+
+#endif /* E_CAL_ATTACHMENT_HANDLER_H */
diff --git a/modules/calendar/e-cal-config-hook.c b/modules/calendar/e-cal-config-hook.c
new file mode 100644
index 0000000..4a05224
--- /dev/null
+++ b/modules/calendar/e-cal-config-hook.c
@@ -0,0 +1,68 @@
+/*
+ * e-cal-config-hook.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#include "e-cal-config-hook.h"
+
+#include "e-util/e-config.h"
+#include "calendar/gui/e-cal-config.h"
+
+static const EConfigHookTargetMask no_masks[] = {
+	{ NULL }
+};
+
+static const EConfigHookTargetMap targets[] = {
+	{ "source", EC_CONFIG_TARGET_SOURCE, no_masks },
+	{ "prefs", EC_CONFIG_TARGET_PREFS, no_masks },
+	{ NULL }
+};
+
+static void
+cal_config_hook_class_init (EPluginHookClass *class)
+{
+	gint ii;
+
+	class->id = "org.gnome.evolution.calendar.config:1.0";
+
+	for (ii = 0; targets[ii].type != NULL; ii++)
+		e_config_hook_class_add_target_map (
+			(EConfigHookClass *) class, &targets[ii]);
+}
+
+void
+e_cal_config_hook_register_type (GTypeModule *type_module)
+{
+	const GTypeInfo type_info = {
+		sizeof (EConfigHookClass),
+		(GBaseInitFunc) NULL,
+		(GBaseFinalizeFunc) NULL,
+		(GClassInitFunc) cal_config_hook_class_init,
+		(GClassFinalizeFunc) NULL,
+		NULL,  /* class_data */
+		sizeof (EConfigHook),
+		0,     /* n_preallocs */
+		(GInstanceInitFunc) NULL,
+		NULL   /* value_table */
+	};
+
+	g_type_module_register_type (
+		type_module, e_config_hook_get_type (),
+		"ECalConfigHook", &type_info, 0);
+}
diff --git a/plugins/mono/mono-plugin.h b/modules/calendar/e-cal-config-hook.h
similarity index 51%
rename from plugins/mono/mono-plugin.h
rename to modules/calendar/e-cal-config-hook.h
index 8ea867e..a22ec56 100644
--- a/plugins/mono/mono-plugin.h
+++ b/modules/calendar/e-cal-config-hook.h
@@ -1,4 +1,5 @@
 /*
+ * e-cal-config-hook.h
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -14,38 +15,19 @@
  * License along with the program; if not, see <http://www.gnu.org/licenses/>
  *
  *
- * Authors:
- *		Sankar P <psankar novell com>
- *		Michael Zucchi <notzed novell com>
- *
  * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
  *
  */
 
-#ifndef _ORG_GNOME_EVOLUTION_MONO_H
-#define _ORG_GNOME_EVOLUTION_MONO_H
-
-#include "e-util/e-plugin.h"
-
-/* ********************************************************************** */
-/* This is ALL private */
-
-typedef struct _EPluginMono EPluginMono;
-typedef struct _EPluginMonoClass EPluginMonoClass;
-
-struct _EPluginMono {
-	EPlugin plugin;
+#ifndef E_CAL_CONFIG_HOOK_H
+#define E_CAL_CONFIG_HOOK_H
 
-	struct _EPluginMonoPrivate *priv;
+#include <glib-object.h>
 
-	gchar *location;		/* location */
-	gchar *handler;		/* handler class */
-};
+G_BEGIN_DECLS
 
-struct _EPluginMonoClass {
-	EPluginClass plugin_class;
-};
+void e_cal_config_hook_register_type (GTypeModule *type_module);
 
-gpointer org_gnome_evolution_mono_get_type(gpointer a, gpointer b);
+G_END_DECLS
 
-#endif /* ! _ORG_GNOME_EVOLUTION_MONO_H */
+#endif /* E_CAL_CONFIG_HOOK_H */
diff --git a/modules/calendar/e-cal-event-hook.c b/modules/calendar/e-cal-event-hook.c
new file mode 100644
index 0000000..b263727
--- /dev/null
+++ b/modules/calendar/e-cal-event-hook.c
@@ -0,0 +1,72 @@
+/*
+ * e-cal-event-hook.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#include "e-cal-event-hook.h"
+
+#include "e-util/e-event.h"
+#include "calendar/gui/e-cal-event.h"
+
+static const EEventHookTargetMask masks[] = {
+	{ "migration", E_CAL_EVENT_MODULE_MIGRATION },
+	{ NULL }
+};
+
+static const EEventHookTargetMap targets[] = {
+	{ "module", E_CAL_EVENT_TARGET_BACKEND, masks },
+	{ NULL }
+};
+
+static void
+cal_event_hook_class_init (EPluginHookClass *class)
+{
+	EEventHookClass *event_hook_class;
+	gint ii;
+
+	event_hook_class = (EEventHookClass *) class;
+	event_hook_class->event = (EEvent *) e_cal_event_peek ();
+
+	class->id = "org.gnome.evolution.calendar.events:1.0";
+
+	for (ii = 0; targets[ii].type != NULL; ii++)
+		e_event_hook_class_add_target_map (
+			(EEventHookClass *) class, &targets[ii]);
+}
+
+void
+e_cal_event_hook_register_type (GTypeModule *type_module)
+{
+	const GTypeInfo type_info = {
+		sizeof (EEventHookClass),
+		(GBaseInitFunc) NULL,
+		(GBaseFinalizeFunc) NULL,
+		(GClassInitFunc) cal_event_hook_class_init,
+		(GClassFinalizeFunc) NULL,
+		NULL,  /* class_data */
+		sizeof (EEventHook),
+		0,     /* n_preallocs */
+		(GInstanceInitFunc) NULL,
+		NULL   /* value_table */
+	};
+
+	g_type_module_register_type (
+		type_module, e_event_hook_get_type (),
+		"ECalEventHook", &type_info, 0);
+}
diff --git a/plugins/python/python-plugin-loader.h b/modules/calendar/e-cal-event-hook.h
similarity index 54%
copy from plugins/python/python-plugin-loader.h
copy to modules/calendar/e-cal-event-hook.h
index 66bd8d5..9dde31f 100644
--- a/plugins/python/python-plugin-loader.h
+++ b/modules/calendar/e-cal-event-hook.h
@@ -1,4 +1,6 @@
 /*
+ * e-cal-event-hook.h
+ *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
@@ -13,35 +15,19 @@
  * License along with the program; if not, see <http://www.gnu.org/licenses/>
  *
  *
- * Authors:
- *		Johnny Jacob <jjohnny novell com>
- *
  * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
  *
  */
 
-#ifndef _ORG_GNOME_EVOLUTION_PYTHON_H
-#define _ORG_GNOME_EVOLUTION_PYTHON_H
-
-#include "e-util/e-plugin.h"
-
-typedef struct _EPluginPython EPluginPython;
-typedef struct _EPluginPythonClass EPluginPythonClass;
-
-struct _EPluginPython {
-	EPlugin plugin;
+#ifndef E_CAL_EVENT_HOOK_H
+#define E_CAL_EVENT_HOOK_H
 
-	struct _EPluginPythonPrivate *priv;
+#include <glib-object.h>
 
-	gchar *location;		/* location */
-	gchar *pClass;		/* handler class */
-        gchar *module_name;
-};
+G_BEGIN_DECLS
 
-struct _EPluginPythonClass {
-	EPluginClass plugin_class;
-};
+void e_cal_event_hook_register_type (GTypeModule *type_module);
 
-gpointer org_gnome_evolution_python_get_type(gpointer a, gpointer b);
+G_END_DECLS
 
-#endif /* ! _ORG_GNOME_EVOLUTION_PYTHON_H */
+#endif /* E_CAL_EVENT_HOOK_H */
diff --git a/modules/calendar/e-cal-shell-backend.c b/modules/calendar/e-cal-shell-backend.c
index 6d9c744..5149574 100644
--- a/modules/calendar/e-cal-shell-backend.c
+++ b/modules/calendar/e-cal-shell-backend.c
@@ -38,9 +38,6 @@
 #include "calendar/common/authentication.h"
 #include "calendar/gui/calendar-config.h"
 #include "calendar/gui/comp-util.h"
-#include "calendar/gui/e-attachment-handler-calendar.h"
-#include "calendar/gui/e-cal-config.h"
-#include "calendar/gui/e-cal-event.h"
 #include "calendar/gui/dialogs/cal-prefs-dialog.h"
 #include "calendar/gui/dialogs/calendar-setup.h"
 #include "calendar/gui/dialogs/event-editor.h"
@@ -509,13 +506,6 @@ static GtkActionEntry source_entries[] = {
 };
 
 static void
-cal_shell_backend_init_hooks (void)
-{
-	e_plugin_hook_register_type (e_cal_config_hook_get_type ());
-	e_plugin_hook_register_type (e_cal_event_hook_get_type ());
-}
-
-static void
 cal_shell_backend_init_importers (void)
 {
 	EImportClass *import_class;
@@ -778,15 +768,12 @@ cal_shell_backend_constructed (GObject *object)
 		G_CALLBACK (cal_shell_backend_window_created_cb),
 		shell_backend);
 
-	cal_shell_backend_init_hooks ();
 	cal_shell_backend_init_importers ();
 
 	/* Initialize settings before initializing preferences,
 	 * since the preferences bind to the shell settings. */
 	e_cal_shell_backend_init_settings (shell);
 	cal_shell_backend_init_preferences (shell);
-
-	e_attachment_handler_calendar_get_type ();
 }
 
 static void
diff --git a/modules/calendar/evolution-module-calendar.c b/modules/calendar/evolution-module-calendar.c
index 63bf98e..f72e8a9 100644
--- a/modules/calendar/evolution-module-calendar.c
+++ b/modules/calendar/evolution-module-calendar.c
@@ -19,6 +19,11 @@
  *
  */
 
+#include "e-cal-attachment-handler.h"
+
+#include "e-cal-config-hook.h"
+#include "e-cal-event-hook.h"
+
 #include "e-cal-shell-backend.h"
 #include "e-cal-shell-content.h"
 #include "e-cal-shell-sidebar.h"
@@ -43,6 +48,11 @@ e_module_load (GTypeModule *type_module)
 {
 	/* Register dynamically loaded types. */
 
+	e_cal_attachment_handler_register_type (type_module);
+
+	e_cal_config_hook_register_type (type_module);
+	e_cal_event_hook_register_type (type_module);
+
 	e_cal_shell_backend_register_type (type_module);
 	e_cal_shell_content_register_type (type_module);
 	e_cal_shell_sidebar_register_type (type_module);
diff --git a/modules/mail/Makefile.am b/modules/mail/Makefile.am
index 866a137..4621618 100644
--- a/modules/mail/Makefile.am
+++ b/modules/mail/Makefile.am
@@ -12,8 +12,14 @@ module_LTLIBRARIES = libevolution-module-mail.la
 
 libevolution_module_mail_la_SOURCES =					\
 	evolution-module-mail.c						\
-	e-attachment-handler-mail.c					\
-	e-attachment-handler-mail.h					\
+	e-mail-attachment-handler.c					\
+	e-mail-attachment-handler.h					\
+	e-mail-config-hook.c						\
+	e-mail-config-hook.h						\
+	e-mail-event-hook.c						\
+	e-mail-event-hook.h						\
+	e-mail-junk-hook.c						\
+	e-mail-junk-hook.h						\
 	e-mail-shell-backend.c						\
 	e-mail-shell-backend.h						\
 	e-mail-shell-content.c						\
diff --git a/modules/mail/e-attachment-handler-mail.c b/modules/mail/e-mail-attachment-handler.c
similarity index 84%
rename from modules/mail/e-attachment-handler-mail.c
rename to modules/mail/e-mail-attachment-handler.c
index c17c97d..91fe5d3 100644
--- a/modules/mail/e-attachment-handler-mail.c
+++ b/modules/mail/e-mail-attachment-handler.c
@@ -1,5 +1,5 @@
 /*
- * e-attachment-handler-mail.c
+ * e-mail-attachment-handler.c
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -19,7 +19,7 @@
  *
  */
 
-#include "e-attachment-handler-mail.h"
+#include "e-mail-attachment-handler.h"
 
 #include <glib/gi18n.h>
 #include <camel/camel-folder.h>
@@ -29,15 +29,16 @@
 #include "mail/em-composer-utils.h"
 #include "mail/mail-tools.h"
 
-#define E_ATTACHMENT_HANDLER_MAIL_GET_PRIVATE(obj) \
+#define E_MAIL_ATTACHMENT_HANDLER_GET_PRIVATE(obj) \
 	(G_TYPE_INSTANCE_GET_PRIVATE \
-	((obj), E_TYPE_ATTACHMENT_HANDLER_MAIL, EAttachmentHandlerMailPrivate))
+	((obj), E_TYPE_MAIL_ATTACHMENT_HANDLER, EMailAttachmentHandlerPrivate))
 
-struct _EAttachmentHandlerMailPrivate {
+struct _EMailAttachmentHandlerPrivate {
 	gint placeholder;
 };
 
 static gpointer parent_class;
+static GType mail_attachment_handler_type;
 
 static const gchar *ui =
 "<ui>"
@@ -57,7 +58,7 @@ static GtkTargetEntry target_table[] = {
 };
 
 static void
-attachment_handler_mail_forward (GtkAction *action,
+mail_attachment_handler_forward (GtkAction *action,
                                  EAttachmentView *view)
 {
 	EAttachment *attachment;
@@ -79,7 +80,7 @@ attachment_handler_mail_forward (GtkAction *action,
 }
 
 static void
-attachment_handler_mail_reply_all (GtkAction *action,
+mail_attachment_handler_reply_all (GtkAction *action,
                                    EAttachmentView *view)
 {
 	EAttachment *attachment;
@@ -103,7 +104,7 @@ attachment_handler_mail_reply_all (GtkAction *action,
 }
 
 static void
-attachment_handler_mail_reply_sender (GtkAction *action,
+mail_attachment_handler_reply_sender (GtkAction *action,
                                       EAttachmentView *view)
 {
 	EAttachment *attachment;
@@ -133,25 +134,25 @@ static GtkActionEntry standard_entries[] = {
 	  N_("_Forward"),
 	  NULL,
 	  NULL,  /* XXX Add a tooltip! */
-	  G_CALLBACK (attachment_handler_mail_forward) },
+	  G_CALLBACK (mail_attachment_handler_forward) },
 
 	{ "mail-reply-all",
 	  "mail-reply-all",
 	  N_("Reply to _All"),
 	  NULL,
 	  NULL,  /* XXX Add a tooltip! */
-	  G_CALLBACK (attachment_handler_mail_reply_all) },
+	  G_CALLBACK (mail_attachment_handler_reply_all) },
 
 	{ "mail-reply-sender",
 	  "mail-reply-sender",
 	  N_("_Reply to Sender"),
 	  NULL,
 	  NULL,  /* XXX Add a tooltip! */
-	  G_CALLBACK (attachment_handler_mail_reply_sender) }
+	  G_CALLBACK (mail_attachment_handler_reply_sender) }
 };
 
 static void
-attachment_handler_mail_message_rfc822 (EAttachmentView *view,
+mail_attachment_handler_message_rfc822 (EAttachmentView *view,
                                         GdkDragContext *drag_context,
                                         gint x,
                                         gint y,
@@ -213,7 +214,7 @@ exit:
 }
 
 static void
-attachment_handler_mail_x_uid_list (EAttachmentView *view,
+mail_attachment_handler_x_uid_list (EAttachmentView *view,
                                     GdkDragContext *drag_context,
                                     gint x,
                                     gint y,
@@ -380,7 +381,7 @@ exit:
 }
 
 static void
-attachment_handler_mail_update_actions (EAttachmentView *view)
+mail_attachment_handler_update_actions (EAttachmentView *view)
 {
 	EAttachment *attachment;
 	CamelMimePart *mime_part;
@@ -413,7 +414,7 @@ exit:
 }
 
 static void
-attachment_handler_mail_constructed (GObject *object)
+mail_attachment_handler_constructed (GObject *object)
 {
 	EAttachmentHandler *handler;
 	EAttachmentView *view;
@@ -443,28 +444,28 @@ attachment_handler_mail_constructed (GObject *object)
 
 	g_signal_connect (
 		view, "update-actions",
-		G_CALLBACK (attachment_handler_mail_update_actions),
+		G_CALLBACK (mail_attachment_handler_update_actions),
 		NULL);
 
 	g_signal_connect (
 		view, "drag-data-received",
-		G_CALLBACK (attachment_handler_mail_message_rfc822),
+		G_CALLBACK (mail_attachment_handler_message_rfc822),
 		NULL);
 
 	g_signal_connect (
 		view, "drag-data-received",
-		G_CALLBACK (attachment_handler_mail_x_uid_list),
+		G_CALLBACK (mail_attachment_handler_x_uid_list),
 		NULL);
 }
 
 static GdkDragAction
-attachment_handler_mail_get_drag_actions (EAttachmentHandler *handler)
+mail_attachment_handler_get_drag_actions (EAttachmentHandler *handler)
 {
 	return GDK_ACTION_COPY;
 }
 
 static const GtkTargetEntry *
-attachment_handler_mail_get_target_table (EAttachmentHandler *handler,
+mail_attachment_handler_get_target_table (EAttachmentHandler *handler,
                                           guint *n_targets)
 {
 	if (n_targets != NULL)
@@ -474,51 +475,51 @@ attachment_handler_mail_get_target_table (EAttachmentHandler *handler,
 }
 
 static void
-attachment_handler_mail_class_init (EAttachmentHandlerMailClass *class)
+mail_attachment_handler_class_init (EMailAttachmentHandlerClass *class)
 {
 	GObjectClass *object_class;
 	EAttachmentHandlerClass *handler_class;
 
 	parent_class = g_type_class_peek_parent (class);
-	g_type_class_add_private (class, sizeof (EAttachmentHandlerMailPrivate));
+	g_type_class_add_private (class, sizeof (EMailAttachmentHandlerPrivate));
 
 	object_class = G_OBJECT_CLASS (class);
-	object_class->constructed = attachment_handler_mail_constructed;
+	object_class->constructed = mail_attachment_handler_constructed;
 
 	handler_class = E_ATTACHMENT_HANDLER_CLASS (class);
-	handler_class->get_drag_actions = attachment_handler_mail_get_drag_actions;
-	handler_class->get_target_table = attachment_handler_mail_get_target_table;
+	handler_class->get_drag_actions = mail_attachment_handler_get_drag_actions;
+	handler_class->get_target_table = mail_attachment_handler_get_target_table;
 }
 
 static void
-attachment_handler_mail_init (EAttachmentHandlerMail *handler)
+mail_attachment_handler_init (EMailAttachmentHandler *handler)
 {
-	handler->priv = E_ATTACHMENT_HANDLER_MAIL_GET_PRIVATE (handler);
+	handler->priv = E_MAIL_ATTACHMENT_HANDLER_GET_PRIVATE (handler);
 }
 
 GType
-e_attachment_handler_mail_get_type (void)
+e_mail_attachment_handler_get_type (void)
 {
-	static GType type = 0;
-
-	if (G_UNLIKELY (type == 0)) {
-		static const GTypeInfo type_info = {
-			sizeof (EAttachmentHandlerMailClass),
-			(GBaseInitFunc) NULL,
-			(GBaseFinalizeFunc) NULL,
-			(GClassInitFunc) attachment_handler_mail_class_init,
-			(GClassFinalizeFunc) NULL,
-			NULL,  /* class_data */
-			sizeof (EAttachmentHandlerMail),
-			0,     /* n_preallocs */
-			(GInstanceInitFunc) attachment_handler_mail_init,
-			NULL   /* value_table */
-		};
-
-		type = g_type_register_static (
-			E_TYPE_ATTACHMENT_HANDLER,
-			"EAttachmentHandlerMail", &type_info, 0);
-	}
+	return mail_attachment_handler_type;
+}
 
-	return type;
+void
+e_mail_attachment_handler_register_type (GTypeModule *type_module)
+{
+	static const GTypeInfo type_info = {
+		sizeof (EMailAttachmentHandlerClass),
+		(GBaseInitFunc) NULL,
+		(GBaseFinalizeFunc) NULL,
+		(GClassInitFunc) mail_attachment_handler_class_init,
+		(GClassFinalizeFunc) NULL,
+		NULL,  /* class_data */
+		sizeof (EMailAttachmentHandler),
+		0,     /* n_preallocs */
+		(GInstanceInitFunc) mail_attachment_handler_init,
+		NULL   /* value_table */
+	};
+
+	mail_attachment_handler_type = g_type_module_register_type (
+		type_module, E_TYPE_ATTACHMENT_HANDLER,
+		"EMailAttachmentHandler", &type_info, 0);
 }
diff --git a/modules/mail/e-mail-attachment-handler.h b/modules/mail/e-mail-attachment-handler.h
new file mode 100644
index 0000000..13032b4
--- /dev/null
+++ b/modules/mail/e-mail-attachment-handler.h
@@ -0,0 +1,67 @@
+/*
+ * e-mail-attachment-handler.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifndef E_MAIL_ATTACHMENT_HANDLER_H
+#define E_MAIL_ATTACHMENT_HANDLER_H
+
+#include <widgets/misc/e-attachment-handler.h>
+
+/* Standard GObject macros */
+#define E_TYPE_MAIL_ATTACHMENT_HANDLER \
+	(e_mail_attachment_handler_get_type ())
+#define E_MAIL_ATTACHMENT_HANDLER(obj) \
+	(G_TYPE_CHECK_INSTANCE_CAST \
+	((obj), E_TYPE_MAIL_ATTACHMENT_HANDLER, EMailAttachmentHandler))
+#define E_MAIL_ATTACHMENT_HANDLER_CLASS(cls) \
+	(G_TYPE_CHECK_CLASS_CAST \
+	((cls), E_TYPE_MAIL_ATTACHMENT_HANDLER, EMailAttachmentHandlerClass))
+#define E_IS_MAIL_ATTACHMENT_HANDLER(obj) \
+	(G_TYPE_CHECK_INSTANCE_TYPE \
+	((obj), E_TYPE_MAIL_ATTACHMENT_HANDLER))
+#define E_IS_MAIL_ATTACHMENT_HANDLER_CLASS(cls) \
+	(G_TYPE_CHECK_CLASS_TYPE \
+	((cls), E_TYPE_MAIL_ATTACHMENT_HANDLER))
+#define E_MAIL_ATTACHMENT_HANDLER_GET_CLASS(obj) \
+	(G_TYPE_INSTANCE_GET_CLASS \
+	((obj), E_TYPE_MAIL_ATTACHMENT_HANDLER, EMailAttachmentHandlerClass))
+
+G_BEGIN_DECLS
+
+typedef struct _EMailAttachmentHandler EMailAttachmentHandler;
+typedef struct _EMailAttachmentHandlerClass EMailAttachmentHandlerClass;
+typedef struct _EMailAttachmentHandlerPrivate EMailAttachmentHandlerPrivate;
+
+struct _EMailAttachmentHandler {
+	EAttachmentHandler parent;
+	EMailAttachmentHandlerPrivate *priv;
+};
+
+struct _EMailAttachmentHandlerClass {
+	EAttachmentHandlerClass parent_class;
+};
+
+GType		e_mail_attachment_handler_get_type	(void);
+void		e_mail_attachment_handler_register_type
+						(GTypeModule *type_module);
+
+G_END_DECLS
+
+#endif /* E_MAIL_ATTACHMENT_HANDLER_H */
diff --git a/modules/mail/e-mail-config-hook.c b/modules/mail/e-mail-config-hook.c
new file mode 100644
index 0000000..4b37a6b
--- /dev/null
+++ b/modules/mail/e-mail-config-hook.c
@@ -0,0 +1,69 @@
+/*
+ * e-mail-config-hook.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#include "e-mail-config-hook.h"
+
+#include "e-util/e-config.h"
+#include "mail/em-config.h"
+
+static const EConfigHookTargetMask no_masks[] = {
+	{ NULL }
+};
+
+static const EConfigHookTargetMap targets[] = {
+	{ "folder", EM_CONFIG_TARGET_FOLDER, no_masks },
+	{ "prefs", EM_CONFIG_TARGET_PREFS, no_masks },
+	{ "account", EM_CONFIG_TARGET_ACCOUNT, no_masks },
+	{ NULL }
+};
+
+static void
+mail_config_hook_class_init (EPluginHookClass *class)
+{
+	gint ii;
+
+	class->id = "org.gnome.evolution.mail.config:1.0";
+
+	for (ii = 0; targets[ii].type != NULL; ii++)
+		e_config_hook_class_add_target_map (
+			(EConfigHookClass *) class, &targets[ii]);
+}
+
+void
+e_mail_config_hook_register_type (GTypeModule *type_module)
+{
+	const GTypeInfo type_info = {
+		sizeof (EConfigHookClass),
+		(GBaseInitFunc) NULL,
+		(GBaseFinalizeFunc) NULL,
+		(GClassInitFunc) mail_config_hook_class_init,
+		(GClassFinalizeFunc) NULL,
+		NULL,  /* class_data */
+		sizeof (EConfigHook),
+		0,     /* n_preallocs */
+		(GInstanceInitFunc) NULL,
+		NULL   /* value_table */
+	};
+
+	g_type_module_register_type (
+		type_module, e_config_hook_get_type (),
+		"EMailConfigHook", &type_info, 0);
+}
diff --git a/plugins/python/python-plugin-loader.h b/modules/mail/e-mail-config-hook.h
similarity index 54%
copy from plugins/python/python-plugin-loader.h
copy to modules/mail/e-mail-config-hook.h
index 66bd8d5..e54ad81 100644
--- a/plugins/python/python-plugin-loader.h
+++ b/modules/mail/e-mail-config-hook.h
@@ -1,4 +1,6 @@
 /*
+ * e-mail-config-hook.h
+ *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
@@ -13,35 +15,19 @@
  * License along with the program; if not, see <http://www.gnu.org/licenses/>
  *
  *
- * Authors:
- *		Johnny Jacob <jjohnny novell com>
- *
  * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
  *
  */
 
-#ifndef _ORG_GNOME_EVOLUTION_PYTHON_H
-#define _ORG_GNOME_EVOLUTION_PYTHON_H
-
-#include "e-util/e-plugin.h"
-
-typedef struct _EPluginPython EPluginPython;
-typedef struct _EPluginPythonClass EPluginPythonClass;
-
-struct _EPluginPython {
-	EPlugin plugin;
+#ifndef E_MAIL_CONFIG_HOOK_H
+#define E_MAIL_CONFIG_HOOK_H
 
-	struct _EPluginPythonPrivate *priv;
+#include <glib-object.h>
 
-	gchar *location;		/* location */
-	gchar *pClass;		/* handler class */
-        gchar *module_name;
-};
+G_BEGIN_DECLS
 
-struct _EPluginPythonClass {
-	EPluginClass plugin_class;
-};
+void e_mail_config_hook_register_type (GTypeModule *type_module);
 
-gpointer org_gnome_evolution_python_get_type(gpointer a, gpointer b);
+G_END_DECLS
 
-#endif /* ! _ORG_GNOME_EVOLUTION_PYTHON_H */
+#endif /* E_MAIL_CONFIG_HOOK_H */
diff --git a/modules/mail/e-mail-event-hook.c b/modules/mail/e-mail-event-hook.c
new file mode 100644
index 0000000..a6be6d2
--- /dev/null
+++ b/modules/mail/e-mail-event-hook.c
@@ -0,0 +1,93 @@
+/*
+ * e-mail-event-hook.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#include "e-mail-event-hook.h"
+
+#include "e-util/e-event.h"
+#include "mail/em-event.h"
+
+static const EEventHookTargetMask folder_masks[] = {
+	{ "newmail", EM_EVENT_FOLDER_NEWMAIL },
+	{ NULL }
+};
+
+static const EEventHookTargetMask composer_masks[] = {
+	{ "sendoption", EM_EVENT_COMPOSER_SEND_OPTION },
+	{ NULL }
+};
+
+static const EEventHookTargetMask message_masks[] = {
+	{ "replyall", EM_EVENT_MESSAGE_REPLY_ALL },
+	{ "reply", EM_EVENT_MESSAGE_REPLY },
+	{ NULL }
+};
+
+static const EEventHookTargetMask send_receive_masks[] = {
+	{ "sendreceive", EM_EVENT_SEND_RECEIVE },
+	{ NULL }
+};
+
+static const EEventHookTargetMask custom_icon_masks[] = {
+	{ "customicon", EM_EVENT_CUSTOM_ICON },
+	{ NULL }
+};
+
+static const EEventHookTargetMap targets[] = {
+	{ "folder", EM_EVENT_TARGET_FOLDER, folder_masks },
+	{ "message", EM_EVENT_TARGET_MESSAGE, message_masks },
+	{ "composer", EM_EVENT_TARGET_COMPOSER, composer_masks },
+	{ "sendreceive", EM_EVENT_TARGET_SEND_RECEIVE, send_receive_masks },
+	{ "customicon", EM_EVENT_TARGET_CUSTOM_ICON, custom_icon_masks },
+	{ NULL }
+};
+
+static void
+mail_event_hook_class_init (EPluginHookClass *class)
+{
+	gint ii;
+
+	class->id = "org.gnome.evolution.mail.events:1.0";
+
+	for (ii = 0; targets[ii].type != NULL; ii++)
+		e_event_hook_class_add_target_map (
+			(EEventHookClass *) class, &targets[ii]);
+}
+
+void
+e_mail_event_hook_register_type (GTypeModule *type_module)
+{
+	const GTypeInfo type_info = {
+		sizeof (EEventHookClass),
+		(GBaseInitFunc) NULL,
+		(GBaseFinalizeFunc) NULL,
+		(GClassInitFunc) mail_event_hook_class_init,
+		(GClassFinalizeFunc) NULL,
+		NULL,  /* class_data */
+		sizeof (EEventHook),
+		0,     /* n_preallocs */
+		(GInstanceInitFunc) NULL,
+		NULL   /* value_table */
+	};
+
+	g_type_module_register_type (
+		type_module, e_event_hook_get_type (),
+		"EMailEventHook", &type_info, 0);
+}
diff --git a/plugins/python/python-plugin-loader.h b/modules/mail/e-mail-event-hook.h
similarity index 54%
copy from plugins/python/python-plugin-loader.h
copy to modules/mail/e-mail-event-hook.h
index 66bd8d5..9cad43a 100644
--- a/plugins/python/python-plugin-loader.h
+++ b/modules/mail/e-mail-event-hook.h
@@ -1,4 +1,6 @@
 /*
+ * e-mail-event-hook.h
+ *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
@@ -13,35 +15,19 @@
  * License along with the program; if not, see <http://www.gnu.org/licenses/>
  *
  *
- * Authors:
- *		Johnny Jacob <jjohnny novell com>
- *
  * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
  *
  */
 
-#ifndef _ORG_GNOME_EVOLUTION_PYTHON_H
-#define _ORG_GNOME_EVOLUTION_PYTHON_H
-
-#include "e-util/e-plugin.h"
-
-typedef struct _EPluginPython EPluginPython;
-typedef struct _EPluginPythonClass EPluginPythonClass;
-
-struct _EPluginPython {
-	EPlugin plugin;
+#ifndef E_MAIL_EVENT_HOOK_H
+#define E_MAIL_EVENT_HOOK_H
 
-	struct _EPluginPythonPrivate *priv;
+#include <glib-object.h>
 
-	gchar *location;		/* location */
-	gchar *pClass;		/* handler class */
-        gchar *module_name;
-};
+G_BEGIN_DECLS
 
-struct _EPluginPythonClass {
-	EPluginClass plugin_class;
-};
+void e_mail_event_hook_register_type (GTypeModule *type_module);
 
-gpointer org_gnome_evolution_python_get_type(gpointer a, gpointer b);
+G_END_DECLS
 
-#endif /* ! _ORG_GNOME_EVOLUTION_PYTHON_H */
+#endif /* E_MAIL_EVENT_HOOK_H */
diff --git a/modules/mail/e-mail-junk-hook.c b/modules/mail/e-mail-junk-hook.c
new file mode 100644
index 0000000..2687223
--- /dev/null
+++ b/modules/mail/e-mail-junk-hook.c
@@ -0,0 +1,323 @@
+/*
+ * e-mail-junk-hook.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#include "e-mail-junk-hook.h"
+
+#include <glib/gi18n.h>
+#include <camel/camel-junk-plugin.h>
+
+#include "e-util/e-error.h"
+#include "mail/em-junk.h"
+#include "mail/em-utils.h"
+#include "mail/mail-session.h"
+
+#define E_MAIL_JUNK_HOOK_GET_PRIVATE(obj) \
+	(G_TYPE_INSTANCE_GET_PRIVATE \
+	((obj), E_TYPE_MAIL_JUNK_HOOK, EMailJunkHookPrivate))
+
+struct _EMailJunkHookPrivate {
+	EMJunkInterface interface;
+};
+
+struct ErrorData {
+	const gchar *error_message;
+	GError *error;
+};
+
+static gpointer parent_class;
+static GType mail_junk_hook_type;
+
+static gboolean
+mail_junk_hook_idle_cb (struct ErrorData *data)
+{
+	GtkWidget *widget;
+
+	widget = e_error_new (
+		NULL, data->error_message, data->error->message, NULL);
+	em_utils_show_error_silent (widget);
+
+	g_error_free (data->error);
+	g_slice_free (struct ErrorData, data);
+
+	return FALSE;
+}
+
+static void
+mail_junk_hook_error (const gchar *error_message,
+                      GError *error)
+{
+	struct ErrorData *data;
+
+	g_return_if_fail (error != NULL);
+
+	data = g_slice_new (struct ErrorData);
+	data->error_message = error_message;
+	data->error = error;
+
+	g_idle_add ((GSourceFunc) mail_junk_hook_idle_cb, data);
+}
+
+static const gchar *
+mail_junk_hook_get_name (CamelJunkPlugin *junk_plugin)
+{
+	EMJunkInterface *interface;
+
+	interface = (EMJunkInterface *) junk_plugin;
+
+	if (!interface->hook->plugin->enabled)
+		return _("None");
+
+	return interface->hook->plugin->name;
+}
+
+static void
+mail_junk_hook_plugin_init (CamelJunkPlugin *junk_plugin)
+{
+	EMJunkInterface *interface;
+	EPluginClass *class;
+
+	interface = (EMJunkInterface *) junk_plugin;
+
+	class = E_PLUGIN_GET_CLASS (interface->hook->plugin);
+	g_return_if_fail (class->enable != NULL);
+
+	class->enable (interface->hook->plugin, 1);
+}
+
+static gboolean
+mail_junk_hook_check_junk (CamelJunkPlugin *junk_plugin,
+                           CamelMimeMessage *mime_message)
+{
+	EMJunkTarget target = { mime_message, NULL };
+	EMJunkInterface *interface;
+	gpointer result;
+
+	interface = (EMJunkInterface *) junk_plugin;
+
+	if (!interface->hook->plugin->enabled)
+		return FALSE;
+
+	result = e_plugin_invoke (
+		interface->hook->plugin,
+		interface->check_junk, &target);
+
+	if (target.error != NULL)
+		mail_junk_hook_error ("mail:junk-check-error", target.error);
+
+	return (result != NULL);
+}
+
+static void
+mail_junk_hook_report_junk (CamelJunkPlugin *junk_plugin,
+                            CamelMimeMessage *mime_message)
+{
+	EMJunkTarget target = { mime_message, NULL };
+	EMJunkInterface *interface;
+
+	interface = (EMJunkInterface *) junk_plugin;
+
+	if (!interface->hook->plugin->enabled)
+		return;
+
+	e_plugin_invoke (
+		interface->hook->plugin,
+		interface->report_junk, &target);
+
+	if (target.error != NULL)
+		mail_junk_hook_error ("mail:junk-report-error", target.error);
+}
+
+static void
+mail_junk_hook_report_notjunk (CamelJunkPlugin *junk_plugin,
+                               CamelMimeMessage *mime_message)
+{
+	EMJunkTarget target = { mime_message, NULL };
+	EMJunkInterface *interface;
+
+	interface = (EMJunkInterface *) junk_plugin;
+
+	if (!interface->hook->plugin->enabled)
+		return;
+
+	e_plugin_invoke (
+		interface->hook->plugin,
+		interface->report_notjunk, &target);
+
+	if (target.error != NULL)
+		mail_junk_hook_error (
+			"mail:junk-not-report-error", target.error);
+}
+
+static void
+mail_junk_hook_commit_reports (CamelJunkPlugin *junk_plugin)
+{
+	EMJunkInterface *interface;
+
+	interface = (EMJunkInterface *) junk_plugin;
+
+	if (!interface->hook->plugin->enabled)
+		return;
+
+	e_plugin_invoke (
+		interface->hook->plugin,
+		interface->commit_reports, NULL);
+}
+
+static void
+mail_junk_hook_finalize (GObject *object)
+{
+	EMailJunkHookPrivate *priv;
+
+	priv = E_MAIL_JUNK_HOOK_GET_PRIVATE (object);
+
+	g_free (priv->interface.check_junk);
+	g_free (priv->interface.report_junk);
+	g_free (priv->interface.report_notjunk);
+	g_free (priv->interface.commit_reports);
+	g_free (priv->interface.validate_binary);
+	g_free (priv->interface.plugin_name);
+
+	/* Chain up to parent's finalize() method. */
+	G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+static gint
+mail_junk_hook_construct (EPluginHook *hook,
+                          EPlugin *plugin,
+                          xmlNodePtr node)
+{
+	EMailJunkHookPrivate *priv;
+	gchar *property;
+
+	priv = E_MAIL_JUNK_HOOK_GET_PRIVATE (hook);
+
+	/* Chain up to parent's construct() method. */
+	if (E_PLUGIN_HOOK_CLASS (parent_class)->construct (hook, plugin, node) == -1)
+		return -1;
+
+	if (!plugin->enabled)
+		return -1;
+
+	node = xmlFirstElementChild (node);
+
+	if (node == NULL)
+		return -1;
+
+	if (g_strcmp0 ((gchar *) node->name, "interface") != 0)
+		return -1;
+
+	property = e_plugin_xml_prop (node, "check_junk");
+	priv->interface.check_junk = property;
+
+	property = e_plugin_xml_prop (node, "report_junk");
+	priv->interface.report_junk = property;
+
+	property = e_plugin_xml_prop (node, "report_non_junk");
+	priv->interface.report_notjunk = property;
+
+	property = e_plugin_xml_prop (node, "commit_reports");
+	priv->interface.commit_reports = property;
+
+	property = e_plugin_xml_prop (node, "validate_binary");
+	priv->interface.validate_binary = property;
+
+	property = e_plugin_xml_prop (node, "name");
+	priv->interface.plugin_name = property;
+
+	if (priv->interface.check_junk == NULL)
+		return -1;
+
+	if (priv->interface.report_junk == NULL)
+		return -1;
+
+	if (priv->interface.report_notjunk == NULL)
+		return -1;
+
+	if (priv->interface.commit_reports == NULL)
+		return -1;
+
+	mail_session_add_junk_plugin (
+		priv->interface.plugin_name, &priv->interface.camel);
+
+	return 0;
+}
+
+static void
+mail_junk_hook_class_init (EMailJunkHookClass *class)
+{
+	GObjectClass *object_class;
+	EPluginHookClass *plugin_hook_class;
+
+	parent_class = g_type_class_peek_parent (class);
+	g_type_class_add_private (class, sizeof (EMailJunkHookPrivate));
+
+	object_class = G_OBJECT_CLASS (class);
+	object_class->finalize = mail_junk_hook_finalize;
+
+	plugin_hook_class = E_PLUGIN_HOOK_CLASS (class);
+	plugin_hook_class->construct = mail_junk_hook_construct;
+	plugin_hook_class->id = "org.gnome.evolution.mail.junk:1.0";
+}
+
+static void
+mail_junk_hook_init (EMailJunkHook *mail_junk_hook)
+{
+	EMJunkInterface *interface;
+
+	mail_junk_hook->priv = E_MAIL_JUNK_HOOK_GET_PRIVATE (mail_junk_hook);
+
+	interface = &mail_junk_hook->priv->interface;
+	interface->camel.get_name = mail_junk_hook_get_name;
+	interface->camel.api_version = 1;
+	interface->camel.check_junk = mail_junk_hook_check_junk;
+	interface->camel.report_junk = mail_junk_hook_report_junk;
+	interface->camel.report_notjunk = mail_junk_hook_report_notjunk;
+	interface->camel.commit_reports = mail_junk_hook_commit_reports;
+	interface->camel.init = mail_junk_hook_plugin_init;
+	interface->hook = E_PLUGIN_HOOK (mail_junk_hook);
+}
+
+GType
+e_mail_junk_hook_get_type (void)
+{
+	return mail_junk_hook_type;
+}
+
+void
+e_mail_junk_hook_register_type (GTypeModule *type_module)
+{
+	const GTypeInfo type_info = {
+		sizeof (EMailJunkHookClass),
+		(GBaseInitFunc) NULL,
+		(GBaseFinalizeFunc) NULL,
+		(GClassInitFunc) mail_junk_hook_class_init,
+		(GClassFinalizeFunc) NULL,
+		NULL,  /* class_data */
+		sizeof (EMailJunkHook),
+		0,     /* n_preallocs */
+		(GInstanceInitFunc) mail_junk_hook_init,
+		NULL   /* value_table */
+	};
+
+	mail_junk_hook_type = g_type_module_register_type (
+		type_module, E_TYPE_PLUGIN_HOOK,
+		"EMailJunkHook", &type_info, 0);
+}
diff --git a/modules/mail/e-mail-junk-hook.h b/modules/mail/e-mail-junk-hook.h
new file mode 100644
index 0000000..f5882e6
--- /dev/null
+++ b/modules/mail/e-mail-junk-hook.h
@@ -0,0 +1,66 @@
+/*
+ * e-mail-junk-hook.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifndef E_MAIL_JUNK_HOOK_H
+#define E_MAIL_JUNK_HOOK_H
+
+#include <e-util/e-plugin.h>
+
+/* Standard GObject macros */
+#define E_TYPE_MAIL_JUNK_HOOK \
+	(e_mail_junk_hook_get_type ())
+#define E_MAIL_JUNK_HOOK(obj) \
+	(G_TYPE_CHECK_INSTANCE_CAST \
+	((obj), E_TYPE_MAIL_JUNK_HOOK, EMailJunkHook))
+#define E_MAIL_JUNK_HOOK_CLASS(cls) \
+	(G_TYPE_CHECK_CLASS_CAST \
+	((cls), E_TYPE_MAIL_JUNK_HOOK, EMailJunkHookClass))
+#define E_IS_MAIL_JUNK_HOOK(obj) \
+	(G_TYPE_CHECK_INSTANCE_TYPE \
+	((obj), E_TYPE_MAIL_JUNK_HOOK))
+#define E_IS_MAIL_JUNK_HOOK_CLASS(cls) \
+	(G_TYPE_CHECK_CLASS_TYPE \
+	((cls), E_TYPE_MAIL_JUNK_HOOK))
+#define E_MAIL_JUNK_HOOK_GET_CLASS(obj) \
+	(G_TYPE_INSTANCE_GET_CLASS \
+	((obj), E_TYPE_MAIL_JUNK_HOOK, EMailJunkHookClass))
+
+G_BEGIN_DECLS
+
+typedef struct _EMailJunkHook EMailJunkHook;
+typedef struct _EMailJunkHookClass EMailJunkHookClass;
+typedef struct _EMailJunkHookPrivate EMailJunkHookPrivate;
+
+struct _EMailJunkHook {
+	EPluginHook parent;
+	EMailJunkHookPrivate *priv;
+};
+
+struct _EMailJunkHookClass {
+	EPluginHookClass parent_class;
+};
+
+GType		e_mail_junk_hook_get_type	(void);
+void		e_mail_junk_hook_register_type	(GTypeModule *type_module);
+
+G_END_DECLS
+
+#endif /* E_MAIL_JUNK_HOOK_H */
diff --git a/modules/mail/e-mail-shell-backend.c b/modules/mail/e-mail-shell-backend.c
index 2d6e1a9..fd1e726 100644
--- a/modules/mail/e-mail-shell-backend.c
+++ b/modules/mail/e-mail-shell-backend.c
@@ -42,7 +42,6 @@
 #include "e-mail-shell-sidebar.h"
 #include "e-mail-shell-view.h"
 
-#include "e-attachment-handler-mail.h"
 #include "e-mail-browser.h"
 #include "e-mail-local.h"
 #include "e-mail-reader.h"
@@ -51,12 +50,9 @@
 #include "em-account-prefs.h"
 #include "em-composer-prefs.h"
 #include "em-composer-utils.h"
-#include "em-config.h"
-#include "em-event.h"
 #include "em-folder-utils.h"
 #include "em-format-hook.h"
 #include "em-format-html-display.h"
-#include "em-junk-hook.h"
 #include "em-mailer-prefs.h"
 #include "em-network-prefs.h"
 #include "em-utils.h"
@@ -85,22 +81,6 @@ static GType mail_shell_backend_type;
 extern gint camel_application_is_exiting;
 
 static void
-mail_shell_backend_init_hooks (void)
-{
-	e_plugin_hook_register_type (em_config_hook_get_type ());
-	e_plugin_hook_register_type (em_event_hook_get_type ());
-	e_plugin_hook_register_type (em_junk_hook_get_type ());
-
-	/* EMFormat classes must be registered before EMFormatHook. */
-	em_format_hook_register_type (em_format_get_type ());
-	em_format_hook_register_type (em_format_html_get_type ());
-	em_format_hook_register_type (em_format_html_display_get_type ());
-	e_plugin_hook_register_type (em_format_hook_get_type ());
-
-	em_junk_hook_register_type (emj_get_type ());
-}
-
-static void
 mail_shell_backend_init_importers (void)
 {
 	EImportClass *import_class;
@@ -812,10 +792,15 @@ mail_shell_backend_constructed (GObject *object)
 	/* This also initializes Camel, so it needs to happen early. */
 	mail_session_init (shell_backend);
 
-	mail_shell_backend_init_hooks ();
-	mail_shell_backend_init_importers ();
+	/* Register format types for EMFormatHook. */
+	em_format_hook_register_type (em_format_get_type ());
+	em_format_hook_register_type (em_format_html_get_type ());
+	em_format_hook_register_type (em_format_html_display_get_type ());
+
+	/* Register plugin hook types. */
+	em_format_hook_get_type ();
 
-	e_attachment_handler_mail_get_type ();
+	mail_shell_backend_init_importers ();
 
 	g_signal_connect (
 		shell, "notify::online",
diff --git a/modules/mail/em-mailer-prefs.c b/modules/mail/em-mailer-prefs.c
index e2c956e..621dae4 100644
--- a/modules/mail/em-mailer-prefs.c
+++ b/modules/mail/em-mailer-prefs.c
@@ -47,7 +47,7 @@
 
 #include "e-mail-label-manager.h"
 #include "mail-config.h"
-#include "em-junk-hook.h"
+#include "em-junk.h"
 #include "em-config.h"
 #include "mail-session.h"
 
@@ -710,17 +710,17 @@ junk_plugin_changed (GtkWidget *combo, EMMailerPrefs *prefs)
 
 	gconf_client_set_string (prefs->gconf, "/apps/evolution/mail/junk/default_plugin", def_plugin, NULL);
 	while (plugins) {
-		struct _EMJunkHookItem *item = plugins->data;;
+		EMJunkInterface *iface = plugins->data;
 
-		if (item->plugin_name && def_plugin && !strcmp (item->plugin_name, def_plugin)) {
+		if (iface->plugin_name && def_plugin && !strcmp (iface->plugin_name, def_plugin)) {
 			gboolean status;
 
-			session->junk_plugin = CAMEL_JUNK_PLUGIN (&(item->csp));
-			status = e_plugin_invoke (item->hook->hook.plugin, item->validate_binary, NULL) != NULL;
+			session->junk_plugin = CAMEL_JUNK_PLUGIN (&iface->camel);
+			status = e_plugin_invoke (iface->hook->plugin, iface->validate_binary, NULL) != NULL;
 			if ((gboolean)status == TRUE) {
 				gchar *text, *html;
 				gtk_image_set_from_stock (prefs->plugin_image, "gtk-dialog-info", GTK_ICON_SIZE_MENU);
-				text = g_strdup_printf (_("%s plugin is available and the binary is installed."), item->plugin_name);
+				text = g_strdup_printf (_("%s plugin is available and the binary is installed."), iface->plugin_name);
 				html = g_strdup_printf ("<i>%s</i>", text);
 				gtk_label_set_markup (prefs->plugin_status, html);
 				g_free (html);
@@ -728,7 +728,7 @@ junk_plugin_changed (GtkWidget *combo, EMMailerPrefs *prefs)
 			} else {
 				gchar *text, *html;
 				gtk_image_set_from_stock (prefs->plugin_image, "gtk-dialog-warning", GTK_ICON_SIZE_MENU);
-				text = g_strdup_printf (_("%s plugin is not available. Please check whether the package is installed."), item->plugin_name);
+				text = g_strdup_printf (_("%s plugin is not available. Please check whether the package is installed."), iface->plugin_name);
 				html = g_strdup_printf ("<i>%s</i>", text);
 				gtk_label_set_markup (prefs->plugin_status, html);
 				g_free (html);
@@ -761,20 +761,20 @@ junk_plugin_setup (GtkWidget *combo, EMMailerPrefs *prefs)
 	}
 
 	while (plugins) {
-		struct _EMJunkHookItem *item = plugins->data;;
+		EMJunkInterface *iface = plugins->data;
 
-		gtk_combo_box_append_text (GTK_COMBO_BOX (combo), item->plugin_name);
-		if (!def_set && pdefault && item->plugin_name && !strcmp(pdefault, item->plugin_name)) {
+		gtk_combo_box_append_text (GTK_COMBO_BOX (combo), iface->plugin_name);
+		if (!def_set && pdefault && iface->plugin_name && !strcmp(pdefault, iface->plugin_name)) {
 			gboolean status;
 
 			def_set = TRUE;
 			gtk_combo_box_set_active (GTK_COMBO_BOX (combo), index);
-			status = e_plugin_invoke (item->hook->hook.plugin, item->validate_binary, NULL) != NULL;
+			status = e_plugin_invoke (iface->hook->plugin, iface->validate_binary, NULL) != NULL;
 			if (status) {
 				gchar *text, *html;
 				gtk_image_set_from_stock (prefs->plugin_image, "gtk-dialog-info", GTK_ICON_SIZE_MENU);
 				/* May be a better text */
-				text = g_strdup_printf (_("%s plugin is available and the binary is installed."), item->plugin_name);
+				text = g_strdup_printf (_("%s plugin is available and the binary is installed."), iface->plugin_name);
 				html = g_strdup_printf ("<i>%s</i>", text);
 				gtk_label_set_markup (prefs->plugin_status, html);
 				g_free (html);
@@ -783,7 +783,7 @@ junk_plugin_setup (GtkWidget *combo, EMMailerPrefs *prefs)
 				gchar *text, *html;
 				gtk_image_set_from_stock (prefs->plugin_image, "gtk-dialog-warning", GTK_ICON_SIZE_MENU);
 				/* May be a better text */
-				text = g_strdup_printf (_("%s plugin is not available. Please check whether the package is installed."), item->plugin_name);
+				text = g_strdup_printf (_("%s plugin is not available. Please check whether the package is installed."), iface->plugin_name);
 				html = g_strdup_printf ("<i>%s</i>", text);
 				gtk_label_set_markup (prefs->plugin_status, html);
 				g_free (html);
diff --git a/modules/mail/evolution-module-mail.c b/modules/mail/evolution-module-mail.c
index 97bc953..1bb58c7 100644
--- a/modules/mail/evolution-module-mail.c
+++ b/modules/mail/evolution-module-mail.c
@@ -19,6 +19,12 @@
  *
  */
 
+#include "e-mail-attachment-handler.h"
+
+#include "e-mail-config-hook.h"
+#include "e-mail-event-hook.h"
+#include "e-mail-junk-hook.h"
+
 #include "e-mail-shell-backend.h"
 #include "e-mail-shell-content.h"
 #include "e-mail-shell-sidebar.h"
@@ -34,6 +40,12 @@ e_module_load (GTypeModule *type_module)
 {
 	/* Register dynamically loaded types. */
 
+	e_mail_attachment_handler_register_type (type_module);
+
+	e_mail_config_hook_register_type (type_module);
+	e_mail_event_hook_register_type (type_module);
+	e_mail_junk_hook_register_type (type_module);
+
 	e_mail_shell_backend_register_type (type_module);
 	e_mail_shell_content_register_type (type_module);
 	e_mail_shell_sidebar_register_type (type_module);
diff --git a/modules/plugin-lib/Makefile.am b/modules/plugin-lib/Makefile.am
new file mode 100644
index 0000000..cce6090
--- /dev/null
+++ b/modules/plugin-lib/Makefile.am
@@ -0,0 +1,20 @@
+AM_CPPFLAGS =							\
+	-DG_LOG_DOMAIN=\"evolution-plugin-lib\"			\
+	-I$(top_srcdir)						\
+	$(E_UTIL_CFLAGS)
+
+module_LTLIBRARIES = libevolution-module-plugin-lib.la
+
+libevolution_module_plugin_lib_la_SOURCES =			\
+	evolution-module-plugin-lib.c				\
+	e-plugin-lib.c						\
+	e-plugin-lib.h
+
+libevolution_module_plugin_lib_la_LIBADD =			\
+	$(top_builddir)/e-util/libeutil.la			\
+	$(E_UTIL_LIBS)
+
+libevolution_module_plugin_lib_la_LDFLAGS =			\
+	-module -avoid-version $(NO_UNDEFINED)
+
+-include $(top_srcdir)/git.mk
diff --git a/modules/plugin-lib/e-plugin-lib.c b/modules/plugin-lib/e-plugin-lib.c
new file mode 100644
index 0000000..c7a0233
--- /dev/null
+++ b/modules/plugin-lib/e-plugin-lib.c
@@ -0,0 +1,249 @@
+/*
+ * e-plugin-lib.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#include "e-plugin-lib.h"
+
+#include <string.h>
+
+static gpointer parent_class;
+static GType plugin_lib_type;
+
+/* TODO:
+   We need some way to manage lifecycle.
+   We need some way to manage state.
+
+   Maybe just the g module init method will do, or we could add
+   another which returns context.
+
+   There is also the question of per-instance context, e.g. for config
+   pages.
+*/
+
+static gint
+plugin_lib_loadmodule (EPlugin *plugin)
+{
+	EPluginLib *plugin_lib = E_PLUGIN_LIB (plugin);
+	EPluginLibEnableFunc enable;
+
+	if (plugin_lib->module != NULL)
+		return 0;
+
+	if (plugin_lib->location == NULL) {
+		g_warning ("Location not set in plugin '%s'", plugin->name);
+		return -1;
+	}
+
+	if ((plugin_lib->module = g_module_open (plugin_lib->location, 0)) == NULL) {
+		g_warning ("can't load plugin '%s': %s", plugin_lib->location, g_module_error ());
+		return -1;
+	}
+
+	if (g_module_symbol (plugin_lib->module, "e_plugin_lib_enable", (gpointer)&enable)) {
+		if (enable (plugin_lib, TRUE) != 0) {
+			plugin->enabled = FALSE;
+			g_module_close (plugin_lib->module);
+			plugin_lib->module = NULL;
+			return -1;
+		}
+	}
+
+	return 0;
+}
+
+static gpointer
+plugin_lib_invoke (EPlugin *plugin, const gchar *name, gpointer data)
+{
+	EPluginLib *plugin_lib = E_PLUGIN_LIB (plugin);
+	EPluginLibFunc cb;
+
+	if (!plugin->enabled) {
+		g_warning ("trying to invoke '%s' on disabled plugin '%s'", name, plugin->id);
+		return NULL;
+	}
+
+	if (plugin_lib_loadmodule (plugin) != 0)
+		return NULL;
+
+	if (!g_module_symbol (plugin_lib->module, name, (gpointer)&cb)) {
+		g_warning ("Cannot resolve symbol '%s' in plugin '%s' (not exported?)", name, plugin_lib->location);
+		return NULL;
+	}
+
+	return cb (plugin_lib, data);
+}
+
+static gpointer
+plugin_lib_get_symbol (EPlugin *plugin, const gchar *name)
+{
+	EPluginLib *plugin_lib = E_PLUGIN_LIB (plugin);
+	gpointer symbol;
+
+	if (plugin_lib_loadmodule (plugin) != 0)
+		return NULL;
+
+	if (!g_module_symbol (plugin_lib->module, name, &symbol))
+		return NULL;
+
+	return symbol;
+}
+
+static gint
+plugin_lib_construct (EPlugin *plugin, xmlNodePtr root)
+{
+	EPluginLib *plugin_lib = E_PLUGIN_LIB (plugin);
+
+	/* Set the location before chaining up, as some EPluginHooks
+	 * will cause the module to load during hook construction. */
+
+	plugin_lib->location = e_plugin_xml_prop (root, "location");
+
+	if (plugin_lib->location == NULL) {
+		g_warning ("Library plugin '%s' has no location", plugin->id);
+		return -1;
+	}
+#ifdef G_OS_WIN32
+	{
+		gchar *mapped_location =
+			e_util_rplugin_libace_prefix (EVOLUTION_PREFIX,
+					       e_util_get_prefix (),
+					       plugin_lib->location);
+		g_free (plugin_lib->location);
+		plugin_lib->location = mapped_location;
+	}
+#endif
+
+	/* Chain up to parent's construct() method. */
+	if (E_PLUGIN_CLASS (parent_class)->construct (plugin, root) == -1)
+		return -1;
+
+	/* If we're enabled, check for the load-on-startup property */
+	if (plugin->enabled) {
+		xmlChar *tmp;
+
+		tmp = xmlGetProp (root, (const guchar *)"load-on-startup");
+		if (tmp) {
+			if (plugin_lib_loadmodule (plugin) != 0) {
+				xmlFree (tmp);
+				return -1;
+			}
+			xmlFree (tmp);
+		}
+	}
+
+	return 0;
+}
+
+static GtkWidget *
+plugin_lib_get_configure_widget (EPlugin *plugin)
+{
+	EPluginLib *plugin_lib = E_PLUGIN_LIB (plugin);
+	EPluginLibGetConfigureWidgetFunc get_configure_widget;
+
+	if (plugin_lib_loadmodule (plugin) != 0) {
+		return NULL;
+	}
+
+	if (g_module_symbol (plugin_lib->module, "e_plugin_lib_get_configure_widget", (gpointer)&get_configure_widget)) {
+		return (GtkWidget*) get_configure_widget (plugin_lib);
+	}
+	return NULL;
+}
+
+static void
+plugin_lib_enable (EPlugin *plugin, gint state)
+{
+	EPluginLib *plugin_lib = E_PLUGIN_LIB (plugin);
+	EPluginLibEnableFunc enable;
+
+	E_PLUGIN_CLASS (parent_class)->enable (plugin, state);
+
+	/* if we're disabling and it isn't loaded, nothing to do */
+	if (!state && plugin_lib->module == NULL)
+		return;
+
+	/* this will noop if we're disabling since we tested it above */
+	if (plugin_lib_loadmodule (plugin) != 0)
+		return;
+
+	if (g_module_symbol (plugin_lib->module, "e_plugin_lib_enable", (gpointer) &enable)) {
+		if (enable (plugin_lib, state) != 0)
+			return;
+	}
+}
+
+static void
+plugin_lib_finalize (GObject *object)
+{
+	EPluginLib *plugin_lib = E_PLUGIN_LIB (object);
+
+	g_free (plugin_lib->location);
+
+	if (plugin_lib->module)
+		g_module_close (plugin_lib->module);
+
+	/* Chain up to parent's finalize() method. */
+	G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+static void
+plugin_lib_class_init (EPluginClass *class)
+{
+	GObjectClass *object_class;
+
+	parent_class = g_type_class_peek_parent (class);
+
+	object_class = G_OBJECT_CLASS (class);
+	object_class->finalize = plugin_lib_finalize;
+
+	class->construct = plugin_lib_construct;
+	class->invoke = plugin_lib_invoke;
+	class->get_symbol = plugin_lib_get_symbol;
+	class->enable = plugin_lib_enable;
+	class->get_configure_widget = plugin_lib_get_configure_widget;
+	class->type = "shlib";
+}
+
+GType
+e_plugin_lib_get_type (void)
+{
+	return plugin_lib_type;
+}
+
+void
+e_plugin_lib_register_type (GTypeModule *type_module)
+{
+	static const GTypeInfo type_info = {
+		sizeof (EPluginLibClass),
+		(GBaseInitFunc) NULL,
+		(GBaseFinalizeFunc) NULL,
+		(GClassInitFunc) plugin_lib_class_init,
+		(GClassFinalizeFunc) NULL,
+		NULL,  /* class_data */
+		sizeof (EPluginLib),
+		0,     /* n_preallocs */
+		(GInstanceInitFunc) NULL,
+		NULL   /* value_table */
+	};
+
+	plugin_lib_type = g_type_module_register_type (
+		type_module, E_TYPE_PLUGIN,
+		"EPluginLib", &type_info, 0);
+}
diff --git a/modules/plugin-lib/e-plugin-lib.h b/modules/plugin-lib/e-plugin-lib.h
new file mode 100644
index 0000000..b485d96
--- /dev/null
+++ b/modules/plugin-lib/e-plugin-lib.h
@@ -0,0 +1,92 @@
+/*
+ * e-plugin-lib.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifndef E_PLUGIN_LIB_H
+#define E_PLUGIN_LIB_H
+
+#include <gmodule.h>
+#include <e-util/e-plugin.h>
+
+/* Standard GObject macros */
+#define E_TYPE_PLUGIN_LIB \
+	(e_plugin_lib_get_type ())
+#define E_PLUGIN_LIB(obj) \
+	(G_TYPE_CHECK_INSTANCE_CAST \
+	((obj), E_TYPE_PLUGIN_LIB, EPluginLib))
+#define E_PLUGIN_LIB_CLASS(cls) \
+	(G_TYPE_CHECK_CLASS_CAST \
+	((cls), E_TYPE_PLUGIN_LIB, EPluginLibClass))
+#define E_IS_PLUGIN_LIB(obj) \
+	(G_TYPE_CHECK_INSTANCE_TYPE \
+	((obj), E_TYPE_PLUGIN_LIB))
+#define E_IS_PLUGIN_LIB_CLASS(cls) \
+	(G_TYPE_CHECK_CLASS_TYPE \
+	((cls), E_TYPE_PLUGIN_LIB))
+#define E_PLUGIN_LIB_GET_CLASS(obj) \
+	(G_TYPE_INSTANCE_GET_CLASS \
+	((obj), E_TYPE_PLUGIN_LIB, EPluginLibClass))
+
+G_BEGIN_DECLS
+
+typedef struct _EPluginLib EPluginLib;
+typedef struct _EPluginLibClass EPluginLibClass;
+
+/* The callback signature used for epluginlib methods */
+typedef gpointer (*EPluginLibFunc) (EPluginLib *ep, gpointer data);
+
+/* The setup method, this will be called when the plugin is
+ * initialized.  In the future it may also be called when the plugin
+ * is disabled. */
+typedef gint (*EPluginLibEnableFunc) (EPluginLib *ep, gint enable);
+
+typedef gpointer (*EPluginLibGetConfigureWidgetFunc) (EPluginLib *ep);
+
+/**
+ * struct _EPluginLib -
+ *
+ * @plugin: Superclass.
+ * @location: The filename of the shared object.
+ * @module: The GModule once it is loaded.
+ *
+ * This is a concrete EPlugin class.  It loads and invokes dynamically
+ * loaded libraries using GModule.  The shared object isn't loaded
+ * until the first callback is invoked.
+ *
+ * When the plugin is loaded, and if it exists, "e_plugin_lib_enable"
+ * will be invoked to initialize the plugin.
+ **/
+struct _EPluginLib {
+	EPlugin parent;
+
+	gchar *location;
+	GModule *module;
+};
+
+struct _EPluginLibClass {
+	EPluginClass parent_class;
+};
+
+GType		e_plugin_lib_get_type		(void);
+void		e_plugin_lib_register_type	(GTypeModule *type_module);
+
+G_END_DECLS
+
+#endif /* E_PLUGIN_LIB_H */
diff --git a/plugins/python/python-plugin-loader.h b/modules/plugin-lib/evolution-module-plugin-lib.c
similarity index 54%
copy from plugins/python/python-plugin-loader.h
copy to modules/plugin-lib/evolution-module-plugin-lib.c
index 66bd8d5..833ca59 100644
--- a/plugins/python/python-plugin-loader.h
+++ b/modules/plugin-lib/evolution-module-plugin-lib.c
@@ -1,4 +1,6 @@
 /*
+ * evolution-module-plugin-lib.c
+ *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
@@ -13,35 +15,27 @@
  * License along with the program; if not, see <http://www.gnu.org/licenses/>
  *
  *
- * Authors:
- *		Johnny Jacob <jjohnny novell com>
- *
  * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
  *
  */
 
-#ifndef _ORG_GNOME_EVOLUTION_PYTHON_H
-#define _ORG_GNOME_EVOLUTION_PYTHON_H
-
-#include "e-util/e-plugin.h"
-
-typedef struct _EPluginPython EPluginPython;
-typedef struct _EPluginPythonClass EPluginPythonClass;
-
-struct _EPluginPython {
-	EPlugin plugin;
+#include <config.h>
 
-	struct _EPluginPythonPrivate *priv;
+#include "e-plugin-lib.h"
 
-	gchar *location;		/* location */
-	gchar *pClass;		/* handler class */
-        gchar *module_name;
-};
+/* Module Entry Points */
+void e_module_load (GTypeModule *type_module);
+void e_module_unload (GTypeModule *type_module);
 
-struct _EPluginPythonClass {
-	EPluginClass plugin_class;
-};
+G_MODULE_EXPORT void
+e_module_load (GTypeModule *type_module)
+{
+	/* Register dynamically loaded types. */
 
-gpointer org_gnome_evolution_python_get_type(gpointer a, gpointer b);
+	e_plugin_lib_register_type (type_module);
+}
 
-#endif /* ! _ORG_GNOME_EVOLUTION_PYTHON_H */
+G_MODULE_EXPORT void
+e_module_unload (GTypeModule *type_module)
+{
+}
diff --git a/plugins/mono/Camel.cs b/modules/plugin-mono/Camel.cs
similarity index 100%
rename from plugins/mono/Camel.cs
rename to modules/plugin-mono/Camel.cs
diff --git a/plugins/mono/Evolution.cs b/modules/plugin-mono/Evolution.cs
similarity index 100%
rename from plugins/mono/Evolution.cs
rename to modules/plugin-mono/Evolution.cs
diff --git a/modules/plugin-mono/Makefile.am b/modules/plugin-mono/Makefile.am
new file mode 100644
index 0000000..f4f436a
--- /dev/null
+++ b/modules/plugin-mono/Makefile.am
@@ -0,0 +1,22 @@
+AM_CPPFLAGS =							\
+	-DG_LOG_DOMAIN=\"evolution-plugin-mono\"		\
+	-I$(top_srcdir)						\
+	$(E_UTIL_CFLAGS)					\
+	$(MONO_CFLAGS)
+
+module_LTLIBRARIES = libevolution-module-plugin-mono.la
+
+libevolution_module_plugin_mono_la_SOURCES =			\
+	evolution-module-plugin-mono.c				\
+	e-plugin-mono.c						\
+	e-plugin-mono.h
+
+libevolution_module_plugin_mono_la_LIBADD =			\
+	$(top_builddir)/e-util/libeutil.la			\
+	$(E_UTIL_LIBS)						\
+	$(MONO_LIBS)
+
+libevolution_module_plugin_mono_la_LDFLAGS =			\
+	-module -avoid-version $(NO_UNDEFINED)
+
+-include $(top_srcdir)/git.mk
diff --git a/modules/plugin-mono/e-plugin-mono.c b/modules/plugin-mono/e-plugin-mono.c
new file mode 100644
index 0000000..1c43fb9
--- /dev/null
+++ b/modules/plugin-mono/e-plugin-mono.c
@@ -0,0 +1,261 @@
+/*
+ * e-plugin-mono.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#include "e-plugin-mono.h"
+
+#include <sys/types.h>
+#include <string.h>
+
+#include "e-plugin-mono.h"
+
+#include <mono/metadata/debug-helpers.h>
+#include <mono/metadata/object.h>
+#include <mono/metadata/appdomain.h>
+#include <mono/metadata/assembly.h>
+#include <mono/metadata/threads.h>
+#include <mono/metadata/mono-config.h>
+#include <mono/jit/jit.h>
+
+#define E_PLUGIN_MONO_GET_PRIVATE(obj) \
+	(G_TYPE_INSTANCE_GET_PRIVATE \
+	((obj), E_TYPE_PLUGIN_MONO, EPluginMonoPrivate))
+
+struct _EPluginMonoPrivate {
+	MonoAssembly *assembly;
+	MonoClass *class;
+	MonoObject *plugin;
+	GHashTable *methods;
+};
+
+static MonoDomain *domain;
+static gpointer parent_class;
+static GType plugin_mono_type;
+
+static gchar *
+get_xml_prop (xmlNodePtr node, const gchar *id)
+{
+	xmlChar *prop;
+	gchar *out = NULL;
+
+	prop = xmlGetProp (node, (xmlChar *) id);
+
+	if (prop != NULL) {
+		out = g_strdup ((gchar *) prop);
+		xmlFree (prop);
+	}
+
+	return out;
+}
+
+static void
+plugin_mono_finalize (GObject *object)
+{
+	EPluginMono *plugin_mono;
+
+	plugin_mono = E_PLUGIN_MONO (object);
+
+	g_free (plugin_mono->location);
+	g_free (plugin_mono->handler);
+
+	g_hash_table_destroy (plugin_mono->priv->methods);
+
+	/* Chain up to parent's finalize() method. */
+	G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+static gint
+plugin_mono_construct (EPlugin *plugin, xmlNodePtr root)
+{
+	EPluginMono *plugin_mono;
+
+	/* Chain up to parent's construct() method. */
+	if (E_PLUGIN_CLASS (parent_class)->construct (plugin, root) == -1)
+		return -1;
+
+	plugin_mono = E_PLUGIN_MONO (plugin);
+	plugin_mono->location = get_xml_prop (root, "location");
+	plugin_mono->handler = get_xml_prop (root, "handler");
+
+	return (plugin_mono->location != NULL) ? 0 : -1;
+}
+
+/*
+  Two approaches:
+    You can have a Evolution.Plugin implementation which has every
+    callback as methods on it.  Or you can just use static methods
+    for everything.
+
+   All methods take a single (structured) argument.
+*/
+
+static gpointer
+plugin_mono_invoke (EPlugin *plugin,
+                    const gchar *name,
+                    gpointer data)
+{
+	EPluginMono *plugin_mono;
+	EPluginMonoPrivate *priv;
+	MonoMethodDesc *d;
+	MonoMethod *m;
+	MonoObject *x = NULL, *res;
+	gpointer *params;
+
+	plugin_mono = E_PLUGIN_MONO (plugin);
+	priv = plugin_mono->priv;
+
+	/* we need to do this every time since we may be called from any thread for some uses */
+	mono_thread_attach (domain);
+
+	if (priv->assembly == NULL) {
+		priv->assembly = mono_domain_assembly_open (
+			domain, plugin_mono->location);
+		if (priv->assembly == NULL) {
+			g_warning (
+				"Can't load assembly '%s'",
+				plugin_mono->location);
+			return NULL;
+		}
+
+		if (plugin_mono->handler == NULL
+		    || (priv->class = mono_class_from_name (mono_assembly_get_image (priv->assembly), "", plugin_mono->handler)) == NULL) {
+		} else {
+			priv->plugin = mono_object_new (domain, priv->class);
+			/* could conceivably init with some context too */
+			mono_runtime_object_init (priv->plugin);
+		}
+	}
+
+	m = g_hash_table_lookup (priv->methods, name);
+	if (m == NULL) {
+		if (priv->class) {
+			/* class method */
+			MonoMethod* mono_method;
+			gpointer iter = NULL;
+
+			d = mono_method_desc_new (name, FALSE);
+			/*if (d == NULL) {
+				g_warning ("Can't create method descriptor for '%s'", name);
+				return NULL;
+			}*/
+
+			while ((mono_method = mono_class_get_methods (priv->class, &iter))) {
+				g_print ("\n\a Method name is : <%s>\n\a", mono_method_get_name (mono_method));
+			}
+//mono_class_get_method_from_name
+			m = mono_class_get_method_from_name (priv->class, name, -1);
+			if (m == NULL) {
+				g_warning ("Can't find method callback '%s'", name);
+				return NULL;
+			}
+		} else {
+			/* static method */
+			d = mono_method_desc_new (name, FALSE);
+			if (d == NULL) {
+				g_warning ("Can't create method descriptor for '%s'", name);
+				return NULL;
+			}
+
+			m = mono_method_desc_search_in_image (d, mono_assembly_get_image (priv->assembly));
+			if (m == NULL) {
+				g_warning ("Can't find method callback '%s'", name);
+				return NULL;
+			}
+		}
+
+		g_hash_table_insert (priv->methods, g_strdup (name), m);
+	}
+
+	params = g_malloc0(sizeof (*params)*1);
+	params[0] = &data;
+	res = mono_runtime_invoke (m, priv->plugin, params, &x);
+	/* do i need to free params?? */
+
+	if (x)
+		mono_print_unhandled_exception (x);
+
+	if (res) {
+		gpointer *p = mono_object_unbox (res);
+		return *p;
+	} else
+		return NULL;
+}
+
+static void
+plugin_mono_class_init (EPluginMonoClass *class)
+{
+	GObjectClass *object_class;
+	EPluginClass *plugin_class;
+
+	parent_class = g_type_class_peek_parent (class);
+	g_type_class_add_private (class, sizeof (EPluginMonoPrivate));
+
+	object_class = G_OBJECT_CLASS (class);
+	object_class->finalize = plugin_mono_finalize;
+
+	plugin_class = E_PLUGIN_CLASS (class);
+	plugin_class->construct = plugin_mono_construct;
+	plugin_class->invoke = plugin_mono_invoke;
+	plugin_class->type = "mono";
+}
+
+static void
+plugin_mono_init (EPluginMono *plugin_mono)
+{
+	GHashTable *methods;
+
+	methods = g_hash_table_new_full (
+		g_str_hash, g_str_equal,
+		(GDestroyNotify) g_free,
+		(GDestroyNotify) NULL);
+
+	plugin_mono->priv = E_PLUGIN_MONO_GET_PRIVATE (plugin_mono);
+	plugin_mono->priv->methods = methods;
+}
+
+GType
+e_plugin_mono_get_type (void)
+{
+	return plugin_mono_type;
+}
+
+void
+e_plugin_mono_register_type (GTypeModule *type_module)
+{
+	static const GTypeInfo type_info = {
+		sizeof (EPluginMonoClass),
+		(GBaseInitFunc) NULL,
+		(GBaseFinalizeFunc) NULL,
+		(GClassInitFunc) plugin_mono_class_init,
+		(GClassFinalizeFunc) NULL,
+		NULL,  /* class_data */
+		sizeof (EPluginMono),
+		0,     /* n_preallocs */
+		(GInstanceInitFunc) plugin_mono_init,
+		NULL   /* value_table */
+	};
+
+	plugin_mono_type = g_type_module_register_type (
+		type_module, E_TYPE_PLUGIN,
+		"EPluginMono", &type_info, 0);
+
+	domain = mono_jit_init ("Evolution");
+	mono_thread_attach (domain);
+}
diff --git a/modules/plugin-mono/e-plugin-mono.h b/modules/plugin-mono/e-plugin-mono.h
new file mode 100644
index 0000000..a4ed2d4
--- /dev/null
+++ b/modules/plugin-mono/e-plugin-mono.h
@@ -0,0 +1,69 @@
+/*
+ * e-plugin-mono.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifndef E_PLUGIN_MONO_H
+#define E_PLUGIN_MONO_H
+
+#include <e-util/e-plugin.h>
+
+/* Standard GObject macros */
+#define E_TYPE_PLUGIN_MONO \
+	(e_plugin_mono_get_type ())
+#define E_PLUGIN_MONO(obj) \
+	(G_TYPE_CHECK_INSTANCE_CAST \
+	((obj), E_TYPE_PLUGIN_MONO, EPluginMono))
+#define E_PLUGIN_MONO_CLASS(cls) \
+	(G_TYPE_CHECK_CLASS_CAST \
+	((cls), E_TYPE_PLUGIN_MONO, EPluginMonoClass))
+#define E_IS_PLUGIN_MONO(obj) \
+	(G_TYPE_CHECK_INSTANCE_TYPE \
+	((obj), E_TYPE_PLUGIN_MONO))
+#define E_IS_PLUGIN_MONO_CLASS(cls) \
+	(G_TYPE_CHECK_CLASS_TYPE \
+	((cls), E_TYPE_PLUGIN_MONO))
+#define E_PLUGIN_MONO_GET_CLASS(obj) \
+	(G_TYPE_INSTANCE_GET_CLASS \
+	((obj), E_TYPE_PLUGIN_MONO, EPluginMonoClass))
+
+G_BEGIN_DECLS
+
+typedef struct _EPluginMono EPluginMono;
+typedef struct _EPluginMonoClass EPluginMonoClass;
+typedef struct _EPluginMonoPrivate EPluginMonoPrivate;
+
+struct _EPluginMono {
+	EPlugin parent;
+	EPluginMonoPrivate *priv;
+
+	gchar *location;
+	gchar *handler;
+};
+
+struct _EPluginMonoClass {
+	EPluginClass parent_class;
+};
+
+GType		e_plugin_mono_get_type		(void);
+void		e_plugin_mono_register_type	(GTypeModule *type_module);
+
+G_END_DECLS
+
+#endif /* E_PLUGIN_MONO_H */
diff --git a/plugins/python/python-plugin-loader.h b/modules/plugin-mono/evolution-module-plugin-mono.c
similarity index 54%
copy from plugins/python/python-plugin-loader.h
copy to modules/plugin-mono/evolution-module-plugin-mono.c
index 66bd8d5..75ad534 100644
--- a/plugins/python/python-plugin-loader.h
+++ b/modules/plugin-mono/evolution-module-plugin-mono.c
@@ -1,4 +1,6 @@
 /*
+ * evolution-module-plugin-mono.c
+ *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
@@ -13,35 +15,27 @@
  * License along with the program; if not, see <http://www.gnu.org/licenses/>
  *
  *
- * Authors:
- *		Johnny Jacob <jjohnny novell com>
- *
  * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
  *
  */
 
-#ifndef _ORG_GNOME_EVOLUTION_PYTHON_H
-#define _ORG_GNOME_EVOLUTION_PYTHON_H
-
-#include "e-util/e-plugin.h"
-
-typedef struct _EPluginPython EPluginPython;
-typedef struct _EPluginPythonClass EPluginPythonClass;
-
-struct _EPluginPython {
-	EPlugin plugin;
+#include <config.h>
 
-	struct _EPluginPythonPrivate *priv;
+#include "e-plugin-mono.h"
 
-	gchar *location;		/* location */
-	gchar *pClass;		/* handler class */
-        gchar *module_name;
-};
+/* Module Entry Points */
+void e_module_load (GTypeModule *type_module);
+void e_module_unload (GTypeModule *type_module);
 
-struct _EPluginPythonClass {
-	EPluginClass plugin_class;
-};
+G_MODULE_EXPORT void
+e_module_load (GTypeModule *type_module)
+{
+	/* Register dynamically loaded types. */
 
-gpointer org_gnome_evolution_python_get_type(gpointer a, gpointer b);
+	e_plugin_mono_register_type (type_module);
+}
 
-#endif /* ! _ORG_GNOME_EVOLUTION_PYTHON_H */
+G_MODULE_EXPORT void
+e_module_unload (GTypeModule *type_module)
+{
+}
diff --git a/modules/plugin-python/Makefile.am b/modules/plugin-python/Makefile.am
new file mode 100644
index 0000000..e6a32c3
--- /dev/null
+++ b/modules/plugin-python/Makefile.am
@@ -0,0 +1,31 @@
+AM_CPPFLAGS =							\
+	-DG_LOG_DOMAIN=\"evolution-plugin-python\"		\
+	-I$(top_srcdir)						\
+	$(E_UTIL_CFLAGS)					\
+	$(PY_INCLUDES)
+
+module_LTLIBRARIES = libevolution-module-plugin-python.la
+
+libevolution_module_plugin_python_la_SOURCES =			\
+	evolution-module-plugin-python.c			\
+	e-plugin-python.c					\
+	e-plugin-python.h
+
+libevolution_module_plugin_python_la_LIBADD =			\
+	-lpthread -ldl -lutil -lm				\
+	$(top_builddir)/e-util/libeutil.la			\
+	$(E_UTIL_LIBS)						\
+	$(PY_LIBS)
+
+libevolution_module_plugin_python_la_LDFLAGS =			\
+	-module -avoid-version $(NO_UNDEFINED)
+
+example_sources =						\
+	example/hello_python.py					\
+	example/org-gnome-hello-python-ui.xml			\
+	example/org-gnome-hello-python.eplug.xml		\
+	example/Makefile.am
+
+EXTRA_DIST = $(example_sources)
+
+-include $(top_srcdir)/git.mk
diff --git a/modules/plugin-python/e-plugin-python.c b/modules/plugin-python/e-plugin-python.c
new file mode 100644
index 0000000..747ba57
--- /dev/null
+++ b/modules/plugin-python/e-plugin-python.c
@@ -0,0 +1,230 @@
+/*
+ * e-plugin-python.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+/* Include <Python.h> first to avoid:
+ * warning: "_POSIX_C_SOURCE" redefined */
+#include <Python.h>
+
+#include "e-plugin-python.h"
+
+#include <sys/types.h>
+#include <string.h>
+
+#define E_PLUGIN_PYTHON_GET_PRIVATE(obj) \
+	(G_TYPE_INSTANCE_GET_PRIVATE \
+	((obj), E_TYPE_PLUGIN_PYTHON, EPluginPythonPrivate))
+
+struct _EPluginPythonPrivate {
+	PyObject *pModule;
+	PyObject *pClass;
+	PyObject *pFunc;
+	PyObject *pDict;
+	GHashTable *methods;
+};
+
+static gpointer parent_class;
+static GType plugin_python_type;
+
+static gchar *
+get_xml_prop (xmlNodePtr node, const gchar *id)
+{
+	xmlChar *prop;
+	gchar *out = NULL;
+
+	prop = xmlGetProp (node, (xmlChar *) id);
+
+	if (prop != NULL) {
+		out = g_strdup ((gchar *) prop);
+		xmlFree (prop);
+	}
+
+	return out;
+}
+
+static void
+plugin_python_finalize (GObject *object)
+{
+	EPluginPython *plugin_python;
+
+	plugin_python = E_PLUGIN_PYTHON (object);
+
+	g_free (plugin_python->location);
+	g_free (plugin_python->module_name);
+	g_free (plugin_python->pClass);
+
+	g_hash_table_destroy (plugin_python->priv->methods);
+
+	/* Chain up to parent's finalize() method. */
+	G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+static gint
+plugin_python_construct (EPlugin *plugin, xmlNodePtr root)
+{
+	EPluginPython *plugin_python;
+
+	/* Chain up to parent's construct() method. */
+	if (E_PLUGIN_CLASS (parent_class)->construct (plugin, root) == -1)
+		return -1;
+
+	plugin_python = E_PLUGIN_PYTHON (plugin);
+	plugin_python->location = get_xml_prop (root, "location");
+	plugin_python->module_name = get_xml_prop (root, "module_name");
+	plugin_python->pClass = get_xml_prop (root, "pClass");
+
+	return (plugin_python->location != NULL) ? 0 : -1;
+}
+
+static gpointer
+plugin_python_invoke (EPlugin *plugin,
+                      const gchar *name,
+                      gpointer data)
+{
+	EPluginPython *plugin_python;
+	EPluginPythonPrivate *priv;
+	PyObject *pModuleName, *pFunc;
+	PyObject *pInstance, *pValue = NULL;
+
+	plugin_python = E_PLUGIN_PYTHON (plugin);
+	priv = plugin_python->priv;
+
+	/* We need to do this every time since we may be called
+	 * from any thread for some uses. */
+	Py_Initialize ();
+
+	if (priv->pModule == NULL) {
+		gchar *string;
+
+		pModuleName = PyString_FromString (plugin_python->module_name);
+
+		string = g_strdup_printf (
+			"import sys; "
+			"sys.path.insert(0, '%s')",
+			plugin_python->location);
+		PyRun_SimpleString (string);
+		g_free (string);
+
+		priv->pModule = PyImport_Import (pModuleName);
+
+		Py_DECREF (pModuleName); //Free
+
+		if (priv->pModule == NULL) {
+			PyErr_Print ();
+			g_warning (
+				"Can't load python module '%s'",
+				plugin_python->location);
+			return NULL;
+		}
+
+		priv->pDict = PyModule_GetDict (priv->pModule);
+
+		if (plugin_python->pClass != NULL) {
+			priv->pClass = PyDict_GetItemString (
+				priv->pDict, plugin_python->pClass);
+		}
+	}
+
+	if (priv->pClass) {
+
+		if (PyCallable_Check (priv->pClass))
+			pInstance = PyObject_CallObject (priv->pClass, NULL);
+
+		pValue = PyObject_CallMethod (pInstance, (gchar *) name, NULL);
+
+	} else {
+
+		pFunc = PyDict_GetItemString (priv->pDict, name);
+
+		if (pFunc && PyCallable_Check (pFunc))
+			pValue = PyObject_CallObject (pFunc, NULL);
+		else
+			PyErr_Print ();
+	}
+
+	if (pValue) {
+                Py_DECREF(pValue);
+		/* Fixme */
+		return NULL;
+	} else
+		return NULL;
+}
+
+static void
+plugin_python_class_init (EPluginPythonClass *class)
+{
+	GObjectClass *object_class;
+	EPluginClass *plugin_class;
+
+	parent_class = g_type_class_peek_parent (class);
+	g_type_class_add_private (class, sizeof (EPluginPythonPrivate));
+
+	object_class = G_OBJECT_CLASS (class);
+	object_class->finalize = plugin_python_finalize;
+
+	plugin_class = E_PLUGIN_CLASS (class);
+	plugin_class->construct = plugin_python_construct;
+	plugin_class->invoke = plugin_python_invoke;
+	plugin_class->type = "python";
+}
+
+static void
+plugin_python_init (EPluginPython *plugin_python)
+{
+	GHashTable *methods;
+
+	methods = g_hash_table_new_full (
+		g_str_hash, g_str_equal,
+		(GDestroyNotify) g_free,
+		(GDestroyNotify) NULL);
+
+	plugin_python->priv = E_PLUGIN_PYTHON_GET_PRIVATE (plugin_python);
+	plugin_python->priv->methods = methods;
+}
+
+GType
+e_plugin_python_get_type (void)
+{
+	return plugin_python_type;
+}
+
+void
+e_plugin_python_register_type (GTypeModule *type_module)
+{
+	static const GTypeInfo type_info = {
+		sizeof (EPluginPythonClass),
+		(GBaseInitFunc) NULL,
+		(GBaseFinalizeFunc) NULL,
+		(GClassInitFunc) plugin_python_class_init,
+		(GClassFinalizeFunc) NULL,
+		NULL,  /* class_data */
+		sizeof (EPluginPython),
+		0,     /* n_preallocs */
+		(GInstanceInitFunc) plugin_python_init,
+		NULL   /* value_table */
+	};
+
+	plugin_python_type = g_type_module_register_type (
+		type_module, E_TYPE_PLUGIN,
+		"EPluginPython", &type_info, 0);
+
+	/* TODO Does this mean I can cache the instance of pyobjects? */
+	Py_Initialize ();
+}
diff --git a/modules/plugin-python/e-plugin-python.h b/modules/plugin-python/e-plugin-python.h
new file mode 100644
index 0000000..9ee780c
--- /dev/null
+++ b/modules/plugin-python/e-plugin-python.h
@@ -0,0 +1,70 @@
+/*
+ * e-plugin-python.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifndef E_PLUGIN_PYTHON_H
+#define E_PLUGIN_PYTHON_H
+
+#include <e-util/e-plugin.h>
+
+/* Standard GObject macros */
+#define E_TYPE_PLUGIN_PYTHON \
+	(e_plugin_python_get_type ())
+#define E_PLUGIN_PYTHON(obj) \
+	(G_TYPE_CHECK_INSTANCE_CAST \
+	((obj), E_TYPE_PLUGIN_PYTHON, EPluginPython))
+#define E_PLUGIN_PYTHON_CLASS(cls) \
+	(G_TYPE_CHECK_CLASS_CAST \
+	((cls), E_TYPE_PLUGIN_PYTHON, EPluginPythonClass))
+#define E_IS_PLUGIN_PYTHON(obj) \
+	(G_TYPE_CHECK_INSTANCE_TYPE \
+	((obj), E_TYPE_PLUGIN_PYTHON))
+#define E_IS_PLUGIN_PYTHON_CLASS(cls) \
+	(G_TYPE_CHECK_CLASS_TYPE \
+	((cls), E_TYPE_PLUGIN_PYTHON))
+#define E_PLUGIN_PYTHON_GET_CLASS(obj) \
+	(G_TYPE_INSTANCE_GET_CLASS \
+	((obj), E_TYPE_PLUGIN_PYTHON, EPluginPythonClass))
+
+G_BEGIN_DECLS
+
+typedef struct _EPluginPython EPluginPython;
+typedef struct _EPluginPythonClass EPluginPythonClass;
+typedef struct _EPluginPythonPrivate EPluginPythonPrivate;
+
+struct _EPluginPython {
+	EPlugin parent;
+	EPluginPythonPrivate *priv;
+
+	gchar *location;
+	gchar *pClass;
+	gchar *module_name;
+};
+
+struct _EPluginPythonClass {
+	EPluginClass parent_class;
+};
+
+GType		e_plugin_python_get_type	(void);
+void		e_plugin_python_register_type	(GTypeModule *type_module);
+
+G_END_DECLS
+
+#endif /* E_PLUGIN_PYTHON_H */
diff --git a/plugins/python/python-plugin-loader.h b/modules/plugin-python/evolution-module-plugin-python.c
similarity index 54%
rename from plugins/python/python-plugin-loader.h
rename to modules/plugin-python/evolution-module-plugin-python.c
index 66bd8d5..84ab3b3 100644
--- a/plugins/python/python-plugin-loader.h
+++ b/modules/plugin-python/evolution-module-plugin-python.c
@@ -1,4 +1,6 @@
 /*
+ * evolution-module-plugin-python.c
+ *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
@@ -13,35 +15,27 @@
  * License along with the program; if not, see <http://www.gnu.org/licenses/>
  *
  *
- * Authors:
- *		Johnny Jacob <jjohnny novell com>
- *
  * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
  *
  */
 
-#ifndef _ORG_GNOME_EVOLUTION_PYTHON_H
-#define _ORG_GNOME_EVOLUTION_PYTHON_H
-
-#include "e-util/e-plugin.h"
-
-typedef struct _EPluginPython EPluginPython;
-typedef struct _EPluginPythonClass EPluginPythonClass;
-
-struct _EPluginPython {
-	EPlugin plugin;
+#include <config.h>
 
-	struct _EPluginPythonPrivate *priv;
+#include "e-plugin-python.h"
 
-	gchar *location;		/* location */
-	gchar *pClass;		/* handler class */
-        gchar *module_name;
-};
+/* Module Entry Points */
+void e_module_load (GTypeModule *type_module);
+void e_module_unload (GTypeModule *type_module);
 
-struct _EPluginPythonClass {
-	EPluginClass plugin_class;
-};
+G_MODULE_EXPORT void
+e_module_load (GTypeModule *type_module)
+{
+	/* Register dynamically loaded types. */
 
-gpointer org_gnome_evolution_python_get_type(gpointer a, gpointer b);
+	e_plugin_python_register_type (type_module);
+}
 
-#endif /* ! _ORG_GNOME_EVOLUTION_PYTHON_H */
+G_MODULE_EXPORT void
+e_module_unload (GTypeModule *type_module)
+{
+}
diff --git a/plugins/python/example/Makefile.am b/modules/plugin-python/example/Makefile.am
similarity index 100%
rename from plugins/python/example/Makefile.am
rename to modules/plugin-python/example/Makefile.am
diff --git a/plugins/python/example/hello_python.py b/modules/plugin-python/example/hello_python.py
similarity index 100%
rename from plugins/python/example/hello_python.py
rename to modules/plugin-python/example/hello_python.py
diff --git a/plugins/python/example/org-gnome-hello-python-ui.xml b/modules/plugin-python/example/org-gnome-hello-python-ui.xml
similarity index 100%
rename from plugins/python/example/org-gnome-hello-python-ui.xml
rename to modules/plugin-python/example/org-gnome-hello-python-ui.xml
diff --git a/plugins/python/example/org-gnome-hello-python.eplug.xml b/modules/plugin-python/example/org-gnome-hello-python.eplug.xml
similarity index 100%
rename from plugins/python/example/org-gnome-hello-python.eplug.xml
rename to modules/plugin-python/example/org-gnome-hello-python.eplug.xml
diff --git a/plugins/Makefile.am b/plugins/Makefile.am
index 88edda3..c20e1dd 100644
--- a/plugins/Makefile.am
+++ b/plugins/Makefile.am
@@ -1,4 +1,4 @@
 SUBDIRS = $(plugins_enabled)
-DIST_SUBDIRS = $(all_plugins_base) $(all_plugins_standard) $(all_plugins_experimental) profiler python
+DIST_SUBDIRS = $(all_plugins_base) $(all_plugins_standard) $(all_plugins_experimental) profiler
 
 -include $(top_srcdir)/git.mk
diff --git a/plugins/attachment-reminder/attachment-reminder.c b/plugins/attachment-reminder/attachment-reminder.c
index 87acc16..330fd5d 100644
--- a/plugins/attachment-reminder/attachment-reminder.c
+++ b/plugins/attachment-reminder/attachment-reminder.c
@@ -67,7 +67,7 @@ enum {
 	CLUE_N_COLUMNS
 };
 
-gint e_plugin_lib_enable (EPluginLib *ep, gint enable);
+gint e_plugin_lib_enable (EPlugin *ep, gint enable);
 GtkWidget *e_plugin_lib_get_configure_widget (EPlugin *epl);
 
 void org_gnome_evolution_attachment_reminder (EPlugin *ep, EMEventTargetComposer *t);
@@ -85,7 +85,7 @@ static gboolean clue_foreach_check_isempty (GtkTreeModel *model, GtkTreePath
 					*path, GtkTreeIter *iter, UIData *ui);
 
 gint
-e_plugin_lib_enable (EPluginLib *ep, gint enable)
+e_plugin_lib_enable (EPlugin *ep, gint enable)
 {
 	return 0;
 }
diff --git a/plugins/bbdb/bbdb.c b/plugins/bbdb/bbdb.c
index c7d7cdf..d5104dc 100644
--- a/plugins/bbdb/bbdb.c
+++ b/plugins/bbdb/bbdb.c
@@ -42,7 +42,7 @@
 #define d(x)
 
 /* Plugin hooks */
-gint e_plugin_lib_enable (EPluginLib *ep, gint enable);
+gint e_plugin_lib_enable (EPlugin *ep, gint enable);
 void bbdb_handle_send (EPlugin *ep, EMEventTargetComposer *target);
 GtkWidget *bbdb_page_factory (EPlugin *ep, EConfigHookItemFactoryData *hook_data);
 
@@ -106,7 +106,7 @@ find_esource_by_uri (ESourceList *source_list, const gchar *target_uri)
 }
 
 gint
-e_plugin_lib_enable (EPluginLib *ep, gint enable)
+e_plugin_lib_enable (EPlugin *ep, gint enable)
 {
 	/* Start up the plugin. */
 	if (enable) {
diff --git a/plugins/bogo-junk-plugin/bf-junk-filter.c b/plugins/bogo-junk-plugin/bf-junk-filter.c
index 3de8c30..da38422 100644
--- a/plugins/bogo-junk-plugin/bf-junk-filter.c
+++ b/plugins/bogo-junk-plugin/bf-junk-filter.c
@@ -44,7 +44,7 @@
 #include <gtk/gtk.h>
 #include <e-util/e-plugin.h>
 #include "mail/em-config.h"
-#include <mail/em-junk-hook.h>
+#include <mail/em-junk.h>
 #include <camel/camel-data-wrapper.h>
 #include <camel/camel-mime-message.h>
 #include <camel/camel-mime-parser.h>
@@ -70,15 +70,15 @@ static const gchar em_junk_bf_gconf_dir[] = EM_JUNK_BF_GCONF_DIR;
 GtkWidget * org_gnome_bogo_convert_unicode (struct _EPlugin *epl, struct _EConfigHookItemFactoryData *data);
 
 /* plugin fonction prototypes */
-gboolean em_junk_bf_check_junk (EPlugin *ep, EMJunkHookTarget *target);
-gpointer em_junk_bf_validate_binary (EPlugin *ep, EMJunkHookTarget *target);
-void em_junk_bf_report_junk (EPlugin *ep, EMJunkHookTarget *target);
-void em_junk_bf_report_non_junk (EPlugin *ep, EMJunkHookTarget *target);
-void em_junk_bf_commit_reports (EPlugin *ep, EMJunkHookTarget *target);
+gboolean em_junk_bf_check_junk (EPlugin *ep, EMJunkTarget *target);
+gpointer em_junk_bf_validate_binary (EPlugin *ep, EMJunkTarget *target);
+void em_junk_bf_report_junk (EPlugin *ep, EMJunkTarget *target);
+void em_junk_bf_report_non_junk (EPlugin *ep, EMJunkTarget *target);
+void em_junk_bf_commit_reports (EPlugin *ep, EMJunkTarget *target);
 static gint pipe_to_bogofilter (CamelMimeMessage *msg, const gchar **argv, GError **error);
 
 /* eplugin stuff */
-gint e_plugin_lib_enable (EPluginLib *ep, gint enable);
+gint e_plugin_lib_enable (EPlugin *ep, gint enable);
 
 #define EM_JUNK_BF_GCONF_DIR_LENGTH (G_N_ELEMENTS (em_junk_bf_gconf_dir) - 1)
 
@@ -241,7 +241,7 @@ em_junk_bf_setting_notify (GConfClient *gconf,
 }
 
 gboolean
-em_junk_bf_check_junk (EPlugin *ep, EMJunkHookTarget *target)
+em_junk_bf_check_junk (EPlugin *ep, EMJunkTarget *target)
 {
 	CamelMimeMessage *msg = target->m;
 	gint rv;
@@ -266,7 +266,7 @@ em_junk_bf_check_junk (EPlugin *ep, EMJunkHookTarget *target)
 }
 
 void
-em_junk_bf_report_junk (EPlugin *ep, EMJunkHookTarget *target)
+em_junk_bf_report_junk (EPlugin *ep, EMJunkTarget *target)
 {
 	CamelMimeMessage *msg = target->m;
 
@@ -287,7 +287,7 @@ em_junk_bf_report_junk (EPlugin *ep, EMJunkHookTarget *target)
 }
 
 void
-em_junk_bf_report_non_junk (EPlugin *ep, EMJunkHookTarget *target)
+em_junk_bf_report_non_junk (EPlugin *ep, EMJunkTarget *target)
 {
 	CamelMimeMessage *msg = target->m;
 
@@ -308,18 +308,18 @@ em_junk_bf_report_non_junk (EPlugin *ep, EMJunkHookTarget *target)
 }
 
 void
-em_junk_bf_commit_reports (EPlugin *ep, EMJunkHookTarget *target)
+em_junk_bf_commit_reports (EPlugin *ep, EMJunkTarget *target)
 {
 }
 
 gpointer
-em_junk_bf_validate_binary (EPlugin *ep, EMJunkHookTarget *target)
+em_junk_bf_validate_binary (EPlugin *ep, EMJunkTarget *target)
 {
 	return g_file_test (em_junk_bf_binary, G_FILE_TEST_EXISTS) ? (gpointer) "1" : NULL;
 }
 
 gint
-e_plugin_lib_enable (EPluginLib *ep, gint enable)
+e_plugin_lib_enable (EPlugin *ep, gint enable)
 {
 	GConfClient *gconf;
 
diff --git a/plugins/bogo-junk-plugin/org-gnome-bogo-junk-plugin.eplug.xml b/plugins/bogo-junk-plugin/org-gnome-bogo-junk-plugin.eplug.xml
index e1d8cc8..1317b98 100644
--- a/plugins/bogo-junk-plugin/org-gnome-bogo-junk-plugin.eplug.xml
+++ b/plugins/bogo-junk-plugin/org-gnome-bogo-junk-plugin.eplug.xml
@@ -7,13 +7,12 @@
 		<_description>Filter junk messages using Bogofilter.</_description>
 		<author name="Mikhail Zabaluev" email="mhz altlinux org"/>
 		<hook class="org.gnome.evolution.mail.junk:1.0">
-			<group id="EMJunk" >
-				<item name="Bogofilter" report_non_junk="em_junk_bf_report_non_junk"
-				      report_junk="em_junk_bf_report_junk"
-				      check_junk="em_junk_bf_check_junk"
-				      commit_reports="em_junk_bf_commit_reports" 
-				      validate_binary="em_junk_bf_validate_binary"/>
-			</group>
+			<interface name="Bogofilter"
+			  report_non_junk="em_junk_bf_report_non_junk"
+			  report_junk="em_junk_bf_report_junk"
+			  check_junk="em_junk_bf_check_junk"
+			  commit_reports="em_junk_bf_commit_reports" 
+			  validate_binary="em_junk_bf_validate_binary"/>
 		</hook>
 		<!-- hook into the 'mail properties' menu -->
 		<hook class="org.gnome.evolution.mail.config:1.0">
diff --git a/plugins/caldav/caldav-source.c b/plugins/caldav/caldav-source.c
index 3407353..f5d8f59 100644
--- a/plugins/caldav/caldav-source.c
+++ b/plugins/caldav/caldav-source.c
@@ -42,7 +42,7 @@
 
 /*****************************************************************************/
 /* prototypes */
-gint              e_plugin_lib_enable      (EPluginLib                 *ep,
+gint              e_plugin_lib_enable      (EPlugin                 *ep,
 					   gint                         enable);
 
 GtkWidget *      oge_caldav               (EPlugin                    *epl,
@@ -66,7 +66,7 @@ ensure_caldav_source_group (ECalSourceType source_type)
 }
 
 gint
-e_plugin_lib_enable (EPluginLib *ep, gint enable)
+e_plugin_lib_enable (EPlugin *ep, gint enable)
 {
 
 	if (enable) {
diff --git a/plugins/calendar-weather/calendar-weather.c b/plugins/calendar-weather/calendar-weather.c
index b49726a..b558f7e 100644
--- a/plugins/calendar-weather/calendar-weather.c
+++ b/plugins/calendar-weather/calendar-weather.c
@@ -42,12 +42,12 @@ GtkWidget *e_calendar_weather_refresh (EPlugin *epl, EConfigHookItemFactoryData
 GtkWidget *e_calendar_weather_units (EPlugin *epl, EConfigHookItemFactoryData *data);
 gboolean   e_calendar_weather_check (EPlugin *epl, EConfigHookPageCheckData *data);
 void       e_calendar_weather_migrate (EPlugin *epl, ECalEventTargetBackend *data);
-gint        e_plugin_lib_enable (EPluginLib *epl, gint enable);
+gint        e_plugin_lib_enable (EPlugin *epl, gint enable);
 
 #define WEATHER_BASE_URI "weather://"
 
 gint
-e_plugin_lib_enable (EPluginLib *epl, gint enable)
+e_plugin_lib_enable (EPlugin *epl, gint enable)
 {
 	GList *l;
 	const gchar *tmp;
diff --git a/plugins/email-custom-header/email-custom-header.c b/plugins/email-custom-header/email-custom-header.c
index 4e76f97..127cbdc 100644
--- a/plugins/email-custom-header/email-custom-header.c
+++ b/plugins/email-custom-header/email-custom-header.c
@@ -79,13 +79,13 @@ static void epech_dialog_dispose (GObject *object);
 static void epech_setup_widgets (CustomHeaderOptionsDialog *mch);
 static gint epech_check_existing_composer_window(gconstpointer a, gconstpointer b);
 static void commit_changes (ConfigData *cd);
-gint e_plugin_lib_enable (EPluginLib *ep, gint enable);
+gint e_plugin_lib_enable (EPlugin *ep, gint enable);
 GtkWidget *e_plugin_lib_get_configure_widget (EPlugin *epl);
 gboolean e_plugin_ui_init(GtkUIManager *ui_manager, EMsgComposer *composer);
 GtkWidget *org_gnome_email_custom_header_config_option (struct _EPlugin *epl, struct _EConfigHookItemFactoryData *data);
 
 gint
-e_plugin_lib_enable (EPluginLib *ep, gint enable)
+e_plugin_lib_enable (EPlugin *ep, gint enable)
 {
         return 0;
 }
diff --git a/plugins/exchange-operations/exchange-operations.c b/plugins/exchange-operations/exchange-operations.c
index d79948c..35ed781 100644
--- a/plugins/exchange-operations/exchange-operations.c
+++ b/plugins/exchange-operations/exchange-operations.c
@@ -58,7 +58,7 @@ free_exchange_listener (void)
 }
 
 gint
-e_plugin_lib_enable (EPluginLib *eplib, gint enable)
+e_plugin_lib_enable (EPlugin *eplib, gint enable)
 {
 	if (!exchange_global_config_listener) {
 		exchange_global_config_listener = exchange_config_listener_new ();
diff --git a/plugins/google-account-setup/google-source.c b/plugins/google-account-setup/google-source.c
index aea49fa..1dc76a0 100644
--- a/plugins/google-account-setup/google-source.c
+++ b/plugins/google-account-setup/google-source.c
@@ -60,7 +60,7 @@
 
 /*****************************************************************************/
 /* prototypes */
-gint e_plugin_lib_enable (EPluginLib *ep, gint enable);
+gint e_plugin_lib_enable (EPlugin *ep, gint enable);
 GtkWidget *plugin_google (EPlugin *epl, EConfigHookItemFactoryData *data);
 void e_calendar_google_migrate (EPlugin *epl, ECalEventTargetBackend *data);
 
@@ -82,7 +82,7 @@ ensure_google_source_group (void)
 }
 
 gint
-e_plugin_lib_enable (EPluginLib *ep, gint enable)
+e_plugin_lib_enable (EPlugin *ep, gint enable)
 {
 
 	if (enable) {
diff --git a/plugins/groupwise-account-setup/groupwise-account-setup.c b/plugins/groupwise-account-setup/groupwise-account-setup.c
index 6375446..0872a9c 100644
--- a/plugins/groupwise-account-setup/groupwise-account-setup.c
+++ b/plugins/groupwise-account-setup/groupwise-account-setup.c
@@ -32,7 +32,7 @@
 
 static CamelGwListener *config_listener = NULL;
 
-gint e_plugin_lib_enable (EPluginLib *ep, gint enable);
+gint e_plugin_lib_enable (EPlugin *ep, gint enable);
 GtkWidget* org_gnome_gw_account_setup(struct _EPlugin *epl, struct _EConfigHookItemFactoryData *data);
 void ensure_mandatory_esource_properties (EPlugin *ep, ESEventTargetUpgrade *target);
 
@@ -114,7 +114,7 @@ free_groupwise_listener ( void )
 }
 
 gint
-e_plugin_lib_enable (EPluginLib *ep, gint enable)
+e_plugin_lib_enable (EPlugin *ep, gint enable)
 {
 	if (!config_listener) {
 		config_listener = camel_gw_listener_new ();
diff --git a/plugins/hula-account-setup/hula-account-setup.c b/plugins/hula-account-setup/hula-account-setup.c
index 3f5898b..34427f3 100644
--- a/plugins/hula-account-setup/hula-account-setup.c
+++ b/plugins/hula-account-setup/hula-account-setup.c
@@ -27,7 +27,7 @@
 
 static CamelHulaListener *config_listener = NULL;
 
-gint e_plugin_lib_enable (EPluginLib *ep, gint enable);
+gint e_plugin_lib_enable (EPlugin *ep, gint enable);
 GtkWidget* org_gnome_evolution_hula_account_setup (struct _EPlugin *epl, struct _EConfigHookItemFactoryData *data);
 
 static void
@@ -37,7 +37,7 @@ free_hula_listener ( void )
 }
 
 gint
-e_plugin_lib_enable (EPluginLib *ep, gint enable)
+e_plugin_lib_enable (EPlugin *ep, gint enable)
 {
 	if (!config_listener) {
 		config_listener = camel_hula_listener_new ();
diff --git a/plugins/mail-notification/mail-notification.c b/plugins/mail-notification/mail-notification.c
index 8a2e7c2..07483e7 100644
--- a/plugins/mail-notification/mail-notification.c
+++ b/plugins/mail-notification/mail-notification.c
@@ -885,7 +885,7 @@ get_cfg_widget (void)
 void org_gnome_mail_new_notify (EPlugin *ep, EMEventTargetFolder *t);
 void org_gnome_mail_read_notify (EPlugin *ep, EMEventTargetMessage *t);
 
-gint e_plugin_lib_enable (EPluginLib *ep, gint enable);
+gint e_plugin_lib_enable (EPlugin *ep, gint enable);
 GtkWidget *e_plugin_lib_get_configure_widget (EPlugin *epl);
 
 void
@@ -935,7 +935,7 @@ org_gnome_mail_read_notify (EPlugin *ep, EMEventTargetMessage *t)
 }
 
 gint
-e_plugin_lib_enable (EPluginLib *ep, gint enable)
+e_plugin_lib_enable (EPlugin *ep, gint enable)
 {
 	if (enable) {
 #ifdef HAVE_DBUS
diff --git a/plugins/prefer-plain/prefer-plain.c b/plugins/prefer-plain/prefer-plain.c
index 0a1da1f..b896f19 100644
--- a/plugins/prefer-plain/prefer-plain.c
+++ b/plugins/prefer-plain/prefer-plain.c
@@ -243,10 +243,10 @@ org_gnome_prefer_plain_config_mode(struct _EPlugin *epl, struct _EConfigHookItem
 	return (GtkWidget *)dropdown;
 }
 
-gint e_plugin_lib_enable(EPluginLib *ep, gint enable);
+gint e_plugin_lib_enable(EPlugin *ep, gint enable);
 
 gint
-e_plugin_lib_enable(EPluginLib *ep, gint enable)
+e_plugin_lib_enable(EPlugin *ep, gint enable)
 {
 	gchar *key;
 	gint i;
diff --git a/plugins/pst-import/pst-importer.c b/plugins/pst-import/pst-importer.c
index 976eaa4..8009d56 100644
--- a/plugins/pst-import/pst-importer.c
+++ b/plugins/pst-import/pst-importer.c
@@ -94,7 +94,7 @@ gboolean org_credativ_evolution_readpst_supported (EPlugin *epl, EImportTarget *
 GtkWidget *org_credativ_evolution_readpst_getwidget (EImport *ei, EImportTarget *target, EImportImporter *im);
 void org_credativ_evolution_readpst_import (EImport *ei, EImportTarget *target, EImportImporter *im);
 void org_credativ_evolution_readpst_cancel (EImport *ei, EImportTarget *target, EImportImporter *im);
-gint e_plugin_lib_enable (EPluginLib *ep, gint enable);
+gint e_plugin_lib_enable (EPlugin *ep, gint enable);
 
 /* em-folder-selection-button.h is private, even though other internal evo plugins use it!
    so declare the functions here
@@ -1655,7 +1655,7 @@ org_credativ_evolution_readpst_cancel (EImport *ei, EImportTarget *target, EImpo
 }
 
 gint
-e_plugin_lib_enable (EPluginLib *ep, gint enable)
+e_plugin_lib_enable (EPlugin *ep, gint enable)
 {
 	if (enable) {
 		bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR);
diff --git a/plugins/sa-junk-plugin/em-junk-filter.c b/plugins/sa-junk-plugin/em-junk-filter.c
index 74010f2..ff38f18 100644
--- a/plugins/sa-junk-plugin/em-junk-filter.c
+++ b/plugins/sa-junk-plugin/em-junk-filter.c
@@ -42,7 +42,7 @@
 #include <camel/camel-stream-fs.h>
 #include <camel/camel-stream-mem.h>
 #include <camel/camel-i18n.h>
-#include <mail/em-junk-hook.h>
+#include <mail/em-junk.h>
 #include <mail/em-utils.h>
 #include <e-util/e-mktemp.h>
 
@@ -58,10 +58,10 @@ static pthread_mutex_t em_junk_sa_report_lock = PTHREAD_MUTEX_INITIALIZER;
 static pthread_mutex_t em_junk_sa_preferred_socket_path_lock = PTHREAD_MUTEX_INITIALIZER;
 static pthread_mutex_t em_junk_sa_spamd_restart_lock = PTHREAD_MUTEX_INITIALIZER;
 
-gint e_plugin_lib_enable (EPluginLib *ep, gint enable);
-gboolean em_junk_sa_check_junk (EPlugin *ep, EMJunkHookTarget *target);
-void em_junk_sa_report_junk (EPlugin *ep, EMJunkHookTarget *target);
-void em_junk_sa_report_non_junk (EPlugin *ep, EMJunkHookTarget *target);
+gint e_plugin_lib_enable (EPlugin *ep, gint enable);
+gboolean em_junk_sa_check_junk (EPlugin *ep, EMJunkTarget *target);
+void em_junk_sa_report_junk (EPlugin *ep, EMJunkTarget *target);
+void em_junk_sa_report_non_junk (EPlugin *ep, EMJunkTarget *target);
 void em_junk_sa_commit_reports (EPlugin *ep);
 gpointer em_junk_sa_validate_binary (EPlugin *ep);
 GtkWidget *org_gnome_sa_use_remote_tests (struct _EPlugin *epl, struct _EConfigHookItemFactoryData *data);
@@ -571,7 +571,7 @@ em_junk_sa_respawn_spamd ()
 }
 
 gboolean
-em_junk_sa_check_junk(EPlugin *ep, EMJunkHookTarget *target)
+em_junk_sa_check_junk(EPlugin *ep, EMJunkTarget *target)
 {
 	GByteArray *out = NULL;
 	const gchar *argv[7];
@@ -675,7 +675,7 @@ get_spamassassin_version ()
 }
 
 void
-em_junk_sa_report_junk (EPlugin *ep, EMJunkHookTarget *target)
+em_junk_sa_report_junk (EPlugin *ep, EMJunkTarget *target)
 {
 	const gchar *sync_op =
 		(get_spamassassin_version () >= 3)
@@ -715,7 +715,7 @@ em_junk_sa_report_junk (EPlugin *ep, EMJunkHookTarget *target)
 }
 
 void
-em_junk_sa_report_non_junk (EPlugin *ep, EMJunkHookTarget *target)
+em_junk_sa_report_non_junk (EPlugin *ep, EMJunkTarget *target)
 {
 	const gchar *sync_op =
 		(get_spamassassin_version () >= 3)
@@ -812,7 +812,7 @@ em_junk_sa_setting_notify(GConfClient *gconf, guint cnxn_id, GConfEntry *entry,
 }
 
 gint
-e_plugin_lib_enable (EPluginLib *ep, gint enable)
+e_plugin_lib_enable (EPlugin *ep, gint enable)
 {
 	em_junk_sa_init();
 
diff --git a/plugins/sa-junk-plugin/org-gnome-sa-junk-plugin.eplug.xml b/plugins/sa-junk-plugin/org-gnome-sa-junk-plugin.eplug.xml
index 3403a3b..83ed170 100644
--- a/plugins/sa-junk-plugin/org-gnome-sa-junk-plugin.eplug.xml
+++ b/plugins/sa-junk-plugin/org-gnome-sa-junk-plugin.eplug.xml
@@ -6,14 +6,12 @@
 		<_description>Filter junk messages using SpamAssassin.</_description>
 		<author name="Vivek Jain" email="jvivek novell com"/>
 		<hook class="org.gnome.evolution.mail.junk:1.0">
-			<group id="EMJunk" >
-				<item   name="SpamAssassin" 
-				        check_junk="em_junk_sa_check_junk" 
-				        report_junk="em_junk_sa_report_junk" 
-					report_non_junk="em_junk_sa_report_non_junk" 
-					commit_reports="em_junk_sa_commit_reports"
-					validate_binary="em_junk_sa_validate_binary"/>
-			</group>
+			<interface name="SpamAssassin" 
+			  check_junk="em_junk_sa_check_junk" 
+			  report_junk="em_junk_sa_report_junk" 
+			  report_non_junk="em_junk_sa_report_non_junk" 
+			  commit_reports="em_junk_sa_commit_reports"
+			  validate_binary="em_junk_sa_validate_binary"/>
 		</hook>
 		<!-- hook into the 'mail properties' menu -->
 		<hook class="org.gnome.evolution.mail.config:1.0">
@@ -21,6 +19,6 @@
 				<item type="section_table" path="40.junk/10.options" _label="SpamAssassin Options"/>
 				<item type="item_table" path="40.junk/20.options" factory="org_gnome_sa_use_remote_tests"/>
 		        </group>
-			    </hook>
+		</hook>
 	</e-plugin>
 </e-plugin-list>
diff --git a/plugins/tnef-attachments/tnef-plugin.c b/plugins/tnef-attachments/tnef-plugin.c
index a74dcee..3e537e1 100644
--- a/plugins/tnef-attachments/tnef-plugin.c
+++ b/plugins/tnef-attachments/tnef-plugin.c
@@ -192,10 +192,10 @@ org_gnome_format_tnef(gpointer ep, EMFormatHookTarget *t)
 	g_free(tmpdir);
 }
 
-gint e_plugin_lib_enable(EPluginLib *ep, gint enable);
+gint e_plugin_lib_enable(EPlugin *ep, gint enable);
 
 gint
-e_plugin_lib_enable(EPluginLib *ep, gint enable)
+e_plugin_lib_enable(EPlugin *ep, gint enable)
 {
     if (loaded)
 	    return 0;
diff --git a/plugins/webdav-account-setup/webdav-contacts-source.c b/plugins/webdav-account-setup/webdav-contacts-source.c
index b6d4443..990a541 100644
--- a/plugins/webdav-account-setup/webdav-contacts-source.c
+++ b/plugins/webdav-account-setup/webdav-contacts-source.c
@@ -52,7 +52,7 @@ GtkWidget *
 plugin_webdav_contacts(EPlugin *epl, EConfigHookItemFactoryData *data);
 
 gint
-e_plugin_lib_enable(EPluginLib *ep, gint enable);
+e_plugin_lib_enable(EPlugin *ep, gint enable);
 
 static void
 ensure_webdav_contacts_source_group(void)
@@ -341,7 +341,7 @@ plugin_webdav_contacts(EPlugin *epl, EConfigHookItemFactoryData *data)
 }
 
 gint
-e_plugin_lib_enable(EPluginLib *ep, gint enable)
+e_plugin_lib_enable(EPlugin *ep, gint enable)
 {
 	if (enable) {
 		ensure_webdav_contacts_source_group();
diff --git a/shell/main.c b/shell/main.c
index 5adae2e..72333c1 100644
--- a/shell/main.c
+++ b/shell/main.c
@@ -257,12 +257,6 @@ idle_cb (gchar **uris)
 	if (unique_app_is_running (UNIQUE_APP (shell)))
 		gtk_main_quit ();
 
-	/* This must be done after EShell has loaded all the backends.
-	 * For example the mail backend makes the global variable 'session'
-	 * which is being used by several EPlugins */
-	else if (uris == NULL && !disable_eplugin)
-		e_plugin_load_plugins_with_missing_symbols ();
-
 	return FALSE;
 }
 
@@ -406,11 +400,11 @@ static void
 create_default_shell (void)
 {
 	EShell *shell;
-	GConfClient *conf_client;
+	GConfClient *client;
 	gboolean online = TRUE;
 	GError *error = NULL;
 
-	conf_client = gconf_client_get_default ();
+	client = gconf_client_get_default ();
 
 	if (start_online)
 		online = TRUE;
@@ -421,7 +415,7 @@ create_default_shell (void)
 		gboolean value;
 
 		key = "/apps/evolution/shell/start_offline";
-		value = gconf_client_get_bool (conf_client, key, &error);
+		value = gconf_client_get_bool (client, key, &error);
 		if (error == NULL)
 			online = !value;
 		else {
@@ -440,7 +434,7 @@ create_default_shell (void)
 		shell, "window-destroyed",
 		G_CALLBACK (shell_window_destroyed_cb), NULL);
 
-	g_object_unref (conf_client);
+	g_object_unref (client);
 
 	/* EShell keeps its own reference to the first instance for use
 	 * in e_shell_get_default(), so it's safe to unreference here. */
@@ -568,18 +562,6 @@ main (gint argc, gchar **argv)
 	categories_icon_theme_hack ();
 	gtk_accel_map_load (e_get_accels_filename ());
 
-	if (!disable_eplugin) {
-		e_plugin_register_type (e_plugin_lib_get_type ());
-		e_plugin_hook_register_type (es_event_hook_get_type ());
-#ifdef ENABLE_PROFILING
-		e_plugin_hook_register_type (e_profile_event_hook_get_type ());
-#endif
-		e_plugin_hook_register_type (e_plugin_type_hook_get_type ());
-		e_plugin_hook_register_type (e_import_hook_get_type ());
-		e_plugin_hook_register_type (E_TYPE_PLUGIN_UI_HOOK);
-		e_plugin_load_plugins ();
-	}
-
 #ifdef DEVELOPMENT
 	skip_warning_dialog = gconf_client_get_bool (
 		client, SKIP_WARNING_DIALOG_KEY, NULL);
@@ -594,6 +576,20 @@ main (gint argc, gchar **argv)
 
 	create_default_shell ();
 
+	if (!disable_eplugin) {
+		/* Register built-in plugin hook types. */
+		es_event_hook_get_type ();
+#ifdef ENABLE_PROFILING
+		e_profile_event_hook_get_type ();
+#endif
+		e_import_hook_get_type ();
+		e_plugin_ui_hook_get_type ();
+
+		/* All EPlugin and EPluginHook subclasses should be
+		 * registered in GType now, so load plugins now. */
+		e_plugin_load_plugins ();
+	}
+
 	gtk_main ();
 
 	/* Drop what should be the last reference to the shell.



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