[gvfs] Port volume monitoring and metadata to GDBus



commit 8315eaf84e52c6a00a4905f1f6a73182db9e8015
Author: Tomas Bzatek <tbzatek redhat com>
Date:   Wed May 18 13:56:58 2011 +0200

    Port volume monitoring and metadata to GDBus
    
    This is a complete port of volume monitors and metadata to GDBus.
    The (private) d-bus API has been mostly preserved except of
    MountOp methods.
    
    No difference in functionality should be observed.

 .gitignore                                   |    2 +
 client/gdaemonfile.c                         |   72 +-
 client/gdaemonvfs.c                          |  273 +++--
 client/gdaemonvfs.h                          |    6 +-
 metadata/Makefile.am                         |   25 +-
 metadata/dbus-interface.xml                  |   57 +
 metadata/meta-daemon.c                       |  683 ++++--------
 metadata/meta-set.c                          |  139 ++--
 monitor/afc/Makefile.am                      |    1 -
 monitor/gdu/Makefile.am                      |    2 -
 monitor/proxy/Makefile.am                    |   30 +-
 monitor/proxy/dbus-interfaces.xml            |  176 +++
 monitor/proxy/gproxydrive.c                  |  484 ++++-----
 monitor/proxy/gproxydrive.h                  |   14 +-
 monitor/proxy/gproxymount.c                  |  186 ++--
 monitor/proxy/gproxymount.h                  |    2 +-
 monitor/proxy/gproxymountoperation.c         |  235 ++---
 monitor/proxy/gproxymountoperation.h         |   27 +-
 monitor/proxy/gproxyshadowmount.c            |    2 -
 monitor/proxy/gproxyvolume.c                 |  183 ++--
 monitor/proxy/gproxyvolume.h                 |    2 +-
 monitor/proxy/gproxyvolumemonitor.c          | 1214 ++++++++++++---------
 monitor/proxy/gproxyvolumemonitor.h          |   17 +-
 monitor/proxy/gvfsproxyvolumemonitordaemon.c | 1549 +++++++++++---------------
 24 files changed, 2618 insertions(+), 2763 deletions(-)
---
diff --git a/.gitignore b/.gitignore
index 17ff40a..0a044dd 100644
--- a/.gitignore
+++ b/.gitignore
@@ -38,3 +38,5 @@ gtk-doc.make
 *-marshal.[ch]
 *.gschema.valid
 *.enums.xml
+monitor/proxy/gvfsvolumemonitordbus.*
+metadata/metadata-dbus.*
diff --git a/client/gdaemonfile.c b/client/gdaemonfile.c
index 15c368c..5ab98d6 100644
--- a/client/gdaemonfile.c
+++ b/client/gdaemonfile.c
@@ -29,6 +29,7 @@
 #include <sys/socket.h>
 
 #include "gdaemonfile.h"
+#include "gdaemonvfs.h"
 #include "gvfsdaemondbus.h"
 #include "gdaemonmount.h"
 #include <gvfsdaemonprotocol.h>
@@ -41,6 +42,7 @@
 #include "gmountoperationdbus.h"
 #include <gio/gio.h>
 #include "metatree.h"
+#include <metadata-dbus.h>
 
 static void g_daemon_file_file_iface_init (GFileIface       *iface);
 
@@ -2215,53 +2217,57 @@ set_metadata_attribute (GFile *file,
 			GError **error)
 {
   GDaemonFile *daemon_file;
-  DBusMessage *message;
   char *treename;
   const char *metatreefile;
   MetaTree *tree;
   int appended;
   gboolean res;
+  GVfsMetadata *proxy;
+  GVariantBuilder *builder;
 
   daemon_file = G_DAEMON_FILE (file);
 
   treename = g_mount_spec_to_string (daemon_file->mount_spec);
   tree = meta_tree_lookup_by_name (treename, FALSE);
   g_free (treename);
+  
+  res = FALSE;
+  proxy = _g_daemon_vfs_get_metadata_proxy (cancellable, error);
 
-  message =
-    dbus_message_new_method_call (G_VFS_DBUS_METADATA_NAME,
-				  G_VFS_DBUS_METADATA_PATH,
-				  G_VFS_DBUS_METADATA_INTERFACE,
-				  G_VFS_DBUS_METADATA_OP_SET);
-  g_assert (message != NULL);
-  metatreefile = meta_tree_get_filename (tree);
-  _g_dbus_message_append_args (message,
-			       G_DBUS_TYPE_CSTRING, &metatreefile,
-			       G_DBUS_TYPE_CSTRING, &daemon_file->path,
-			       0);
-
-  appended = _g_daemon_vfs_append_metadata_for_set (message,
-						    tree,
-						    daemon_file->path,
-						    attribute,
-						    type,
-						    value);
-
-  res = TRUE;
-  if (appended == -1)
+  if (proxy)
     {
-      res = FALSE;
-      g_set_error (error, G_IO_ERROR,
-		   G_IO_ERROR_INVALID_ARGUMENT,
-		   _("Error setting file metadata: %s"),
-		   _("values must be string or list of strings"));
-    }
-  else if (appended > 0 &&
-      !_g_daemon_vfs_send_message_sync (message,
-					cancellable, error))
-    res = FALSE;
+      builder = g_variant_builder_new (G_VARIANT_TYPE_VARDICT);
 
-  dbus_message_unref (message);
+      metatreefile = meta_tree_get_filename (tree);
+
+      appended = _g_daemon_vfs_append_metadata_for_set (builder,
+                                                        tree,
+                                                        daemon_file->path,
+                                                        attribute,
+                                                        type,
+                                                        value);
+    
+      res = TRUE;
+      if (appended == -1)
+        {
+          res = FALSE;
+          g_set_error (error, G_IO_ERROR,
+                       G_IO_ERROR_INVALID_ARGUMENT,
+                       _("Error setting file metadata: %s"),
+                       _("values must be string or list of strings"));
+        }
+      else if (appended > 0 &&
+               !gvfs_metadata_call_set_sync (proxy,
+                                             metatreefile,
+                                             daemon_file->path,
+                                             g_variant_builder_end (builder),
+                                             cancellable,
+                                             error))
+        res = FALSE;
+
+      g_variant_builder_unref (builder);
+      g_object_unref (proxy);
+    }
 
   meta_tree_unref (tree);
 
diff --git a/client/gdaemonvfs.c b/client/gdaemonvfs.c
index e62da9b..c131545 100644
--- a/client/gdaemonvfs.c
+++ b/client/gdaemonvfs.c
@@ -77,6 +77,9 @@ G_DEFINE_DYNAMIC_TYPE (GDaemonVfs, g_daemon_vfs, G_TYPE_VFS)
 
 static GDaemonVfs *the_vfs = NULL;
 
+G_LOCK_DEFINE_STATIC (metadata_proxy);
+static GVfsMetadata *metadata_proxy = NULL;
+
 G_LOCK_DEFINE_STATIC(mount_cache);
 
 
@@ -1170,19 +1173,6 @@ g_daemon_vfs_add_writable_namespaces (GVfs       *vfs,
 				  G_FILE_ATTRIBUTE_INFO_COPY_WHEN_MOVED);
 }
 
-static void
-send_message_oneway (DBusMessage *message)
-{
-  DBusConnection *connection;
-
-  connection = _g_dbus_connection_get_sync (NULL, NULL);
-  if (connection == NULL)
-    return;
-
-  dbus_connection_send (connection, message, NULL);
-  dbus_connection_flush (connection);
-}
-
 /* Sends a message on the session bus and blocks for the reply,
    using the thread local connection */
 gboolean
@@ -1239,7 +1229,7 @@ strv_equal (char **a, char **b)
 
 /* -1 => error, otherwise number of added items */
 int
-_g_daemon_vfs_append_metadata_for_set (DBusMessage *message,
+_g_daemon_vfs_append_metadata_for_set (GVariantBuilder *builder,
 				       MetaTree *tree,
 				       const char *path,
 				       const char *attribute,
@@ -1261,10 +1251,7 @@ _g_daemon_vfs_append_metadata_for_set (DBusMessage *message,
       if (current == NULL || strcmp (current, val) != 0)
 	{
 	  res = 1;
-	  _g_dbus_message_append_args (message,
-				       DBUS_TYPE_STRING, &key,
-				       DBUS_TYPE_STRING, &val,
-				       0);
+	  g_variant_builder_add (builder, "{sv}", key, g_variant_new_string (val));
 	}
       g_free (current);
     }
@@ -1276,10 +1263,7 @@ _g_daemon_vfs_append_metadata_for_set (DBusMessage *message,
       if (current == NULL || !strv_equal (current, val))
 	{
 	  res = 1;
-	  _g_dbus_message_append_args (message,
-				       DBUS_TYPE_STRING, &key,
-				       DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, &val, g_strv_length (val),
-				       0);
+	  g_variant_builder_add (builder, "{sv}", key, g_variant_new_strv ((const gchar * const  *) val, -1));
 	}
       g_strfreev (current);
     }
@@ -1290,10 +1274,7 @@ _g_daemon_vfs_append_metadata_for_set (DBusMessage *message,
 	  char c = 0;
 	  res = 1;
 	  /* Byte => unset */
-	  _g_dbus_message_append_args (message,
-				       DBUS_TYPE_STRING, &key,
-				       DBUS_TYPE_BYTE, &c,
-				       0);
+	  g_variant_builder_add (builder, "{sv}", key, g_variant_new_byte (c));
 	}
     }
   else
@@ -1302,6 +1283,62 @@ _g_daemon_vfs_append_metadata_for_set (DBusMessage *message,
   return res;
 }
 
+static void
+metadata_daemon_vanished (GDBusConnection *connection,
+                          const gchar *name,
+                          gpointer user_data)
+{
+  guint *watcher_id = user_data;
+
+  G_LOCK (metadata_proxy);
+  g_clear_object (&metadata_proxy);
+  G_UNLOCK (metadata_proxy);
+
+  if (*watcher_id > 0)
+    g_bus_unwatch_name (*watcher_id);
+}
+
+GVfsMetadata *
+_g_daemon_vfs_get_metadata_proxy (GCancellable *cancellable, GError **error)
+{
+  GVfsMetadata *proxy;
+  guint *watcher_id;
+
+  G_LOCK (metadata_proxy);
+
+  proxy = NULL;
+  if (metadata_proxy == NULL)
+    {
+      metadata_proxy = gvfs_metadata_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION,
+                                                             G_DBUS_PROXY_FLAGS_NONE,
+                                                             G_VFS_DBUS_METADATA_NAME,
+                                                             G_VFS_DBUS_METADATA_PATH,
+                                                             cancellable,
+                                                             error);
+
+      if (proxy != NULL)
+        {
+          /* a place in memory to store the returned ID in */
+          watcher_id = g_malloc0 (sizeof (guint));
+          *watcher_id = g_bus_watch_name_on_connection (g_dbus_proxy_get_connection (G_DBUS_PROXY (proxy)),
+                                                        G_VFS_DBUS_METADATA_NAME,
+                                                        G_BUS_NAME_WATCHER_FLAGS_AUTO_START,
+                                                        NULL,
+                                                        metadata_daemon_vanished,
+                                                        watcher_id,
+                                                        g_free);
+        }
+    }
+
+  if (metadata_proxy != NULL)
+    /* take the reference so that we don't need to protect returned object against racy metadata_daemon_vanished() */
+    proxy = g_object_ref (metadata_proxy);
+
+  G_UNLOCK (metadata_proxy);
+
+  return proxy;
+}
+
 static gboolean
 g_daemon_vfs_local_file_set_attributes (GVfs       *vfs,
 					const char *filename,
@@ -1319,10 +1356,11 @@ g_daemon_vfs_local_file_set_attributes (GVfs       *vfs,
   MetaTree *tree;
   int errsv;
   int i, num_set;
-  DBusMessage *message;
   gboolean res;
   int appended;
   gpointer value;
+  GVfsMetadata *proxy;
+  GVariantBuilder *builder;
 
   res = TRUE;
   if (g_file_info_has_namespace (info, "metadata"))
@@ -1352,65 +1390,71 @@ g_daemon_vfs_local_file_set_attributes (GVfs       *vfs,
 						statbuf.st_dev,
 						FALSE,
 						&tree_path);
-	  message =
-	    dbus_message_new_method_call (G_VFS_DBUS_METADATA_NAME,
-					  G_VFS_DBUS_METADATA_PATH,
-					  G_VFS_DBUS_METADATA_INTERFACE,
-					  G_VFS_DBUS_METADATA_OP_SET);
-	  g_assert (message != NULL);
-	  metatreefile = meta_tree_get_filename (tree);
-	  _g_dbus_message_append_args (message,
-				       G_DBUS_TYPE_CSTRING, &metatreefile,
-				       G_DBUS_TYPE_CSTRING, &tree_path,
-				       0);
-	  meta_lookup_cache_free (cache);
-
-	  num_set = 0;
-	  for (i = 0; attributes[i] != NULL; i++)
+	  
+	  proxy = _g_daemon_vfs_get_metadata_proxy (NULL, error);
+	  if (proxy == NULL)
 	    {
-	      if (g_file_info_get_attribute_data (info, attributes[i], &type, &value, NULL))
-		{
-		  appended = _g_daemon_vfs_append_metadata_for_set (message,
-								    tree,
-								    tree_path,
-								    attributes[i],
-								    type,
-								    value);
-		  if (appended != -1)
-		    {
-		      num_set += appended;
-		      g_file_info_set_attribute_status (info, attributes[i],
-							G_FILE_ATTRIBUTE_STATUS_SET);
-		    }
-		  else
-		    {
-		      res = FALSE;
-		      g_set_error (error, G_IO_ERROR,
-				   G_IO_ERROR_INVALID_ARGUMENT,
-				   _("Error setting file metadata: %s"),
-				   _("values must be string or list of strings"));
-		      error = NULL; /* Don't set further errors */
-		      g_file_info_set_attribute_status (info, attributes[i],
-							G_FILE_ATTRIBUTE_STATUS_ERROR_SETTING);
-		    }
-		}
+	      res = FALSE;
+              error = NULL; /* Don't set further errors */
 	    }
-
-	  meta_tree_unref (tree);
-	  g_free (tree_path);
-
-	  if (num_set > 0 &&
-	      !_g_daemon_vfs_send_message_sync (message,
-						cancellable, error))
+	  else
 	    {
-	      res = FALSE;
-	      error = NULL; /* Don't set further errors */
-	      for (i = 0; attributes[i] != NULL; i++)
-		g_file_info_set_attribute_status (info, attributes[i],
-						  G_FILE_ATTRIBUTE_STATUS_ERROR_SETTING);
+              builder = g_variant_builder_new (G_VARIANT_TYPE_VARDICT);
+	      metatreefile = meta_tree_get_filename (tree);
+              num_set = 0;
+
+              for (i = 0; attributes[i] != NULL; i++)
+                {
+                  if (g_file_info_get_attribute_data (info, attributes[i], &type, &value, NULL))
+                    {
+                      appended = _g_daemon_vfs_append_metadata_for_set (builder,
+                                                                        tree,
+                                                                        tree_path,
+                                                                        attributes[i],
+                                                                        type,
+                                                                        value);
+                      if (appended != -1)
+                        {
+                          num_set += appended;
+                          g_file_info_set_attribute_status (info, attributes[i],
+                                                            G_FILE_ATTRIBUTE_STATUS_SET);
+                        }
+                      else
+                        {
+                          res = FALSE;
+                          g_set_error (error, G_IO_ERROR,
+                                       G_IO_ERROR_INVALID_ARGUMENT,
+                                       _("Error setting file metadata: %s"),
+                                       _("values must be string or list of strings"));
+                          error = NULL; /* Don't set further errors */
+                          g_file_info_set_attribute_status (info, attributes[i],
+                                                            G_FILE_ATTRIBUTE_STATUS_ERROR_SETTING);
+                        }
+                    }
+                }
+	      
+	      if (num_set > 0 &&
+	          ! gvfs_metadata_call_set_sync (proxy,
+	                                         metatreefile,
+	                                         tree_path,
+	                                         g_variant_builder_end (builder),
+	                                         NULL,
+	                                         error))
+                {
+	          res = FALSE;
+                  error = NULL; /* Don't set further errors */
+                  for (i = 0; attributes[i] != NULL; i++)
+                    g_file_info_set_attribute_status (info, attributes[i],
+                                                      G_FILE_ATTRIBUTE_STATUS_ERROR_SETTING);
+                }
+
+	      g_variant_builder_unref (builder);
+	      
+              meta_lookup_cache_free (cache);
+              meta_tree_unref (tree);
+              g_free (tree_path);
+              g_object_unref (proxy);
 	    }
-
-	  dbus_message_unref (message);
 	}
 
       g_strfreev (attributes);
@@ -1424,10 +1468,10 @@ g_daemon_vfs_local_file_removed (GVfs       *vfs,
 				 const char *filename)
 {
   MetaLookupCache *cache;
-  DBusMessage *message;
   const char *metatreefile;
   MetaTree *tree;
   char *tree_path;
+  GVfsMetadata *proxy;
 
   cache = meta_lookup_cache_new ();
   tree = meta_lookup_cache_lookup_path (cache,
@@ -1437,19 +1481,23 @@ g_daemon_vfs_local_file_removed (GVfs       *vfs,
 					&tree_path);
   if (tree)
     {
-      message =
-	dbus_message_new_method_call (G_VFS_DBUS_METADATA_NAME,
-				      G_VFS_DBUS_METADATA_PATH,
-				      G_VFS_DBUS_METADATA_INTERFACE,
-				      G_VFS_DBUS_METADATA_OP_REMOVE);
-      g_assert (message != NULL);
-      metatreefile = meta_tree_get_filename (tree);
-      _g_dbus_message_append_args (message,
-				   G_DBUS_TYPE_CSTRING, &metatreefile,
-				   G_DBUS_TYPE_CSTRING, &tree_path,
-				   0);
-      send_message_oneway (message);
-      dbus_message_unref (message);
+      proxy = _g_daemon_vfs_get_metadata_proxy (NULL, NULL);
+      if (proxy)
+        {
+          metatreefile = meta_tree_get_filename (tree);
+          /* we don't care about the result, let's queue the call and don't block */
+          gvfs_metadata_call_remove (proxy,
+                                     metatreefile,
+                                     tree_path,
+                                     NULL,
+                                     NULL, /* callback */
+                                     NULL);
+          /* flush the call with the expense of sending all queued messages on the connection */
+          g_dbus_connection_flush_sync (g_dbus_proxy_get_connection (G_DBUS_PROXY (proxy)),
+                                        NULL, NULL);
+          g_object_unref (proxy);
+        }
+      
       meta_tree_unref (tree);
       g_free (tree_path);
     }
@@ -1463,10 +1511,10 @@ g_daemon_vfs_local_file_moved (GVfs       *vfs,
 			       const char *dest)
 {
   MetaLookupCache *cache;
-  DBusMessage *message;
   const char *metatreefile;
   MetaTree *tree1, *tree2;
   char *tree_path1, *tree_path2;
+  GVfsMetadata *proxy;
 
   cache = meta_lookup_cache_new ();
   tree1 = meta_lookup_cache_lookup_path (cache,
@@ -1481,20 +1529,23 @@ g_daemon_vfs_local_file_moved (GVfs       *vfs,
 					 &tree_path2);
   if (tree1 && tree2 && tree1 == tree2)
     {
-      message =
-	dbus_message_new_method_call (G_VFS_DBUS_METADATA_NAME,
-				      G_VFS_DBUS_METADATA_PATH,
-				      G_VFS_DBUS_METADATA_INTERFACE,
-				      G_VFS_DBUS_METADATA_OP_MOVE);
-      g_assert (message != NULL);
-      metatreefile = meta_tree_get_filename (tree1);
-      _g_dbus_message_append_args (message,
-				   G_DBUS_TYPE_CSTRING, &metatreefile,
-				   G_DBUS_TYPE_CSTRING, &tree_path1,
-				   G_DBUS_TYPE_CSTRING, &tree_path2,
-				   0);
-      send_message_oneway (message);
-      dbus_message_unref (message);
+      proxy = _g_daemon_vfs_get_metadata_proxy (NULL, NULL);
+      if (proxy)
+        {
+          metatreefile = meta_tree_get_filename (tree1);
+          /* we don't care about the result, let's queue the call and don't block */
+          gvfs_metadata_call_move (proxy,
+                                   metatreefile,
+                                   tree_path1,
+                                   tree_path2,
+                                   NULL,
+                                   NULL, /* callback */
+                                   NULL);
+          /* flush the call with the expense of sending all queued messages on the connection */
+          g_dbus_connection_flush_sync (g_dbus_proxy_get_connection (G_DBUS_PROXY (proxy)),
+                                        NULL, NULL);
+          g_object_unref (proxy);
+        }
     }
 
   if (tree1)
diff --git a/client/gdaemonvfs.h b/client/gdaemonvfs.h
index 16d01a7..f96ab89 100644
--- a/client/gdaemonvfs.h
+++ b/client/gdaemonvfs.h
@@ -29,6 +29,7 @@
 #include "gmounttracker.h"
 #include "gvfsuriutils.h"
 #include <metatree.h>
+#include <metadata-dbus.h>
 
 G_BEGIN_DECLS
 
@@ -71,13 +72,16 @@ DBusConnection *_g_daemon_vfs_get_async_bus            (void);
 gboolean        _g_daemon_vfs_send_message_sync        (DBusMessage              *message,
 							GCancellable             *cancellable,
 							GError                  **error);
-int             _g_daemon_vfs_append_metadata_for_set  (DBusMessage *message,
+int             _g_daemon_vfs_append_metadata_for_set  (GVariantBuilder *builder,
 							MetaTree *tree,
 							const char *path,
 							const char *attribute,
 							GFileAttributeType type,
 							gpointer   value);
 
+GVfsMetadata *  _g_daemon_vfs_get_metadata_proxy       (GCancellable             *cancellable,
+                                                        GError                  **error);
+
 
 
 G_END_DECLS
diff --git a/metadata/Makefile.am b/metadata/Makefile.am
index d3f25be..4bf2d04 100644
--- a/metadata/Makefile.am
+++ b/metadata/Makefile.am
@@ -1,5 +1,16 @@
 NULL =
 
+dbus_built_sources = metadata-dbus.c metadata-dbus.h
+BUILT_SOURCES = $(dbus_built_sources)
+
+$(dbus_built_sources) : Makefile.am dbus-interface.xml
+	gdbus-codegen						\
+		--interface-prefix org.gtk.vfs.			\
+		--c-namespace GVfs				\
+		--generate-c-code metadata-dbus			\
+		dbus-interface.xml				\
+		$(NULL)
+
 noinst_LTLIBRARIES=libmetadata.la
 
 APPS = 	\
@@ -30,6 +41,7 @@ libmetadata_la_SOURCES = 		\
 	metatree.c metatree.h		\
 	metabuilder.c metabuilder.h 	\
 	crc32.c crc32.h			\
+	$(dbus_built_sources)		\
 	$(NULL)
 
 libmetadata_la_LIBADD = $(GLIB_LIBS) $(UDEV_LIBS)
@@ -37,7 +49,7 @@ libmetadata_la_LIBADD = $(GLIB_LIBS) $(UDEV_LIBS)
 meta_ls_LDADD = libmetadata.la
 meta_ls_SOURCES = meta-ls.c
 
-meta_set_LDADD = libmetadata.la $(DBUS_LIBS) ../common/libgvfscommon.la
+meta_set_LDADD = libmetadata.la ../common/libgvfscommon.la
 meta_set_SOURCES = meta-set.c
 
 meta_get_LDADD = libmetadata.la
@@ -49,7 +61,7 @@ meta_get_tree_SOURCES = meta-get-tree.c
 convert_nautilus_metadata_LDADD = libmetadata.la $(LIBXML_LIBS)
 convert_nautilus_metadata_SOURCES = metadata-nautilus.c
 
-gvfsd_metadata_LDADD = libmetadata.la $(DBUS_LIBS) ../common/libgvfscommon.la
+gvfsd_metadata_LDADD = libmetadata.la ../common/libgvfscommon.la
 gvfsd_metadata_SOURCES = meta-daemon.c
 
 # D-BUS service file
@@ -60,7 +72,14 @@ servicedir = $(DBUS_SERVICE_DIR)
 service_in_files = gvfs-metadata.service.in
 service_DATA = gvfs-metadata.service
 
-EXTRA_DIST = gvfs-metadata.service.in
+EXTRA_DIST =				\
+	gvfs-metadata.service.in	\
+	dbus-interface.xml		\
+	$(NULL)
 
 clean-local:
 	rm -f gvfs-metadata.service
+
+CLEANFILES =				\
+	$(dbus_built_sources)		\
+	$(NULL)
diff --git a/metadata/dbus-interface.xml b/metadata/dbus-interface.xml
new file mode 100644
index 0000000..f4d8af8
--- /dev/null
+++ b/metadata/dbus-interface.xml
@@ -0,0 +1,57 @@
+<!DOCTYPE node PUBLIC
+"-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
+"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd";>
+
+<!--
+ Copyright (C) 2011 Red Hat, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General
+ Public License along with this library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ Boston, MA 02111-1307, USA.
+
+ Author: Tomas Bzatek <tbzatek redhat com>
+-->
+
+<node name="/" xmlns:doc="http://www.freedesktop.org/dbus/1.0/doc.dtd";>
+  <interface name='org.gtk.vfs.Metadata'>
+
+    <method name="Set">
+      <arg type='ay' name='treefile' direction='in'/>
+      <arg type='ay' name='path' direction='in'/>
+      <arg type='a{sv}' name='data' direction='in'/>
+    </method>
+    <method name="Unset">
+      <arg type='ay' name='treefile' direction='in'/>
+      <arg type='ay' name='path' direction='in'/>
+      <arg type='s' name='key' direction='in'/>
+    </method>
+    <method name="Get">
+      <arg type='ay' name='treefile' direction='in'/>
+      <arg type='ay' name='path' direction='in'/>
+      <arg type='as' name='keys' direction='in'/>
+      <arg type='a{sv}' name='data' direction='out'/>
+    </method>
+    <method name="Remove">
+      <arg type='ay' name='treefile' direction='in'/>
+      <arg type='ay' name='path' direction='in'/>
+    </method>
+    <method name="Move">
+      <arg type='ay' name='treefile' direction='in'/>
+      <arg type='ay' name='path' direction='in'/>
+      <arg type='ay' name='dest_path' direction='in'/>
+    </method>
+
+  </interface>
+</node>
+
diff --git a/metadata/meta-daemon.c b/metadata/meta-daemon.c
index 0e21696..9c102a5 100644
--- a/metadata/meta-daemon.c
+++ b/metadata/meta-daemon.c
@@ -27,10 +27,11 @@
 #include <glib/gstdio.h>
 #include <locale.h>
 #include <stdlib.h>
+/*  TODO: remove + remove traces in Makefile.am  */
 #include <dbus/dbus.h>
-#include "gvfsdbusutils.h"
 #include "metatree.h"
 #include "gvfsdaemonprotocol.h"
+#include "metadata-dbus.h"
 
 #define WRITEOUT_TIMEOUT_SECS 60
 
@@ -41,6 +42,7 @@ typedef struct {
 } TreeInfo;
 
 static GHashTable *tree_infos = NULL;
+static GVfsMetadata *skeleton = NULL;
 
 static void
 tree_info_free (TreeInfo *info)
@@ -109,174 +111,90 @@ tree_info_lookup (const char *filename)
 }
 
 static gboolean
-metadata_set (const char *treefile,
-	      const char *path,
-	      DBusMessageIter *iter,
-	      DBusError *derror)
+handle_set (GVfsMetadata *object,
+            GDBusMethodInvocation *invocation,
+            const gchar *arg_treefile,
+            const gchar *arg_path,
+            GVariant *arg_data,
+            GVfsMetadata *daemon)
 {
   TreeInfo *info;
-  const char *str;
-  char **strv;
-  gboolean res;
-  const char *key;
-  int n_elements;
-  char c;
+  const gchar *str;
+  const gchar **strv;
+  const gchar *key;
+  GError *error;
+  GVariantIter iter;
+  GVariant *value;
 
-  info = tree_info_lookup (treefile);
+  info = tree_info_lookup (arg_treefile);
   if (info == NULL)
     {
-      dbus_set_error (derror,
-		      DBUS_ERROR_FILE_NOT_FOUND,
-		      _("Can't find metadata file %s"),
-		      treefile);
-      return FALSE;
+      g_dbus_method_invocation_return_error (invocation,
+                                             G_IO_ERROR,
+                                             G_IO_ERROR_NOT_FOUND,
+                                             _("Can't find metadata file %s"),
+                                             arg_treefile);
+      return TRUE;
     }
 
-  res = TRUE;
-  while (dbus_message_iter_get_arg_type (iter) != 0)
-    {
-      if (!_g_dbus_message_iter_get_args (iter, derror,
-					  DBUS_TYPE_STRING, &key,
-					  0))
-	{
-	  res = FALSE;
-	  break;
-	}
+  error = NULL;
 
-      if (dbus_message_iter_get_arg_type (iter) == DBUS_TYPE_ARRAY)
+  g_variant_iter_init (&iter, arg_data);
+  while (g_variant_iter_next (&iter, "{&sv}", &key, &value))
+    {
+      if (g_variant_is_of_type (value, G_VARIANT_TYPE_STRING_ARRAY))
 	{
 	  /* stringv */
-	  if (!_g_dbus_message_iter_get_args (iter, derror,
-					      DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, &strv, &n_elements,
-					      0))
+          strv = g_variant_get_strv (value, NULL);
+	  if (!meta_tree_set_stringv (info->tree, arg_path, key, (gchar **) strv))
 	    {
-	      res = FALSE;
-	      break;
+	      g_set_error_literal (&error, G_IO_ERROR,
+                                   G_IO_ERROR_FAILED,
+                                  _("Unable to set metadata key"));
 	    }
-	  if (!meta_tree_set_stringv (info->tree, path, key, strv))
-	    {
-	      dbus_set_error (derror,
-			      DBUS_ERROR_FAILED,
-			      _("Unable to set metadata key"));
-	      res = FALSE;
-	    }
-	  g_strfreev (strv);
+	  g_free (strv);
 	}
-      else if (dbus_message_iter_get_arg_type (iter) == DBUS_TYPE_STRING)
+      else if (g_variant_is_of_type (value, G_VARIANT_TYPE_STRING))
 	{
 	  /* string */
-	  if (!_g_dbus_message_iter_get_args (iter, derror,
-					      DBUS_TYPE_STRING, &str,
-					      0))
-	    {
-	      res = FALSE;
-	      break;
-	    }
-	  if (!meta_tree_set_string (info->tree, path, key, str))
+          str = g_variant_get_string (value, NULL);
+	  if (!meta_tree_set_string (info->tree, arg_path, key, str))
 	    {
-	      dbus_set_error (derror,
-			      DBUS_ERROR_FAILED,
-			      _("Unable to set metadata key"));
-	      res = FALSE;
+              g_set_error_literal (&error, G_IO_ERROR,
+                                   G_IO_ERROR_FAILED,
+                                   _("Unable to set metadata key"));
 	    }
 	}
-      else if (dbus_message_iter_get_arg_type (iter) == DBUS_TYPE_BYTE)
+      else if (g_variant_is_of_type (value, G_VARIANT_TYPE_BYTE))
 	{
 	  /* Unset */
-	  if (!_g_dbus_message_iter_get_args (iter, derror,
-					      DBUS_TYPE_BYTE, &c,
-					      0))
+	  if (!meta_tree_unset (info->tree, arg_path, key))
 	    {
-	      res = FALSE;
-	      break;
-	    }
-	  if (!meta_tree_unset (info->tree, path, key))
-	    {
-	      dbus_set_error (derror,
-			      DBUS_ERROR_FAILED,
-			      _("Unable to unset metadata key"));
-	      res = FALSE;
+              g_set_error_literal (&error, G_IO_ERROR,
+                                   G_IO_ERROR_FAILED,
+                                   _("Unable to unset metadata key"));
 	    }
 	}
+      g_variant_unref (value);
     }
 
   tree_info_schedule_writeout (info);
 
-  return res;
-}
-
-static void
-append_string (DBusMessageIter *iter,
-	       const char *key,
-	       const char *string)
-{
-  DBusMessageIter variant_iter, struct_iter;
-
-  if (!dbus_message_iter_open_container (iter,
-					 DBUS_TYPE_STRUCT,
-					 NULL,
-					 &struct_iter))
-    _g_dbus_oom ();
-
-  if (!dbus_message_iter_append_basic (&struct_iter,
-				       DBUS_TYPE_STRING,
-				       &key))
-    _g_dbus_oom ();
-
-  if (!dbus_message_iter_open_container (&struct_iter,
-					 DBUS_TYPE_VARIANT,
-					 DBUS_TYPE_STRING_AS_STRING,
-					 &variant_iter))
-    _g_dbus_oom ();
-
-  if (!dbus_message_iter_append_basic (&variant_iter,
-				       DBUS_TYPE_STRING, &string))
-    _g_dbus_oom ();
-
-  if (!dbus_message_iter_close_container (&struct_iter, &variant_iter))
-    _g_dbus_oom ();
-
-  if (!dbus_message_iter_close_container (iter, &struct_iter))
-    _g_dbus_oom ();
-}
-
-static void
-append_stringv (DBusMessageIter *iter,
-		const char *key,
-		char **stringv)
-{
-  DBusMessageIter variant_iter, struct_iter;
-
-  if (!dbus_message_iter_open_container (iter,
-					 DBUS_TYPE_STRUCT,
-					 NULL,
-					 &struct_iter))
-    _g_dbus_oom ();
-
-  if (!dbus_message_iter_append_basic (&struct_iter,
-				       DBUS_TYPE_STRING,
-				       &key))
-    _g_dbus_oom ();
-
-  if (!dbus_message_iter_open_container (&struct_iter,
-					 DBUS_TYPE_VARIANT,
-					 DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_STRING_AS_STRING,
-					 &variant_iter))
-    _g_dbus_oom ();
-
-  _g_dbus_message_iter_append_args (&variant_iter,
-				    DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, &stringv, g_strv_length (stringv),
-				    0);
-
-  if (!dbus_message_iter_close_container (&struct_iter, &variant_iter))
-    _g_dbus_oom ();
-
-  if (!dbus_message_iter_close_container (iter, &struct_iter))
-    _g_dbus_oom ();
+  if (error)
+    {
+      g_dbus_method_invocation_return_gerror (invocation, error);
+      g_error_free (error);
+    }
+  else
+    {
+      gvfs_metadata_complete_set (object, invocation);
+    }
+  
+  return TRUE;
 }
 
 static void
-append_key (DBusMessageIter *iter,
+append_key (GVariantBuilder *builder,
 	    MetaTree *tree,
 	    const char *path,
 	    const char *key)
@@ -290,13 +208,13 @@ append_key (DBusMessageIter *iter,
   if (keytype == META_KEY_TYPE_STRING)
     {
       str = meta_tree_lookup_string (tree, path, key);
-      append_string (iter, key, str);
+      g_variant_builder_add (builder, "{sv}", key, g_variant_new_string (str));
       g_free (str);
     }
   else if (keytype == META_KEY_TYPE_STRINGV)
     {
       strv = meta_tree_lookup_stringv (tree, path, key);
-      append_stringv (iter, key, strv);
+      g_variant_builder_add (builder, "{sv}", key, g_variant_new_strv ((const gchar * const  *) strv, -1));
       g_strfreev (strv);
     }
 }
@@ -313,382 +231,217 @@ enum_keys (const char *key,
   return TRUE;
 }
 
-static DBusMessage *
-metadata_get (const char *treefile,
-	      const char *path,
-	      DBusMessage *message,
-	      DBusMessageIter *iter,
-	      DBusError *derror)
+static gboolean
+handle_get (GVfsMetadata *object,
+            GDBusMethodInvocation *invocation,
+            const gchar *arg_treefile,
+            const gchar *arg_path,
+            const gchar *const *arg_keys,
+            GVfsMetadata *daemon)
 {
   TreeInfo *info;
-  char *key;
-  DBusMessage *reply;
-  DBusMessageIter reply_iter;
-  GPtrArray *keys;
-  int i;
+  GPtrArray *meta_keys;
   gboolean free_keys;
+  gchar **iter_keys;
+  gchar **i;
+  GVariantBuilder *builder;
 
-  info = tree_info_lookup (treefile);
+  info = tree_info_lookup (arg_treefile);
   if (info == NULL)
     {
-      dbus_set_error (derror,
-		      DBUS_ERROR_FILE_NOT_FOUND,
-		      _("Can't find metadata file %s"),
-		      treefile);
-      return NULL;
+      g_dbus_method_invocation_return_error (invocation,
+                                             G_IO_ERROR,
+                                             G_IO_ERROR_NOT_FOUND,
+                                             _("Can't find metadata file %s"),
+                                             arg_treefile);
+      return TRUE;
     }
 
-  reply = dbus_message_new_method_return (message);
-  dbus_message_iter_init_append (reply, &reply_iter);
-
-  keys = g_ptr_array_new ();
-  if (dbus_message_iter_get_arg_type (iter) == 0)
+  if (arg_keys == NULL)
     {
       /* Get all keys */
       free_keys = TRUE;
-      meta_tree_enumerate_keys (info->tree, path, enum_keys, keys);
+      meta_keys = g_ptr_array_new ();
+      meta_tree_enumerate_keys (info->tree, arg_path, enum_keys, meta_keys);
+      iter_keys = (gchar **) g_ptr_array_free (meta_keys, FALSE);
     }
   else
     {
       free_keys = FALSE;
-      while (dbus_message_iter_get_arg_type (iter) != 0)
-	{
-	  if (!_g_dbus_message_iter_get_args (iter, derror,
-					      DBUS_TYPE_STRING, &key,
-					      0))
-	    break;
-
-	  g_ptr_array_add (keys, key);
-	}
+      iter_keys = (gchar **) arg_keys;
     }
 
-  for (i = 0; i < keys->len; i++)
-    {
-      key = g_ptr_array_index (keys, i);
-      append_key (&reply_iter, info->tree, path, key);
-      if (free_keys)
-	g_free (key);
-    }
-  g_ptr_array_free (keys, TRUE);
+  builder = g_variant_builder_new (G_VARIANT_TYPE_VARDICT);
+
+  for (i = iter_keys; *i; i++)
+    append_key (builder, info->tree, arg_path, *i);
+  if (free_keys)
+    g_strfreev (iter_keys);
+  
+  gvfs_metadata_complete_get (object, invocation,
+                              g_variant_builder_end (builder));
+  g_variant_builder_unref (builder);
 
-  return reply;
+  return TRUE;
 }
 
 static gboolean
-metadata_unset (const char *treefile,
-		const char *path,
-		const char *key,
-		DBusError *derror)
+handle_unset (GVfsMetadata *object,
+              GDBusMethodInvocation *invocation,
+              const gchar *arg_treefile,
+              const gchar *arg_path,
+              const gchar *arg_key,
+              GVfsMetadata *daemon)
 {
   TreeInfo *info;
 
-  info = tree_info_lookup (treefile);
+  info = tree_info_lookup (arg_treefile);
   if (info == NULL)
     {
-      dbus_set_error (derror,
-		      DBUS_ERROR_FILE_NOT_FOUND,
-		      _("Can't find metadata file %s"),
-		      treefile);
-      return FALSE;
+      g_dbus_method_invocation_return_error (invocation,
+                                             G_IO_ERROR,
+                                             G_IO_ERROR_NOT_FOUND,
+                                             _("Can't find metadata file %s"),
+                                             arg_treefile);
+      return TRUE;
     }
 
-  if (!meta_tree_unset (info->tree, path, key))
+  if (!meta_tree_unset (info->tree, arg_path, arg_key))
     {
-      dbus_set_error (derror,
-		      DBUS_ERROR_FAILED,
-		      _("Unable to unset metadata key"));
-      return FALSE;
+      g_dbus_method_invocation_return_error_literal (invocation,
+                                                     G_IO_ERROR,
+                                                     G_IO_ERROR_FAILED,
+                                                     _("Unable to unset metadata key"));
+      return TRUE;
     }
 
   tree_info_schedule_writeout (info);
+  gvfs_metadata_complete_unset (object, invocation);
+
   return TRUE;
 }
 
 static gboolean
-metadata_remove (const char *treefile,
-		 const char *path,
-		 DBusError *derror)
+handle_remove (GVfsMetadata *object,
+               GDBusMethodInvocation *invocation,
+               const gchar *arg_treefile,
+               const gchar *arg_path,
+               GVfsMetadata *daemon)
 {
   TreeInfo *info;
 
-  info = tree_info_lookup (treefile);
+  info = tree_info_lookup (arg_treefile);
   if (info == NULL)
     {
-      dbus_set_error (derror,
-		      DBUS_ERROR_FILE_NOT_FOUND,
-		      _("Can't find metadata file %s"),
-		      treefile);
-      return FALSE;
+      g_dbus_method_invocation_return_error (invocation,
+                                             G_IO_ERROR,
+                                             G_IO_ERROR_NOT_FOUND,
+                                             _("Can't find metadata file %s"),
+                                             arg_treefile);
+      return TRUE;
     }
 
-  if (!meta_tree_remove (info->tree, path))
+  if (!meta_tree_remove (info->tree, arg_path))
     {
-      dbus_set_error (derror,
-		      DBUS_ERROR_FAILED,
-		      _("Unable to remove metadata keys"));
-      return FALSE;
+      g_dbus_method_invocation_return_error_literal (invocation,
+                                                     G_IO_ERROR,
+                                                     G_IO_ERROR_FAILED,
+                                                     _("Unable to remove metadata keys"));
+      return TRUE;
     }
 
   tree_info_schedule_writeout (info);
+  gvfs_metadata_complete_remove (object, invocation);
+  
   return TRUE;
 }
 
 static gboolean
-metadata_move (const char *treefile,
-	       const char *src_path,
-	       const char *dest_path,
-	       DBusError *derror)
+handle_move (GVfsMetadata *object,
+             GDBusMethodInvocation *invocation,
+             const gchar *arg_treefile,
+             const gchar *arg_path,
+             const gchar *arg_dest_path,
+             GVfsMetadata *daemon)
 {
   TreeInfo *info;
 
-  info = tree_info_lookup (treefile);
+  info = tree_info_lookup (arg_treefile);
   if (info == NULL)
     {
-      dbus_set_error (derror,
-		      DBUS_ERROR_FILE_NOT_FOUND,
-		      _("Can't find metadata file %s"),
-		      treefile);
-      return FALSE;
+      g_dbus_method_invocation_return_error (invocation,
+                                             G_IO_ERROR,
+                                             G_IO_ERROR_NOT_FOUND,
+                                             _("Can't find metadata file %s"),
+                                             arg_treefile);
+      return TRUE;
     }
 
   /* Overwrites any dest */
-  if (!meta_tree_copy (info->tree, src_path, dest_path))
+  if (!meta_tree_copy (info->tree, arg_path, arg_dest_path))
     {
-      dbus_set_error (derror,
-		      DBUS_ERROR_FAILED,
-		      _("Unable to move metadata keys"));
-      return FALSE;
+      g_dbus_method_invocation_return_error_literal (invocation,
+                                                     G_IO_ERROR,
+                                                     G_IO_ERROR_FAILED,
+                                                     _("Unable to move metadata keys"));
+      return TRUE;
     }
 
   /* Remove source if copy succeeded (ignoring errors) */
-  meta_tree_remove (info->tree, src_path);
+  meta_tree_remove (info->tree, arg_path);
 
   tree_info_schedule_writeout (info);
+  gvfs_metadata_complete_move (object, invocation);
+  
   return TRUE;
 }
 
-static gboolean
-register_name (DBusConnection *conn,
-	       gboolean replace)
-{
-  DBusError error;
-  unsigned int flags;
-  int ret;
-
-  flags = DBUS_NAME_FLAG_ALLOW_REPLACEMENT | DBUS_NAME_FLAG_DO_NOT_QUEUE;
-  if (replace)
-    flags |= DBUS_NAME_FLAG_REPLACE_EXISTING;
-
-  dbus_error_init (&error);
-  ret = dbus_bus_request_name (conn, G_VFS_DBUS_METADATA_NAME, flags, &error);
-  if (ret == -1)
-    {
-      g_printerr ("Failed to acquire daemon name: %s", error.message);
-      dbus_error_free (&error);
-      return FALSE;
-    }
-  else if (ret == DBUS_REQUEST_NAME_REPLY_EXISTS)
-    {
-      g_printerr ("Metadata daemon already running, exiting.\n");
-      return FALSE;
-    }
-  else if (ret != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER)
-    {
-      g_printerr ("Not primary owner of the service, exiting.\n");
-      return FALSE;
-    }
-  return TRUE;
-}
-
-static DBusHandlerResult
-dbus_message_filter_func (DBusConnection *conn,
-			  DBusMessage    *message,
-			  gpointer        data)
+static void
+on_name_acquired (GDBusConnection *connection,
+                  const gchar     *name,
+                  gpointer         user_data)
 {
-  char *name;
+  GError *error;
+  
+  skeleton = gvfs_metadata_skeleton_new ();
+  
+  g_signal_connect (skeleton, "handle-set", G_CALLBACK (handle_set), skeleton);
+  g_signal_connect (skeleton, "handle-unset", G_CALLBACK (handle_unset), skeleton);
+  g_signal_connect (skeleton, "handle-get", G_CALLBACK (handle_get), skeleton);
+  g_signal_connect (skeleton, "handle-remove", G_CALLBACK (handle_remove), skeleton);
+  g_signal_connect (skeleton, "handle-move", G_CALLBACK (handle_move), skeleton);
 
-  if (dbus_message_is_signal (message, DBUS_INTERFACE_DBUS, "NameLost"))
+  error = NULL;
+  if (!g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (skeleton), connection,
+                                         G_VFS_DBUS_METADATA_PATH, &error))
     {
-      if (dbus_message_get_args (message, NULL,
-				 DBUS_TYPE_STRING, &name,
-				 DBUS_TYPE_INVALID) &&
-	  strcmp (name, G_VFS_DBUS_METADATA_NAME) == 0)
-	{
-	  /* Someone else got the name (i.e. someone used --replace), exit */
-	  exit (1);
-	}
+      g_printerr ("Error exporting volume monitor: %s (%s, %d)\n",
+                  error->message, g_quark_to_string (error->domain), error->code);
+      g_error_free (error);
     }
-
-  return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
 }
 
 static void
-metadata_unregistered (DBusConnection  *connection,
-		       void            *user_data)
+on_name_lost (GDBusConnection *connection,
+              const gchar     *name,
+              gpointer         user_data)
 {
-}
-
-static DBusHandlerResult
-metadata_message (DBusConnection  *connection,
-		  DBusMessage     *message,
-		  void            *user_data)
-{
-  DBusMessageIter iter;
-  DBusError derror;
-  DBusMessage *reply;
-  char *treefile;
-  char *path, *dest_path;
-  const char *key;
-
-  reply = NULL;
-  dbus_message_iter_init (message, &iter);
-  dbus_error_init (&derror);
-
-  if (dbus_message_is_method_call (message,
-				   G_VFS_DBUS_METADATA_INTERFACE,
-				   G_VFS_DBUS_METADATA_OP_SET))
-    {
-      treefile = NULL;
-      path = NULL;
-      if (!_g_dbus_message_iter_get_args (&iter, &derror,
-					  G_DBUS_TYPE_CSTRING, &treefile,
-					  G_DBUS_TYPE_CSTRING, &path,
-					  0) ||
-	  !metadata_set (treefile, path, &iter, &derror))
-	{
-	  reply = dbus_message_new_error (message,
-					  derror.name,
-					  derror.message);
-	  dbus_error_free (&derror);
-	}
-      else
-	reply = dbus_message_new_method_return (message);
-
-      g_free (treefile);
-      g_free (path);
-    }
-
-  else if (dbus_message_is_method_call (message,
-				   G_VFS_DBUS_METADATA_INTERFACE,
-				   G_VFS_DBUS_METADATA_OP_UNSET))
-    {
-      treefile = NULL;
-      path = NULL;
-      if (!_g_dbus_message_iter_get_args (&iter, &derror,
-					  G_DBUS_TYPE_CSTRING, &treefile,
-					  G_DBUS_TYPE_CSTRING, &path,
-					  DBUS_TYPE_STRING, &key,
-					  0) ||
-	  !metadata_unset (treefile, path, key, &derror))
-	{
-	  reply = dbus_message_new_error (message,
-					  derror.name,
-					  derror.message);
-	  dbus_error_free (&derror);
-	}
-      else
-	reply = dbus_message_new_method_return (message);
-
-      g_free (treefile);
-      g_free (path);
-    }
-
-  if (dbus_message_is_method_call (message,
-				   G_VFS_DBUS_METADATA_INTERFACE,
-				   G_VFS_DBUS_METADATA_OP_GET))
-    {
-      treefile = NULL;
-      path = NULL;
-      if (!_g_dbus_message_iter_get_args (&iter, &derror,
-					  G_DBUS_TYPE_CSTRING, &treefile,
-					  G_DBUS_TYPE_CSTRING, &path,
-					  0) ||
-	  (reply = metadata_get (treefile, path, message, &iter, &derror)) == NULL)
-	{
-	  reply = dbus_message_new_error (message,
-					  derror.name,
-					  derror.message);
-	  dbus_error_free (&derror);
-	}
-
-      g_free (treefile);
-      g_free (path);
-    }
-
-  else if (dbus_message_is_method_call (message,
-					G_VFS_DBUS_METADATA_INTERFACE,
-					G_VFS_DBUS_METADATA_OP_REMOVE))
-    {
-      treefile = NULL;
-      path = NULL;
-      if (!_g_dbus_message_iter_get_args (&iter, &derror,
-					  G_DBUS_TYPE_CSTRING, &treefile,
-					  G_DBUS_TYPE_CSTRING, &path,
-					  0) ||
-	  !metadata_remove (treefile, path, &derror))
-	{
-	  reply = dbus_message_new_error (message,
-					  derror.name,
-					  derror.message);
-	  dbus_error_free (&derror);
-	}
-      else
-	reply = dbus_message_new_method_return (message);
-
-      g_free (treefile);
-      g_free (path);
-    }
+  GMainLoop *loop = user_data;
 
-  else if (dbus_message_is_method_call (message,
-					G_VFS_DBUS_METADATA_INTERFACE,
-					G_VFS_DBUS_METADATA_OP_MOVE))
-    {
-      treefile = NULL;
-      path = NULL;
-      dest_path = NULL;
-      if (!_g_dbus_message_iter_get_args (&iter, &derror,
-					  G_DBUS_TYPE_CSTRING, &treefile,
-					  G_DBUS_TYPE_CSTRING, &path,
-					  G_DBUS_TYPE_CSTRING, &dest_path,
-					  0) ||
-	  !metadata_move (treefile, path, dest_path, &derror))
-	{
-	  reply = dbus_message_new_error (message,
-					  derror.name,
-					  derror.message);
-	  dbus_error_free (&derror);
-	}
-      else
-	reply = dbus_message_new_method_return (message);
-
-      g_free (treefile);
-      g_free (path);
-      g_free (dest_path);
-    }
-
-  if (reply)
-    {
-      dbus_connection_send (connection, reply, NULL);
-      dbus_message_unref (reply);
-      return DBUS_HANDLER_RESULT_HANDLED;
-    }
-  else
-    return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+  /* means that someone has claimed our name (we allow replacement) */
+  g_main_loop_quit (loop);
 }
 
-static struct DBusObjectPathVTable metadata_dbus_vtable = {
-  metadata_unregistered,
-  metadata_message
-};
 
 int
 main (int argc, char *argv[])
 {
   GMainLoop *loop;
-  DBusConnection *conn;
+  GDBusConnection *conn;
   gboolean replace;
   GError *error;
-  DBusError derror;
+  guint name_owner_id;
+  GBusNameOwnerFlags flags;
   GOptionContext *context;
   const GOptionEntry options[] = {
     { "replace", 'r', 0, G_OPTION_ARG_NONE, &replace,  N_("Replace old daemon."), NULL },
@@ -709,6 +462,7 @@ main (int argc, char *argv[])
   g_option_context_add_main_entries (context, options, GETTEXT_PACKAGE);
 
   replace = FALSE;
+  name_owner_id = 0;
 
   error = NULL;
   if (!g_option_context_parse (context, &argc, &argv, &error))
@@ -731,56 +485,43 @@ main (int argc, char *argv[])
 
   loop = g_main_loop_new (NULL, FALSE);
 
-  dbus_error_init (&derror);
-  conn = dbus_bus_get (DBUS_BUS_SESSION, &derror);
+  error = NULL;
+  conn = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error);
   if (!conn)
     {
-      g_printerr ("Failed to connect to the D-BUS daemon: %s\n",
-		  derror.message);
-
-      dbus_error_free (&derror);
-      return 1;
-    }
-
-  dbus_bus_add_match (conn,
-		      "type='signal',"
-		      "interface='org.freedesktop.DBus',"
-		      "member='NameOwnerChanged',"
-		      "arg0='"G_VFS_DBUS_METADATA_NAME"'",
-		      &derror);
-  if (dbus_error_is_set (&derror))
-    {
-      g_printerr ("Failed to add dbus match: %s\n", derror.message);
-      dbus_error_free (&derror);
-      return 1;
-    }
-
-  if (!dbus_connection_add_filter (conn,
-				   dbus_message_filter_func, NULL, NULL))
-    {
-      g_printerr ("Failed to add dbus filter\n");
-      return 1;
-    }
-
-  if (!dbus_connection_register_object_path (conn,
-					     G_VFS_DBUS_METADATA_PATH,
-					     &metadata_dbus_vtable, NULL))
-    {
-      g_printerr ("Failed to register object path\n");
+      g_printerr ("Failed to connect to the D-BUS daemon: %s (%s, %d)\n",
+                  error->message, g_quark_to_string (error->domain), error->code);
+      g_error_free (error);
       return 1;
     }
-
-  if (!register_name (conn, replace))
-    return 1;
-
-  _g_dbus_connection_integrate_with_main (conn);
-
+  
+  flags = G_BUS_NAME_OWNER_FLAGS_ALLOW_REPLACEMENT;
+  if (replace)
+    flags |= G_BUS_NAME_OWNER_FLAGS_REPLACE;
+
+  name_owner_id = g_bus_own_name_on_connection (conn,
+                                                G_VFS_DBUS_METADATA_NAME,
+                                                flags,
+                                                on_name_acquired,
+                                                on_name_lost,
+                                                loop,
+                                                NULL);
+  
   tree_infos = g_hash_table_new_full (g_str_hash,
 				      g_str_equal,
 				      NULL,
 				      (GDestroyNotify)tree_info_free);
 
   g_main_loop_run (loop);
+  
+  if (skeleton)
+    g_dbus_interface_skeleton_unexport (G_DBUS_INTERFACE_SKELETON (skeleton));
+  if (name_owner_id != 0)
+    g_bus_unown_name (name_owner_id);
+  if (conn)
+    g_object_unref (conn);
+  if (loop != NULL)
+    g_main_loop_unref (loop);
 
   return 0;
 }
diff --git a/metadata/meta-set.c b/metadata/meta-set.c
index 22af1fc..04a6b38 100644
--- a/metadata/meta-set.c
+++ b/metadata/meta-set.c
@@ -1,9 +1,10 @@
 #include "config.h"
 #include "metatree.h"
 #include <glib/gstdio.h>
+/*  TODO: remove + remove traces in Makefile.am  */
 #include <dbus/dbus.h>
 #include "gvfsdaemonprotocol.h"
-#include "gvfsdbusutils.h"
+#include "metadata-dbus.h"
 
 static gboolean unset = FALSE;
 static gboolean list = FALSE;
@@ -28,12 +29,12 @@ main (int argc,
   MetaLookupCache *lookup;
   struct stat statbuf;
   const char *path, *key;
-  DBusConnection *connection;
-  DBusMessage *message, *reply;
   const char *metatreefile;
-  DBusError derror;
   char *tree_path;
-
+  GVfsMetadata *proxy;
+  
+  g_type_init();
+  
   context = g_option_context_new ("<path> <key> <value> - set metadata");
   g_option_context_add_main_entries (context, entries, GETTEXT_PACKAGE);
   if (!g_option_context_parse (context, &argc, &argv, &error))
@@ -96,39 +97,42 @@ main (int argc,
 	}
     }
 
-  connection = NULL;
+  proxy = NULL;
   if (use_dbus)
     {
-      dbus_error_init (&derror);
-      connection = dbus_bus_get (DBUS_BUS_SESSION, &derror);
-      if (connection == NULL)
+      proxy = gvfs_metadata_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION,
+                                                    G_DBUS_PROXY_FLAGS_NONE,
+                                                    G_VFS_DBUS_METADATA_NAME,
+                                                    G_VFS_DBUS_METADATA_PATH,
+                                                    NULL,
+                                                    &error);
+      
+      if (proxy == NULL)
 	{
-	  g_printerr ("Unable to connect to dbus: %s\n", derror.message);
-	  dbus_error_free (&derror);
+	  g_printerr ("Unable to connect to dbus: %s (%s, %d)\n",
+                      error->message, g_quark_to_string (error->domain), error->code);
+	  g_error_free (error);
 	  return 1;
 	}
+      
+      g_dbus_proxy_set_default_timeout (G_DBUS_PROXY (proxy), 1000*30);
     }
 
   if (unset)
     {
       if (use_dbus)
 	{
-	  message =
-	    dbus_message_new_method_call (G_VFS_DBUS_METADATA_NAME,
-					  G_VFS_DBUS_METADATA_PATH,
-					  G_VFS_DBUS_METADATA_INTERFACE,
-					  G_VFS_DBUS_METADATA_OP_UNSET);
-	  metatreefile = meta_tree_get_filename (tree);
-	  _g_dbus_message_append_args (message,
-				       G_DBUS_TYPE_CSTRING, &metatreefile,
-				       G_DBUS_TYPE_CSTRING, &tree_path,
-				       DBUS_TYPE_STRING, &key,
-				       0);
-	  reply = dbus_connection_send_with_reply_and_block (connection, message, 1000*30,
-							     &derror);
-	  if (reply == NULL)
+          metatreefile = meta_tree_get_filename (tree);
+
+          if (! gvfs_metadata_call_unset_sync (proxy,
+                                               metatreefile,
+                                               tree_path,
+                                               key,
+                                               NULL,
+                                               &error))
 	    {
-	      g_printerr ("Unset error: %s\n", derror.message);
+	      g_printerr ("Unset error: %s (%s, %d)\n",
+                           error->message, g_quark_to_string (error->domain), error->code);
 	      return 1;
 	    }
 	}
@@ -146,26 +150,27 @@ main (int argc,
       if (use_dbus)
 	{
 	  char **strv;
-	  message =
-	    dbus_message_new_method_call (G_VFS_DBUS_METADATA_NAME,
-					  G_VFS_DBUS_METADATA_PATH,
-					  G_VFS_DBUS_METADATA_INTERFACE,
-					  G_VFS_DBUS_METADATA_OP_SET);
-	  metatreefile = meta_tree_get_filename (tree);
-	  strv = &argv[3];
-	  _g_dbus_message_append_args (message,
-				       G_DBUS_TYPE_CSTRING, &metatreefile,
-				       G_DBUS_TYPE_CSTRING, &tree_path,
-				       DBUS_TYPE_STRING, &key,
-				       DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, &strv, argc - 3,
-				       0);
-	  reply = dbus_connection_send_with_reply_and_block (connection, message, 1000*30,
-							     &derror);
-	  if (reply == NULL)
-	    {
-	      g_printerr ("SetStringv error: %s\n", derror.message);
-	      return 1;
-	    }
+	  GVariantBuilder *builder;
+
+          metatreefile = meta_tree_get_filename (tree);
+          strv = &argv[3];
+
+          builder = g_variant_builder_new (G_VARIANT_TYPE_VARDICT);
+          g_variant_builder_add (builder, "{sv}", key, g_variant_new_strv ((const gchar * const  *) strv, -1));
+
+          if (! gvfs_metadata_call_set_sync (proxy,
+                                             metatreefile,
+                                             tree_path,
+                                             g_variant_builder_end (builder),
+                                             NULL,
+                                             &error))
+            {
+              g_printerr ("SetStringv error: %s (%s, %d)\n",
+                           error->message, g_quark_to_string (error->domain), error->code);
+              return 1;
+            }
+          
+          g_variant_builder_unref (builder);
 	}
       else
 	{
@@ -180,25 +185,26 @@ main (int argc,
     {
       if (use_dbus)
 	{
-	  message =
-	    dbus_message_new_method_call (G_VFS_DBUS_METADATA_NAME,
-					  G_VFS_DBUS_METADATA_PATH,
-					  G_VFS_DBUS_METADATA_INTERFACE,
-					  G_VFS_DBUS_METADATA_OP_SET);
-	  metatreefile = meta_tree_get_filename (tree);
-	  _g_dbus_message_append_args (message,
-				       G_DBUS_TYPE_CSTRING, &metatreefile,
-				       G_DBUS_TYPE_CSTRING, &tree_path,
-				       DBUS_TYPE_STRING, &key,
-				       DBUS_TYPE_STRING, &argv[3],
-				       0);
-	  reply = dbus_connection_send_with_reply_and_block (connection, message, 1000*30,
-							     &derror);
-	  if (reply == NULL)
-	    {
-	      g_printerr ("SetString error: %s\n", derror.message);
-	      return 1;
-	    }
+          GVariantBuilder *builder;
+
+          metatreefile = meta_tree_get_filename (tree);
+          
+          builder = g_variant_builder_new (G_VARIANT_TYPE_VARDICT);
+          g_variant_builder_add (builder, "{sv}", key, g_variant_new_string (argv[3]));
+
+          if (! gvfs_metadata_call_set_sync (proxy,
+                                             metatreefile,
+                                             tree_path,
+                                             g_variant_builder_end (builder),
+                                             NULL,
+                                             &error))
+            {
+              g_printerr ("SetString error: %s (%s, %d)\n",
+                           error->message, g_quark_to_string (error->domain), error->code);
+              return 1;
+            }
+          
+          g_variant_builder_unref (builder);
 	}
       else
 	{
@@ -210,5 +216,8 @@ main (int argc,
 	}
     }
 
+  if (proxy)
+    g_object_unref (proxy);
+    
   return 0;
 }
diff --git a/monitor/afc/Makefile.am b/monitor/afc/Makefile.am
index e524481..0b022b2 100644
--- a/monitor/afc/Makefile.am
+++ b/monitor/afc/Makefile.am
@@ -23,7 +23,6 @@ gvfs_afc_volume_monitor_CFLAGS = \
 
 gvfs_afc_volume_monitor_LDADD = \
 	$(GLIB_LIBS) \
-	$(DBUS_LIBS) \
 	$(AFC_LIBS) \
 	$(top_builddir)/common/libgvfscommon.la \
 	$(top_builddir)/monitor/proxy/libgvfsproxyvolumemonitordaemon-noin.la \
diff --git a/monitor/gdu/Makefile.am b/monitor/gdu/Makefile.am
index 4945445..5d49cbc 100644
--- a/monitor/gdu/Makefile.am
+++ b/monitor/gdu/Makefile.am
@@ -19,7 +19,6 @@ gvfs_gdu_volume_monitor_CFLAGS =		\
 	$(GLIB_CFLAGS)                          \
 	$(GDU_CFLAGS)                           \
 	$(GUDEV_CFLAGS)                         \
-	$(DBUS_CFLAGS)                          \
 	-DGIO_MODULE_DIR=\"$(GIO_MODULE_DIR)\"	\
 	-DGVFS_LOCALEDIR=\""$(localedir)"\"	\
 	-DGDU_API_IS_SUBJECT_TO_CHANGE		\
@@ -32,7 +31,6 @@ gvfs_gdu_volume_monitor_LDADD  =		     			      	\
 	$(GLIB_LIBS)                                 			      	\
 	$(GDU_LIBS)                                  			      	\
 	$(GUDEV_LIBS)                                  			      	\
-	$(DBUS_LIBS)                                 				\
 	$(top_builddir)/common/libgvfscommon.la 			      	\
 	$(top_builddir)/monitor/proxy/libgvfsproxyvolumemonitordaemon-noin.la 	\
 	$(NULL)
diff --git a/monitor/proxy/Makefile.am b/monitor/proxy/Makefile.am
index bd3b451..1c0fc7e 100644
--- a/monitor/proxy/Makefile.am
+++ b/monitor/proxy/Makefile.am
@@ -5,6 +5,19 @@ remote_volume_monitorsdir = $(datadir)/gvfs/remote-volume-monitors
 
 module_flags = -export_dynamic -avoid-version -module -no-undefined -export-symbols-regex '^g_io_module_(load|unload|query)'
 
+dbus_built_sources = gvfsvolumemonitordbus.c gvfsvolumemonitordbus.h
+BUILT_SOURCES = $(dbus_built_sources)
+
+$(dbus_built_sources) : Makefile.am dbus-interfaces.xml
+	gdbus-codegen									\
+		--interface-prefix org.gtk.Private.					\
+		--c-namespace GVfs							\
+		--generate-c-code gvfsvolumemonitordbus					\
+		dbus-interfaces.xml							\
+		$(NULL)
+
+
+
 giomodules_LTLIBRARIES = libgioremote-volume-monitor.la
 
 libgioremote_volume_monitor_la_SOURCES =				\
@@ -15,13 +28,13 @@ libgioremote_volume_monitor_la_SOURCES =				\
 	gproxyshadowmount.c		gproxyshadowmount.h		\
 	gproxyvolumemonitor.c		gproxyvolumemonitor.h		\
 	gproxymountoperation.c		gproxymountoperation.h		\
+	$(dbus_built_sources)						\
 	$(NULL)
 
 libgioremote_volume_monitor_la_CFLAGS =					\
 	-DG_LOG_DOMAIN=\"GVFS-RemoteVolumeMonitor\"			\
 	-I$(top_srcdir)/common                  			\
 	$(GLIB_CFLAGS)                          			\
-	$(DBUS_CFLAGS)                          			\
 	-DGIO_MODULE_DIR=\"$(GIO_MODULE_DIR)\"				\
 	-DREMOTE_VOLUME_MONITORS_DIR=\"$(remote_volume_monitorsdir)\" 	\
 	-DGVFS_LOCALEDIR=\""$(localedir)"\"				\
@@ -33,7 +46,6 @@ libgioremote_volume_monitor_la_LDFLAGS = 				\
 
 libgioremote_volume_monitor_la_LIBADD  =		     		\
 	$(GLIB_LIBS)                                 			\
-	$(DBUS_LIBS)                                 			\
 	$(top_builddir)/common/libgvfscommon.la 			\
 	$(NULL)
 
@@ -43,12 +55,13 @@ noinst_LTLIBRARIES = libgvfsproxyvolumemonitordaemon-noin.la
 
 libgvfsproxyvolumemonitordaemon_noin_la_SOURCES =		\
 	gvfsproxyvolumemonitordaemon.c				\
-	gvfsproxyvolumemonitordaemon.h
+	gvfsproxyvolumemonitordaemon.h				\
+	$(dbus_built_sources)					\
+	$(NULL)
 
 libgvfsproxyvolumemonitordaemon_noin_la_CFLAGS =		\
 	-I$(top_srcdir)/common                  		\
 	$(GLIB_CFLAGS)                          		\
-	$(DBUS_CFLAGS)                          		\
 	$(GDU_CFLAGS)                           		\
 	-DG_LOG_DOMAIN=\"GVFS-RemoteVolumeMonitorDaemon\"	\
 	-DGVFS_LOCALEDIR=\""$(localedir)"\"			\
@@ -56,7 +69,6 @@ libgvfsproxyvolumemonitordaemon_noin_la_CFLAGS =		\
 
 libgvfsproxyvolumemonitordaemon_noin_la_LIBADD  =     		\
 	$(GLIB_LIBS)                                 		\
-	$(DBUS_LIBS)                                 		\
 	$(top_builddir)/common/libgvfscommon.la 		\
 	$(NULL)
 
@@ -65,3 +77,11 @@ clean-local:
 
 install-data-local:
 	mkdir -p $(DESTDIR)$(remote_volume_monitorsdir)
+
+EXTRA_DIST =							\
+	dbus-interfaces.xml					\
+	$(NULL)
+
+CLEANFILES =							\
+	$(dbus_built_sources)					\
+	$(NULL)
diff --git a/monitor/proxy/dbus-interfaces.xml b/monitor/proxy/dbus-interfaces.xml
new file mode 100644
index 0000000..49af8c7
--- /dev/null
+++ b/monitor/proxy/dbus-interfaces.xml
@@ -0,0 +1,176 @@
+<!DOCTYPE node PUBLIC
+"-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
+"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd";>
+
+<!--
+ Copyright (C) 2011 Red Hat, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General
+ Public License along with this library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ Boston, MA 02111-1307, USA.
+
+ Author: Tomas Bzatek <tbzatek redhat com>
+-->
+
+<node name="/" xmlns:doc="http://www.freedesktop.org/dbus/1.0/doc.dtd";>
+  <interface name='org.gtk.Private.RemoteVolumeMonitor'>
+
+    <!--  GIO side  -->
+    <signal name="DriveChanged">
+      <arg type='s' name='dbus_name'/>
+      <arg type='s' name='id'/>
+      <arg type='(sssbbbbbbbbuasa{ss}sa{sv})' name='drive'/>
+    </signal>
+    <signal name="DriveConnected">
+      <arg type='s' name='dbus_name'/>
+      <arg type='s' name='id'/>
+      <arg type='(sssbbbbbbbbuasa{ss}sa{sv})' name='drive'/>
+    </signal>
+    <signal name="DriveDisconnected">
+      <arg type='s' name='dbus_name'/>
+      <arg type='s' name='id'/>
+      <arg type='(sssbbbbbbbbuasa{ss}sa{sv})' name='drive'/>
+    </signal>
+    <signal name="DriveEjectButton">
+      <arg type='s' name='dbus_name'/>
+      <arg type='s' name='id'/>
+      <arg type='(sssbbbbbbbbuasa{ss}sa{sv})' name='drive'/>
+    </signal>
+    <signal name="DriveStopButton">
+      <arg type='s' name='dbus_name'/>
+      <arg type='s' name='id'/>
+      <arg type='(sssbbbbbbbbuasa{ss}sa{sv})' name='drive'/>
+    </signal>
+    <signal name="VolumeChanged">
+      <arg type='s' name='dbus_name'/>
+      <arg type='s' name='id'/>
+      <arg type='(sssssbbssa{ss}sa{sv})' name='volume'/>
+    </signal>
+    <signal name="VolumeAdded">
+      <arg type='s' name='dbus_name'/>
+      <arg type='s' name='id'/>
+      <arg type='(sssssbbssa{ss}sa{sv})' name='volume'/>
+    </signal>
+    <signal name="VolumeRemoved">
+      <arg type='s' name='dbus_name'/>
+      <arg type='s' name='id'/>
+      <arg type='(sssssbbssa{ss}sa{sv})' name='volume'/>
+    </signal>
+    <signal name="MountChanged">
+      <arg type='s' name='dbus_name'/>
+      <arg type='s' name='id'/>
+      <arg type='(sssssbsassa{sv})' name='mount'/>
+    </signal>
+    <signal name="MountAdded">
+      <arg type='s' name='dbus_name'/>
+      <arg type='s' name='id'/>
+      <arg type='(sssssbsassa{sv})' name='mount'/>
+    </signal>
+    <signal name="MountPreUnmount">
+      <arg type='s' name='dbus_name'/>
+      <arg type='s' name='id'/>
+      <arg type='(sssssbsassa{sv})' name='mount'/>
+    </signal>
+    <signal name="MountRemoved">
+      <arg type='s' name='dbus_name'/>
+      <arg type='s' name='id'/>
+      <arg type='(sssssbsassa{sv})' name='mount'/>
+    </signal>
+    <signal name="MountOpAskPassword">
+      <arg type='s' name='dbus_name'/>
+      <arg type='s' name='id'/>
+      <arg type='s' name='message_to_show'/>
+      <arg type='s' name='default_user'/>
+      <arg type='s' name='default_domain'/>
+      <arg type='u' name='flags'/>
+    </signal>
+    <signal name="MountOpAskQuestion">
+      <arg type='s' name='dbus_name'/>
+      <arg type='s' name='id'/>
+      <arg type='s' name='message_to_show'/>
+      <arg type='as' name='choices'/>
+    </signal>
+    <signal name="MountOpShowProcesses">
+      <arg type='s' name='dbus_name'/>
+      <arg type='s' name='id'/>
+      <arg type='s' name='message_to_show'/>
+      <arg type='ai' name='pid'/>
+      <arg type='as' name='choices'/>
+    </signal>
+    <signal name="MountOpAborted">
+      <arg type='s' name='dbus_name'/>
+      <arg type='s' name='id'/>
+    </signal>
+
+
+    <!--  Particular volume monitor implementations  -->
+    <method name="IsSupported">
+      <arg type='b' name='is_supported' direction='out'/>
+    </method>
+    <method name="List">
+      <arg type='a(sssbbbbbbbbuasa{ss}sa{sv})' name='drives' direction='out'/>
+      <arg type='a(sssssbbssa{ss}sa{sv})' name='volumes' direction='out'/>
+      <arg type='a(sssssbsassa{sv})' name='mounts' direction='out'/>
+    </method>
+    <method name="CancelOperation">
+      <arg type='s' name='cancellation_id' direction='in'/>
+      <arg type='b' name='was_cancelled' direction='out'/>
+    </method>
+    <method name="MountUnmount">
+      <arg type='s' name='id' direction='in'/>
+      <arg type='s' name='cancellation_id' direction='in'/>
+      <arg type='u' name='unmount_flags' direction='in'/>
+      <arg type='s' name='mount_op_id' direction='in'/>
+    </method>
+    <method name="VolumeMount">
+      <arg type='s' name='id' direction='in'/>
+      <arg type='s' name='cancellation_id' direction='in'/>
+      <arg type='u' name='mount_flags' direction='in'/>
+      <arg type='s' name='mount_op_id' direction='in'/>
+    </method>
+    <method name="DriveEject">
+      <arg type='s' name='id' direction='in'/>
+      <arg type='s' name='cancellation_id' direction='in'/>
+      <arg type='u' name='unmount_flags' direction='in'/>
+      <arg type='s' name='mount_op_id' direction='in'/>
+    </method>
+    <method name="DrivePollForMedia">
+      <arg type='s' name='id' direction='in'/>
+      <arg type='s' name='cancellation_id' direction='in'/>
+    </method>
+    <method name="DriveStart">
+      <arg type='s' name='id' direction='in'/>
+      <arg type='s' name='cancellation_id' direction='in'/>
+      <arg type='u' name='flags' direction='in'/>
+      <arg type='s' name='mount_op_id' direction='in'/>
+    </method>
+    <method name="DriveStop">
+      <arg type='s' name='id' direction='in'/>
+      <arg type='s' name='cancellation_id' direction='in'/>
+      <arg type='u' name='unmount_flags' direction='in'/>
+      <arg type='s' name='mount_op_id' direction='in'/>
+    </method>
+    <method name="MountOpReply">
+      <arg type='s' name='mount_op_id' direction='in'/>
+      <arg type='i' name='result' direction='in'/>
+      <arg type='s' name='user_name' direction='in'/>
+      <arg type='s' name='domain' direction='in'/>
+      <arg type='s' name='encoded_password' direction='in'/>
+      <arg type='i' name='password_save' direction='in'/>
+      <arg type='i' name='choice' direction='in'/>
+      <arg type='b' name='anonymous' direction='in'/>
+    </method>
+  </interface>
+</node>
+
diff --git a/monitor/proxy/gproxydrive.c b/monitor/proxy/gproxydrive.c
index be2b600..558913f 100644
--- a/monitor/proxy/gproxydrive.c
+++ b/monitor/proxy/gproxydrive.c
@@ -30,12 +30,11 @@
 #include <glib.h>
 #include <glib/gi18n-lib.h>
 
-#include <gvfsdbusutils.h>
-
 #include "gproxyvolumemonitor.h"
 #include "gproxydrive.h"
 #include "gproxyvolume.h"
 #include "gproxymountoperation.h"
+#include "gvfsvolumemonitordbus.h"
 
 /* Protects all fields of GProxyDrive that can change */
 G_LOCK_DEFINE_STATIC(proxy_drive);
@@ -139,80 +138,52 @@ g_proxy_drive_new (GProxyVolumeMonitor *volume_monitor)
  * string               sort_key
  * a{sv}                expansion
  */
-#define DRIVE_STRUCT_TYPE "(sssbbbbbbbbuasa{ss}sa{sv})"
+#define DRIVE_STRUCT_TYPE "(&s&s&sbbbbbbbbuasa{ss}&sa{sv})"
 
 void
-g_proxy_drive_update (GProxyDrive         *drive,
-                      DBusMessageIter     *iter)
+g_proxy_drive_update (GProxyDrive  *drive,
+                      GVariant     *iter)
 {
-  DBusMessageIter iter_struct;
-  DBusMessageIter iter_volume_ids_iter;
   const char *id;
   const char *name;
   const char *gicon_data;
-  dbus_bool_t can_eject;
-  dbus_bool_t can_poll_for_media;
-  dbus_bool_t has_media;
-  dbus_bool_t is_media_removable;
-  dbus_bool_t is_media_check_automatic;
-  dbus_bool_t can_start;
-  dbus_bool_t can_start_degraded;
-  dbus_bool_t can_stop;
-  dbus_uint32_t start_stop_type;
+  gboolean can_eject;
+  gboolean can_poll_for_media;
+  gboolean has_media;
+  gboolean is_media_removable;
+  gboolean is_media_check_automatic;
+  gboolean can_start;
+  gboolean can_start_degraded;
+  gboolean can_stop;
+  guint32 start_stop_type;
   GPtrArray *volume_ids;
   GHashTable *identifiers;
   const char *sort_key;
+  const gchar *volume_id;
+  GVariantIter *iter_volume_ids;
+  GVariantIter *iter_identifiers;
+  GVariantIter *iter_expansion;
 
-  dbus_message_iter_recurse (iter, &iter_struct);
-  dbus_message_iter_get_basic (&iter_struct, &id);
-  dbus_message_iter_next (&iter_struct);
-  dbus_message_iter_get_basic (&iter_struct, &name);
-  dbus_message_iter_next (&iter_struct);
-  dbus_message_iter_get_basic (&iter_struct, &gicon_data);
-  dbus_message_iter_next (&iter_struct);
-  dbus_message_iter_get_basic (&iter_struct, &can_eject);
-  dbus_message_iter_next (&iter_struct);
-  dbus_message_iter_get_basic (&iter_struct, &can_poll_for_media);
-  dbus_message_iter_next (&iter_struct);
-  dbus_message_iter_get_basic (&iter_struct, &has_media);
-  dbus_message_iter_next (&iter_struct);
-  dbus_message_iter_get_basic (&iter_struct, &is_media_removable);
-  dbus_message_iter_next (&iter_struct);
-  dbus_message_iter_get_basic (&iter_struct, &is_media_check_automatic);
-  dbus_message_iter_next (&iter_struct);
-  dbus_message_iter_get_basic (&iter_struct, &can_start);
-  dbus_message_iter_next (&iter_struct);
-  dbus_message_iter_get_basic (&iter_struct, &can_start_degraded);
-  dbus_message_iter_next (&iter_struct);
-  dbus_message_iter_get_basic (&iter_struct, &can_stop);
-  dbus_message_iter_next (&iter_struct);
-  dbus_message_iter_get_basic (&iter_struct, &start_stop_type);
-  dbus_message_iter_next (&iter_struct);
+
+  sort_key = NULL;
+  g_variant_get (iter, DRIVE_STRUCT_TYPE,
+                 &id, &name, &gicon_data,
+                 &can_eject, &can_poll_for_media,
+                 &has_media, &is_media_removable,
+                 &is_media_check_automatic,
+                 &can_start, &can_start_degraded,
+                 &can_stop, &start_stop_type,
+                 &iter_volume_ids,
+                 &iter_identifiers,
+                 &sort_key,
+                 &iter_expansion);
 
   volume_ids = g_ptr_array_new ();
-  dbus_message_iter_recurse (&iter_struct, &iter_volume_ids_iter);
-  while (dbus_message_iter_get_arg_type (&iter_volume_ids_iter) != DBUS_TYPE_INVALID)
-    {
-      const char *volume_id;
-      dbus_message_iter_get_basic (&iter_volume_ids_iter, &volume_id);
-      dbus_message_iter_next (&iter_volume_ids_iter);
-      g_ptr_array_add (volume_ids, (gpointer) volume_id);
-    }
+  while (g_variant_iter_loop (iter_volume_ids, "&s", &volume_id))
+    g_ptr_array_add (volume_ids, (gpointer) volume_id);
   g_ptr_array_add (volume_ids, NULL);
-  dbus_message_iter_next (&iter_struct);
-
-  identifiers = _get_identifiers (&iter_struct);
-  dbus_message_iter_next (&iter_struct);
-
-  /* make sure we are backwards compat with old daemon instance */
-  sort_key = NULL;
-  if (dbus_message_iter_has_next (&iter_struct))
-    {
-      dbus_message_iter_get_basic (&iter_struct, &sort_key);
-      dbus_message_iter_next (&iter_struct);
-      /* TODO: decode expansion, once used */
-    }
 
+  identifiers = _get_identifiers (iter_identifiers);
   if (drive->id != NULL && strcmp (drive->id, id) != 0)
     {
       g_warning ("id mismatch during update of drive");
@@ -255,7 +226,12 @@ g_proxy_drive_update (GProxyDrive         *drive,
   drive->volume_ids = g_strdupv ((char **) volume_ids->pdata);
   drive->sort_key = g_strdup (sort_key);
 
+  /* TODO: decode expansion, once used */
+
  out:
+  g_variant_iter_free (iter_volume_ids);
+  g_variant_iter_free (iter_identifiers);
+  g_variant_iter_free (iter_expansion);
   g_ptr_array_free (volume_ids, TRUE);
   g_hash_table_unref (identifiers);
 }
@@ -511,13 +487,20 @@ typedef struct {
 } DBusOp;
 
 static void
-cancel_operation_reply_cb (DBusMessage *reply,
-                           GError      *error,
-                           gpointer     user_data)
+cancel_operation_reply_cb (GVfsRemoteVolumeMonitor *proxy,
+                           GAsyncResult *res,
+                           gpointer user_data)
 {
-  if (error != NULL)
+  gboolean out_WasCancelled;
+  GError *error = NULL;
+  
+  if (!gvfs_remote_volume_monitor_call_cancel_operation_finish (proxy,
+                                                                &out_WasCancelled,
+                                                                res,
+                                                                &error))
     {
       g_warning ("Error from CancelOperation(): %s", error->message);
+      g_error_free (error);
     }
 }
 
@@ -527,9 +510,7 @@ operation_cancelled (GCancellable *cancellable,
 {
   DBusOp *data = user_data;
   GSimpleAsyncResult *simple;
-  DBusConnection *connection;
-  DBusMessage *message;
-  const char *name;
+  GVfsRemoteVolumeMonitor *proxy;
 
   G_LOCK (proxy_drive);
 
@@ -543,35 +524,31 @@ operation_cancelled (GCancellable *cancellable,
   g_object_unref (simple);
 
   /* Now tell the remote volume monitor that the op has been cancelled */
-  connection = g_proxy_volume_monitor_get_dbus_connection (data->drive->volume_monitor);
-  name = g_proxy_volume_monitor_get_dbus_name (data->drive->volume_monitor);
-  message = dbus_message_new_method_call (name,
-                                          "/org/gtk/Private/RemoteVolumeMonitor",
-                                          "org.gtk.Private.RemoteVolumeMonitor",
-                                          "CancelOperation");
-  dbus_message_append_args (message,
-                            DBUS_TYPE_STRING,
-                            &(data->cancellation_id),
-                            DBUS_TYPE_INVALID);
+  proxy = g_proxy_volume_monitor_get_dbus_proxy (data->drive->volume_monitor);
+  gvfs_remote_volume_monitor_call_cancel_operation (proxy,
+                                                    data->cancellation_id,
+                                                    NULL,
+                                                    (GAsyncReadyCallback) cancel_operation_reply_cb,
+                                                    NULL);
+  g_object_unref (proxy);
 
   G_UNLOCK (proxy_drive);
-
-  _g_dbus_connection_call_async (connection,
-                                 message,
-                                 -1,
-                                 (GAsyncDBusCallback) cancel_operation_reply_cb,
-                                 NULL);
-  dbus_message_unref (message);
-  dbus_connection_unref (connection);
 }
 
 /* ---------------------------------------------------------------------------------------------------- */
 
 static void
-eject_cb (DBusMessage *reply,
-          GError *error,
-          DBusOp *data)
+eject_cb (GVfsRemoteVolumeMonitor *proxy,
+          GAsyncResult *res,
+          gpointer user_data)
 {
+  DBusOp *data = user_data;
+  GError *error = NULL;
+ 
+  gvfs_remote_volume_monitor_call_drive_eject_finish (proxy, 
+                                                      res, 
+                                                      &error);
+
   if (data->cancelled_handler_id > 0)
     g_signal_handler_disconnect (data->cancellable, data->cancelled_handler_id);
 
@@ -580,15 +557,20 @@ eject_cb (DBusMessage *reply,
       GSimpleAsyncResult *simple;
 
       if (error != NULL)
-        simple = g_simple_async_result_new_from_error (G_OBJECT (data->drive),
-                                                       data->callback,
-                                                       data->user_data,
-                                                       error);
+        {
+          g_dbus_error_strip_remote_error (error);
+          simple = g_simple_async_result_new_from_error (G_OBJECT (data->drive),
+                                                         data->callback,
+                                                         data->user_data,
+                                                         error);
+        }
       else
-        simple = g_simple_async_result_new (G_OBJECT (data->drive),
-                                            data->callback,
-                                            data->user_data,
-                                            NULL);
+        {
+          simple = g_simple_async_result_new (G_OBJECT (data->drive),
+                                              data->callback,
+                                              data->user_data,
+                                              NULL);
+        }
       g_simple_async_result_complete (simple);
       g_object_unref (simple);
     }
@@ -599,6 +581,8 @@ eject_cb (DBusMessage *reply,
   if (data->cancellable != NULL)
     g_object_unref (data->cancellable);
   g_free (data);
+  if (error != NULL)
+    g_error_free (error);
 }
 
 static void
@@ -610,11 +594,8 @@ g_proxy_drive_eject_with_operation (GDrive              *drive,
                                     gpointer             user_data)
 {
   GProxyDrive *proxy_drive = G_PROXY_DRIVE (drive);
-  DBusConnection *connection;
-  const char *name;
-  DBusMessage *message;
   DBusOp *data;
-  dbus_uint32_t _flags = flags;
+  GVfsRemoteVolumeMonitor *proxy;
 
   G_LOCK (proxy_drive);
 
@@ -653,32 +634,23 @@ g_proxy_drive_eject_with_operation (GDrive              *drive,
       data->cancellation_id = g_strdup ("");
     }
 
-  connection = g_proxy_volume_monitor_get_dbus_connection (proxy_drive->volume_monitor);
-  name = g_proxy_volume_monitor_get_dbus_name (proxy_drive->volume_monitor);
-
-  message = dbus_message_new_method_call (name,
-                                          "/org/gtk/Private/RemoteVolumeMonitor",
-                                          "org.gtk.Private.RemoteVolumeMonitor",
-                                          "DriveEject");
-  dbus_message_append_args (message,
-                            DBUS_TYPE_STRING,
-                            &(proxy_drive->id),
-                            DBUS_TYPE_STRING,
-                            &(data->cancellation_id),
-                            DBUS_TYPE_UINT32,
-                            &_flags,
-                            DBUS_TYPE_STRING,
-                            &(data->mount_op_id),
-                            DBUS_TYPE_INVALID);
+  proxy = g_proxy_volume_monitor_get_dbus_proxy (data->drive->volume_monitor);
+  g_dbus_proxy_set_default_timeout (G_DBUS_PROXY (proxy), G_PROXY_VOLUME_MONITOR_DBUS_TIMEOUT);  /* 30 minute timeout */
+  
+  gvfs_remote_volume_monitor_call_drive_eject (proxy,
+                                               proxy_drive->id,
+                                               data->cancellation_id,
+                                               flags,
+                                               data->mount_op_id,
+                                               NULL,
+                                               (GAsyncReadyCallback) eject_cb,
+                                               data);
+
+  g_dbus_proxy_set_default_timeout (G_DBUS_PROXY (proxy), -1);
+  g_object_unref (proxy);
+
   G_UNLOCK (proxy_drive);
 
-  _g_dbus_connection_call_async (connection,
-                                 message,
-                                 G_PROXY_VOLUME_MONITOR_DBUS_TIMEOUT, /* 30 minute timeout */
-                                 (GAsyncDBusCallback) eject_cb,
-                                 data);
-  dbus_connection_unref (connection);
-  dbus_message_unref (message);
  out:
   ;
 }
@@ -716,10 +688,17 @@ g_proxy_drive_eject_finish (GDrive        *drive,
 /* ---------------------------------------------------------------------------------------------------- */
 
 static void
-stop_cb (DBusMessage *reply,
-          GError *error,
-          DBusOp *data)
+stop_cb (GVfsRemoteVolumeMonitor *proxy,
+         GAsyncResult *res,
+         gpointer user_data)
 {
+  DBusOp *data = user_data;
+  GError *error = NULL;
+
+  gvfs_remote_volume_monitor_call_drive_stop_finish (proxy, 
+                                                     res, 
+                                                     &error);
+
   if (data->cancelled_handler_id > 0)
     g_signal_handler_disconnect (data->cancellable, data->cancelled_handler_id);
 
@@ -728,15 +707,20 @@ stop_cb (DBusMessage *reply,
       GSimpleAsyncResult *simple;
 
       if (error != NULL)
-        simple = g_simple_async_result_new_from_error (G_OBJECT (data->drive),
-                                                       data->callback,
-                                                       data->user_data,
-                                                       error);
+        {
+          g_dbus_error_strip_remote_error (error);
+          simple = g_simple_async_result_new_from_error (G_OBJECT (data->drive),
+                                                         data->callback,
+                                                         data->user_data,
+                                                         error);
+        }
       else
-        simple = g_simple_async_result_new (G_OBJECT (data->drive),
-                                            data->callback,
-                                            data->user_data,
-                                            NULL);
+        {
+          simple = g_simple_async_result_new (G_OBJECT (data->drive),
+                                              data->callback,
+                                              data->user_data,
+                                              NULL);
+        }
       g_simple_async_result_complete (simple);
       g_object_unref (simple);
     }
@@ -747,6 +731,8 @@ stop_cb (DBusMessage *reply,
   if (data->cancellable != NULL)
     g_object_unref (data->cancellable);
   g_free (data);
+  if (error != NULL)
+    g_error_free (error);
 }
 
 static void
@@ -758,11 +744,8 @@ g_proxy_drive_stop (GDrive              *drive,
                     gpointer             user_data)
 {
   GProxyDrive *proxy_drive = G_PROXY_DRIVE (drive);
-  DBusConnection *connection;
-  const char *name;
-  DBusMessage *message;
   DBusOp *data;
-  dbus_uint32_t _flags = flags;
+  GVfsRemoteVolumeMonitor *proxy;
 
   G_LOCK (proxy_drive);
 
@@ -801,32 +784,23 @@ g_proxy_drive_stop (GDrive              *drive,
       data->cancellation_id = g_strdup ("");
     }
 
-  connection = g_proxy_volume_monitor_get_dbus_connection (proxy_drive->volume_monitor);
-  name = g_proxy_volume_monitor_get_dbus_name (proxy_drive->volume_monitor);
-
-  message = dbus_message_new_method_call (name,
-                                          "/org/gtk/Private/RemoteVolumeMonitor",
-                                          "org.gtk.Private.RemoteVolumeMonitor",
-                                          "DriveStop");
-  dbus_message_append_args (message,
-                            DBUS_TYPE_STRING,
-                            &(proxy_drive->id),
-                            DBUS_TYPE_STRING,
-                            &(data->cancellation_id),
-                            DBUS_TYPE_UINT32,
-                            &_flags,
-                            DBUS_TYPE_STRING,
-                            &(data->mount_op_id),
-                            DBUS_TYPE_INVALID);
+  proxy = g_proxy_volume_monitor_get_dbus_proxy (data->drive->volume_monitor);
+  g_dbus_proxy_set_default_timeout (G_DBUS_PROXY (proxy), G_PROXY_VOLUME_MONITOR_DBUS_TIMEOUT);  /* 30 minute timeout */
+
+  gvfs_remote_volume_monitor_call_drive_stop (proxy,
+                                              proxy_drive->id,
+                                              data->cancellation_id,
+                                              flags,
+                                              data->mount_op_id,
+                                              NULL,
+                                              (GAsyncReadyCallback) stop_cb,
+                                              data);
+  
+  g_dbus_proxy_set_default_timeout (G_DBUS_PROXY (proxy), -1);
+  g_object_unref (proxy);
+
   G_UNLOCK (proxy_drive);
 
-  _g_dbus_connection_call_async (connection,
-                                 message,
-                                 G_PROXY_VOLUME_MONITOR_DBUS_TIMEOUT, /* 30 minute timeout */
-                                 (GAsyncDBusCallback) stop_cb,
-                                 data);
-  dbus_connection_unref (connection);
-  dbus_message_unref (message);
  out:
   ;
 }
@@ -856,11 +830,18 @@ typedef struct {
 } DBusStartOp;
 
 static void
-start_cb (DBusMessage  *reply,
-          GError       *error,
-          DBusStartOp  *data)
+start_cb (GVfsRemoteVolumeMonitor *proxy,
+          GAsyncResult *res,
+          gpointer user_data)
 {
-  if (data->cancelled_handler_id > 0)
+  DBusStartOp *data = user_data;
+  GError *error = NULL;
+
+  gvfs_remote_volume_monitor_call_drive_start_finish (proxy, 
+                                                      res, 
+                                                      &error);
+
+if (data->cancelled_handler_id > 0)
     g_signal_handler_disconnect (data->cancellable, data->cancelled_handler_id);
 
   if (!g_cancellable_is_cancelled (data->cancellable))
@@ -868,15 +849,20 @@ start_cb (DBusMessage  *reply,
       GSimpleAsyncResult *simple;
 
       if (error != NULL)
-        simple = g_simple_async_result_new_from_error (G_OBJECT (data->drive),
-                                                       data->callback,
-                                                       data->user_data,
-                                                       error);
+        {
+          g_dbus_error_strip_remote_error (error);
+          simple = g_simple_async_result_new_from_error (G_OBJECT (data->drive),
+                                                         data->callback,
+                                                         data->user_data,
+                                                         error);
+        }
       else
-        simple = g_simple_async_result_new (G_OBJECT (data->drive),
-                                            data->callback,
-                                            data->user_data,
-                                            NULL);
+        {
+          simple = g_simple_async_result_new (G_OBJECT (data->drive),
+                                              data->callback,
+                                              data->user_data,
+                                              NULL);
+        }
       g_simple_async_result_complete_in_idle (simple);
       g_object_unref (simple);
     }
@@ -890,6 +876,8 @@ start_cb (DBusMessage  *reply,
     g_object_unref (data->cancellable);
 
   g_free (data);
+  if (error != NULL)
+    g_error_free (error);
 }
 
 static void
@@ -898,9 +886,7 @@ start_cancelled (GCancellable *cancellable,
 {
   DBusStartOp *data = user_data;
   GSimpleAsyncResult *simple;
-  DBusConnection *connection;
-  DBusMessage *message;
-  const char *name;
+  GVfsRemoteVolumeMonitor *proxy;
 
   G_LOCK (proxy_drive);
 
@@ -914,26 +900,15 @@ start_cancelled (GCancellable *cancellable,
   g_object_unref (simple);
 
   /* Now tell the remote drive monitor that the op has been cancelled */
-  connection = g_proxy_volume_monitor_get_dbus_connection (data->drive->volume_monitor);
-  name = g_proxy_volume_monitor_get_dbus_name (data->drive->volume_monitor);
-  message = dbus_message_new_method_call (name,
-                                          "/org/gtk/Private/RemoteVolumeMonitor",
-                                          "org.gtk.Private.RemoteVolumeMonitor",
-                                          "CancelOperation");
-  dbus_message_append_args (message,
-                            DBUS_TYPE_STRING,
-                            &(data->cancellation_id),
-                            DBUS_TYPE_INVALID);
+  proxy = g_proxy_volume_monitor_get_dbus_proxy (data->drive->volume_monitor);
+  gvfs_remote_volume_monitor_call_cancel_operation (proxy,
+                                                    data->cancellation_id,
+                                                    NULL,
+                                                    (GAsyncReadyCallback) cancel_operation_reply_cb,
+                                                    NULL);
+  g_object_unref (proxy);
 
   G_UNLOCK (proxy_drive);
-
-  _g_dbus_connection_call_async (connection,
-                                 message,
-                                 -1,
-                                 (GAsyncDBusCallback) cancel_operation_reply_cb,
-                                 NULL);
-  dbus_message_unref (message);
-  dbus_connection_unref (connection);
 }
 
 static void
@@ -946,9 +921,7 @@ g_proxy_drive_start (GDrive              *drive,
 {
   GProxyDrive *proxy_drive = G_PROXY_DRIVE (drive);
   DBusStartOp *data;
-  DBusConnection *connection;
-  const char *name;
-  DBusMessage *message;
+  GVfsRemoteVolumeMonitor *proxy;
 
   G_LOCK (proxy_drive);
 
@@ -987,33 +960,22 @@ g_proxy_drive_start (GDrive              *drive,
 
   data->mount_op_id = g_proxy_mount_operation_wrap (mount_operation, proxy_drive->volume_monitor);
 
-  connection = g_proxy_volume_monitor_get_dbus_connection (proxy_drive->volume_monitor);
-  name = g_proxy_volume_monitor_get_dbus_name (proxy_drive->volume_monitor);
-
-  message = dbus_message_new_method_call (name,
-                                          "/org/gtk/Private/RemoteVolumeMonitor",
-                                          "org.gtk.Private.RemoteVolumeMonitor",
-                                          "DriveStart");
-  dbus_message_append_args (message,
-                            DBUS_TYPE_STRING,
-                            &(proxy_drive->id),
-                            DBUS_TYPE_STRING,
-                            &(data->cancellation_id),
-                            DBUS_TYPE_UINT32,
-                            &(flags),
-                            DBUS_TYPE_STRING,
-                            &(data->mount_op_id),
-                            DBUS_TYPE_INVALID);
-  G_UNLOCK (proxy_drive);
+  proxy = g_proxy_volume_monitor_get_dbus_proxy (data->drive->volume_monitor);
+  g_dbus_proxy_set_default_timeout (G_DBUS_PROXY (proxy), G_PROXY_VOLUME_MONITOR_DBUS_TIMEOUT);  /* 30 minute timeout */
+
+  gvfs_remote_volume_monitor_call_drive_start (proxy,
+                                               proxy_drive->id,
+                                               data->cancellation_id,
+                                               flags,
+                                               data->mount_op_id,
+                                               NULL,
+                                               (GAsyncReadyCallback) start_cb,
+                                               data);
 
-  _g_dbus_connection_call_async (connection,
-                                 message,
-                                 G_PROXY_VOLUME_MONITOR_DBUS_TIMEOUT,
-                                 (GAsyncDBusCallback) start_cb,
-                                 data);
-  dbus_message_unref (message);
-  dbus_connection_unref (connection);
+  g_dbus_proxy_set_default_timeout (G_DBUS_PROXY (proxy), -1);
+  g_object_unref (proxy);
 
+  G_UNLOCK (proxy_drive);
  out:
   ;
 }
@@ -1031,24 +993,36 @@ g_proxy_drive_start_finish (GDrive        *drive,
 /* ---------------------------------------------------------------------------------------------------- */
 
 static void
-poll_for_media_cb (DBusMessage *reply,
-                   GError *error,
-                   DBusOp *data)
+poll_for_media_cb (GVfsRemoteVolumeMonitor *proxy,
+                   GAsyncResult *res,
+                   gpointer user_data)
 {
+  DBusOp *data = user_data;
+  GError *error = NULL;
+
+  gvfs_remote_volume_monitor_call_drive_poll_for_media_finish (proxy, 
+                                                               res, 
+                                                               &error);
+
   if (!g_cancellable_is_cancelled (data->cancellable))
     {
       GSimpleAsyncResult *simple;
 
       if (error != NULL)
-        simple = g_simple_async_result_new_from_error (G_OBJECT (data->drive),
-                                                       data->callback,
-                                                       data->user_data,
-                                                       error);
+        {
+          g_dbus_error_strip_remote_error (error);
+          simple = g_simple_async_result_new_from_error (G_OBJECT (data->drive),
+                                                         data->callback,
+                                                         data->user_data,
+                                                         error);
+        }
       else
-        simple = g_simple_async_result_new (G_OBJECT (data->drive),
-                                            data->callback,
-                                            data->user_data,
-                                            NULL);
+        {
+          simple = g_simple_async_result_new (G_OBJECT (data->drive),
+                                              data->callback,
+                                              data->user_data,
+                                              NULL);
+        }
       g_simple_async_result_complete (simple);
       g_object_unref (simple);
     }
@@ -1060,6 +1034,8 @@ poll_for_media_cb (DBusMessage *reply,
   if (data->cancellable != NULL)
     g_object_unref (data->cancellable);
   g_free (data);
+  if (error != NULL)
+    g_error_free (error);
 }
 
 static void
@@ -1069,10 +1045,8 @@ g_proxy_drive_poll_for_media (GDrive              *drive,
                               gpointer             user_data)
 {
   GProxyDrive *proxy_drive = G_PROXY_DRIVE (drive);
-  DBusConnection *connection;
-  const char *name;
-  DBusMessage *message;
   DBusOp *data;
+  GVfsRemoteVolumeMonitor *proxy;
 
   G_LOCK (proxy_drive);
 
@@ -1109,29 +1083,17 @@ g_proxy_drive_poll_for_media (GDrive              *drive,
     {
       data->cancellation_id = g_strdup ("");
     }
+  
+  proxy = g_proxy_volume_monitor_get_dbus_proxy (data->drive->volume_monitor);
+  gvfs_remote_volume_monitor_call_drive_poll_for_media (proxy,
+                                                        proxy_drive->id,
+                                                        data->cancellation_id,
+                                                        NULL,
+                                                        (GAsyncReadyCallback) poll_for_media_cb,
+                                                        data);
+  g_object_unref (proxy);
 
-  connection = g_proxy_volume_monitor_get_dbus_connection (proxy_drive->volume_monitor);
-  name = g_proxy_volume_monitor_get_dbus_name (proxy_drive->volume_monitor);
-
-  message = dbus_message_new_method_call (name,
-                                          "/org/gtk/Private/RemoteVolumeMonitor",
-                                          "org.gtk.Private.RemoteVolumeMonitor",
-                                          "DrivePollForMedia");
-  dbus_message_append_args (message,
-                            DBUS_TYPE_STRING,
-                            &(proxy_drive->id),
-                            DBUS_TYPE_STRING,
-                            &(data->cancellation_id),
-                            DBUS_TYPE_INVALID);
   G_UNLOCK (proxy_drive);
-
-  _g_dbus_connection_call_async (connection,
-                                 message,
-                                 -1,
-                                 (GAsyncDBusCallback) poll_for_media_cb,
-                                 data);
-  dbus_connection_unref (connection);
-  dbus_message_unref (message);
  out:
   ;
 }
diff --git a/monitor/proxy/gproxydrive.h b/monitor/proxy/gproxydrive.h
index ab26244..206ea1c 100644
--- a/monitor/proxy/gproxydrive.h
+++ b/monitor/proxy/gproxydrive.h
@@ -47,17 +47,17 @@ GType         g_proxy_drive_get_type     (void) G_GNUC_CONST;
 void          g_proxy_drive_register     (GIOModule           *module);
 GProxyDrive  *g_proxy_drive_new          (GProxyVolumeMonitor *volume_monitor);
 void          g_proxy_drive_update       (GProxyDrive         *drive,
-                                          DBusMessageIter     *iter);
+                                          GVariant            *iter);
 const char   *g_proxy_drive_get_id       (GProxyDrive         *drive);
 
-void          g_proxy_drive_handle_start_op_ask_password (GProxyDrive        *drive,
-                                                          DBusMessageIter    *iter);
+void          g_proxy_drive_handle_start_op_ask_password (GProxyDrive  *drive,
+                                                          GVariant     *iter);
 
-void          g_proxy_drive_handle_start_op_ask_question (GProxyDrive        *drive,
-                                                          DBusMessageIter    *iter);
+void          g_proxy_drive_handle_start_op_ask_question (GProxyDrive  *drive,
+                                                          GVariant     *iter);
 
-void          g_proxy_drive_handle_start_op_aborted      (GProxyDrive        *drive,
-                                                          DBusMessageIter    *iter);
+void          g_proxy_drive_handle_start_op_aborted      (GProxyDrive  *drive,
+                                                          GVariant     *iter);
 
 G_END_DECLS
 
diff --git a/monitor/proxy/gproxymount.c b/monitor/proxy/gproxymount.c
index cd3ca49..88aa955 100644
--- a/monitor/proxy/gproxymount.c
+++ b/monitor/proxy/gproxymount.c
@@ -31,8 +31,6 @@
 #include <glib/gi18n-lib.h>
 #include <gio/gio.h>
 
-#include <gvfsdbusutils.h>
-
 #include "gproxyvolumemonitor.h"
 #include "gproxymount.h"
 #include "gproxyvolume.h"
@@ -145,58 +143,38 @@ g_proxy_mount_has_mount_path (GProxyMount *mount, const char *mount_path)
  * array:string         x-content-types
  */
 
+#define MOUNT_STRUCT_TYPE "(&s&s&s&s&sb&sas&sa{sv})"
+
 void
 g_proxy_mount_update (GProxyMount         *mount,
-                      DBusMessageIter     *iter)
+                      GVariant            *iter)
 {
-  DBusMessageIter iter_struct;
-  DBusMessageIter iter_x_content_types;
   const char *id;
   const char *name;
   const char *gicon_data;
   const char *uuid;
   const char *root_uri;
-  dbus_bool_t can_unmount;
+  gboolean can_unmount;
   const char *volume_id;
   GPtrArray *x_content_types;
   const gchar *sort_key;
+  const char *x_content_type;
+  GVariantIter *iter_content_types;
+  GVariantIter *iter_expansion;
 
-  dbus_message_iter_recurse (iter, &iter_struct);
-  dbus_message_iter_get_basic (&iter_struct, &id);
-  dbus_message_iter_next (&iter_struct);
-  dbus_message_iter_get_basic (&iter_struct, &name);
-  dbus_message_iter_next (&iter_struct);
-  dbus_message_iter_get_basic (&iter_struct, &gicon_data);
-  dbus_message_iter_next (&iter_struct);
-  dbus_message_iter_get_basic (&iter_struct, &uuid);
-  dbus_message_iter_next (&iter_struct);
-  dbus_message_iter_get_basic (&iter_struct, &root_uri);
-  dbus_message_iter_next (&iter_struct);
-  dbus_message_iter_get_basic (&iter_struct, &can_unmount);
-  dbus_message_iter_next (&iter_struct);
-  dbus_message_iter_get_basic (&iter_struct, &volume_id);
-  dbus_message_iter_next (&iter_struct);
+  sort_key = NULL;
+  g_variant_get (iter, MOUNT_STRUCT_TYPE,
+                 &id, &name, &gicon_data,
+                 &uuid, &root_uri,
+                 &can_unmount, &volume_id,
+                 &iter_content_types,
+                 &sort_key,
+                 &iter_expansion);
 
   x_content_types = g_ptr_array_new ();
-  dbus_message_iter_recurse (&iter_struct, &iter_x_content_types);
-  while (dbus_message_iter_get_arg_type (&iter_x_content_types) != DBUS_TYPE_INVALID)
-    {
-      const char *x_content_type;
-      dbus_message_iter_get_basic (&iter_x_content_types, &x_content_type);
-      dbus_message_iter_next (&iter_x_content_types);
-      g_ptr_array_add (x_content_types, (gpointer) x_content_type);
-    }
+  while (g_variant_iter_loop (iter_content_types, "&s", &x_content_type))
+    g_ptr_array_add (x_content_types, (gpointer) x_content_type);
   g_ptr_array_add (x_content_types, NULL);
-  dbus_message_iter_next (&iter_struct);
-
-  /* make sure we are backwards compat with old daemon instance */
-  sort_key = NULL;
-  if (dbus_message_iter_has_next (&iter_struct))
-    {
-      dbus_message_iter_get_basic (&iter_struct, &sort_key);
-      dbus_message_iter_next (&iter_struct);
-      /* TODO: decode expansion, once used */
-    }
 
   if (mount->id != NULL && strcmp (mount->id, id) != 0)
     {
@@ -237,7 +215,11 @@ g_proxy_mount_update (GProxyMount         *mount,
   mount->x_content_types = g_strdupv ((char **) x_content_types->pdata);
   mount->sort_key = g_strdup (sort_key);
 
+  /* TODO: decode expansion, once used */
+
  out:
+  g_variant_iter_free (iter_content_types);
+  g_variant_iter_free (iter_expansion);
   g_ptr_array_free (x_content_types, TRUE);
 }
 
@@ -458,13 +440,20 @@ typedef struct {
 } DBusOp;
 
 static void
-cancel_operation_reply_cb (DBusMessage *reply,
-                           GError      *error,
-                           gpointer     user_data)
-{
-  if (error != NULL)
+cancel_operation_reply_cb (GVfsRemoteVolumeMonitor *proxy,
+                           GAsyncResult *res,
+                           gpointer user_data)
+{
+  gboolean out_WasCancelled;
+  GError *error = NULL;
+  
+  if (!gvfs_remote_volume_monitor_call_cancel_operation_finish (proxy,
+                                                                &out_WasCancelled,
+                                                                res,
+                                                                &error))
     {
       g_warning ("Error from CancelOperation(): %s", error->message);
+      g_error_free (error);
     }
 }
 
@@ -474,9 +463,7 @@ operation_cancelled (GCancellable *cancellable,
 {
   DBusOp *data = user_data;
   GSimpleAsyncResult *simple;
-  DBusConnection *connection;
-  DBusMessage *message;
-  const char *name;
+  GVfsRemoteVolumeMonitor *proxy;
 
   G_LOCK (proxy_mount);
 
@@ -490,33 +477,29 @@ operation_cancelled (GCancellable *cancellable,
   g_object_unref (simple);
 
   /* Now tell the remote volume monitor that the op has been cancelled */
-  connection = g_proxy_volume_monitor_get_dbus_connection (data->mount->volume_monitor);
-  name = g_proxy_volume_monitor_get_dbus_name (data->mount->volume_monitor);
-  message = dbus_message_new_method_call (name,
-                                          "/org/gtk/Private/RemoteVolumeMonitor",
-                                          "org.gtk.Private.RemoteVolumeMonitor",
-                                          "CancelOperation");
-  dbus_message_append_args (message,
-                            DBUS_TYPE_STRING,
-                            &(data->cancellation_id),
-                            DBUS_TYPE_INVALID);
+  proxy = g_proxy_volume_monitor_get_dbus_proxy (data->mount->volume_monitor);
+  gvfs_remote_volume_monitor_call_cancel_operation (proxy,
+                                                    data->cancellation_id,
+                                                    NULL,
+                                                    (GAsyncReadyCallback) cancel_operation_reply_cb,
+                                                    NULL);
+  g_object_unref (proxy);
 
   G_UNLOCK (proxy_mount);
-
-  _g_dbus_connection_call_async (connection,
-                                 message,
-                                 -1,
-                                 (GAsyncDBusCallback) cancel_operation_reply_cb,
-                                 NULL);
-  dbus_message_unref (message);
-  dbus_connection_unref (connection);
 }
 
 static void
-unmount_cb (DBusMessage *reply,
-            GError *error,
-            DBusOp *data)
+unmount_cb (GVfsRemoteVolumeMonitor *proxy,
+            GAsyncResult *res,
+            gpointer user_data)
 {
+  DBusOp *data = user_data;
+  GError *error = NULL;
+
+  gvfs_remote_volume_monitor_call_mount_unmount_finish (proxy, 
+                                                        res, 
+                                                        &error);
+
   if (data->cancelled_handler_id > 0)
     g_signal_handler_disconnect (data->cancellable, data->cancelled_handler_id);
 
@@ -524,15 +507,20 @@ unmount_cb (DBusMessage *reply,
     {
       GSimpleAsyncResult *simple;
       if (error != NULL)
-        simple = g_simple_async_result_new_from_error (G_OBJECT (data->mount),
-                                                       data->callback,
-                                                       data->user_data,
-                                                       error);
+        {
+          g_dbus_error_strip_remote_error (error);
+          simple = g_simple_async_result_new_from_error (G_OBJECT (data->mount),
+                                                         data->callback,
+                                                         data->user_data,
+                                                         error);
+        }
       else
-        simple = g_simple_async_result_new (G_OBJECT (data->mount),
-                                            data->callback,
-                                            data->user_data,
-                                            NULL);
+        {
+          simple = g_simple_async_result_new (G_OBJECT (data->mount),
+                                              data->callback,
+                                              data->user_data,
+                                              NULL);
+        }
       g_simple_async_result_complete (simple);
       g_object_unref (simple);
     }
@@ -543,6 +531,8 @@ unmount_cb (DBusMessage *reply,
   if (data->cancellable != NULL)
     g_object_unref (data->cancellable);
   g_free (data);
+  if (error != NULL)
+    g_error_free (error);
 }
 
 static void
@@ -554,11 +544,8 @@ g_proxy_mount_unmount_with_operation (GMount              *mount,
                                       gpointer             user_data)
 {
   GProxyMount *proxy_mount = G_PROXY_MOUNT (mount);
-  DBusConnection *connection;
-  const char *name;
-  DBusMessage *message;
   DBusOp *data;
-  dbus_uint32_t _flags = flags;
+  GVfsRemoteVolumeMonitor *proxy;
 
   G_LOCK (proxy_mount);
 
@@ -596,34 +583,23 @@ g_proxy_mount_unmount_with_operation (GMount              *mount,
     {
       data->cancellation_id = g_strdup ("");
     }
+  
+  proxy = g_proxy_volume_monitor_get_dbus_proxy (proxy_mount->volume_monitor);
+  g_dbus_proxy_set_default_timeout (G_DBUS_PROXY (proxy), G_PROXY_VOLUME_MONITOR_DBUS_TIMEOUT);  /* 30 minute timeout */
+
+  gvfs_remote_volume_monitor_call_mount_unmount (proxy,
+                                                 proxy_mount->id,
+                                                 data->cancellation_id,
+                                                 flags,
+                                                 data->mount_op_id,
+                                                 NULL,
+                                                 (GAsyncReadyCallback) unmount_cb,
+                                                 data);
+
+  g_dbus_proxy_set_default_timeout (G_DBUS_PROXY (proxy), -1);
+  g_object_unref (proxy);
 
-  connection = g_proxy_volume_monitor_get_dbus_connection (proxy_mount->volume_monitor);
-  name = g_proxy_volume_monitor_get_dbus_name (proxy_mount->volume_monitor);
-
-  message = dbus_message_new_method_call (name,
-                                          "/org/gtk/Private/RemoteVolumeMonitor",
-                                          "org.gtk.Private.RemoteVolumeMonitor",
-                                          "MountUnmount");
-  dbus_message_append_args (message,
-                            DBUS_TYPE_STRING,
-                            &(proxy_mount->id),
-                            DBUS_TYPE_STRING,
-                            &(data->cancellation_id),
-                            DBUS_TYPE_UINT32,
-                            &_flags,
-                            DBUS_TYPE_STRING,
-                            &(data->mount_op_id),
-                            DBUS_TYPE_INVALID);
   G_UNLOCK (proxy_mount);
-
-  _g_dbus_connection_call_async (connection,
-                                 message,
-                                 G_PROXY_VOLUME_MONITOR_DBUS_TIMEOUT, /* 30 minute timeout */
-                                 (GAsyncDBusCallback) unmount_cb,
-                                 data);
-
-  dbus_message_unref (message);
-  dbus_connection_unref (connection);
  out:
   ;
 }
diff --git a/monitor/proxy/gproxymount.h b/monitor/proxy/gproxymount.h
index c635651..50262fd 100644
--- a/monitor/proxy/gproxymount.h
+++ b/monitor/proxy/gproxymount.h
@@ -47,7 +47,7 @@ GType         g_proxy_mount_get_type (void) G_GNUC_CONST;
 void          g_proxy_mount_register (GIOModule           *module);
 GProxyMount  *g_proxy_mount_new      (GProxyVolumeMonitor *volume_monitor);
 void          g_proxy_mount_update   (GProxyMount         *mount,
-                                      DBusMessageIter     *iter);
+                                      GVariant            *iter);
 const char   *g_proxy_mount_get_id   (GProxyMount         *mount);
 gboolean      g_proxy_mount_has_mount_path (GProxyMount *mount, const char *mount_path);
 
diff --git a/monitor/proxy/gproxymountoperation.c b/monitor/proxy/gproxymountoperation.c
index 8826f31..5253d59 100644
--- a/monitor/proxy/gproxymountoperation.c
+++ b/monitor/proxy/gproxymountoperation.c
@@ -27,8 +27,6 @@
 #include <sys/types.h>
 #include <unistd.h>
 
-#include <gvfsdbusutils.h>
-
 #include "gproxymountoperation.h"
 
 /* for protecting the id_to_op and id_count */
@@ -109,13 +107,18 @@ g_proxy_mount_operation_wrap (GMountOperation *op,
 /* ---------------------------------------------------------------------------------------------------- */
 
 static void
-mount_op_reply_cb (DBusMessage *reply,
-                   GError      *error,
-                   gpointer     user_data)
+mount_op_reply_cb (GVfsRemoteVolumeMonitor *proxy,
+                   GAsyncResult *res,
+                   gpointer user_data)
 {
-  if (error != NULL)
+  GError *error = NULL;
+  
+  if (!gvfs_remote_volume_monitor_call_mount_op_reply_finish (proxy,
+                                                              res,
+                                                              &error))
     {
       g_warning ("Error from MountOpReply(): %s", error->message);
+      g_error_free (error);
     }
 }
 
@@ -125,20 +128,15 @@ mount_operation_reply (GMountOperation        *mount_operation,
                        gpointer               user_data)
 {
   ProxyMountOpData *data = user_data;
-  DBusConnection *connection;
-  const gchar *name;
-  DBusMessage *message;
+  GVfsRemoteVolumeMonitor *proxy;
   const gchar *user_name;
   const gchar *domain;
   const gchar *password;
   gchar *encoded_password;
-  dbus_uint32_t password_save;
-  dbus_uint32_t choice;
-  dbus_bool_t anonymous;
-
-  connection = g_proxy_volume_monitor_get_dbus_connection (data->monitor);
-  name = g_proxy_volume_monitor_get_dbus_name (data->monitor);
-
+  gint password_save;
+  gint choice;
+  gboolean anonymous;
+  
   user_name     = g_mount_operation_get_username (mount_operation);
   domain        = g_mount_operation_get_domain (mount_operation);
   password      = g_mount_operation_get_password (mount_operation);
@@ -158,79 +156,46 @@ mount_operation_reply (GMountOperation        *mount_operation,
    */
   encoded_password = g_base64_encode ((const guchar *) password, (gsize) (strlen (password) + 1));
 
-  message = dbus_message_new_method_call (name,
-                                          "/org/gtk/Private/RemoteVolumeMonitor",
-                                          "org.gtk.Private.RemoteVolumeMonitor",
-                                          "MountOpReply");
-  dbus_message_append_args (message,
-                            DBUS_TYPE_STRING,
-                            &(data->id),
-                            DBUS_TYPE_INT32,
-                            &result,
-                            DBUS_TYPE_STRING,
-                            &user_name,
-                            DBUS_TYPE_STRING,
-                            &domain,
-                            DBUS_TYPE_STRING,
-                            &encoded_password,
-                            DBUS_TYPE_INT32,
-                            &password_save,
-                            DBUS_TYPE_INT32,
-                            &choice,
-                            DBUS_TYPE_BOOLEAN,
-                            &anonymous,
-                            DBUS_TYPE_INVALID);
-
-  _g_dbus_connection_call_async (connection,
-                                 message,
-                                 -1,
-                                 (GAsyncDBusCallback) mount_op_reply_cb,
-                                 data);
-
+  proxy = g_proxy_volume_monitor_get_dbus_proxy (data->monitor);
+  gvfs_remote_volume_monitor_call_mount_op_reply (proxy,
+                                                  data->id,
+                                                  result,
+                                                  user_name,
+                                                  domain,
+                                                  encoded_password,
+                                                  password_save,
+                                                  choice,
+                                                  anonymous,
+                                                  NULL,
+                                                  (GAsyncReadyCallback) mount_op_reply_cb,
+                                                  data);
+  g_object_unref (proxy);
   g_free (encoded_password);
-  dbus_message_unref (message);
-  dbus_connection_unref (connection);
 }
 
 /* ---------------------------------------------------------------------------------------------------- */
 
 void
-g_proxy_mount_operation_handle_ask_password (const gchar      *wrapped_id,
-                                             DBusMessageIter  *iter)
+g_proxy_mount_operation_handle_ask_password (const gchar  *wrapped_id,
+                                             const gchar  *message,
+                                             const gchar  *default_user,
+                                             const gchar  *default_domain,
+                                             guint         flags)
 {
   ProxyMountOpData *data;
-  const gchar *message;
-  const gchar *default_user;
-  const gchar *default_domain;
-  dbus_int32_t flags;
 
   g_return_if_fail (wrapped_id != NULL);
-  g_return_if_fail (iter != NULL);
 
+  if (id_to_op == NULL)
+    goto out;
+  
   G_LOCK (proxy_op);
   data = g_hash_table_lookup (id_to_op, wrapped_id);
   G_UNLOCK (proxy_op);
 
   if (data == NULL)
-    {
-      g_warning ("%s: No GMountOperation for id `%s'",
-                 G_STRFUNC,
-                 wrapped_id);
-      goto out;
-    }
-
-  dbus_message_iter_get_basic (iter, &message);
-  dbus_message_iter_next (iter);
-
-  dbus_message_iter_get_basic (iter, &default_user);
-  dbus_message_iter_next (iter);
-
-  dbus_message_iter_get_basic (iter, &default_domain);
-  dbus_message_iter_next (iter);
-
-  dbus_message_iter_get_basic (iter, &flags);
-  dbus_message_iter_next (iter);
-
+    goto out;
+  
   if (data->reply_handler_id == 0)
     {
       data->reply_handler_id = g_signal_connect (data->op,
@@ -253,45 +218,23 @@ g_proxy_mount_operation_handle_ask_password (const gchar      *wrapped_id,
 /* ---------------------------------------------------------------------------------------------------- */
 
 void
-g_proxy_mount_operation_handle_ask_question (const gchar      *wrapped_id,
-                                             DBusMessageIter  *iter)
+g_proxy_mount_operation_handle_ask_question (const gchar        *wrapped_id,
+                                             const gchar        *message,
+                                             const gchar *const *choices)
 {
   ProxyMountOpData *data;
-  const gchar *message;
-  GPtrArray *choices;
-  DBusMessageIter iter_array;
 
   g_return_if_fail (wrapped_id != NULL);
-  g_return_if_fail (iter != NULL);
-
-  choices = NULL;
 
+  if (id_to_op == NULL)
+    goto out;
+  
   G_LOCK (proxy_op);
   data = g_hash_table_lookup (id_to_op, wrapped_id);
   G_UNLOCK (proxy_op);
 
   if (data == NULL)
-    {
-      g_warning ("%s: No GMountOperation for id `%s'",
-                 G_STRFUNC,
-                 wrapped_id);
-      goto out;
-    }
-
-  dbus_message_iter_get_basic (iter, &message);
-  dbus_message_iter_next (iter);
-
-  choices = g_ptr_array_new ();
-  dbus_message_iter_recurse (iter, &iter_array);
-  while (dbus_message_iter_get_arg_type (&iter_array) != DBUS_TYPE_INVALID)
-    {
-      const gchar *choice;
-      dbus_message_iter_get_basic (&iter_array, &choice);
-      dbus_message_iter_next (&iter_array);
-
-      g_ptr_array_add (choices, g_strdup (choice));
-    }
-  g_ptr_array_add (choices, NULL);
+    goto out;
 
   if (data->reply_handler_id == 0)
     {
@@ -304,70 +247,44 @@ g_proxy_mount_operation_handle_ask_question (const gchar      *wrapped_id,
   g_signal_emit_by_name (data->op,
                          "ask-question",
                          message,
-                         choices->pdata);
+                         choices);
 
  out:
-  g_ptr_array_free (choices, TRUE);
+   ;
 }
 
 /* ---------------------------------------------------------------------------------------------------- */
 
 void
-g_proxy_mount_operation_handle_show_processes (const gchar      *wrapped_id,
-                                               DBusMessageIter  *iter)
+g_proxy_mount_operation_handle_show_processes (const gchar        *wrapped_id,
+                                               const gchar        *message,
+                                               GVariant           *pids,
+                                               const gchar *const *choices)
 {
   ProxyMountOpData *data;
-  const gchar *message;
-  GPtrArray *choices;
   GArray *processes;
-  DBusMessageIter iter_array;
+  GVariantIter iter;
+  GPid pid;
 
   g_return_if_fail (wrapped_id != NULL);
-  g_return_if_fail (iter != NULL);
 
-  choices = NULL;
   processes = NULL;
 
+  if (id_to_op == NULL)
+    goto out;
+  
   G_LOCK (proxy_op);
   data = g_hash_table_lookup (id_to_op, wrapped_id);
   G_UNLOCK (proxy_op);
 
   if (data == NULL)
-    {
-      g_warning ("%s: No GMountOperation for id `%s'",
-                 G_STRFUNC,
-                 wrapped_id);
-      goto out;
-    }
-
-  dbus_message_iter_get_basic (iter, &message);
-  dbus_message_iter_next (iter);
-
+    goto out;
+  
   processes = g_array_new (FALSE, FALSE, sizeof (GPid));
-  dbus_message_iter_recurse (iter, &iter_array);
-  while (dbus_message_iter_get_arg_type (&iter_array) != DBUS_TYPE_INVALID)
-    {
-      GPid pid;
-
-      dbus_message_iter_get_basic (&iter_array, &pid);
-      dbus_message_iter_next (&iter_array);
-      g_array_append_val (processes, pid);
-    }
-
-  dbus_message_iter_next (iter);
-
-  choices = g_ptr_array_new ();
-  dbus_message_iter_recurse (iter, &iter_array);
-  while (dbus_message_iter_get_arg_type (&iter_array) != DBUS_TYPE_INVALID)
-    {
-      const gchar *choice;
-      dbus_message_iter_get_basic (&iter_array, &choice);
-      dbus_message_iter_next (&iter_array);
-
-      g_ptr_array_add (choices, g_strdup (choice));
-    }
-  g_ptr_array_add (choices, NULL);
-
+  g_variant_iter_init (&iter, pids);
+  while (g_variant_iter_loop (&iter, "i", &pid))
+    g_array_append_val (processes, pid);
+ 
   if (data->reply_handler_id == 0)
     {
       data->reply_handler_id = g_signal_connect (data->op,
@@ -380,11 +297,9 @@ g_proxy_mount_operation_handle_show_processes (const gchar      *wrapped_id,
                          "show-processes",
                          message,
                          processes,
-                         choices->pdata);
+                         choices);
 
  out:
-  if (choices)
-    g_ptr_array_free (choices, TRUE);
   if (processes)
     g_array_unref (processes);
 }
@@ -392,25 +307,21 @@ g_proxy_mount_operation_handle_show_processes (const gchar      *wrapped_id,
 /* ---------------------------------------------------------------------------------------------------- */
 
 void
-g_proxy_mount_operation_handle_aborted (const gchar      *wrapped_id,
-                                        DBusMessageIter  *iter)
+g_proxy_mount_operation_handle_aborted (const gchar *wrapped_id)
 {
   ProxyMountOpData *data;
 
   g_return_if_fail (wrapped_id != NULL);
-  g_return_if_fail (iter != NULL);
+
+  if (id_to_op == NULL)
+    goto out;
 
   G_LOCK (proxy_op);
   data = g_hash_table_lookup (id_to_op, wrapped_id);
   G_UNLOCK (proxy_op);
 
   if (data == NULL)
-    {
-      g_warning ("%s: No GMountOperation for id `%s'",
-                 G_STRFUNC,
-                 wrapped_id);
-      goto out;
-    }
+    goto out;
 
   g_signal_emit_by_name (data->op, "aborted");
 
@@ -428,13 +339,11 @@ g_proxy_mount_operation_destroy (const gchar *wrapped_id)
   if (strlen (wrapped_id) == 0)
     return;
 
+  if (id_to_op == NULL)
+    return;
+
   G_LOCK (proxy_op);
-  if (!g_hash_table_remove (id_to_op, wrapped_id))
-    {
-      g_warning ("%s: No GMountOperation for id `%s'",
-                 G_STRFUNC,
-                 wrapped_id);
-    }
+  g_hash_table_remove (id_to_op, wrapped_id);
   G_UNLOCK (proxy_op);
 }
 
diff --git a/monitor/proxy/gproxymountoperation.h b/monitor/proxy/gproxymountoperation.h
index a57b50e..a7d51b8 100644
--- a/monitor/proxy/gproxymountoperation.h
+++ b/monitor/proxy/gproxymountoperation.h
@@ -34,17 +34,22 @@ G_BEGIN_DECLS
 const gchar *g_proxy_mount_operation_wrap                (GMountOperation     *op,
                                                           GProxyVolumeMonitor *monitor);
 
-void  g_proxy_mount_operation_handle_ask_password   (const gchar      *wrapped_id,
-                                                     DBusMessageIter  *iter);
-
-void  g_proxy_mount_operation_handle_ask_question   (const gchar      *wrapped_id,
-                                                     DBusMessageIter  *iter);
-
-void  g_proxy_mount_operation_handle_show_processes (const gchar      *wrapped_id,
-                                                     DBusMessageIter  *iter);
-
-void  g_proxy_mount_operation_handle_aborted        (const gchar      *wrapped_id,
-                                                     DBusMessageIter  *iter);
+void  g_proxy_mount_operation_handle_ask_password   (const gchar        *wrapped_id,
+                                                     const gchar        *message,
+                                                     const gchar        *default_user,
+                                                     const gchar        *default_domain,
+                                                     guint              flags);
+
+void  g_proxy_mount_operation_handle_ask_question   (const gchar        *wrapped_id,
+                                                     const gchar        *message,
+                                                     const gchar *const *choices);
+
+void  g_proxy_mount_operation_handle_show_processes (const gchar        *wrapped_id,
+                                                     const gchar        *message,
+                                                     GVariant           *pids,
+                                                     const gchar *const *choices);
+
+void  g_proxy_mount_operation_handle_aborted        (const gchar      *wrapped_id);
 
 void  g_proxy_mount_operation_destroy               (const gchar      *wrapped_id);
 
diff --git a/monitor/proxy/gproxyshadowmount.c b/monitor/proxy/gproxyshadowmount.c
index b83d2f1..02ebe87 100644
--- a/monitor/proxy/gproxyshadowmount.c
+++ b/monitor/proxy/gproxyshadowmount.c
@@ -31,8 +31,6 @@
 #include <glib/gi18n-lib.h>
 #include <gio/gio.h>
 
-#include <gvfsdbusutils.h>
-
 #include "gproxyvolumemonitor.h"
 #include "gproxyshadowmount.h"
 #include "gproxyvolume.h"
diff --git a/monitor/proxy/gproxyvolume.c b/monitor/proxy/gproxyvolume.c
index b6b8c91..6f600ab 100644
--- a/monitor/proxy/gproxyvolume.c
+++ b/monitor/proxy/gproxyvolume.c
@@ -31,8 +31,6 @@
 #include <glib/gi18n-lib.h>
 #include <gio/gio.h>
 
-#include <gvfsdbusutils.h>
-
 #include "gproxydrive.h"
 #include "gproxyvolume.h"
 #include "gproxymount.h"
@@ -193,7 +191,6 @@ g_proxy_volume_new (GProxyVolumeMonitor *volume_monitor)
   return volume;
 }
 
-
 static void
 union_monitor_mount_added (GVolumeMonitor *union_monitor,
                            GMount         *mount,
@@ -356,10 +353,11 @@ update_shadow_mount_in_idle (GProxyVolume *volume)
  * a{sv}                expansion
  */
 
+#define VOLUME_STRUCT_TYPE "(&s&s&s&s&sbb&s&sa{ss}&sa{sv})"
+
 void g_proxy_volume_update (GProxyVolume    *volume,
-                            DBusMessageIter *iter)
+                            GVariant        *iter)
 {
-  DBusMessageIter iter_struct;
   const char *id;
   const char *name;
   const char *gicon_data;
@@ -367,42 +365,24 @@ void g_proxy_volume_update (GProxyVolume    *volume,
   const char *activation_uri;
   const char *drive_id;
   const char *mount_id;
-  dbus_bool_t can_mount;
-  dbus_bool_t should_automount;
+  gboolean can_mount;
+  gboolean should_automount;
   GHashTable *identifiers;
   const gchar *sort_key;
+  GVariantIter *iter_identifiers;
+  GVariantIter *iter_expansion;
 
-  dbus_message_iter_recurse (iter, &iter_struct);
-  dbus_message_iter_get_basic (&iter_struct, &id);
-  dbus_message_iter_next (&iter_struct);
-  dbus_message_iter_get_basic (&iter_struct, &name);
-  dbus_message_iter_next (&iter_struct);
-  dbus_message_iter_get_basic (&iter_struct, &gicon_data);
-  dbus_message_iter_next (&iter_struct);
-  dbus_message_iter_get_basic (&iter_struct, &uuid);
-  dbus_message_iter_next (&iter_struct);
-  dbus_message_iter_get_basic (&iter_struct, &activation_uri);
-  dbus_message_iter_next (&iter_struct);
-  dbus_message_iter_get_basic (&iter_struct, &can_mount);
-  dbus_message_iter_next (&iter_struct);
-  dbus_message_iter_get_basic (&iter_struct, &should_automount);
-  dbus_message_iter_next (&iter_struct);
-  dbus_message_iter_get_basic (&iter_struct, &drive_id);
-  dbus_message_iter_next (&iter_struct);
-  dbus_message_iter_get_basic (&iter_struct, &mount_id);
-  dbus_message_iter_next (&iter_struct);
-
-  identifiers = _get_identifiers (&iter_struct);
-  dbus_message_iter_next (&iter_struct);
-
-  /* make sure we are backwards compat with old daemon instance */
   sort_key = NULL;
-  if (dbus_message_iter_has_next (&iter_struct))
-    {
-      dbus_message_iter_get_basic (&iter_struct, &sort_key);
-      dbus_message_iter_next (&iter_struct);
-      /* TODO: decode expansion, once used */
-    }
+  g_variant_get (iter, VOLUME_STRUCT_TYPE,
+                 &id, &name, &gicon_data, 
+                 &uuid, &activation_uri, 
+                 &can_mount, &should_automount, 
+                 &drive_id, &mount_id, 
+                 &iter_identifiers,
+                 &sort_key,
+                 &iter_expansion);
+
+  identifiers = _get_identifiers (iter_identifiers);
 
   if (volume->id != NULL && strcmp (volume->id, id) != 0)
     {
@@ -448,10 +428,14 @@ void g_proxy_volume_update (GProxyVolume    *volume,
   volume->identifiers = identifiers != NULL ? g_hash_table_ref (identifiers) : NULL;
   volume->sort_key = g_strdup (sort_key);
 
+  /* TODO: decode expansion, once used */
+
   /* this calls into the union monitor; do it in idle to avoid locking issues */
   update_shadow_mount_in_idle (volume);
 
  out:
+  g_variant_iter_free (iter_identifiers);
+  g_variant_iter_free (iter_expansion);
   g_hash_table_unref (identifiers);
 }
 
@@ -741,10 +725,17 @@ typedef struct {
 } DBusOp;
 
 static void
-mount_cb (DBusMessage *reply,
-          GError      *error,
-          DBusOp      *data)
+mount_cb (GVfsRemoteVolumeMonitor *proxy,
+          GAsyncResult *res,
+          gpointer user_data)
 {
+  DBusOp *data = user_data;
+  GError *error = NULL;
+ 
+  gvfs_remote_volume_monitor_call_volume_mount_finish (proxy, 
+                                                       res, 
+                                                       &error);
+  
   if (data->cancelled_handler_id > 0)
     g_signal_handler_disconnect (data->cancellable, data->cancelled_handler_id);
 
@@ -753,15 +744,20 @@ mount_cb (DBusMessage *reply,
       GSimpleAsyncResult *simple;
 
       if (error != NULL)
-        simple = g_simple_async_result_new_from_error (G_OBJECT (data->volume),
-                                                       data->callback,
-                                                       data->user_data,
-                                                       error);
+        {
+          g_dbus_error_strip_remote_error (error);
+          simple = g_simple_async_result_new_from_error (G_OBJECT (data->volume),
+                                                         data->callback,
+                                                         data->user_data,
+                                                         error);
+        }
       else
-        simple = g_simple_async_result_new (G_OBJECT (data->volume),
-                                            data->callback,
-                                            data->user_data,
-                                            NULL);
+        {
+          simple = g_simple_async_result_new (G_OBJECT (data->volume),
+                                              data->callback,
+                                              data->user_data,
+                                              NULL);
+        }
       g_simple_async_result_complete_in_idle (simple);
       g_object_unref (simple);
     }
@@ -775,6 +771,8 @@ mount_cb (DBusMessage *reply,
     g_object_unref (data->cancellable);
 
   g_free (data);
+  if (error != NULL)
+    g_error_free (error);
 }
 
 typedef struct
@@ -796,13 +794,20 @@ mount_foreign_callback (GObject *source_object,
 }
 
 static void
-cancel_operation_reply_cb (DBusMessage *reply,
-                           GError      *error,
-                           gpointer     user_data)
+cancel_operation_reply_cb (GVfsRemoteVolumeMonitor *proxy,
+                           GAsyncResult *res,
+                           gpointer user_data)
 {
-  if (error != NULL)
+  gboolean out_WasCancelled;
+  GError *error = NULL;
+  
+  if (!gvfs_remote_volume_monitor_call_cancel_operation_finish (proxy,
+                                                                &out_WasCancelled,
+                                                                res,
+                                                                &error))
     {
       g_warning ("Error from CancelOperation(): %s", error->message);
+      g_error_free (error);
     }
 }
 
@@ -812,9 +817,7 @@ mount_cancelled (GCancellable *cancellable,
 {
   DBusOp *data = user_data;
   GSimpleAsyncResult *simple;
-  DBusConnection *connection;
-  DBusMessage *message;
-  const char *name;
+  GVfsRemoteVolumeMonitor *proxy;
 
   G_LOCK (proxy_volume);
 
@@ -828,26 +831,15 @@ mount_cancelled (GCancellable *cancellable,
   g_object_unref (simple);
 
   /* Now tell the remote volume monitor that the op has been cancelled */
-  connection = g_proxy_volume_monitor_get_dbus_connection (data->volume->volume_monitor);
-  name = g_proxy_volume_monitor_get_dbus_name (data->volume->volume_monitor);
-  message = dbus_message_new_method_call (name,
-                                          "/org/gtk/Private/RemoteVolumeMonitor",
-                                          "org.gtk.Private.RemoteVolumeMonitor",
-                                          "CancelOperation");
-  dbus_message_append_args (message,
-                            DBUS_TYPE_STRING,
-                            &(data->cancellation_id),
-                            DBUS_TYPE_INVALID);
+  proxy = g_proxy_volume_monitor_get_dbus_proxy (data->volume->volume_monitor);
+  gvfs_remote_volume_monitor_call_cancel_operation (proxy,
+                                                    data->cancellation_id,
+                                                    NULL,
+                                                    (GAsyncReadyCallback) cancel_operation_reply_cb,
+                                                    NULL);
+  g_object_unref (proxy);
 
   G_UNLOCK (proxy_volume);
-
-  _g_dbus_connection_call_async (connection,
-                                 message,
-                                 -1,
-                                 (GAsyncDBusCallback) cancel_operation_reply_cb,
-                                 NULL);
-  dbus_message_unref (message);
-  dbus_connection_unref (connection);
 }
 
 static void
@@ -887,10 +879,7 @@ g_proxy_volume_mount (GVolume             *volume,
   else
     {
       DBusOp *data;
-      DBusConnection *connection;
-      const char *name;
-      DBusMessage *message;
-      dbus_uint32_t _flags = flags;
+      GVfsRemoteVolumeMonitor *proxy;
 
       if (g_cancellable_is_cancelled (cancellable))
         {
@@ -927,32 +916,22 @@ g_proxy_volume_mount (GVolume             *volume,
 
       data->mount_op_id = g_proxy_mount_operation_wrap (mount_operation, proxy_volume->volume_monitor);
 
-      connection = g_proxy_volume_monitor_get_dbus_connection (proxy_volume->volume_monitor);
-      name = g_proxy_volume_monitor_get_dbus_name (proxy_volume->volume_monitor);
-
-      message = dbus_message_new_method_call (name,
-                                              "/org/gtk/Private/RemoteVolumeMonitor",
-                                              "org.gtk.Private.RemoteVolumeMonitor",
-                                              "VolumeMount");
-      dbus_message_append_args (message,
-                                DBUS_TYPE_STRING,
-                                &(proxy_volume->id),
-                                DBUS_TYPE_STRING,
-                                &(data->cancellation_id),
-                                DBUS_TYPE_UINT32,
-                                &_flags,
-                                DBUS_TYPE_STRING,
-                                &(data->mount_op_id),
-                                DBUS_TYPE_INVALID);
-      G_UNLOCK (proxy_volume);
+      proxy = g_proxy_volume_monitor_get_dbus_proxy (proxy_volume->volume_monitor);
+      g_dbus_proxy_set_default_timeout (G_DBUS_PROXY (proxy), G_PROXY_VOLUME_MONITOR_DBUS_TIMEOUT);  /* 30 minute timeout */
 
-      _g_dbus_connection_call_async (connection,
-                                     message,
-                                     G_PROXY_VOLUME_MONITOR_DBUS_TIMEOUT, /* 30 minute timeout */
-                                     (GAsyncDBusCallback) mount_cb,
-                                     data);
-      dbus_message_unref (message);
-      dbus_connection_unref (connection);
+      gvfs_remote_volume_monitor_call_volume_mount (proxy,
+                                                    proxy_volume->id,
+                                                    data->cancellation_id,
+                                                    flags,
+                                                    data->mount_op_id,
+                                                    NULL,
+                                                    (GAsyncReadyCallback) mount_cb,
+                                                    data);
+
+      g_dbus_proxy_set_default_timeout (G_DBUS_PROXY (proxy), -1);
+      g_object_unref (proxy);
+
+      G_UNLOCK (proxy_volume);
     }
 
  out:
diff --git a/monitor/proxy/gproxyvolume.h b/monitor/proxy/gproxyvolume.h
index 953b800..0c6a2c4 100644
--- a/monitor/proxy/gproxyvolume.h
+++ b/monitor/proxy/gproxyvolume.h
@@ -47,7 +47,7 @@ struct _GProxyVolumeClass {
 GType         g_proxy_volume_get_type            (void) G_GNUC_CONST;
 GProxyVolume *g_proxy_volume_new                 (GProxyVolumeMonitor *volume_monitor);
 void          g_proxy_volume_update              (GProxyVolume        *volume,
-                                                  DBusMessageIter     *iter);
+                                                  GVariant            *iter);
 const char   *g_proxy_volume_get_id              (GProxyVolume        *volume);
 void          g_proxy_volume_register            (GIOModule           *module);
 
diff --git a/monitor/proxy/gproxyvolumemonitor.c b/monitor/proxy/gproxyvolumemonitor.c
index 2c974d1..6aab4dc 100644
--- a/monitor/proxy/gproxyvolumemonitor.c
+++ b/monitor/proxy/gproxyvolumemonitor.c
@@ -35,30 +35,30 @@
 #include <glib.h>
 #include <glib/gi18n-lib.h>
 #include <gio/gio.h>
-#include <gvfsdbusutils.h>
 
 #include "gproxyvolumemonitor.h"
 #include "gproxymount.h"
 #include "gproxyvolume.h"
 #include "gproxydrive.h"
 #include "gproxymountoperation.h"
+#include "gvfsvolumemonitordbus.h"
 
 G_LOCK_DEFINE_STATIC(proxy_vm);
 
-static DBusConnection *the_session_bus = NULL;
-static gboolean the_session_bus_is_integrated = FALSE;
+static GDBusConnection *the_session_bus = NULL;
 static GHashTable *the_volume_monitors = NULL;
 
 struct _GProxyVolumeMonitor {
   GNativeVolumeMonitor parent;
-  DBusConnection *session_bus;
+  
+  guint name_owner_id;
+  GVfsRemoteVolumeMonitor *proxy;
 
   GHashTable *drives;
   GHashTable *volumes;
   GHashTable *mounts;
 
-  /* The unique D-Bus name of the remote monitor or NULL if disconnected */
-  gchar *unique_name;
+  gulong name_watcher_id;
 };
 
 G_DEFINE_DYNAMIC_TYPE_EXTENDED (GProxyVolumeMonitor,
@@ -67,9 +67,9 @@ G_DEFINE_DYNAMIC_TYPE_EXTENDED (GProxyVolumeMonitor,
                                 G_TYPE_FLAG_ABSTRACT,
                                 {})
 
-static void seed_monitor (GProxyVolumeMonitor  *monitor);
+static gboolean g_proxy_volume_monitor_setup_session_bus_connection (void);
 
-static DBusHandlerResult filter_function (DBusConnection *connection, DBusMessage *message, void *user_data);
+static void seed_monitor (GProxyVolumeMonitor  *monitor);
 
 static void signal_emit_in_idle (gpointer object, const char *signal_name, gpointer other_object);
 
@@ -99,25 +99,6 @@ static is_supported_func is_supported_funcs[] = {
   NULL
 };
 
-static char *
-get_match_rule_for_signals (GProxyVolumeMonitor *monitor)
-{
-  return g_strdup_printf ("type='signal',"
-                          "interface='org.gtk.Private.RemoteVolumeMonitor',"
-                          "sender='%s',",
-                          g_proxy_volume_monitor_get_dbus_name (monitor));
-}
-
-static char *
-get_match_rule_for_name_owner_changed (GProxyVolumeMonitor *monitor)
-{
-  return g_strdup_printf ("type='signal',"
-                          "interface='org.freedesktop.DBus',"
-                          "member='NameOwnerChanged',"
-                          "arg0='%s'",
-                          g_proxy_volume_monitor_get_dbus_name (monitor));
-}
-
 static void
 g_proxy_volume_monitor_finalize (GObject *object)
 {
@@ -365,6 +346,562 @@ get_mount_for_mount_path (const char *mount_path,
   return mount;
 }
 
+static void
+drive_changed (GVfsRemoteVolumeMonitor *object,
+               const gchar *arg_dbus_name,
+               const gchar *arg_id,
+               GVariant *arg_drive,
+               gpointer user_data)
+{
+  GProxyVolumeMonitor *monitor = G_PROXY_VOLUME_MONITOR (user_data);
+  GProxyVolumeMonitorClass *klass;
+  GProxyDrive *d;
+
+  G_LOCK (proxy_vm);
+
+  klass = G_PROXY_VOLUME_MONITOR_CLASS (G_OBJECT_GET_CLASS (monitor));
+
+  if (strcmp (arg_dbus_name, klass->dbus_name) != 0)
+    goto not_for_us;
+  
+  d = g_hash_table_lookup (monitor->drives, arg_id);
+  if (d != NULL)
+    {
+      g_proxy_drive_update (d, arg_drive);
+      signal_emit_in_idle (d, "changed", NULL);
+      signal_emit_in_idle (monitor, "drive-changed", d);
+    }
+    
+  not_for_us:
+   G_UNLOCK (proxy_vm);
+}
+
+static void
+drive_connected (GVfsRemoteVolumeMonitor *object,
+                 const gchar *arg_dbus_name,
+                 const gchar *arg_id,
+                 GVariant *arg_drive,
+                 gpointer user_data)
+{
+  GProxyVolumeMonitor *monitor = G_PROXY_VOLUME_MONITOR (user_data);
+  GProxyVolumeMonitorClass *klass;
+  GProxyDrive *d;
+
+  G_LOCK (proxy_vm);
+
+  klass = G_PROXY_VOLUME_MONITOR_CLASS (G_OBJECT_GET_CLASS (monitor));
+
+  if (strcmp (arg_dbus_name, klass->dbus_name) != 0)
+    goto not_for_us;
+  
+  d = g_hash_table_lookup (monitor->drives, arg_id);
+  if (d == NULL)
+    {
+      d = g_proxy_drive_new (monitor);
+      g_proxy_drive_update (d, arg_drive);
+      g_hash_table_insert (monitor->drives, g_strdup (g_proxy_drive_get_id (d)), d);
+      signal_emit_in_idle (monitor, "drive-connected", d);
+    }
+    
+  not_for_us:
+   G_UNLOCK (proxy_vm);
+}
+
+static void
+drive_disconnected (GVfsRemoteVolumeMonitor *object,
+                    const gchar *arg_dbus_name,
+                    const gchar *arg_id,
+                    GVariant *arg_drive,
+                    gpointer user_data)
+{
+  GProxyVolumeMonitor *monitor = G_PROXY_VOLUME_MONITOR (user_data);
+  GProxyVolumeMonitorClass *klass;
+  GProxyDrive *d;
+
+  G_LOCK (proxy_vm);
+
+  klass = G_PROXY_VOLUME_MONITOR_CLASS (G_OBJECT_GET_CLASS (monitor));
+
+  if (strcmp (arg_dbus_name, klass->dbus_name) != 0)
+    goto not_for_us;
+  
+  d = g_hash_table_lookup (monitor->drives, arg_id);
+  if (d != NULL)
+    {
+      g_object_ref (d);
+      g_hash_table_remove (monitor->drives, arg_id);
+      signal_emit_in_idle (d, "disconnected", NULL);
+      signal_emit_in_idle (monitor, "drive-disconnected", d);
+      g_object_unref (d);
+    }
+  
+  not_for_us:
+   G_UNLOCK (proxy_vm);
+}
+
+static void
+drive_eject_button (GVfsRemoteVolumeMonitor *object,
+                    const gchar *arg_dbus_name,
+                    const gchar *arg_id,
+                    GVariant *arg_drive,
+                    gpointer user_data)
+{
+  GProxyVolumeMonitor *monitor = G_PROXY_VOLUME_MONITOR (user_data);
+  GProxyVolumeMonitorClass *klass;
+  GProxyDrive *d;
+
+  G_LOCK (proxy_vm);
+
+  klass = G_PROXY_VOLUME_MONITOR_CLASS (G_OBJECT_GET_CLASS (monitor));
+
+  if (strcmp (arg_dbus_name, klass->dbus_name) != 0)
+    goto not_for_us;
+  
+  d = g_hash_table_lookup (monitor->drives, arg_id);
+  if (d != NULL)
+    {
+      signal_emit_in_idle (d, "eject-button", NULL);
+      signal_emit_in_idle (monitor, "drive-eject-button", d);
+    }
+
+  not_for_us:
+   G_UNLOCK (proxy_vm);
+}
+
+static void
+drive_stop_button (GVfsRemoteVolumeMonitor *object,
+                   const gchar *arg_dbus_name,
+                   const gchar *arg_id,
+                   GVariant *arg_drive,
+                   gpointer user_data)
+{
+  GProxyVolumeMonitor *monitor = G_PROXY_VOLUME_MONITOR (user_data);
+  GProxyVolumeMonitorClass *klass;
+  GProxyDrive *d;
+
+  G_LOCK (proxy_vm);
+
+  klass = G_PROXY_VOLUME_MONITOR_CLASS (G_OBJECT_GET_CLASS (monitor));
+
+  if (strcmp (arg_dbus_name, klass->dbus_name) != 0)
+    goto not_for_us;
+  
+  d = g_hash_table_lookup (monitor->drives, arg_id);
+  if (d != NULL)
+    {
+      signal_emit_in_idle (d, "stop-button", NULL);
+      signal_emit_in_idle (monitor, "drive-stop-button", d);
+    }
+
+  not_for_us:
+   G_UNLOCK (proxy_vm);
+}
+
+static void
+mount_added (GVfsRemoteVolumeMonitor *object,
+             const gchar *arg_dbus_name,
+             const gchar *arg_id,
+             GVariant *arg_mount,
+             gpointer user_data)
+{
+  GProxyVolumeMonitor *monitor = G_PROXY_VOLUME_MONITOR (user_data);
+  GProxyVolumeMonitorClass *klass;
+  GProxyMount *m;
+
+  G_LOCK (proxy_vm);
+
+  klass = G_PROXY_VOLUME_MONITOR_CLASS (G_OBJECT_GET_CLASS (monitor));
+
+  if (strcmp (arg_dbus_name, klass->dbus_name) != 0)
+    goto not_for_us;
+  
+  m = g_hash_table_lookup (monitor->mounts, arg_id);
+  if (m == NULL)
+    {
+      m = g_proxy_mount_new (monitor);
+      g_proxy_mount_update (m, arg_mount);
+      g_hash_table_insert (monitor->mounts, g_strdup (g_proxy_mount_get_id (m)), m);
+      signal_emit_in_idle (monitor, "mount-added", m);
+    }
+    
+  not_for_us:
+   G_UNLOCK (proxy_vm);
+}
+
+static void
+mount_changed (GVfsRemoteVolumeMonitor *object,
+               const gchar *arg_dbus_name,
+               const gchar *arg_id,
+               GVariant *arg_mount,
+               gpointer user_data)
+{
+  GProxyVolumeMonitor *monitor = G_PROXY_VOLUME_MONITOR (user_data);
+  GProxyVolumeMonitorClass *klass;
+  GProxyMount *m;
+
+  G_LOCK (proxy_vm);
+
+  klass = G_PROXY_VOLUME_MONITOR_CLASS (G_OBJECT_GET_CLASS (monitor));
+
+  if (strcmp (arg_dbus_name, klass->dbus_name) != 0)
+    goto not_for_us;
+  
+  m = g_hash_table_lookup (monitor->mounts, arg_id);
+  if (m != NULL)
+    {
+      g_proxy_mount_update (m, arg_mount);
+      signal_emit_in_idle (m, "changed", NULL);
+      signal_emit_in_idle (monitor, "mount-changed", m);
+    }
+    
+  not_for_us:
+   G_UNLOCK (proxy_vm);
+}
+
+static void
+mount_pre_unmount (GVfsRemoteVolumeMonitor *object,
+                   const gchar *arg_dbus_name,
+                   const gchar *arg_id,
+                   GVariant *arg_mount,
+                   gpointer user_data)
+{
+  GProxyVolumeMonitor *monitor = G_PROXY_VOLUME_MONITOR (user_data);
+  GProxyVolumeMonitorClass *klass;
+  GProxyMount *m;
+
+  G_LOCK (proxy_vm);
+
+  klass = G_PROXY_VOLUME_MONITOR_CLASS (G_OBJECT_GET_CLASS (monitor));
+
+  if (strcmp (arg_dbus_name, klass->dbus_name) != 0)
+    goto not_for_us;
+  
+  m = g_hash_table_lookup (monitor->mounts, arg_id);
+  if (m != NULL)
+    {
+      signal_emit_in_idle (m, "pre-unmount", NULL);
+      signal_emit_in_idle (monitor, "mount-pre-unmount", m);
+    }
+
+  not_for_us:
+   G_UNLOCK (proxy_vm);
+}
+
+static void
+mount_removed (GVfsRemoteVolumeMonitor *object,
+               const gchar *arg_dbus_name,
+               const gchar *arg_id,
+               GVariant *arg_mount,
+               gpointer user_data)
+{
+  GProxyVolumeMonitor *monitor = G_PROXY_VOLUME_MONITOR (user_data);
+  GProxyVolumeMonitorClass *klass;
+  GProxyMount *m;
+
+  G_LOCK (proxy_vm);
+
+  klass = G_PROXY_VOLUME_MONITOR_CLASS (G_OBJECT_GET_CLASS (monitor));
+
+  if (strcmp (arg_dbus_name, klass->dbus_name) != 0)
+    goto not_for_us;
+  
+  m = g_hash_table_lookup (monitor->mounts, arg_id);
+  if (m != NULL)
+    {
+      g_object_ref (m);
+      g_hash_table_remove (monitor->mounts, arg_id);
+      signal_emit_in_idle (m, "unmounted", NULL);
+      signal_emit_in_idle (monitor, "mount-removed", m);
+      g_object_unref (m);
+    }
+    
+  not_for_us:
+   G_UNLOCK (proxy_vm);
+}
+
+static void
+mount_op_aborted (GVfsRemoteVolumeMonitor *object,
+                  const gchar *arg_dbus_name,
+                  const gchar *arg_id,
+                  gpointer user_data)
+{
+  GProxyVolumeMonitor *monitor = G_PROXY_VOLUME_MONITOR (user_data);
+  GProxyVolumeMonitorClass *klass;
+
+  G_LOCK (proxy_vm);
+
+  klass = G_PROXY_VOLUME_MONITOR_CLASS (G_OBJECT_GET_CLASS (monitor));
+
+  if (strcmp (arg_dbus_name, klass->dbus_name) != 0)
+    goto not_for_us;
+  
+  g_proxy_mount_operation_handle_aborted (arg_id);
+
+  not_for_us:
+   G_UNLOCK (proxy_vm);
+}
+
+static void
+mount_op_ask_password (GVfsRemoteVolumeMonitor *object,
+                       const gchar *arg_dbus_name,
+                       const gchar *arg_id,
+                       const gchar *arg_message_to_show,
+                       const gchar *arg_default_user,
+                       const gchar *arg_default_domain,
+                       guint arg_flags,
+                       gpointer user_data)
+{
+  GProxyVolumeMonitor *monitor = G_PROXY_VOLUME_MONITOR (user_data);
+  GProxyVolumeMonitorClass *klass;
+
+  G_LOCK (proxy_vm);
+
+  klass = G_PROXY_VOLUME_MONITOR_CLASS (G_OBJECT_GET_CLASS (monitor));
+
+  if (strcmp (arg_dbus_name, klass->dbus_name) != 0)
+    goto not_for_us;
+  
+  g_proxy_mount_operation_handle_ask_password (arg_id,
+                                               arg_message_to_show,
+                                               arg_default_user,
+                                               arg_default_domain,
+                                               arg_flags);
+
+  not_for_us:
+   G_UNLOCK (proxy_vm);
+}
+
+static void
+mount_op_ask_question (GVfsRemoteVolumeMonitor *object,
+                       const gchar *arg_dbus_name,
+                       const gchar *arg_id,
+                       const gchar *arg_message_to_show,
+                       const gchar *const *arg_choices,
+                       gpointer user_data)
+{
+  GProxyVolumeMonitor *monitor = G_PROXY_VOLUME_MONITOR (user_data);
+  GProxyVolumeMonitorClass *klass;
+
+  G_LOCK (proxy_vm);
+
+  klass = G_PROXY_VOLUME_MONITOR_CLASS (G_OBJECT_GET_CLASS (monitor));
+
+  if (strcmp (arg_dbus_name, klass->dbus_name) != 0)
+    goto not_for_us;
+  
+  g_proxy_mount_operation_handle_ask_question (arg_id,
+                                               arg_message_to_show,
+                                               arg_choices);
+
+  not_for_us:
+   G_UNLOCK (proxy_vm);
+}
+
+static void
+mount_op_show_processes (GVfsRemoteVolumeMonitor *object,
+                         const gchar *arg_dbus_name,
+                         const gchar *arg_id,
+                         const gchar *arg_message_to_show,
+                         GVariant *arg_pid,
+                         const gchar *const *arg_choices,
+                         gpointer user_data)
+{
+  GProxyVolumeMonitor *monitor = G_PROXY_VOLUME_MONITOR (user_data);
+  GProxyVolumeMonitorClass *klass;
+
+  G_LOCK (proxy_vm);
+
+  klass = G_PROXY_VOLUME_MONITOR_CLASS (G_OBJECT_GET_CLASS (monitor));
+
+  if (strcmp (arg_dbus_name, klass->dbus_name) != 0)
+    goto not_for_us;
+  
+  g_proxy_mount_operation_handle_show_processes (arg_id,
+                                                 arg_message_to_show,
+                                                 arg_pid,
+                                                 arg_choices);
+
+  not_for_us:
+   G_UNLOCK (proxy_vm);
+}
+
+static void
+volume_added (GVfsRemoteVolumeMonitor *object,
+              const gchar *arg_dbus_name,
+              const gchar *arg_id,
+              GVariant *arg_volume,
+              gpointer user_data)
+{
+  GProxyVolumeMonitor *monitor = G_PROXY_VOLUME_MONITOR (user_data);
+  GProxyVolumeMonitorClass *klass;
+  GProxyVolume *v;
+
+  G_LOCK (proxy_vm);
+
+  klass = G_PROXY_VOLUME_MONITOR_CLASS (G_OBJECT_GET_CLASS (monitor));
+
+  if (strcmp (arg_dbus_name, klass->dbus_name) != 0)
+    goto not_for_us;
+  
+  v = g_hash_table_lookup (monitor->volumes, arg_id);
+  if (v == NULL)
+    {
+      v = g_proxy_volume_new (monitor);
+      g_proxy_volume_update (v, arg_volume);
+      g_hash_table_insert (monitor->volumes, g_strdup (g_proxy_volume_get_id (v)), v);
+      signal_emit_in_idle (monitor, "volume-added", v);
+    }
+    
+  not_for_us:
+   G_UNLOCK (proxy_vm);
+}
+
+static void
+volume_changed (GVfsRemoteVolumeMonitor *object,
+                const gchar *arg_dbus_name,
+                const gchar *arg_id,
+                GVariant *arg_volume,
+                gpointer user_data)
+{
+  GProxyVolumeMonitor *monitor = G_PROXY_VOLUME_MONITOR (user_data);
+  GProxyVolumeMonitorClass *klass;
+  GProxyVolume *v;
+
+  G_LOCK (proxy_vm);
+
+  klass = G_PROXY_VOLUME_MONITOR_CLASS (G_OBJECT_GET_CLASS (monitor));
+
+  if (strcmp (arg_dbus_name, klass->dbus_name) != 0)
+    goto not_for_us;
+  
+  v = g_hash_table_lookup (monitor->volumes, arg_id);
+  if (v != NULL)
+    {
+      GProxyShadowMount *shadow_mount;
+
+      g_proxy_volume_update (v, arg_volume);
+      signal_emit_in_idle (v, "changed", NULL);
+      signal_emit_in_idle (monitor, "volume-changed", v);
+
+      shadow_mount = g_proxy_volume_get_shadow_mount (v);
+      if (shadow_mount != NULL)
+        {
+          signal_emit_in_idle (shadow_mount, "changed", NULL);
+          signal_emit_in_idle (monitor, "mount-changed", shadow_mount);
+          g_object_unref (shadow_mount);
+        }
+    }
+
+  not_for_us:
+   G_UNLOCK (proxy_vm);
+}
+
+static void
+volume_removed (GVfsRemoteVolumeMonitor *object,
+                const gchar *arg_dbus_name,
+                const gchar *arg_id,
+                GVariant *arg_volume,
+                gpointer user_data)
+{
+  GProxyVolumeMonitor *monitor = G_PROXY_VOLUME_MONITOR (user_data);
+  GProxyVolumeMonitorClass *klass;
+  GProxyVolume *v;
+
+  G_LOCK (proxy_vm);
+
+  klass = G_PROXY_VOLUME_MONITOR_CLASS (G_OBJECT_GET_CLASS (monitor));
+
+  if (strcmp (arg_dbus_name, klass->dbus_name) != 0)
+    goto not_for_us;
+  
+  v = g_hash_table_lookup (monitor->volumes, arg_id);
+  if (v != NULL)
+    {
+      g_object_ref (v);
+      g_hash_table_remove (monitor->volumes, arg_id);
+      signal_emit_in_idle (v, "removed", NULL);
+      signal_emit_in_idle (monitor, "volume-removed", v);
+      dispose_in_idle (v);
+      g_object_unref (v);
+    }
+    
+  not_for_us:
+   G_UNLOCK (proxy_vm);
+}
+
+static void
+on_name_owner_appeared (GDBusConnection *connection,
+                        const gchar     *name,
+                        const gchar     *name_owner,
+                        gpointer         user_data)
+{
+  GProxyVolumeMonitor *monitor = G_PROXY_VOLUME_MONITOR (user_data);
+  GHashTableIter hash_iter;
+  GProxyDrive *drive;
+  GProxyVolume *volume;
+  GProxyMount *mount;
+
+  seed_monitor (monitor);
+
+  /* emit signals for all the drives/volumes/mounts "added" */
+  g_hash_table_iter_init (&hash_iter, monitor->drives);
+  while (g_hash_table_iter_next (&hash_iter, NULL, (gpointer) &drive))
+    signal_emit_in_idle (monitor, "drive-connected", drive);
+
+  g_hash_table_iter_init (&hash_iter, monitor->volumes);
+  while (g_hash_table_iter_next (&hash_iter, NULL, (gpointer) &volume))
+    signal_emit_in_idle (monitor, "volume-added", volume);
+
+  g_hash_table_iter_init (&hash_iter, monitor->mounts);
+  while (g_hash_table_iter_next (&hash_iter, NULL, (gpointer) &mount))
+    signal_emit_in_idle (monitor, "mount-added", mount);
+}
+
+static void
+on_name_owner_vanished (GDBusConnection *connection,
+                        const gchar     *name,
+                        gpointer         user_data)
+{
+  GProxyVolumeMonitor *monitor = G_PROXY_VOLUME_MONITOR (user_data);
+  GProxyVolumeMonitorClass *klass;
+  GHashTableIter hash_iter;
+  GProxyDrive *drive;
+  GProxyVolume *volume;
+  GProxyMount *mount;
+
+  klass = G_PROXY_VOLUME_MONITOR_CLASS (G_OBJECT_GET_CLASS (monitor));
+
+  g_warning ("Owner of %s of volume monitor %s disconnected from the bus; removing drives/volumes/mounts",
+             name,
+             klass->dbus_name);
+
+  g_hash_table_iter_init (&hash_iter, monitor->mounts);
+  while (g_hash_table_iter_next (&hash_iter, NULL, (gpointer) &mount))
+    {
+      signal_emit_in_idle (mount, "unmounted", NULL);
+      signal_emit_in_idle (monitor, "mount-removed", mount);
+    }
+  g_hash_table_remove_all (monitor->mounts);
+
+  g_hash_table_iter_init (&hash_iter, monitor->volumes);
+  while (g_hash_table_iter_next (&hash_iter, NULL, (gpointer) &volume))
+    {
+      signal_emit_in_idle (volume, "removed", NULL);
+      signal_emit_in_idle (monitor, "volume-removed", volume);
+    }
+  g_hash_table_remove_all (monitor->volumes);
+
+  g_hash_table_iter_init (&hash_iter, monitor->drives);
+  while (g_hash_table_iter_next (&hash_iter, NULL, (gpointer) &drive))
+    {
+      signal_emit_in_idle (drive, "disconnected", NULL);
+      signal_emit_in_idle (monitor, "drive-disconnected", drive);
+    }
+  g_hash_table_remove_all (monitor->drives);
+
+  /* TODO: maybe try to relaunch the monitor? */
+}
+
 static GObject *
 g_proxy_volume_monitor_constructor (GType                  type,
                                     guint                  n_construct_properties,
@@ -374,8 +911,8 @@ g_proxy_volume_monitor_constructor (GType                  type,
   GProxyVolumeMonitor *monitor;
   GProxyVolumeMonitorClass *klass;
   GObjectClass *parent_class;
-  DBusError dbus_error;
-  char *match_rule;
+  GError *error;
+  const char *dbus_name;
 
   G_LOCK (proxy_vm);
 
@@ -387,6 +924,8 @@ g_proxy_volume_monitor_constructor (GType                  type,
       goto out;
     }
 
+  dbus_name = klass->dbus_name;
+
   /* Invoke parent constructor. */
   klass = G_PROXY_VOLUME_MONITOR_CLASS (g_type_class_peek (G_TYPE_PROXY_VOLUME_MONITOR));
   parent_class = G_OBJECT_CLASS (g_type_class_peek_parent (klass));
@@ -396,37 +935,52 @@ g_proxy_volume_monitor_constructor (GType                  type,
 
   monitor = G_PROXY_VOLUME_MONITOR (object);
 
-  dbus_error_init (&dbus_error);
-  monitor->session_bus = dbus_connection_ref (the_session_bus);
+  error = NULL;
+  monitor->proxy = gvfs_remote_volume_monitor_proxy_new_sync (the_session_bus,
+                                                              G_DBUS_PROXY_FLAGS_NONE,
+                                                              dbus_name,
+                                                              "/org/gtk/Private/RemoteVolumeMonitor",
+                                                              NULL,
+                                                              &error);
+  if (monitor->proxy == NULL)
+    {
+      g_printerr ("Error creating proxy: %s (%s, %d)\n",
+                  error->message, g_quark_to_string (error->domain), error->code);
+      g_error_free (error);
+      goto out;
+    }
+
+  /* listen to volume monitor signals */
+  g_signal_connect (monitor->proxy, "drive-changed", G_CALLBACK (drive_changed), monitor);
+  g_signal_connect (monitor->proxy, "drive-connected", G_CALLBACK (drive_connected), monitor);
+  g_signal_connect (monitor->proxy, "drive-disconnected", G_CALLBACK (drive_disconnected), monitor);
+  g_signal_connect (monitor->proxy, "drive-eject-button", G_CALLBACK (drive_eject_button), monitor);
+  g_signal_connect (monitor->proxy, "drive-stop-button", G_CALLBACK (drive_stop_button), monitor);
+  g_signal_connect (monitor->proxy, "mount-added", G_CALLBACK (mount_added), monitor);
+  g_signal_connect (monitor->proxy, "mount-changed", G_CALLBACK (mount_changed), monitor);
+  g_signal_connect (monitor->proxy, "mount-op-aborted", G_CALLBACK (mount_op_aborted), monitor);
+  g_signal_connect (monitor->proxy, "mount-op-ask-password", G_CALLBACK (mount_op_ask_password), monitor);
+  g_signal_connect (monitor->proxy, "mount-op-ask-question", G_CALLBACK (mount_op_ask_question), monitor);
+  g_signal_connect (monitor->proxy, "mount-op-show-processes", G_CALLBACK (mount_op_show_processes), monitor);
+  g_signal_connect (monitor->proxy, "mount-pre-unmount", G_CALLBACK (mount_pre_unmount), monitor);
+  g_signal_connect (monitor->proxy, "mount-removed", G_CALLBACK (mount_removed), monitor);
+  g_signal_connect (monitor->proxy, "volume-added", G_CALLBACK (volume_added), monitor);
+  g_signal_connect (monitor->proxy, "volume-changed", G_CALLBACK (volume_changed), monitor);
+  g_signal_connect (monitor->proxy, "volume-removed", G_CALLBACK (volume_removed), monitor);
+
   monitor->drives = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref);
   monitor->volumes = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref);
   monitor->mounts = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref);
 
-  dbus_connection_add_filter (monitor->session_bus, filter_function, monitor, NULL);
-
-  /* listen to volume monitor signals */
-  match_rule = get_match_rule_for_signals (monitor);
-  dbus_bus_add_match (monitor->session_bus,
-                      match_rule,
-                      &dbus_error);
-  if (dbus_error_is_set (&dbus_error)) {
-    g_warning ("cannot add match rule '%s': %s: %s", match_rule, dbus_error.name, dbus_error.message);
-    dbus_error_free (&dbus_error);
-  }
-  g_free (match_rule);
-
   /* listen to when the owner of the service appears/disappears */
-  match_rule = get_match_rule_for_name_owner_changed (monitor);
-  dbus_bus_add_match (monitor->session_bus,
-                      match_rule,
-                      &dbus_error);
-  if (dbus_error_is_set (&dbus_error)) {
-    g_warning ("cannot add match rule '%s': %s: %s", match_rule, dbus_error.name, dbus_error.message);
-    dbus_error_free (&dbus_error);
-  }
-  g_free (match_rule);
-
-  seed_monitor (monitor);
+  /* this will automatically call on_name_owner_appeared() when the daemon is ready and seed drives/volumes/mounts */
+  monitor->name_watcher_id = g_bus_watch_name_on_connection (the_session_bus,
+                                                             dbus_name,
+                                                             G_BUS_NAME_WATCHER_FLAGS_AUTO_START,
+                                                             on_name_owner_appeared,
+                                                             on_name_owner_vanished,
+                                                             monitor,
+                                                             NULL);
 
   g_hash_table_insert (the_volume_monitors, (gpointer) type, object);
 
@@ -491,336 +1045,10 @@ dispose_in_idle (gpointer object)
   g_idle_add ((GSourceFunc) dispose_in_idle_do, g_object_ref (object));
 }
 
-
-
-static DBusHandlerResult
-filter_function (DBusConnection *connection, DBusMessage *message, void *user_data)
-{
-  GProxyVolumeMonitor *monitor = G_PROXY_VOLUME_MONITOR (user_data);
-  DBusMessageIter iter;
-  const char *id;
-  const char *the_dbus_name;
-  const char *member;
-  GProxyDrive *drive;
-  GProxyVolume *volume;
-  GProxyMount *mount;
-  GProxyVolumeMonitorClass *klass;
-
-  G_LOCK (proxy_vm);
-
-  klass = G_PROXY_VOLUME_MONITOR_CLASS (G_OBJECT_GET_CLASS (monitor));
-
-  member = dbus_message_get_member (message);
-
-  if (dbus_message_is_signal (message, "org.freedesktop.DBus", "NameOwnerChanged"))
-    {
-      GHashTableIter hash_iter;
-      GProxyMount *mount;
-      GProxyVolume *volume;
-      GProxyDrive *drive;
-      const gchar *name;
-      const gchar *old_owner;
-      const gchar *new_owner;
-
-      dbus_message_iter_init (message, &iter);
-      dbus_message_iter_get_basic (&iter, &name);
-      dbus_message_iter_next (&iter);
-      dbus_message_iter_get_basic (&iter, &old_owner);
-      dbus_message_iter_next (&iter);
-      dbus_message_iter_get_basic (&iter, &new_owner);
-      dbus_message_iter_next (&iter);
-
-      if (strcmp (name, klass->dbus_name) != 0)
-        goto not_for_us;
-
-      if (monitor->unique_name != NULL && g_strcmp0 (new_owner, monitor->unique_name) != 0)
-        {
-          g_warning ("Owner %s of volume monitor %s disconnected from the bus; removing drives/volumes/mounts",
-                     monitor->unique_name,
-                     klass->dbus_name);
-
-          g_hash_table_iter_init (&hash_iter, monitor->mounts);
-          while (g_hash_table_iter_next (&hash_iter, NULL, (gpointer) &mount))
-            {
-              signal_emit_in_idle (mount, "unmounted", NULL);
-              signal_emit_in_idle (monitor, "mount-removed", mount);
-            }
-          g_hash_table_remove_all (monitor->mounts);
-
-          g_hash_table_iter_init (&hash_iter, monitor->volumes);
-          while (g_hash_table_iter_next (&hash_iter, NULL, (gpointer) &volume))
-            {
-              signal_emit_in_idle (volume, "removed", NULL);
-              signal_emit_in_idle (monitor, "volume-removed", volume);
-            }
-          g_hash_table_remove_all (monitor->volumes);
-
-          g_hash_table_iter_init (&hash_iter, monitor->drives);
-          while (g_hash_table_iter_next (&hash_iter, NULL, (gpointer) &drive))
-            {
-              signal_emit_in_idle (drive, "disconnected", NULL);
-              signal_emit_in_idle (monitor, "drive-disconnected", drive);
-            }
-          g_hash_table_remove_all (monitor->drives);
-
-          g_free (monitor->unique_name);
-          monitor->unique_name = NULL;
-
-          /* TODO: maybe try to relaunch the monitor? */
-
-        }
-
-      if (strlen (new_owner) > 0 && monitor->unique_name == NULL)
-        {
-          g_warning ("New owner %s for volume monitor %s connected to the bus; seeding drives/volumes/mounts",
-                     new_owner,
-                     klass->dbus_name);
-
-          seed_monitor (monitor);
-
-          /* emit signals for all the drives/volumes/mounts "added" */
-          g_hash_table_iter_init (&hash_iter, monitor->drives);
-          while (g_hash_table_iter_next (&hash_iter, NULL, (gpointer) &drive))
-            signal_emit_in_idle (monitor, "drive-connected", drive);
-
-          g_hash_table_iter_init (&hash_iter, monitor->volumes);
-          while (g_hash_table_iter_next (&hash_iter, NULL, (gpointer) &volume))
-            signal_emit_in_idle (monitor, "volume-added", volume);
-
-          g_hash_table_iter_init (&hash_iter, monitor->mounts);
-          while (g_hash_table_iter_next (&hash_iter, NULL, (gpointer) &mount))
-            signal_emit_in_idle (monitor, "mount-added", mount);
-        }
-
-    }
-  else  if (dbus_message_is_signal (message, "org.gtk.Private.RemoteVolumeMonitor", "DriveChanged") ||
-            dbus_message_is_signal (message, "org.gtk.Private.RemoteVolumeMonitor", "DriveConnected") ||
-            dbus_message_is_signal (message, "org.gtk.Private.RemoteVolumeMonitor", "DriveDisconnected") ||
-            dbus_message_is_signal (message, "org.gtk.Private.RemoteVolumeMonitor", "DriveEjectButton") ||
-            dbus_message_is_signal (message, "org.gtk.Private.RemoteVolumeMonitor", "DriveStopButton"))
-    {
-
-      dbus_message_iter_init (message, &iter);
-      dbus_message_iter_get_basic (&iter, &the_dbus_name);
-      dbus_message_iter_next (&iter);
-      dbus_message_iter_get_basic (&iter, &id);
-      dbus_message_iter_next (&iter);
-
-      if (strcmp (the_dbus_name, klass->dbus_name) != 0)
-        goto not_for_us;
-
-      if (strcmp (member, "DriveChanged") == 0)
-        {
-          drive = g_hash_table_lookup (monitor->drives, id);
-          if (drive != NULL)
-            {
-              g_proxy_drive_update (drive, &iter);
-              signal_emit_in_idle (drive, "changed", NULL);
-              signal_emit_in_idle (monitor, "drive-changed", drive);
-            }
-        }
-      else if (strcmp (member, "DriveConnected") == 0)
-        {
-          drive = g_hash_table_lookup (monitor->drives, id);
-          if (drive == NULL)
-            {
-              drive = g_proxy_drive_new (monitor);
-              g_proxy_drive_update (drive, &iter);
-              g_hash_table_insert (monitor->drives, g_strdup (g_proxy_drive_get_id (drive)), drive);
-              signal_emit_in_idle (monitor, "drive-connected", drive);
-            }
-        }
-      else if (strcmp (member, "DriveDisconnected") == 0)
-        {
-          drive = g_hash_table_lookup (monitor->drives, id);
-          if (drive != NULL)
-            {
-              g_object_ref (drive);
-              g_hash_table_remove (monitor->drives, id);
-              signal_emit_in_idle (drive, "disconnected", NULL);
-              signal_emit_in_idle (monitor, "drive-disconnected", drive);
-              g_object_unref (drive);
-            }
-        }
-      else if (strcmp (member, "DriveEjectButton") == 0)
-        {
-          drive = g_hash_table_lookup (monitor->drives, id);
-          if (drive != NULL)
-            {
-              signal_emit_in_idle (drive, "eject-button", NULL);
-              signal_emit_in_idle (monitor, "drive-eject-button", drive);
-            }
-        }
-      else if (strcmp (member, "DriveStopButton") == 0)
-        {
-          drive = g_hash_table_lookup (monitor->drives, id);
-          if (drive != NULL)
-            {
-              signal_emit_in_idle (drive, "stop-button", NULL);
-              signal_emit_in_idle (monitor, "drive-stop-button", drive);
-            }
-        }
-
-    }
-  else if (dbus_message_is_signal (message, "org.gtk.Private.RemoteVolumeMonitor", "VolumeChanged") ||
-           dbus_message_is_signal (message, "org.gtk.Private.RemoteVolumeMonitor", "VolumeAdded") ||
-           dbus_message_is_signal (message, "org.gtk.Private.RemoteVolumeMonitor", "VolumeRemoved"))
-    {
-      dbus_message_iter_init (message, &iter);
-      dbus_message_iter_get_basic (&iter, &the_dbus_name);
-      dbus_message_iter_next (&iter);
-      dbus_message_iter_get_basic (&iter, &id);
-      dbus_message_iter_next (&iter);
-
-      if (strcmp (the_dbus_name, klass->dbus_name) != 0)
-        goto not_for_us;
-
-      if (strcmp (member, "VolumeChanged") == 0)
-        {
-          volume = g_hash_table_lookup (monitor->volumes, id);
-          if (volume != NULL)
-            {
-              GProxyShadowMount *shadow_mount;
-
-              g_proxy_volume_update (volume, &iter);
-              signal_emit_in_idle (volume, "changed", NULL);
-              signal_emit_in_idle (monitor, "volume-changed", volume);
-
-              shadow_mount = g_proxy_volume_get_shadow_mount (volume);
-              if (shadow_mount != NULL)
-                {
-                  signal_emit_in_idle (shadow_mount, "changed", NULL);
-                  signal_emit_in_idle (monitor, "mount-changed", shadow_mount);
-                  g_object_unref (shadow_mount);
-                }
-            }
-        }
-      else if (strcmp (member, "VolumeAdded") == 0)
-        {
-          volume = g_hash_table_lookup (monitor->volumes, id);
-          if (volume == NULL)
-            {
-              volume = g_proxy_volume_new (monitor);
-              g_proxy_volume_update (volume, &iter);
-              g_hash_table_insert (monitor->volumes, g_strdup (g_proxy_volume_get_id (volume)), volume);
-              signal_emit_in_idle (monitor, "volume-added", volume);
-            }
-        }
-      else if (strcmp (member, "VolumeRemoved") == 0)
-        {
-          volume = g_hash_table_lookup (monitor->volumes, id);
-          if (volume != NULL)
-            {
-              g_object_ref (volume);
-              g_hash_table_remove (monitor->volumes, id);
-              signal_emit_in_idle (volume, "removed", NULL);
-              signal_emit_in_idle (monitor, "volume-removed", volume);
-              dispose_in_idle (volume);
-              g_object_unref (volume);
-            }
-        }
-
-    }
-  else if (dbus_message_is_signal (message, "org.gtk.Private.RemoteVolumeMonitor", "MountChanged") ||
-           dbus_message_is_signal (message, "org.gtk.Private.RemoteVolumeMonitor", "MountAdded") ||
-           dbus_message_is_signal (message, "org.gtk.Private.RemoteVolumeMonitor", "MountPreUnmount") ||
-           dbus_message_is_signal (message, "org.gtk.Private.RemoteVolumeMonitor", "MountRemoved"))
-    {
-
-      dbus_message_iter_init (message, &iter);
-      dbus_message_iter_get_basic (&iter, &the_dbus_name);
-      dbus_message_iter_next (&iter);
-      dbus_message_iter_get_basic (&iter, &id);
-      dbus_message_iter_next (&iter);
-
-      if (strcmp (the_dbus_name, klass->dbus_name) != 0)
-        goto not_for_us;
-
-      if (strcmp (member, "MountChanged") == 0)
-        {
-          mount = g_hash_table_lookup (monitor->mounts, id);
-          if (mount != NULL)
-            {
-              g_proxy_mount_update (mount, &iter);
-              signal_emit_in_idle (mount, "changed", NULL);
-              signal_emit_in_idle (monitor, "mount-changed", mount);
-            }
-        }
-      else if (strcmp (member, "MountAdded") == 0)
-        {
-          mount = g_hash_table_lookup (monitor->mounts, id);
-          if (mount == NULL)
-            {
-              mount = g_proxy_mount_new (monitor);
-              g_proxy_mount_update (mount, &iter);
-              g_hash_table_insert (monitor->mounts, g_strdup (g_proxy_mount_get_id (mount)), mount);
-              signal_emit_in_idle (monitor, "mount-added", mount);
-            }
-        }
-      else if (strcmp (member, "MountPreUnmount") == 0)
-        {
-          mount = g_hash_table_lookup (monitor->mounts, id);
-          if (mount != NULL)
-            {
-              signal_emit_in_idle (mount, "pre-unmount", NULL);
-              signal_emit_in_idle (monitor, "mount-pre-unmount", mount);
-            }
-        }
-      else if (strcmp (member, "MountRemoved") == 0)
-        {
-          mount = g_hash_table_lookup (monitor->mounts, id);
-          if (mount != NULL)
-            {
-              g_object_ref (mount);
-              g_hash_table_remove (monitor->mounts, id);
-              signal_emit_in_idle (mount, "unmounted", NULL);
-              signal_emit_in_idle (monitor, "mount-removed", mount);
-              g_object_unref (mount);
-            }
-        }
-    }
-  else if (dbus_message_is_method_call (message, "org.gtk.Private.RemoteVolumeMonitor", "MountOpAskPassword") ||
-           dbus_message_is_method_call (message, "org.gtk.Private.RemoteVolumeMonitor", "MountOpAskQuestion") ||
-           dbus_message_is_method_call (message, "org.gtk.Private.RemoteVolumeMonitor", "MountOpShowProcesses") ||
-           dbus_message_is_method_call (message, "org.gtk.Private.RemoteVolumeMonitor", "MountOpAborted"))
-    {
-      dbus_message_iter_init (message, &iter);
-      dbus_message_iter_get_basic (&iter, &the_dbus_name);
-      dbus_message_iter_next (&iter);
-      dbus_message_iter_get_basic (&iter, &id);
-      dbus_message_iter_next (&iter);
-
-      if (strcmp (the_dbus_name, klass->dbus_name) != 0)
-        goto not_for_us;
-
-      if (strcmp (member, "MountOpAskPassword") == 0)
-        {
-          g_proxy_mount_operation_handle_ask_password (id, &iter);
-        }
-      else if (strcmp (member, "MountOpAskQuestion") == 0)
-        {
-          g_proxy_mount_operation_handle_ask_question (id, &iter);
-        }
-      else if (strcmp (member, "MountOpShowProcesses") == 0)
-        {
-          g_proxy_mount_operation_handle_show_processes (id, &iter);
-        }
-      else if (strcmp (member, "MountOpAborted") == 0)
-        {
-          g_proxy_mount_operation_handle_aborted (id, &iter);
-        }
-    }
-
- not_for_us:
-  G_UNLOCK (proxy_vm);
-
-  return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
-}
-
 static void
 g_proxy_volume_monitor_init (GProxyVolumeMonitor *monitor)
 {
-  g_proxy_volume_monitor_setup_session_bus_connection (TRUE);
+  g_proxy_volume_monitor_setup_session_bus_connection ();
 }
 
 static void
@@ -855,6 +1083,7 @@ static void
 g_proxy_volume_monitor_class_intern_init_pre (GProxyVolumeMonitorClass *klass, gconstpointer class_data)
 {
   ProxyClassData *data = (ProxyClassData *) class_data;
+  
   klass->dbus_name = g_strdup (data->dbus_name);
   klass->is_native = data->is_native;
   klass->is_supported_nr = data->is_supported_nr;
@@ -864,56 +1093,45 @@ g_proxy_volume_monitor_class_intern_init_pre (GProxyVolumeMonitorClass *klass, g
 static gboolean
 is_remote_monitor_supported (const char *dbus_name)
 {
-  DBusMessage *message;
-  DBusMessage *reply;
-  DBusError dbus_error;
-  dbus_bool_t is_supported;
+  gboolean is_supported;
+  GVfsRemoteVolumeMonitor *proxy;
+  GError *error;
 
-  message = NULL;
-  reply = NULL;
   is_supported = FALSE;
+  error = NULL;
 
-  message = dbus_message_new_method_call (dbus_name,
-                                          "/org/gtk/Private/RemoteVolumeMonitor",
-                                          "org.gtk.Private.RemoteVolumeMonitor",
-                                          "IsSupported");
-  if (message == NULL)
-    {
-      g_warning ("Cannot allocate memory for DBusMessage");
-      goto fail;
-    }
-  dbus_error_init (&dbus_error);
-  reply = dbus_connection_send_with_reply_and_block (the_session_bus,
-                                                     message,
-                                                     -1,
-                                                     &dbus_error);
-  if (dbus_error_is_set (&dbus_error))
+  proxy = gvfs_remote_volume_monitor_proxy_new_sync (the_session_bus,
+                                                     G_DBUS_PROXY_FLAGS_NONE,
+                                                     dbus_name,
+                                                     "/org/gtk/Private/RemoteVolumeMonitor",
+                                                     NULL,
+                                                     &error);
+  if (proxy == NULL)
     {
-      g_warning ("invoking IsSupported() failed for remote volume monitor with dbus name %s: %s: %s",
-                 dbus_name,
-                 dbus_error.name,
-                 dbus_error.message);
-      dbus_error_free (&dbus_error);
-      goto fail;
+      g_printerr ("Error creating proxy: %s (%s, %d)\n",
+                  error->message, g_quark_to_string (error->domain), error->code);
+      g_error_free (error);
+      goto out;
     }
 
-  if (!dbus_message_get_args (reply, &dbus_error,
-                              DBUS_TYPE_BOOLEAN, &is_supported,
-                              DBUS_TYPE_INVALID))
+  error = NULL;
+  if (!gvfs_remote_volume_monitor_call_is_supported_sync (proxy,
+                                                          &is_supported,
+                                                          NULL,
+                                                          &error))
     {
-      g_warning ("Error parsing args in reply for IsSupported(): %s: %s", dbus_error.name, dbus_error.message);
-      dbus_error_free (&dbus_error);
-      goto fail;
+      g_printerr ("invoking IsSupported() failed for remote volume monitor with dbus name %s:: %s (%s, %d)\n",
+                  dbus_name, error->message, g_quark_to_string (error->domain), error->code);
+      g_error_free (error);
+      goto out;
     }
-
+  
   if (!is_supported)
     g_warning ("remote volume monitor with dbus name %s is not supported", dbus_name);
 
- fail:
-  if (message != NULL)
-    dbus_message_unref (message);
-  if (reply != NULL)
-    dbus_message_unref (reply);
+ out:
+  if (proxy != NULL)
+    g_object_unref (proxy);
   return is_supported;
 }
 
@@ -923,7 +1141,7 @@ is_supported (GProxyVolumeMonitorClass *klass)
   gboolean res;
 
   G_LOCK (proxy_vm);
-  res = g_proxy_volume_monitor_setup_session_bus_connection (FALSE);
+  res = g_proxy_volume_monitor_setup_session_bus_connection ();
   G_UNLOCK (proxy_vm);
   
   if (res)
@@ -961,86 +1179,70 @@ g_proxy_volume_monitor_class_init (GProxyVolumeMonitorClass *klass)
 static void
 seed_monitor (GProxyVolumeMonitor *monitor)
 {
-  DBusMessage *message;
-  DBusMessage *reply;
-  DBusError dbus_error;
-  DBusMessageIter iter_reply;
-  DBusMessageIter iter_array;
-
-  message = dbus_message_new_method_call (g_proxy_volume_monitor_get_dbus_name (monitor),
-                                          "/org/gtk/Private/RemoteVolumeMonitor",
-                                          "org.gtk.Private.RemoteVolumeMonitor",
-                                          "List");
-  if (message == NULL)
-    {
-      g_warning ("Cannot allocate memory for DBusMessage");
-      goto fail;
-    }
-  dbus_error_init (&dbus_error);
-  reply = dbus_connection_send_with_reply_and_block (monitor->session_bus,
-                                                     message,
-                                                     -1,
-                                                     &dbus_error);
-  dbus_message_unref (message);
-  if (dbus_error_is_set (&dbus_error))
+  GVariant *Drives;
+  GVariant *Volumes;
+  GVariant *Mounts;
+  GVariantIter iter;
+  GVariant *child;
+  GError *error;
+
+  error = NULL;
+  if (!gvfs_remote_volume_monitor_call_list_sync (monitor->proxy,
+                                                  &Drives,
+                                                  &Volumes,
+                                                  &Mounts,
+                                                  NULL,
+                                                  &error))
     {
-      g_warning ("invoking List() failed for type %s: %s: %s",
+      g_warning ("invoking List() failed for type %s: %s (%s, %d)",
                  G_OBJECT_TYPE_NAME (monitor),
-                 dbus_error.name,
-                 dbus_error.message);
-      dbus_error_free (&dbus_error);
+                 error->message, g_quark_to_string (error->domain), error->code);
+      g_error_free (error);
       goto fail;
     }
 
-  dbus_message_iter_init (reply, &iter_reply);
-
-  /* TODO: verify signature */
-
   /* drives */
-  dbus_message_iter_recurse (&iter_reply, &iter_array);
-  while (dbus_message_iter_get_arg_type (&iter_array) != DBUS_TYPE_INVALID)
+  g_variant_iter_init (&iter, Drives);
+  while ((child = g_variant_iter_next_value (&iter)))
     {
       GProxyDrive *drive;
       const char *id;
       drive = g_proxy_drive_new (monitor);
-      g_proxy_drive_update (drive, &iter_array);
+      g_proxy_drive_update (drive, child);
       id = g_proxy_drive_get_id (drive);
       g_hash_table_insert (monitor->drives, g_strdup (id), drive);
-      dbus_message_iter_next (&iter_array);
+      g_variant_unref (child);
     }
-  dbus_message_iter_next (&iter_reply);
 
   /* volumes */
-  dbus_message_iter_recurse (&iter_reply, &iter_array);
-  while (dbus_message_iter_get_arg_type (&iter_array) != DBUS_TYPE_INVALID)
+  g_variant_iter_init (&iter, Volumes);
+  while ((child = g_variant_iter_next_value (&iter)))
     {
       GProxyVolume *volume;
       const char *id;
       volume = g_proxy_volume_new (monitor);
-      g_proxy_volume_update (volume, &iter_array);
+      g_proxy_volume_update (volume, child);
       id = g_proxy_volume_get_id (volume);
       g_hash_table_insert (monitor->volumes, g_strdup (id), volume);
-      dbus_message_iter_next (&iter_array);
+      g_variant_unref (child);
     }
-  dbus_message_iter_next (&iter_reply);
 
   /* mounts */
-  dbus_message_iter_recurse (&iter_reply, &iter_array);
-  while (dbus_message_iter_get_arg_type (&iter_array) != DBUS_TYPE_INVALID)
+  g_variant_iter_init (&iter, Mounts);
+  while ((child = g_variant_iter_next_value (&iter)))
     {
       GProxyMount *mount;
       const char *id;
       mount = g_proxy_mount_new (monitor);
-      g_proxy_mount_update (mount, &iter_array);
+      g_proxy_mount_update (mount, child);
       id = g_proxy_mount_get_id (mount);
       g_hash_table_insert (monitor->mounts, g_strdup (id), mount);
-      dbus_message_iter_next (&iter_array);
+      g_variant_unref (child);
     }
-  dbus_message_iter_next (&iter_reply);
-
-  monitor->unique_name = g_strdup (dbus_message_get_sender (reply));
 
-  dbus_message_unref (reply);
+  g_variant_unref (Drives);
+  g_variant_unref (Volumes);
+  g_variant_unref (Mounts);
 
  fail:
   ;
@@ -1093,47 +1295,27 @@ g_proxy_volume_monitor_get_mount_for_id  (GProxyVolumeMonitor *volume_monitor,
 
 
 GHashTable *
-_get_identifiers (DBusMessageIter *iter)
+_get_identifiers (GVariantIter *iter)
 {
   GHashTable *hash_table;
-  DBusMessageIter iter_array;
+  char *key;
+  char *value;
 
   hash_table = g_hash_table_new_full (g_str_hash,
                                       g_str_equal,
                                       g_free,
                                       g_free);
 
-  dbus_message_iter_recurse (iter, &iter_array);
-  while (dbus_message_iter_get_arg_type (&iter_array) != DBUS_TYPE_INVALID)
-    {
-      DBusMessageIter iter_dict_entry;
-      const char *key;
-      const char *value;
-
-      dbus_message_iter_recurse (&iter_array, &iter_dict_entry);
-      dbus_message_iter_get_basic (&iter_dict_entry, &key);
-      dbus_message_iter_next (&iter_dict_entry);
-      dbus_message_iter_get_basic (&iter_dict_entry, &value);
-
-      g_hash_table_insert (hash_table, g_strdup (key), g_strdup (value));
-
-      dbus_message_iter_next (&iter_array);
-    }
-
+  while (g_variant_iter_next (iter, "{ss}", &key, &value))
+    g_hash_table_insert (hash_table, key, value);
+  
   return hash_table;
 }
 
-DBusConnection *
-g_proxy_volume_monitor_get_dbus_connection (GProxyVolumeMonitor *volume_monitor)
+GVfsRemoteVolumeMonitor *
+g_proxy_volume_monitor_get_dbus_proxy (GProxyVolumeMonitor *volume_monitor)
 {
-  return dbus_connection_ref (volume_monitor->session_bus);
-}
-
-const char *
-g_proxy_volume_monitor_get_dbus_name (GProxyVolumeMonitor *volume_monitor)
-{
-  GProxyVolumeMonitorClass *klass = G_PROXY_VOLUME_MONITOR_CLASS (G_OBJECT_GET_CLASS (volume_monitor));
-  return klass->dbus_name;
+  return g_object_ref (volume_monitor->proxy);
 }
 
 static void
@@ -1171,11 +1353,11 @@ register_volume_monitor (GTypeModule *type_module,
 }
 
 /* Call with proxy_vm lock held */
-gboolean
-g_proxy_volume_monitor_setup_session_bus_connection (gboolean need_integration)
+static gboolean
+g_proxy_volume_monitor_setup_session_bus_connection (void)
 {
   gboolean ret;
-  DBusError dbus_error;
+  GError *error;
 
   ret = FALSE;
 
@@ -1189,25 +1371,21 @@ g_proxy_volume_monitor_setup_session_bus_connection (gboolean need_integration)
   if (g_getenv ("DBUS_SESSION_BUS_ADDRESS") == NULL)
     goto out;
 
-  dbus_error_init (&dbus_error);
-  the_session_bus = dbus_bus_get_private (DBUS_BUS_SESSION, &dbus_error);
-  if (dbus_error_is_set (&dbus_error))
+  error = NULL;
+  the_session_bus = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error);
+  if (error != NULL)
     {
-      g_warning ("cannot connect to the session bus: %s: %s", dbus_error.name, dbus_error.message);
-      dbus_error_free (&dbus_error);
+      g_printerr ("cannot connect to the session bus: %s (%s, %d)\n",
+                  error->message, g_quark_to_string (error->domain), error->code);
+      g_error_free (error);
       goto out;
     }
+  g_dbus_connection_set_exit_on_close (the_session_bus, FALSE);
 
   the_volume_monitors = g_hash_table_new (g_direct_hash, g_direct_equal);
 
  has_bus_already:
-  
-  if (need_integration && !the_session_bus_is_integrated)
-    {
-      _g_dbus_connection_integrate_with_main (the_session_bus);
-      the_session_bus_is_integrated = TRUE;
-    }
-  
+
   ret = TRUE;
 
  out:
@@ -1220,10 +1398,8 @@ g_proxy_volume_monitor_teardown_session_bus_connection (void)
   G_LOCK (proxy_vm);
   if (the_session_bus != NULL)
     {
-      if (the_session_bus_is_integrated)
-        _g_dbus_connection_remove_from_main (the_session_bus);
-      the_session_bus_is_integrated = FALSE;      
-      dbus_connection_close (the_session_bus);
+      g_dbus_connection_close_sync (the_session_bus, NULL, NULL);
+      g_object_unref (the_session_bus);
       the_session_bus = NULL;
 
       g_hash_table_unref (the_volume_monitors);
diff --git a/monitor/proxy/gproxyvolumemonitor.h b/monitor/proxy/gproxyvolumemonitor.h
index 3d29d7b..137e56b 100644
--- a/monitor/proxy/gproxyvolumemonitor.h
+++ b/monitor/proxy/gproxyvolumemonitor.h
@@ -27,7 +27,8 @@
 #include <glib-object.h>
 #include <gio/gio.h>
 #include <gio/gunixmounts.h>
-#include <dbus/dbus.h>
+
+#include "gvfsvolumemonitordbus.h"
 
 G_BEGIN_DECLS
 
@@ -64,21 +65,19 @@ struct _GProxyVolumeMonitorClass {
 
 GType g_proxy_volume_monitor_get_type (void) G_GNUC_CONST;
 
-void            g_proxy_volume_monitor_register          (GIOModule           *module);
-GProxyDrive    *g_proxy_volume_monitor_get_drive_for_id  (GProxyVolumeMonitor *volume_monitor,
+void             g_proxy_volume_monitor_register          (GIOModule           *module);
+GProxyDrive     *g_proxy_volume_monitor_get_drive_for_id  (GProxyVolumeMonitor *volume_monitor,
                                                           const char          *id);
-GProxyVolume   *g_proxy_volume_monitor_get_volume_for_id (GProxyVolumeMonitor *volume_monitor,
+GProxyVolume    *g_proxy_volume_monitor_get_volume_for_id (GProxyVolumeMonitor *volume_monitor,
                                                           const char          *id);
-GProxyMount    *g_proxy_volume_monitor_get_mount_for_id  (GProxyVolumeMonitor *volume_monitor,
+GProxyMount     *g_proxy_volume_monitor_get_mount_for_id  (GProxyVolumeMonitor *volume_monitor,
                                                           const char          *id);
-DBusConnection *g_proxy_volume_monitor_get_dbus_connection (GProxyVolumeMonitor *volume_monitor);
-const char     *g_proxy_volume_monitor_get_dbus_name       (GProxyVolumeMonitor *volume_monitor);
+GVfsRemoteVolumeMonitor *g_proxy_volume_monitor_get_dbus_proxy (GProxyVolumeMonitor *volume_monitor);
 
-gboolean g_proxy_volume_monitor_setup_session_bus_connection (gboolean need_integration);
 void g_proxy_volume_monitor_teardown_session_bus_connection (void);
 
 
-GHashTable *_get_identifiers (DBusMessageIter *iter);
+GHashTable *_get_identifiers (GVariantIter *identifiers);
 
 G_END_DECLS
 
diff --git a/monitor/proxy/gvfsproxyvolumemonitordaemon.c b/monitor/proxy/gvfsproxyvolumemonitordaemon.c
index fe2f1a7..713250c 100644
--- a/monitor/proxy/gvfsproxyvolumemonitordaemon.c
+++ b/monitor/proxy/gvfsproxyvolumemonitordaemon.c
@@ -25,25 +25,26 @@
 #include <string.h>
 #include <locale.h>
 #include <gio/gio.h>
-#include <dbus/dbus.h>
 #include <glib/gi18n.h>
 #include <stdlib.h>
 #include <glib/gprintf.h>
 
-#include "gvfsdbusutils.h"
 #include "gvfsproxyvolumemonitordaemon.h"
+#include "gvfsvolumemonitordbus.h"
 
 /* ---------------------------------------------------------------------------------------------------- */
 
+static GMainLoop *loop = NULL;
 static GVolumeMonitor *monitor = NULL;
-static DBusConnection *connection = NULL;
 static GType the_volume_monitor_type;
 static const char *the_dbus_name = NULL;
 static GList *outstanding_ops = NULL;
 static GList *outstanding_mount_op_objects = NULL;
 static GHashTable *unique_names_being_watched = NULL;
 
-/* #define DEBUG_ENABLED */
+static GVfsRemoteVolumeMonitor *monitor_daemon = NULL;
+
+#define DEBUG_ENABLED
 
 #ifdef DEBUG_ENABLED
 static void
@@ -136,31 +137,23 @@ g_proxy_mount_operation_class_init (GProxyMountOperationClass *klass)
 }
 
 static void
-ask_password_cb (GMountOperation  *mount_operation,
-                 const gchar      *message_to_show,
-                 const gchar      *default_user,
-                 const gchar      *default_domain,
-                 GAskPasswordFlags flags,
-                 gpointer          user_data)
+ask_password_cb (GMountOperation          *mount_operation,
+                 const gchar              *message_to_show,
+                 const gchar              *default_user,
+                 const gchar              *default_domain,
+                 GAskPasswordFlags         flags,
+                 GVfsRemoteVolumeMonitor  *monitor)
 {
-  DBusMessage *message;
-  DBusMessageIter iter;
   const gchar *mount_op_id;
   const gchar *mount_op_owner;
+  GDBusConnection *connection;
+  GError *error;
 
   print_debug ("in ask_password_cb %s", message_to_show);
 
   mount_op_id = g_object_get_data (G_OBJECT (mount_operation), "mount_op_id");
   mount_op_owner = g_object_get_data (G_OBJECT (mount_operation), "mount_op_owner");
 
-  message = dbus_message_new_method_call (mount_op_owner,
-                                          "/org/gtk/Private/RemoteVolumeMonitor",
-                                          "org.gtk.Private.RemoteVolumeMonitor",
-                                          "MountOpAskPassword");
-  dbus_message_iter_init_append (message, &iter);
-  dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &the_dbus_name);
-  dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &mount_op_id);
-
   if (message_to_show == NULL)
     message_to_show = "";
 
@@ -170,129 +163,178 @@ ask_password_cb (GMountOperation  *mount_operation,
   if (default_domain == NULL)
     default_domain = "";
 
-  dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &message_to_show);
-  dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &default_user);
-  dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &default_domain);
-  dbus_message_iter_append_basic (&iter, DBUS_TYPE_INT32, &flags);
-
-  dbus_connection_send (connection, message, NULL);
-  dbus_message_unref (message);
+  connection = g_dbus_interface_skeleton_get_connection (G_DBUS_INTERFACE_SKELETON (monitor));
+  g_assert (connection != NULL);
+  
+  error = NULL;
+  if (!g_dbus_connection_emit_signal (connection,
+                                      mount_op_owner,
+                                      "/org/gtk/Private/RemoteVolumeMonitor",
+                                      "org.gtk.Private.RemoteVolumeMonitor",
+                                      "MountOpAskPassword",
+                                      g_variant_new ("(sssssu)",
+                                                     the_dbus_name,
+                                                     mount_op_id,
+                                                     message_to_show,
+                                                     default_user,
+                                                     default_domain,
+                                                     flags),
+                                      &error))
+    {
+      g_printerr ("Error emitting signal: %s (%s, %d)\n",
+                  error->message, g_quark_to_string (error->domain), error->code);
+      g_error_free (error);
+    }
 }
 
 static void
-ask_question_cb (GMountOperation  *mount_operation,
-                 const gchar      *message_to_show,
-                 gchar           **choices,
-                 gpointer          user_data)
+ask_question_cb (GMountOperation          *mount_operation,
+                 const gchar              *message_to_show,
+                 gchar                   **choices,
+                 GVfsRemoteVolumeMonitor  *monitor)
 {
-  DBusMessage *message;
-  DBusMessageIter iter;
-  DBusMessageIter iter_string_array;
   const gchar *mount_op_id;
   const gchar *mount_op_owner;
   guint n;
+  GVariantBuilder *choices_array;
+  GDBusConnection *connection;
+  GError *error;
 
   print_debug ("in ask_question_cb %s", message_to_show);
 
   mount_op_id = g_object_get_data (G_OBJECT (mount_operation), "mount_op_id");
   mount_op_owner = g_object_get_data (G_OBJECT (mount_operation), "mount_op_owner");
 
-  message = dbus_message_new_method_call (mount_op_owner,
-                                          "/org/gtk/Private/RemoteVolumeMonitor",
-                                          "org.gtk.Private.RemoteVolumeMonitor",
-                                          "MountOpAskQuestion");
-  dbus_message_iter_init_append (message, &iter);
-  dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &the_dbus_name);
-  dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &mount_op_id);
-
   if (message_to_show == NULL)
     message_to_show = "";
 
-  dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &message_to_show);
-
-  dbus_message_iter_open_container (&iter, DBUS_TYPE_ARRAY, DBUS_TYPE_STRING_AS_STRING, &iter_string_array);
+  choices_array = g_variant_builder_new (G_VARIANT_TYPE_STRING_ARRAY);
   for (n = 0; choices != NULL && choices[n] != NULL; n++)
-    dbus_message_iter_append_basic (&iter_string_array, DBUS_TYPE_STRING, &(choices[n]));
-  dbus_message_iter_close_container (&iter, &iter_string_array);
+    {
+      g_variant_builder_add (choices_array, "s", choices[n]);
+    }
+
+  connection = g_dbus_interface_skeleton_get_connection (G_DBUS_INTERFACE_SKELETON (monitor));
+  g_assert (connection != NULL);
+  
+  error = NULL;
+  if (!g_dbus_connection_emit_signal (connection,
+                                      mount_op_owner,
+                                      "/org/gtk/Private/RemoteVolumeMonitor",
+                                      "org.gtk.Private.RemoteVolumeMonitor",
+                                      "MountOpAskQuestion",
+                                      g_variant_new ("(sssas)",
+                                                     the_dbus_name,
+                                                     mount_op_id,
+                                                     message_to_show,
+                                                     choices_array),
+                                      &error))
+    {
+      g_printerr ("Error emitting signal: %s (%s, %d)\n",
+                  error->message, g_quark_to_string (error->domain), error->code);
+      g_error_free (error);
+    }
 
-  dbus_connection_send (connection, message, NULL);
-  dbus_message_unref (message);
+  g_variant_builder_unref (choices_array);
 }
 
 static void
-show_processes_cb (GMountOperation  *mount_operation,
-                   const gchar      *message_to_show,
-                   GArray           *processes,
-                   gchar           **choices,
-                   gpointer          user_data)
+show_processes_cb (GMountOperation          *mount_operation,
+                   const gchar              *message_to_show,
+                   GArray                   *processes,
+                   gchar                   **choices,
+                   GVfsRemoteVolumeMonitor  *monitor)
 {
-  DBusMessage *message;
-  DBusMessageIter iter;
-  DBusMessageIter iter_string_array;
   const gchar *mount_op_id;
   const gchar *mount_op_owner;
   guint n;
+  GVariantBuilder *pids;
+  GVariantBuilder *choices_array;
+  GDBusConnection *connection;
+  GError *error;
 
   print_debug ("in show_processes_cb %s", message_to_show);
 
   mount_op_id = g_object_get_data (G_OBJECT (mount_operation), "mount_op_id");
   mount_op_owner = g_object_get_data (G_OBJECT (mount_operation), "mount_op_owner");
 
-  message = dbus_message_new_method_call (mount_op_owner,
-                                          "/org/gtk/Private/RemoteVolumeMonitor",
-                                          "org.gtk.Private.RemoteVolumeMonitor",
-                                          "MountOpShowProcesses");
-  dbus_message_iter_init_append (message, &iter);
-  dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &the_dbus_name);
-  dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &mount_op_id);
+  print_debug ("  owner =  '%s'", mount_op_owner);
 
   if (message_to_show == NULL)
     message_to_show = "";
 
-  dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &message_to_show);
-
-  dbus_message_iter_open_container (&iter, DBUS_TYPE_ARRAY, DBUS_TYPE_INT32_AS_STRING, &iter_string_array);
+  pids = g_variant_builder_new (G_VARIANT_TYPE ("ai"));
   for (n = 0; processes != NULL && n < processes->len; n++)
     {
       GPid pid;
       pid = g_array_index (processes, GPid, n);
-      dbus_message_iter_append_basic (&iter_string_array, DBUS_TYPE_INT32, &pid);
+      g_variant_builder_add (pids, "i", pid);
     }
-  dbus_message_iter_close_container (&iter, &iter_string_array);
 
-  dbus_message_iter_open_container (&iter, DBUS_TYPE_ARRAY, DBUS_TYPE_STRING_AS_STRING, &iter_string_array);
+  choices_array = g_variant_builder_new (G_VARIANT_TYPE_STRING_ARRAY);
   for (n = 0; choices != NULL && choices[n] != NULL; n++)
-    dbus_message_iter_append_basic (&iter_string_array, DBUS_TYPE_STRING, &(choices[n]));
-  dbus_message_iter_close_container (&iter, &iter_string_array);
+    {
+      g_variant_builder_add (choices_array, "s", choices[n]);
+    }
+
+  connection = g_dbus_interface_skeleton_get_connection (G_DBUS_INTERFACE_SKELETON (monitor));
+  g_assert (connection != NULL);
+  
+  error = NULL;
+  if (!g_dbus_connection_emit_signal (connection,
+                                      mount_op_owner,
+                                      "/org/gtk/Private/RemoteVolumeMonitor",
+                                      "org.gtk.Private.RemoteVolumeMonitor",
+                                      "MountOpShowProcesses",
+                                      g_variant_new ("(sssaias)",
+                                                     the_dbus_name,
+                                                     mount_op_id,
+                                                     message_to_show,
+                                                     pids,
+                                                     choices_array),
+                                      &error))
+    {
+      g_printerr ("Error emitting signal: %s (%s, %d)\n",
+                  error->message, g_quark_to_string (error->domain), error->code);
+      g_error_free (error);
+    }
 
-  dbus_connection_send (connection, message, NULL);
-  dbus_message_unref (message);
+  g_variant_builder_unref (pids);
+  g_variant_builder_unref (choices_array);
 }
 
 static void
-aborted_cb (GMountOperation  *mount_operation,
-            gpointer          user_data)
+aborted_cb (GMountOperation         *mount_operation,
+            GVfsRemoteVolumeMonitor *monitor)
 {
-  DBusMessage *message;
-  DBusMessageIter iter;
   const gchar *mount_op_id;
   const gchar *mount_op_owner;
+  GDBusConnection *connection;
+  GError *error;
 
   print_debug ("in aborted_cb");
 
   mount_op_id = g_object_get_data (G_OBJECT (mount_operation), "mount_op_id");
   mount_op_owner = g_object_get_data (G_OBJECT (mount_operation), "mount_op_owner");
 
-  message = dbus_message_new_method_call (mount_op_owner,
-                                          "/org/gtk/Private/RemoteVolumeMonitor",
-                                          "org.gtk.Private.RemoteVolumeMonitor",
-                                          "MountOpAborted");
-  dbus_message_iter_init_append (message, &iter);
-  dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &the_dbus_name);
-  dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &mount_op_id);
-
-  dbus_connection_send (connection, message, NULL);
-  dbus_message_unref (message);
+  connection = g_dbus_interface_skeleton_get_connection (G_DBUS_INTERFACE_SKELETON (monitor));
+  g_assert (connection != NULL);
+  
+  error = NULL;
+  if (!g_dbus_connection_emit_signal (connection,
+                                      mount_op_owner,
+                                      "/org/gtk/Private/RemoteVolumeMonitor",
+                                      "org.gtk.Private.RemoteVolumeMonitor",
+                                      "MountOpAborted",
+                                      g_variant_new ("(ss)",
+                                                     the_dbus_name,
+                                                     mount_op_id),
+                                      &error))
+    {
+      g_printerr ("Error emitting signal: %s (%s, %d)\n",
+                  error->message, g_quark_to_string (error->domain), error->code);
+      g_error_free (error);
+    }
 }
 
 static void
@@ -304,20 +346,22 @@ mount_op_destroyed_cb (gpointer user_data,
 
 static GMountOperation *
 wrap_mount_op (const gchar *mount_op_id,
-               const gchar *mount_op_owner)
+               const gchar *mount_op_owner,
+               GVfsRemoteVolumeMonitor *monitor)
 {
   GMountOperation *op;
 
   op = g_proxy_mount_operation_new ();
   //op = g_mount_operation_new ();
-  g_signal_connect (op, "ask-password", G_CALLBACK (ask_password_cb), NULL);
-  g_signal_connect (op, "ask-question", G_CALLBACK (ask_question_cb), NULL);
-  g_signal_connect (op, "show-processes", G_CALLBACK (show_processes_cb), NULL);
-  g_signal_connect (op, "aborted", G_CALLBACK (aborted_cb), NULL);
+  g_signal_connect (op, "ask-password", G_CALLBACK (ask_password_cb), monitor);
+  g_signal_connect (op, "ask-question", G_CALLBACK (ask_question_cb), monitor);
+  g_signal_connect (op, "show-processes", G_CALLBACK (show_processes_cb), monitor);
+  g_signal_connect (op, "aborted", G_CALLBACK (aborted_cb), monitor);
   g_object_set_data_full (G_OBJECT (op), "mount_op_id", g_strdup (mount_op_id), g_free);
   g_object_set_data_full (G_OBJECT (op), "mount_op_owner", g_strdup (mount_op_owner), g_free);
 
   outstanding_mount_op_objects = g_list_prepend (outstanding_mount_op_objects, op);
+
   g_object_weak_ref (G_OBJECT (op),
                      mount_op_destroyed_cb,
                      NULL);
@@ -336,64 +380,79 @@ cancellable_destroyed_cb (gpointer user_data,
 }
 
 static void
-remove_name_owned_changed_for_unique_name (const gchar *unique_name)
+on_name_owner_vanished (GDBusConnection *connection,
+                        const gchar     *name,
+                        gpointer         user_data)
 {
-  const gchar *match_rule;
-  DBusError dbus_error;
+  GList *l;
+  guint name_watcher_id;
+  
+  print_debug ("Name owner '%s' vanished", name);
 
-  match_rule = g_hash_table_lookup (unique_names_being_watched, unique_name);
-  if (match_rule == NULL)
+  /* if @name has outstanding mount operation objects; abort them */
+  for (l = outstanding_mount_op_objects; l != NULL; l = l->next)
     {
-      g_warning ("Was asked to remove match rule for unique_name %s but we don't have one", unique_name);
-      goto out;
+      GMountOperation *op = G_MOUNT_OPERATION (l->data);
+      const gchar *owner;
+
+      owner = g_object_get_data (G_OBJECT (op), "mount_op_owner");
+      if (g_strcmp0 (owner, name) == 0)
+        {
+          print_debug ("****** name `%s' has an outstanding mount operation object, aborting it",
+                       name);
+          g_mount_operation_reply (op, G_MOUNT_OPERATION_ABORTED);
+        }
     }
 
-  dbus_error_init (&dbus_error);
-  dbus_bus_remove_match (connection,
-                         match_rule,
-                         &dbus_error);
-  if (dbus_error_is_set (&dbus_error)) {
-    g_warning ("cannot remove match rule '%s': %s: %s", match_rule, dbus_error.name, dbus_error.message);
-    dbus_error_free (&dbus_error);
-  }
+  /* see if @name has outstanding ops; if so, cancel them */
+  for (l = outstanding_ops; l != NULL; l = l->next)
+    {
+      GCancellable *cancellable = G_CANCELLABLE (l->data);
+      const gchar *owner;
+
+      owner = g_object_get_data (G_OBJECT (cancellable), "owner");
+      print_debug ("looking at op for %s", owner);
+      if (g_strcmp0 (owner, name) == 0)
+        {
+          print_debug ("****** name `%s' has an outstanding op, cancelling it",
+                       name);
+          g_cancellable_cancel (cancellable);
+        }
+    }
 
-  g_hash_table_remove (unique_names_being_watched, unique_name);
+  /* unwatch the name */
+  name_watcher_id = GPOINTER_TO_UINT (g_hash_table_lookup (unique_names_being_watched, name));
+  if (name_watcher_id == 0)
+    {
+      g_warning ("Was asked to remove match rule for unique_name %s but we don't have one", name);
+    }
+  else
+    {
+      g_bus_unwatch_name (name_watcher_id);
+    }
 
- out:
-  ;
+  g_hash_table_remove (unique_names_being_watched, name);
 }
 
 static void
-ensure_name_owner_changed_for_unique_name (const gchar *unique_name)
+ensure_name_owner_changed_for_unique_name (GDBusMethodInvocation *invocation)
 {
-  gchar *match_rule;
-  DBusError dbus_error;
+  guint name_watcher_id;
+  const gchar *unique_name;
+  
+  unique_name = g_dbus_method_invocation_get_sender (invocation);
 
   if (g_hash_table_lookup (unique_names_being_watched, unique_name) != NULL)
-    goto out;
-
-  match_rule = g_strdup_printf ("type='signal',"
-                                "interface='org.freedesktop.DBus',"
-                                "member='NameOwnerChanged',"
-                                "arg0='%s'",
-                                unique_name);
-
-  dbus_error_init (&dbus_error);
-  dbus_bus_add_match (connection,
-                      match_rule,
-                      &dbus_error);
-  if (dbus_error_is_set (&dbus_error))
-    {
-      g_warning ("cannot add match rule '%s': %s: %s", match_rule, dbus_error.name, dbus_error.message);
-      dbus_error_free (&dbus_error);
-      g_free (match_rule);
-      goto out;
-    }
-
-  g_hash_table_insert (unique_names_being_watched, g_strdup (unique_name), match_rule);
-
- out:
-  ;
+    return;
+  
+  name_watcher_id = g_bus_watch_name_on_connection (g_dbus_method_invocation_get_connection (invocation),
+                                                    unique_name,
+                                                    G_BUS_NAME_WATCHER_FLAGS_NONE,
+                                                    NULL, /* name_appeared_handler */
+                                                    on_name_owner_vanished,
+                                                    NULL,
+                                                    NULL);
+  g_hash_table_insert (unique_names_being_watched, g_strdup (unique_name), GUINT_TO_POINTER (name_watcher_id));
 }
 
 static void monitor_try_create (void);
@@ -417,12 +476,9 @@ static void monitor_try_create (void);
  */
 #define DRIVE_STRUCT_TYPE "(sssbbbbbbbbuasa{ss}sa{sv})"
 
-static void
-append_drive (GDrive *drive, DBusMessageIter *iter_array)
+static GVariant *
+drive_to_dbus (GDrive *drive)
 {
-  DBusMessageIter iter_struct;
-  DBusMessageIter iter_volume_array;
-  DBusMessageIter iter_identifiers;
   char *id;
   char *name;
   GIcon *icon;
@@ -440,9 +496,11 @@ append_drive (GDrive *drive, DBusMessageIter *iter_array)
   char **identifiers;
   int n;
   const gchar *sort_key;
-  DBusMessageIter iter_expansion;
+  GVariant *result;
+  GVariantBuilder *volume_array_builder;
+  GVariantBuilder *identifiers_builder;
+  GVariantBuilder *expansion_builder;
 
-  dbus_message_iter_open_container (iter_array, DBUS_TYPE_STRUCT, NULL, &iter_struct);
 
   id = g_strdup_printf ("%p", drive);
   name = g_drive_get_name (drive);
@@ -470,51 +528,63 @@ append_drive (GDrive *drive, DBusMessageIter *iter_array)
   if (sort_key == NULL)
     sort_key = "";
 
-  dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_STRING, &id);
-  dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_STRING, &name);
-  dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_STRING, &icon_data);
-  dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_BOOLEAN, &can_eject);
-  dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_BOOLEAN, &can_poll_for_media);
-  dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_BOOLEAN, &has_media);
-  dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_BOOLEAN, &is_media_removable);
-  dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_BOOLEAN, &is_media_check_automatic);
-  dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_BOOLEAN, &can_start);
-  dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_BOOLEAN, &can_start_degraded);
-  dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_BOOLEAN, &can_stop);
-  dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_UINT32, &start_stop_type);
-
-  dbus_message_iter_open_container (&iter_struct, DBUS_TYPE_ARRAY, "s", &iter_volume_array);
+  volume_array_builder = g_variant_builder_new (G_VARIANT_TYPE ("as"));
   for (l = volumes; l != NULL; l = l->next)
     {
       GVolume *volume = G_VOLUME (l->data);
       char *volume_id;
       volume_id = g_strdup_printf ("%p", volume);
-      dbus_message_iter_append_basic (&iter_volume_array, DBUS_TYPE_STRING, &volume_id);
+      g_variant_builder_add (volume_array_builder, "s", volume_id);
       g_free (volume_id);
     }
-  dbus_message_iter_close_container (&iter_struct, &iter_volume_array);
 
-  dbus_message_iter_open_container (&iter_struct, DBUS_TYPE_ARRAY, "{ss}", &iter_identifiers);
+  identifiers_builder = g_variant_builder_new (G_VARIANT_TYPE ("a{ss}"));
   for (n = 0; identifiers != NULL && identifiers[n] != NULL; n++)
     {
-      DBusMessageIter iter_dict_entry;
       char *id_value;
       id_value = g_drive_get_identifier (drive, identifiers[n]);
-      dbus_message_iter_open_container (&iter_identifiers,
-                                        DBUS_TYPE_DICT_ENTRY,
-                                        NULL,
-                                        &iter_dict_entry);
-      dbus_message_iter_append_basic (&iter_dict_entry, DBUS_TYPE_STRING, &(identifiers[n]));
-      dbus_message_iter_append_basic (&iter_dict_entry, DBUS_TYPE_STRING, &id_value);
-      dbus_message_iter_close_container (&iter_identifiers, &iter_dict_entry);
+
+      g_variant_builder_add (identifiers_builder, "{ss}",
+                             identifiers[n],
+                             id_value);
       g_free (id_value);
     }
-  dbus_message_iter_close_container (&iter_struct, &iter_identifiers);
 
-  dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_STRING, &sort_key);
-  dbus_message_iter_open_container (&iter_struct, DBUS_TYPE_ARRAY, "{sv}", &iter_expansion);
+  expansion_builder = g_variant_builder_new (G_VARIANT_TYPE_VARDICT);
   /* left for future expansion without ABI breaks */
-  dbus_message_iter_close_container (&iter_struct, &iter_expansion);
+
+  for (n = 0; identifiers != NULL && identifiers[n] != NULL; n++)
+    {
+      char *id_value;
+      id_value = g_drive_get_identifier (drive, identifiers[n]);
+
+      g_variant_builder_add (identifiers_builder, "{ss}",
+                             identifiers[n],
+                             id_value);
+      g_free (id_value);
+    }
+
+  result = g_variant_new (DRIVE_STRUCT_TYPE,
+                          id,
+                          name,
+                          icon_data,
+                          can_eject,
+                          can_poll_for_media,
+                          has_media,
+                          is_media_removable,
+                          is_media_check_automatic,
+                          can_start,
+                          can_start_degraded,
+                          can_stop,
+                          start_stop_type,
+                          volume_array_builder,
+                          identifiers_builder,
+                          sort_key,
+                          expansion_builder);
+
+  g_variant_builder_unref (volume_array_builder);
+  g_variant_builder_unref (identifiers_builder);
+  g_variant_builder_unref (expansion_builder);
 
   g_strfreev (identifiers);
   g_list_foreach (volumes, (GFunc) g_object_unref, NULL);
@@ -524,7 +594,7 @@ append_drive (GDrive *drive, DBusMessageIter *iter_array)
   g_free (name);
   g_free (id);
 
-  dbus_message_iter_close_container (iter_array, &iter_struct);
+  return result;
 }
 
 /* string               id
@@ -542,11 +612,9 @@ append_drive (GDrive *drive, DBusMessageIter *iter_array)
  */
 #define VOLUME_STRUCT_TYPE "(sssssbbssa{ss}sa{sv})"
 
-static void
-append_volume (GVolume *volume, DBusMessageIter *iter_array)
+static GVariant *
+volume_to_dbus (GVolume *volume)
 {
-  DBusMessageIter iter_struct;
-  DBusMessageIter iter_identifiers;
   char *id;
   char *name;
   GIcon *icon;
@@ -563,9 +631,10 @@ append_volume (GVolume *volume, DBusMessageIter *iter_array)
   char **identifiers;
   int n;
   const gchar *sort_key;
-  DBusMessageIter iter_expansion;
+  GVariant *result;
+  GVariantBuilder *identifiers_builder;
+  GVariantBuilder *expansion_builder;
 
-  dbus_message_iter_open_container (iter_array, DBUS_TYPE_STRUCT, NULL, &iter_struct);
 
   id = g_strdup_printf ("%p", volume);
   name = g_volume_get_name (volume);
@@ -603,39 +672,39 @@ append_volume (GVolume *volume, DBusMessageIter *iter_array)
   if (sort_key == NULL)
     sort_key = "";
 
-  dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_STRING, &id);
-  dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_STRING, &name);
-  dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_STRING, &icon_data);
-  dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_STRING, &uuid);
-  dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_STRING, &activation_uri);
-  dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_BOOLEAN, &can_mount);
-  dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_BOOLEAN, &should_automount);
-  dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_STRING, &drive_id);
-  dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_STRING, &mount_id);
-
-  dbus_message_iter_open_container (&iter_struct, DBUS_TYPE_ARRAY, "{ss}", &iter_identifiers);
+  identifiers_builder = g_variant_builder_new (G_VARIANT_TYPE ("a{ss}"));
   for (n = 0; identifiers != NULL && identifiers[n] != NULL; n++)
     {
-      DBusMessageIter iter_dict_entry;
       char *id_value;
       id_value = g_volume_get_identifier (volume, identifiers[n]);
       if (id_value == NULL)
         continue;
-      dbus_message_iter_open_container (&iter_identifiers,
-                                        DBUS_TYPE_DICT_ENTRY,
-                                        NULL,
-                                        &iter_dict_entry);
-      dbus_message_iter_append_basic (&iter_dict_entry, DBUS_TYPE_STRING, &(identifiers[n]));
-      dbus_message_iter_append_basic (&iter_dict_entry, DBUS_TYPE_STRING, &id_value);
-      dbus_message_iter_close_container (&iter_identifiers, &iter_dict_entry);
+
+      g_variant_builder_add (identifiers_builder, "{ss}",
+                             identifiers[n],
+                             id_value);
       g_free (id_value);
     }
-  dbus_message_iter_close_container (&iter_struct, &iter_identifiers);
 
-  dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_STRING, &sort_key);
-  dbus_message_iter_open_container (&iter_struct, DBUS_TYPE_ARRAY, "{sv}", &iter_expansion);
+  expansion_builder = g_variant_builder_new (G_VARIANT_TYPE_VARDICT);
   /* left for future expansion without ABI breaks */
-  dbus_message_iter_close_container (&iter_struct, &iter_expansion);
+
+  result = g_variant_new (VOLUME_STRUCT_TYPE,
+                          id,
+                          name,
+                          icon_data,
+                          uuid,
+                          activation_uri,
+                          can_mount,
+                          should_automount,
+                          drive_id,
+                          mount_id,
+                          identifiers_builder,
+                          sort_key,
+                          expansion_builder);
+
+  g_variant_builder_unref (identifiers_builder);
+  g_variant_builder_unref (expansion_builder);
 
   g_strfreev (identifiers);
   g_free (mount_id);
@@ -653,7 +722,7 @@ append_volume (GVolume *volume, DBusMessageIter *iter_array)
   g_free (name);
   g_free (id);
 
-  dbus_message_iter_close_container (iter_array, &iter_struct);
+  return result;
 }
 
 /* string               id
@@ -669,11 +738,9 @@ append_volume (GVolume *volume, DBusMessageIter *iter_array)
  */
 #define MOUNT_STRUCT_TYPE "(sssssbsassa{sv})"
 
-static void
-append_mount (GMount *mount, DBusMessageIter *iter_array)
+static GVariant *
+mount_to_dbus (GMount *mount)
 {
-  DBusMessageIter iter_struct;
-  DBusMessageIter iter_x_content_types_array;
   char *id;
   char *name;
   GIcon *icon;
@@ -687,9 +754,9 @@ append_mount (GMount *mount, DBusMessageIter *iter_array)
   char **x_content_types;
   int n;
   const gchar *sort_key;
-  DBusMessageIter iter_expansion;
-
-  dbus_message_iter_open_container (iter_array, DBUS_TYPE_STRUCT, NULL, &iter_struct);
+  GVariant *result;
+  GVariantBuilder *x_content_types_array_builder;
+  GVariantBuilder *expansion_builder;
 
   id = g_strdup_printf ("%p", mount);
   name = g_mount_get_name (mount);
@@ -717,28 +784,31 @@ append_mount (GMount *mount, DBusMessageIter *iter_array)
   if (sort_key == NULL)
     sort_key = "";
 
-
-  dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_STRING, &id);
-  dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_STRING, &name);
-  dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_STRING, &icon_data);
-  dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_STRING, &uuid);
-  dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_STRING, &root_uri);
-  dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_BOOLEAN, &can_unmount);
-  dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_STRING, &volume_id);
-
-  dbus_message_iter_open_container (&iter_struct, DBUS_TYPE_ARRAY, "s", &iter_x_content_types_array);
+  x_content_types_array_builder = g_variant_builder_new (G_VARIANT_TYPE ("as"));
   x_content_types = (char **) g_object_get_data (G_OBJECT (mount), "x-content-types");
   if (x_content_types != NULL)
     {
       for (n = 0; x_content_types[n] != NULL; n++)
-        dbus_message_iter_append_basic (&iter_x_content_types_array, DBUS_TYPE_STRING, &(x_content_types[n]));
+        g_variant_builder_add (x_content_types_array_builder, "s", x_content_types[n]);
     }
-  dbus_message_iter_close_container (&iter_struct, &iter_x_content_types_array);
 
-  dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_STRING, &sort_key);
-  dbus_message_iter_open_container (&iter_struct, DBUS_TYPE_ARRAY, "{sv}", &iter_expansion);
+  expansion_builder = g_variant_builder_new (G_VARIANT_TYPE_VARDICT);
   /* left for future expansion without ABI breaks */
-  dbus_message_iter_close_container (&iter_struct, &iter_expansion);
+
+  result = g_variant_new (MOUNT_STRUCT_TYPE,
+                          id,
+                          name,
+                          icon_data,
+                          uuid,
+                          root_uri,
+                          can_unmount,
+                          volume_id,
+                          x_content_types_array_builder,
+                          sort_key,
+                          expansion_builder);
+
+  g_variant_builder_unref (x_content_types_array_builder);
+  g_variant_builder_unref (expansion_builder);
 
   g_free (volume_id);
   if (volume != NULL)
@@ -751,18 +821,21 @@ append_mount (GMount *mount, DBusMessageIter *iter_array)
   g_free (name);
   g_free (id);
 
-  dbus_message_iter_close_container (iter_array, &iter_struct);
+  return result;
 }
 
-static DBusHandlerResult
-handle_list (DBusConnection *connection, DBusMessage *message)
+static gboolean
+handle_list (GVfsRemoteVolumeMonitor *object,
+             GDBusMethodInvocation *invocation,
+             gpointer user_data)
 {
   GList *drives;
   GList *volumes;
   GList *mounts;
-  DBusMessageIter iter;
-  DBusMessageIter iter_array;
-  DBusMessage *reply;
+  GList *l;
+  GVariantBuilder *drives_array;
+  GVariantBuilder *volumes_array;
+  GVariantBuilder *mounts_array;
 
   print_debug ("in handle_list");
 
@@ -770,20 +843,15 @@ handle_list (DBusConnection *connection, DBusMessage *message)
   volumes = g_volume_monitor_get_volumes (monitor);
   mounts = g_volume_monitor_get_mounts (monitor);
 
-  reply = dbus_message_new_method_return (message);
-  dbus_message_iter_init_append (reply, &iter);
-
-  dbus_message_iter_open_container (&iter, DBUS_TYPE_ARRAY, DRIVE_STRUCT_TYPE, &iter_array);
-  g_list_foreach (drives, (GFunc) append_drive, &iter_array);
-  dbus_message_iter_close_container (&iter, &iter_array);
-
-  dbus_message_iter_open_container (&iter, DBUS_TYPE_ARRAY, VOLUME_STRUCT_TYPE, &iter_array);
-  g_list_foreach (volumes, (GFunc) append_volume, &iter_array);
-  dbus_message_iter_close_container (&iter, &iter_array);
-
-  dbus_message_iter_open_container (&iter, DBUS_TYPE_ARRAY, MOUNT_STRUCT_TYPE, &iter_array);
-  g_list_foreach (mounts, (GFunc) append_mount, &iter_array);
-  dbus_message_iter_close_container (&iter, &iter_array);
+  drives_array = g_variant_builder_new (G_VARIANT_TYPE ("a" DRIVE_STRUCT_TYPE));
+  for (l = drives; l; l = l->next)
+    g_variant_builder_add_value (drives_array, drive_to_dbus (l->data));
+  volumes_array = g_variant_builder_new (G_VARIANT_TYPE ("a" VOLUME_STRUCT_TYPE));
+  for (l = volumes; l; l = l->next)
+    g_variant_builder_add_value (volumes_array, volume_to_dbus (l->data));
+  mounts_array = g_variant_builder_new (G_VARIANT_TYPE ("a" MOUNT_STRUCT_TYPE));
+  for (l = mounts; l; l = l->next)
+    g_variant_builder_add_value (mounts_array, mount_to_dbus (l->data));
 
   g_list_foreach (drives, (GFunc) g_object_unref, NULL);
   g_list_free (drives);
@@ -791,20 +859,25 @@ handle_list (DBusConnection *connection, DBusMessage *message)
   g_list_free (volumes);
   g_list_foreach (mounts, (GFunc) g_object_unref, NULL);
   g_list_free (mounts);
-
-  dbus_connection_send (connection, reply, NULL);
-  dbus_message_unref (reply);
-
-  return DBUS_HANDLER_RESULT_HANDLED;
+  
+  gvfs_remote_volume_monitor_complete_list (object, invocation,
+                                            g_variant_builder_end (drives_array),
+                                            g_variant_builder_end (volumes_array),
+                                            g_variant_builder_end (mounts_array));
+  
+  g_variant_builder_unref (drives_array);
+  g_variant_builder_unref (volumes_array);
+  g_variant_builder_unref (mounts_array);
+  
+  return TRUE;
 }
 
 /* ---------------------------------------------------------------------------------------------------- */
 
 static void
-mount_unmount_cb (GMount *mount, GAsyncResult *result, DBusMessage *message)
+mount_unmount_cb (GMount *mount, GAsyncResult *result, GDBusMethodInvocation *invocation)
 {
   GError *error;
-  DBusMessage *reply;
 
   print_debug ("in mount_unmount_cb");
 
@@ -815,59 +888,37 @@ mount_unmount_cb (GMount *mount, GAsyncResult *result, DBusMessage *message)
   if (!g_mount_unmount_with_operation_finish (mount, result, &error))
     {
       print_debug ("  error: %s", error->message);
-      reply = _dbus_message_new_from_gerror (message, error);
+      g_dbus_method_invocation_return_gerror (invocation, error);
       g_error_free (error);
     }
   else
     {
       print_debug (" success");
-      reply = dbus_message_new_method_return (message);
+      gvfs_remote_volume_monitor_complete_mount_unmount (NULL, invocation);
     }
 
-  dbus_connection_send (connection, reply, NULL);
-  dbus_message_unref (message);
-  dbus_message_unref (reply);
-
   g_object_unref (mount);
+  g_object_unref (invocation);
 }
 
-static DBusHandlerResult
-handle_mount_unmount (DBusConnection *connection, DBusMessage *message)
+static gboolean
+handle_mount_unmount (GVfsRemoteVolumeMonitor *object,
+                      GDBusMethodInvocation *invocation,
+                      const gchar *arg_id,
+                      const gchar *arg_cancellation_id,
+                      guint arg_unmount_flags,
+                      const gchar *arg_mount_op_id,
+                      gpointer user_data)
 {
-  const char *id;
-  const char *cancellation_id;
   const char *sender;
-  const char *mount_op_id;
   GCancellable *cancellable;
   GMountOperation *mount_operation;
-  dbus_uint32_t unmount_flags;
-  DBusError dbus_error;
   GList *mounts, *l;
   GMount *mount;
-  DBusHandlerResult ret;
-
-  mounts = NULL;
-  unmount_flags = 0;
-  ret = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
-
-  dbus_error_init (&dbus_error);
-  if (!dbus_message_get_args (message, &dbus_error,
-                              DBUS_TYPE_STRING, &id,
-                              DBUS_TYPE_STRING, &cancellation_id,
-                              DBUS_TYPE_UINT32, &unmount_flags,
-                              DBUS_TYPE_STRING, &mount_op_id,
-                              DBUS_TYPE_INVALID))
-    {
-      g_warning ("Error parsing args for MountUnmount(): %s: %s", dbus_error.name, dbus_error.message);
-      dbus_error_free (&dbus_error);
-      goto out;
-    }
 
   print_debug ("in handle_mount_unmount");
 
-  ret = DBUS_HANDLER_RESULT_HANDLED;
-
-  sender = dbus_message_get_sender (message);
+  sender = g_dbus_method_invocation_get_sender (invocation);
 
   mount = NULL;
   mounts = g_volume_monitor_get_mounts (monitor);
@@ -877,7 +928,7 @@ handle_mount_unmount (DBusConnection *connection, DBusMessage *message)
 
       mount = G_MOUNT (l->data);
       mount_id = g_strdup_printf ("%p", mount);
-      if (strcmp (mount_id, id) == 0)
+      if (strcmp (mount_id, arg_id) == 0)
         break;
 
       g_free (mount_id);
@@ -887,49 +938,43 @@ handle_mount_unmount (DBusConnection *connection, DBusMessage *message)
 
   if (mount == NULL)
     {
-      DBusMessage *reply;
-      reply = dbus_message_new_error (message,
-                                      "org.gtk.Private.RemoteVolumeMonitor.NotFound",
-                                      "The given mount was not found");
-      dbus_connection_send (connection, reply, NULL);
-      dbus_message_unref (reply);
+      g_dbus_method_invocation_return_dbus_error (invocation,
+                                                  "org.gtk.Private.RemoteVolumeMonitor.NotFound",
+                                                  "The given mount was not found");
       goto out;
     }
 
   if (g_object_get_data (G_OBJECT (mount), "cancellable") != NULL)
     {
-      DBusMessage *reply;
-      reply = dbus_message_new_error (message,
-                                      "org.gtk.Private.RemoteVolumeMonitor.Failed",
-                                      "An operation is already pending");
-      dbus_connection_send (connection, reply, NULL);
-      dbus_message_unref (reply);
+      g_dbus_method_invocation_return_dbus_error (invocation,
+                                                  "org.gtk.Private.RemoteVolumeMonitor.Failed",
+                                                  "An operation is already pending");
       goto out;
     }
 
   cancellable = g_cancellable_new ();
   g_object_set_data_full (G_OBJECT (mount), "cancellable", cancellable, g_object_unref);
   g_object_set_data_full (G_OBJECT (cancellable), "owner", g_strdup (sender), g_free);
-  g_object_set_data_full (G_OBJECT (cancellable), "cancellation_id", g_strdup (cancellation_id), g_free);
+  g_object_set_data_full (G_OBJECT (cancellable), "cancellation_id", g_strdup (arg_cancellation_id), g_free);
   outstanding_ops = g_list_prepend (outstanding_ops, cancellable);
   g_object_weak_ref (G_OBJECT (cancellable),
                      cancellable_destroyed_cb,
                      NULL);
 
   mount_operation = NULL;
-  if (mount_op_id != NULL && strlen (mount_op_id) > 0)
+  if (arg_mount_op_id != NULL && strlen (arg_mount_op_id) > 0)
     {
-      mount_operation = wrap_mount_op (mount_op_id, sender);
+      mount_operation = wrap_mount_op (arg_mount_op_id, sender, object);
       g_object_set_data_full (G_OBJECT (mount), "mount_operation", mount_operation, g_object_unref);
     }
 
   g_object_ref (mount);
   g_mount_unmount_with_operation (mount,
-                                  unmount_flags,
+                                  arg_unmount_flags,
                                   mount_operation,
                                   cancellable,
                                   (GAsyncReadyCallback) mount_unmount_cb,
-                                  dbus_message_ref (message));
+                                  g_object_ref (invocation));
 
  out:
   if (mounts != NULL)
@@ -937,57 +982,34 @@ handle_mount_unmount (DBusConnection *connection, DBusMessage *message)
       g_list_foreach (mounts, (GFunc) g_object_unref, NULL);
       g_list_free (mounts);
     }
-  return ret;
+  return TRUE;
 }
 
 /* ---------------------------------------------------------------------------------------------------- */
 
-static DBusHandlerResult
-handle_mount_op_reply (DBusConnection *connection, DBusMessage *message)
+static gboolean
+handle_mount_op_reply (GVfsRemoteVolumeMonitor *object,
+                       GDBusMethodInvocation *invocation,
+                       const gchar *arg_mount_op_id,
+                       gint arg_result,
+                       const gchar *arg_user_name,
+                       const gchar *arg_domain,
+                       const gchar *arg_encoded_password,
+                       gint arg_password_save,
+                       gint arg_choice,
+                       gboolean arg_anonymous,
+                       gpointer user_data)
 {
-  const char *mount_op_id;
-  dbus_int32_t result;
-  const char *user_name;
-  const char *domain;
-  const char *encoded_password;
   char *decoded_password;
   gsize decoded_password_len;
-  dbus_int32_t password_save;
-  dbus_int32_t choice;
-  dbus_bool_t anonymous;
-  DBusError dbus_error;
-  DBusHandlerResult ret;
   GList *l;
-  DBusMessage *reply;
   GMountOperation *mount_operation;
   const gchar *sender;
 
-  decoded_password = NULL;
-  ret = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
-
-  dbus_error_init (&dbus_error);
-  if (!dbus_message_get_args (message,
-                              &dbus_error,
-                              DBUS_TYPE_STRING, &mount_op_id,
-                              DBUS_TYPE_INT32, &result,
-                              DBUS_TYPE_STRING, &user_name,
-                              DBUS_TYPE_STRING, &domain,
-                              DBUS_TYPE_STRING, &encoded_password,
-                              DBUS_TYPE_INT32, &password_save,
-                              DBUS_TYPE_INT32, &choice,
-                              DBUS_TYPE_BOOLEAN, &anonymous,
-                              DBUS_TYPE_INVALID))
-    {
-      g_warning ("Error parsing args for MountOpReply(): %s: %s", dbus_error.name, dbus_error.message);
-      dbus_error_free (&dbus_error);
-      goto out;
-    }
-
   print_debug ("in handle_mount_op_reply");
 
-  ret = DBUS_HANDLER_RESULT_HANDLED;
-
-  sender = dbus_message_get_sender (message);
+  decoded_password = NULL;
+  sender = g_dbus_method_invocation_get_sender (invocation);
 
   /* Find the op */
   mount_operation = NULL;
@@ -1000,7 +1022,7 @@ handle_mount_op_reply (DBusConnection *connection, DBusMessage *message)
 
       owner = g_object_get_data (G_OBJECT (op), "mount_op_owner");
       id = g_object_get_data (G_OBJECT (op), "mount_op_id");
-      if (g_strcmp0 (owner, sender) == 0 && g_strcmp0 (id, mount_op_id) == 0)
+      if (g_strcmp0 (owner, sender) == 0 && g_strcmp0 (id, arg_mount_op_id) == 0)
         {
           print_debug ("found mount_op");
           mount_operation = op;
@@ -1010,42 +1032,36 @@ handle_mount_op_reply (DBusConnection *connection, DBusMessage *message)
 
   if (mount_operation == NULL)
     {
-      DBusMessage *reply;
-      reply = dbus_message_new_error (message,
-                                      "org.gtk.Private.RemoteVolumeMonitor.NotFound",
-                                      "No outstanding mount operation");
-      dbus_connection_send (connection, reply, NULL);
-      dbus_message_unref (reply);
+      g_dbus_method_invocation_return_dbus_error (invocation,
+                                                  "org.gtk.Private.RemoteVolumeMonitor.NotFound",
+                                                  "No outstanding mount operation");
       goto out;
     }
 
-  decoded_password = (gchar *) g_base64_decode (encoded_password, &decoded_password_len);
+  decoded_password = (gchar *) g_base64_decode (arg_encoded_password, &decoded_password_len);
 
-  g_mount_operation_set_username (mount_operation, user_name);
-  g_mount_operation_set_domain (mount_operation, domain);
+  g_mount_operation_set_username (mount_operation, arg_user_name);
+  g_mount_operation_set_domain (mount_operation, arg_domain);
   g_mount_operation_set_password (mount_operation, decoded_password);
-  g_mount_operation_set_password_save (mount_operation, password_save);
-  g_mount_operation_set_choice (mount_operation, choice);
-  g_mount_operation_set_anonymous (mount_operation, anonymous);
+  g_mount_operation_set_password_save (mount_operation, arg_password_save);
+  g_mount_operation_set_choice (mount_operation, arg_choice);
+  g_mount_operation_set_anonymous (mount_operation, arg_anonymous);
 
-  g_mount_operation_reply (mount_operation, result);
+  g_mount_operation_reply (mount_operation, arg_result);
 
-  reply = dbus_message_new_method_return (message);
-  dbus_connection_send (connection, reply, NULL);
-  dbus_message_unref (reply);
+  gvfs_remote_volume_monitor_complete_mount_op_reply (object, invocation);
 
  out:
   g_free (decoded_password);
-  return ret;
+  return TRUE;
 }
 
 /* ---------------------------------------------------------------------------------------------------- */
 
 static void
-volume_mount_cb (GVolume *volume, GAsyncResult *result, DBusMessage *message)
+volume_mount_cb (GVolume *volume, GAsyncResult *result, GDBusMethodInvocation *invocation)
 {
   GError *error;
-  DBusMessage *reply;
 
   print_debug ("in volume_mount_cb");
 
@@ -1056,56 +1072,35 @@ volume_mount_cb (GVolume *volume, GAsyncResult *result, DBusMessage *message)
   if (!g_volume_mount_finish (volume, result, &error))
     {
       print_debug ("  error: %s", error->message);
-      reply = _dbus_message_new_from_gerror (message, error);
+      g_dbus_method_invocation_return_gerror (invocation, error);
       g_error_free (error);
     }
   else
     {
       print_debug (" success");
-      reply = dbus_message_new_method_return (message);
+      gvfs_remote_volume_monitor_complete_volume_mount (NULL, invocation);      
     }
-
-  dbus_connection_send (connection, reply, NULL);
-  dbus_message_unref (message);
-  dbus_message_unref (reply);
+  g_object_unref (invocation);
 }
 
-static DBusHandlerResult
-handle_volume_mount (DBusConnection *connection, DBusMessage *message)
+static gboolean
+handle_volume_mount (GVfsRemoteVolumeMonitor *object,
+                     GDBusMethodInvocation *invocation,
+                     const gchar *arg_id,
+                     const gchar *arg_cancellation_id,
+                     guint arg_mount_flags,
+                     const gchar *arg_mount_op_id,
+                     gpointer user_data)
 {
-  const char *id;
-  const char *cancellation_id;
   const char *sender;
-  dbus_uint32_t mount_flags;
-  const char *mount_op_id;
-  DBusError dbus_error;
   GList *volumes, *l;
   GVolume *volume;
-  DBusHandlerResult ret;
   GMountOperation *mount_operation;
   GCancellable *cancellable;
 
-  volumes = NULL;
-  ret = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
-
-  dbus_error_init (&dbus_error);
-  if (!dbus_message_get_args (message, &dbus_error,
-                              DBUS_TYPE_STRING, &id,
-                              DBUS_TYPE_STRING, &cancellation_id,
-                              DBUS_TYPE_UINT32, &mount_flags,
-                              DBUS_TYPE_STRING, &mount_op_id,
-                              DBUS_TYPE_INVALID))
-    {
-      g_warning ("Error parsing args for VolumeMount(): %s: %s", dbus_error.name, dbus_error.message);
-      dbus_error_free (&dbus_error);
-      goto out;
-    }
-
   print_debug ("in handle_volume_mount");
 
-  ret = DBUS_HANDLER_RESULT_HANDLED;
-
-  sender = dbus_message_get_sender (message);
+  sender = g_dbus_method_invocation_get_sender (invocation);
 
   volume = NULL;
   volumes = g_volume_monitor_get_volumes (monitor);
@@ -1115,7 +1110,7 @@ handle_volume_mount (DBusConnection *connection, DBusMessage *message)
 
       volume = G_VOLUME (l->data);
       volume_id = g_strdup_printf ("%p", volume);
-      if (strcmp (volume_id, id) == 0)
+      if (strcmp (volume_id, arg_id) == 0)
         break;
 
       g_free (volume_id);
@@ -1125,48 +1120,42 @@ handle_volume_mount (DBusConnection *connection, DBusMessage *message)
 
   if (volume == NULL)
     {
-      DBusMessage *reply;
-      reply = dbus_message_new_error (message,
-                                      "org.gtk.Private.RemoteVolumeMonitor.NotFound",
-                                      "The given volume was not found");
-      dbus_connection_send (connection, reply, NULL);
-      dbus_message_unref (reply);
+      g_dbus_method_invocation_return_dbus_error (invocation,
+                                                  "org.gtk.Private.RemoteVolumeMonitor.NotFound",
+                                                  "The given volume was not found");
       goto out;
     }
 
   if (g_object_get_data (G_OBJECT (volume), "cancellable") != NULL)
     {
-      DBusMessage *reply;
-      reply = dbus_message_new_error (message,
-                                      "org.gtk.Private.RemoteVolumeMonitor.Failed",
-                                      "An operation is already pending");
-      dbus_connection_send (connection, reply, NULL);
-      dbus_message_unref (reply);
+      g_dbus_method_invocation_return_dbus_error (invocation,
+                                                  "org.gtk.Private.RemoteVolumeMonitor.Failed",
+                                                  "An operation is already pending");
       goto out;
     }
 
   mount_operation = NULL;
-  if (mount_op_id != NULL && strlen (mount_op_id) > 0)
+  if (arg_mount_op_id != NULL && strlen (arg_mount_op_id) > 0)
     {
-      mount_operation = wrap_mount_op (mount_op_id, sender);
+      mount_operation = wrap_mount_op (arg_mount_op_id, sender, object);
       g_object_set_data_full (G_OBJECT (volume), "mount_operation", mount_operation, g_object_unref);
     }
 
   cancellable = g_cancellable_new ();
   g_object_set_data_full (G_OBJECT (volume), "cancellable", cancellable, g_object_unref);
   g_object_set_data_full (G_OBJECT (cancellable), "owner", g_strdup (sender), g_free);
-  g_object_set_data_full (G_OBJECT (cancellable), "cancellation_id", g_strdup (cancellation_id), g_free);
+  g_object_set_data_full (G_OBJECT (cancellable), "cancellation_id", g_strdup (arg_cancellation_id), g_free);
   outstanding_ops = g_list_prepend (outstanding_ops, cancellable);
   g_object_weak_ref (G_OBJECT (cancellable),
                      cancellable_destroyed_cb,
                      NULL);
 
   g_volume_mount (volume,
-                  mount_flags,
+                  arg_mount_flags,
                   mount_operation,
                   cancellable,
                   (GAsyncReadyCallback) volume_mount_cb,
-                  dbus_message_ref (message));
+                  g_object_ref (invocation));
 
  out:
   if (volumes != NULL)
@@ -1174,16 +1163,15 @@ handle_volume_mount (DBusConnection *connection, DBusMessage *message)
       g_list_foreach (volumes, (GFunc) g_object_unref, NULL);
       g_list_free (volumes);
     }
-  return ret;
+  return TRUE;
 }
 
 /* ---------------------------------------------------------------------------------------------------- */
 
 static void
-drive_eject_cb (GDrive *drive, GAsyncResult *result, DBusMessage *message)
+drive_eject_cb (GDrive *drive, GAsyncResult *result, GDBusMethodInvocation *invocation)
 {
   GError *error;
-  DBusMessage *reply;
 
   print_debug ("in drive_eject_cb");
 
@@ -1194,58 +1182,35 @@ drive_eject_cb (GDrive *drive, GAsyncResult *result, DBusMessage *message)
   if (!g_drive_eject_with_operation_finish (drive, result, &error))
     {
       print_debug ("  error: %s", error->message);
-      reply = _dbus_message_new_from_gerror (message, error);
+      g_dbus_method_invocation_return_gerror (invocation, error);
       g_error_free (error);
     }
   else
     {
       print_debug (" success");
-      reply = dbus_message_new_method_return (message);
+      gvfs_remote_volume_monitor_complete_drive_eject (NULL, invocation);
     }
-
-  dbus_connection_send (connection, reply, NULL);
-  dbus_message_unref (message);
-  dbus_message_unref (reply);
+  g_object_unref (invocation);
 }
 
-static DBusHandlerResult
-handle_drive_eject (DBusConnection *connection, DBusMessage *message)
+static gboolean
+handle_drive_eject (GVfsRemoteVolumeMonitor *object,
+                    GDBusMethodInvocation *invocation,
+                    const gchar *arg_id,
+                    const gchar *arg_cancellation_id,
+                    guint arg_unmount_flags,
+                    const gchar *arg_mount_op_id,
+                    gpointer user_data)
 {
-  const char *id;
-  const char *cancellation_id;
   const char *sender;
-  const char *mount_op_id;
   GMountOperation *mount_operation;
   GCancellable *cancellable;
-  dbus_uint32_t unmount_flags;
-  DBusError dbus_error;
   GList *drives, *l;
   GDrive *drive;
-  DBusHandlerResult ret;
-
-  drive = NULL;
-  drives = NULL;
-  unmount_flags = 0;
-  ret = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
-
-  dbus_error_init (&dbus_error);
-  if (!dbus_message_get_args (message, &dbus_error,
-                              DBUS_TYPE_STRING, &id,
-                              DBUS_TYPE_STRING, &cancellation_id,
-                              DBUS_TYPE_UINT32, &unmount_flags,
-                              DBUS_TYPE_STRING, &mount_op_id,
-                              DBUS_TYPE_INVALID))
-    {
-      g_warning ("Error parsing args for DriveEject(): %s: %s", dbus_error.name, dbus_error.message);
-      dbus_error_free (&dbus_error);
-      goto out;
-    }
 
   print_debug ("in handle_drive_eject");
 
-  ret = DBUS_HANDLER_RESULT_HANDLED;
-
-  sender = dbus_message_get_sender (message);
+  sender = g_dbus_method_invocation_get_sender (invocation);
 
   drive = NULL;
   drives = g_volume_monitor_get_connected_drives (monitor);
@@ -1255,7 +1220,7 @@ handle_drive_eject (DBusConnection *connection, DBusMessage *message)
 
       drive = G_DRIVE (l->data);
       drive_id = g_strdup_printf ("%p", drive);
-      if (strcmp (drive_id, id) == 0)
+      if (strcmp (drive_id, arg_id) == 0)
         break;
 
       g_free (drive_id);
@@ -1265,48 +1230,42 @@ handle_drive_eject (DBusConnection *connection, DBusMessage *message)
 
   if (drive == NULL)
     {
-      DBusMessage *reply;
-      reply = dbus_message_new_error (message,
-                                      "org.gtk.Private.RemoteVolumeMonitor.NotFound",
-                                      "The given drive was not found");
-      dbus_connection_send (connection, reply, NULL);
-      dbus_message_unref (reply);
+      g_dbus_method_invocation_return_dbus_error (invocation,
+                                                  "org.gtk.Private.RemoteVolumeMonitor.NotFound",
+                                                  "The given drive was not found");
       goto out;
     }
 
   if (g_object_get_data (G_OBJECT (drive), "cancellable") != NULL)
     {
-      DBusMessage *reply;
-      reply = dbus_message_new_error (message,
-                                      "org.gtk.Private.RemoteVolumeMonitor.Failed",
-                                      "An operation is already pending");
-      dbus_connection_send (connection, reply, NULL);
-      dbus_message_unref (reply);
+      g_dbus_method_invocation_return_dbus_error (invocation,
+                                                  "org.gtk.Private.RemoteVolumeMonitor.Failed",
+                                                  "An operation is already pending");
       goto out;
     }
 
   cancellable = g_cancellable_new ();
   g_object_set_data_full (G_OBJECT (drive), "cancellable", cancellable, g_object_unref);
   g_object_set_data_full (G_OBJECT (cancellable), "owner", g_strdup (sender), g_free);
-  g_object_set_data_full (G_OBJECT (cancellable), "cancellation_id", g_strdup (cancellation_id), g_free);
+  g_object_set_data_full (G_OBJECT (cancellable), "cancellation_id", g_strdup (arg_cancellation_id), g_free);
   outstanding_ops = g_list_prepend (outstanding_ops, cancellable);
   g_object_weak_ref (G_OBJECT (cancellable),
                      cancellable_destroyed_cb,
                      NULL);
 
   mount_operation = NULL;
-  if (mount_op_id != NULL && strlen (mount_op_id) > 0)
+  if (arg_mount_op_id != NULL && strlen (arg_mount_op_id) > 0)
     {
-      mount_operation = wrap_mount_op (mount_op_id, sender);
+      mount_operation = wrap_mount_op (arg_mount_op_id, sender, object);
       g_object_set_data_full (G_OBJECT (drive), "mount_operation", mount_operation, g_object_unref);
     }
 
   g_drive_eject_with_operation (drive,
-                                unmount_flags,
+                                arg_unmount_flags,
                                 mount_operation,
                                 cancellable,
                                 (GAsyncReadyCallback) drive_eject_cb,
-                                dbus_message_ref (message));
+                                g_object_ref (invocation));
 
  out:
   if (drives != NULL)
@@ -1314,16 +1273,15 @@ handle_drive_eject (DBusConnection *connection, DBusMessage *message)
       g_list_foreach (drives, (GFunc) g_object_unref, NULL);
       g_list_free (drives);
     }
-  return ret;
+  return TRUE;
 }
 
 /* ---------------------------------------------------------------------------------------------------- */
 
 static void
-drive_stop_cb (GDrive *drive, GAsyncResult *result, DBusMessage *message)
+drive_stop_cb (GDrive *drive, GAsyncResult *result, GDBusMethodInvocation *invocation)
 {
   GError *error;
-  DBusMessage *reply;
 
   print_debug ("in drive_stop_cb");
 
@@ -1334,58 +1292,35 @@ drive_stop_cb (GDrive *drive, GAsyncResult *result, DBusMessage *message)
   if (!g_drive_stop_finish (drive, result, &error))
     {
       print_debug ("  error: %s", error->message);
-      reply = _dbus_message_new_from_gerror (message, error);
+      g_dbus_method_invocation_return_gerror (invocation, error);
       g_error_free (error);
     }
   else
     {
       print_debug (" success");
-      reply = dbus_message_new_method_return (message);
+      gvfs_remote_volume_monitor_complete_drive_stop (NULL, invocation);
     }
-
-  dbus_connection_send (connection, reply, NULL);
-  dbus_message_unref (message);
-  dbus_message_unref (reply);
+  g_object_unref (invocation);
 }
 
-static DBusHandlerResult
-handle_drive_stop (DBusConnection *connection, DBusMessage *message)
+static gboolean
+handle_drive_stop (GVfsRemoteVolumeMonitor *object,
+                   GDBusMethodInvocation *invocation,
+                   const gchar *arg_id,
+                   const gchar *arg_cancellation_id,
+                   guint arg_unmount_flags,
+                   const gchar *arg_mount_op_id,
+                   gpointer user_data)
 {
-  const char *id;
-  const char *cancellation_id;
   const char *sender;
-  const char *mount_op_id;
   GMountOperation *mount_operation;
   GCancellable *cancellable;
-  dbus_uint32_t unmount_flags;
-  DBusError dbus_error;
   GList *drives, *l;
   GDrive *drive;
-  DBusHandlerResult ret;
-
-  drive = NULL;
-  drives = NULL;
-  unmount_flags = 0;
-  ret = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
-
-  dbus_error_init (&dbus_error);
-  if (!dbus_message_get_args (message, &dbus_error,
-                              DBUS_TYPE_STRING, &id,
-                              DBUS_TYPE_STRING, &cancellation_id,
-                              DBUS_TYPE_UINT32, &unmount_flags,
-                              DBUS_TYPE_STRING, &mount_op_id,
-                              DBUS_TYPE_INVALID))
-    {
-      g_warning ("Error parsing args for DriveStop(): %s: %s", dbus_error.name, dbus_error.message);
-      dbus_error_free (&dbus_error);
-      goto out;
-    }
 
   print_debug ("in handle_drive_stop");
 
-  ret = DBUS_HANDLER_RESULT_HANDLED;
-
-  sender = dbus_message_get_sender (message);
+  sender = g_dbus_method_invocation_get_sender (invocation);
 
   drive = NULL;
   drives = g_volume_monitor_get_connected_drives (monitor);
@@ -1395,7 +1330,7 @@ handle_drive_stop (DBusConnection *connection, DBusMessage *message)
 
       drive = G_DRIVE (l->data);
       drive_id = g_strdup_printf ("%p", drive);
-      if (strcmp (drive_id, id) == 0)
+      if (strcmp (drive_id, arg_id) == 0)
         break;
 
       g_free (drive_id);
@@ -1405,48 +1340,42 @@ handle_drive_stop (DBusConnection *connection, DBusMessage *message)
 
   if (drive == NULL)
     {
-      DBusMessage *reply;
-      reply = dbus_message_new_error (message,
-                                      "org.gtk.Private.RemoteVolumeMonitor.NotFound",
-                                      "The given drive was not found");
-      dbus_connection_send (connection, reply, NULL);
-      dbus_message_unref (reply);
+      g_dbus_method_invocation_return_dbus_error (invocation,
+                                                  "org.gtk.Private.RemoteVolumeMonitor.NotFound",
+                                                  "The given drive was not found");
       goto out;
     }
 
   if (g_object_get_data (G_OBJECT (drive), "cancellable") != NULL)
     {
-      DBusMessage *reply;
-      reply = dbus_message_new_error (message,
-                                      "org.gtk.Private.RemoteVolumeMonitor.Failed",
-                                      "An operation is already pending");
-      dbus_connection_send (connection, reply, NULL);
-      dbus_message_unref (reply);
+      g_dbus_method_invocation_return_dbus_error (invocation,
+                                                  "org.gtk.Private.RemoteVolumeMonitor.Failed",
+                                                  "An operation is already pending");
       goto out;
     }
 
   cancellable = g_cancellable_new ();
   g_object_set_data_full (G_OBJECT (drive), "cancellable", cancellable, g_object_unref);
   g_object_set_data_full (G_OBJECT (cancellable), "owner", g_strdup (sender), g_free);
-  g_object_set_data_full (G_OBJECT (cancellable), "cancellation_id", g_strdup (cancellation_id), g_free);
+  g_object_set_data_full (G_OBJECT (cancellable), "cancellation_id", g_strdup (arg_cancellation_id), g_free);
   outstanding_ops = g_list_prepend (outstanding_ops, cancellable);
   g_object_weak_ref (G_OBJECT (cancellable),
                      cancellable_destroyed_cb,
                      NULL);
 
   mount_operation = NULL;
-  if (mount_op_id != NULL && strlen (mount_op_id) > 0)
+  if (arg_mount_op_id != NULL && strlen (arg_mount_op_id) > 0)
     {
-      mount_operation = wrap_mount_op (mount_op_id, sender);
+      mount_operation = wrap_mount_op (arg_mount_op_id, sender, object);
       g_object_set_data_full (G_OBJECT (drive), "mount_operation", mount_operation, g_object_unref);
     }
 
   g_drive_stop (drive,
-                unmount_flags,
+                arg_unmount_flags,
                 mount_operation,
                 cancellable,
                 (GAsyncReadyCallback) drive_stop_cb,
-                dbus_message_ref (message));
+                g_object_ref (invocation));
 
  out:
   if (drives != NULL)
@@ -1454,16 +1383,15 @@ handle_drive_stop (DBusConnection *connection, DBusMessage *message)
       g_list_foreach (drives, (GFunc) g_object_unref, NULL);
       g_list_free (drives);
     }
-  return ret;
+  return TRUE;
 }
 
 /* ---------------------------------------------------------------------------------------------------- */
 
 static void
-drive_start_cb (GDrive *drive, GAsyncResult *result, DBusMessage *message)
+drive_start_cb (GDrive *drive, GAsyncResult *result, GDBusMethodInvocation *invocation)
 {
   GError *error;
-  DBusMessage *reply;
 
   print_debug ("in drive_start_cb");
 
@@ -1474,56 +1402,35 @@ drive_start_cb (GDrive *drive, GAsyncResult *result, DBusMessage *message)
   if (!g_drive_start_finish (drive, result, &error))
     {
       print_debug ("  error: %s", error->message);
-      reply = _dbus_message_new_from_gerror (message, error);
+      g_dbus_method_invocation_return_gerror (invocation, error);
       g_error_free (error);
     }
   else
     {
       print_debug (" success");
-      reply = dbus_message_new_method_return (message);
+      gvfs_remote_volume_monitor_complete_drive_start (NULL, invocation);
     }
-
-  dbus_connection_send (connection, reply, NULL);
-  dbus_message_unref (message);
-  dbus_message_unref (reply);
+  g_object_unref (invocation);
 }
 
-static DBusHandlerResult
-handle_drive_start (DBusConnection *connection, DBusMessage *message)
+static gboolean
+handle_drive_start (GVfsRemoteVolumeMonitor *object,
+                    GDBusMethodInvocation *invocation,
+                    const gchar *arg_id,
+                    const gchar *arg_cancellation_id,
+                    guint arg_flags,
+                    const gchar *arg_mount_op_id,
+                    gpointer user_data)
 {
-  const char *id;
-  const char *cancellation_id;
   const char *sender;
-  const char *mount_op_id;
-  GDriveStartFlags flags;
-  DBusError dbus_error;
   GList *drives, *l;
   GDrive *drive;
-  DBusHandlerResult ret;
   GMountOperation *mount_operation;
   GCancellable *cancellable;
 
-  drives = NULL;
-  ret = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
-
-  dbus_error_init (&dbus_error);
-  if (!dbus_message_get_args (message, &dbus_error,
-                              DBUS_TYPE_STRING, &id,
-                              DBUS_TYPE_STRING, &cancellation_id,
-                              DBUS_TYPE_UINT32, &flags,
-                              DBUS_TYPE_STRING, &mount_op_id,
-                              DBUS_TYPE_INVALID))
-    {
-      g_warning ("Error parsing args for DriveStart(): %s: %s", dbus_error.name, dbus_error.message);
-      dbus_error_free (&dbus_error);
-      goto out;
-    }
-
   print_debug ("in handle_drive_start");
 
-  ret = DBUS_HANDLER_RESULT_HANDLED;
-
-  sender = dbus_message_get_sender (message);
+  sender = g_dbus_method_invocation_get_sender (invocation);
 
   drive = NULL;
   drives = g_volume_monitor_get_connected_drives (monitor);
@@ -1533,7 +1440,7 @@ handle_drive_start (DBusConnection *connection, DBusMessage *message)
 
       drive = G_DRIVE (l->data);
       drive_id = g_strdup_printf ("%p", drive);
-      if (strcmp (drive_id, id) == 0)
+      if (strcmp (drive_id, arg_id) == 0)
         break;
 
       g_free (drive_id);
@@ -1543,48 +1450,42 @@ handle_drive_start (DBusConnection *connection, DBusMessage *message)
 
   if (drive == NULL)
     {
-      DBusMessage *reply;
-      reply = dbus_message_new_error (message,
-                                      "org.gtk.Private.RemoteVolumeMonitor.NotFound",
-                                      "The given drive was not found");
-      dbus_connection_send (connection, reply, NULL);
-      dbus_message_unref (reply);
+      g_dbus_method_invocation_return_dbus_error (invocation,
+                                                  "org.gtk.Private.RemoteVolumeMonitor.NotFound",
+                                                  "The given drive was not found");
       goto out;
     }
 
   if (g_object_get_data (G_OBJECT (drive), "cancellable") != NULL)
     {
-      DBusMessage *reply;
-      reply = dbus_message_new_error (message,
-                                      "org.gtk.Private.RemoteVolumeMonitor.Failed",
-                                      "An operation is already pending");
-      dbus_connection_send (connection, reply, NULL);
-      dbus_message_unref (reply);
+      g_dbus_method_invocation_return_dbus_error (invocation,
+                                                  "org.gtk.Private.RemoteVolumeMonitor.Failed",
+                                                  "An operation is already pending");
       goto out;
     }
 
   mount_operation = NULL;
-  if (mount_op_id != NULL && strlen (mount_op_id) > 0)
+  if (arg_mount_op_id != NULL && strlen (arg_mount_op_id) > 0)
     {
-      mount_operation = wrap_mount_op (mount_op_id, sender);
+      mount_operation = wrap_mount_op (arg_mount_op_id, sender, object);
       g_object_set_data_full (G_OBJECT (drive), "mount_operation", mount_operation, g_object_unref);
     }
 
   cancellable = g_cancellable_new ();
   g_object_set_data_full (G_OBJECT (drive), "cancellable", cancellable, g_object_unref);
   g_object_set_data_full (G_OBJECT (cancellable), "owner", g_strdup (sender), g_free);
-  g_object_set_data_full (G_OBJECT (cancellable), "cancellation_id", g_strdup (cancellation_id), g_free);
+  g_object_set_data_full (G_OBJECT (cancellable), "cancellation_id", g_strdup (arg_cancellation_id), g_free);
   outstanding_ops = g_list_prepend (outstanding_ops, cancellable);
   g_object_weak_ref (G_OBJECT (cancellable),
                      cancellable_destroyed_cb,
                      NULL);
 
   g_drive_start (drive,
-                 flags,
+                 arg_flags,
                  mount_operation,
                  cancellable,
                  (GAsyncReadyCallback) drive_start_cb,
-                 dbus_message_ref (message));
+                 g_object_ref (invocation));
 
  out:
   if (drives != NULL)
@@ -1592,16 +1493,15 @@ handle_drive_start (DBusConnection *connection, DBusMessage *message)
       g_list_foreach (drives, (GFunc) g_object_unref, NULL);
       g_list_free (drives);
     }
-  return ret;
+  return TRUE;
 }
 
 /* ---------------------------------------------------------------------------------------------------- */
 
 static void
-drive_poll_for_media_cb (GDrive *drive, GAsyncResult *result, DBusMessage *message)
+drive_poll_for_media_cb (GDrive *drive, GAsyncResult *result, GDBusMethodInvocation *invocation)
 {
   GError *error;
-  DBusMessage *reply;
 
   print_debug ("in drive_poll_for_media_cb");
 
@@ -1611,52 +1511,32 @@ drive_poll_for_media_cb (GDrive *drive, GAsyncResult *result, DBusMessage *messa
   if (!g_drive_poll_for_media_finish (drive, result, &error))
     {
       print_debug ("  error: %s", error->message);
-      reply = _dbus_message_new_from_gerror (message, error);
+      g_dbus_method_invocation_return_gerror (invocation, error);
       g_error_free (error);
     }
   else
     {
       print_debug (" success");
-      reply = dbus_message_new_method_return (message);
+      gvfs_remote_volume_monitor_complete_drive_poll_for_media (NULL, invocation);
     }
-
-  dbus_connection_send (connection, reply, NULL);
-  dbus_message_unref (message);
-  dbus_message_unref (reply);
+  g_object_unref (invocation);
 }
 
-static DBusHandlerResult
-handle_drive_poll_for_media (DBusConnection *connection, DBusMessage *message)
+static gboolean
+handle_drive_poll_for_media (GVfsRemoteVolumeMonitor *object,
+                             GDBusMethodInvocation *invocation,
+                             const gchar *arg_id,
+                             const gchar *arg_cancellation_id,
+                             gpointer user_data)
 {
-  const char *id;
-  const char *cancellation_id;
   const char *sender;
   GCancellable *cancellable;
-  DBusError dbus_error;
   GList *drives, *l;
   GDrive *drive;
-  DBusHandlerResult ret;
-
-  drive = NULL;
-  drives = NULL;
-  ret = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
-
-  dbus_error_init (&dbus_error);
-  if (!dbus_message_get_args (message, &dbus_error,
-                              DBUS_TYPE_STRING, &id,
-                              DBUS_TYPE_STRING, &cancellation_id,
-                              DBUS_TYPE_INVALID))
-    {
-      g_warning ("Error parsing args for DrivePollForMedia(): %s: %s", dbus_error.name, dbus_error.message);
-      dbus_error_free (&dbus_error);
-      goto out;
-    }
 
   print_debug ("in handle_drive_poll_for_media");
 
-  ret = DBUS_HANDLER_RESULT_HANDLED;
-
-  sender = dbus_message_get_sender (message);
+  sender = g_dbus_method_invocation_get_sender (invocation);
 
   drive = NULL;
   drives = g_volume_monitor_get_connected_drives (monitor);
@@ -1666,7 +1546,7 @@ handle_drive_poll_for_media (DBusConnection *connection, DBusMessage *message)
 
       drive = G_DRIVE (l->data);
       drive_id = g_strdup_printf ("%p", drive);
-      if (strcmp (drive_id, id) == 0)
+      if (strcmp (drive_id, arg_id) == 0)
         break;
 
       g_free (drive_id);
@@ -1676,30 +1556,24 @@ handle_drive_poll_for_media (DBusConnection *connection, DBusMessage *message)
 
   if (drive == NULL)
     {
-      DBusMessage *reply;
-      reply = dbus_message_new_error (message,
-                                      "org.gtk.Private.RemoteVolumeMonitor.NotFound",
-                                      "The given drive was not found");
-      dbus_connection_send (connection, reply, NULL);
-      dbus_message_unref (reply);
+      g_dbus_method_invocation_return_dbus_error (invocation,
+                                                  "org.gtk.Private.RemoteVolumeMonitor.NotFound",
+                                                  "The given drive was not found");
       goto out;
     }
 
   if (g_object_get_data (G_OBJECT (drive), "cancellable") != NULL)
     {
-      DBusMessage *reply;
-      reply = dbus_message_new_error (message,
-                                      "org.gtk.Private.RemoteVolumeMonitor.Failed",
-                                      "An operation is already pending");
-      dbus_connection_send (connection, reply, NULL);
-      dbus_message_unref (reply);
+      g_dbus_method_invocation_return_dbus_error (invocation,
+                                                  "org.gtk.Private.RemoteVolumeMonitor.Failed",
+                                                  "An operation is already pending");
       goto out;
     }
 
   cancellable = g_cancellable_new ();
   g_object_set_data_full (G_OBJECT (drive), "cancellable", cancellable, g_object_unref);
   g_object_set_data_full (G_OBJECT (cancellable), "owner", g_strdup (sender), g_free);
-  g_object_set_data_full (G_OBJECT (cancellable), "cancellation_id", g_strdup (cancellation_id), g_free);
+  g_object_set_data_full (G_OBJECT (cancellable), "cancellation_id", g_strdup (arg_cancellation_id), g_free);
   outstanding_ops = g_list_prepend (outstanding_ops, cancellable);
   g_object_weak_ref (G_OBJECT (cancellable),
                      cancellable_destroyed_cb,
@@ -1708,69 +1582,59 @@ handle_drive_poll_for_media (DBusConnection *connection, DBusMessage *message)
   g_drive_poll_for_media (drive,
                           cancellable,
                           (GAsyncReadyCallback) drive_poll_for_media_cb,
-                          dbus_message_ref (message));
-
+                          g_object_ref (invocation));
+  
  out:
   if (drives != NULL)
     {
       g_list_foreach (drives, (GFunc) g_object_unref, NULL);
       g_list_free (drives);
     }
-  return ret;
+  return TRUE;
 }
 
 /* ---------------------------------------------------------------------------------------------------- */
 
-static DBusHandlerResult
-handle_is_supported (DBusConnection *connection, DBusMessage *message)
+static gboolean
+handle_is_supported (GVfsRemoteVolumeMonitor *object,
+                     GDBusMethodInvocation *invocation,
+                     gpointer user_data)
 {
-  dbus_bool_t is_supported;
-  DBusMessage *reply;
-  DBusMessageIter iter;
-
   print_debug ("in handle_supported");
 
   /* if monitor wasn't created on startup; try again */
   if (monitor == NULL)
     monitor_try_create ();
 
-  is_supported = (monitor != NULL);
-
-  reply = dbus_message_new_method_return (message);
-  dbus_message_iter_init_append (reply, &iter);
-  dbus_message_iter_append_basic (&iter, DBUS_TYPE_BOOLEAN, &is_supported);
-  dbus_connection_send (connection, reply, NULL);
-  dbus_message_unref (reply);
-
-  return DBUS_HANDLER_RESULT_HANDLED;
+  if (monitor != NULL)
+    {
+      /* If someone is calling into this object and interface, start watching their name so
+       * we can cancel operations initiated by them when they disconnect
+       */
+      ensure_name_owner_changed_for_unique_name (invocation);
+    }
+  
+  gvfs_remote_volume_monitor_complete_is_supported (object, invocation,
+                                                    monitor != NULL);
+  
+  return TRUE; /* invocation was handled */
 }
 
 /* ---------------------------------------------------------------------------------------------------- */
 
-static DBusHandlerResult
-handle_cancel_operation (DBusConnection *connection, DBusMessage *message)
+static gboolean
+handle_cancel_operation (GVfsRemoteVolumeMonitor *object,
+                         GDBusMethodInvocation *invocation,
+                         const gchar *arg_cancellation_id,
+                         gpointer user_data)
 {
-  DBusMessage *reply;
-  DBusMessageIter iter;
-  DBusError dbus_error;
-  dbus_bool_t was_cancelled;
+  gboolean was_cancelled;
   const char *sender;
-  const char *cancellation_id;
   GList *l;
 
   was_cancelled = FALSE;
 
-  sender = dbus_message_get_sender (message);
-
-  dbus_error_init (&dbus_error);
-  if (!dbus_message_get_args (message, &dbus_error,
-                              DBUS_TYPE_STRING, &cancellation_id,
-                              DBUS_TYPE_INVALID))
-    {
-      g_warning ("Error parsing args for CancelOperation(): %s: %s", dbus_error.name, dbus_error.message);
-      dbus_error_free (&dbus_error);
-      goto out;
-    }
+  sender = g_dbus_method_invocation_get_sender (invocation);
 
   print_debug ("in handle_cancel_operation");
 
@@ -1783,7 +1647,7 @@ handle_cancel_operation (DBusConnection *connection, DBusMessage *message)
 
       owner = g_object_get_data (G_OBJECT (cancellable), "owner");
       id = g_object_get_data (G_OBJECT (cancellable), "cancellation_id");
-      if (g_strcmp0 (owner, sender) == 0 && g_strcmp0 (id, cancellation_id) == 0)
+      if (g_strcmp0 (owner, sender) == 0 && g_strcmp0 (id, arg_cancellation_id) == 0)
         {
           print_debug ("found op to cancel");
           g_cancellable_cancel (cancellable);
@@ -1796,215 +1660,87 @@ handle_cancel_operation (DBusConnection *connection, DBusMessage *message)
   if (!was_cancelled)
     g_warning ("didn't find op to cancel");
 
- out:
-  reply = dbus_message_new_method_return (message);
-  dbus_message_iter_init_append (reply, &iter);
-  dbus_message_iter_append_basic (&iter, DBUS_TYPE_BOOLEAN, &was_cancelled);
-  dbus_connection_send (connection, reply, NULL);
-  dbus_message_unref (reply);
+  gvfs_remote_volume_monitor_complete_cancel_operation (object, invocation, was_cancelled);
 
-  return DBUS_HANDLER_RESULT_HANDLED;
+  return TRUE;
 }
 
 /* ---------------------------------------------------------------------------------------------------- */
 
-static DBusHandlerResult
-filter_function (DBusConnection *connection, DBusMessage *message, void *user_data)
-{
-  DBusHandlerResult ret;
-
-  ret = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
-
-  if (dbus_message_is_signal (message, "org.freedesktop.DBus", "NameLost"))
-    {
-      /* means that someone has claimed our name (we allow replacement) */
-      g_warning ("Got NameLost, some other instance replaced us");
-      exit (0);
-    }
-  else if (dbus_message_is_signal (message, "org.freedesktop.DBus", "NameOwnerChanged"))
-    {
-      DBusMessageIter iter;
-      const gchar *name;
-      const gchar *old_owner;
-      const gchar *new_owner;
-
-      dbus_message_iter_init (message, &iter);
-      dbus_message_iter_get_basic (&iter, &name);
-      dbus_message_iter_next (&iter);
-      dbus_message_iter_get_basic (&iter, &old_owner);
-      dbus_message_iter_next (&iter);
-      dbus_message_iter_get_basic (&iter, &new_owner);
-      dbus_message_iter_next (&iter);
-
-      print_debug ("NameOwnerChanged: '%s' '%s' '%s'", name, old_owner, new_owner);
-
-      if (strlen (new_owner) == 0)
-        {
-          GList *l;
-
-          /* if @name has outstanding mount operation objects; abort them */
-          for (l = outstanding_mount_op_objects; l != NULL; l = l->next)
-            {
-              GMountOperation *op = G_MOUNT_OPERATION (l->data);
-              const gchar *owner;
-
-              owner = g_object_get_data (G_OBJECT (op), "mount_op_owner");
-              if (g_strcmp0 (owner, name) == 0)
-                {
-                  print_debug ("****** name `%s' has an outstanding mount operation object, aborting it",
-                               name);
-                  g_mount_operation_reply (op, G_MOUNT_OPERATION_ABORTED);
-                }
-            }
-
-          /* see if @name has outstanding ops; if so, cancel them */
-          for (l = outstanding_ops; l != NULL; l = l->next)
-            {
-              GCancellable *cancellable = G_CANCELLABLE (l->data);
-              const gchar *owner;
-
-              owner = g_object_get_data (G_OBJECT (cancellable), "owner");
-              print_debug ("looking at op for %s", owner);
-              if (g_strcmp0 (owner, name) == 0)
-                {
-                  print_debug ("****** name `%s' has an outstanding op, cancelling it",
-                               name);
-                  g_cancellable_cancel (cancellable);
-                }
-            }
-
-          remove_name_owned_changed_for_unique_name (name);
-        }
-
-    }
-  else if (g_strcmp0 (dbus_message_get_interface (message), "org.gtk.Private.RemoteVolumeMonitor") == 0 &&
-           g_strcmp0 (dbus_message_get_path (message), "/org/gtk/Private/RemoteVolumeMonitor") == 0)
-    {
-      /* If someone is calling into this object and interface, start watching their name so
-       * we can cancel operations initiated by them when they disconnect
-       */
-      ensure_name_owner_changed_for_unique_name (dbus_message_get_sender (message));
-
-      if (dbus_message_is_method_call (message, "org.gtk.Private.RemoteVolumeMonitor", "IsSupported"))
-        {
-          ret = handle_is_supported (connection, message);
-        }
-      else
-        {
-          if (monitor != NULL)
-            {
-              if (dbus_message_is_method_call (message, "org.gtk.Private.RemoteVolumeMonitor", "List"))
-                ret = handle_list (connection, message);
-
-              else if (dbus_message_is_method_call (message, "org.gtk.Private.RemoteVolumeMonitor", "CancelOperation"))
-                ret = handle_cancel_operation (connection, message);
-
-              else if (dbus_message_is_method_call (message, "org.gtk.Private.RemoteVolumeMonitor", "MountUnmount"))
-                ret = handle_mount_unmount (connection, message);
-
-              else if (dbus_message_is_method_call (message, "org.gtk.Private.RemoteVolumeMonitor", "VolumeMount"))
-                ret = handle_volume_mount (connection, message);
-
-              else if (dbus_message_is_method_call (message, "org.gtk.Private.RemoteVolumeMonitor", "DriveEject"))
-                ret = handle_drive_eject (connection, message);
-
-              else if (dbus_message_is_method_call (message, "org.gtk.Private.RemoteVolumeMonitor", "DrivePollForMedia"))
-                ret = handle_drive_poll_for_media (connection, message);
-
-              else if (dbus_message_is_method_call (message, "org.gtk.Private.RemoteVolumeMonitor", "DriveStart"))
-                ret = handle_drive_start (connection, message);
-
-              else if (dbus_message_is_method_call (message, "org.gtk.Private.RemoteVolumeMonitor", "DriveStop"))
-                ret = handle_drive_stop (connection, message);
-
-              else if (dbus_message_is_method_call (message, "org.gtk.Private.RemoteVolumeMonitor", "MountOpReply"))
-                ret = handle_mount_op_reply (connection, message);
-            }
-        }
-    }
-
-  return ret;
-}
-
-typedef void (*AppendFunc) (void *object, DBusMessageIter *iter);
+typedef GVariant * (*MonitorDBusFunc) (void *object);
+typedef void (*MonitorSignalFunc) (GVfsRemoteVolumeMonitor *object, 
+                                   const gchar *arg_dbus_name,
+                                   const gchar *arg_id,
+                                   GVariant *val);
 
 static void
-emit_signal (DBusConnection *connection, const char *signal_name, void *object, AppendFunc func)
+emit_signal (GVfsRemoteVolumeMonitor *instance, MonitorSignalFunc signal_func, void *object, MonitorDBusFunc func)
 {
   char *id;
-  DBusMessage *message;
-  DBusMessageIter iter;
-
+  GVariant *val;
+  
+  print_debug ("emit_signal: %p", object);
+  
   id = g_strdup_printf ("%p", object);
+  val = func (object);
 
-  message = dbus_message_new_signal ("/org/gtk/Private/RemoteVolumeMonitor",
-                                     "org.gtk.Private.RemoteVolumeMonitor",
-                                     signal_name);
-  dbus_message_iter_init_append (message, &iter);
-  dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &the_dbus_name);
-  dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &id);
-
-  func (object, &iter);
-
-  dbus_connection_send (connection, message, NULL);
-  dbus_message_unref (message);
-
+  signal_func (instance, the_dbus_name, id, val);
 
   g_free (id);
 }
 
 static void
-drive_changed (GVolumeMonitor *monitor, GDrive *drive, DBusConnection *connection)
+drive_changed (GVolumeMonitor *monitor, GDrive *drive, GVfsRemoteVolumeMonitor *instance)
 {
-  emit_signal (connection, "DriveChanged", drive, (AppendFunc) append_drive);
+  emit_signal (instance, (MonitorSignalFunc) gvfs_remote_volume_monitor_emit_drive_changed, drive, (MonitorDBusFunc) drive_to_dbus);
 }
 
 static void
-drive_connected (GVolumeMonitor *monitor, GDrive *drive, DBusConnection *connection)
+drive_connected (GVolumeMonitor *monitor, GDrive *drive, GVfsRemoteVolumeMonitor *instance)
 {
-  emit_signal (connection, "DriveConnected", drive, (AppendFunc) append_drive);
+  emit_signal (instance, (MonitorSignalFunc) gvfs_remote_volume_monitor_emit_drive_connected, drive, (MonitorDBusFunc) drive_to_dbus);
 }
 
 static void
-drive_disconnected (GVolumeMonitor *monitor, GDrive *drive, DBusConnection *connection)
+drive_disconnected (GVolumeMonitor *monitor, GDrive *drive, GVfsRemoteVolumeMonitor *instance)
 {
-  emit_signal (connection, "DriveDisconnected", drive, (AppendFunc) append_drive);
+  emit_signal (instance, (MonitorSignalFunc) gvfs_remote_volume_monitor_emit_drive_disconnected, drive, (MonitorDBusFunc) drive_to_dbus);
 }
 
 static void
-drive_eject_button (GVolumeMonitor *monitor, GDrive *drive, DBusConnection *connection)
+drive_eject_button (GVolumeMonitor *monitor, GDrive *drive, GVfsRemoteVolumeMonitor *instance)
 {
-  emit_signal (connection, "DriveEjectButton", drive, (AppendFunc) append_drive);
+  emit_signal (instance, (MonitorSignalFunc) gvfs_remote_volume_monitor_emit_drive_eject_button, drive, (MonitorDBusFunc) drive_to_dbus);
 }
 
 static void
-drive_stop_button (GVolumeMonitor *monitor, GDrive *drive, DBusConnection *connection)
+drive_stop_button (GVolumeMonitor *monitor, GDrive *drive, GVfsRemoteVolumeMonitor *instance)
 {
-  emit_signal (connection, "DriveStopButton", drive, (AppendFunc) append_drive);
+  emit_signal (instance, (MonitorSignalFunc) gvfs_remote_volume_monitor_emit_drive_stop_button, drive, (MonitorDBusFunc) drive_to_dbus);
 }
 
 static void
-volume_changed (GVolumeMonitor *monitor, GVolume *volume, DBusConnection *connection)
+volume_changed (GVolumeMonitor *monitor, GVolume *volume, GVfsRemoteVolumeMonitor *instance)
 {
-  emit_signal (connection, "VolumeChanged", volume, (AppendFunc) append_volume);
+  emit_signal (instance, (MonitorSignalFunc) gvfs_remote_volume_monitor_emit_volume_changed, volume, (MonitorDBusFunc) volume_to_dbus);
 }
 
 static void
-volume_added (GVolumeMonitor *monitor, GVolume *volume, DBusConnection *connection)
+volume_added (GVolumeMonitor *monitor, GVolume *volume, GVfsRemoteVolumeMonitor *instance)
 {
-  emit_signal (connection, "VolumeAdded", volume, (AppendFunc) append_volume);
+  emit_signal (instance, (MonitorSignalFunc) gvfs_remote_volume_monitor_emit_volume_added, volume, (MonitorDBusFunc) volume_to_dbus);
 }
 
 static void
-volume_removed (GVolumeMonitor *monitor, GVolume *volume, DBusConnection *connection)
+volume_removed (GVolumeMonitor *monitor, GVolume *volume, GVfsRemoteVolumeMonitor *instance)
 {
-  emit_signal (connection, "VolumeRemoved", volume, (AppendFunc) append_volume);
+  emit_signal (instance, (MonitorSignalFunc) gvfs_remote_volume_monitor_emit_volume_removed, volume, (MonitorDBusFunc) volume_to_dbus);
 }
 
 static void
-mount_changed (GVolumeMonitor *monitor, GMount *mount, DBusConnection *connection)
+mount_changed (GVolumeMonitor *monitor, GMount *mount, GVfsRemoteVolumeMonitor *instance)
 {
-  emit_signal (connection, "MountChanged", mount, (AppendFunc) append_mount);
+  emit_signal (instance, (MonitorSignalFunc) gvfs_remote_volume_monitor_emit_mount_changed, mount, (MonitorDBusFunc) mount_to_dbus);
 }
 
 static void
@@ -2016,22 +1752,22 @@ mount_sniff_x_content_type (GMount *mount)
 }
 
 static void
-mount_added (GVolumeMonitor *monitor, GMount *mount, DBusConnection *connection)
+mount_added (GVolumeMonitor *monitor, GMount *mount, GVfsRemoteVolumeMonitor *instance)
 {
   mount_sniff_x_content_type (mount);
-  emit_signal (connection, "MountAdded", mount, (AppendFunc) append_mount);
+  emit_signal (instance, (MonitorSignalFunc) gvfs_remote_volume_monitor_emit_mount_added, mount, (MonitorDBusFunc) mount_to_dbus);
 }
 
 static void
-mount_pre_unmount (GVolumeMonitor *monitor, GMount *mount, DBusConnection *connection)
+mount_pre_unmount (GVolumeMonitor *monitor, GMount *mount, GVfsRemoteVolumeMonitor *instance)
 {
-  emit_signal (connection, "MountPreUnmount", mount, (AppendFunc) append_mount);
+  emit_signal (instance, (MonitorSignalFunc) gvfs_remote_volume_monitor_emit_mount_pre_unmount, mount, (MonitorDBusFunc) mount_to_dbus);
 }
 
 static void
-mount_removed (GVolumeMonitor *monitor, GMount *mount, DBusConnection *connection)
+mount_removed (GVolumeMonitor *monitor, GMount *mount, GVfsRemoteVolumeMonitor *instance)
 {
-  emit_signal (connection, "MountRemoved", mount, (AppendFunc) append_mount);
+  emit_signal (instance, (MonitorSignalFunc) gvfs_remote_volume_monitor_emit_mount_removed, mount, (MonitorDBusFunc) mount_to_dbus);
 }
 
 void
@@ -2049,7 +1785,6 @@ g_vfs_proxy_volume_monitor_daemon_init (void)
   bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
   textdomain (GETTEXT_PACKAGE);
 
-  dbus_threads_init_default ();
   g_type_init ();
 }
 
@@ -2096,17 +1831,89 @@ monitor_try_create (void)
     g_type_class_unref (klass);
 }
 
+static void
+bus_acquired_handler_cb (GDBusConnection *conn,
+                         const gchar *name,
+                         gpointer user_data)
+{
+  GError *error;
+  
+  if (! conn)
+    return;
+
+  monitor_daemon = gvfs_remote_volume_monitor_skeleton_new ();
+  
+  g_signal_connect (monitor_daemon, "handle-is-supported", G_CALLBACK (handle_is_supported), NULL);
+  if (monitor != NULL)
+    {
+      g_signal_connect (monitor_daemon, "handle-list", G_CALLBACK (handle_list), NULL);
+      g_signal_connect (monitor_daemon, "handle-cancel-operation", G_CALLBACK (handle_cancel_operation), NULL);
+      g_signal_connect (monitor_daemon, "handle-drive-eject", G_CALLBACK (handle_drive_eject), NULL);
+      g_signal_connect (monitor_daemon, "handle-drive-poll-for-media", G_CALLBACK (handle_drive_poll_for_media), NULL);
+      g_signal_connect (monitor_daemon, "handle-drive-start", G_CALLBACK (handle_drive_start), NULL);
+      g_signal_connect (monitor_daemon, "handle-drive-stop", G_CALLBACK (handle_drive_stop), NULL);
+      g_signal_connect (monitor_daemon, "handle-mount-op-reply", G_CALLBACK (handle_mount_op_reply), NULL);
+      g_signal_connect (monitor_daemon, "handle-mount-unmount", G_CALLBACK (handle_mount_unmount), NULL);
+      g_signal_connect (monitor_daemon, "handle-volume-mount", G_CALLBACK (handle_volume_mount), NULL);
+    }
+
+  /*  This way we open our d-bus API to public, though there's the "Private" path element  */
+  error = NULL;
+  if (!g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (monitor_daemon), conn,
+                                         "/org/gtk/Private/RemoteVolumeMonitor", &error))
+    {
+      g_printerr ("Error exporting volume monitor: %s (%s, %d)\n",
+                  error->message, g_quark_to_string (error->domain), error->code);
+      g_error_free (error);
+    }
+
+
+  if (monitor != NULL)
+    {
+      g_signal_connect (monitor, "drive-changed", (GCallback) drive_changed, monitor_daemon);
+      g_signal_connect (monitor, "drive-connected", (GCallback) drive_connected, monitor_daemon);
+      g_signal_connect (monitor, "drive-disconnected", (GCallback) drive_disconnected, monitor_daemon);
+      g_signal_connect (monitor, "drive-eject-button", (GCallback) drive_eject_button, monitor_daemon);
+      g_signal_connect (monitor, "drive-stop-button", (GCallback) drive_stop_button, monitor_daemon);
+
+      g_signal_connect (monitor, "volume-changed", (GCallback) volume_changed, monitor_daemon);
+      g_signal_connect (monitor, "volume-added", (GCallback) volume_added, monitor_daemon);
+      g_signal_connect (monitor, "volume-removed", (GCallback) volume_removed, monitor_daemon);
+
+      g_signal_connect (monitor, "mount-changed", (GCallback) mount_changed, monitor_daemon);
+      g_signal_connect (monitor, "mount-added", (GCallback) mount_added, monitor_daemon);
+      g_signal_connect (monitor, "mount-pre-unmount", (GCallback) mount_pre_unmount, monitor_daemon);
+      g_signal_connect (monitor, "mount-removed", (GCallback) mount_removed, monitor_daemon);
+    }
+}
+
+static void
+on_name_lost (GDBusConnection *connection,
+              const gchar     *name,
+              gpointer         user_data)
+{
+  /* means that someone has claimed our name (we allow replacement) */
+  g_main_loop_quit (loop);
+}
+
+static void
+on_name_acquired (GDBusConnection *connection,
+                  const gchar     *name,
+                  gpointer         user_data)
+{
+  /* acquired the name %s on the session message bus */
+}
+
 int
 g_vfs_proxy_volume_monitor_daemon_main (int argc,
                                         char *argv[],
                                         const char *dbus_name,
                                         GType volume_monitor_type)
 {
-  int rc G_GNUC_UNUSED;
   int ret;
-  GMainLoop *loop;
-  DBusError dbus_error;
+  guint name_owner_id;
 
+  name_owner_id = 0;
   ret = 1;
 
   loop = g_main_loop_new (NULL, FALSE);
@@ -2118,69 +1925,31 @@ g_vfs_proxy_volume_monitor_daemon_main (int argc,
 
   the_volume_monitor_type = volume_monitor_type;
   the_dbus_name = dbus_name;
-  unique_names_being_watched = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
+  unique_names_being_watched = g_hash_table_new_full (g_str_hash, g_int_equal, g_free, NULL);
 
   /* try and create the monitor */
   monitor_try_create ();
 
-  dbus_error_init (&dbus_error);
-  connection = dbus_bus_get (DBUS_BUS_SESSION, &dbus_error);
-  if (dbus_error_is_set (&dbus_error))
-    {
-      g_warning ("Cannot connect to session bus: %s: %s", dbus_error.name, dbus_error.message);
-      dbus_error_free (&dbus_error);
-      goto out;
-    }
-
-  _g_dbus_connection_integrate_with_main (connection);
-
-  rc = dbus_bus_request_name (connection,
-                              dbus_name,
-                              DBUS_NAME_FLAG_ALLOW_REPLACEMENT |
-                              DBUS_NAME_FLAG_DO_NOT_QUEUE |
-                              DBUS_NAME_FLAG_REPLACE_EXISTING,
-                              &dbus_error);
-  if (dbus_error_is_set (&dbus_error))
-    {
-      g_warning ("dbus_bus_request_name failed: %s: %s", dbus_error.name, dbus_error.message);
-      dbus_error_free (&dbus_error);
-      goto out;
-    }
-  if (ret != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER)
-    {
-      g_warning ("Cannot become primary owner");
-      goto out;
-    }
-
-  if (!dbus_connection_add_filter (connection, filter_function, NULL, NULL))
-    {
-      g_warning ("Cannot add filter function");
-      goto out;
-    }
-
-  if (monitor != NULL)
-    {
-      g_signal_connect (monitor, "drive-changed", (GCallback) drive_changed, connection);
-      g_signal_connect (monitor, "drive-connected", (GCallback) drive_connected, connection);
-      g_signal_connect (monitor, "drive-disconnected", (GCallback) drive_disconnected, connection);
-      g_signal_connect (monitor, "drive-eject-button", (GCallback) drive_eject_button, connection);
-      g_signal_connect (monitor, "drive-stop-button", (GCallback) drive_stop_button, connection);
-
-      g_signal_connect (monitor, "volume-changed", (GCallback) volume_changed, connection);
-      g_signal_connect (monitor, "volume-added", (GCallback) volume_added, connection);
-      g_signal_connect (monitor, "volume-removed", (GCallback) volume_removed, connection);
-
-      g_signal_connect (monitor, "mount-changed", (GCallback) mount_changed, connection);
-      g_signal_connect (monitor, "mount-added", (GCallback) mount_added, connection);
-      g_signal_connect (monitor, "mount-pre-unmount", (GCallback) mount_pre_unmount, connection);
-      g_signal_connect (monitor, "mount-removed", (GCallback) mount_removed, connection);
-    }
-
+  name_owner_id = g_bus_own_name (G_BUS_TYPE_SESSION,
+                                  dbus_name,
+                                  G_BUS_NAME_OWNER_FLAGS_ALLOW_REPLACEMENT |
+                                  G_BUS_NAME_OWNER_FLAGS_REPLACE,
+                                  bus_acquired_handler_cb,
+                                  on_name_acquired,
+                                  on_name_lost,
+                                  NULL,
+                                  NULL);
   g_main_loop_run (loop);
-  g_main_loop_unref (loop);
 
   ret = 0;
 
 out:
+  if (name_owner_id != 0)
+    g_bus_unown_name (name_owner_id);
+  if (loop != NULL)
+    g_main_loop_unref (loop);
+  if (unique_names_being_watched)
+    g_hash_table_unref (unique_names_being_watched);
+
   return ret;
 }



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