[gedit/new-message-bus] Implemented new bindable message bus



commit cccbf6bd0a69fa13471027c43a43d2cb5e78a33a
Author: Jesse van den Kieboom <jesse vandenkieboom epfl ch>
Date:   Wed Mar 23 22:31:11 2011 +0100

    Implemented new bindable message bus

 configure.ac                                       |   13 +
 gedit/Gedit.py                                     |   35 +
 gedit/Makefile.am                                  |    8 +-
 gedit/gedit-marshal.list                           |    1 +
 gedit/gedit-message-bus.c                          |  805 +++++++++++---------
 gedit/gedit-message-bus.h                          |  189 +++---
 gedit/gedit-message-type.c                         |  544 -------------
 gedit/gedit-message-type.h                         |   89 ---
 gedit/gedit-message.c                              |  539 +++----------
 gedit/gedit-message.h                              |   52 +-
 plugins/filebrowser/Makefile.am                    |   12 +
 plugins/filebrowser/gedit-file-browser-messages.c  |  438 ++++++------
 plugins/filebrowser/messages.xml                   |   44 ++
 .../gedit-file-browser-message-activation.c        |   80 ++
 .../gedit-file-browser-message-activation.h        |   46 ++
 .../gedit-file-browser-message-add-context-item.c  |  144 ++++
 .../gedit-file-browser-message-add-context-item.h  |   46 ++
 .../gedit-file-browser-message-add-filter.c        |  137 ++++
 .../gedit-file-browser-message-add-filter.h        |   46 ++
 .../messages/gedit-file-browser-message-get-root.c |  102 +++
 .../messages/gedit-file-browser-message-get-root.h |   46 ++
 .../messages/gedit-file-browser-message-get-view.c |  102 +++
 .../messages/gedit-file-browser-message-get-view.h |   46 ++
 .../gedit-file-browser-message-id-location.c       |  142 ++++
 .../gedit-file-browser-message-id-location.h       |   46 ++
 .../messages/gedit-file-browser-message-id.c       |   82 ++
 .../messages/gedit-file-browser-message-id.h       |   46 ++
 .../gedit-file-browser-message-set-emblem.c        |  117 +++
 .../gedit-file-browser-message-set-emblem.h        |   46 ++
 .../messages/gedit-file-browser-message-set-root.c |  124 +++
 .../messages/gedit-file-browser-message-set-root.h |   46 ++
 plugins/filebrowser/messages/messages.h            |   15 +
 plugins/quickopen/quickopen/__init__.py            |   17 +-
 plugins/snippets/snippets/windowactivatable.py     |   50 +-
 tools/generate-message.py                          |  685 +++++++++++++++++
 35 files changed, 3196 insertions(+), 1784 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index 3504322..e1b3b2e 100644
--- a/configure.ac
+++ b/configure.ac
@@ -294,6 +294,19 @@ fi
 
 AM_CONDITIONAL(ENABLE_ZEITGEIST, test x"$enable_zeitgeist" = "xyes")
 
+PYGOBJECT_REQUIRED=2.28
+
+PKG_CHECK_EXISTS([pygobject-2.0 >= $PYGOBJECT_REQUIRED],
+                 [have_pygobject=yes],[have_pygobject=no])
+
+if test "x$have_pygobject" = "xyes";
+then
+	pyoverridesdir=`$PKG_CONFIG --variable=overridesdir pygobject-2.0`
+	AC_SUBST(pyoverridesdir)
+fi
+
+AM_CONDITIONAL(HAVE_PYGOBJECT, test x"$have_pygobject" = "xyes")
+
 dnl ================================================================
 dnl Start of pkg-config checks
 dnl ================================================================
diff --git a/gedit/Gedit.py b/gedit/Gedit.py
new file mode 100644
index 0000000..7603583
--- /dev/null
+++ b/gedit/Gedit.py
@@ -0,0 +1,35 @@
+from gi.repository import GObject
+from ..overrides import override
+from ..importer import modules
+
+Gedit = modules['Gedit']._introspection_module
+__all__ = []
+
+class MessageBus(Gedit.MessageBus):
+    def create(self, object_path, method, **kwargs):
+        tp = self.lookup(object_path, method)
+
+        if not tp.is_a(Gedit.Message.__gtype__):
+            return None
+
+        kwargs['object-path'] = object_path
+        kwargs['method'] = method
+
+        return GObject.new(tp, **kwargs)
+
+    def send_sync(self, object_path, method, **kwargs):
+        msg = self.create(object_path, method, **kwargs)
+        self.send_message_sync(msg)
+
+        return msg
+
+    def send(self, object_path, method, **kwargs):
+        msg = self.create(object_path, method, **kwargs)
+        self.send_message(msg)
+
+        return msg
+
+MessageBus = override(MessageBus)
+__all__.append('MessageBus')
+
+# vi:ex:ts=4:et
diff --git a/gedit/Makefile.am b/gedit/Makefile.am
index 430a416..9d1e407 100644
--- a/gedit/Makefile.am
+++ b/gedit/Makefile.am
@@ -145,7 +145,6 @@ INST_H_FILES =				\
 	gedit-encodings.h		\
 	gedit-encodings-combo-box.h	\
 	gedit-message-bus.h		\
-	gedit-message-type.h		\
 	gedit-message.h			\
 	gedit-panel.h			\
 	gedit-progress-info-bar.h	\
@@ -202,7 +201,6 @@ libgedit_c_files =			\
 	gedit-io-error-info-bar.c	\
 	gedit-language-manager.c	\
 	gedit-message-bus.c		\
-	gedit-message-type.c		\
 	gedit-message.c			\
 	gedit-multi-notebook.c		\
 	gedit-notebook.c		\
@@ -264,6 +262,12 @@ ui_DATA = 				\
 	gedit-ui.xml			\
 	gedit-print-preferences.ui
 
+if HAVE_PYGOBJECT
+overridesdir = $(pyoverridesdir)
+overrides_DATA =			\
+	Gedit.py
+endif
+
 EXTRA_DIST = 				\
 	$(ui_DATA)			\
 	gedit-enum-types.h.template	\
diff --git a/gedit/gedit-marshal.list b/gedit/gedit-marshal.list
index bf6014a..8ed0c94 100644
--- a/gedit/gedit-marshal.list
+++ b/gedit/gedit-marshal.list
@@ -15,3 +15,4 @@ VOID:VOID
 VOID:INT,INT
 VOID:OBJECT,OBJECT,INT
 OBJECT:OBJECT,OBJECT,INT,INT
+VOID:STRING,STRING
diff --git a/gedit/gedit-message-bus.c b/gedit/gedit-message-bus.c
index 6882255..7939840 100644
--- a/gedit/gedit-message-bus.c
+++ b/gedit/gedit-message-bus.c
@@ -21,6 +21,7 @@
  */
 
 #include "gedit-message-bus.h"
+#include "gedit-marshal.h"
 
 #include <string.h>
 #include <stdarg.h>
@@ -68,8 +69,8 @@
  *
  * // Register 'method' at '/plugins/example' with one required
  * // string argument 'arg1'
- * GeditMessageType *message_type = gedit_message_bus_register ("/plugins/example", "method", 
- *                                                              0, 
+ * GeditMessageType *message_type = gedit_message_bus_register ("/plugins/example", "method",
+ *                                                              0,
  *                                                              "arg1", G_TYPE_STRING,
  *                                                              NULL);
  * </programlisting>
@@ -83,20 +84,20 @@
  *                    gpointer         user_data)
  * {
  * 	gchar *arg1 = NULL;
- *	
+ *
  * 	gedit_message_get (message, "arg1", &arg1, NULL);
  * 	g_message ("Evoked /plugins/example.method with: %s", arg1);
  * 	g_free (arg1);
  * }
  *
  * GeditMessageBus *bus = gedit_message_bus_get_default ();
- * 
- * guint id = gedit_message_bus_connect (bus, 
+ *
+ * guint id = gedit_message_bus_connect (bus,
  *                                       "/plugins/example", "method",
  *                                       example_method_cb,
  *                                       NULL,
  *                                       NULL);
- *                                        
+ *
  * </programlisting>
  * </example>
  * <example>
@@ -104,9 +105,9 @@
  * <programlisting>
  * GeditMessageBus *bus = gedit_message_bus_get_default ();
  *
- * gedit_message_bus_send (bus, 
- *                         "/plugins/example", "method", 
- *                         "arg1", "Hello World", 
+ * gedit_message_bus_send (bus,
+ *                         "/plugins/example", "method",
+ *                         "arg1", "Hello World",
  *                         NULL);
  * </programlisting>
  * </example>
@@ -114,7 +115,7 @@
  * Since: 2.25.3
  *
  */
- 
+
 #define GEDIT_MESSAGE_BUS_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE((object), GEDIT_TYPE_MESSAGE_BUS, GeditMessageBusPrivate))
 
 typedef struct
@@ -122,6 +123,13 @@ typedef struct
 	gchar *object_path;
 	gchar *method;
 
+	gchar *identifier;
+} MessageIdentifier;
+
+typedef struct
+{
+	MessageIdentifier *identifier;
+
 	GList *listeners;
 } Message;
 
@@ -150,7 +158,7 @@ struct _GeditMessageBusPrivate
 	guint idle_id;
 
 	guint next_id;
-	
+
 	GHashTable *types; /* mapping from identifier to GeditMessageType */
 };
 
@@ -166,26 +174,68 @@ enum
 static guint message_bus_signals[LAST_SIGNAL];
 
 static void gedit_message_bus_dispatch_real (GeditMessageBus *bus,
-				 	     GeditMessage    *message);
+                                             GeditMessage    *message);
 
 G_DEFINE_TYPE(GeditMessageBus, gedit_message_bus, G_TYPE_OBJECT)
 
+static MessageIdentifier *
+message_identifier_new (const gchar *object_path,
+                        const gchar *method)
+{
+	MessageIdentifier *ret;
+
+	ret = g_slice_new (MessageIdentifier);
+
+	ret->object_path = g_strdup (object_path);
+	ret->method = g_strdup (method);
+
+	ret->identifier = gedit_message_type_identifier (object_path, method);
+
+	return ret;
+}
+
+static void
+message_identifier_free (MessageIdentifier *identifier)
+{
+	g_free (identifier->object_path);
+	g_free (identifier->method);
+	g_free (identifier->identifier);
+
+	g_slice_free (MessageIdentifier, identifier);
+}
+
+static guint
+message_identifier_hash (gconstpointer id)
+{
+	return g_str_hash (((MessageIdentifier *)id)->identifier);
+}
+
+static gboolean
+message_identifier_equal (gconstpointer id1,
+                          gconstpointer id2)
+{
+	return g_str_equal (((MessageIdentifier *)id1)->identifier,
+	                    ((MessageIdentifier *)id2)->identifier);
+}
+
 static void
 listener_free (Listener *listener)
 {
 	if (listener->destroy_data)
+	{
 		listener->destroy_data (listener->user_data);
+	}
 
-	g_free (listener);
+	g_slice_free (Listener, listener);
 }
 
 static void
 message_free (Message *message)
 {
-	g_free (message->method);
-	g_free (message->object_path);
+	message_identifier_free (message->identifier);
+
 	g_list_free_full (message->listeners, (GDestroyNotify) listener_free);
-	g_free (message);
+	g_slice_free (Message, message);
 }
 
 static void
@@ -198,16 +248,18 @@ static void
 gedit_message_bus_finalize (GObject *object)
 {
 	GeditMessageBus *bus = GEDIT_MESSAGE_BUS (object);
-	
+
 	if (bus->priv->idle_id != 0)
+	{
 		g_source_remove (bus->priv->idle_id);
-	
+	}
+
 	message_queue_free (bus->priv->message_queue);
 
 	g_hash_table_destroy (bus->priv->messages);
 	g_hash_table_destroy (bus->priv->idmap);
 	g_hash_table_destroy (bus->priv->types);
-	
+
 	G_OBJECT_CLASS (gedit_message_bus_parent_class)->finalize (object);
 }
 
@@ -215,9 +267,9 @@ static void
 gedit_message_bus_class_init (GeditMessageBusClass *klass)
 {
 	GObjectClass *object_class = G_OBJECT_CLASS (klass);
-	
+
 	object_class->finalize = gedit_message_bus_finalize;
-	
+
 	klass->dispatch = gedit_message_bus_dispatch_real;
 
 	/**
@@ -226,21 +278,22 @@ gedit_message_bus_class_init (GeditMessageBusClass *klass)
 	 * @message: the #GeditMessage to dispatch
 	 *
 	 * The "dispatch" signal is emitted when a message is to be dispatched.
-	 * The message is dispatched in the default handler of this signal. 
+	 * The message is dispatched in the default handler of this signal.
 	 * Primary use of this signal is to customize the dispatch of a message
 	 * (for instance to automatically dispatch all messages over DBus).
-	 *2
+	 *
 	 */
 	message_bus_signals[DISPATCH] =
-   		g_signal_new ("dispatch",
-			      G_OBJECT_CLASS_TYPE (object_class),
-			      G_SIGNAL_RUN_LAST,
-			      G_STRUCT_OFFSET (GeditMessageBusClass, dispatch),
-			      NULL, NULL,
-			      g_cclosure_marshal_VOID__OBJECT,
-			      G_TYPE_NONE,
-			      1,
-			      GEDIT_TYPE_MESSAGE);
+		g_signal_new ("dispatch",
+		              G_OBJECT_CLASS_TYPE (object_class),
+		              G_SIGNAL_RUN_LAST,
+		              G_STRUCT_OFFSET (GeditMessageBusClass, dispatch),
+		              NULL,
+		              NULL,
+		              g_cclosure_marshal_VOID__OBJECT,
+		              G_TYPE_NONE,
+		              1,
+		              GEDIT_TYPE_MESSAGE);
 
 	/**
 	 * GeditMessageBus::registered:
@@ -252,89 +305,97 @@ gedit_message_bus_class_init (GeditMessageBusClass *klass)
 	 *
 	 */
 	message_bus_signals[REGISTERED] =
-   		g_signal_new ("registered",
-			      G_OBJECT_CLASS_TYPE (object_class),
-			      G_SIGNAL_RUN_LAST,
-			      G_STRUCT_OFFSET (GeditMessageBusClass, registered),
-			      NULL, NULL,
-			      g_cclosure_marshal_VOID__BOXED,
-			      G_TYPE_NONE,
-			      1,
-			      GEDIT_TYPE_MESSAGE_TYPE);
+		g_signal_new ("registered",
+		              G_OBJECT_CLASS_TYPE (object_class),
+		              G_SIGNAL_RUN_LAST,
+		              G_STRUCT_OFFSET (GeditMessageBusClass, registered),
+		              NULL,
+		              NULL,
+		              gedit_marshal_VOID__STRING_STRING,
+		              G_TYPE_NONE,
+		              2,
+		              G_TYPE_STRING,
+		              G_TYPE_STRING);
 
 	/**
 	 * GeditMessageBus::unregistered:
 	 * @bus: a #GeditMessageBus
 	 * @message_type: the unregistered #GeditMessageType
 	 *
-	 * The "unregistered" signal is emitted when a message has been 
+	 * The "unregistered" signal is emitted when a message has been
 	 * unregistered from the bus.
 	 *
 	 */
 	message_bus_signals[UNREGISTERED] =
-   		g_signal_new ("unregistered",
-			      G_OBJECT_CLASS_TYPE (object_class),
-			      G_SIGNAL_RUN_LAST,
-			      G_STRUCT_OFFSET (GeditMessageBusClass, unregistered),
-			      NULL, NULL,
-			      g_cclosure_marshal_VOID__BOXED,
-			      G_TYPE_NONE,
-			      1,
-			      GEDIT_TYPE_MESSAGE_TYPE);
+		g_signal_new ("unregistered",
+		              G_OBJECT_CLASS_TYPE (object_class),
+		              G_SIGNAL_RUN_LAST,
+		              G_STRUCT_OFFSET (GeditMessageBusClass, unregistered),
+		              NULL,
+		              NULL,
+		              gedit_marshal_VOID__STRING_STRING,
+		              G_TYPE_NONE,
+		              2,
+		              G_TYPE_STRING,
+		              G_TYPE_STRING);
 
 	g_type_class_add_private (object_class, sizeof (GeditMessageBusPrivate));
 }
 
 static Message *
 message_new (GeditMessageBus *bus,
-	     const gchar     *object_path,
-	     const gchar     *method)
+             const gchar     *object_path,
+             const gchar     *method)
 {
-	Message *message = g_new (Message, 1);
-	
-	message->object_path = g_strdup (object_path);
-	message->method = g_strdup (method);
+	Message *message = g_slice_new (Message);
+
+	message->identifier = message_identifier_new (object_path, method);
 	message->listeners = NULL;
 
-	g_hash_table_insert (bus->priv->messages, 
-			     gedit_message_type_identifier (object_path, method),
-			     message);
+	g_hash_table_insert (bus->priv->messages,
+	                     message->identifier,
+	                     message);
+
 	return message;
 }
 
 static Message *
 lookup_message (GeditMessageBus *bus,
-	       const gchar      *object_path,
-	       const gchar      *method,
-	       gboolean          create)
+                const gchar      *object_path,
+                const gchar      *method,
+                gboolean          create)
 {
-	gchar *identifier;
+	MessageIdentifier *identifier;
 	Message *message;
-	
-	identifier = gedit_message_type_identifier (object_path, method);
-	message = (Message *)g_hash_table_lookup (bus->priv->messages, identifier);
-	g_free (identifier);
+
+	identifier = message_identifier_new (object_path, method);
+	message = g_hash_table_lookup (bus->priv->messages, identifier);
+	message_identifier_free (identifier);
 
 	if (!message && !create)
+	{
 		return NULL;
-	
+	}
+
 	if (!message)
+	{
 		message = message_new (bus, object_path, method);
-	
+	}
+
 	return message;
 }
 
 static guint
 add_listener (GeditMessageBus      *bus,
-	      Message		   *message,
-	      GeditMessageCallback  callback,
-	      gpointer		    user_data,
-	      GDestroyNotify        destroy_data)
+              Message		   *message,
+              GeditMessageCallback  callback,
+              gpointer		    user_data,
+              GDestroyNotify        destroy_data)
 {
 	Listener *listener;
 	IdMap *idmap;
-	
-	listener = g_new (Listener, 1);
+
+	listener = g_slice_new (Listener);
 	listener->id = ++bus->priv->next_id;
 	listener->callback = callback;
 	listener->user_data = user_data;
@@ -342,31 +403,32 @@ add_listener (GeditMessageBus      *bus,
 	listener->destroy_data = destroy_data;
 
 	message->listeners = g_list_append (message->listeners, listener);
-	
+
 	idmap = g_new (IdMap, 1);
 	idmap->message = message;
 	idmap->listener = g_list_last (message->listeners);
 
-	g_hash_table_insert (bus->priv->idmap, GINT_TO_POINTER (listener->id), idmap);	
+	g_hash_table_insert (bus->priv->idmap, GINT_TO_POINTER (listener->id), idmap);
+
 	return listener->id;
 }
 
 static void
 remove_listener (GeditMessageBus *bus,
-		 Message         *message,
-		 GList		 *listener)
+                 Message         *message,
+                 GList		 *listener)
 {
 	Listener *lst;
-	
+
 	lst = (Listener *)listener->data;
-	
+
 	/* remove from idmap */
 	g_hash_table_remove (bus->priv->idmap, GINT_TO_POINTER (lst->id));
 	listener_free (lst);
 
 	/* remove from list of listeners */
 	message->listeners = g_list_delete_link (message->listeners, listener);
-	
+
 	if (!message->listeners)
 	{
 		/* remove message because it does not have any listeners */
@@ -376,64 +438,71 @@ remove_listener (GeditMessageBus *bus,
 
 static void
 block_listener (GeditMessageBus *bus,
-		Message		*message,
-		GList		*listener)
+                Message         *message,
+                GList           *listener)
 {
 	Listener *lst;
-	
-	lst = (Listener *)listener->data;
+
+	lst = listener->data;
 	lst->blocked = TRUE;
 }
 
 static void
 unblock_listener (GeditMessageBus *bus,
-		  Message	  *message,
-		  GList		  *listener)
+                  Message         *message,
+                  GList           *listener)
 {
 	Listener *lst;
-	
-	lst = (Listener *)listener->data;
+
+	lst = listener->data;
 	lst->blocked = FALSE;
 }
 
 static void
 dispatch_message_real (GeditMessageBus *bus,
-		       Message         *msg,
-		       GeditMessage    *message)
+                       Message         *msg,
+                       GeditMessage    *message)
 {
 	GList *item;
-	
+
 	for (item = msg->listeners; item; item = item->next)
 	{
 		Listener *listener = (Listener *)item->data;
-		
+
 		if (!listener->blocked)
+		{
 			listener->callback (bus, message, listener->user_data);
+		}
 	}
 }
 
 static void
 gedit_message_bus_dispatch_real (GeditMessageBus *bus,
-				 GeditMessage    *message)
+                                 GeditMessage    *message)
 {
 	const gchar *object_path;
 	const gchar *method;
 	Message *msg;
-	
+
 	object_path = gedit_message_get_object_path (message);
 	method = gedit_message_get_method (message);
 
+	g_return_if_fail (object_path != NULL);
+	g_return_if_fail (method != NULL);
+
 	msg = lookup_message (bus, object_path, method, FALSE);
-	
+
 	if (msg)
+	{
 		dispatch_message_real (bus, msg, message);
+	}
 }
 
 static void
 dispatch_message (GeditMessageBus *bus,
-		  GeditMessage    *message)
+                  GeditMessage    *message)
 {
-	g_signal_emit (bus, message_bus_signals[DISPATCH], 0, message);	
+	g_signal_emit (bus, message_bus_signals[DISPATCH], 0, message);
 }
 
 static gboolean
@@ -441,7 +510,7 @@ idle_dispatch (GeditMessageBus *bus)
 {
 	GList *list;
 	GList *item;
-	
+
 	/* make sure to set idle_id to 0 first so that any new async messages
 	   will be queued properly */
 	bus->priv->idle_id = 0;
@@ -449,14 +518,14 @@ idle_dispatch (GeditMessageBus *bus)
 	/* reverse queue to get correct delivery order */
 	list = g_list_reverse (bus->priv->message_queue);
 	bus->priv->message_queue = NULL;
-	
+
 	for (item = list; item; item = item->next)
 	{
 		GeditMessage *msg = GEDIT_MESSAGE (item->data);
-		
+
 		dispatch_message (bus, msg);
 	}
-	
+
 	message_queue_free (list);
 	return FALSE;
 }
@@ -464,76 +533,82 @@ idle_dispatch (GeditMessageBus *bus)
 typedef void (*MatchCallback) (GeditMessageBus *, Message *, GList *);
 
 static void
-process_by_id (GeditMessageBus  *bus,
-	       guint	         id,
-	       MatchCallback     processor)
+process_by_id (GeditMessageBus *bus,
+               guint            id,
+               MatchCallback    processor)
 {
 	IdMap *idmap;
-	
+
 	idmap = (IdMap *)g_hash_table_lookup (bus->priv->idmap, GINT_TO_POINTER (id));
-	
+
 	if (idmap == NULL)
 	{
 		g_warning ("No handler registered with id `%d'", id);
 		return;
 	}
-		
+
 	processor (bus, idmap->message, idmap->listener);
 }
 
 static void
 process_by_match (GeditMessageBus      *bus,
-	          const gchar          *object_path,
-	          const gchar          *method,
-	          GeditMessageCallback  callback,
-	          gpointer              user_data,
-	          MatchCallback         processor)
+                  const gchar          *object_path,
+                  const gchar          *method,
+                  GeditMessageCallback  callback,
+                  gpointer              user_data,
+                  MatchCallback         processor)
 {
 	Message *message;
 	GList *item;
-	
+
 	message = lookup_message (bus, object_path, method, FALSE);
-	
+
 	if (!message)
 	{
 		g_warning ("No such handler registered for %s.%s", object_path, method);
 		return;
 	}
-	
+
 	for (item = message->listeners; item; item = item->next)
 	{
 		Listener *listener = (Listener *)item->data;
-		
-		if (listener->callback == callback && 
+
+		if (listener->callback == callback &&
 		    listener->user_data == user_data)
 		{
 			processor (bus, message, item);
 			return;
 		}
 	}
-	
+
 	g_warning ("No such handler registered for %s.%s", object_path, method);
 }
 
 static void
+free_type (gpointer data)
+{
+	g_slice_free (GType, data);
+}
+
+static void
 gedit_message_bus_init (GeditMessageBus *self)
 {
 	self->priv = GEDIT_MESSAGE_BUS_GET_PRIVATE (self);
-	
-	self->priv->messages = g_hash_table_new_full (g_str_hash,
-						      g_str_equal,
-						      (GDestroyNotify)g_free,
-						      (GDestroyNotify)message_free);
+
+	self->priv->messages = g_hash_table_new_full (message_identifier_hash,
+	                                              message_identifier_equal,
+	                                              NULL,
+	                                              (GDestroyNotify) message_free);
 
 	self->priv->idmap = g_hash_table_new_full (g_direct_hash,
-	 					   g_direct_equal,
-	 					   NULL,
-	 					   (GDestroyNotify)g_free);
-	 					   
-	self->priv->types = g_hash_table_new_full (g_str_hash,
-						   g_str_equal,
-						   (GDestroyNotify)g_free,
-						   (GDestroyNotify)gedit_message_type_unref);
+	                                           g_direct_equal,
+	                                           NULL,
+	                                           (GDestroyNotify) g_free);
+
+	self->priv->types = g_hash_table_new_full (message_identifier_hash,
+	                                           message_identifier_equal,
+	                                           (GDestroyNotify) message_identifier_free,
+	                                           (GDestroyNotify) free_type);
 }
 
 /**
@@ -548,20 +623,21 @@ GeditMessageBus *
 gedit_message_bus_get_default (void)
 {
 	static GeditMessageBus *default_bus = NULL;
-	
+
 	if (G_UNLIKELY (default_bus == NULL))
 	{
 		default_bus = g_object_new (GEDIT_TYPE_MESSAGE_BUS, NULL);
+
 		g_object_add_weak_pointer (G_OBJECT (default_bus),
-				           (gpointer) &default_bus);
+		                           (gpointer) &default_bus);
 	}
-	
+
 	return default_bus;
 }
 
 /**
  * gedit_message_bus_new:
- * 
+ *
  * Create a new message bus. Use gedit_message_bus_get_default() to get the
  * default, application wide, message bus. Creating a new bus is useful for
  * associating a specific bus with for instance a #GeditWindow.
@@ -581,124 +657,119 @@ gedit_message_bus_new (void)
  * @object_path: the object path
  * @method: the method
  *
- * Get the registered #GeditMessageType for @method at @object_path. The 
+ * Get the registered #GeditMessageType for @method at @object_path. The
  * returned #GeditMessageType is owned by the bus and should not be unreffed.
  *
  * Return value: the registered #GeditMessageType or %NULL if no message type
  *               is registered for @method at @object_path
  *
  */
-GeditMessageType *
+GType
 gedit_message_bus_lookup (GeditMessageBus *bus,
-			  const gchar	  *object_path,
-			  const gchar	  *method)
+                          const gchar	  *object_path,
+                          const gchar	  *method)
 {
-	gchar *identifier;
-	GeditMessageType *message_type;
-	
-	g_return_val_if_fail (GEDIT_IS_MESSAGE_BUS (bus), NULL);
-	g_return_val_if_fail (object_path != NULL, NULL);
-	g_return_val_if_fail (method != NULL, NULL);
-
-	identifier = gedit_message_type_identifier (object_path, method);
-	message_type = GEDIT_MESSAGE_TYPE (g_hash_table_lookup (bus->priv->types, identifier));
-	
-	g_free (identifier);
-	return message_type;
+	MessageIdentifier *identifier;
+	GType *message_type;
+
+	g_return_val_if_fail (GEDIT_IS_MESSAGE_BUS (bus), G_TYPE_INVALID);
+	g_return_val_if_fail (object_path != NULL, G_TYPE_INVALID);
+	g_return_val_if_fail (method != NULL, G_TYPE_INVALID);
+
+	identifier = message_identifier_new (object_path, method);
+	message_type = g_hash_table_lookup (bus->priv->types, identifier);
+	message_identifier_free (identifier);
+
+	if (!message_type)
+	{
+		return G_TYPE_INVALID;
+	}
+	else
+	{
+		return *message_type;
+	}
 }
 
 /**
  * gedit_message_bus_register:
  * @bus: a #GeditMessageBus
+ * @message_type: the message type
  * @object_path: the object path
  * @method: the method to register
- * @num_optional: the number of optional arguments
- * @...: NULL terminated list of key/gtype method argument pairs
  *
  * Register a message on the bus. A message must be registered on the bus before
- * it can be send. This function registers the type arguments for @method at 
- * @object_path. The arguments are specified with the variable arguments which 
- * should contain pairs of const gchar *key and GType terminated by %NULL. The 
- * last @num_optional arguments are registered as optional (and are thus not
- * required when sending a message).
+ * it can be send. This function registers the type for @method at
+ * @object_path.
  *
  * This function emits a #GeditMessageBus::registered signal.
  *
- * Return value: the registered #GeditMessageType. The returned reference is
- *               owned by the bus. If you want to keep it alive after
- *               unregistering, use gedit_message_type_ref().
- *
  */
-GeditMessageType *
+void
 gedit_message_bus_register (GeditMessageBus *bus,
-			    const gchar     *object_path,
-			    const gchar	    *method,
-			    guint	     num_optional,
-			    ...)
+                            GType            message_type,
+                            const gchar     *object_path,
+                            const gchar	    *method)
 {
-	gchar *identifier;
-	va_list var_args;
-	GeditMessageType *message_type;
+	MessageIdentifier *identifier;
+	GType *ntype;
+
+	g_return_if_fail (GEDIT_IS_MESSAGE_BUS (bus));
+	g_return_if_fail (gedit_message_is_valid_object_path (object_path));
+	g_return_if_fail (g_type_is_a (message_type, GEDIT_TYPE_MESSAGE));
 
-	g_return_val_if_fail (GEDIT_IS_MESSAGE_BUS (bus), NULL);
-	g_return_val_if_fail (gedit_message_type_is_valid_object_path (object_path), NULL);
-	
 	if (gedit_message_bus_is_registered (bus, object_path, method))
 	{
-		g_warning ("Message type for '%s.%s' is already registered", object_path, method);
-		return NULL;
+		g_warning ("Message type for '%s.%s' is already registered",
+		           object_path,
+		           method);
 	}
 
-	identifier = gedit_message_type_identifier (object_path, method);
-	
-	va_start (var_args, num_optional);
-	message_type = gedit_message_type_new_valist (object_path, 
-						      method,
-						      num_optional,
-						      var_args);
-	va_end (var_args);
-	
-	if (message_type)
-	{
-		g_hash_table_insert (bus->priv->types, identifier, message_type);
-		g_signal_emit (bus, message_bus_signals[REGISTERED], 0, message_type);
-	}
-	else
-	{
-		g_free (identifier);
-	}
-	
-	return message_type;	
+	identifier = message_identifier_new (object_path, method);
+	ntype = g_slice_new (GType);
+
+	*ntype = message_type;
+
+	g_hash_table_insert (bus->priv->types,
+	                     identifier,
+	                     ntype);
+
+	g_signal_emit (bus,
+	               message_bus_signals[REGISTERED],
+	               0,
+	               object_path,
+	               method);
 }
 
 static void
 gedit_message_bus_unregister_real (GeditMessageBus  *bus,
-				   GeditMessageType *message_type,
-				   gboolean          remove_from_store)
+                                   const gchar      *object_path,
+                                   const gchar      *method,
+                                   gboolean          remove_from_store)
 {
-	gchar *identifier;
-	
-	g_return_if_fail (GEDIT_IS_MESSAGE_BUS (bus));
+	MessageIdentifier *identifier;
+
+	identifier = message_identifier_new (object_path, method);
+
+	if (!remove_from_store || g_hash_table_remove (bus->priv->types,
+	                                               identifier))
+	{
+		g_signal_emit (bus,
+		               message_bus_signals[UNREGISTERED],
+		               0,
+		               object_path,
+		               method);
+	}
 
-	identifier = gedit_message_type_identifier (gedit_message_type_get_object_path (message_type), 
-						    gedit_message_type_get_method (message_type));
-	
-	/* Keep message type alive for signal emission */
-	gedit_message_type_ref (message_type);
-
-	if (!remove_from_store || g_hash_table_remove (bus->priv->types, identifier))
-		g_signal_emit (bus, message_bus_signals[UNREGISTERED], 0, message_type);
-	
-	gedit_message_type_unref (message_type);
-	g_free (identifier);
+	message_identifier_free (identifier);
 }
 
 /**
  * gedit_message_bus_unregister:
  * @bus: a #GeditMessageBus
- * @message_type: the #GeditMessageType to unregister
+ * @object_path: the object path
+ * @method: the method
  *
- * Unregisters a previously registered message type. This is especially useful 
+ * Unregisters a previously registered message type. This is especially useful
  * for plugins which should unregister message types when they are deactivated.
  *
  * This function emits the #GeditMessageBus::unregistered signal.
@@ -706,30 +777,40 @@ gedit_message_bus_unregister_real (GeditMessageBus  *bus,
  */
 void
 gedit_message_bus_unregister (GeditMessageBus  *bus,
-			      GeditMessageType *message_type)
+                              const gchar      *object_path,
+                              const gchar      *method)
 {
 	g_return_if_fail (GEDIT_IS_MESSAGE_BUS (bus));
-	gedit_message_bus_unregister_real (bus, message_type, TRUE);
+	g_return_if_fail (object_path != NULL);
+	g_return_if_fail (method != NULL);
+
+	gedit_message_bus_unregister_real (bus,
+	                                   object_path,
+	                                   method,
+	                                   TRUE);
 }
 
-typedef struct 
+typedef struct
 {
 	GeditMessageBus *bus;
 	const gchar *object_path;
 } UnregisterInfo;
 
 static gboolean
-unregister_each (const gchar      *identifier,
-		 GeditMessageType *message_type,
-		 UnregisterInfo   *info)
+unregister_each (MessageIdentifier *identifier,
+                 GType             *gtype,
+                 UnregisterInfo    *info)
 {
-	if (strcmp (gedit_message_type_get_object_path (message_type),
-		    info->object_path) == 0)
-	{	
-		gedit_message_bus_unregister_real (info->bus, message_type, FALSE);
+	if (g_strcmp0 (identifier->object_path, info->object_path) == 0)
+	{
+		gedit_message_bus_unregister_real (info->bus,
+		                                   identifier->object_path,
+		                                   identifier->method,
+		                                   FALSE);
+
 		return TRUE;
 	}
-	
+
 	return FALSE;
 }
 
@@ -747,16 +828,16 @@ unregister_each (const gchar      *identifier,
  */
 void
 gedit_message_bus_unregister_all (GeditMessageBus *bus,
-			          const gchar     *object_path)
+                                  const gchar     *object_path)
 {
 	UnregisterInfo info = {bus, object_path};
 
 	g_return_if_fail (GEDIT_IS_MESSAGE_BUS (bus));
 	g_return_if_fail (object_path != NULL);
 
-	g_hash_table_foreach_remove (bus->priv->types, 
-				     (GHRFunc)unregister_each,
-				     &info);
+	g_hash_table_foreach_remove (bus->priv->types,
+	                             (GHRFunc)unregister_each,
+	                             &info);
 }
 
 /**
@@ -765,29 +846,29 @@ gedit_message_bus_unregister_all (GeditMessageBus *bus,
  * @object_path: the object path
  * @method: the method
  *
- * Check whether a message type @method at @object_path is registered on the 
+ * Check whether a message type @method at @object_path is registered on the
  * bus.
  *
- * Return value: %TRUE if the @method at @object_path is a registered message 
+ * Return value: %TRUE if the @method at @object_path is a registered message
  *               type on the bus
  *
  */
 gboolean
 gedit_message_bus_is_registered (GeditMessageBus  *bus,
-				 const gchar	  *object_path,
-				 const gchar      *method)
+                                 const gchar	  *object_path,
+                                 const gchar      *method)
 {
-	gchar *identifier;
+	MessageIdentifier *identifier;
 	gboolean ret;
-	
+
 	g_return_val_if_fail (GEDIT_IS_MESSAGE_BUS (bus), FALSE);
 	g_return_val_if_fail (object_path != NULL, FALSE);
 	g_return_val_if_fail (method != NULL, FALSE);
 
-	identifier = gedit_message_type_identifier (object_path, method);
+	identifier = message_identifier_new (object_path, method);
 	ret = g_hash_table_lookup (bus->priv->types, identifier) != NULL;
-	
-	g_free(identifier);
+	message_identifier_free (identifier);
+
 	return ret;
 }
 
@@ -798,13 +879,13 @@ typedef struct
 } ForeachInfo;
 
 static void
-foreach_type (const gchar      *key,
-	      GeditMessageType *message_type,
-	      ForeachInfo      *info)
+foreach_type (MessageIdentifier *identifier,
+              GType              *message_type,
+              ForeachInfo       *info)
 {
-	gedit_message_type_ref (message_type);
-	info->func (message_type, info->user_data);
-	gedit_message_type_unref (message_type);
+	info->func (identifier->object_path,
+	            identifier->method,
+	            info->user_data);
 }
 
 /**
@@ -816,13 +897,13 @@ foreach_type (const gchar      *key,
  * Calls @func for each message type registered on the bus
  *
  */
-void 
+void
 gedit_message_bus_foreach (GeditMessageBus        *bus,
-			   GeditMessageBusForeach  func,
-			   gpointer		   user_data)
+                           GeditMessageBusForeach  func,
+                           gpointer		   user_data)
 {
 	ForeachInfo info = {func, user_data};
-	
+
 	g_return_if_fail (GEDIT_IS_MESSAGE_BUS (bus));
 	g_return_if_fail (func != NULL);
 
@@ -835,8 +916,8 @@ gedit_message_bus_foreach (GeditMessageBus        *bus,
  * @object_path: the object path
  * @method: the method
  * @callback: function to be called when message @method at @object_path is sent
- * @user_data: user_data to use for the callback
- * @destroy_data: function to evoke with @user_data as argument when @user_data
+ * @user_data: (allow-none): user_data to use for the callback
+ * @destroy_data: (allow-none): function to evoke with @user_data as argument when @user_data
  *                needs to be freed
  *
  * Connect a callback handler to be evoked when message @method at @object_path
@@ -846,12 +927,12 @@ gedit_message_bus_foreach (GeditMessageBus        *bus,
  *
  */
 guint
-gedit_message_bus_connect (GeditMessageBus	*bus, 
-		           const gchar		*object_path,
-		           const gchar		*method,
-		           GeditMessageCallback  callback,
-		           gpointer		 user_data,
-		           GDestroyNotify	 destroy_data)
+gedit_message_bus_connect (GeditMessageBus	*bus,
+                           const gchar		*object_path,
+                           const gchar		*method,
+                           GeditMessageCallback  callback,
+                           gpointer		 user_data,
+                           GDestroyNotify	 destroy_data)
 {
 	Message *message;
 
@@ -859,10 +940,10 @@ gedit_message_bus_connect (GeditMessageBus	*bus,
 	g_return_val_if_fail (object_path != NULL, 0);
 	g_return_val_if_fail (method != NULL, 0);
 	g_return_val_if_fail (callback != NULL, 0);
-	
+
 	/* lookup the message and create if it does not exist yet */
 	message = lookup_message (bus, object_path, method, TRUE);
-	
+
 	return add_listener (bus, message, callback, user_data, destroy_data);
 }
 
@@ -876,10 +957,10 @@ gedit_message_bus_connect (GeditMessageBus	*bus,
  */
 void
 gedit_message_bus_disconnect (GeditMessageBus *bus,
-			      guint            id)
+                              guint            id)
 {
 	g_return_if_fail (GEDIT_IS_MESSAGE_BUS (bus));
-	
+
 	process_by_id (bus, id, remove_listener);
 }
 
@@ -891,21 +972,26 @@ gedit_message_bus_disconnect (GeditMessageBus *bus,
  * @callback: (scope call): the connected callback
  * @user_data: the user_data with which the callback was connected
  *
- * Disconnects a previously connected message callback by matching the 
- * provided callback function and user_data. See also 
+ * Disconnects a previously connected message callback by matching the
+ * provided callback function and user_data. See also
  * gedit_message_bus_disconnect().
  *
  */
 void
 gedit_message_bus_disconnect_by_func (GeditMessageBus      *bus,
-				      const gchar	   *object_path,
-				      const gchar	   *method,
-				      GeditMessageCallback  callback,
-				      gpointer		    user_data)
+                                      const gchar	   *object_path,
+                                      const gchar	   *method,
+                                      GeditMessageCallback  callback,
+                                      gpointer		    user_data)
 {
 	g_return_if_fail (GEDIT_IS_MESSAGE_BUS (bus));
-	
-	process_by_match (bus, object_path, method, callback, user_data, remove_listener);
+
+	process_by_match (bus,
+	                  object_path,
+	                  method,
+	                  callback,
+	                  user_data,
+	                  remove_listener);
 }
 
 /**
@@ -919,10 +1005,10 @@ gedit_message_bus_disconnect_by_func (GeditMessageBus      *bus,
  */
 void
 gedit_message_bus_block (GeditMessageBus *bus,
-			 guint		  id)
+                         guint		  id)
 {
 	g_return_if_fail (GEDIT_IS_MESSAGE_BUS (bus));
-	
+
 	process_by_id (bus, id, block_listener);
 }
 
@@ -940,14 +1026,19 @@ gedit_message_bus_block (GeditMessageBus *bus,
  */
 void
 gedit_message_bus_block_by_func (GeditMessageBus      *bus,
-				 const gchar	      *object_path,
-				 const gchar	      *method,
-				 GeditMessageCallback  callback,
-				 gpointer	       user_data)
+                                 const gchar	      *object_path,
+                                 const gchar	      *method,
+                                 GeditMessageCallback  callback,
+                                 gpointer	       user_data)
 {
 	g_return_if_fail (GEDIT_IS_MESSAGE_BUS (bus));
-	
-	process_by_match (bus, object_path, method, callback, user_data, block_listener);
+
+	process_by_match (bus,
+	                  object_path,
+	                  method,
+	                  callback,
+	                  user_data,
+	                  block_listener);
 }
 
 /**
@@ -960,10 +1051,10 @@ gedit_message_bus_block_by_func (GeditMessageBus      *bus,
  */
 void
 gedit_message_bus_unblock (GeditMessageBus *bus,
-			   guint	    id)
+                           guint	    id)
 {
 	g_return_if_fail (GEDIT_IS_MESSAGE_BUS (bus));
-	
+
 	process_by_id (bus, id, unblock_listener);
 }
 
@@ -980,47 +1071,34 @@ gedit_message_bus_unblock (GeditMessageBus *bus,
  */
 void
 gedit_message_bus_unblock_by_func (GeditMessageBus      *bus,
-				   const gchar	        *object_path,
-				   const gchar	        *method,
-				   GeditMessageCallback  callback,
-				   gpointer	         user_data)
+                                   const gchar	        *object_path,
+                                   const gchar	        *method,
+                                   GeditMessageCallback  callback,
+                                   gpointer	         user_data)
 {
 	g_return_if_fail (GEDIT_IS_MESSAGE_BUS (bus));
-	
-	process_by_match (bus, object_path, method, callback, user_data, unblock_listener);
-}
 
-static gboolean
-validate_message (GeditMessage *message)
-{
-	if (!gedit_message_validate (message))
-	{
-		g_warning ("Message '%s.%s' is invalid", gedit_message_get_object_path (message),
-							 gedit_message_get_method (message));
-		return FALSE;
-	}
-	
-	return TRUE;
+	process_by_match (bus,
+	                  object_path,
+	                  method,
+	                  callback,
+	                  user_data,
+	                  unblock_listener);
 }
 
 static void
 send_message_real (GeditMessageBus *bus,
-		   GeditMessage    *message)
+                   GeditMessage    *message)
 {
-	if (!validate_message (message))
-	{
-		return;
-	}
-	
-	bus->priv->message_queue = g_list_prepend (bus->priv->message_queue, 
-						   g_object_ref (message));
+	bus->priv->message_queue = g_list_prepend (bus->priv->message_queue,
+	                                           g_object_ref (message));
 
 	if (bus->priv->idle_id == 0)
 	{
 		bus->priv->idle_id = g_idle_add_full (G_PRIORITY_HIGH,
-						      (GSourceFunc)idle_dispatch,
-						      bus,
-						      NULL);
+		                                      (GSourceFunc)idle_dispatch,
+		                                      bus,
+		                                      NULL);
 	}
 }
 
@@ -1030,18 +1108,18 @@ send_message_real (GeditMessageBus *bus,
  * @message: the message to send
  *
  * This sends the provided @message asynchronously over the bus. To send
- * a message synchronously, use gedit_message_bus_send_message_sync(). The 
+ * a message synchronously, use gedit_message_bus_send_message_sync(). The
  * convenience function gedit_message_bus_send() can be used to easily send
  * a message without constructing the message object explicitly first.
  *
  */
 void
 gedit_message_bus_send_message (GeditMessageBus *bus,
-			        GeditMessage    *message)
+                                GeditMessage    *message)
 {
 	g_return_if_fail (GEDIT_IS_MESSAGE_BUS (bus));
 	g_return_if_fail (GEDIT_IS_MESSAGE (message));
-	
+
 	send_message_real (bus, message);
 }
 
@@ -1049,11 +1127,6 @@ static void
 send_message_sync_real (GeditMessageBus *bus,
                         GeditMessage    *message)
 {
-	if (!validate_message (message))
-	{
-		return;
-	}
-	
 	dispatch_message (bus, message);
 }
 
@@ -1063,39 +1136,57 @@ send_message_sync_real (GeditMessageBus *bus,
  * @message: the message to send
  *
  * This sends the provided @message synchronously over the bus. To send
- * a message asynchronously, use gedit_message_bus_send_message(). The 
+ * a message asynchronously, use gedit_message_bus_send_message(). The
  * convenience function gedit_message_bus_send_sync() can be used to easily send
  * a message without constructing the message object explicitly first.
  *
  */
 void
 gedit_message_bus_send_message_sync (GeditMessageBus *bus,
-			             GeditMessage    *message)
+                                     GeditMessage    *message)
 {
 	g_return_if_fail (GEDIT_IS_MESSAGE_BUS (bus));
 	g_return_if_fail (GEDIT_IS_MESSAGE (message));
 
-	send_message_sync_real (bus, message);	
+	send_message_sync_real (bus, message);
 }
 
 static GeditMessage *
 create_message (GeditMessageBus *bus,
-		const gchar     *object_path,
-		const gchar     *method,
-		va_list          var_args)
+                const gchar     *object_path,
+                const gchar     *method,
+                const gchar     *first_property,
+                va_list          var_args)
 {
-	GeditMessageType *message_type;
-	
+	GType message_type;
+	GeditMessage *msg;
+
 	message_type = gedit_message_bus_lookup (bus, object_path, method);
-	
-	if (!message_type)
+
+	if (message_type == G_TYPE_INVALID)
 	{
-		g_warning ("Could not find message type for '%s.%s'", object_path, method);
+		g_warning ("Could not find message type for '%s.%s'",
+		           object_path,
+		           method);
+
 		return NULL;
 	}
 
-	return gedit_message_type_instantiate_valist (message_type, 
-						      var_args);
+	msg = GEDIT_MESSAGE (g_object_new_valist (message_type,
+	                                          first_property,
+	                                          var_args));
+
+	if (msg)
+	{
+		g_object_set (msg,
+		              "object_path",
+		              object_path,
+		              "method",
+		              method,
+		              NULL);
+	}
+
+	return msg;
 }
 
 /**
@@ -1105,25 +1196,30 @@ create_message (GeditMessageBus *bus,
  * @method: the method
  * @...: NULL terminated list of key/value pairs
  *
- * This provides a convenient way to quickly send a message @method at 
- * @object_path asynchronously over the bus. The variable argument list 
- * specifies key (string) value pairs used to construct the message arguments. 
+ * This provides a convenient way to quickly send a message @method at
+ * @object_path asynchronously over the bus. The variable argument list
+ * specifies key (string) value pairs used to construct the message arguments.
  * To send a message synchronously use gedit_message_bus_send_sync().
  *
  */
 void
 gedit_message_bus_send (GeditMessageBus *bus,
-			const gchar     *object_path,
-			const gchar     *method,
-			...)
+                        const gchar     *object_path,
+                        const gchar     *method,
+                        const gchar     *first_property,
+                        ...)
 {
 	va_list var_args;
 	GeditMessage *message;
-	
-	va_start (var_args, method);
 
-	message = create_message (bus, object_path, method, var_args);
-	
+	va_start (var_args, first_property);
+
+	message = create_message (bus,
+	                          object_path,
+	                          method,
+	                          first_property,
+	                          var_args);
+
 	if (message)
 	{
 		send_message_real (bus, message);
@@ -1144,9 +1240,9 @@ gedit_message_bus_send (GeditMessageBus *bus,
  * @method: the method
  * @...: (allow-none): %NULL terminated list of key/value pairs
  *
- * This provides a convenient way to quickly send a message @method at 
- * @object_path synchronously over the bus. The variable argument list 
- * specifies key (string) value pairs used to construct the message 
+ * This provides a convenient way to quickly send a message @method at
+ * @object_path synchronously over the bus. The variable argument list
+ * specifies key (string) value pairs used to construct the message
  * arguments. To send a message asynchronously use gedit_message_bus_send().
  *
  * Return value: (allow-none) (transfer full): the constructed #GeditMessage.
@@ -1155,21 +1251,28 @@ gedit_message_bus_send (GeditMessageBus *bus,
  */
 GeditMessage *
 gedit_message_bus_send_sync (GeditMessageBus *bus,
-			     const gchar     *object_path,
-			     const gchar     *method,
-			     ...)
+                             const gchar     *object_path,
+                             const gchar     *method,
+                             const gchar     *first_property,
+                             ...)
 {
 	va_list var_args;
 	GeditMessage *message;
-	
-	va_start (var_args, method);
-	message = create_message (bus, object_path, method, var_args);
-	
+
+	va_start (var_args, first_property);
+	message = create_message (bus,
+	                          object_path,
+	                          method,
+	                          first_property,
+	                          var_args);
+
 	if (message)
+	{
 		send_message_sync_real (bus, message);
+	}
 
 	va_end (var_args);
-	
+
 	return message;
 }
 
diff --git a/gedit/gedit-message-bus.h b/gedit/gedit-message-bus.h
index 2513ad3..a7b58d9 100644
--- a/gedit/gedit-message-bus.h
+++ b/gedit/gedit-message-bus.h
@@ -25,7 +25,6 @@
 
 #include <glib-object.h>
 #include <gedit/gedit-message.h>
-#include <gedit/gedit-message-type.h>
 
 G_BEGIN_DECLS
 
@@ -44,107 +43,109 @@ typedef struct _GeditMessageBusPrivate	GeditMessageBusPrivate;
 struct _GeditMessageBus
 {
 	GObject parent;
-	
+
 	GeditMessageBusPrivate *priv;
 };
 
 struct _GeditMessageBusClass
 {
 	GObjectClass parent_class;
-	
-	void (*dispatch)		(GeditMessageBus  *bus,
-					 GeditMessage     *message);
-	void (*registered)		(GeditMessageBus  *bus,
-					 GeditMessageType *message_type);
-	void (*unregistered)		(GeditMessageBus  *bus,
-					 GeditMessageType *message_type);
+
+	void (*dispatch)      (GeditMessageBus  *bus,
+	                       GeditMessage     *message);
+	void (*registered)    (GeditMessageBus  *bus,
+	                       const gchar      *object_path,
+	                       const gchar      *method);
+	void (*unregistered)  (GeditMessageBus  *bus,
+	                       const gchar      *object_path,
+	                       const gchar      *method);
 };
 
-typedef void (* GeditMessageCallback) 	(GeditMessageBus  *bus,
-					 GeditMessage	  *message,
-					 gpointer	   user_data);
-
-typedef void (* GeditMessageBusForeach) (GeditMessageType *message_type,
-					 gpointer	   user_data);
-
-GType			 gedit_message_bus_get_type		(void) G_GNUC_CONST;
-
-GeditMessageBus		*gedit_message_bus_get_default		(void);
-GeditMessageBus		*gedit_message_bus_new			(void);
-
-/* registering messages */
-GeditMessageType	*gedit_message_bus_lookup		(GeditMessageBus        *bus,
-								 const gchar            *object_path,
-								 const gchar            *method);
-GeditMessageType	*gedit_message_bus_register		(GeditMessageBus        *bus,
-								 const gchar            *object_path,
-								 const gchar            *method,
-								 guint                   num_optional,
-								 ...) G_GNUC_NULL_TERMINATED;
-
-void			 gedit_message_bus_unregister		(GeditMessageBus        *bus,
-								 GeditMessageType       *message_type);
-
-void			 gedit_message_bus_unregister_all	(GeditMessageBus        *bus,
-								 const gchar            *object_path);
-
-gboolean		 gedit_message_bus_is_registered	(GeditMessageBus        *bus,
-								 const gchar            *object_path,
-								 const gchar            *method);
-
-void			 gedit_message_bus_foreach		(GeditMessageBus        *bus,
-								 GeditMessageBusForeach  func,
-								 gpointer                user_data);
-
-
-/* connecting to message events */		   
-guint			 gedit_message_bus_connect		(GeditMessageBus        *bus,
-								 const gchar            *object_path,
-								 const gchar            *method,
-								 GeditMessageCallback    callback,
-								 gpointer                user_data,
-								 GDestroyNotify          destroy_data);
-
-void			 gedit_message_bus_disconnect		(GeditMessageBus        *bus,
-								 guint                   id);
-
-void			 gedit_message_bus_disconnect_by_func	(GeditMessageBus        *bus,
-								 const gchar            *object_path,
-								 const gchar            *method,
-								 GeditMessageCallback    callback,
-								 gpointer                user_data);
-
-/* blocking message event callbacks */
-void			 gedit_message_bus_block		(GeditMessageBus        *bus,
-								 guint                   id);
-void			 gedit_message_bus_block_by_func	(GeditMessageBus        *bus,
-								 const gchar            *object_path,
-								 const gchar            *method,
-								 GeditMessageCallback    callback,
-								 gpointer                user_data);
-
-void			 gedit_message_bus_unblock		(GeditMessageBus        *bus,
-								 guint                   id);
-void			 gedit_message_bus_unblock_by_func	(GeditMessageBus        *bus,
-								 const gchar            *object_path,
-								 const gchar            *method,
-								 GeditMessageCallback    callback,
-								 gpointer                user_data);
-
-/* sending messages */
-void			 gedit_message_bus_send_message		(GeditMessageBus        *bus,
-								 GeditMessage           *message);
-void			 gedit_message_bus_send_message_sync	(GeditMessageBus        *bus,
-								 GeditMessage           *message);
-					  
-void			 gedit_message_bus_send			(GeditMessageBus        *bus,
-								 const gchar            *object_path,
-								 const gchar            *method,
-								 ...) G_GNUC_NULL_TERMINATED;
-GeditMessage		*gedit_message_bus_send_sync		(GeditMessageBus        *bus,
-								 const gchar            *object_path,
-								 const gchar            *method,
-								 ...) G_GNUC_NULL_TERMINATED;
+typedef void (* GeditMessageCallback)   (GeditMessageBus  *bus,
+                                         GeditMessage     *message,
+                                         gpointer          user_data);
+
+typedef void (* GeditMessageBusForeach) (gchar const      *object_path,
+                                         gchar const      *method,
+                                         gpointer          user_data);
+
+GType             gedit_message_bus_get_type           (void) G_GNUC_CONST;
+
+GeditMessageBus  *gedit_message_bus_get_default        (void);
+GeditMessageBus  *gedit_message_bus_new                (void);
+
+GType             gedit_message_bus_lookup             (GeditMessageBus        *bus,
+                                                        const gchar            *object_path,
+                                                        const gchar            *method);
+
+void              gedit_message_bus_register           (GeditMessageBus        *bus,
+                                                        GType                   message_type,
+                                                        const gchar            *object_path,
+                                                        const gchar            *method);
+
+void              gedit_message_bus_unregister         (GeditMessageBus        *bus,
+                                                        const gchar            *object_path,
+                                                        const gchar            *method);
+
+void              gedit_message_bus_unregister_all     (GeditMessageBus        *bus,
+                                                        const gchar            *object_path);
+
+gboolean          gedit_message_bus_is_registered      (GeditMessageBus        *bus,
+                                                        const gchar            *object_path,
+                                                        const gchar            *method);
+
+void              gedit_message_bus_foreach            (GeditMessageBus        *bus,
+                                                        GeditMessageBusForeach  func,
+                                                        gpointer                user_data);
+
+guint             gedit_message_bus_connect            (GeditMessageBus        *bus,
+                                                        const gchar            *object_path,
+                                                        const gchar            *method,
+                                                        GeditMessageCallback    callback,
+                                                        gpointer                user_data,
+                                                        GDestroyNotify          destroy_data);
+
+void              gedit_message_bus_disconnect         (GeditMessageBus        *bus,
+                                                        guint                   id);
+
+void              gedit_message_bus_disconnect_by_func (GeditMessageBus        *bus,
+                                                        const gchar            *object_path,
+                                                        const gchar            *method,
+                                                        GeditMessageCallback    callback,
+                                                        gpointer                user_data);
+
+void              gedit_message_bus_block              (GeditMessageBus        *bus,
+                                                        guint                   id);
+void              gedit_message_bus_block_by_func      (GeditMessageBus        *bus,
+                                                        const gchar            *object_path,
+                                                        const gchar            *method,
+                                                        GeditMessageCallback    callback,
+                                                        gpointer                user_data);
+
+void              gedit_message_bus_unblock            (GeditMessageBus        *bus,
+                                                        guint                   id);
+void              gedit_message_bus_unblock_by_func    (GeditMessageBus        *bus,
+                                                        const gchar            *object_path,
+                                                        const gchar            *method,
+                                                        GeditMessageCallback    callback,
+                                                        gpointer                user_data);
+
+void              gedit_message_bus_send_message       (GeditMessageBus        *bus,
+                                                        GeditMessage           *message);
+void              gedit_message_bus_send_message_sync  (GeditMessageBus        *bus,
+                                                        GeditMessage           *message);
+
+void              gedit_message_bus_send               (GeditMessageBus        *bus,
+                                                        const gchar            *object_path,
+                                                        const gchar            *method,
+                                                        const gchar            *first_property,
+                                                        ...) G_GNUC_NULL_TERMINATED;
+
+GeditMessage     *gedit_message_bus_send_sync          (GeditMessageBus        *bus,
+                                                        const gchar            *object_path,
+                                                        const gchar            *method,
+                                                        const gchar            *first_property,
+                                                        ...) G_GNUC_NULL_TERMINATED;
 
 G_END_DECLS
 
diff --git a/gedit/gedit-message.c b/gedit/gedit-message.c
index 73f6e8f..1086633 100644
--- a/gedit/gedit-message.c
+++ b/gedit/gedit-message.c
@@ -21,10 +21,8 @@
  */
 
 #include "gedit-message.h"
-#include "gedit-message-type.h"
 
 #include <string.h>
-#include <gobject/gvaluecollector.h>
 
 /**
  * SECTION:gedit-message
@@ -45,20 +43,18 @@
  */
 #define GEDIT_MESSAGE_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE((object), GEDIT_TYPE_MESSAGE, GeditMessagePrivate))
 
-enum {
+enum
+{
 	PROP_0,
 
 	PROP_OBJECT_PATH,
-	PROP_METHOD,
-	PROP_TYPE
+	PROP_METHOD
 };
 
 struct _GeditMessagePrivate
 {
-	GeditMessageType *type;
-	gboolean valid;
-
-	GHashTable *values;
+	gchar *object_path;
+	gchar *method;
 };
 
 G_DEFINE_TYPE (GeditMessage, gedit_message, G_TYPE_OBJECT)
@@ -67,31 +63,30 @@ static void
 gedit_message_finalize (GObject *object)
 {
 	GeditMessage *message = GEDIT_MESSAGE (object);
-	
-	gedit_message_type_unref (message->priv->type);
-	g_hash_table_destroy (message->priv->values);
+
+	g_free (message->priv->object_path);
+	g_free (message->priv->method);
 
 	G_OBJECT_CLASS (gedit_message_parent_class)->finalize (object);
 }
 
 static void
 gedit_message_get_property (GObject    *object,
-			    guint       prop_id,
-			    GValue     *value,
-			    GParamSpec *pspec)
+                            guint       prop_id,
+                            GValue     *value,
+                            GParamSpec *pspec)
 {
 	GeditMessage *msg = GEDIT_MESSAGE (object);
 
 	switch (prop_id)
 	{
 		case PROP_OBJECT_PATH:
-			g_value_set_string (value, gedit_message_type_get_object_path (msg->priv->type));
+			g_value_set_string (value,
+			                    msg->priv->object_path);
 			break;
 		case PROP_METHOD:
-			g_value_set_string (value, gedit_message_type_get_method (msg->priv->type));
-			break;
-		case PROP_TYPE:
-			g_value_set_boxed (value, msg->priv->type);
+			g_value_set_string (value,
+			                    msg->priv->method);
 			break;
 		default:
 			G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@@ -101,16 +96,21 @@ gedit_message_get_property (GObject    *object,
 
 static void
 gedit_message_set_property (GObject      *object,
-			    guint         prop_id,
-			    const GValue *value,
-			    GParamSpec   *pspec)
+                            guint         prop_id,
+                            const GValue *value,
+                            GParamSpec   *pspec)
 {
 	GeditMessage *msg = GEDIT_MESSAGE (object);
 
 	switch (prop_id)
 	{
-		case PROP_TYPE:
-			msg->priv->type = GEDIT_MESSAGE_TYPE (g_value_dup_boxed (value));
+		case PROP_OBJECT_PATH:
+			g_free (msg->priv->object_path);
+			msg->priv->object_path = g_value_dup_string (value);
+			break;
+		case PROP_METHOD:
+			g_free (msg->priv->method);
+			msg->priv->method = g_value_dup_string (value);
 			break;
 		default:
 			G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@@ -118,47 +118,31 @@ gedit_message_set_property (GObject      *object,
 	}
 }
 
-static GValue *
-add_value (GeditMessage *message,
-	   const gchar  *key)
-{
-	GValue *value;
-	GType type = gedit_message_type_lookup (message->priv->type, key);
-	
-	if (type == G_TYPE_INVALID)
-		return NULL;
-	
-	value = g_new0 (GValue, 1);
-	g_value_init (value, type);
-	g_value_reset (value);
-
-	g_hash_table_insert (message->priv->values, g_strdup (key), value);
-	
-	return value;
-}
-
 static void
 gedit_message_class_init (GeditMessageClass *klass)
 {
 	GObjectClass *object_class = G_OBJECT_CLASS(klass);
-	
+
 	object_class->finalize = gedit_message_finalize;
+
 	object_class->get_property = gedit_message_get_property;
 	object_class->set_property = gedit_message_set_property;
-	
+
 	/**
 	 * GeditMessage:object_path:
 	 *
 	 * The messages object path (e.g. /gedit/object/path).
 	 *
 	 */
-	g_object_class_install_property (object_class, PROP_OBJECT_PATH,
-					 g_param_spec_string ("object-path",
-							      "OBJECT_PATH",
-							      "The message object path",
-							      NULL,
-							      G_PARAM_READABLE |
-							      G_PARAM_STATIC_STRINGS));
+	g_object_class_install_property (object_class,
+	                                 PROP_OBJECT_PATH,
+	                                 g_param_spec_string ("object-path",
+	                                                      "OBJECT_PATH",
+	                                                      "The message object path",
+	                                                      NULL,
+	                                                      G_PARAM_READWRITE |
+	                                                      G_PARAM_CONSTRUCT |
+	                                                      G_PARAM_STATIC_STRINGS));
 
 	/**
 	 * GeditMessage:method:
@@ -166,103 +150,23 @@ gedit_message_class_init (GeditMessageClass *klass)
 	 * The messages method.
 	 *
 	 */
-	g_object_class_install_property (object_class, PROP_METHOD,
-					 g_param_spec_string ("method",
-							      "METHOD",
-							      "The message method",
-							      NULL,
-							      G_PARAM_READABLE |
-							      G_PARAM_STATIC_STRINGS));
-	
-	/**
-	 * GeditMEssage:type:
-	 *
-	 * The message type.
-	 *
-	 */
-	g_object_class_install_property (object_class, PROP_TYPE,
-					 g_param_spec_boxed ("type",
-					 		     "TYPE",
-					 		     "The message type",
-					 		     GEDIT_TYPE_MESSAGE_TYPE,
-					 		     G_PARAM_READWRITE |
-					 		     G_PARAM_CONSTRUCT_ONLY |
-					 		     G_PARAM_STATIC_STRINGS));
+	g_object_class_install_property (object_class,
+	                                 PROP_METHOD,
+	                                 g_param_spec_string ("method",
+	                                                      "METHOD",
+	                                                      "The message method",
+	                                                      NULL,
+	                                                      G_PARAM_READWRITE |
+	                                                      G_PARAM_CONSTRUCT |
+	                                                      G_PARAM_STATIC_STRINGS));
 
 	g_type_class_add_private (object_class, sizeof (GeditMessagePrivate));
 }
 
 static void
-destroy_value (GValue *value)
-{
-	g_value_unset (value);
-	g_free (value);
-}
-
-static void
 gedit_message_init (GeditMessage *self)
 {
 	self->priv = GEDIT_MESSAGE_GET_PRIVATE (self);
-
-	self->priv->values = g_hash_table_new_full (g_str_hash,
-						    g_str_equal,
-						    (GDestroyNotify)g_free,
-						    (GDestroyNotify)destroy_value);
-}
-
-static gboolean
-set_value_real (GValue 	     *to, 
-		const GValue *from)
-{
-	GType from_type;
-	GType to_type;
-	
-	from_type = G_VALUE_TYPE (from);
-	to_type = G_VALUE_TYPE (to);
-
-	if (!g_type_is_a (from_type, to_type))
-	{		
-		if (!g_value_transform (from, to))
-		{
-			g_warning ("%s: Unable to make conversion from %s to %s",
-				   G_STRLOC,
-				   g_type_name (from_type),
-				   g_type_name (to_type));
-			return FALSE;
-		}
-		
-		return TRUE;
-	}
-	
-	g_value_copy (from, to);
-	return TRUE;
-}
-
-inline static GValue *
-value_lookup (GeditMessage *message,
-	      const gchar  *key,
-	      gboolean	    create)
-{
-	GValue *ret = (GValue *)g_hash_table_lookup (message->priv->values, key);
-	
-	if (!ret && create)
-		ret = add_value (message, key);
-	
-	return ret;
-}
-
-/**
- * gedit_message_get_message_type:
- * @message:
- *
- * Return value: (transfer none):
- */
-GeditMessageType *
-gedit_message_get_message_type (GeditMessage *message)
-{
-	g_return_val_if_fail (GEDIT_IS_MESSAGE (message), NULL);
-
-	return message->priv->type;
 }
 
 /**
@@ -279,7 +183,7 @@ gedit_message_get_method (GeditMessage *message)
 {
 	g_return_val_if_fail (GEDIT_IS_MESSAGE (message), NULL);
 
-	return gedit_message_type_get_method (message->priv->type);
+	return message->priv->method;
 }
 
 /**
@@ -296,335 +200,130 @@ gedit_message_get_object_path (GeditMessage *message)
 {
 	g_return_val_if_fail (GEDIT_IS_MESSAGE (message), NULL);
 
-	return gedit_message_type_get_object_path (message->priv->type);
+	return message->priv->object_path;
 }
 
 /**
- * gedit_message_set:
- * @message: the #GeditMessage
- * @...: a %NULL terminated variable list of key/value pairs
+ * gedit_message_is_valid_object_path:
+ * @object_path: (allow-none): the object path
  *
- * Set values of message arguments. The supplied @var_args should contain
- * pairs of keys and argument values.
+ * Returns whether @object_path is a valid object path
  *
- */
-void
-gedit_message_set (GeditMessage *message,
-		   ...)
-{
-	va_list ap;
-
-	g_return_if_fail (GEDIT_IS_MESSAGE (message));
-
-	va_start (ap, message);
-	gedit_message_set_valist (message, ap);
-	va_end (ap);
-}
-
-/**
- * gedit_message_set_valist:
- * @message: the #GeditMessage
- * @var_args: a %NULL terminated variable list of key/value pairs
- *
- * Set values of message arguments. The supplied @var_args should contain
- * pairs of keys and argument values.
+ * Return value: %TRUE if @object_path is a valid object path
  *
  */
-void
-gedit_message_set_valist (GeditMessage *message,
-			  va_list	var_args)
+gboolean
+gedit_message_is_valid_object_path (const gchar *object_path)
 {
-	const gchar *key;
-
-	g_return_if_fail (GEDIT_IS_MESSAGE (message));
-
-	while ((key = va_arg (var_args, const gchar *)) != NULL)
+	if (!object_path)
 	{
-		/* lookup the key */
-		GValue *container = value_lookup (message, key, TRUE);
-		GValue value = {0,};
-		gchar *error = NULL;
-		
-		if (!container)
-		{
-			g_warning ("%s: Cannot set value for %s, does not exist", 
-				   G_STRLOC,
-				   key);
-			
-			/* skip value */
-			va_arg (var_args, gpointer);
-			continue;
-		}
-		
-		g_value_init (&value, G_VALUE_TYPE (container));
-		G_VALUE_COLLECT (&value, var_args, 0, &error);
-		
-		if (error)
-		{
-			g_warning ("%s: %s", G_STRLOC, error);
-			continue;
-		}
-
-		set_value_real (container, &value);
-		g_value_unset (&value);
+		return FALSE;
 	}
-}
 
-/**
- * gedit_message_set_value:
- * @message: the #GeditMessage
- * @key: the argument key
- * @value: (out): the argument value
- *
- * Set value of message argument @key to @value.
- *
- */
-void
-gedit_message_set_value (GeditMessage *message,
-			 const gchar  *key,
-			 GValue	      *value)
-{
-	GValue *container;
-	g_return_if_fail (GEDIT_IS_MESSAGE (message));
-	
-	container = value_lookup (message, key, TRUE);
-	
-	if (!container)
+	/* needs to start with / */
+	if (*object_path != '/')
 	{
-		g_warning ("%s: Cannot set value for %s, does not exist", 
-			   G_STRLOC, 
-			   key);
-		return;
+		return FALSE;
 	}
-	
-	set_value_real (container, value);
-}
 
-/**
- * gedit_message_set_valuesv:
- * @message: the #GeditMessage
- * @keys: (array length=n_values): keys to set values for
- * @values: (array length=n_values): values to set
- * @n_values: number of arguments to set values for
- *
- * Set message argument values.
- *
- */
-void
-gedit_message_set_valuesv (GeditMessage	 *message,
-			   const gchar	**keys,
-			   GValue        *values,
-			   gint		  n_values)
-{
-	gint i;
-	
-	g_return_if_fail (GEDIT_IS_MESSAGE (message));
-	
-	for (i = 0; i < n_values; i++)
+	while (*object_path)
 	{
-		gedit_message_set_value (message, keys[i], &values[i]);
-	}
-}
-
-/* FIXME this is an issue for introspection */
-/**
- * gedit_message_get:
- * @message: the #GeditMessage
- * @...: a %NULL variable argument list of key/value container pairs
- *
- * Get values of message arguments. The supplied @var_args should contain
- * pairs of keys and pointers to variables which are set to the argument
- * value for the specified key.
- *
- */
-void 
-gedit_message_get (GeditMessage	*message,
-		   ...)
-{
-	va_list ap;
-
-	g_return_if_fail (GEDIT_IS_MESSAGE (message));
-	
-	va_start (ap, message);
-	gedit_message_get_valist (message, ap);
-	va_end (ap);
-}
-
-/**
- * gedit_message_get_valist:
- * @message: the #GeditMessage
- * @var_args: a %NULL variable argument list of key/value container pairs
- *
- * Get values of message arguments. The supplied @var_args should contain
- * pairs of keys and pointers to variables which are set to the argument
- * value for the specified key.
- *
- */
-void
-gedit_message_get_valist (GeditMessage *message,
-			  va_list 	var_args)
-{
-	const gchar *key;
+		if (*object_path == '/')
+		{
+			++object_path;
 
-	g_return_if_fail (GEDIT_IS_MESSAGE (message));
-	
-	while ((key = va_arg (var_args, const gchar *)) != NULL)
-	{
-		GValue *container;
-		GValue copy = {0,};
-		gchar *error = NULL;
-
-		container = value_lookup (message, key, FALSE);
-	
-		if (!container)
-		{		
-			/* skip value */
-			va_arg (var_args, gpointer);
-			continue;
+			if (!*object_path || !(g_ascii_isalpha (*object_path) || *object_path == '_'))
+			{
+				return FALSE;
+			}
 		}
-		
-		/* copy the value here, to be sure it isn't tainted */
-		g_value_init (&copy, G_VALUE_TYPE (container));
-		g_value_copy (container, &copy);
-		
-		G_VALUE_LCOPY (&copy, var_args, 0, &error);
-		
-		if (error)
+		else if (!(g_ascii_isalnum (*object_path) || *object_path == '_'))
 		{
-			g_warning ("%s: %s", G_STRLOC, error);
-			g_free (error);
-			
-			/* purposely leak the value here, because it might
-			   be in a bad state */
-			continue;
+			return FALSE;
 		}
-		
-		g_value_unset (&copy);
-	}
-}
 
-/**
- * gedit_message_get_value:
- * @message: the #GeditMessage
- * @key: the argument key
- * @value: (out): value return container
- *
- * Get the value of a specific message argument. @value will be initialized
- * with the correct type.
- *
- */
-void 
-gedit_message_get_value (GeditMessage *message,
-			 const gchar  *key,
-			 GValue	      *value)
-{
-	GValue *container;
-	
-	g_return_if_fail (GEDIT_IS_MESSAGE (message));
-	
-	container = value_lookup (message, key, FALSE);
-	
-	if (!container)
-	{
-		g_warning ("%s: Invalid key `%s'",
-			   G_STRLOC,
-			   key);
-		return;
+		++object_path;
 	}
-	
-	g_value_init (value, G_VALUE_TYPE (container));
-	set_value_real (value, container);
+
+	return TRUE;
 }
 
 /**
- * gedit_message_get_key_type:
- * @message: the #GeditMessage
- * @key: the argument key
+ * gedit_message_type_identifier:
+ * @object_path: (allow-none): the object path
+ * @method: (allow-none): the method
  *
- * Get the type of a message argument.
+ * Get the string identifier for @method at @object_path.
  *
- * Return value: the type of @key
+ * Return value: the identifier for @method at @object_path
  *
  */
-GType 
-gedit_message_get_key_type (GeditMessage    *message,
-			    const gchar	    *key)
+gchar *
+gedit_message_type_identifier (const gchar *object_path,
+                               const gchar *method)
 {
-	g_return_val_if_fail (GEDIT_IS_MESSAGE (message), G_TYPE_INVALID);
-	g_return_val_if_fail (message->priv->type != NULL, G_TYPE_INVALID);
-
-	return gedit_message_type_lookup (message->priv->type, key);
+	return g_strconcat (object_path, ".", method, NULL);
 }
 
 /**
- * gedit_message_has_key:
+ * gedit_message_has:
  * @message: the #GeditMessage
- * @key: the argument key
+ * @propname: the property name
  *
- * Check whether the message has a specific key.
+ * Check if a message has a certain property.
  *
- * Return value: %TRUE if @message has argument @key
+ * @returns: %TRUE if message has @propname, %FALSE otherwise
  *
  */
 gboolean
-gedit_message_has_key (GeditMessage *message,
-		       const gchar  *key)
+gedit_message_has (GeditMessage *message,
+                   const gchar  *propname)
 {
+	GObjectClass *klass;
+
 	g_return_val_if_fail (GEDIT_IS_MESSAGE (message), FALSE);
+	g_return_val_if_fail (propname != NULL, FALSE);
 
-	return value_lookup (message, key, FALSE) != NULL;
+	klass = G_OBJECT_GET_CLASS (G_OBJECT (message));
+
+	return g_object_class_find_property (klass, propname) != NULL;
 }
 
-typedef struct
+gboolean
+gedit_message_type_has (GType         gtype,
+                        const gchar  *propname)
 {
-	GeditMessage *message;
-	gboolean valid;	
-} ValidateInfo;
+	GObjectClass *klass;
+	gboolean ret;
 
-static void
-validate_key (const gchar  *key,
-	      GType         type,
-	      gboolean	    required,
-	      ValidateInfo *info)
-{
-	GValue *value;
-	
-	if (!info->valid || !required)
-		return;
-	
-	value = value_lookup (info->message, key, FALSE);
-	
-	if (!value)
-		info->valid = FALSE;
+	g_return_val_if_fail (g_type_is_a (gtype, GEDIT_TYPE_MESSAGE), FALSE);
+	g_return_val_if_fail (propname != NULL, FALSE);
+
+	klass = g_type_class_ref (gtype);
+	ret = g_object_class_find_property (klass, propname) != NULL;
+	g_type_class_unref (klass);
+
+	return ret;
 }
 
-/**
- * gedit_message_validate:
- * @message: the #GeditMessage
- *
- * Validates the message arguments according to the message type.
- *
- * Return value: %TRUE if the message is valid
- *
- */
 gboolean
-gedit_message_validate (GeditMessage *message)
+gedit_message_type_check (GType         gtype,
+                          const gchar  *propname,
+                          GType         value_type)
 {
-	ValidateInfo info = {message, TRUE};
+	GObjectClass *klass;
+	gboolean ret;
+	GParamSpec *spec;
 
-	g_return_val_if_fail (GEDIT_IS_MESSAGE (message), FALSE);
-	g_return_val_if_fail (message->priv->type != NULL, FALSE);
-	
-	if (!message->priv->valid)
-	{
-		gedit_message_type_foreach (message->priv->type, 
-					    (GeditMessageTypeForeach)validate_key,
-					    &info);
+	g_return_val_if_fail (g_type_is_a (gtype, GEDIT_TYPE_MESSAGE), FALSE);
+	g_return_val_if_fail (propname != NULL, FALSE);
 
-		message->priv->valid = info.valid;
-	}
+	klass = g_type_class_ref (gtype);
+	spec = g_object_class_find_property (klass, propname);
+	ret = spec != NULL && spec->value_type == value_type;
+	g_type_class_unref (klass);
 
-	return message->priv->valid;
+	return ret;
 }
 
 /* ex:set ts=8 noet: */
diff --git a/gedit/gedit-message.h b/gedit/gedit-message.h
index 9da6a08..1ead223 100644
--- a/gedit/gedit-message.h
+++ b/gedit/gedit-message.h
@@ -24,7 +24,6 @@
 #define __GEDIT_MESSAGE_H__
 
 #include <glib-object.h>
-#include <stdarg.h>
 
 G_BEGIN_DECLS
 
@@ -36,14 +35,15 @@ G_BEGIN_DECLS
 #define GEDIT_IS_MESSAGE_CLASS(klass)		(G_TYPE_CHECK_CLASS_TYPE ((klass), GEDIT_TYPE_MESSAGE))
 #define GEDIT_MESSAGE_GET_CLASS(obj)		(G_TYPE_INSTANCE_GET_CLASS ((obj), GEDIT_TYPE_MESSAGE, GeditMessageClass))
 
-typedef struct _GeditMessage		GeditMessage;
-typedef struct _GeditMessageClass	GeditMessageClass;
-typedef struct _GeditMessagePrivate	GeditMessagePrivate;
+typedef struct _GeditMessage             GeditMessage;
+typedef struct _GeditMessageClass        GeditMessageClass;
+typedef struct _GeditMessagePrivate      GeditMessagePrivate;
+typedef struct _GeditMessageClassPrivate GeditMessageClassPrivate;
 
 struct _GeditMessage
 {
 	GObject parent;
-	
+
 	GeditMessagePrivate *priv;
 };
 
@@ -52,40 +52,24 @@ struct _GeditMessageClass
 	GObjectClass parent_class;
 };
 
-GType		 gedit_message_get_type			(void) G_GNUC_CONST;
-
-struct _GeditMessageType *gedit_message_get_message_type (GeditMessage  *message);
-
-void		 gedit_message_get			(GeditMessage  *message,
-							 ...) G_GNUC_NULL_TERMINATED;
-void		 gedit_message_get_valist		(GeditMessage  *message,
-							 va_list        var_args);
-void		 gedit_message_get_value		(GeditMessage  *message,
-							 const gchar   *key,
-							 GValue        *value);
+GType        gedit_message_get_type             (void) G_GNUC_CONST;
 
-void		 gedit_message_set			(GeditMessage  *message,
-							 ...) G_GNUC_NULL_TERMINATED;
-void		 gedit_message_set_valist		(GeditMessage  *message,
-							 va_list        var_args);
-void		 gedit_message_set_value		(GeditMessage  *message,
-							 const gchar   *key,
-							 GValue        *value);
-void		 gedit_message_set_valuesv		(GeditMessage  *message,
-							 const gchar  **keys,
-							 GValue        *values,
-							 gint           n_values);
+const gchar *gedit_message_get_object_path      (GeditMessage *message);
+const gchar *gedit_message_get_method           (GeditMessage *message);
 
-const gchar	*gedit_message_get_object_path		(GeditMessage  *message);
-const gchar	*gedit_message_get_method		(GeditMessage  *message);
+gboolean     gedit_message_type_has             (GType         gtype,
+                                                 const gchar  *propname);
 
-gboolean	 gedit_message_has_key			(GeditMessage  *message,
-							 const gchar   *key);
+gboolean     gedit_message_type_check           (GType         gtype,
+                                                 const gchar  *propname,
+                                                 GType         value_type);
 
-GType		 gedit_message_get_key_type 		(GeditMessage  *message,
-							 const gchar   *key);
+gboolean     gedit_message_has                  (GeditMessage *message,
+                                                 const gchar  *propname);
 
-gboolean	 gedit_message_validate			(GeditMessage  *message);
+gboolean     gedit_message_is_valid_object_path (const gchar  *object_path);
+gchar       *gedit_message_type_identifier      (const gchar  *object_path,
+                                                 const gchar  *method);
 
 G_END_DECLS
 
diff --git a/plugins/filebrowser/Makefile.am b/plugins/filebrowser/Makefile.am
index 7acdadf..c9586f4 100644
--- a/plugins/filebrowser/Makefile.am
+++ b/plugins/filebrowser/Makefile.am
@@ -35,6 +35,15 @@ libfilebrowser_la_SOURCES = \
 	gedit-file-browser-utils.c 		\
 	gedit-file-browser-plugin.c		\
 	gedit-file-browser-messages.c		\
+	messages/gedit-file-browser-message-activation.c \
+	messages/gedit-file-browser-message-add-context-item.c \
+	messages/gedit-file-browser-message-add-filter.c \
+	messages/gedit-file-browser-message-get-root.c \
+	messages/gedit-file-browser-message-get-view.c \
+	messages/gedit-file-browser-message-id.c \
+	messages/gedit-file-browser-message-id-location.c \
+	messages/gedit-file-browser-message-set-emblem.c \
+	messages/gedit-file-browser-message-set-root.c \
 	$(NOINST_H_FILES)
 
 libfilebrowser_la_LDFLAGS = $(PLUGIN_LIBTOOL_FLAGS)
@@ -73,6 +82,9 @@ gsettings_SCHEMAS = org.gnome.gedit.plugins.filebrowser.gschema.xml
 
 @GSETTINGS_RULES@
 
+update-messages:
+	$(top_srcdir)/tools/generate-message.py $(builddir)/messages/ $(srcdir)/messages.xml
+
 EXTRA_DIST = \
 	$(ui_DATA)					\
 	$(plugin_in_files)				\
diff --git a/plugins/filebrowser/gedit-file-browser-messages.c b/plugins/filebrowser/gedit-file-browser-messages.c
index 0695bf6..d149b5a 100644
--- a/plugins/filebrowser/gedit-file-browser-messages.c
+++ b/plugins/filebrowser/gedit-file-browser-messages.c
@@ -20,6 +20,8 @@
 
 #include "gedit-file-browser-messages.h"
 #include "gedit-file-browser-store.h"
+#include "messages/messages.h"
+
 #include <gedit/gedit-message.h>
 
 #define MESSAGE_OBJECT_PATH 	"/plugins/filebrowser"
@@ -205,7 +207,7 @@ message_get_root_cb (GeditMessageBus *bus,
 
 	if (location)
 	{
-		gedit_message_set (message, "location", location, NULL);
+		g_object_set (message, "location", location, NULL);
 		g_object_unref (location);
 	}
 }
@@ -218,18 +220,23 @@ message_set_root_cb (GeditMessageBus *bus,
 	GFile *root;
 	GFile *virtual = NULL;
 
-	gedit_message_get (message, "location", &root, NULL);
+	g_object_get (message, "location", &root, NULL);
 
 	if (!root)
+	{
 		return;
+	}
 
-	if (gedit_message_has_key (message, "virtual"))
-		gedit_message_get (message, "virtual", &virtual, NULL);
+	g_object_get (message, "virtual", &virtual, NULL);
 
 	if (virtual)
+	{
 		gedit_file_browser_widget_set_root_and_virtual_root (data->widget, root, virtual);
+	}
 	else
+	{
 		gedit_file_browser_widget_set_root (data->widget, root, TRUE);
+	}
 }
 
 static void
@@ -242,7 +249,7 @@ message_set_emblem_cb (GeditMessageBus *bus,
 	GtkTreePath *path;
 	GeditFileBrowserStore *store;
 
-	gedit_message_get (message, "id", &id, "emblem", &emblem, NULL);
+	g_object_get (message, "id", &id, "emblem", &emblem, NULL);
 
 	if (!id || !emblem)
 	{
@@ -352,19 +359,26 @@ set_item_message (WindowData   *data,
 		gchar *track_id;
 
 		if (path && gtk_tree_path_get_depth (path) != 0)
+		{
 			track_id = track_row (data, store, path, location);
+		}
 		else
+		{
 			track_id = NULL;
+		}
 
-		gedit_message_set (message,
-				   "id", track_id,
-				   "location", location,
-				   NULL);
+		g_object_set (message,
+		              "id", track_id,
+		              "location", location,
+		              NULL);
 
-		if (gedit_message_has_key (message, "is_directory"))
-			gedit_message_set (message,
-					   "is_directory", FILE_IS_DIR (flags),
-					   NULL);
+		if (gedit_message_has (message, "is_directory"))
+		{
+			g_object_set (message,
+			              "is_directory",
+			              FILE_IS_DIR (flags),
+			              NULL);
+		}
 
 		g_free (track_id);
 		g_object_unref (location);
@@ -395,10 +409,10 @@ custom_message_filter_func (GeditFileBrowserWidget *widget,
 	set_item_message (wdata, iter, path, data->message);
 	gtk_tree_path_free (path);
 
-	gedit_message_set (data->message, "filter", filter, NULL);
+	g_object_set (data->message, "filter", filter, NULL);
 
 	gedit_message_bus_send_message_sync (wdata->bus, data->message);
-	gedit_message_get (data->message, "filter", &filter, NULL);
+	g_object_get (data->message, "filter", &filter, NULL);
 
 	g_object_unref (location);
 
@@ -407,61 +421,54 @@ custom_message_filter_func (GeditFileBrowserWidget *widget,
 
 static void
 message_add_filter_cb (GeditMessageBus *bus,
-		       GeditMessage    *message,
-		       GeditWindow     *window)
+                       GeditMessage    *message,
+                       GeditWindow     *window)
 {
-	gchar *object_path = NULL;
-	gchar *method = NULL;
+	const gchar *object_path = NULL;
+	const gchar *method = NULL;
 	gulong id;
-	GeditMessageType *message_type;
 	GeditMessage *cbmessage;
 	FilterData *filter_data;
-	WindowData *data = get_window_data (window);
-
-	gedit_message_get (message,
-			   "object_path", &object_path,
-			   "method", &method,
-			   NULL);
+	WindowData *data;
+	GType message_type;
 
-	/* Check if there exists such a 'callback' message */
-	if (!object_path || !method)
-	{
-		g_free (object_path);
-		g_free (method);
+	data = get_window_data (window);
 
-		return;
-	}
+	object_path = gedit_message_get_object_path (message);
+	method = gedit_message_get_method (message);
 
 	message_type = gedit_message_bus_lookup (bus, object_path, method);
 
-	if (!message_type)
+	if (message_type == G_TYPE_INVALID)
 	{
-		g_free (object_path);
-		g_free (method);
-
 		return;
 	}
 
 	/* Check if the message type has the correct arguments */
-	if (gedit_message_type_lookup (message_type, "id") != G_TYPE_STRING ||
-	    gedit_message_type_lookup (message_type, "location") != G_TYPE_FILE ||
-	    gedit_message_type_lookup (message_type, "is_directory") != G_TYPE_BOOLEAN ||
-	    gedit_message_type_lookup (message_type, "filter") != G_TYPE_BOOLEAN)
+	if (!gedit_message_type_check (message_type, "id", G_TYPE_STRING) ||
+	    !gedit_message_type_check (message_type, "location", G_TYPE_FILE) ||
+	    !gedit_message_type_check (message_type, "is-directory", G_TYPE_BOOLEAN) ||
+	    !gedit_message_type_check (message_type, "filter", G_TYPE_BOOLEAN))
+	{
 		return;
+	}
 
-	cbmessage = gedit_message_type_instantiate (message_type,
-						    "id", NULL,
-						    "location", NULL,
-						    "is_directory", FALSE,
-						    "filter", FALSE,
-						    NULL);
+	cbmessage = g_object_new (message_type,
+	                          "object-path", object_path,
+	                          "method", method,
+	                          "id", NULL,
+	                          "location", NULL,
+	                          "is-directory", FALSE,
+	                          "filter", FALSE,
+	                          NULL);
 
 	/* Register the custom filter on the widget */
 	filter_data = filter_data_new (window, cbmessage);
+
 	id = gedit_file_browser_widget_add_filter (data->widget,
-						   (GeditFileBrowserWidgetFilterFunc)custom_message_filter_func,
-						   filter_data,
-						   (GDestroyNotify)filter_data_free);
+	                                           (GeditFileBrowserWidgetFilterFunc)custom_message_filter_func,
+	                                           filter_data,
+	                                           (GDestroyNotify)filter_data_free);
 
 	filter_data->id = id;
 }
@@ -473,7 +480,7 @@ message_remove_filter_cb (GeditMessageBus *bus,
 {
 	gulong id = 0;
 
-	gedit_message_get (message, "id", &id, NULL);
+	g_object_get (message, "id", &id, NULL);
 
 	if (!id)
 		return;
@@ -524,7 +531,7 @@ message_set_show_hidden_cb (GeditMessageBus *bus,
 	GeditFileBrowserStore *store;
 	GeditFileBrowserStoreFilterMode mode;
 
-	gedit_message_get (message, "active", &active, NULL);
+	g_object_get (message, "active", &active, NULL);
 
 	store = gedit_file_browser_widget_get_browser_store (data->widget);
 	mode = gedit_file_browser_store_get_filter_mode (store);
@@ -546,7 +553,7 @@ message_set_show_binary_cb (GeditMessageBus *bus,
 	GeditFileBrowserStore *store;
 	GeditFileBrowserStoreFilterMode mode;
 
-	gedit_message_get (message, "active", &active, NULL);
+	g_object_get (message, "active", &active, NULL);
 
 	store = gedit_file_browser_widget_get_browser_store (data->widget);
 	mode = gedit_file_browser_store_get_filter_mode (store);
@@ -586,7 +593,7 @@ message_add_context_item_cb (GeditMessageBus *bus,
 	GtkUIManager *manager;
 	guint merge_id;
 
-	gedit_message_get (message,
+	g_object_get (message,
 			   "action", &action,
 			   "path", &path,
 			   NULL);
@@ -616,11 +623,11 @@ message_add_context_item_cb (GeditMessageBus *bus,
 	if (gtk_ui_manager_get_widget (manager, path))
 	{
 		data->merge_ids = g_list_prepend (data->merge_ids, GINT_TO_POINTER (merge_id));
-		gedit_message_set (message, "id", merge_id, NULL);
+		g_object_set (message, "id", merge_id, NULL);
 	}
 	else
 	{
-		gedit_message_set (message, "id", 0, NULL);
+		g_object_set (message, "id", 0, NULL);
 	}
 
 	g_object_unref (action);
@@ -636,7 +643,7 @@ message_remove_context_item_cb (GeditMessageBus *bus,
 	guint merge_id = 0;
 	GtkUIManager *manager;
 
-	gedit_message_get (message, "id", &merge_id, NULL);
+	g_object_get (message, "id", &merge_id, NULL);
 
 	if (merge_id == 0)
 		return;
@@ -655,7 +662,7 @@ message_get_view_cb (GeditMessageBus *bus,
 	GeditFileBrowserView *view;
 	view = gedit_file_browser_widget_get_browser_view (data->widget);
 
-	gedit_message_set (message, "view", view, NULL);
+	g_object_set (message, "view", view, NULL);
 }
 
 static void
@@ -667,79 +674,84 @@ register_methods (GeditWindow            *window,
 
 	/* Register method calls */
 	gedit_message_bus_register (bus,
-				    MESSAGE_OBJECT_PATH, "get_root",
-				    1,
-				    "location", G_TYPE_FILE,
-				    NULL);
+	                            GEDIT_TYPE_FILE_BROWSER_MESSAGE_GET_ROOT,
+	                            MESSAGE_OBJECT_PATH,
+	                            "get_root");
 
 	gedit_message_bus_register (bus,
-				    MESSAGE_OBJECT_PATH, "set_root",
-				    1,
-				    "location", G_TYPE_FILE,
-				    "virtual", G_TYPE_STRING,
-				    NULL);
+	                            GEDIT_TYPE_FILE_BROWSER_MESSAGE_SET_ROOT,
+	                            MESSAGE_OBJECT_PATH,
+	                            "set_root");
 
 	gedit_message_bus_register (bus,
-				    MESSAGE_OBJECT_PATH, "set_emblem",
-				    0,
-				    "id", G_TYPE_STRING,
-				    "emblem", G_TYPE_STRING,
-				    NULL);
+	                            GEDIT_TYPE_FILE_BROWSER_MESSAGE_SET_EMBLEM,
+	                            MESSAGE_OBJECT_PATH,
+	                            "set_emblem");
 
 	gedit_message_bus_register (bus,
-				    MESSAGE_OBJECT_PATH, "add_filter",
-				    1,
-				    "object_path", G_TYPE_STRING,
-				    "method", G_TYPE_STRING,
-				    "id", G_TYPE_ULONG,
-				    NULL);
+	                            GEDIT_TYPE_FILE_BROWSER_MESSAGE_ADD_FILTER,
+	                            MESSAGE_OBJECT_PATH,
+	                            "add_filter");
 
 	gedit_message_bus_register (bus,
-				    MESSAGE_OBJECT_PATH, "remove_filter",
-				    0,
-				    "id", G_TYPE_ULONG,
-				    NULL);
+	                            GEDIT_TYPE_FILE_BROWSER_MESSAGE_ID,
+	                            MESSAGE_OBJECT_PATH,
+	                            "remove_filter");
 
 	gedit_message_bus_register (bus,
-				    MESSAGE_OBJECT_PATH, "add_context_item",
-				    1,
-				    "action", GTK_TYPE_ACTION,
-				    "path", G_TYPE_STRING,
-				    "id", G_TYPE_UINT,
-				    NULL);
+	                            GEDIT_TYPE_FILE_BROWSER_MESSAGE_ADD_CONTEXT_ITEM,
+	                            MESSAGE_OBJECT_PATH,
+	                            "add_context_item");
 
 	gedit_message_bus_register (bus,
-				    MESSAGE_OBJECT_PATH, "remove_context_item",
-				    0,
-				    "id", G_TYPE_UINT,
-				    NULL);
+	                            GEDIT_TYPE_FILE_BROWSER_MESSAGE_ID,
+	                            MESSAGE_OBJECT_PATH,
+	                            "remove_context_item");
 
-	gedit_message_bus_register (bus, MESSAGE_OBJECT_PATH, "up", 0, NULL);
+	gedit_message_bus_register (bus,
+	                            GEDIT_TYPE_MESSAGE,
+	                            MESSAGE_OBJECT_PATH,
+	                            "up");
 
-	gedit_message_bus_register (bus, MESSAGE_OBJECT_PATH, "history_back", 0, NULL);
-	gedit_message_bus_register (bus, MESSAGE_OBJECT_PATH, "history_forward", 0, NULL);
+	gedit_message_bus_register (bus,
+	                            GEDIT_TYPE_MESSAGE,
+	                            MESSAGE_OBJECT_PATH,
+	                            "history_back");
 
-	gedit_message_bus_register (bus, MESSAGE_OBJECT_PATH, "refresh", 0, NULL);
+	gedit_message_bus_register (bus,
+	                            GEDIT_TYPE_MESSAGE,
+	                            MESSAGE_OBJECT_PATH,
+	                            "history_forward");
 
 	gedit_message_bus_register (bus,
-				    MESSAGE_OBJECT_PATH, "set_show_hidden",
-				    0,
-				    "active", G_TYPE_BOOLEAN,
-				    NULL);
+	                            GEDIT_TYPE_MESSAGE,
+	                            MESSAGE_OBJECT_PATH,
+	                            "refresh");
+
 	gedit_message_bus_register (bus,
-				    MESSAGE_OBJECT_PATH, "set_show_binary",
-				    0,
-				    "active", G_TYPE_BOOLEAN,
-				    NULL);
+	                            GEDIT_TYPE_FILE_BROWSER_MESSAGE_ACTIVATION,
+	                            MESSAGE_OBJECT_PATH,
+	                            "set_show_hidden");
 
-	gedit_message_bus_register (bus, MESSAGE_OBJECT_PATH, "show_bookmarks", 0, NULL);
-	gedit_message_bus_register (bus, MESSAGE_OBJECT_PATH, "show_files", 0, NULL);
+	gedit_message_bus_register (bus,
+	                            GEDIT_TYPE_FILE_BROWSER_MESSAGE_ACTIVATION,
+	                            MESSAGE_OBJECT_PATH,
+	                            "set_show_binary");
 
 	gedit_message_bus_register (bus,
-				    MESSAGE_OBJECT_PATH, "get_view",
-				    1,
-				    "view", GEDIT_TYPE_FILE_BROWSER_VIEW,
-				    NULL);
+	                            GEDIT_TYPE_MESSAGE,
+	                            MESSAGE_OBJECT_PATH,
+	                            "show_bookmarks");
+
+	gedit_message_bus_register (bus,
+	                            GEDIT_TYPE_MESSAGE,
+	                            MESSAGE_OBJECT_PATH,
+	                            "show_files");
+
+	gedit_message_bus_register (bus,
+	                            GEDIT_TYPE_FILE_BROWSER_MESSAGE_GET_VIEW,
+	                            MESSAGE_OBJECT_PATH,
+	                            "get_view");
 
 	BUS_CONNECT (bus, get_root, data);
 	BUS_CONNECT (bus, set_root, data);
@@ -821,11 +833,13 @@ store_virtual_root_changed (GeditFileBrowserStore *store,
 	vroot = gedit_file_browser_store_get_virtual_root (store);
 
 	if (!vroot)
+	{
 		return;
+	}
 
-	gedit_message_set (data->message,
-			   "location", vroot,
-			   NULL);
+	g_object_set (data->message,
+	              "location", vroot,
+	              NULL);
 
 	gedit_message_bus_send_message_sync (wdata->bus, data->message);
 
@@ -870,142 +884,134 @@ register_signals (GeditWindow            *window,
 {
 	GeditMessageBus *bus = gedit_window_get_message_bus (window);
 	GeditFileBrowserStore *store;
-	GeditMessageType *inserted_type;
-	GeditMessageType *deleted_type;
-	GeditMessageType *begin_loading_type;
-	GeditMessageType *end_loading_type;
-	GeditMessageType *root_changed_type;
 
 	GeditMessage *message;
 	WindowData *data;
 
 	/* Register signals */
-	root_changed_type = gedit_message_bus_register (bus,
-				    MESSAGE_OBJECT_PATH, "root_changed",
-				    0,
-				    "id", G_TYPE_STRING,
-				    "location", G_TYPE_FILE,
-				    NULL);
-
-	begin_loading_type = gedit_message_bus_register (bus,
-				    MESSAGE_OBJECT_PATH, "begin_loading",
-				    0,
-				    "id", G_TYPE_STRING,
-				    "location", G_TYPE_FILE,
-				    NULL);
-
-	end_loading_type = gedit_message_bus_register (bus,
-				    MESSAGE_OBJECT_PATH, "end_loading",
-				    0,
-				    "id", G_TYPE_STRING,
-				    "location", G_TYPE_FILE,
-				    NULL);
-
-	inserted_type = gedit_message_bus_register (bus,
-						    MESSAGE_OBJECT_PATH, "inserted",
-						    0,
-						    "id", G_TYPE_STRING,
-						    "location", G_TYPE_FILE,
-						    "is_directory", G_TYPE_BOOLEAN,
-						    NULL);
-
-	deleted_type = gedit_message_bus_register (bus,
-						   MESSAGE_OBJECT_PATH, "deleted",
-						   0,
-						   "id", G_TYPE_STRING,
-						   "location", G_TYPE_FILE,
-						   "is_directory", G_TYPE_BOOLEAN,
-						   NULL);
+	gedit_message_bus_register (bus,
+	                            GEDIT_TYPE_FILE_BROWSER_MESSAGE_ID_LOCATION,
+	                            MESSAGE_OBJECT_PATH,
+	                            "root_changed");
+
+	gedit_message_bus_register (bus,
+	                            GEDIT_TYPE_FILE_BROWSER_MESSAGE_ID_LOCATION,
+	                            MESSAGE_OBJECT_PATH,
+	                            "begin_loading");
+
+	gedit_message_bus_register (bus,
+	                            GEDIT_TYPE_FILE_BROWSER_MESSAGE_ID_LOCATION,
+	                            MESSAGE_OBJECT_PATH,
+	                            "end_loading");
+
+	gedit_message_bus_register (bus,
+	                            GEDIT_TYPE_FILE_BROWSER_MESSAGE_ID_LOCATION,
+	                            MESSAGE_OBJECT_PATH,
+	                            "inserted");
+
+	gedit_message_bus_register (bus,
+	                            GEDIT_TYPE_FILE_BROWSER_MESSAGE_ID_LOCATION,
+	                            MESSAGE_OBJECT_PATH,
+	                            "deleted");
 
 	store = gedit_file_browser_widget_get_browser_store (widget);
 
-	message = gedit_message_type_instantiate (inserted_type,
-						  "id", NULL,
-						  "location", NULL,
-						  "is_directory", FALSE,
-						  NULL);
+	message = g_object_new (GEDIT_TYPE_FILE_BROWSER_MESSAGE_ID_LOCATION,
+	                        "object-path", MESSAGE_OBJECT_PATH,
+	                        "method", "inserted",
+	                        NULL);
 
 	data = get_window_data (window);
 
 	data->row_inserted_id =
 		g_signal_connect_data (store,
-				       "row-inserted",
-				       G_CALLBACK (store_row_inserted),
-				       message_cache_data_new (window, message),
-				       (GClosureNotify)message_cache_data_free,
-				       0);
-
-	message = gedit_message_type_instantiate (deleted_type,
-						  "id", NULL,
-						  "location", NULL,
-						  "is_directory", FALSE,
-						  NULL);
+		                       "row-inserted",
+		                       G_CALLBACK (store_row_inserted),
+		                       message_cache_data_new (window, message),
+		                       (GClosureNotify)message_cache_data_free,
+		                       0);
+
+	message = g_object_new (GEDIT_TYPE_FILE_BROWSER_MESSAGE_ID_LOCATION,
+	                        "object-path", MESSAGE_OBJECT_PATH,
+	                        "method", "deleted",
+	                        NULL);
+
 	data->row_deleted_id =
 		g_signal_connect_data (store,
-				       "row-deleted",
-				       G_CALLBACK (store_row_deleted),
-				       message_cache_data_new (window, message),
-				       (GClosureNotify)message_cache_data_free,
-				       0);
-
-	message = gedit_message_type_instantiate (root_changed_type,
-						  "id", NULL,
-						  "location", NULL,
-						  NULL);
+		                       "row-deleted",
+		                       G_CALLBACK (store_row_deleted),
+		                       message_cache_data_new (window, message),
+		                       (GClosureNotify)message_cache_data_free,
+		                       0);
+
+	message = g_object_new (GEDIT_TYPE_FILE_BROWSER_MESSAGE_ID_LOCATION,
+	                        "object-path", MESSAGE_OBJECT_PATH,
+	                        "method", "root_changed",
+	                        NULL);
+
 	data->root_changed_id =
 		g_signal_connect_data (store,
-				       "notify::virtual-root",
-				       G_CALLBACK (store_virtual_root_changed),
-				       message_cache_data_new (window, message),
-				       (GClosureNotify)message_cache_data_free,
-				       0);
-
-	message = gedit_message_type_instantiate (begin_loading_type,
-						  "id", NULL,
-						  "location", NULL,
-						  NULL);
+		                       "notify::virtual-root",
+		                       G_CALLBACK (store_virtual_root_changed),
+		                       message_cache_data_new (window, message),
+		                       (GClosureNotify)message_cache_data_free,
+		                       0);
+
+	message = g_object_new (GEDIT_TYPE_FILE_BROWSER_MESSAGE_ID_LOCATION,
+	                        "object-path", MESSAGE_OBJECT_PATH,
+	                        "method", "begin_loading",
+	                        NULL);
+
 	data->begin_loading_id =
 		g_signal_connect_data (store,
-				      "begin_loading",
-				       G_CALLBACK (store_begin_loading),
-				       message_cache_data_new (window, message),
-				       (GClosureNotify)message_cache_data_free,
-				       0);
-
-	message = gedit_message_type_instantiate (end_loading_type,
-						  "id", NULL,
-						  "location", NULL,
-						  NULL);
+		                       "begin_loading",
+		                       G_CALLBACK (store_begin_loading),
+		                       message_cache_data_new (window, message),
+		                       (GClosureNotify)message_cache_data_free,
+		                       0);
+
+	message = g_object_new (GEDIT_TYPE_FILE_BROWSER_MESSAGE_ID_LOCATION,
+	                        "object-path", MESSAGE_OBJECT_PATH,
+	                        "method", "end_loading",
+	                        NULL);
+
 	data->end_loading_id =
 		g_signal_connect_data (store,
-				       "end_loading",
-				       G_CALLBACK (store_end_loading),
-				       message_cache_data_new (window, message),
-				       (GClosureNotify)message_cache_data_free,
-				       0);
+		                       "end_loading",
+		                       G_CALLBACK (store_end_loading),
+		                       message_cache_data_new (window, message),
+		                       (GClosureNotify)message_cache_data_free,
+		                       0);
 }
 
 static void
-message_unregistered (GeditMessageBus  *bus,
-		      GeditMessageType *message_type,
-		      GeditWindow      *window)
+message_unregistered (GeditMessageBus *bus,
+		      const gchar     *object_path,
+		      const gchar     *method,
+		      GeditWindow     *window)
 {
-	gchar *identifier = gedit_message_type_identifier (gedit_message_type_get_object_path (message_type),
-							   gedit_message_type_get_method (message_type));
+	gchar *identifier;
 	FilterData *data;
-	WindowData *wdata = get_window_data (window);
+	WindowData *wdata;
+
+	wdata = get_window_data (window);
+
+	identifier = gedit_message_type_identifier (object_path, method);
 
 	data = g_hash_table_lookup (wdata->filters, identifier);
 
 	if (data)
-		gedit_file_browser_widget_remove_filter (wdata->widget, data->id);
+	{
+		gedit_file_browser_widget_remove_filter (wdata->widget,
+		                                         data->id);
+	}
 
 	g_free (identifier);
 }
 
 void
 gedit_file_browser_messages_register (GeditWindow            *window,
-				      GeditFileBrowserWidget *widget)
+                                      GeditFileBrowserWidget *widget)
 {
 	window_data_new (window, widget);
 
@@ -1013,9 +1019,9 @@ gedit_file_browser_messages_register (GeditWindow            *window,
 	register_signals (window, widget);
 
 	g_signal_connect (gedit_window_get_message_bus (window),
-			  "unregistered",
-			  G_CALLBACK (message_unregistered),
-			  window);
+	                  "unregistered",
+	                  G_CALLBACK (message_unregistered),
+	                  window);
 }
 
 static void
diff --git a/plugins/filebrowser/messages.xml b/plugins/filebrowser/messages.xml
new file mode 100644
index 0000000..aba0ba6
--- /dev/null
+++ b/plugins/filebrowser/messages.xml
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="utf-8"?>
+<messages>
+  <message namespace="Gedit" name="FileBrowserMessageGetRoot">
+    <include>gio/gio.h</include>
+    <property name="location" type="object" gtype="G_TYPE_FILE"/>
+  </message>
+  <message namespace="Gedit" name="FileBrowserMessageSetRoot">
+    <include>gio/gio.h</include>
+    <property name="location" type="object" gtype="G_TYPE_FILE"/>
+    <property name="virtual" type="string"/>
+  </message>
+  <message namespace="Gedit" name="FileBrowserMessageSetEmblem">
+    <property name="id" type="string"/>
+    <property name="emblem" type="string"/>
+  </message>
+  <message namespace="Gedit" name="FileBrowserMessageAddFilter">
+    <property name="object_path" type="string"/>
+    <property name="method" type="string"/>
+    <property name="id" type="uint"/>
+  </message>
+  <message namespace="Gedit" name="FileBrowserMessageId">
+    <property name="id" type="uint"/>
+  </message>
+  <message namespace="Gedit" name="FileBrowserMessageAddContextItem">
+    <include system="yes">gtk/gtk.h</include>
+    <property name="action" type="object" gtype="GTK_TYPE_ACTION"/>
+    <property name="path" type="string"/>
+    <property name="id" type="uint"/>
+  </message>
+    <message namespace="Gedit" name="FileBrowserMessageActivation">
+    <property name="active" type="boolean"/>
+  </message>
+  <message namespace="Gedit" name="FileBrowserMessageGetView">
+    <include>plugins/filebrowser/gedit-file-browser-view.h</include>
+    <property name="view" type="object" gtype="GEDIT_TYPE_FILE_BROWSER_VIEW"/>
+  </message>
+  <message namespace="Gedit" name="FileBrowserMessageIdLocation">
+    <include>gio/gio.h</include>
+    <property name="id" type="string"/>
+    <property name="location" type="object" gtype="G_TYPE_FILE"/>
+    <property name="is-directory" type="boolean"/>
+  </message>
+</messages>
+<!-- vi:ex:ts=2:et -->
diff --git a/plugins/filebrowser/messages/gedit-file-browser-message-activation.c b/plugins/filebrowser/messages/gedit-file-browser-message-activation.c
new file mode 100644
index 0000000..2869f1a
--- /dev/null
+++ b/plugins/filebrowser/messages/gedit-file-browser-message-activation.c
@@ -0,0 +1,80 @@
+#include "gedit-file-browser-message-activation.h"
+
+#define GEDIT_FILE_BROWSER_MESSAGE_ACTIVATION_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE((object), GEDIT_TYPE_FILE_BROWSER_MESSAGE_ACTIVATION, GeditFileBrowserMessageActivationPrivate))
+
+enum
+{
+	PROP_0,
+
+	PROP_ACTIVE,
+};
+
+struct _GeditFileBrowserMessageActivationPrivate
+{
+	gboolean active;
+};
+
+G_DEFINE_TYPE (GeditFileBrowserMessageActivation, gedit_file_browser_message_activation, GEDIT_TYPE_MESSAGE)
+
+static void
+gedit_file_browser_message_activation_get_property (GObject    *obj,
+                                                    guint       prop_id,
+                                                    GValue     *value,
+                                                    GParamSpec *pspec)
+{
+	GeditFileBrowserMessageActivation *msg;
+
+	msg = GEDIT_FILE_BROWSER_MESSAGE_ACTIVATION (obj);
+
+	switch (prop_id)
+	{
+		case PROP_ACTIVE:
+			g_value_set_boolean (value, msg->priv->active);
+			break;
+	}
+}
+
+static void
+gedit_file_browser_message_activation_set_property (GObject      *obj,
+                                                    guint         prop_id,
+                                                    GValue const *value,
+                                                    GParamSpec   *pspec)
+{
+	GeditFileBrowserMessageActivation *msg;
+
+	msg = GEDIT_FILE_BROWSER_MESSAGE_ACTIVATION (obj);
+
+	switch (prop_id)
+	{
+		case PROP_ACTIVE:
+			msg->priv->active = g_value_get_boolean (value);
+			break;
+	}
+}
+
+static void
+gedit_file_browser_message_activation_class_init (GeditFileBrowserMessageActivationClass *klass)
+{
+	GObjectClass *object_class = G_OBJECT_CLASS(klass);
+
+	object_class->get_property = gedit_file_browser_message_activation_get_property;
+	object_class->set_property = gedit_file_browser_message_activation_set_property;
+
+	g_object_class_install_property (object_class,
+	                                 PROP_ACTIVE,
+	                                 g_param_spec_boolean ("active",
+	                                                       "Active",
+	                                                       "Active",
+	                                                       FALSE,
+	                                                       G_PARAM_READWRITE |
+	                                                       G_PARAM_CONSTRUCT |
+	                                                       G_PARAM_STATIC_STRINGS));
+
+	g_type_class_add_private (object_class, sizeof (GeditFileBrowserMessageActivationPrivate));
+}
+
+static void
+gedit_file_browser_message_activation_init (GeditFileBrowserMessageActivation *message)
+{
+	message->priv = GEDIT_FILE_BROWSER_MESSAGE_ACTIVATION_GET_PRIVATE (message);
+}
diff --git a/plugins/filebrowser/messages/gedit-file-browser-message-activation.h b/plugins/filebrowser/messages/gedit-file-browser-message-activation.h
new file mode 100644
index 0000000..1e14a36
--- /dev/null
+++ b/plugins/filebrowser/messages/gedit-file-browser-message-activation.h
@@ -0,0 +1,46 @@
+#ifndef __GEDIT_FILE_BROWSER_MESSAGE_ACTIVATION_H__
+#define __GEDIT_FILE_BROWSER_MESSAGE_ACTIVATION_H__
+
+#include <gedit/gedit-message.h>
+
+G_BEGIN_DECLS
+
+#define GEDIT_TYPE_FILE_BROWSER_MESSAGE_ACTIVATION            (gedit_file_browser_message_activation_get_type ())
+#define GEDIT_FILE_BROWSER_MESSAGE_ACTIVATION(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj),\
+                                                               GEDIT_TYPE_FILE_BROWSER_MESSAGE_ACTIVATION,\
+                                                               GeditFileBrowserMessageActivation))
+#define GEDIT_FILE_BROWSER_MESSAGE_ACTIVATION_CONST(obj)      (G_TYPE_CHECK_INSTANCE_CAST ((obj),\
+                                                               GEDIT_TYPE_FILE_BROWSER_MESSAGE_ACTIVATION,\
+                                                               GeditFileBrowserMessageActivation const))
+#define GEDIT_FILE_BROWSER_MESSAGE_ACTIVATION_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass),\
+                                                               GEDIT_TYPE_FILE_BROWSER_MESSAGE_ACTIVATION,\
+                                                               GeditFileBrowserMessageActivationClass))
+#define GEDIT_IS_FILE_BROWSER_MESSAGE_ACTIVATION(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj),\
+                                                               GEDIT_TYPE_FILE_BROWSER_MESSAGE_ACTIVATION))
+#define GEDIT_IS_FILE_BROWSER_MESSAGE_ACTIVATION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass),\
+                                                               GEDIT_TYPE_FILE_BROWSER_MESSAGE_ACTIVATION))
+#define GEDIT_FILE_BROWSER_MESSAGE_ACTIVATION_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj),\
+                                                               GEDIT_TYPE_FILE_BROWSER_MESSAGE_ACTIVATION,\
+                                                               GeditFileBrowserMessageActivationClass))
+
+typedef struct _GeditFileBrowserMessageActivation        GeditFileBrowserMessageActivation;
+typedef struct _GeditFileBrowserMessageActivationClass   GeditFileBrowserMessageActivationClass;
+typedef struct _GeditFileBrowserMessageActivationPrivate GeditFileBrowserMessageActivationPrivate;
+
+struct _GeditFileBrowserMessageActivation
+{
+	GeditMessage parent;
+
+	GeditFileBrowserMessageActivationPrivate *priv;
+};
+
+struct _GeditFileBrowserMessageActivationClass
+{
+	GeditMessageClass parent_class;
+};
+
+GType gedit_file_browser_message_activation_get_type (void) G_GNUC_CONST;
+
+G_END_DECLS
+
+#endif /* __GEDIT_FILE_BROWSER_MESSAGE_ACTIVATION_H__ */
diff --git a/plugins/filebrowser/messages/gedit-file-browser-message-add-context-item.c b/plugins/filebrowser/messages/gedit-file-browser-message-add-context-item.c
new file mode 100644
index 0000000..5da0488
--- /dev/null
+++ b/plugins/filebrowser/messages/gedit-file-browser-message-add-context-item.c
@@ -0,0 +1,144 @@
+#include "gedit-file-browser-message-add-context-item.h"
+#include <gtk/gtk.h>
+
+#define GEDIT_FILE_BROWSER_MESSAGE_ADD_CONTEXT_ITEM_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE((object), GEDIT_TYPE_FILE_BROWSER_MESSAGE_ADD_CONTEXT_ITEM, GeditFileBrowserMessageAddContextItemPrivate))
+
+enum
+{
+	PROP_0,
+
+	PROP_ACTION,
+	PROP_PATH,
+	PROP_ID,
+};
+
+struct _GeditFileBrowserMessageAddContextItemPrivate
+{
+	GtkAction *action;
+	gchar *path;
+	guint id;
+};
+
+G_DEFINE_TYPE (GeditFileBrowserMessageAddContextItem, gedit_file_browser_message_add_context_item, GEDIT_TYPE_MESSAGE)
+
+static void
+gedit_file_browser_message_add_context_item_finalize (GObject *obj)
+{
+	GeditFileBrowserMessageAddContextItem *msg = GEDIT_FILE_BROWSER_MESSAGE_ADD_CONTEXT_ITEM (obj);
+
+	if (msg->priv->action)
+	{
+		g_object_unref (msg->priv->action);
+	}
+	g_free (msg->priv->path);
+
+	G_OBJECT_CLASS (gedit_file_browser_message_add_context_item_parent_class)->finalize (obj);
+}
+
+static void
+gedit_file_browser_message_add_context_item_get_property (GObject    *obj,
+                                                          guint       prop_id,
+                                                          GValue     *value,
+                                                          GParamSpec *pspec)
+{
+	GeditFileBrowserMessageAddContextItem *msg;
+
+	msg = GEDIT_FILE_BROWSER_MESSAGE_ADD_CONTEXT_ITEM (obj);
+
+	switch (prop_id)
+	{
+		case PROP_ACTION:
+			g_value_set_object (value, msg->priv->action);
+			break;
+		case PROP_PATH:
+			g_value_set_string (value, msg->priv->path);
+			break;
+		case PROP_ID:
+			g_value_set_uint (value, msg->priv->id);
+			break;
+	}
+}
+
+static void
+gedit_file_browser_message_add_context_item_set_property (GObject      *obj,
+                                                          guint         prop_id,
+                                                          GValue const *value,
+                                                          GParamSpec   *pspec)
+{
+	GeditFileBrowserMessageAddContextItem *msg;
+
+	msg = GEDIT_FILE_BROWSER_MESSAGE_ADD_CONTEXT_ITEM (obj);
+
+	switch (prop_id)
+	{
+		case PROP_ACTION:
+		{
+			if (msg->priv->action)
+			{
+				g_object_unref (msg->priv->action);
+			}
+			msg->priv->action = g_value_dup_object (value);
+			break;
+		}
+		case PROP_PATH:
+		{
+			g_free (msg->priv->path);
+			msg->priv->path = g_value_dup_string (value);
+			break;
+		}
+		case PROP_ID:
+			msg->priv->id = g_value_get_uint (value);
+			break;
+	}
+}
+
+static void
+gedit_file_browser_message_add_context_item_class_init (GeditFileBrowserMessageAddContextItemClass *klass)
+{
+	GObjectClass *object_class = G_OBJECT_CLASS(klass);
+
+	object_class->finalize = gedit_file_browser_message_add_context_item_finalize;
+
+	object_class->get_property = gedit_file_browser_message_add_context_item_get_property;
+	object_class->set_property = gedit_file_browser_message_add_context_item_set_property;
+
+	g_object_class_install_property (object_class,
+	                                 PROP_ACTION,
+	                                 g_param_spec_object ("action",
+	                                                      "Action",
+	                                                      "Action",
+	                                                      GTK_TYPE_ACTION,
+	                                                      G_PARAM_READWRITE |
+	                                                      G_PARAM_CONSTRUCT |
+	                                                      G_PARAM_STATIC_STRINGS));
+
+	g_object_class_install_property (object_class,
+	                                 PROP_PATH,
+	                                 g_param_spec_string ("path",
+	                                                      "Path",
+	                                                      "Path",
+	                                                      NULL,
+	                                                      G_PARAM_READWRITE |
+	                                                      G_PARAM_CONSTRUCT |
+	                                                      G_PARAM_STATIC_STRINGS));
+
+	g_object_class_install_property (object_class,
+	                                 PROP_ID,
+	                                 g_param_spec_uint ("id",
+	                                                    "Id",
+	                                                    "Id",
+	                                                    0,
+	                                                    G_MAXUINT,
+	                                                    0,
+	                                                    G_PARAM_READWRITE |
+	                                                    G_PARAM_CONSTRUCT |
+	                                                    G_PARAM_STATIC_STRINGS));
+
+	g_type_class_add_private (object_class, sizeof (GeditFileBrowserMessageAddContextItemPrivate));
+}
+
+static void
+gedit_file_browser_message_add_context_item_init (GeditFileBrowserMessageAddContextItem *message)
+{
+	message->priv = GEDIT_FILE_BROWSER_MESSAGE_ADD_CONTEXT_ITEM_GET_PRIVATE (message);
+}
diff --git a/plugins/filebrowser/messages/gedit-file-browser-message-add-context-item.h b/plugins/filebrowser/messages/gedit-file-browser-message-add-context-item.h
new file mode 100644
index 0000000..2eb72aa
--- /dev/null
+++ b/plugins/filebrowser/messages/gedit-file-browser-message-add-context-item.h
@@ -0,0 +1,46 @@
+#ifndef __GEDIT_FILE_BROWSER_MESSAGE_ADD_CONTEXT_ITEM_H__
+#define __GEDIT_FILE_BROWSER_MESSAGE_ADD_CONTEXT_ITEM_H__
+
+#include <gedit/gedit-message.h>
+
+G_BEGIN_DECLS
+
+#define GEDIT_TYPE_FILE_BROWSER_MESSAGE_ADD_CONTEXT_ITEM            (gedit_file_browser_message_add_context_item_get_type ())
+#define GEDIT_FILE_BROWSER_MESSAGE_ADD_CONTEXT_ITEM(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj),\
+                                                                     GEDIT_TYPE_FILE_BROWSER_MESSAGE_ADD_CONTEXT_ITEM,\
+                                                                     GeditFileBrowserMessageAddContextItem))
+#define GEDIT_FILE_BROWSER_MESSAGE_ADD_CONTEXT_ITEM_CONST(obj)      (G_TYPE_CHECK_INSTANCE_CAST ((obj),\
+                                                                     GEDIT_TYPE_FILE_BROWSER_MESSAGE_ADD_CONTEXT_ITEM,\
+                                                                     GeditFileBrowserMessageAddContextItem const))
+#define GEDIT_FILE_BROWSER_MESSAGE_ADD_CONTEXT_ITEM_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass),\
+                                                                     GEDIT_TYPE_FILE_BROWSER_MESSAGE_ADD_CONTEXT_ITEM,\
+                                                                     GeditFileBrowserMessageAddContextItemClass))
+#define GEDIT_IS_FILE_BROWSER_MESSAGE_ADD_CONTEXT_ITEM(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj),\
+                                                                     GEDIT_TYPE_FILE_BROWSER_MESSAGE_ADD_CONTEXT_ITEM))
+#define GEDIT_IS_FILE_BROWSER_MESSAGE_ADD_CONTEXT_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass),\
+                                                                     GEDIT_TYPE_FILE_BROWSER_MESSAGE_ADD_CONTEXT_ITEM))
+#define GEDIT_FILE_BROWSER_MESSAGE_ADD_CONTEXT_ITEM_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj),\
+                                                                     GEDIT_TYPE_FILE_BROWSER_MESSAGE_ADD_CONTEXT_ITEM,\
+                                                                     GeditFileBrowserMessageAddContextItemClass))
+
+typedef struct _GeditFileBrowserMessageAddContextItem        GeditFileBrowserMessageAddContextItem;
+typedef struct _GeditFileBrowserMessageAddContextItemClass   GeditFileBrowserMessageAddContextItemClass;
+typedef struct _GeditFileBrowserMessageAddContextItemPrivate GeditFileBrowserMessageAddContextItemPrivate;
+
+struct _GeditFileBrowserMessageAddContextItem
+{
+	GeditMessage parent;
+
+	GeditFileBrowserMessageAddContextItemPrivate *priv;
+};
+
+struct _GeditFileBrowserMessageAddContextItemClass
+{
+	GeditMessageClass parent_class;
+};
+
+GType gedit_file_browser_message_add_context_item_get_type (void) G_GNUC_CONST;
+
+G_END_DECLS
+
+#endif /* __GEDIT_FILE_BROWSER_MESSAGE_ADD_CONTEXT_ITEM_H__ */
diff --git a/plugins/filebrowser/messages/gedit-file-browser-message-add-filter.c b/plugins/filebrowser/messages/gedit-file-browser-message-add-filter.c
new file mode 100644
index 0000000..5cc6898
--- /dev/null
+++ b/plugins/filebrowser/messages/gedit-file-browser-message-add-filter.c
@@ -0,0 +1,137 @@
+#include "gedit-file-browser-message-add-filter.h"
+
+#define GEDIT_FILE_BROWSER_MESSAGE_ADD_FILTER_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE((object), GEDIT_TYPE_FILE_BROWSER_MESSAGE_ADD_FILTER, GeditFileBrowserMessageAddFilterPrivate))
+
+enum
+{
+	PROP_0,
+
+	PROP_OBJECT_PATH,
+	PROP_METHOD,
+	PROP_ID,
+};
+
+struct _GeditFileBrowserMessageAddFilterPrivate
+{
+	gchar *object_path;
+	gchar *method;
+	guint id;
+};
+
+G_DEFINE_TYPE (GeditFileBrowserMessageAddFilter, gedit_file_browser_message_add_filter, GEDIT_TYPE_MESSAGE)
+
+static void
+gedit_file_browser_message_add_filter_finalize (GObject *obj)
+{
+	GeditFileBrowserMessageAddFilter *msg = GEDIT_FILE_BROWSER_MESSAGE_ADD_FILTER (obj);
+
+	g_free (msg->priv->object_path);
+	g_free (msg->priv->method);
+
+	G_OBJECT_CLASS (gedit_file_browser_message_add_filter_parent_class)->finalize (obj);
+}
+
+static void
+gedit_file_browser_message_add_filter_get_property (GObject    *obj,
+                                                    guint       prop_id,
+                                                    GValue     *value,
+                                                    GParamSpec *pspec)
+{
+	GeditFileBrowserMessageAddFilter *msg;
+
+	msg = GEDIT_FILE_BROWSER_MESSAGE_ADD_FILTER (obj);
+
+	switch (prop_id)
+	{
+		case PROP_OBJECT_PATH:
+			g_value_set_string (value, msg->priv->object_path);
+			break;
+		case PROP_METHOD:
+			g_value_set_string (value, msg->priv->method);
+			break;
+		case PROP_ID:
+			g_value_set_uint (value, msg->priv->id);
+			break;
+	}
+}
+
+static void
+gedit_file_browser_message_add_filter_set_property (GObject      *obj,
+                                                    guint         prop_id,
+                                                    GValue const *value,
+                                                    GParamSpec   *pspec)
+{
+	GeditFileBrowserMessageAddFilter *msg;
+
+	msg = GEDIT_FILE_BROWSER_MESSAGE_ADD_FILTER (obj);
+
+	switch (prop_id)
+	{
+		case PROP_OBJECT_PATH:
+		{
+			g_free (msg->priv->object_path);
+			msg->priv->object_path = g_value_dup_string (value);
+			break;
+		}
+		case PROP_METHOD:
+		{
+			g_free (msg->priv->method);
+			msg->priv->method = g_value_dup_string (value);
+			break;
+		}
+		case PROP_ID:
+			msg->priv->id = g_value_get_uint (value);
+			break;
+	}
+}
+
+static void
+gedit_file_browser_message_add_filter_class_init (GeditFileBrowserMessageAddFilterClass *klass)
+{
+	GObjectClass *object_class = G_OBJECT_CLASS(klass);
+
+	object_class->finalize = gedit_file_browser_message_add_filter_finalize;
+
+	object_class->get_property = gedit_file_browser_message_add_filter_get_property;
+	object_class->set_property = gedit_file_browser_message_add_filter_set_property;
+
+	g_object_class_install_property (object_class,
+	                                 PROP_OBJECT_PATH,
+	                                 g_param_spec_string ("object-path",
+	                                                      "Object Path",
+	                                                      "Object Path",
+	                                                      NULL,
+	                                                      G_PARAM_READWRITE |
+	                                                      G_PARAM_CONSTRUCT |
+	                                                      G_PARAM_STATIC_STRINGS));
+
+	g_object_class_install_property (object_class,
+	                                 PROP_METHOD,
+	                                 g_param_spec_string ("method",
+	                                                      "Method",
+	                                                      "Method",
+	                                                      NULL,
+	                                                      G_PARAM_READWRITE |
+	                                                      G_PARAM_CONSTRUCT |
+	                                                      G_PARAM_STATIC_STRINGS));
+
+	g_object_class_install_property (object_class,
+	                                 PROP_ID,
+	                                 g_param_spec_uint ("id",
+	                                                    "Id",
+	                                                    "Id",
+	                                                    0,
+	                                                    G_MAXUINT,
+	                                                    0,
+	                                                    G_PARAM_READWRITE |
+	                                                    G_PARAM_CONSTRUCT |
+	                                                    G_PARAM_STATIC_STRINGS));
+
+	g_type_class_add_private (object_class, sizeof (GeditFileBrowserMessageAddFilterPrivate));
+}
+
+static void
+gedit_file_browser_message_add_filter_init (GeditFileBrowserMessageAddFilter *message)
+{
+	message->priv = GEDIT_FILE_BROWSER_MESSAGE_ADD_FILTER_GET_PRIVATE (message);
+}
diff --git a/plugins/filebrowser/messages/gedit-file-browser-message-add-filter.h b/plugins/filebrowser/messages/gedit-file-browser-message-add-filter.h
new file mode 100644
index 0000000..9c6b3e1
--- /dev/null
+++ b/plugins/filebrowser/messages/gedit-file-browser-message-add-filter.h
@@ -0,0 +1,46 @@
+#ifndef __GEDIT_FILE_BROWSER_MESSAGE_ADD_FILTER_H__
+#define __GEDIT_FILE_BROWSER_MESSAGE_ADD_FILTER_H__
+
+#include <gedit/gedit-message.h>
+
+G_BEGIN_DECLS
+
+#define GEDIT_TYPE_FILE_BROWSER_MESSAGE_ADD_FILTER            (gedit_file_browser_message_add_filter_get_type ())
+#define GEDIT_FILE_BROWSER_MESSAGE_ADD_FILTER(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj),\
+                                                               GEDIT_TYPE_FILE_BROWSER_MESSAGE_ADD_FILTER,\
+                                                               GeditFileBrowserMessageAddFilter))
+#define GEDIT_FILE_BROWSER_MESSAGE_ADD_FILTER_CONST(obj)      (G_TYPE_CHECK_INSTANCE_CAST ((obj),\
+                                                               GEDIT_TYPE_FILE_BROWSER_MESSAGE_ADD_FILTER,\
+                                                               GeditFileBrowserMessageAddFilter const))
+#define GEDIT_FILE_BROWSER_MESSAGE_ADD_FILTER_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass),\
+                                                               GEDIT_TYPE_FILE_BROWSER_MESSAGE_ADD_FILTER,\
+                                                               GeditFileBrowserMessageAddFilterClass))
+#define GEDIT_IS_FILE_BROWSER_MESSAGE_ADD_FILTER(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj),\
+                                                               GEDIT_TYPE_FILE_BROWSER_MESSAGE_ADD_FILTER))
+#define GEDIT_IS_FILE_BROWSER_MESSAGE_ADD_FILTER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass),\
+                                                               GEDIT_TYPE_FILE_BROWSER_MESSAGE_ADD_FILTER))
+#define GEDIT_FILE_BROWSER_MESSAGE_ADD_FILTER_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj),\
+                                                               GEDIT_TYPE_FILE_BROWSER_MESSAGE_ADD_FILTER,\
+                                                               GeditFileBrowserMessageAddFilterClass))
+
+typedef struct _GeditFileBrowserMessageAddFilter        GeditFileBrowserMessageAddFilter;
+typedef struct _GeditFileBrowserMessageAddFilterClass   GeditFileBrowserMessageAddFilterClass;
+typedef struct _GeditFileBrowserMessageAddFilterPrivate GeditFileBrowserMessageAddFilterPrivate;
+
+struct _GeditFileBrowserMessageAddFilter
+{
+	GeditMessage parent;
+
+	GeditFileBrowserMessageAddFilterPrivate *priv;
+};
+
+struct _GeditFileBrowserMessageAddFilterClass
+{
+	GeditMessageClass parent_class;
+};
+
+GType gedit_file_browser_message_add_filter_get_type (void) G_GNUC_CONST;
+
+G_END_DECLS
+
+#endif /* __GEDIT_FILE_BROWSER_MESSAGE_ADD_FILTER_H__ */
diff --git a/plugins/filebrowser/messages/gedit-file-browser-message-get-root.c b/plugins/filebrowser/messages/gedit-file-browser-message-get-root.c
new file mode 100644
index 0000000..b3ca787
--- /dev/null
+++ b/plugins/filebrowser/messages/gedit-file-browser-message-get-root.c
@@ -0,0 +1,102 @@
+#include "gedit-file-browser-message-get-root.h"
+#include "gio/gio.h"
+
+#define GEDIT_FILE_BROWSER_MESSAGE_GET_ROOT_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE((object), GEDIT_TYPE_FILE_BROWSER_MESSAGE_GET_ROOT, GeditFileBrowserMessageGetRootPrivate))
+
+enum
+{
+	PROP_0,
+
+	PROP_LOCATION,
+};
+
+struct _GeditFileBrowserMessageGetRootPrivate
+{
+	GFile *location;
+};
+
+G_DEFINE_TYPE (GeditFileBrowserMessageGetRoot, gedit_file_browser_message_get_root, GEDIT_TYPE_MESSAGE)
+
+static void
+gedit_file_browser_message_get_root_finalize (GObject *obj)
+{
+	GeditFileBrowserMessageGetRoot *msg = GEDIT_FILE_BROWSER_MESSAGE_GET_ROOT (obj);
+
+	if (msg->priv->location)
+	{
+		g_object_unref (msg->priv->location);
+	}
+
+	G_OBJECT_CLASS (gedit_file_browser_message_get_root_parent_class)->finalize (obj);
+}
+
+static void
+gedit_file_browser_message_get_root_get_property (GObject    *obj,
+                                                  guint       prop_id,
+                                                  GValue     *value,
+                                                  GParamSpec *pspec)
+{
+	GeditFileBrowserMessageGetRoot *msg;
+
+	msg = GEDIT_FILE_BROWSER_MESSAGE_GET_ROOT (obj);
+
+	switch (prop_id)
+	{
+		case PROP_LOCATION:
+			g_value_set_object (value, msg->priv->location);
+			break;
+	}
+}
+
+static void
+gedit_file_browser_message_get_root_set_property (GObject      *obj,
+                                                  guint         prop_id,
+                                                  GValue const *value,
+                                                  GParamSpec   *pspec)
+{
+	GeditFileBrowserMessageGetRoot *msg;
+
+	msg = GEDIT_FILE_BROWSER_MESSAGE_GET_ROOT (obj);
+
+	switch (prop_id)
+	{
+		case PROP_LOCATION:
+		{
+			if (msg->priv->location)
+			{
+				g_object_unref (msg->priv->location);
+			}
+			msg->priv->location = g_value_dup_object (value);
+			break;
+		}
+	}
+}
+
+static void
+gedit_file_browser_message_get_root_class_init (GeditFileBrowserMessageGetRootClass *klass)
+{
+	GObjectClass *object_class = G_OBJECT_CLASS(klass);
+
+	object_class->finalize = gedit_file_browser_message_get_root_finalize;
+
+	object_class->get_property = gedit_file_browser_message_get_root_get_property;
+	object_class->set_property = gedit_file_browser_message_get_root_set_property;
+
+	g_object_class_install_property (object_class,
+	                                 PROP_LOCATION,
+	                                 g_param_spec_object ("location",
+	                                                      "Location",
+	                                                      "Location",
+	                                                      G_TYPE_FILE,
+	                                                      G_PARAM_READWRITE |
+	                                                      G_PARAM_CONSTRUCT |
+	                                                      G_PARAM_STATIC_STRINGS));
+
+	g_type_class_add_private (object_class, sizeof (GeditFileBrowserMessageGetRootPrivate));
+}
+
+static void
+gedit_file_browser_message_get_root_init (GeditFileBrowserMessageGetRoot *message)
+{
+	message->priv = GEDIT_FILE_BROWSER_MESSAGE_GET_ROOT_GET_PRIVATE (message);
+}
diff --git a/plugins/filebrowser/messages/gedit-file-browser-message-get-root.h b/plugins/filebrowser/messages/gedit-file-browser-message-get-root.h
new file mode 100644
index 0000000..b3098bd
--- /dev/null
+++ b/plugins/filebrowser/messages/gedit-file-browser-message-get-root.h
@@ -0,0 +1,46 @@
+#ifndef __GEDIT_FILE_BROWSER_MESSAGE_GET_ROOT_H__
+#define __GEDIT_FILE_BROWSER_MESSAGE_GET_ROOT_H__
+
+#include <gedit/gedit-message.h>
+
+G_BEGIN_DECLS
+
+#define GEDIT_TYPE_FILE_BROWSER_MESSAGE_GET_ROOT            (gedit_file_browser_message_get_root_get_type ())
+#define GEDIT_FILE_BROWSER_MESSAGE_GET_ROOT(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj),\
+                                                             GEDIT_TYPE_FILE_BROWSER_MESSAGE_GET_ROOT,\
+                                                             GeditFileBrowserMessageGetRoot))
+#define GEDIT_FILE_BROWSER_MESSAGE_GET_ROOT_CONST(obj)      (G_TYPE_CHECK_INSTANCE_CAST ((obj),\
+                                                             GEDIT_TYPE_FILE_BROWSER_MESSAGE_GET_ROOT,\
+                                                             GeditFileBrowserMessageGetRoot const))
+#define GEDIT_FILE_BROWSER_MESSAGE_GET_ROOT_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass),\
+                                                             GEDIT_TYPE_FILE_BROWSER_MESSAGE_GET_ROOT,\
+                                                             GeditFileBrowserMessageGetRootClass))
+#define GEDIT_IS_FILE_BROWSER_MESSAGE_GET_ROOT(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj),\
+                                                             GEDIT_TYPE_FILE_BROWSER_MESSAGE_GET_ROOT))
+#define GEDIT_IS_FILE_BROWSER_MESSAGE_GET_ROOT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass),\
+                                                             GEDIT_TYPE_FILE_BROWSER_MESSAGE_GET_ROOT))
+#define GEDIT_FILE_BROWSER_MESSAGE_GET_ROOT_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj),\
+                                                             GEDIT_TYPE_FILE_BROWSER_MESSAGE_GET_ROOT,\
+                                                             GeditFileBrowserMessageGetRootClass))
+
+typedef struct _GeditFileBrowserMessageGetRoot        GeditFileBrowserMessageGetRoot;
+typedef struct _GeditFileBrowserMessageGetRootClass   GeditFileBrowserMessageGetRootClass;
+typedef struct _GeditFileBrowserMessageGetRootPrivate GeditFileBrowserMessageGetRootPrivate;
+
+struct _GeditFileBrowserMessageGetRoot
+{
+	GeditMessage parent;
+
+	GeditFileBrowserMessageGetRootPrivate *priv;
+};
+
+struct _GeditFileBrowserMessageGetRootClass
+{
+	GeditMessageClass parent_class;
+};
+
+GType gedit_file_browser_message_get_root_get_type (void) G_GNUC_CONST;
+
+G_END_DECLS
+
+#endif /* __GEDIT_FILE_BROWSER_MESSAGE_GET_ROOT_H__ */
diff --git a/plugins/filebrowser/messages/gedit-file-browser-message-get-view.c b/plugins/filebrowser/messages/gedit-file-browser-message-get-view.c
new file mode 100644
index 0000000..53064b9
--- /dev/null
+++ b/plugins/filebrowser/messages/gedit-file-browser-message-get-view.c
@@ -0,0 +1,102 @@
+#include "gedit-file-browser-message-get-view.h"
+#include "plugins/filebrowser/gedit-file-browser-view.h"
+
+#define GEDIT_FILE_BROWSER_MESSAGE_GET_VIEW_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE((object), GEDIT_TYPE_FILE_BROWSER_MESSAGE_GET_VIEW, GeditFileBrowserMessageGetViewPrivate))
+
+enum
+{
+	PROP_0,
+
+	PROP_VIEW,
+};
+
+struct _GeditFileBrowserMessageGetViewPrivate
+{
+	GeditFileBrowserView *view;
+};
+
+G_DEFINE_TYPE (GeditFileBrowserMessageGetView, gedit_file_browser_message_get_view, GEDIT_TYPE_MESSAGE)
+
+static void
+gedit_file_browser_message_get_view_finalize (GObject *obj)
+{
+	GeditFileBrowserMessageGetView *msg = GEDIT_FILE_BROWSER_MESSAGE_GET_VIEW (obj);
+
+	if (msg->priv->view)
+	{
+		g_object_unref (msg->priv->view);
+	}
+
+	G_OBJECT_CLASS (gedit_file_browser_message_get_view_parent_class)->finalize (obj);
+}
+
+static void
+gedit_file_browser_message_get_view_get_property (GObject    *obj,
+                                                  guint       prop_id,
+                                                  GValue     *value,
+                                                  GParamSpec *pspec)
+{
+	GeditFileBrowserMessageGetView *msg;
+
+	msg = GEDIT_FILE_BROWSER_MESSAGE_GET_VIEW (obj);
+
+	switch (prop_id)
+	{
+		case PROP_VIEW:
+			g_value_set_object (value, msg->priv->view);
+			break;
+	}
+}
+
+static void
+gedit_file_browser_message_get_view_set_property (GObject      *obj,
+                                                  guint         prop_id,
+                                                  GValue const *value,
+                                                  GParamSpec   *pspec)
+{
+	GeditFileBrowserMessageGetView *msg;
+
+	msg = GEDIT_FILE_BROWSER_MESSAGE_GET_VIEW (obj);
+
+	switch (prop_id)
+	{
+		case PROP_VIEW:
+		{
+			if (msg->priv->view)
+			{
+				g_object_unref (msg->priv->view);
+			}
+			msg->priv->view = g_value_dup_object (value);
+			break;
+		}
+	}
+}
+
+static void
+gedit_file_browser_message_get_view_class_init (GeditFileBrowserMessageGetViewClass *klass)
+{
+	GObjectClass *object_class = G_OBJECT_CLASS(klass);
+
+	object_class->finalize = gedit_file_browser_message_get_view_finalize;
+
+	object_class->get_property = gedit_file_browser_message_get_view_get_property;
+	object_class->set_property = gedit_file_browser_message_get_view_set_property;
+
+	g_object_class_install_property (object_class,
+	                                 PROP_VIEW,
+	                                 g_param_spec_object ("view",
+	                                                      "View",
+	                                                      "View",
+	                                                      GEDIT_TYPE_FILE_BROWSER_VIEW,
+	                                                      G_PARAM_READWRITE |
+	                                                      G_PARAM_CONSTRUCT |
+	                                                      G_PARAM_STATIC_STRINGS));
+
+	g_type_class_add_private (object_class, sizeof (GeditFileBrowserMessageGetViewPrivate));
+}
+
+static void
+gedit_file_browser_message_get_view_init (GeditFileBrowserMessageGetView *message)
+{
+	message->priv = GEDIT_FILE_BROWSER_MESSAGE_GET_VIEW_GET_PRIVATE (message);
+}
diff --git a/plugins/filebrowser/messages/gedit-file-browser-message-get-view.h b/plugins/filebrowser/messages/gedit-file-browser-message-get-view.h
new file mode 100644
index 0000000..993ff20
--- /dev/null
+++ b/plugins/filebrowser/messages/gedit-file-browser-message-get-view.h
@@ -0,0 +1,46 @@
+#ifndef __GEDIT_FILE_BROWSER_MESSAGE_GET_VIEW_H__
+#define __GEDIT_FILE_BROWSER_MESSAGE_GET_VIEW_H__
+
+#include <gedit/gedit-message.h>
+
+G_BEGIN_DECLS
+
+#define GEDIT_TYPE_FILE_BROWSER_MESSAGE_GET_VIEW            (gedit_file_browser_message_get_view_get_type ())
+#define GEDIT_FILE_BROWSER_MESSAGE_GET_VIEW(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj),\
+                                                             GEDIT_TYPE_FILE_BROWSER_MESSAGE_GET_VIEW,\
+                                                             GeditFileBrowserMessageGetView))
+#define GEDIT_FILE_BROWSER_MESSAGE_GET_VIEW_CONST(obj)      (G_TYPE_CHECK_INSTANCE_CAST ((obj),\
+                                                             GEDIT_TYPE_FILE_BROWSER_MESSAGE_GET_VIEW,\
+                                                             GeditFileBrowserMessageGetView const))
+#define GEDIT_FILE_BROWSER_MESSAGE_GET_VIEW_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass),\
+                                                             GEDIT_TYPE_FILE_BROWSER_MESSAGE_GET_VIEW,\
+                                                             GeditFileBrowserMessageGetViewClass))
+#define GEDIT_IS_FILE_BROWSER_MESSAGE_GET_VIEW(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj),\
+                                                             GEDIT_TYPE_FILE_BROWSER_MESSAGE_GET_VIEW))
+#define GEDIT_IS_FILE_BROWSER_MESSAGE_GET_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass),\
+                                                             GEDIT_TYPE_FILE_BROWSER_MESSAGE_GET_VIEW))
+#define GEDIT_FILE_BROWSER_MESSAGE_GET_VIEW_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj),\
+                                                             GEDIT_TYPE_FILE_BROWSER_MESSAGE_GET_VIEW,\
+                                                             GeditFileBrowserMessageGetViewClass))
+
+typedef struct _GeditFileBrowserMessageGetView        GeditFileBrowserMessageGetView;
+typedef struct _GeditFileBrowserMessageGetViewClass   GeditFileBrowserMessageGetViewClass;
+typedef struct _GeditFileBrowserMessageGetViewPrivate GeditFileBrowserMessageGetViewPrivate;
+
+struct _GeditFileBrowserMessageGetView
+{
+	GeditMessage parent;
+
+	GeditFileBrowserMessageGetViewPrivate *priv;
+};
+
+struct _GeditFileBrowserMessageGetViewClass
+{
+	GeditMessageClass parent_class;
+};
+
+GType gedit_file_browser_message_get_view_get_type (void) G_GNUC_CONST;
+
+G_END_DECLS
+
+#endif /* __GEDIT_FILE_BROWSER_MESSAGE_GET_VIEW_H__ */
diff --git a/plugins/filebrowser/messages/gedit-file-browser-message-id-location.c b/plugins/filebrowser/messages/gedit-file-browser-message-id-location.c
new file mode 100644
index 0000000..3a508e8
--- /dev/null
+++ b/plugins/filebrowser/messages/gedit-file-browser-message-id-location.c
@@ -0,0 +1,142 @@
+#include "gedit-file-browser-message-id-location.h"
+#include "gio/gio.h"
+
+#define GEDIT_FILE_BROWSER_MESSAGE_ID_LOCATION_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE((object), GEDIT_TYPE_FILE_BROWSER_MESSAGE_ID_LOCATION, GeditFileBrowserMessageIdLocationPrivate))
+
+enum
+{
+	PROP_0,
+
+	PROP_ID,
+	PROP_LOCATION,
+	PROP_IS_DIRECTORY,
+};
+
+struct _GeditFileBrowserMessageIdLocationPrivate
+{
+	gchar *id;
+	GFile *location;
+	gboolean is_directory;
+};
+
+G_DEFINE_TYPE (GeditFileBrowserMessageIdLocation, gedit_file_browser_message_id_location, GEDIT_TYPE_MESSAGE)
+
+static void
+gedit_file_browser_message_id_location_finalize (GObject *obj)
+{
+	GeditFileBrowserMessageIdLocation *msg = GEDIT_FILE_BROWSER_MESSAGE_ID_LOCATION (obj);
+
+	g_free (msg->priv->id);
+	if (msg->priv->location)
+	{
+		g_object_unref (msg->priv->location);
+	}
+
+	G_OBJECT_CLASS (gedit_file_browser_message_id_location_parent_class)->finalize (obj);
+}
+
+static void
+gedit_file_browser_message_id_location_get_property (GObject    *obj,
+                                                     guint       prop_id,
+                                                     GValue     *value,
+                                                     GParamSpec *pspec)
+{
+	GeditFileBrowserMessageIdLocation *msg;
+
+	msg = GEDIT_FILE_BROWSER_MESSAGE_ID_LOCATION (obj);
+
+	switch (prop_id)
+	{
+		case PROP_ID:
+			g_value_set_string (value, msg->priv->id);
+			break;
+		case PROP_LOCATION:
+			g_value_set_object (value, msg->priv->location);
+			break;
+		case PROP_IS_DIRECTORY:
+			g_value_set_boolean (value, msg->priv->is_directory);
+			break;
+	}
+}
+
+static void
+gedit_file_browser_message_id_location_set_property (GObject      *obj,
+                                                     guint         prop_id,
+                                                     GValue const *value,
+                                                     GParamSpec   *pspec)
+{
+	GeditFileBrowserMessageIdLocation *msg;
+
+	msg = GEDIT_FILE_BROWSER_MESSAGE_ID_LOCATION (obj);
+
+	switch (prop_id)
+	{
+		case PROP_ID:
+		{
+			g_free (msg->priv->id);
+			msg->priv->id = g_value_dup_string (value);
+			break;
+		}
+		case PROP_LOCATION:
+		{
+			if (msg->priv->location)
+			{
+				g_object_unref (msg->priv->location);
+			}
+			msg->priv->location = g_value_dup_object (value);
+			break;
+		}
+		case PROP_IS_DIRECTORY:
+			msg->priv->is_directory = g_value_get_boolean (value);
+			break;
+	}
+}
+
+static void
+gedit_file_browser_message_id_location_class_init (GeditFileBrowserMessageIdLocationClass *klass)
+{
+	GObjectClass *object_class = G_OBJECT_CLASS(klass);
+
+	object_class->finalize = gedit_file_browser_message_id_location_finalize;
+
+	object_class->get_property = gedit_file_browser_message_id_location_get_property;
+	object_class->set_property = gedit_file_browser_message_id_location_set_property;
+
+	g_object_class_install_property (object_class,
+	                                 PROP_ID,
+	                                 g_param_spec_string ("id",
+	                                                      "Id",
+	                                                      "Id",
+	                                                      NULL,
+	                                                      G_PARAM_READWRITE |
+	                                                      G_PARAM_CONSTRUCT |
+	                                                      G_PARAM_STATIC_STRINGS));
+
+	g_object_class_install_property (object_class,
+	                                 PROP_LOCATION,
+	                                 g_param_spec_object ("location",
+	                                                      "Location",
+	                                                      "Location",
+	                                                      G_TYPE_FILE,
+	                                                      G_PARAM_READWRITE |
+	                                                      G_PARAM_CONSTRUCT |
+	                                                      G_PARAM_STATIC_STRINGS));
+
+	g_object_class_install_property (object_class,
+	                                 PROP_IS_DIRECTORY,
+	                                 g_param_spec_boolean ("is-directory",
+	                                                       "Is Directory",
+	                                                       "Is Directory",
+	                                                       FALSE,
+	                                                       G_PARAM_READWRITE |
+	                                                       G_PARAM_CONSTRUCT |
+	                                                       G_PARAM_STATIC_STRINGS));
+
+	g_type_class_add_private (object_class, sizeof (GeditFileBrowserMessageIdLocationPrivate));
+}
+
+static void
+gedit_file_browser_message_id_location_init (GeditFileBrowserMessageIdLocation *message)
+{
+	message->priv = GEDIT_FILE_BROWSER_MESSAGE_ID_LOCATION_GET_PRIVATE (message);
+}
diff --git a/plugins/filebrowser/messages/gedit-file-browser-message-id-location.h b/plugins/filebrowser/messages/gedit-file-browser-message-id-location.h
new file mode 100644
index 0000000..7b51ee7
--- /dev/null
+++ b/plugins/filebrowser/messages/gedit-file-browser-message-id-location.h
@@ -0,0 +1,46 @@
+#ifndef __GEDIT_FILE_BROWSER_MESSAGE_ID_LOCATION_H__
+#define __GEDIT_FILE_BROWSER_MESSAGE_ID_LOCATION_H__
+
+#include <gedit/gedit-message.h>
+
+G_BEGIN_DECLS
+
+#define GEDIT_TYPE_FILE_BROWSER_MESSAGE_ID_LOCATION            (gedit_file_browser_message_id_location_get_type ())
+#define GEDIT_FILE_BROWSER_MESSAGE_ID_LOCATION(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj),\
+                                                                GEDIT_TYPE_FILE_BROWSER_MESSAGE_ID_LOCATION,\
+                                                                GeditFileBrowserMessageIdLocation))
+#define GEDIT_FILE_BROWSER_MESSAGE_ID_LOCATION_CONST(obj)      (G_TYPE_CHECK_INSTANCE_CAST ((obj),\
+                                                                GEDIT_TYPE_FILE_BROWSER_MESSAGE_ID_LOCATION,\
+                                                                GeditFileBrowserMessageIdLocation const))
+#define GEDIT_FILE_BROWSER_MESSAGE_ID_LOCATION_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass),\
+                                                                GEDIT_TYPE_FILE_BROWSER_MESSAGE_ID_LOCATION,\
+                                                                GeditFileBrowserMessageIdLocationClass))
+#define GEDIT_IS_FILE_BROWSER_MESSAGE_ID_LOCATION(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj),\
+                                                                GEDIT_TYPE_FILE_BROWSER_MESSAGE_ID_LOCATION))
+#define GEDIT_IS_FILE_BROWSER_MESSAGE_ID_LOCATION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass),\
+                                                                GEDIT_TYPE_FILE_BROWSER_MESSAGE_ID_LOCATION))
+#define GEDIT_FILE_BROWSER_MESSAGE_ID_LOCATION_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj),\
+                                                                GEDIT_TYPE_FILE_BROWSER_MESSAGE_ID_LOCATION,\
+                                                                GeditFileBrowserMessageIdLocationClass))
+
+typedef struct _GeditFileBrowserMessageIdLocation        GeditFileBrowserMessageIdLocation;
+typedef struct _GeditFileBrowserMessageIdLocationClass   GeditFileBrowserMessageIdLocationClass;
+typedef struct _GeditFileBrowserMessageIdLocationPrivate GeditFileBrowserMessageIdLocationPrivate;
+
+struct _GeditFileBrowserMessageIdLocation
+{
+	GeditMessage parent;
+
+	GeditFileBrowserMessageIdLocationPrivate *priv;
+};
+
+struct _GeditFileBrowserMessageIdLocationClass
+{
+	GeditMessageClass parent_class;
+};
+
+GType gedit_file_browser_message_id_location_get_type (void) G_GNUC_CONST;
+
+G_END_DECLS
+
+#endif /* __GEDIT_FILE_BROWSER_MESSAGE_ID_LOCATION_H__ */
diff --git a/plugins/filebrowser/messages/gedit-file-browser-message-id.c b/plugins/filebrowser/messages/gedit-file-browser-message-id.c
new file mode 100644
index 0000000..634450b
--- /dev/null
+++ b/plugins/filebrowser/messages/gedit-file-browser-message-id.c
@@ -0,0 +1,82 @@
+#include "gedit-file-browser-message-id.h"
+
+#define GEDIT_FILE_BROWSER_MESSAGE_ID_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE((object), GEDIT_TYPE_FILE_BROWSER_MESSAGE_ID, GeditFileBrowserMessageIdPrivate))
+
+enum
+{
+	PROP_0,
+
+	PROP_ID,
+};
+
+struct _GeditFileBrowserMessageIdPrivate
+{
+	guint id;
+};
+
+G_DEFINE_TYPE (GeditFileBrowserMessageId, gedit_file_browser_message_id, GEDIT_TYPE_MESSAGE)
+
+static void
+gedit_file_browser_message_id_get_property (GObject    *obj,
+                                            guint       prop_id,
+                                            GValue     *value,
+                                            GParamSpec *pspec)
+{
+	GeditFileBrowserMessageId *msg;
+
+	msg = GEDIT_FILE_BROWSER_MESSAGE_ID (obj);
+
+	switch (prop_id)
+	{
+		case PROP_ID:
+			g_value_set_uint (value, msg->priv->id);
+			break;
+	}
+}
+
+static void
+gedit_file_browser_message_id_set_property (GObject      *obj,
+                                            guint         prop_id,
+                                            GValue const *value,
+                                            GParamSpec   *pspec)
+{
+	GeditFileBrowserMessageId *msg;
+
+	msg = GEDIT_FILE_BROWSER_MESSAGE_ID (obj);
+
+	switch (prop_id)
+	{
+		case PROP_ID:
+			msg->priv->id = g_value_get_uint (value);
+			break;
+	}
+}
+
+static void
+gedit_file_browser_message_id_class_init (GeditFileBrowserMessageIdClass *klass)
+{
+	GObjectClass *object_class = G_OBJECT_CLASS(klass);
+
+	object_class->get_property = gedit_file_browser_message_id_get_property;
+	object_class->set_property = gedit_file_browser_message_id_set_property;
+
+	g_object_class_install_property (object_class,
+	                                 PROP_ID,
+	                                 g_param_spec_uint ("id",
+	                                                    "Id",
+	                                                    "Id",
+	                                                    0,
+	                                                    G_MAXUINT,
+	                                                    0,
+	                                                    G_PARAM_READWRITE |
+	                                                    G_PARAM_CONSTRUCT |
+	                                                    G_PARAM_STATIC_STRINGS));
+
+	g_type_class_add_private (object_class, sizeof (GeditFileBrowserMessageIdPrivate));
+}
+
+static void
+gedit_file_browser_message_id_init (GeditFileBrowserMessageId *message)
+{
+	message->priv = GEDIT_FILE_BROWSER_MESSAGE_ID_GET_PRIVATE (message);
+}
diff --git a/plugins/filebrowser/messages/gedit-file-browser-message-id.h b/plugins/filebrowser/messages/gedit-file-browser-message-id.h
new file mode 100644
index 0000000..7376b22
--- /dev/null
+++ b/plugins/filebrowser/messages/gedit-file-browser-message-id.h
@@ -0,0 +1,46 @@
+#ifndef __GEDIT_FILE_BROWSER_MESSAGE_ID_H__
+#define __GEDIT_FILE_BROWSER_MESSAGE_ID_H__
+
+#include <gedit/gedit-message.h>
+
+G_BEGIN_DECLS
+
+#define GEDIT_TYPE_FILE_BROWSER_MESSAGE_ID            (gedit_file_browser_message_id_get_type ())
+#define GEDIT_FILE_BROWSER_MESSAGE_ID(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj),\
+                                                       GEDIT_TYPE_FILE_BROWSER_MESSAGE_ID,\
+                                                       GeditFileBrowserMessageId))
+#define GEDIT_FILE_BROWSER_MESSAGE_ID_CONST(obj)      (G_TYPE_CHECK_INSTANCE_CAST ((obj),\
+                                                       GEDIT_TYPE_FILE_BROWSER_MESSAGE_ID,\
+                                                       GeditFileBrowserMessageId const))
+#define GEDIT_FILE_BROWSER_MESSAGE_ID_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass),\
+                                                       GEDIT_TYPE_FILE_BROWSER_MESSAGE_ID,\
+                                                       GeditFileBrowserMessageIdClass))
+#define GEDIT_IS_FILE_BROWSER_MESSAGE_ID(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj),\
+                                                       GEDIT_TYPE_FILE_BROWSER_MESSAGE_ID))
+#define GEDIT_IS_FILE_BROWSER_MESSAGE_ID_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass),\
+                                                       GEDIT_TYPE_FILE_BROWSER_MESSAGE_ID))
+#define GEDIT_FILE_BROWSER_MESSAGE_ID_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj),\
+                                                       GEDIT_TYPE_FILE_BROWSER_MESSAGE_ID,\
+                                                       GeditFileBrowserMessageIdClass))
+
+typedef struct _GeditFileBrowserMessageId        GeditFileBrowserMessageId;
+typedef struct _GeditFileBrowserMessageIdClass   GeditFileBrowserMessageIdClass;
+typedef struct _GeditFileBrowserMessageIdPrivate GeditFileBrowserMessageIdPrivate;
+
+struct _GeditFileBrowserMessageId
+{
+	GeditMessage parent;
+
+	GeditFileBrowserMessageIdPrivate *priv;
+};
+
+struct _GeditFileBrowserMessageIdClass
+{
+	GeditMessageClass parent_class;
+};
+
+GType gedit_file_browser_message_id_get_type (void) G_GNUC_CONST;
+
+G_END_DECLS
+
+#endif /* __GEDIT_FILE_BROWSER_MESSAGE_ID_H__ */
diff --git a/plugins/filebrowser/messages/gedit-file-browser-message-set-emblem.c b/plugins/filebrowser/messages/gedit-file-browser-message-set-emblem.c
new file mode 100644
index 0000000..bf51f8c
--- /dev/null
+++ b/plugins/filebrowser/messages/gedit-file-browser-message-set-emblem.c
@@ -0,0 +1,117 @@
+#include "gedit-file-browser-message-set-emblem.h"
+
+#define GEDIT_FILE_BROWSER_MESSAGE_SET_EMBLEM_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE((object), GEDIT_TYPE_FILE_BROWSER_MESSAGE_SET_EMBLEM, GeditFileBrowserMessageSetEmblemPrivate))
+
+enum
+{
+	PROP_0,
+
+	PROP_ID,
+	PROP_EMBLEM,
+};
+
+struct _GeditFileBrowserMessageSetEmblemPrivate
+{
+	gchar *id;
+	gchar *emblem;
+};
+
+G_DEFINE_TYPE (GeditFileBrowserMessageSetEmblem, gedit_file_browser_message_set_emblem, GEDIT_TYPE_MESSAGE)
+
+static void
+gedit_file_browser_message_set_emblem_finalize (GObject *obj)
+{
+	GeditFileBrowserMessageSetEmblem *msg = GEDIT_FILE_BROWSER_MESSAGE_SET_EMBLEM (obj);
+
+	g_free (msg->priv->id);
+	g_free (msg->priv->emblem);
+
+	G_OBJECT_CLASS (gedit_file_browser_message_set_emblem_parent_class)->finalize (obj);
+}
+
+static void
+gedit_file_browser_message_set_emblem_get_property (GObject    *obj,
+                                                    guint       prop_id,
+                                                    GValue     *value,
+                                                    GParamSpec *pspec)
+{
+	GeditFileBrowserMessageSetEmblem *msg;
+
+	msg = GEDIT_FILE_BROWSER_MESSAGE_SET_EMBLEM (obj);
+
+	switch (prop_id)
+	{
+		case PROP_ID:
+			g_value_set_string (value, msg->priv->id);
+			break;
+		case PROP_EMBLEM:
+			g_value_set_string (value, msg->priv->emblem);
+			break;
+	}
+}
+
+static void
+gedit_file_browser_message_set_emblem_set_property (GObject      *obj,
+                                                    guint         prop_id,
+                                                    GValue const *value,
+                                                    GParamSpec   *pspec)
+{
+	GeditFileBrowserMessageSetEmblem *msg;
+
+	msg = GEDIT_FILE_BROWSER_MESSAGE_SET_EMBLEM (obj);
+
+	switch (prop_id)
+	{
+		case PROP_ID:
+		{
+			g_free (msg->priv->id);
+			msg->priv->id = g_value_dup_string (value);
+			break;
+		}
+		case PROP_EMBLEM:
+		{
+			g_free (msg->priv->emblem);
+			msg->priv->emblem = g_value_dup_string (value);
+			break;
+		}
+	}
+}
+
+static void
+gedit_file_browser_message_set_emblem_class_init (GeditFileBrowserMessageSetEmblemClass *klass)
+{
+	GObjectClass *object_class = G_OBJECT_CLASS(klass);
+
+	object_class->finalize = gedit_file_browser_message_set_emblem_finalize;
+
+	object_class->get_property = gedit_file_browser_message_set_emblem_get_property;
+	object_class->set_property = gedit_file_browser_message_set_emblem_set_property;
+
+	g_object_class_install_property (object_class,
+	                                 PROP_ID,
+	                                 g_param_spec_string ("id",
+	                                                      "Id",
+	                                                      "Id",
+	                                                      NULL,
+	                                                      G_PARAM_READWRITE |
+	                                                      G_PARAM_CONSTRUCT |
+	                                                      G_PARAM_STATIC_STRINGS));
+
+	g_object_class_install_property (object_class,
+	                                 PROP_EMBLEM,
+	                                 g_param_spec_string ("emblem",
+	                                                      "Emblem",
+	                                                      "Emblem",
+	                                                      NULL,
+	                                                      G_PARAM_READWRITE |
+	                                                      G_PARAM_CONSTRUCT |
+	                                                      G_PARAM_STATIC_STRINGS));
+
+	g_type_class_add_private (object_class, sizeof (GeditFileBrowserMessageSetEmblemPrivate));
+}
+
+static void
+gedit_file_browser_message_set_emblem_init (GeditFileBrowserMessageSetEmblem *message)
+{
+	message->priv = GEDIT_FILE_BROWSER_MESSAGE_SET_EMBLEM_GET_PRIVATE (message);
+}
diff --git a/plugins/filebrowser/messages/gedit-file-browser-message-set-emblem.h b/plugins/filebrowser/messages/gedit-file-browser-message-set-emblem.h
new file mode 100644
index 0000000..97fe320
--- /dev/null
+++ b/plugins/filebrowser/messages/gedit-file-browser-message-set-emblem.h
@@ -0,0 +1,46 @@
+#ifndef __GEDIT_FILE_BROWSER_MESSAGE_SET_EMBLEM_H__
+#define __GEDIT_FILE_BROWSER_MESSAGE_SET_EMBLEM_H__
+
+#include <gedit/gedit-message.h>
+
+G_BEGIN_DECLS
+
+#define GEDIT_TYPE_FILE_BROWSER_MESSAGE_SET_EMBLEM            (gedit_file_browser_message_set_emblem_get_type ())
+#define GEDIT_FILE_BROWSER_MESSAGE_SET_EMBLEM(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj),\
+                                                               GEDIT_TYPE_FILE_BROWSER_MESSAGE_SET_EMBLEM,\
+                                                               GeditFileBrowserMessageSetEmblem))
+#define GEDIT_FILE_BROWSER_MESSAGE_SET_EMBLEM_CONST(obj)      (G_TYPE_CHECK_INSTANCE_CAST ((obj),\
+                                                               GEDIT_TYPE_FILE_BROWSER_MESSAGE_SET_EMBLEM,\
+                                                               GeditFileBrowserMessageSetEmblem const))
+#define GEDIT_FILE_BROWSER_MESSAGE_SET_EMBLEM_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass),\
+                                                               GEDIT_TYPE_FILE_BROWSER_MESSAGE_SET_EMBLEM,\
+                                                               GeditFileBrowserMessageSetEmblemClass))
+#define GEDIT_IS_FILE_BROWSER_MESSAGE_SET_EMBLEM(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj),\
+                                                               GEDIT_TYPE_FILE_BROWSER_MESSAGE_SET_EMBLEM))
+#define GEDIT_IS_FILE_BROWSER_MESSAGE_SET_EMBLEM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass),\
+                                                               GEDIT_TYPE_FILE_BROWSER_MESSAGE_SET_EMBLEM))
+#define GEDIT_FILE_BROWSER_MESSAGE_SET_EMBLEM_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj),\
+                                                               GEDIT_TYPE_FILE_BROWSER_MESSAGE_SET_EMBLEM,\
+                                                               GeditFileBrowserMessageSetEmblemClass))
+
+typedef struct _GeditFileBrowserMessageSetEmblem        GeditFileBrowserMessageSetEmblem;
+typedef struct _GeditFileBrowserMessageSetEmblemClass   GeditFileBrowserMessageSetEmblemClass;
+typedef struct _GeditFileBrowserMessageSetEmblemPrivate GeditFileBrowserMessageSetEmblemPrivate;
+
+struct _GeditFileBrowserMessageSetEmblem
+{
+	GeditMessage parent;
+
+	GeditFileBrowserMessageSetEmblemPrivate *priv;
+};
+
+struct _GeditFileBrowserMessageSetEmblemClass
+{
+	GeditMessageClass parent_class;
+};
+
+GType gedit_file_browser_message_set_emblem_get_type (void) G_GNUC_CONST;
+
+G_END_DECLS
+
+#endif /* __GEDIT_FILE_BROWSER_MESSAGE_SET_EMBLEM_H__ */
diff --git a/plugins/filebrowser/messages/gedit-file-browser-message-set-root.c b/plugins/filebrowser/messages/gedit-file-browser-message-set-root.c
new file mode 100644
index 0000000..4492392
--- /dev/null
+++ b/plugins/filebrowser/messages/gedit-file-browser-message-set-root.c
@@ -0,0 +1,124 @@
+#include "gedit-file-browser-message-set-root.h"
+#include "gio/gio.h"
+
+#define GEDIT_FILE_BROWSER_MESSAGE_SET_ROOT_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE((object), GEDIT_TYPE_FILE_BROWSER_MESSAGE_SET_ROOT, GeditFileBrowserMessageSetRootPrivate))
+
+enum
+{
+	PROP_0,
+
+	PROP_LOCATION,
+	PROP_VIRTUAL,
+};
+
+struct _GeditFileBrowserMessageSetRootPrivate
+{
+	GFile *location;
+	gchar *virtual;
+};
+
+G_DEFINE_TYPE (GeditFileBrowserMessageSetRoot, gedit_file_browser_message_set_root, GEDIT_TYPE_MESSAGE)
+
+static void
+gedit_file_browser_message_set_root_finalize (GObject *obj)
+{
+	GeditFileBrowserMessageSetRoot *msg = GEDIT_FILE_BROWSER_MESSAGE_SET_ROOT (obj);
+
+	if (msg->priv->location)
+	{
+		g_object_unref (msg->priv->location);
+	}
+	g_free (msg->priv->virtual);
+
+	G_OBJECT_CLASS (gedit_file_browser_message_set_root_parent_class)->finalize (obj);
+}
+
+static void
+gedit_file_browser_message_set_root_get_property (GObject    *obj,
+                                                  guint       prop_id,
+                                                  GValue     *value,
+                                                  GParamSpec *pspec)
+{
+	GeditFileBrowserMessageSetRoot *msg;
+
+	msg = GEDIT_FILE_BROWSER_MESSAGE_SET_ROOT (obj);
+
+	switch (prop_id)
+	{
+		case PROP_LOCATION:
+			g_value_set_object (value, msg->priv->location);
+			break;
+		case PROP_VIRTUAL:
+			g_value_set_string (value, msg->priv->virtual);
+			break;
+	}
+}
+
+static void
+gedit_file_browser_message_set_root_set_property (GObject      *obj,
+                                                  guint         prop_id,
+                                                  GValue const *value,
+                                                  GParamSpec   *pspec)
+{
+	GeditFileBrowserMessageSetRoot *msg;
+
+	msg = GEDIT_FILE_BROWSER_MESSAGE_SET_ROOT (obj);
+
+	switch (prop_id)
+	{
+		case PROP_LOCATION:
+		{
+			if (msg->priv->location)
+			{
+				g_object_unref (msg->priv->location);
+			}
+			msg->priv->location = g_value_dup_object (value);
+			break;
+		}
+		case PROP_VIRTUAL:
+		{
+			g_free (msg->priv->virtual);
+			msg->priv->virtual = g_value_dup_string (value);
+			break;
+		}
+	}
+}
+
+static void
+gedit_file_browser_message_set_root_class_init (GeditFileBrowserMessageSetRootClass *klass)
+{
+	GObjectClass *object_class = G_OBJECT_CLASS(klass);
+
+	object_class->finalize = gedit_file_browser_message_set_root_finalize;
+
+	object_class->get_property = gedit_file_browser_message_set_root_get_property;
+	object_class->set_property = gedit_file_browser_message_set_root_set_property;
+
+	g_object_class_install_property (object_class,
+	                                 PROP_LOCATION,
+	                                 g_param_spec_object ("location",
+	                                                      "Location",
+	                                                      "Location",
+	                                                      G_TYPE_FILE,
+	                                                      G_PARAM_READWRITE |
+	                                                      G_PARAM_CONSTRUCT |
+	                                                      G_PARAM_STATIC_STRINGS));
+
+	g_object_class_install_property (object_class,
+	                                 PROP_VIRTUAL,
+	                                 g_param_spec_string ("virtual",
+	                                                      "Virtual",
+	                                                      "Virtual",
+	                                                      NULL,
+	                                                      G_PARAM_READWRITE |
+	                                                      G_PARAM_CONSTRUCT |
+	                                                      G_PARAM_STATIC_STRINGS));
+
+	g_type_class_add_private (object_class, sizeof (GeditFileBrowserMessageSetRootPrivate));
+}
+
+static void
+gedit_file_browser_message_set_root_init (GeditFileBrowserMessageSetRoot *message)
+{
+	message->priv = GEDIT_FILE_BROWSER_MESSAGE_SET_ROOT_GET_PRIVATE (message);
+}
diff --git a/plugins/filebrowser/messages/gedit-file-browser-message-set-root.h b/plugins/filebrowser/messages/gedit-file-browser-message-set-root.h
new file mode 100644
index 0000000..2210976
--- /dev/null
+++ b/plugins/filebrowser/messages/gedit-file-browser-message-set-root.h
@@ -0,0 +1,46 @@
+#ifndef __GEDIT_FILE_BROWSER_MESSAGE_SET_ROOT_H__
+#define __GEDIT_FILE_BROWSER_MESSAGE_SET_ROOT_H__
+
+#include <gedit/gedit-message.h>
+
+G_BEGIN_DECLS
+
+#define GEDIT_TYPE_FILE_BROWSER_MESSAGE_SET_ROOT            (gedit_file_browser_message_set_root_get_type ())
+#define GEDIT_FILE_BROWSER_MESSAGE_SET_ROOT(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj),\
+                                                             GEDIT_TYPE_FILE_BROWSER_MESSAGE_SET_ROOT,\
+                                                             GeditFileBrowserMessageSetRoot))
+#define GEDIT_FILE_BROWSER_MESSAGE_SET_ROOT_CONST(obj)      (G_TYPE_CHECK_INSTANCE_CAST ((obj),\
+                                                             GEDIT_TYPE_FILE_BROWSER_MESSAGE_SET_ROOT,\
+                                                             GeditFileBrowserMessageSetRoot const))
+#define GEDIT_FILE_BROWSER_MESSAGE_SET_ROOT_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass),\
+                                                             GEDIT_TYPE_FILE_BROWSER_MESSAGE_SET_ROOT,\
+                                                             GeditFileBrowserMessageSetRootClass))
+#define GEDIT_IS_FILE_BROWSER_MESSAGE_SET_ROOT(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj),\
+                                                             GEDIT_TYPE_FILE_BROWSER_MESSAGE_SET_ROOT))
+#define GEDIT_IS_FILE_BROWSER_MESSAGE_SET_ROOT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass),\
+                                                             GEDIT_TYPE_FILE_BROWSER_MESSAGE_SET_ROOT))
+#define GEDIT_FILE_BROWSER_MESSAGE_SET_ROOT_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj),\
+                                                             GEDIT_TYPE_FILE_BROWSER_MESSAGE_SET_ROOT,\
+                                                             GeditFileBrowserMessageSetRootClass))
+
+typedef struct _GeditFileBrowserMessageSetRoot        GeditFileBrowserMessageSetRoot;
+typedef struct _GeditFileBrowserMessageSetRootClass   GeditFileBrowserMessageSetRootClass;
+typedef struct _GeditFileBrowserMessageSetRootPrivate GeditFileBrowserMessageSetRootPrivate;
+
+struct _GeditFileBrowserMessageSetRoot
+{
+	GeditMessage parent;
+
+	GeditFileBrowserMessageSetRootPrivate *priv;
+};
+
+struct _GeditFileBrowserMessageSetRootClass
+{
+	GeditMessageClass parent_class;
+};
+
+GType gedit_file_browser_message_set_root_get_type (void) G_GNUC_CONST;
+
+G_END_DECLS
+
+#endif /* __GEDIT_FILE_BROWSER_MESSAGE_SET_ROOT_H__ */
diff --git a/plugins/filebrowser/messages/messages.h b/plugins/filebrowser/messages/messages.h
new file mode 100644
index 0000000..779a10b
--- /dev/null
+++ b/plugins/filebrowser/messages/messages.h
@@ -0,0 +1,15 @@
+#ifndef __GEDIT_FILE_BROWER_MESSAGES_MESSAGES_H__
+#define __GEDIT_FILE_BROWER_MESSAGES_MESSAGES_H__
+
+#include "gedit-file-browser-message-activation.h"
+#include "gedit-file-browser-message-add-context-item.h"
+#include "gedit-file-browser-message-add-filter.h"
+#include "gedit-file-browser-message-get-root.h"
+#include "gedit-file-browser-message-get-view.h"
+#include "gedit-file-browser-message-id.h"
+#include "gedit-file-browser-message-id-location.h"
+#include "gedit-file-browser-message-set-emblem.h"
+#include "gedit-file-browser-message-set-root.h"
+
+#endif /* __GEDIT_FILE_BROWER_MESSAGES_MESSAGES_H__ */
+
diff --git a/plugins/quickopen/quickopen/__init__.py b/plugins/quickopen/quickopen/__init__.py
index 7ff36c2..e1d75aa 100644
--- a/plugins/quickopen/quickopen/__init__.py
+++ b/plugins/quickopen/quickopen/__init__.py
@@ -92,18 +92,17 @@ class QuickOpenPlugin(GObject.Object, Gedit.WindowActivatable):
         # File browser root directory
         bus = self.window.get_message_bus()
 
-        #try:
-            #FIXME
-            #msg = bus.send_sync('/plugins/filebrowser', 'get_root')
+        try:
+            msg = bus.send_sync('/plugins/filebrowser', 'get_root')
 
-            #if msg:
-            #    gfile = msg.get_value('location')
+            if msg:
+                gfile = msg.props.location
 
-            #    if gfile and gfile.is_native():
-            #        paths.append(gfile)
+                if gfile and gfile.is_native():
+                    paths.append(gfile)
 
-        #except StandardError:
-        #    pass
+        except StandardError as e:
+            print e
 
         # Recent documents
         paths.append(RecentDocumentsDirectory())
diff --git a/plugins/snippets/snippets/windowactivatable.py b/plugins/snippets/snippets/windowactivatable.py
index 11d6135..79c0d8e 100644
--- a/plugins/snippets/snippets/windowactivatable.py
+++ b/plugins/snippets/snippets/windowactivatable.py
@@ -20,10 +20,16 @@ import os
 import gettext
 
 from gi.repository import Gtk, Gdk, Gedit, GObject
+import gobject
 
 from document import Document
 from library import Library
 
+class Activate(Gedit.Message):
+        view = GObject.property(type=Gedit.View)
+        iter = GObject.property(type=Gtk.TextIter)
+        trigger = GObject.property(type=str)
+
 class WindowActivatable(GObject.Object, Gedit.WindowActivatable):
         __gtype_name__ = "GeditSnippetsWindowActivatable"
 
@@ -82,51 +88,45 @@ class WindowActivatable(GObject.Object, Gedit.WindowActivatable):
         def register_messages(self):
                 bus = self.window.get_message_bus()
 
-#                self.messages = {
-#                        'activate': bus.register('/plugins/snippets', 'activate', ('view', 'iter'), trigger=str, view=Gedit.View, iter=Gtk.TextIter),
-#                        'parse-and-activate': bus.register('/plugins/snippets', 'parse-and-activate', ('view', 'iter'), snippet=str, view=Gedit.View, iter=Gtk.TextIter)
-#                }
+                bus.register(Activate, '/plugins/snippets', 'activate')
+                bus.register(Activate, '/plugins/snippets', 'parse-and-activate')
 
-#                bus.connect('/plugins/snippets', 'activate', self.on_message_activate)
-#                bus.connect('/plugins/snippets', 'parse-and-activate', self.on_message_parse_and_activate)
+                bus.connect('/plugins/snippets', 'activate', self.on_message_activate, None)
+                bus.connect('/plugins/snippets', 'parse-and-activate', self.on_message_parse_and_activate, None)
 
         def unregister_messages(self):
                 bus = self.window.get_message_bus()
+                bus.unregister_all('/plugins/snippets')
 
-#                for name in self.messages:
-#                        bus.unregister(self.messages[name])
-
-                self.messages = {}
+        def on_message_activate(self, bus, message, userdata):
+                view = message.props.view
 
-        def on_message_activate(self, bus, message):
-                if message.has_key('view'):
-                        view = message.view
-                else:
+                if not view:
                         view = self.window.get_active_view()
 
                 if not self.has_controller(view):
                         return
 
-                if message.has_key('iter'):
-                        iter = message.iter
-                else:
+                iter = message.props.iter
+
+                if not iter:
                         iter = view.get_buffer().get_iter_at_mark(view.get_buffer().get_insert())
 
                 controller = view._snippet_controller
-                controller.run_snippet_trigger(message.trigger, (iter, iter))
+                controller.run_snippet_trigger(message.props.trigger, (iter, iter))
 
-        def on_message_parse_and_activate(self, bus, message):
-                if message.has_key('view'):
-                        view = message.view
-                else:
+        def on_message_parse_and_activate(self, bus, message, userdata):
+                view = message.props.view
+
+                if not view:
                         view = self.window.get_active_view()
 
                 if not self.has_controller(view):
                         return
 
-                if message.has_key('iter'):
-                        iter = message.iter
-                else:
+                iter = message.props.iter
+
+                if not iter:
                         iter = view.get_buffer().get_iter_at_mark(view.get_buffer().get_insert())
 
                 controller = view._snippet_controller
diff --git a/tools/generate-message.py b/tools/generate-message.py
new file mode 100755
index 0000000..7da90a1
--- /dev/null
+++ b/tools/generate-message.py
@@ -0,0 +1,685 @@
+#!/usr/bin/python
+
+from xml.etree import ElementTree
+import sys
+import re
+import os
+
+class ParamSpec:
+    def __init__(self, name, nick, desc, flags, **kwargs):
+        self.name = name
+        self.nick = nick
+        self.desc = desc
+        self.flags = flags
+
+        self.args = []
+
+    def finalizer(self, container):
+        return None
+
+    def get_value(self, val, container):
+        return 'g_value_set_pointer (%s, %s->%s);' % (val, container, self.cname())
+
+    def set_value(self, val, container):
+        return '%s->%s = g_value_get_pointer (%s);' % (container, self.cname(), val)
+
+    def prop_enum(self):
+        return 'PROP_' + self.name.upper().replace('-', '_')
+
+    def cname(self):
+        return self.name.replace('-', '_')
+
+    def ctype(self):
+        return 'gpointer'
+
+    def spec_name(self):
+        name = self.__class__.__name__
+
+        if name.startswith('ParamSpec'):
+            name = name[len('ParamSpec'):]
+
+        return name.lower()
+
+    def format_str(self, s):
+        if s.startswith('"') or s.startswith('_("'):
+            return s
+
+        return '"%s"' % (s.replace('"', '\\"'),)
+
+    def __str__(self):
+        name = "g_param_spec_" + self.spec_name()
+        indent = " " * (len(name) + 2)
+
+        argstr = ''
+
+        if self.args:
+            ret = (",\n%s" % (indent,)).join(map(lambda x: str(x), self.args))
+            argstr = "\n%s%s," % (indent, ret)
+
+        return "%s (%s,\n%s%s,\n%s%s,%s\n%s%s)" % (name,
+                                                 self.format_str(self.name),
+                                                 indent,
+                                                 self.format_str(self.nick),
+                                                 indent,
+                                                 self.format_str(self.desc),
+                                                 argstr,
+                                                 indent,
+                                                 (' |\n%s' % (indent,)).join([x.strip() for x in self.flags.split('|')]))
+
+    def write(self):
+        delim = "\n" + (" " * 33)
+        spec = delim.join(str(self).splitlines())
+
+        return """
+g_object_class_install_property (object_class,
+                                 %s,
+                                 %s);""" % (self.prop_enum(), spec)
+
+class ParamSpecTyped(ParamSpec):
+    def __init__(self, name, nick, desc, flags, **kwargs):
+        ParamSpec.__init__(self, name, nick, desc, flags, **kwargs)
+
+        if 'ctype' in kwargs:
+            self._ctype = kwargs['ctype']
+        else:
+            parts = kwargs['gtype'].split('_')
+            del parts[1]
+
+            self._ctype = '%s *' % (''.join([x.title() for x in parts]),)
+
+        self.args.append(kwargs['gtype'])
+
+    def ctype(self):
+        return self._ctype
+
+class ParamSpecBoolean(ParamSpec):
+    def __init__(self, name, nick, desc, flags, **kwargs):
+        ParamSpec.__init__(self, name, nick, desc, flags, **kwargs)
+
+        if 'default' in kwargs:
+            if kwargs['default'].lower() in ['true', '1']:
+                self.args = ['TRUE']
+            else:
+                self.args = ['FALSE']
+        else:
+            self.args = ['FALSE']
+
+    def get_value(self, val, container):
+        return 'g_value_set_boolean (%s, %s->%s);' % (val, container, self.cname())
+
+    def set_value(self, val, container):
+        return '%s->%s = g_value_get_boolean (%s);' % (container, self.cname(), val)
+
+    def ctype(self):
+        return 'gboolean'
+
+class ParamSpecBoxed(ParamSpecTyped):
+    def __init__(self, name, nick, desc, flags, **kwargs):
+        ParamSpecTyped.__init__(self, name, nick, desc, flags, **kwargs)
+
+    def finalizer(self, container):
+        return 'if (%s->%s != NULL)\n{\n\tg_boxed_free (%s->%s);\n}' % (container, self.cname(), container, self.cname())
+
+    def get_value(self, val, container):
+        return 'g_value_set_boxed (%s, %s->%s);' % (val, container, self.cname())
+
+    def set_value(self, val, container):
+        return '%s->%s = g_value_dup_boxed (%s);' % (container, self.cname(), val)
+
+class ParamSpecNumeric(ParamSpec):
+    def __init__(self, name, nick, desc, flags, **kwargs):
+        ParamSpec.__init__(self, name, nick, desc, flags, **kwargs)
+
+        if 'min' in kwargs:
+            minv = kwargs['min']
+        else:
+            minv = self.min_value()
+
+        if 'max' in kwargs:
+            maxv = kwargs['max']
+        else:
+            maxv = self.max_value()
+
+        if 'default' in kwargs:
+            default = kwargs['default']
+        else:
+            default = self.default_value()
+
+        self.args = [minv, maxv, default]
+
+    def min_value(self):
+        return '0'
+
+    def max_value(self):
+        return '0'
+
+    def default_value(self):
+        return '0'
+
+class ParamSpecDouble(ParamSpecNumeric):
+    def __init__(self, name, nick, desc, flags, **kwargs):
+        ParamSpecNumeric.__init__(self, name, nick, desc, flags, **kwargs)
+
+    def min_value(self):
+        return 'G_MINDOUBLE'
+
+    def max_value(self):
+        return 'G_MAXDOUBLE'
+
+    def ctype(self):
+        return 'gdouble'
+
+    def get_value(self, val, container):
+        return 'g_value_set_double (%s, %s->%s);' % (val, container, self.cname())
+
+    def set_value(self, val, container):
+        return '%s->%s = g_value_get_double (%s);' % (container, self.cname(), val)
+
+class ParamSpecEnum(ParamSpecTyped):
+    def __init__(self, name, nick, desc, flags, **kwargs):
+        ParamSpec.__init__(self, name, nick, desc, flags, **kwargs)
+
+        if 'default' in kwargs:
+            default = kwargs['default']
+        else:
+            default = '0'
+
+        self.args.append(default)
+
+    def get_value(self, val, container):
+        return 'g_value_set_enum (%s, %s->%s);' % (val, container, self.cname())
+
+    def set_value(self, val, container):
+        return '%s->%s = g_value_get_enum (%s);' % (container, self.cname(), val)
+
+class ParamSpecFlags(ParamSpecEnum):
+    def __init__(self, name, nick, desc, flags, **kwargs):
+        ParamSpecEnum.__init__(self, name, nick, desc, flags, **kwargs)
+
+    def get_value(self, val, container):
+        return 'g_value_set_flags (%s, %s->%s);' % (val, container, self.cname())
+
+    def set_value(self, val, container):
+        return '%s->%s = g_value_get_flags (%s);' % (container, self.cname(), val)
+
+class ParamSpecFloat(ParamSpecNumeric):
+    def __init__(self, name, nick, desc, flags, **kwargs):
+        ParamSpecNumeric.__init__(self, name, nick, desc, flags, **kwargs)
+
+    def min_value(self):
+        return 'G_MINFLOAT'
+
+    def max_value(self):
+        return 'G_MAXFLOAT'
+
+    def ctype(self):
+        return 'gfloat'
+
+    def get_value(self, val, container):
+        return 'g_value_set_float (%s, %s->%s);' % (val, container, self.cname())
+
+    def set_value(self, val, container):
+        return '%s->%s = g_value_get_float (%s);' % (container, self.cname(), val)
+
+class ParamSpecInt(ParamSpecNumeric):
+    def __init__(self, name, nick, desc, flags, **kwargs):
+        ParamSpecNumeric.__init__(self, name, nick, desc, flags, **kwargs)
+
+    def min_value(self):
+        return 'G_MININT'
+
+    def max_value(self):
+        return 'G_MAXINT'
+
+    def ctype(self):
+        return 'gint'
+
+    def get_value(self, val, container):
+        return 'g_value_set_int (%s, %s->%s);' % (val, container, self.cname())
+
+    def set_value(self, val, container):
+        return '%s->%s = g_value_get_int (%s);' % (container, self.cname(), val)
+
+class ParamSpecUInt(ParamSpecNumeric):
+    def __init__(self, name, nick, desc, flags, **kwargs):
+        ParamSpecNumeric.__init__(self, name, nick, desc, flags, **kwargs)
+
+    def min_value(self):
+        return '0'
+
+    def max_value(self):
+        return 'G_MAXUINT'
+
+    def ctype(self):
+        return 'guint'
+
+    def get_value(self, val, container):
+        return 'g_value_set_uint (%s, %s->%s);' % (val, container, self.cname())
+
+    def set_value(self, val, container):
+        return '%s->%s = g_value_get_uint (%s);' % (container, self.cname(), val)
+
+class ParamSpecObject(ParamSpecTyped):
+    def __init__(self, name, nick, desc, flags, **kwargs):
+        ParamSpecTyped.__init__(self, name, nick, desc, flags, **kwargs)
+
+    def finalizer(self, container):
+        return 'if (%s->%s)\n{\n\tg_object_unref (%s->%s);\n}' % (container, self.cname(), container, self.cname())
+
+    def get_value(self, val, container):
+        return 'g_value_set_object (%s, %s->%s);' % (val, container, self.cname())
+
+    def set_value(self, val, container):
+        return '%s->%s = g_value_dup_object (%s);' % (container, self.cname(), val)
+
+class ParamSpecPointer(ParamSpec):
+    def __init__(self, name, nick, desc, flags, **kwargs):
+        ParamSpec.__init__(self, name, nick, desc, flags, **kwargs)
+
+class ParamSpecString(ParamSpec):
+    def __init__(self, name, nick, desc, flags, **kwargs):
+        ParamSpec.__init__(self, name, nick, desc, flags, **kwargs)
+
+        if 'default' in kwargs:
+            default = kwargs['default']
+        else:
+            default = 'NULL'
+
+        if not default.startswith('"') and not default.startswith('_("') and default != 'NULL':
+            default = '"' + default.replace('"', '\\"') + '"'
+
+        self.args.append(default)
+
+    def ctype(self):
+        return 'gchar *'
+
+    def finalizer(self, container):
+        return 'g_free (%s->%s);' % (container, self.cname())
+
+    def get_value(self, val, container):
+        return 'g_value_set_string (%s, %s->%s);' % (val, container, self.cname())
+
+    def set_value(self, val, container):
+        return '%s->%s = g_value_dup_string (%s);' % (container, self.cname(), val)
+
+_prop_types = {
+    'boolean': ParamSpecBoolean,
+    'boxed': ParamSpecBoxed,
+    'double': ParamSpecDouble,
+    'enum': ParamSpecEnum,
+    'flags': ParamSpecFlags,
+    'float': ParamSpecFloat,
+    'int': ParamSpecInt,
+    'object': ParamSpecObject,
+    'pointer': ParamSpecPointer,
+    'string': ParamSpecString,
+    'uint': ParamSpecUInt
+}
+
+class Include:
+    def __init__(self, elem):
+        self.path = elem.text
+        self.is_system = elem.get('system') != None
+
+    def __str__(self):
+        if self.is_system:
+            return '#include <%s>' % (self.path,)
+        else:
+            return '#include "%s"' % (self.path,)
+
+class Message:
+    def __init__(self, elem):
+        self.name = elem.get('name')
+        self.namespace = elem.get('namespace')
+
+        if not self.name:
+            sys.stderr.write("Name for message is required...\n")
+            return
+
+        if not self.namespace:
+            sys.stderr.write("Namespace for message is required (%s)...\n" % (self.name,))
+
+        self.properties = []
+        self.includes = []
+
+        for prop in elem.findall('property'):
+            self.add_prop(prop)
+
+        for inc in elem.findall('include'):
+            self.includes.append(Include(inc))
+
+        self.setup()
+
+    def setup(self):
+        parts = [x.group(0) for x in re.finditer('[A-Z]+[a-z0-9]*', self.name)]
+
+        self.ns_upper = self.namespace.upper()
+        self.ns_lower = self.namespace.lower()
+
+        self.name_upper = '_'.join([x.upper() for x in parts])
+        self.name_lower = self.name_upper.lower()
+
+        self.cname_upper = '%s_%s' % (self.ns_upper, self.name_upper)
+        self.cname_lower = self.cname_upper.lower()
+
+        self.ctype = '%s_%s_%s' % (self.ns_upper, 'TYPE', self.name_upper)
+        self.cclass = '%s%sClass' % (self.namespace, self.name)
+
+        self.cobj = '%s%s' % (self.namespace, self.name)
+        self.filename = '%s-%s' % (self.ns_lower, '-'.join([x.lower() for x in parts]))
+
+    def normalize_name(self, name):
+        if not name:
+            return name
+
+        return name.replace('_', '-')
+
+    def parse_flags(self, flags):
+        return ' | '.join(['G_PARAM_' + x.strip().replace('-', '_').upper() for x in flags.split('|')])
+
+    def add_prop(self, elem):
+        name = self.normalize_name(elem.get('name'))
+        typ = elem.get('type')
+
+        if not name:
+            sys.stderr.write("Name for property not specified...\n")
+            return False
+
+        if not typ:
+            sys.stderr.write("Type for property `%s' not specified...\n" % (name,))
+            return False
+
+        if not typ in _prop_types:
+            sys.stderr.write("Invalid property type `%s'...\n" % (typ,))
+
+        blurb = elem.get('blurb')
+        nick = elem.get('nick')
+        flags = elem.get('flags')
+
+        if not flags:
+            flags = 'G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS'
+        else:
+            flags = self.parse_flags(flags)
+
+        if not nick:
+            nick = ' '.join(map(lambda x: x.title(), name.split('-')))
+
+        if not blurb:
+            blurb = str(nick)
+
+        attr = elem.attrib
+
+        for k in ['blurb', 'nick', 'flags', 'name', 'type']:
+            if k in attr:
+                del attr[k]
+
+        self.properties.append(_prop_types[typ](name, nick, blurb, flags, **attr))
+
+    def _write(self, *args):
+        if len(args) > 1:
+            self.f.write(args[0] % args[1:])
+        elif len(args) > 0:
+            self.f.write(args[0])
+
+        self.f.write("\n")
+
+    def write_header(self, filename):
+        self.f = file(os.path.join(outdir, '%s.h' % (self.filename,)), 'w')
+
+        self._write("#ifndef __%s_H__", self.cname_upper)
+        self._write("#define __%s_H__", self.cname_upper)
+        self._write()
+
+        self._write("#include <gedit/gedit-message.h>\n")
+        self._write("G_BEGIN_DECLS\n")
+
+        alignon = len('%s_IS_%s_CLASS(klass)' % (self.ns_upper, self.name_upper))
+        alignsec = ' ' * (alignon + len('#define   '))
+
+        self._write("#define %s (%s_get_type ())", self.ctype.ljust(alignon), self.cname_lower)
+        self._write("#define %s (G_TYPE_CHECK_INSTANCE_CAST ((obj),\\\n%s%s,\\\n%s%s))",
+                    ('%s(obj)' % (self.cname_upper,)).ljust(alignon),
+                    alignsec, self.ctype,
+                    alignsec, self.cobj)
+
+        self._write("#define %s (G_TYPE_CHECK_INSTANCE_CAST ((obj),\\\n%s%s,\\\n%s%s))",
+                    ('%s_CONST(obj)' % (self.cname_upper,)).ljust(alignon),
+                    alignsec, self.ctype,
+                    alignsec, '%s const' % (self.cobj,))
+
+        self._write("#define %s (G_TYPE_CHECK_CLASS_CAST ((klass),\\\n%s%s,\\\n%s%s))",
+                    ('%s_CLASS(klass)' % (self.cname_upper,)).ljust(alignon),
+                    alignsec, self.ctype,
+                    alignsec, self.cclass)
+
+        self._write("#define %s (G_TYPE_CHECK_INSTANCE_TYPE ((obj),\\\n%s%s))",
+                    ('%s_IS_%s(obj)' % (self.ns_upper, self.name_upper)).ljust(alignon),
+                    alignsec, self.ctype)
+
+        self._write("#define %s (G_TYPE_CHECK_CLASS_TYPE ((klass),\\\n%s%s))",
+                    ('%s_IS_%s_CLASS(klass)' % (self.ns_upper, self.name_upper)).ljust(alignon),
+                    alignsec, self.ctype)
+
+        self._write("#define %s (G_TYPE_INSTANCE_GET_CLASS ((obj),\\\n%s%s,\\\n%s%s))",
+                    ('%s_GET_CLASS(obj)' % (self.cname_upper,)).ljust(alignon),
+                    alignsec, self.ctype,
+                    alignsec, self.cclass)
+
+        thepriv = '%sPrivate' % (self.cobj,)
+        alignon = len(thepriv)
+
+        self._write()
+        self._write('typedef struct _%s %s;', self.cobj.ljust(alignon), self.cobj)
+        self._write('typedef struct _%s %s;', self.cclass.ljust(alignon), self.cclass)
+        self._write('typedef struct _%s %s;', thepriv.ljust(alignon), thepriv)
+        self._write()
+
+        self._write('struct _%s', self.cobj)
+        self._write('{')
+        self._write('\tGeditMessage parent;')
+        self._write()
+        self._write('\t%s *priv;', thepriv)
+        self._write('};')
+        self._write()
+        self._write('struct _%s', self.cclass)
+        self._write('{')
+        self._write('\tGeditMessageClass parent_class;')
+        self._write('};')
+        self._write()
+
+        self._write('GType %s_get_type (void) G_GNUC_CONST;', self.cname_lower)
+        self._write()
+        self._write('G_END_DECLS')
+        self._write()
+        self._write("#endif /* __%s_H__ */", self.cname_upper)
+
+        self.f.close()
+
+    def needs_finalize(self):
+        for prop in self.properties:
+            out = prop.finalizer('ignore')
+
+            if out:
+                return True
+
+        return False
+
+    def write_body(self, outdir):
+        self.f = file(os.path.join(outdir, '%s.c' % (self.filename,)), 'w')
+
+        self._write('#include "%s.h"', self.filename)
+
+        for inc in self.includes:
+            self._write('%s', inc)
+
+        self._write()
+        self._write('#define %s_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE((object), %s, %sPrivate))',
+                    self.cname_upper, self.ctype, self.cobj)
+        self._write()
+
+        self._write('enum')
+        self._write('{')
+        self._write('\tPROP_0,')
+        self._write()
+
+        for prop in self.properties:
+            self._write('\t%s,', prop.prop_enum())
+
+        self._write('};')
+        self._write()
+
+        self._write('struct _%sPrivate', self.cobj)
+        self._write('{')
+
+        for prop in self.properties:
+            ct = prop.ctype()
+
+            if not ct.endswith('*'):
+                ct += ' '
+
+            self._write('\t%s%s;', ct, prop.cname())
+
+        self._write('};')
+        self._write()
+
+        self._write('G_DEFINE_TYPE (%s, %s, GEDIT_TYPE_MESSAGE)', self.cobj, self.cname_lower)
+        self._write()
+
+        if self.needs_finalize():
+            self._write('static void')
+            self._write('%s_finalize (GObject *obj)', self.cname_lower)
+            self._write('{')
+            self._write('\t%s *msg = %s (obj);', self.cobj, self.cname_upper)
+            self._write()
+
+            haswritten = False
+
+            for prop in self.properties:
+                out = prop.finalizer('msg->priv')
+
+                if out:
+                    haswritten = True
+                    self._write('\t%s', '\n\t'.join(out.splitlines()))
+
+            if haswritten:
+                self._write()
+
+            self._write('\tG_OBJECT_CLASS (%s_parent_class)->finalize (obj);', self.cname_lower)
+            self._write('}')
+            self._write()
+
+        ll = ' ' * (len(self.cname_lower))
+
+        self._write('static void')
+        self._write('%s_get_property (GObject    *obj,', self.cname_lower)
+        self._write('%s               guint       prop_id,', ll)
+        self._write('%s               GValue     *value,', ll)
+        self._write('%s               GParamSpec *pspec)', ll)
+        self._write('{')
+        self._write('\t%s *msg;', self.cobj)
+        self._write()
+        self._write('\tmsg = %s (obj);', self.cname_upper)
+        self._write()
+        self._write('\tswitch (prop_id)')
+        self._write('\t{')
+
+        for prop in self.properties:
+            self._write('\t\tcase %s:', prop.prop_enum())
+            self._write('\t\t\t%s', prop.get_value('value', 'msg->priv'))
+            self._write('\t\t\tbreak;')
+
+        self._write('\t}')
+        self._write('}')
+        self._write()
+        self._write('static void')
+        self._write('%s_set_property (GObject      *obj,', self.cname_lower)
+        self._write('%s               guint         prop_id,', ll)
+        self._write('%s               GValue const *value,', ll)
+        self._write('%s               GParamSpec   *pspec)', ll)
+        self._write('{')
+        self._write('\t%s *msg;', self.cobj)
+        self._write()
+        self._write('\tmsg = %s (obj);', self.cname_upper)
+        self._write()
+        self._write('\tswitch (prop_id)')
+        self._write('\t{')
+
+        for prop in self.properties:
+            self._write('\t\tcase %s:', prop.prop_enum())
+
+            out = prop.finalizer('msg->priv')
+
+            if out:
+                out = '\n\t\t\t'.join(out.splitlines())
+                self._write('\t\t{')
+                self._write('\t\t\t%s' % (out,))
+
+            self._write('\t\t\t%s', prop.set_value('value', 'msg->priv'))
+            self._write('\t\t\tbreak;')
+
+            if out:
+                self._write('\t\t}')
+
+        self._write('\t}')
+        self._write('}')
+        self._write()
+
+        self._write('static void')
+        self._write('%s_class_init (%s *klass)', self.cname_lower, self.cclass)
+        self._write('{')
+        self._write('\tGObjectClass *object_class = G_OBJECT_CLASS(klass);')
+        self._write()
+
+        if self.needs_finalize():
+            self._write('\tobject_class->finalize = %s_finalize;', self.cname_lower)
+            self._write()
+
+        self._write('\tobject_class->get_property = %s_get_property;', self.cname_lower)
+        self._write('\tobject_class->set_property = %s_set_property;', self.cname_lower)
+        self._write()
+
+        pp = 'g_object_class_install_property ('
+        prefix = '\t%s' % (' ' * len(pp),)
+
+        for prop in self.properties:
+            out = str(prop)
+            out = ("\n%s" % (prefix,)).join(out.splitlines())
+
+            self._write('\tg_object_class_install_property (object_class,\n%s%s,', prefix, prop.prop_enum())
+            self._write('%s%s);', prefix, out)
+            self._write()
+
+        self._write('\tg_type_class_add_private (object_class, sizeof (%sPrivate));', self.cobj)
+        self._write('}')
+        self._write()
+
+        self._write('static void')
+        self._write('%s_init (%s *message)', self.cname_lower, self.cobj)
+        self._write('{')
+        self._write('\tmessage->priv = %s_GET_PRIVATE (message);', self.cname_upper)
+        self._write('}')
+
+        self.f.close()
+
+class Generator:
+    def __init__(self, filename):
+        self.filename = filename
+        self.doc = ElementTree.parse(filename)
+
+    def write_message(self, outputdir, elem):
+        msg = Message(elem)
+
+        msg.write_header(outputdir)
+        msg.write_body(outputdir)
+
+    def write(self, outputdir = '.'):
+        for message in self.doc.findall('message'):
+            self.write_message(outputdir, message)
+
+outdir = sys.argv[1]
+
+for arg in sys.argv[2:]:
+    generator = Generator(arg)
+    generator.write(outdir)
+
+# vi:ex:ts=4:et



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