Index: gvfs-1.5.1/configure.ac
===================================================================
--- gvfs-1.5.1.orig/configure.ac
+++ gvfs-1.5.1/configure.ac
@@ -46,6 +46,10 @@ PKG_CHECK_MODULES(GLIB, glib-2.0 >= 2.21
 
 PKG_CHECK_MODULES(DBUS, dbus-1)
 
+PKG_CHECK_MODULES(DBUS_GLIB, dbus-glib-1)
+AC_SUBST(DBUS_GLIB_CFLAGS)
+AC_SUBST(DBUS_GLIB_LIBS)
+
 AC_ARG_WITH(dbus_service_dir, [  --with-dbus-service-dir=PATH choose directory for dbus service files, [default=PREFIX/share/dbus-1/services]], with_dbus_service_dir="$withval", with_dbus_service_dir=$datadir/dbus-1/services)
 DBUS_SERVICE_DIR=$with_dbus_service_dir
 AC_SUBST(DBUS_SERVICE_DIR)
Index: gvfs-1.5.1/daemon/dice.mount.in
===================================================================
--- /dev/null
+++ gvfs-1.5.1/daemon/dice.mount.in
@@ -0,0 +1,6 @@
+[Mount]
+Type=dice
+Exec=@libexecdir@/gvfsd-dice
+AutoMount=true
+DBusName=org.gtk.vfs.mountpoint.dice
+
Index: gvfs-1.5.1/daemon/gvfsbackenddice.c
===================================================================
--- /dev/null
+++ gvfs-1.5.1/daemon/gvfsbackenddice.c
@@ -0,0 +1,1989 @@
+/* Novell DICE Backend for GVfs
+ * 
+ * Copyright (C) 2008 Novell, 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:	Boyd Timothy <btimothy@novell.com>
+ *			Brady Anderson <banderso@novell.com>
+ */
+
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/wait.h>
+#include <errno.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <glib/gstdio.h>
+#include <glib/gi18n.h>
+#include <glib/gprintf.h>
+#include <gio/gio.h>
+#include <gio/gunixmounts.h>
+#include <glib/gurifuncs.h>
+
+#include <dbus/dbus-glib.h>
+
+#include <time.h>
+
+#include "gvfsbackenddice.h"
+#include "gvfsmonitor.h"
+#include "gvfsjobopenforread.h"
+#include "gvfsjobread.h"
+#include "gvfsjobseekread.h"
+#include "gvfsjobopenforwrite.h"
+#include "gvfsjobwrite.h"
+#include "gvfsjobclosewrite.h"
+#include "gvfsjobseekwrite.h"
+#include "gvfsjobsetdisplayname.h"
+#include "gvfsjobqueryinfo.h"
+#include "gvfsjobdelete.h"
+#include "gvfsjobqueryfsinfo.h"
+#include "gvfsjobqueryattributes.h"
+#include "gvfsjobenumerate.h"
+#include "gvfsjobcreatemonitor.h"
+#include "gvfsdaemonprotocol.h"
+#include "gvfsdaemonutils.h"
+
+#define G_FILE_ATTRIBUTE_DICE_LOCAL_PATH "dice::local-path"
+#define G_FILE_ATTRIBUTE_DICE_ID "dice::id"
+
+static void lose (const char *fmt, ...) G_GNUC_NORETURN G_GNUC_PRINTF (1, 2);
+static void lose_gerror (const char *prefix, GError *error) G_GNUC_NORETURN;
+static GFileInfo *create_file_info_from_dbus_array(GValueArray *array_obj);
+
+struct _GVfsBackendDice
+{
+	GVfsBackend parent_instance;
+	DBusGConnection *dbus_connection;
+	DBusGProxy *dice_proxy;
+
+	GMountSpec *mount_spec;
+	GList *top_files; /* Files in toplevel dir */
+	guint num_top_files;
+};
+
+struct DiceHandle
+{
+	char *file_path;
+	GFileInputStream *input_stream;
+	GFileOutputStream *output_stream;
+} *PDiceHandle;
+
+G_DEFINE_TYPE (GVfsBackendDice, g_vfs_backend_dice, G_VFS_TYPE_BACKEND)
+
+#define DBUS_STRUCT_STRING_STRING_STRING (dbus_g_type_get_struct ("GValueArray", G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INVALID))
+
+static void
+g_vfs_backend_dice_init (GVfsBackendDice *ice_backend)
+{
+	g_print ("(dice) g_vfs_backend_dice_init \n");
+	GVfsBackendDice *backend = G_VFS_BACKEND_DICE (ice_backend);
+	backend->dbus_connection = NULL;
+	
+	DBusGConnection *connection;
+	GError *error;
+	DBusGProxy *dice_proxy;
+	
+	g_printf(" (dice) connecting to the ICE Daemon via DBus...\n");
+	
+	error = NULL;
+	connection = dbus_g_bus_get (DBUS_BUS_SESSION, &error);
+	if (connection == NULL)
+	{
+		g_printerr (
+			"Failed to open connection to bus: %s\n",
+			error->message);
+		g_error_free (error);
+		exit (1);
+	}
+	
+	g_printf("  (dice) got a connection to the session bus\n");
+	backend->dbus_connection = connection;
+	
+	dice_proxy = 
+		dbus_g_proxy_new_for_name (
+			backend->dbus_connection,
+			"Novell.ICEDesktop.Daemon",
+			"/Novell/ICEDesktop/Daemon",
+			"Novell.ICEDesktop.Daemon");
+			
+	gboolean ping_successful;
+	error = NULL;
+	if (!dbus_g_proxy_call (
+			dice_proxy, 
+			"Ping", 
+			&error,
+			G_TYPE_INVALID, // Input params
+			G_TYPE_BOOLEAN, 
+			&ping_successful, // Output params
+			G_TYPE_INVALID))
+	{
+		lose_gerror ("Could not ping the DICE Daemon", error);
+		exit (-1);
+	}
+	
+	g_printf ("  (dice) connected to the DICE Daemon.\n");
+	backend->dice_proxy = dice_proxy;
+}
+
+static void
+g_vfs_backend_dice_finalize (GObject *object)
+{
+	GVfsBackendDice *dice;
+
+	dice = G_VFS_BACKEND_DICE (object);
+	g_mount_spec_unref (dice->mount_spec);
+	
+	if (G_OBJECT_CLASS (g_vfs_backend_dice_parent_class)->finalize)
+		(*G_OBJECT_CLASS (g_vfs_backend_dice_parent_class)->finalize) (object);
+}
+
+/*********************
+ * Utility Functions *
+ *********************/
+
+
+static void
+lose (const char *str, ...)
+{
+	va_list args;
+	va_start (args, str);
+
+	vfprintf (stderr, str, args);
+	fputc ('\n', stderr);
+
+	va_end (args);
+	exit (1);
+}
+
+
+static void
+lose_gerror (const char *prefix, GError *error)
+{
+	lose ("%s: %s", prefix, error->message);
+}
+
+
+/**
+ * Caller must free using g_free () if not NULL return.
+ */
+/*
+static char *
+get_last_path_component (const char *path)
+{
+	if (path == NULL)
+		return NULL;
+	
+	g_printf ("  (ice) get_last_path_component (%s)\n", path);
+	char *parsable_path = g_strdup (path);
+	char *path_component = NULL;
+	char *last_component = strtok (parsable_path, "/");
+	if (last_component != NULL)
+	{
+		while ((path_component = strtok (NULL, "/")) != NULL)
+		{
+			// Intentionally blank.  Tokenize until we've reached
+			// the last token.
+			last_component = path_component;
+		}
+		
+		// Make a copy of the last component
+		last_component = g_strdup (last_component);
+	}
+	
+	g_free (parsable_path);
+	
+	g_printf("    (ice) get_last_path_component () returning -> '%s'\n", last_component == NULL ? "(null)" : last_component);
+	
+	return last_component;
+}
+*/
+
+
+/*
+G_IO_ERROR_FAILED,             EIO          },
+      { G_IO_ERROR_NOT_FOUND,          ENOENT       },
+      { G_IO_ERROR_EXISTS,             EEXIST       },
+      { G_IO_ERROR_IS_DIRECTORY,       EISDIR       },
+      { G_IO_ERROR_NOT_DIRECTORY,      ENOTDIR      },
+      { G_IO_ERROR_NOT_EMPTY,          ENOTEMPTY    },
+      { G_IO_ERROR_NOT_REGULAR_FILE,   EIO          },
+      { G_IO_ERROR_NOT_SYMBOLIC_LINK,  EIO          },
+      { G_IO_ERROR_NOT_MOUNTABLE_FILE, EIO          },
+      { G_IO_ERROR_FILENAME_TOO_LONG,  ENAMETOOLONG },
+      { G_IO_ERROR_INVALID_FILENAME,   EIO          },
+      { G_IO_ERROR_TOO_MANY_LINKS,     ELOOP        },
+      { G_IO_ERROR_NO_SPACE,           ENOSPC       },
+      { G_IO_ERROR_INVALID_ARGUMENT,   EINVAL       },
+      { G_IO_ERROR_PERMISSION_DENIED,  EACCES       },
+      { G_IO_ERROR_NOT_SUPPORTED,      ENOTSUP      },
+      { G_IO_ERROR_NOT_MOUNTED,        EIO          },
+      { G_IO_ERROR_ALREADY_MOUNTED,    EIO          },
+      { G_IO_ERROR_CLOSED,             EIO          },
+      { G_IO_ERROR_CANCELLED,          EIO          },
+      { G_IO_ERROR_PENDING,            EIO          },
+      { G_IO_ERROR_READ_ONLY,          EACCES       },
+      { G_IO_ERROR_CANT_CREATE_BACKUP, EIO          },
+      { G_IO_ERROR_WRONG_ETAG,         EIO          },
+      { G_IO_ERROR_TIMED_OUT,          EIO          },
+      { G_IO_ERROR_BUSY,               EBUSY        },
+      { -1,                            -1           }
+*/
+
+// Method to convert all DICE Exceptions to an
+// equivalent GIO_ERROR.
+// The Exception class is returned and contained
+// in the error->message field.
+GError * convert_dice_error_to_gio_status (GError *dice_error)
+{
+	GError *error;
+	
+	if (strstr (dice_error->message, "PathNotFoundException") != NULL)
+	{
+		error = 
+			g_error_new (
+				G_IO_ERROR, 
+				G_IO_ERROR_NOT_FOUND, 
+				_("No such file or directory"));
+	}
+	else if (strstr (dice_error->message, "NoEntriesException") != NULL)
+	{
+		error = 
+			g_error_new (
+				G_IO_ERROR, 
+				G_IO_ERROR_NOT_FOUND, 
+				_("No such file or directory"));
+	}
+	else if (strstr (dice_error->message, "NoWorkspacesException") != NULL)
+	{
+		error = 
+			g_error_new (
+				G_IO_ERROR, 
+				G_IO_ERROR_NOT_FOUND, 
+				_("No such file or directory"));
+	}
+	else if (strstr (dice_error->message, "NoFoldersException") != NULL)
+	{
+		error = 
+			g_error_new (
+				G_IO_ERROR, 
+				G_IO_ERROR_NOT_FOUND, 
+				_("No such file or directory"));
+	}
+	else if (strstr (dice_error->message, "NoFolderEntriesException") != NULL)
+	{
+		error = 
+			g_error_new (
+				G_IO_ERROR, 
+				G_IO_ERROR_NOT_FOUND, 
+				_("No such file or directory"));
+	}
+	else if (strstr (dice_error->message, "NoFileEntriesException") != NULL)
+	{
+		error = 
+			g_error_new (
+				G_IO_ERROR, 
+				G_IO_ERROR_NOT_FOUND, 
+				_("No such file or directory"));
+	}
+	else if (strstr (dice_error->message, "FolderNotFoundException") != NULL)
+	{
+		error = 
+			g_error_new (
+				G_IO_ERROR, 
+				G_IO_ERROR_NOT_FOUND, 
+				_("No such file or directory"));
+	}
+	else if (strstr (dice_error->message, "FileNotFoundException") != NULL)
+	{
+		error = 
+			g_error_new (
+				G_IO_ERROR, 
+				G_IO_ERROR_NOT_FOUND, 
+				_("No such file or directory"));
+	}
+	else if (strstr (dice_error->message, "NotAFolderException") != NULL)
+	{
+		error = 
+			g_error_new (
+				G_IO_ERROR, 
+				G_IO_ERROR_NOT_DIRECTORY, 
+				_("is not a directory"));
+		error->code = G_IO_ERROR_NOT_DIRECTORY;
+	}
+	else if (strstr (dice_error->message, "NotAFileException") != NULL)
+	{
+		error = 
+			g_error_new (
+				G_IO_ERROR, 
+				G_IO_ERROR_NOT_REGULAR_FILE, 
+				_("is not a file"));
+	}
+	else if (strstr (error->message, "NotAuthenticatedException") != NULL)
+	{
+		error = 
+			g_error_new (
+				G_IO_ERROR, 
+				G_IO_ERROR_PERMISSION_DENIED, 
+				_("Access denied"));
+	}
+	else if (strstr (dice_error->message, "FailedAuthenticationException") != NULL)
+	{
+		error = 
+			g_error_new (
+				G_IO_ERROR, 
+				G_IO_ERROR_PERMISSION_DENIED, 
+				_("Access denied"));
+	}
+	else if (strstr (dice_error->message, "DiskFullException") != NULL)
+	{
+		error = 
+			g_error_new (
+				G_IO_ERROR, 
+				G_IO_ERROR_NO_SPACE, 
+				_("No available space"));
+	}
+	else
+	{
+		error = 
+			g_error_new (
+				G_IO_ERROR, 
+				G_IO_ERROR_FAILED, 
+				_("General failure"));
+	}
+
+	return error;
+}
+
+static GFileInfo *
+create_file_info_from_dbus_array (GValueArray *array_obj)
+{
+	g_printf ("  ***   create_file_info_from_dbus_array ()  ***\n");
+	
+	if (array_obj == NULL) return NULL;
+	
+	GFileInfo *info = g_file_info_new ();
+	
+	GValue *file_id				= g_value_array_get_nth (array_obj, 0);
+	GValue *file_display_name	= g_value_array_get_nth (array_obj, 1);
+	GValue *file_path			= g_value_array_get_nth (array_obj, 2);
+	GValue *file_local_path		= g_value_array_get_nth (array_obj, 3);
+	GValue *file_type			= g_value_array_get_nth (array_obj, 4);
+	GValue *mime_type			= g_value_array_get_nth (array_obj, 5);
+	GValue *file_access_mask	= g_value_array_get_nth (array_obj, 6);
+	GValue *creation_time		= g_value_array_get_nth (array_obj, 7);
+	GValue *last_access_time	= g_value_array_get_nth (array_obj, 8);
+	GValue *last_modified_time	= g_value_array_get_nth (array_obj, 9);
+	GValue *size				= g_value_array_get_nth (array_obj, 10);
+	GValue *hidden				= g_value_array_get_nth (array_obj, 11);
+	
+	g_printf (" *** read a file info ***\n");
+	g_printf ("\t           ID: %s\n", g_value_get_string (file_id));
+	g_printf ("\t Display Name: %s\n", g_value_get_string (file_display_name));
+	g_printf ("\t         Path: %s\n", g_value_get_string (file_path));
+	g_printf ("\t   Local Path: %s\n", g_value_get_string (file_local_path));
+	
+	struct tm *tmp_time;
+	char timestr[200];
+	gint64 creationDateInSecondsFromEpoch = g_value_get_int64 (creation_time);
+	g_printf("timestamp: %lld\n", creationDateInSecondsFromEpoch); 
+	tmp_time = localtime ((time_t *)&creationDateInSecondsFromEpoch);
+	if (strftime(timestr, sizeof (timestr), "%F %T", tmp_time) != 0)
+	{
+		g_printf ("\t\tCreation Time: %s\n", timestr);
+	}
+
+	gint64 modifiedDateInSecondsFromEpoch = g_value_get_int64 (last_modified_time);
+	g_printf("timestamp: %lld\n", modifiedDateInSecondsFromEpoch); 
+	tmp_time = localtime ((time_t *)&modifiedDateInSecondsFromEpoch);
+	if (strftime(timestr, sizeof (timestr), "%F %T", tmp_time) != 0)
+	{
+		g_printf ("\t\tModifed Time: %s\n", timestr);
+	}
+	
+	// Set the name, display name and the unique id
+	g_file_info_set_name (info, g_value_get_string (file_display_name));
+	g_file_info_set_display_name (info, g_value_get_string (file_display_name));
+	g_file_info_set_attribute_string (info, G_FILE_ATTRIBUTE_ID_FILE, g_value_get_string (file_id));
+	
+	switch (g_value_get_int (file_type))
+	{
+		case 2:
+		case 3:
+			g_printf ("\t\tType: Directory\n");
+			gvfs_file_info_populate_content_types (info, g_value_get_string (file_path), G_FILE_TYPE_DIRECTORY);
+			g_file_info_set_content_type (info, "inode/directory");
+			g_file_info_set_size (info, 4096);
+			break;
+			
+		case 4:
+			g_printf ("\t\tType: Regular\n");
+			gvfs_file_info_populate_content_types (info, g_value_get_string (file_path), G_FILE_TYPE_REGULAR);
+			
+			// Store the local path in the file info
+			g_printf ("\t\tLocal Path: %s\n", g_value_get_string (file_local_path));
+			g_file_info_set_attribute_string (info, G_FILE_ATTRIBUTE_DICE_LOCAL_PATH, g_value_get_string (file_local_path));
+			
+			// File size
+			g_printf ("\t\tFile Size: %lu\n", g_value_get_uint64 (size));
+			g_file_info_set_size (info, g_value_get_uint64 (size));
+			
+			// Mime type
+			g_printf ("\t\tMime Type: %s\n", g_value_get_string (mime_type));
+			g_file_info_set_content_type (info, g_value_get_string (mime_type));
+
+			g_file_info_set_attribute_boolean (info, G_FILE_ATTRIBUTE_ACCESS_CAN_READ, TRUE);
+			g_file_info_set_attribute_boolean (info, G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE, TRUE);
+			//g_file_info_set_attribute_boolean (info, G_FILE_ATTRIBUTE_ACCESS_CAN_EXECUTE, TRUE);
+			g_file_info_set_attribute_boolean (info, G_FILE_ATTRIBUTE_ACCESS_CAN_DELETE, TRUE);
+			g_file_info_set_attribute_boolean (info, G_FILE_ATTRIBUTE_ACCESS_CAN_TRASH, TRUE);
+			g_file_info_set_attribute_boolean (info, G_FILE_ATTRIBUTE_ACCESS_CAN_RENAME, TRUE);
+
+			break;
+			
+		default:
+			g_printf ("\t\tType: Unknown\n");
+			gvfs_file_info_populate_content_types (info, g_value_get_string (file_path), G_FILE_TYPE_UNKNOWN);
+			break;
+	}
+	
+	// File Access
+
+/*
+	uint access_mask = g_value_get_uint (file_access_mask);
+	g_printf ("\t		Access: %X\n", access_mask);
+	if (access_mask & 1) // Read
+		g_file_info_set_attribute_boolean (info, G_FILE_ATTRIBUTE_ACCESS_CAN_READ, TRUE);
+	else
+		g_file_info_set_attribute_boolean (info, G_FILE_ATTRIBUTE_ACCESS_CAN_READ, FALSE);
+		
+	if (access_mask & 2) // Write
+		g_file_info_set_attribute_boolean (info, G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE, TRUE);
+	else
+		g_file_info_set_attribute_boolean (info, G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE, FALSE);
+	
+	if (access_mask & 4) // Execute
+		g_file_info_set_attribute_boolean (info, G_FILE_ATTRIBUTE_ACCESS_CAN_EXECUTE, TRUE);
+	else
+		g_file_info_set_attribute_boolean (info, G_FILE_ATTRIBUTE_ACCESS_CAN_EXECUTE, FALSE);
+	
+	if (access_mask & 8) // CanDelete
+		g_file_info_set_attribute_boolean (info, G_FILE_ATTRIBUTE_ACCESS_CAN_DELETE, TRUE);
+	else
+		g_file_info_set_attribute_boolean (info, G_FILE_ATTRIBUTE_ACCESS_CAN_DELETE, FALSE);
+	
+	if (access_mask & 16) // CanTrash
+		g_file_info_set_attribute_boolean (info, G_FILE_ATTRIBUTE_ACCESS_CAN_TRASH, TRUE);
+	else
+		g_file_info_set_attribute_boolean (info, G_FILE_ATTRIBUTE_ACCESS_CAN_TRASH, FALSE);
+	
+	if (access_mask && 32) // CanRename
+		g_file_info_set_attribute_boolean (info, G_FILE_ATTRIBUTE_ACCESS_CAN_RENAME, TRUE);
+	else
+		g_file_info_set_attribute_boolean (info, G_FILE_ATTRIBUTE_ACCESS_CAN_RENAME, FALSE);
+		*/
+	
+	// Set the creation and modified times
+	g_file_info_set_attribute_uint64 (info, G_FILE_ATTRIBUTE_TIME_CREATED, creationDateInSecondsFromEpoch);
+	g_file_info_set_attribute_uint64 (info, G_FILE_ATTRIBUTE_TIME_MODIFIED, modifiedDateInSecondsFromEpoch);
+
+	GTimeVal t;
+  	t.tv_sec = modifiedDateInSecondsFromEpoch;
+ 	g_file_info_set_modification_time (info, &t);
+
+	g_file_info_set_is_hidden (info, FALSE);
+	return info;
+}
+
+
+static void enumerate_workspaces (
+	GVfsBackendDice *dice_backend,
+	GVfsJob *job)
+{
+  	GPtrArray *files = NULL;
+	GFileInfo *info;
+	GError *dbus_error = NULL;
+	int dbus_status;
+	
+	g_print ("(dice) enumerate_workspaces - called");
+		
+	// Read in all the workspaces
+	dbus_status =
+		dbus_g_proxy_call (
+			dice_backend->dice_proxy, 
+			"EnumerateWorkspaces", 
+			&dbus_error,
+			// Input params (none)
+			G_TYPE_INVALID,
+			// Output params
+			dbus_g_type_get_collection	 (
+				"GPtrArray", 
+				dbus_g_type_get_struct (
+					"GValueArray",
+					G_TYPE_STRING,		// Id
+					G_TYPE_STRING,		// Display Name
+					G_TYPE_STRING,		// Path
+					G_TYPE_STRING,		// Local Path
+					G_TYPE_INT,			// File Type
+					G_TYPE_STRING,		// Mime Type
+					G_TYPE_UINT,		// Access Mask
+					G_TYPE_INT64,		// Creation Time
+					G_TYPE_INT64,		// Last Access Time
+					G_TYPE_INT64,		// Last Modified Time
+					G_TYPE_UINT64,		// Size
+					G_TYPE_BOOLEAN,		// Hidden
+					G_TYPE_INVALID)),
+			&files,
+			G_TYPE_INVALID);
+	
+	g_print ("dbus_status: %d\n", dbus_status);
+	g_print ("dbus_error: 0x%X\n", dbus_error);
+	
+	if (dbus_status > 0 && dbus_error == NULL)
+	{
+		// You have to say succeeded before you add the infos
+		g_vfs_job_succeeded (G_VFS_JOB (job));
+
+		if (files != NULL)
+		{
+			int i;
+			for (i = 0; i < files->len; i++)
+			{
+				GValueArray *dbus_array_obj = g_ptr_array_index (files, i);
+				if (dbus_array_obj != NULL)
+				{
+					info = create_file_info_from_dbus_array (dbus_array_obj);
+					g_vfs_job_enumerate_add_info (job, info);
+					g_object_unref (info);
+				}
+			}
+			
+			g_ptr_array_free (files, TRUE);
+		}
+		
+		g_vfs_job_enumerate_done (job);
+	}
+	else
+	{
+		if (dbus_error != NULL)
+		{
+			if (strstr(dbus_error->message, "NoEntries") != NULL ||
+				strstr (dbus_error->message, "NoWorkspaces") != NULL ||
+				strstr (dbus_error->message, "NoFolders") != NULL ||
+				strstr (dbus_error->message, "NoFiles") != NULL)
+			{
+				g_printf ("Hit the no more entries case");
+				g_vfs_job_succeeded (G_VFS_JOB (job));
+				g_vfs_job_enumerate_done (job);
+			}
+			else
+			{
+				g_vfs_job_failed (
+					G_VFS_JOB (job),
+					G_IO_ERROR,
+					dbus_error->code,
+					dbus_error->message);
+			}
+		}
+		else
+		{
+			g_vfs_job_failed (
+				G_VFS_JOB (job),
+				G_IO_ERROR,
+				G_IO_ERROR_FAILED,
+				_("Error enumerating a directory"));
+				
+		}
+				
+		g_error_free (dbus_error);
+	}
+		
+	g_print ("(dice) enumerate_workspaces. \n");
+}
+
+
+/**
+ * ???
+ *
+ * Note: The returned object should be freed by the caller.
+ */
+static GFileInfo*
+get_g_file_info_from_dice (
+	GVfsBackendDice *dice_backend,
+	const char *filename,// GFile *file, 
+	const char *attributes, 
+	GFileQueryInfoFlags flags,
+	GVfsJob *job,
+	GError **error)
+{
+	g_printf("*** get_g_file_info_from_dice ()\n");
+	g_printf("\tfilename: %s\n", filename);
+	GError *dbus_error = NULL;
+	GFileInfo *info = NULL;
+	GValueArray *dbus_file_info = NULL;
+		
+	if (strlen (filename) == 1 && filename [0] == '/')
+	{
+		// This is the top-level item that will appear in
+		// Nautilus' sidebar as one of the "Places".
+		info = g_file_info_new ();
+		g_file_info_set_name (info, "/");
+		g_file_info_set_display_name (info, _("DICE"));
+		g_file_info_set_file_type (info, G_FILE_TYPE_DIRECTORY);
+		return info;
+	}
+	
+	// If we make it this far, we're dealing with either a
+	// workspace, a directory, or a file.  Communicate via DBus
+	// to the DICE Daemon to determine the information for the
+	// given path.
+	if (dice_backend->dice_proxy == NULL)
+	{
+		*error = 
+			g_error_new (
+				G_IO_ERROR, 
+				G_IO_ERROR_FAILED, 
+				_("No connection to the DICE daemon"));
+		
+		return NULL;
+	}
+	
+	if (!dbus_g_proxy_call (
+		dice_backend->dice_proxy,
+		"GetFileByPath",
+		&dbus_error,
+		// Input Params
+		G_TYPE_STRING,
+		filename,
+		G_TYPE_INVALID,
+		// Output Params (struct of items)
+		dbus_g_type_get_struct (
+			"GValueArray",
+			G_TYPE_STRING,		// Id
+			G_TYPE_STRING,		// Display Name
+			G_TYPE_STRING,		// Path
+			G_TYPE_STRING,		// Local Path
+			G_TYPE_INT,			// File Type
+			G_TYPE_STRING,		// Mime Type
+			G_TYPE_UINT,		// Access Mask
+			G_TYPE_INT64,		// Creation Time
+			G_TYPE_INT64,		// Last Access Time
+			G_TYPE_INT64,		// Last Modified Time
+			G_TYPE_UINT64,		// Size
+			G_TYPE_BOOLEAN,		// Hidden
+			G_TYPE_INVALID),
+		&dbus_file_info,
+		G_TYPE_INVALID))
+	{
+		*error = convert_dice_error_to_gio_status (dbus_error);
+		g_error_free (dbus_error);
+	}
+	else
+	if (dbus_file_info != NULL)
+	{
+		info = create_file_info_from_dbus_array (dbus_file_info);
+		g_value_array_free (dbus_file_info);
+	}
+	
+	g_printf("     success - returning from get_g_file_info_from_dice\n");
+	return info;
+}
+
+// Caller must free the returned GFileInfo on success
+static GFileInfo*
+create_g_file_info_in_dice (
+	GVfsBackendDice *ice_backend,
+	const char *filename,
+	GError **error)
+{
+	g_printf("*** create_g_file_info_in_dice ()\n");
+	g_printf("\tfilename: %s\n", filename);
+	GFileInfo *info = NULL;
+		
+	GError *dbus_error = NULL;
+	if (ice_backend->dice_proxy == NULL)
+	{
+		if (*error != NULL)
+			*error = 
+				g_error_new (
+					G_IO_ERROR, 
+					G_IO_ERROR_FAILED, 
+					_("No connection to the DICE daemon"));
+				
+		return NULL;
+	}
+	
+	GValueArray *dbus_file_info = NULL;
+	
+	if (!dbus_g_proxy_call (
+			ice_backend->dice_proxy,
+			"CreateLocalFile",
+			&dbus_error,
+			// Input Params
+			G_TYPE_STRING, filename, G_TYPE_INVALID,
+			// Output Params (struct of items)
+			dbus_g_type_get_struct (
+				"GValueArray",
+				G_TYPE_STRING,		// Id
+				G_TYPE_STRING,		// Display Name
+				G_TYPE_STRING,		// Path
+				G_TYPE_STRING,		// Local Path
+				G_TYPE_INT,			// File Type
+				G_TYPE_STRING,		// Mime Type
+				G_TYPE_UINT,		// Access Mask
+				G_TYPE_INT64,		// Creation Time
+				G_TYPE_INT64,		// Last Access Time
+				G_TYPE_INT64,		// Last Modified Time
+				G_TYPE_UINT64,		// Size
+				G_TYPE_BOOLEAN,		// Hidden
+				G_TYPE_INVALID),
+			&dbus_file_info,
+			G_TYPE_INVALID))
+	{
+		if (strstr (dbus_error->message, "Exception:") != NULL)
+		{
+			g_printf ("Could not create file '%s': %s\n", filename, dbus_error->message);
+			dbus_file_info = NULL;
+		}
+
+		// Convert the returned dice error to an equivalent GIO_ERROR
+		*error = convert_dice_error_to_gio_status (dbus_error);		
+		g_error_free (dbus_error);
+	}
+	else
+	if (dbus_file_info != NULL)
+	{
+		info = create_file_info_from_dbus_array (dbus_file_info);
+		g_value_array_free (dbus_file_info);
+	}
+	
+	g_printf("     returning from create_g_file_info_in_dice ()\n");
+	return info;
+}
+
+
+// Returns TRUE if the file was successfully deleted.
+// If FALSE, the caller must free the GError that may be set.
+static gboolean
+delete_local_file_from_dice (
+	GVfsBackendDice *dice_backend,
+	const char *filename,
+	GError **error)
+{
+	GError *dbus_error;
+	g_printf ("*** delete_local_file_from_dice ()\n");
+	g_printf ("\tfilename: %s\n", filename);
+		
+	if (dice_backend->dice_proxy == NULL)
+	{
+		*error = 
+			g_error_new (
+				G_IO_ERROR, 
+				G_IO_ERROR_FAILED, 
+				_("No connection to the DICE daemon"));
+		
+		return FALSE;
+	}
+	
+	if (error != NULL) *error = NULL;
+	
+	dbus_error = NULL;
+	if (!dbus_g_proxy_call (
+			dice_backend->dice_proxy,
+			"DeleteLocalFile",
+			&dbus_error,
+			// Input Params
+			G_TYPE_STRING,
+			filename,
+			G_TYPE_INVALID,
+			G_TYPE_INVALID)) // Output Params (none)
+	{
+		if (strstr(dbus_error->message, "Exception:") != NULL)
+		{
+			g_printf ("Could not delete file '%s': %s\n", filename, dbus_error->message);
+		}
+		else
+		{
+			g_printf ("Could not delete the file '%s'\n", filename);
+			g_printf ("Received an unexpected dbus error: %s\n", dbus_error->message);
+		}
+		
+		*error = convert_dice_error_to_gio_status (dbus_error);
+		g_error_free (dbus_error);
+		return FALSE;
+	}
+	
+	g_printf("     success - returning from delete_local_file_from_dice ()\n");
+	return TRUE;
+}
+
+
+// This should be called any time our provider modifies a
+// file.  Basically any time we close a file handle.  Returns
+// TRUE if the file was updated successfully.  If FALSE, the
+// caller must free the GError that may be set.
+static gboolean
+update_local_file_in_dice (
+	GVfsBackendDice *dice_backend,
+	const char *filename,
+	GError **error)
+{
+	GError *dbus_error;
+	g_printf ("*** update_local_file_in_dice ()\n");
+	g_printf ("\tfilename: %s\n", filename);
+		
+	if (dice_backend->dice_proxy == NULL)
+	{
+		*error = 
+			g_error_new (
+				G_IO_ERROR, 
+				G_IO_ERROR_FAILED, 
+				_("No connection to the DICE daemon"));
+				
+		return FALSE;
+	}
+	
+	if (error != NULL) *error = NULL;
+	
+	dbus_error = NULL;
+	if (!dbus_g_proxy_call (
+			dice_backend->dice_proxy,
+			"UpdateLocalFile",
+			&dbus_error,
+			// Input Params
+			G_TYPE_STRING,
+			filename,
+			G_TYPE_INVALID,
+			G_TYPE_INVALID)) // Output Params (none)
+	{
+		if (strstr(dbus_error->message, "Exception:") != NULL)
+		{
+			g_printf ("Could not update file '%s': %s\n", filename, dbus_error->message);
+		}
+		
+		*error = convert_dice_error_to_gio_status (dbus_error);
+		g_error_free (dbus_error);
+		return FALSE;
+	}
+	
+	g_printf("     success - returning from update_local_file_in_dice ()\n");
+	return TRUE;
+}
+
+//
+// Procedure for calling DICE to retrieve
+// file system information, creating a
+// GFileInfo structure and populating it
+// with the correct information.
+//
+// NOTE! The caller must free the returned
+// GFileInfo data structure
+// 
+static GFileInfo *
+get_g_filesystem_info_from_dice (
+	GVfsBackendDice *dice_backend,
+	GFile *file,
+	const char *attributes,
+	GCancellable *cancellable,
+	GError **error)
+{
+	GError *dbus_error;
+	GValueArray *dbus_filesystem_info = NULL;
+	
+	g_printf ("*** get_g_filesystem_info_from_dice ()\n");
+	//g_printf ("\tfilename: %s\n", filename);
+		
+	if (dice_backend->dice_proxy == NULL)
+	{
+		*error = 
+			g_error_new (
+				G_IO_ERROR, 
+				G_IO_ERROR_FAILED, 
+				_("No connection to the DICE daemon"));
+				
+		return NULL;
+	}
+	
+	if (error != NULL) *error = NULL;
+	
+	dbus_error = NULL;
+	
+	if (!dbus_g_proxy_call (
+		dice_backend->dice_proxy,
+		"GetFileSystemInformation",
+		&dbus_error,
+		// Input Params
+		G_TYPE_STRING,
+		"/",
+		G_TYPE_INVALID,
+		// Output Params (struct of items)
+		dbus_g_type_get_struct (
+			"GValueArray",
+			G_TYPE_STRING,		// Label
+			G_TYPE_INT,			// Attributes (RO,RW)
+			G_TYPE_INT64,		// Total Size (in bytes)
+			G_TYPE_INT64,		// Available Size (in bytes)
+			G_TYPE_INVALID),
+		&dbus_filesystem_info,
+		G_TYPE_INVALID))
+	{
+		if (strstr(dbus_error->message, "Exception:") != NULL)
+		{
+			g_printf ("Could not get file system information '%s'\n", dbus_error->message);
+		}
+		else
+		{
+			g_printf ("Could not call DICE daemon's GetFileSystemInformation ()");
+			g_printf ("Received an unexpected dbus error: %s\n", dbus_error->message);
+		}
+		
+		*error = convert_dice_error_to_gio_status (dbus_error);
+		g_error_free (dbus_error);
+		return NULL;
+	}
+	
+	GValue *label				= g_value_array_get_nth (dbus_filesystem_info, 0);
+	GValue *fsattributes		= g_value_array_get_nth (dbus_filesystem_info, 1);
+	GValue *total_space			= g_value_array_get_nth (dbus_filesystem_info, 2);
+	GValue *available_space		= g_value_array_get_nth (dbus_filesystem_info, 3);
+	
+	GFileInfo *info = g_file_info_new ();
+	if (g_value_get_int (fsattributes) == 1)
+		g_file_info_set_attribute_boolean (info, G_FILE_ATTRIBUTE_FILESYSTEM_READONLY, TRUE);
+	else
+		g_file_info_set_attribute_boolean (info, G_FILE_ATTRIBUTE_FILESYSTEM_READONLY, FALSE);
+
+	gint64 total = 4000000000;
+	gint64 available = 3000000000;
+	
+	g_file_info_set_attribute_uint64 (info, G_FILE_ATTRIBUTE_FILESYSTEM_SIZE,  total);
+	g_file_info_set_attribute_uint64 (info, G_FILE_ATTRIBUTE_FILESYSTEM_FREE, available);
+//	g_file_info_set_attribute_uint64 (info, G_FILE_ATTRIBUTE_FILESYSTEM_SIZE,  g_value_get_int64 (total_space));
+//	g_file_info_set_attribute_uint64 (info, G_FILE_ATTRIBUTE_FILESYSTEM_FREE, g_value_get_int64 (available_space));
+	
+	g_value_array_free (dbus_filesystem_info);
+	return info;
+}
+
+
+/*  returned object should be freed in user's function  */
+static GFile*
+get_g_file_from_local (const char *filename, GVfsJob *job)
+{
+	GVfs *local_vfs;
+	GFile *file = NULL;
+	  
+	local_vfs = g_vfs_get_local ();
+	if (! local_vfs)
+	{
+		g_vfs_job_failed (job,	G_IO_ERROR, G_IO_ERROR_FAILED,
+				"Cannot get local vfs"); 
+	    g_print (" (EE) get_g_file_from_local (filename = '%s'): local_vfs == NULL \n", filename);
+	    return NULL;
+	}
+
+	file = g_vfs_get_file_for_path (local_vfs, filename);
+	if (! file)
+	{
+		g_vfs_job_failed (job,	G_IO_ERROR, G_IO_ERROR_FAILED,
+				"Cannot get file from local vfs"); 
+	    g_print (" (EE) get_g_file_from_local (filename = '%s'): file == NULL \n", filename);
+		return NULL;
+	}
+	return file;
+}
+
+
+/************
+ * Mounting *
+ ************/
+
+static void
+do_mount (
+	GVfsBackend *backend,
+	GVfsJobMount *job,
+	GMountSpec *mount_spec,
+	GMountSource *mount_source,
+	gboolean is_automount)
+{
+	GVfsBackendDice *dice_backend = G_VFS_BACKEND_DICE (backend);
+
+	g_print ("(dice) do_mount \n");
+
+	g_vfs_backend_set_display_name (backend, _("My Spaces"));
+
+	dice_backend->mount_spec = g_mount_spec_new ("dice");
+	g_vfs_backend_set_mount_spec (backend, dice_backend->mount_spec);
+
+	g_vfs_backend_set_icon_name (backend, "network-server");
+
+	g_vfs_job_succeeded (G_VFS_JOB (job));
+}
+
+static void
+do_unmount (GVfsBackend *backend, GVfsJobUnmount *job)
+{
+  GVfsBackendDice *dice_backend;
+
+  g_print ("(dice) do_umount \n");
+
+  dice_backend = G_VFS_BACKEND_DICE (backend);
+  g_mount_spec_unref (dice_backend->mount_spec);
+  g_vfs_job_succeeded (G_VFS_JOB (job));
+}
+
+
+/*******************
+ * Query Functions *
+ *******************/
+
+static void
+do_query_info (
+	GVfsBackend *backend,
+	GVfsJobQueryInfo *job,
+	const char *filename,
+	GFileQueryInfoFlags flags,
+	GFileInfo *info,
+	GFileAttributeMatcher *matcher)
+{
+	GVfsBackendDice *dice_backend = G_VFS_BACKEND_DICE (backend);
+	GFileInfo *info2;
+	GError *error = NULL;
+
+	g_print ("(dice) (filename = %s)\n", filename);
+  
+  	// NOTE! get_g_file_info_from_dice is completing the job on failure
+  	// this needs to change
+	info2 = 
+		get_g_file_info_from_dice (
+			dice_backend, 
+			filename, 
+			/*file,*/ "*", 
+			flags, G_VFS_JOB (job),
+			&error);
+ 	if (info2 != NULL && error == NULL)
+	{
+		g_file_info_copy_into (info2, info);
+		g_object_unref (info2);
+		g_vfs_job_succeeded (G_VFS_JOB (job));
+		g_print ("(dice) do_query_info success. \n");
+	}
+	else
+	{
+		g_printf ("Error code: %d\n", error->code);
+		g_printf ("Error message: %s\n", error->message);
+		g_vfs_job_failed_from_error (G_VFS_JOB (job), error);
+		g_error_free (error);
+		g_print ("(dice) do_query_info failed. \n");
+	}
+}
+
+
+static void
+do_query_fs_info (
+	GVfsBackend *backend,
+	GVfsJobQueryFsInfo *job,
+	const char *filename,
+	GFileInfo *info,
+	GFileAttributeMatcher *attribute_matcher)
+{
+	GFile *file;
+	GFileInfo *info2;
+	GError *error = NULL;
+	
+	g_print ("(dice) do_query_fs_info (filename = %s) \n", filename);
+	file = g_file_new_for_path (filename);
+	if (file != NULL)
+	{
+		info2 = get_g_filesystem_info_from_dice (backend, file, "fs:*", G_VFS_JOB (job)->cancellable, &error);
+		if ((error) || (!info2))
+		{
+			g_print ("  (dice) do_query_fs_info (filename = '%s'): g_file_query_filesystem_info failed: %s \n", filename, error->message);
+			g_vfs_job_failed_from_error (G_VFS_JOB (job), error);
+		}
+		else
+		{
+			g_file_info_copy_into (info2, info);
+			g_object_unref (info2);
+			g_file_info_set_attribute_string (info, G_FILE_ATTRIBUTE_FILESYSTEM_TYPE, "dice");
+			g_vfs_job_succeeded (G_VFS_JOB (job));
+			g_print ("(dice) do_query_fs_info success. \n");
+		}
+		
+		g_object_unref (file);
+	}
+	else
+	{
+		error = g_error_new (G_IO_ERROR, G_IO_ERROR_FAILED, _("Error creating a file info from a path"));
+		g_vfs_job_failed_from_error (G_VFS_JOB (job), error);
+		g_print ("(dice) do_query_fs_info failed - creating a new path. \n");
+	}
+	
+	if (error != NULL) g_error_free (error);
+}
+
+
+static void
+do_enumerate (
+	GVfsBackend *backend,
+	GVfsJobEnumerate *job,
+	const char *filename,
+	GFileAttributeMatcher *attribute_matcher,
+	GFileQueryInfoFlags flags)
+{
+	GVfsBackendDice *dice_backend = G_VFS_BACKEND_DICE (backend);
+  	GPtrArray *files = NULL;
+	GFileInfo *info;
+	GError *dbus_error = NULL;
+	int dbus_status;
+	
+	g_print ("(dice) do_enumerate (filename = %s) \n", filename);
+	
+	if (strlen (filename) == 1 && filename [0] == '/')
+	{
+		g_print("  ---> calling EnumerateWorkspaces ()\n");
+		
+		// Read in all the workspaces
+		dbus_status =
+			dbus_g_proxy_call (
+				dice_backend->dice_proxy, 
+				"EnumerateWorkspaces", 
+				&dbus_error,
+				// Input params (none)
+				G_TYPE_INVALID,
+				// Output params
+				dbus_g_type_get_collection	 (
+					"GPtrArray", 
+					dbus_g_type_get_struct (
+						"GValueArray",
+						G_TYPE_STRING,		// Id
+						G_TYPE_STRING,		// Display Name
+						G_TYPE_STRING,		// Path
+						G_TYPE_STRING,		// Local Path
+						G_TYPE_INT,			// File Type
+						G_TYPE_STRING,		// Mime Type
+						G_TYPE_UINT,		// Access Mask
+						G_TYPE_INT64,		// Creation Time
+						G_TYPE_INT64,		// Last Access Time
+						G_TYPE_INT64,		// Last Modified Time
+						G_TYPE_UINT64,		// Size
+						G_TYPE_BOOLEAN,		// Hidden
+						G_TYPE_INVALID)),
+				&files,
+				G_TYPE_INVALID);
+	}
+	else
+	{
+		g_print("  ---> calling EnumerateFiles ()\n");
+		
+		// Read in the files contained in a specific directory
+		int dbus_status =
+			dbus_g_proxy_call (
+				dice_backend->dice_proxy, 
+				"EnumerateFiles", 
+				&dbus_error,
+				// Input params
+				G_TYPE_STRING, filename,
+				G_TYPE_INVALID,
+				// Output params
+				dbus_g_type_get_collection (
+					"GPtrArray", 
+					dbus_g_type_get_struct (
+						"GValueArray",
+						G_TYPE_STRING,		// Id
+						G_TYPE_STRING,		// Display Name
+						G_TYPE_STRING,		// Path
+						G_TYPE_STRING,		// Local Path
+						G_TYPE_INT,			// File Type
+						G_TYPE_STRING,		// Mime Type
+						G_TYPE_UINT,		// Access Mask
+						G_TYPE_INT64,		// Creation Time
+						G_TYPE_INT64,		// Last Access Time
+						G_TYPE_INT64,		// Last Modified Time
+						G_TYPE_UINT64,		// Size
+						G_TYPE_BOOLEAN,		// Hidden
+						G_TYPE_INVALID)),
+				&files,
+				G_TYPE_INVALID);
+				
+	}
+	
+	g_print ("  ---- EnumerateFiles () out of dbus call\n");
+	g_print ("dbus_status: %d\n", dbus_status);
+	g_print ("dbus_error: 0x%X\n", dbus_error);
+	
+	if (dbus_status > 0 && dbus_error == NULL)
+	{
+		// You have to say succeeded before you add the infos
+		g_vfs_job_succeeded (G_VFS_JOB (job));
+
+		if (files != NULL)
+		{
+			int i;
+			for (i = 0; i < files->len; i++)
+			{
+				GValueArray *dbus_array_obj = g_ptr_array_index (files, i);
+				if (dbus_array_obj != NULL)
+				{
+					info = create_file_info_from_dbus_array (dbus_array_obj);
+					g_vfs_job_enumerate_add_info (job, info);
+					g_object_unref (info);
+				}
+			}
+			
+			g_ptr_array_free (files, TRUE);
+		}
+		
+		g_vfs_job_enumerate_done (job);
+	}
+	else
+	{
+		if (dbus_error != NULL)
+		{
+			if (strstr (dbus_error->message, "NoEntries") != NULL ||
+				strstr (dbus_error->message, "NoWorkspaces") != NULL ||
+				strstr (dbus_error->message, "NoFolders") != NULL ||
+				strstr (dbus_error->message, "NoFiles") != NULL)
+			{
+				g_printf ("Hit the no more entries case");
+				g_vfs_job_succeeded (G_VFS_JOB (job));
+				g_vfs_job_enumerate_done (job);
+			}
+			else
+			{
+				GError *error = convert_dice_error_to_gio_status (dbus_error);		
+				g_vfs_job_failed_from_error (G_VFS_JOB (job), error);
+				g_error_free (error);
+			}
+		}
+		else
+		{
+			g_vfs_job_failed (
+				G_VFS_JOB (job),
+				G_IO_ERROR,
+				G_IO_ERROR_FAILED,
+				_("Error enumerating a directory"));
+				
+		}
+				
+		g_error_free (dbus_error);
+	}
+		
+	g_print ("(dice) do_enumerate done. \n");
+}
+
+
+/******************
+ * Read Functions *
+ ******************/
+
+static void
+do_open_for_read (
+	GVfsBackend *backend,
+	GVfsJobOpenForRead *job,
+	const char *filename)
+{
+	GVfsBackendDice *dice_backend = G_VFS_BACKEND_DICE (backend);
+	struct DiceHandle *dice_handle;
+	GFileInputStream *stream;
+	GError *error = NULL;
+	GFile *file = NULL;
+	GFileInfo *info = NULL;
+
+	g_print ("(II) do_open_for_read (filename = '%s') \n", filename);
+	
+	if (strcmp (filename, "/") == 0)
+	{
+		g_print ("caught the read on / case");
+
+		error = 
+			g_error_new (
+				G_IO_ERROR, 
+				G_IO_ERROR_NOT_REGULAR_FILE, 
+				_("Failed to read the root directory"));
+		goto do_open_for_read_error;		
+	}
+	
+	info = 
+		get_g_file_info_from_dice (
+			dice_backend,
+			filename,
+			"*",
+			G_FILE_QUERY_INFO_NONE,
+			G_VFS_JOB (job),
+			&error);
+	if (error != NULL)
+	{
+		goto do_open_for_read_error;
+	}
+	
+	g_assert (info != NULL);
+
+	// Build a GFile object from the local path
+	file = 
+		get_g_file_from_local (
+			g_file_info_get_attribute_string (
+				info, 
+				G_FILE_ATTRIBUTE_DICE_LOCAL_PATH),
+			G_VFS_JOB (job));
+	if (file == NULL)
+	{
+		error = 
+			g_error_new (
+				G_IO_ERROR, 
+				G_IO_ERROR_FAILED, 
+				_("Unable to create a GFile object"));
+		goto do_open_for_read_error;
+	}
+	
+	stream = g_file_read (file, G_VFS_JOB (job)->cancellable, &error);
+	if (stream == NULL)
+	{
+		g_print ("  (EE) do_open_for_read: stream == NULL, error: %s \n", error->message);
+		goto do_open_for_read_error;
+	}
+	
+	dice_handle = g_malloc (sizeof (struct DiceHandle));
+	dice_handle->input_stream = stream;
+	dice_handle->file_path = g_strdup (filename);
+    g_vfs_job_open_for_read_set_can_seek (job, TRUE);
+    g_vfs_job_open_for_read_set_handle (job, dice_handle);
+	g_vfs_job_succeeded (G_VFS_JOB (job));
+	g_print ("(II) do_open_for_read success. \n");
+	g_object_unref (file);
+	g_object_unref (info);
+	return;
+
+do_open_for_read_error:
+	g_vfs_job_failed_from_error (G_VFS_JOB (job), error); 
+	if (error != NULL) g_error_free (error);
+	if (info != NULL) g_object_unref (info);
+	if (file != NULL) g_object_unref (file);
+	
+	return;
+}
+
+
+static void
+do_read (
+	GVfsBackend *backend,
+	GVfsJobRead *job,
+	GVfsBackendHandle handle,
+	char *buffer,
+	gsize bytes_requested)
+{
+	GError *error;
+	struct DiceHandle *dice_handle = (struct DiceHandle *)handle;
+	gssize s;
+
+	g_assert (dice_handle != NULL);
+	g_assert (dice_handle->input_stream);
+	
+	g_print ("(II) do_read (handle = '%lx', buffer = '%lx', bytes_requested = %ld) \n", 
+			 (long int)dice_handle->input_stream, (long int)buffer, (long int)bytes_requested);
+
+	error = NULL;
+	s = g_input_stream_read (G_INPUT_STREAM (dice_handle->input_stream), buffer, bytes_requested, 
+	G_VFS_JOB (job)->cancellable, &error); 
+	if (s >= 0)
+	{
+		g_vfs_job_read_set_size (job, s);
+		g_vfs_job_succeeded (G_VFS_JOB (job));
+		g_print ("(II) do_read success. \n");
+	}
+	else
+	{
+		g_vfs_job_failed_from_error (G_VFS_JOB (job), error); 
+		g_print ("  (EE) do_read: g_input_stream_read() failed, error: %s \n", error->message);
+		g_error_free (error);
+	}
+}
+
+
+static void
+do_seek_on_read (
+	GVfsBackend *backend,
+	GVfsJobSeekRead *job,
+	GVfsBackendHandle handle,
+	goffset    offset,
+	GSeekType  type)
+{
+	GError *error;
+	struct DiceHandle *dice_handle = (struct DiceHandle *)handle;
+
+	g_assert (dice_handle != NULL);
+	g_assert (dice_handle->input_stream != NULL);
+	
+	g_print (
+		"(II) do_seek_on_read (handle = '%lx', offset = %ld) \n", 
+		(long int)dice_handle->input_stream, 
+		(long int)offset);
+	  
+	error = NULL;
+	if (g_seekable_seek (
+			G_SEEKABLE (dice_handle->input_stream), 
+			offset, 
+			type, 
+			G_VFS_JOB (job)->cancellable, &error))
+	{
+		g_vfs_job_seek_read_set_offset (job, g_seekable_tell (G_SEEKABLE (dice_handle->input_stream)));
+		g_vfs_job_succeeded (G_VFS_JOB (job));
+		g_print ("(II) do_seek_on_read success. \n");
+	}
+	else
+	{
+		g_vfs_job_failed_from_error (G_VFS_JOB (job), error); 
+		g_print ("  (EE) do_seek_on_read: g_file_input_stream_seek() failed, error: %s \n", error->message);
+		g_error_free (error);
+	}
+}
+
+
+static void
+do_close_read (
+	GVfsBackend *backend,
+	GVfsJobCloseRead *job,
+	GVfsBackendHandle handle)
+{
+	GError *error;
+	struct DiceHandle *dice_handle = (struct DiceHandle *)handle;
+
+	g_assert (dice_handle != NULL);
+	g_assert (dice_handle->input_stream != NULL);
+	
+	g_print ("(II) do_close_read (handle = '%lx') \n", (long int)dice_handle->input_stream);
+	  
+	error = NULL;
+	if (g_input_stream_close (
+			G_INPUT_STREAM (dice_handle->input_stream), 
+			G_VFS_JOB (job)->cancellable, &error))
+	{
+		g_object_unref (dice_handle->input_stream);
+		if (dice_handle->file_path != NULL)
+			g_free (dice_handle->file_path);
+		g_free (dice_handle);
+		g_vfs_job_succeeded (G_VFS_JOB (job));
+		g_print ("(II) try_close_read success. \n");
+	}
+	else
+	{
+		g_vfs_job_failed_from_error (G_VFS_JOB (job), error); 
+		g_print ("  (EE) try_close_read: g_input_stream_close() failed, error: %s \n", error->message);
+		g_error_free (error);
+	}
+}
+
+
+/*******************
+ * Write Functions *
+ *******************/
+
+static void
+do_create (
+	GVfsBackend *backend,
+	GVfsJobOpenForWrite *job,
+	const char *filename,
+	GFileCreateFlags flags)
+{
+	GVfsBackendDice *dice_backend = G_VFS_BACKEND_DICE (backend);
+	GError *error;
+	GFileInfo *info = NULL;
+	GFile *file;
+	struct DiceHandle *dice_handle;
+	
+	info = 
+		get_g_file_info_from_dice (
+			dice_backend,
+			filename,
+			"*",
+			G_FILE_QUERY_INFO_NONE,
+			G_VFS_JOB (job),
+			&error);
+	
+//		g_file_new_for_path (filename);
+	if (info != NULL)
+	{
+		if (error != NULL) g_error_free (error);
+		g_object_unref (info);
+		error = g_error_new (G_IO_ERROR, G_IO_ERROR_EXISTS, _("Target file already exists"));
+		g_vfs_job_failed_from_error (G_VFS_JOB (job), error);
+		g_error_free (error);
+		return;
+	}
+	
+	// Create a limbo entry in the dice database
+	info = create_g_file_info_in_dice (dice_backend, filename, &error);
+	if (info == NULL)
+	{
+		// The error returned from the dice create call
+		// will be converted to the correct GIO_ERROR
+		g_vfs_job_failed_from_error (G_VFS_JOB (job), error);
+		g_error_free (error);
+		return;
+	}
+
+	g_printf ("Successfully created the file locally");
+	
+	// Open the real local file file!
+	const char *local_path = g_file_info_get_attribute_string (info, G_FILE_ATTRIBUTE_DICE_LOCAL_PATH);
+	g_assert (local_path != NULL);
+
+	g_printf ("local path: %s\n", local_path);
+	file = get_g_file_from_local (local_path, G_VFS_JOB (job));
+	g_object_unref (info);
+
+	error = NULL;
+	GFileOutputStream *stream = g_file_create (file, flags, G_VFS_JOB (job)->cancellable, &error);
+	if (stream != NULL && !error)
+	{
+		g_printf ("g_file_create was successful\n");
+		dice_handle = g_malloc (sizeof (struct DiceHandle));
+		dice_handle->file_path = g_strdup (filename);
+		dice_handle->output_stream = stream;
+
+		//g_vfs_job_open_for_write_set_can_seek (job, TRUE);
+		g_vfs_job_open_for_write_set_handle (job, dice_handle);
+
+		//g_vfs_job_open_for_write_set_handle (G_VFS_JOB_OPEN_FOR_WRITE (job), dice_stream);
+		//g_vfs_job_open_for_write_set_can_seek (G_VFS_JOB_OPEN_FOR_WRITE (job), g_seekable_can_seek (G_SEEKABLE (stream)));
+		////g_vfs_job_succeeded (G_VFS_JOB (job));
+		g_printf ("g_vfs_job_succeeded\n");
+	}
+	else
+	{
+		g_vfs_job_failed_from_error (G_VFS_JOB (job), error);
+		g_error_free (error);
+	}
+	
+	g_object_unref (file);
+	return;
+}
+
+
+static void
+do_close_write (
+	GVfsBackend *backend,
+	GVfsJobCloseWrite *job,
+	GVfsBackendHandle handle)
+{
+	GVfsBackendDice *dice_backend = G_VFS_BACKEND_DICE (backend);
+	GError *error = NULL;
+	struct DiceHandle *dice_handle = (struct DiceHandle *)handle;
+	
+	g_print ("(II) do_close_write (handle = '%lx') \n", (long int)handle);
+	g_assert (dice_handle != NULL);
+	g_assert (dice_handle->output_stream != NULL);
+	g_assert (dice_handle->file_path != NULL);
+	
+	if (!g_output_stream_close (
+			G_OUTPUT_STREAM(dice_handle->output_stream), 
+			G_VFS_JOB (job)->cancellable, 
+			&error))
+	{
+		g_printf ("Failed closing the output stream\n");
+		goto do_close_write_error;
+	}
+
+	// Notify DICE daemon that the file has been closed/changed
+	error = NULL;
+	if (update_local_file_in_dice (
+			dice_backend,
+			dice_handle->file_path,
+			&error) == FALSE)
+	{
+		g_print ("(II) failed updating dice of changes\n");
+		goto do_close_write_error;
+	}
+		
+	g_object_unref (dice_handle->output_stream);
+	if (dice_handle->file_path != NULL)
+		g_free (dice_handle->file_path);
+	g_free (dice_handle);
+	g_vfs_job_succeeded (G_VFS_JOB (job));
+	g_print ("(II) do_close_write success. \n");
+	return;
+
+do_close_write_error:
+	if (dice_handle != NULL)
+	{
+		if (dice_handle->file_path != NULL)
+			g_free (dice_handle->file_path);
+		g_free (dice_handle);
+	}
+	
+	g_vfs_job_failed_from_error (G_VFS_JOB (job), error);
+	g_print ("  (EE) do_close_write: failed, error: %s \n", error->message);
+	g_error_free (error);
+	return;
+}
+
+
+static void
+do_write (
+	GVfsBackend *backend,
+	GVfsJobWrite *job,
+	GVfsBackendHandle handle,
+	char *buffer,
+	gsize buffer_size)
+{
+	GError *error;
+	struct DiceHandle *dice_handle = (struct DiceHandle *)handle;
+	gssize s;
+
+	g_print (
+		"(II) do_write (handle = '%lx', buffer = '%lx', buffer_size = %ld) \n",
+		(long int)handle, 
+		(long int)buffer, 
+		(long int)buffer_size);
+
+	g_assert (dice_handle != NULL);
+	g_assert (dice_handle->output_stream != NULL);
+	  
+	error = NULL;
+	s = 
+		g_output_stream_write (
+			G_OUTPUT_STREAM (dice_handle->output_stream), 
+			buffer, 
+			buffer_size, 
+			G_VFS_JOB (job)->cancellable, 
+			&error);
+	if (s >= 0)
+	{
+		g_vfs_job_write_set_written_size (job, s);
+		g_vfs_job_succeeded (G_VFS_JOB (job));
+		g_print ("(II) do_write success. \n");
+	}
+	else
+	{
+		g_vfs_job_failed_from_error (G_VFS_JOB (job), error); 
+		g_print (
+			"  (EE) do_write: g_output_stream_write() failed, error: %s \n", 
+			error->message);
+		g_error_free (error);
+	}
+}
+
+
+static void
+do_append (
+	GVfsBackend *backend,
+	GVfsJobOpenForWrite *job,
+	const char *filename,
+	GFileCreateFlags flags)
+{
+	GVfsBackendDice *dice_backend = G_VFS_BACKEND_DICE (backend);
+	GError *error;
+	GFileInfo *info;
+	GFile *file;
+	struct DiceHandle *dice_handle = NULL;
+	
+	g_print ("(II) do_append (filename = %s) \n", filename);
+	
+	info = 
+		get_g_file_info_from_dice (
+			dice_backend,
+			filename,
+			"*",
+			G_FILE_QUERY_INFO_NONE,
+			G_VFS_JOB (job),
+			&error);
+	
+	if (info == NULL)
+	{
+		if (error != NULL) g_error_free (error);
+		// The file must not exist, so just use the create function
+		do_create (backend, job, filename, flags);
+		return;
+	}
+
+	// Get the real local path
+	const char *local_path = 
+		g_file_info_get_attribute_string (info, G_FILE_ATTRIBUTE_DICE_LOCAL_PATH);
+	g_assert (local_path != NULL);
+
+	file = get_g_file_from_local (local_path, G_VFS_JOB (job));
+	g_object_unref (info);
+
+	g_assert (file != NULL);
+
+	if (file != NULL)
+	{
+		error = NULL;
+		dice_handle = g_malloc (sizeof (struct DiceHandle));
+		dice_handle->output_stream = 
+			g_file_append_to (file, flags, G_VFS_JOB (job)->cancellable, &error);
+		g_object_unref (file);
+		if (dice_handle->output_stream)
+		{
+			/*  Should seek at the end of the file here  */
+			if ((g_seekable_seek (
+					G_SEEKABLE (dice_handle->output_stream), 
+					0, 
+					G_SEEK_END, 
+					G_VFS_JOB (job)->cancellable, &error)) && (! error))
+			{
+				g_vfs_job_open_for_write_set_initial_offset (
+					job, 
+					g_seekable_tell (G_SEEKABLE (dice_handle->output_stream)));
+			}
+			else
+			{
+				g_print ("  (EE) do_append: error during g_file_output_stream_seek(), error: %s \n", error->message);
+			}
+			
+			// Store the filename so we can close properly and notify the DICE Daemon
+			dice_handle->file_path = g_strdup (filename);
+			g_vfs_job_open_for_write_set_can_seek (
+				job,
+				g_seekable_can_seek (G_SEEKABLE (dice_handle->output_stream)));
+			g_vfs_job_open_for_write_set_handle (job, dice_handle);
+			g_vfs_job_succeeded (G_VFS_JOB (job));
+
+			g_print ("(II) do_append success. \n");
+		}
+		else
+		{
+			g_free (dice_handle);
+			g_vfs_job_failed_from_error (G_VFS_JOB (job), error); 
+			g_print ("  (EE) do_append: stream == NULL, error: %s \n", error->message);
+			g_error_free (error);
+		}
+	}
+	else
+	{
+		g_print ("  (EE) do_append: file == NULL \n");
+
+		g_vfs_job_failed (
+			G_VFS_JOB (job),
+			G_IO_ERROR,
+			G_IO_ERROR_NOT_FOUND,
+			_("Unable to get the local path"));
+	}
+}
+
+
+static void
+do_replace (
+	GVfsBackend *backend,
+	GVfsJobOpenForWrite *job,
+	const char *filename,
+	const char *etag,
+	gboolean make_backup,
+	GFileCreateFlags flags)
+{
+	GVfsBackendDice *dice_backend = G_VFS_BACKEND_DICE (backend);
+	struct DiceHandle *dice_handle = NULL;
+	GError *error = NULL;
+	GFile *file = NULL;
+	GFileInfo *info = NULL;
+	
+	g_print ("(II) do_replace (filename = '%s', etag = '%s') \n", filename, etag);
+	g_print ("\t\t make_backup == %s\n", (make_backup == TRUE) ? "TRUE" : "FALSE");
+	g_print ("\t\t create flags == %X\n", flags);
+
+	if (make_backup == TRUE)
+	{
+		g_printf ("\t\tcan't create backups yet - fail");
+		
+		error = 
+			g_error_new (
+				G_IO_ERROR, 
+				G_IO_ERROR_CANT_CREATE_BACKUP, 
+				_("backup creation is not supported"));
+
+		goto do_replace_error;
+	}
+
+
+	// Check if the file already exists in the DICE namespace
+	info = 
+		get_g_file_info_from_dice (
+			dice_backend,
+			filename,
+			"*",
+			G_FILE_QUERY_INFO_NONE,
+			G_VFS_JOB (job),
+			&error);
+	
+	if (info == NULL)
+	{
+		if (error != NULL)
+		{
+			g_error_free (error);
+			error = NULL;
+		}
+		
+		g_printf ("\t\tfailed to find the filename in the dice namespace");
+
+		// Create a limbo entry in the dice database
+		info = create_g_file_info_in_dice (dice_backend, filename, &error);
+		if (info == NULL)
+		{
+			// The error returned from the dice create call
+			// will be converted to the correct GIO_ERROR
+			goto do_replace_error;
+		}
+
+		/*
+		if (etag == NULL)
+			etag = g_file_info_get_attribute_string (info, G_FILE_ATTRIBUTE_ID_FILE);
+		*/
+
+		g_printf ("Successfully created the file locally");
+	}
+
+	// Get the real local path
+	const char *local_path = 
+		g_file_info_get_attribute_string (info,	G_FILE_ATTRIBUTE_DICE_LOCAL_PATH);
+
+	g_assert (local_path != NULL);
+	g_printf ("local path: %s\n", local_path);
+
+	// Create a GFile object from the local path
+	file = get_g_file_from_local (local_path, G_VFS_JOB (job));
+	if (file == NULL)
+	{
+		g_print ("  (EE) do_replace: file == NULL \n");
+		g_assert (file != NULL);
+		error = 
+			g_error_new (
+				G_IO_ERROR, 
+				G_IO_ERROR_NOT_FOUND, 
+				_("Unable to get the local path"));
+
+		goto do_replace_error;
+	}
+
+	dice_handle = g_malloc (sizeof (struct DiceHandle));
+	dice_handle->output_stream = 
+		g_file_replace (
+			file, 
+			NULL,
+			make_backup, 
+			flags, 
+			G_VFS_JOB (job)->cancellable,
+			&error);
+
+	if (dice_handle->output_stream == NULL)
+	{
+		g_print ("  (EE) do_replace: stream == NULL, error: %s \n", error->message);
+		goto do_replace_error;
+	}
+
+
+	// Save off the filename so we can notify DICE Daemon during a close
+	dice_handle->file_path = g_strdup (filename);
+	g_vfs_job_open_for_write_set_handle (job, dice_handle);
+	g_object_unref (file);
+	g_object_unref (info);
+	g_vfs_job_succeeded (G_VFS_JOB (job));
+
+	// Call dice with a local update
+	if (update_local_file_in_dice (
+			dice_backend,
+			filename,
+			&error) == FALSE)
+	{
+		g_error_free (error);
+	}
+
+	g_print ("(II) do_replace success. \n");
+	return;
+
+do_replace_error:
+	g_print ("  do_replace failed - error message: %s\n", error->message);
+	g_vfs_job_failed_from_error (G_VFS_JOB (job), error);
+	if (error != NULL) g_error_free (error);
+	if (info != NULL) g_object_unref (info);
+	if (file != NULL) g_object_unref (file);
+	if (dice_handle != NULL) g_free (dice_handle);
+	return;
+}
+
+
+static void
+do_delete (
+	GVfsBackend *backend,
+	GVfsJobDelete *job,
+	const char *filename)
+{
+	GVfsBackendDice *dice_backend = G_VFS_BACKEND_DICE (backend);
+	GError *error;
+
+	g_print ("(II) do_delete (filename = %s) \n", filename);
+
+	if (filename != NULL)
+	{
+		error = NULL;
+		if (delete_local_file_from_dice (dice_backend, filename, &error))
+		{
+			g_vfs_job_succeeded (G_VFS_JOB (job));
+			g_print ("(II) do_delete success. \n");
+		}
+		else
+		{
+			g_vfs_job_failed_from_error (G_VFS_JOB (job), error); 
+			g_print ("  (EE) do_delete: g_file_delete == FALSE, error: %s \n", error->message);
+			g_error_free (error);
+		}
+	}
+	else
+	{
+		g_print ("  (EE) do_delete: filename == NULL \n");
+	}
+}
+
+
+static void
+g_vfs_backend_dice_class_init (GVfsBackendDiceClass *klass)
+{
+	GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+	GVfsBackendClass *backend_class = G_VFS_BACKEND_CLASS (klass);
+	
+	gobject_class->finalize = g_vfs_backend_dice_finalize;
+
+	backend_class->mount = do_mount;
+	backend_class->unmount = do_unmount;
+	backend_class->query_info = do_query_info;
+	backend_class->query_fs_info = do_query_fs_info;
+	backend_class->enumerate = do_enumerate;
+	
+	backend_class->open_for_read = do_open_for_read;
+	backend_class->read = do_read;
+	backend_class->seek_on_read = do_seek_on_read;
+	backend_class->close_read = do_close_read;
+
+	backend_class->create = do_create;
+	backend_class->close_write = do_close_write;
+	backend_class->write = do_write;
+	backend_class->append_to = do_append;
+	backend_class->replace = do_replace;
+
+	backend_class->delete = do_delete;
+	
+//	backend_class->move = do_move;
+//	backend_class->make_directory = do_make_directory;
+	
+//	backend_class->create_dir_monitor = do_create_dir_monitor;
+//	backend_class->create_file_monitor = do_create_file_monitor;
+}
Index: gvfs-1.5.1/daemon/gvfsbackenddice.h
===================================================================
--- /dev/null
+++ gvfs-1.5.1/daemon/gvfsbackenddice.h
@@ -0,0 +1,50 @@
+/* Novell IceDesktop Backend for GVfs
+ * 
+ * Copyright (C) 2008 Novell, 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: Boyd Timothy <btimothy@novell.com>
+ */
+
+#ifndef __G_VFS_BACKEND_DICE_H__
+#define __G_VFS_BACKEND_DICE_H__
+
+#include <gvfsbackend.h>
+#include <gmountspec.h>
+
+G_BEGIN_DECLS
+
+#define G_VFS_TYPE_BACKEND_DICE         (g_vfs_backend_dice_get_type ())
+#define G_VFS_BACKEND_DICE(o)           (G_TYPE_CHECK_INSTANCE_CAST ((o), G_VFS_TYPE_BACKEND_DICE, GVfsBackendDice))
+#define G_VFS_BACKEND_DICE_CLASS(k)     (G_TYPE_CHECK_CLASS_CAST((k), G_VFS_TYPE_BACKEND_DICE, GVfsBackendDiceClass))
+#define G_VFS_IS_BACKEND_DICE(o)        (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_VFS_TYPE_BACKEND_DICE))
+#define G_VFS_IS_BACKEND_DICE_CLASS(k)  (G_TYPE_CHECK_CLASS_TYPE ((k), G_VFS_TYPE_BACKEND_DICE))
+#define G_VFS_BACKEND_DICE_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_VFS_TYPE_BACKEND_DICE, GVfsBackendDiceClass))
+
+typedef struct _GVfsBackendDice        GVfsBackendDice;
+typedef struct _GVfsBackendDiceClass   GVfsBackendDiceClass;
+
+struct _GVfsBackendDiceClass
+{
+  GVfsBackendClass parent_class;
+};
+
+GType g_vfs_backend_dice_get_type (void) G_GNUC_CONST;
+
+G_END_DECLS
+
+#endif /* __G_VFS_BACKEND_DICE_H__ */
Index: gvfs-1.5.1/daemon/Makefile.am
===================================================================
--- gvfs-1.5.1.orig/daemon/Makefile.am
+++ gvfs-1.5.1/daemon/Makefile.am
@@ -10,6 +10,7 @@ INCLUDES =					\
 	-I$(top_srcdir)/common			\
 	-I$(top_builddir)			\
 	$(GLIB_CFLAGS) $(DBUS_CFLAGS) 		\
+	$(DBUS_GLIB_CFLAGS)			\
 	$(OBEXFTP_CFLAGS) $(EXPAT_CFLAGS)	\
 	$(KEYRING_CFLAGS)			\
 	-DDBUS_API_SUBJECT_TO_CHANGE		\
@@ -24,7 +25,7 @@ noinst_LTLIBRARIES=libdaemon.la
 libraries =						\
 	libdaemon.la					\
 	$(top_builddir)/common/libgvfscommon.la		\
-	$(GLIB_LIBS) $(DBUS_LIBS) $(KEYRING_LIBS)
+	$(GLIB_LIBS) $(DBUS_LIBS) $(DBUS_GLIB_LIBS) $(KEYRING_LIBS)
 
 # D-BUS service file
 %.service: %.service.in ../config.log
@@ -37,10 +38,10 @@ service_DATA = gvfs-daemon.service
 %.mount: %.mount.in ../config.log
 	$(AM_V_GEN) $(SED) -e "s|\@libexecdir\@|$(libexecdir)|" $< > $@
 
-libexec_PROGRAMS=gvfsd gvfsd-sftp gvfsd-trash gvfsd-computer gvfsd-burn gvfsd-localtest gvfsd-ftp
+libexec_PROGRAMS=gvfsd gvfsd-sftp gvfsd-trash gvfsd-computer gvfsd-burn gvfsd-localtest gvfsd-ftp gvfsd-dice
 
-mount_in_files = sftp.mount.in trash.mount.in computer.mount.in burn.mount.in localtest.mount.in
-mount_DATA =  sftp.mount trash.mount computer.mount burn.mount localtest.mount
+mount_in_files = sftp.mount.in trash.mount.in computer.mount.in burn.mount.in localtest.mount.in dice.mount.in
+mount_DATA =  sftp.mount trash.mount computer.mount burn.mount localtest.mount dice.mount
 
 mount_in_files += http.mount.in dav.mount.in dav+sd.mount.in ftp.mount.in 
 if HAVE_HTTP
@@ -292,6 +293,19 @@ gvfsd_trash_CPPFLAGS = \
 
 gvfsd_trash_LDADD = trashlib/libtrash.a $(libraries)
 
+gvfsd_dice_SOURCES = \
+	gvfsbackenddice.c gvfsbackenddice.h \
+	daemon-main.c daemon-main.h \
+	daemon-main-generic.c
+
+gvfsd_dice_CPPFLAGS = \
+	-DBACKEND_HEADER=gvfsbackenddice.h \
+	-DDEFAULT_BACKEND_TYPE=dice \
+	-DMAX_JOB_THREADS=10 \
+	-DBACKEND_TYPES='"dice", G_VFS_TYPE_BACKEND_DICE,'
+
+gvfsd_dice_LDADD = $(libraries)
+
 gvfsd_computer_SOURCES = \
 	gvfsbackendcomputer.c gvfsbackendcomputer.h \
 	daemon-main.c daemon-main.h \