Index: daemon/gvfsbackend.c
===================================================================
--- daemon/gvfsbackend.c	(revision 2073)
+++ daemon/gvfsbackend.c	(working copy)
@@ -71,7 +71,7 @@ struct _GVfsBackendPrivate
   char *display_name;
   char *stable_name;
   char **x_content_types;
-  char *icon;
+  GIcon *icon;
   char *prefered_filename_encoding;
   gboolean user_visible;
   GMountSpec *mount_spec;
@@ -146,7 +146,8 @@ g_vfs_backend_finalize (GObject *object)
   g_free (backend->priv->display_name);
   g_free (backend->priv->stable_name);
   g_strfreev (backend->priv->x_content_types);
-  g_free (backend->priv->icon);
+  if (backend->priv->icon != NULL)
+    g_object_unref (backend->priv->icon);
   g_free (backend->priv->prefered_filename_encoding);
   if (backend->priv->mount_spec)
     g_mount_spec_unref (backend->priv->mount_spec);
@@ -194,7 +195,7 @@ static void
 g_vfs_backend_init (GVfsBackend *backend)
 {
   backend->priv = G_TYPE_INSTANCE_GET_PRIVATE (backend, G_VFS_TYPE_BACKEND, GVfsBackendPrivate);
-  backend->priv->icon = g_strdup ("");
+  backend->priv->icon = NULL;
   backend->priv->prefered_filename_encoding = g_strdup ("");
   backend->priv->display_name = g_strdup ("");
   backend->priv->stable_name = g_strdup ("");
@@ -326,13 +327,23 @@ g_vfs_backend_set_x_content_types (GVfsBackend
 
 void
 g_vfs_backend_set_icon_name (GVfsBackend *backend,
-			     const char *icon)
+			     const char *icon_name)
 {
-  g_free (backend->priv->icon);
-  backend->priv->icon = g_strdup (icon);
+  if (backend->priv->icon != NULL)
+    g_object_unref (backend->priv->icon);
+  backend->priv->icon = g_themed_icon_new (icon_name);
 }
 
 void
+g_vfs_backend_set_icon (GVfsBackend *backend,
+                        GIcon       *icon)
+{
+  if (backend->priv->icon != NULL)
+    g_object_unref (backend->priv->icon);
+  backend->priv->icon = g_object_ref (icon);
+}
+
+void
 g_vfs_backend_set_prefered_filename_encoding (GVfsBackend  *backend,
 					      const char *prefered_filename_encoding)
 {
@@ -382,8 +393,8 @@ g_vfs_backend_get_x_content_types (GVfsBackend *ba
   return backend->priv->x_content_types;
 }
 
-const char *
-g_vfs_backend_get_icon_name (GVfsBackend *backend)
+GIcon *
+g_vfs_backend_get_icon (GVfsBackend *backend)
 {
   return backend->priv->icon;
 }
@@ -591,12 +602,18 @@ g_vfs_backend_register_mount (GVfsBackend *backend
   DBusMessageIter iter;
   dbus_bool_t user_visible;
   char *x_content_types_string;
+  char *icon_str;
 
   if (backend->priv->x_content_types != NULL && g_strv_length (backend->priv->x_content_types) > 0)
     x_content_types_string = g_strjoinv (" ", backend->priv->x_content_types);
   else
     x_content_types_string = g_strdup ("");
 
+  if (backend->priv->icon != NULL)
+    icon_str = g_icon_to_string (backend->priv->icon);
+  else
+    icon_str = g_strdup ("");
+
   message = dbus_message_new_method_call (G_VFS_DBUS_DAEMON_NAME,
 					  G_VFS_DBUS_MOUNTTRACKER_PATH,
 					  G_VFS_DBUS_MOUNTTRACKER_INTERFACE,
@@ -616,7 +633,7 @@ g_vfs_backend_register_mount (GVfsBackend *backend
 				 DBUS_TYPE_STRING, &backend->priv->display_name,
 				 DBUS_TYPE_STRING, &stable_name,
                                  DBUS_TYPE_STRING, &x_content_types_string,
-				 DBUS_TYPE_STRING, &backend->priv->icon,
+				 DBUS_TYPE_STRING, &icon_str,
 				 DBUS_TYPE_STRING, &backend->priv->prefered_filename_encoding,
 				 DBUS_TYPE_BOOLEAN, &user_visible,
 				 0))
@@ -632,6 +649,7 @@ g_vfs_backend_register_mount (GVfsBackend *backend
   dbus_message_unref (message);
 
   g_free (x_content_types_string);
+  g_free (icon_str);
 }
 
 void
Index: daemon/gvfsbackend.h
===================================================================
--- daemon/gvfsbackend.h	(revision 2073)
+++ daemon/gvfsbackend.h	(working copy)
@@ -408,7 +408,9 @@ void        g_vfs_backend_set_stable_name
 void        g_vfs_backend_set_x_content_types            (GVfsBackend        *backend,
 							  char              **x_content_types);
 void        g_vfs_backend_set_icon_name                  (GVfsBackend        *backend,
-							  const char         *icon);
+							  const char         *icon_name);
+void        g_vfs_backend_set_icon                       (GVfsBackend        *backend,
+							  GIcon              *icon);
 void        g_vfs_backend_set_prefered_filename_encoding (GVfsBackend        *backend,
 							  const char         *prefered_filename_encoding);
 void        g_vfs_backend_set_user_visible               (GVfsBackend        *backend,
@@ -425,7 +427,7 @@ const char *g_vfs_backend_get_backend_type
 const char *g_vfs_backend_get_display_name               (GVfsBackend        *backend);
 const char *g_vfs_backend_get_stable_name                (GVfsBackend        *backend);
 char      **g_vfs_backend_get_x_content_types            (GVfsBackend        *backend);
-const char *g_vfs_backend_get_icon_name                  (GVfsBackend        *backend);
+GIcon      *g_vfs_backend_get_icon                       (GVfsBackend        *backend);
 GMountSpec *g_vfs_backend_get_mount_spec                 (GVfsBackend        *backend);
 GVfsDaemon *g_vfs_backend_get_daemon                     (GVfsBackend        *backend);
 
Index: daemon/gvfsbackendsftp.c
===================================================================
--- daemon/gvfsbackendsftp.c	(revision 2073)
+++ daemon/gvfsbackendsftp.c	(working copy)
@@ -37,8 +37,12 @@
 #include <gio/gunixinputstream.h>
 #include <gio/gunixoutputstream.h>
 
+#include "gvfsicon.h"
+
 #include "gvfsbackendsftp.h"
 #include "gvfsjobopenforread.h"
+#include "gvfsjobopeniconforread.h"
+#include "gvfsjobmount.h"
 #include "gvfsjobread.h"
 #include "gvfsjobseekread.h"
 #include "gvfsjobopenforwrite.h"
@@ -174,7 +178,10 @@ static void parse_attributes (GVfsBackendSftp *bac
                               GDataInputStream *reply,
                               GFileAttributeMatcher *attribute_matcher);
 
+static void setup_icon (GVfsBackendSftp *op_backend,
+                        GVfsJobMount    *job);
 
+
 G_DEFINE_TYPE (GVfsBackendSftp, g_vfs_backend_sftp, G_VFS_TYPE_BACKEND)
 
 static void
@@ -1519,9 +1526,9 @@ do_mount (GVfsBackend *backend,
   display_name = g_strdup_printf (_("sftp on %s"), op_backend->host);
   g_vfs_backend_set_display_name (backend, display_name);
   g_free (display_name);
-  g_vfs_backend_set_icon_name (backend, "folder-remote");
 
-  g_vfs_job_succeeded (G_VFS_JOB (job));
+  /* checks for /etc/favicon.png */
+  setup_icon (op_backend, job);
 }
 
 static gboolean
@@ -2057,6 +2064,26 @@ try_open_for_read (GVfsBackend *backend,
   return TRUE;
 }
 
+static gboolean
+try_open_icon_for_read (GVfsBackend *backend,
+                        GVfsJobOpenIconForRead *job,
+                        const char *icon_id)
+{
+  if (g_str_has_prefix (icon_id, "favicon:"))
+    {
+      return try_open_for_read (backend,
+                                G_VFS_JOB_OPEN_FOR_READ (job),
+                                icon_id + sizeof ("favicon:") -1);
+    }
+
+  g_vfs_job_failed (G_VFS_JOB (job),
+                    G_IO_ERROR,
+                    G_IO_ERROR_INVALID_ARGUMENT,
+                    _("Invalid icon_id '%s' in OpenIconForRead"),
+                    icon_id);
+  return TRUE;
+}
+
 static void
 read_reply (GVfsBackendSftp *backend,
             int reply_type,
@@ -3880,6 +3907,56 @@ try_set_attribute (GVfsBackend *backend,
 }
 
 static void
+setup_icon_reply (GVfsBackendSftp *backend,
+                  MultiReply *replies,
+                  int n_replies,
+                  GVfsJob *job,
+                  gpointer user_data)
+{
+  GIcon *icon;
+  gboolean have_favicon;
+  MultiReply *stat_reply;
+
+  have_favicon = FALSE;
+
+  stat_reply = &replies[0];
+  if (stat_reply->type == SSH_FXP_ATTRS)
+    have_favicon = TRUE;
+
+  if (have_favicon)
+    {
+      icon = g_vfs_icon_new (g_vfs_backend_get_mount_spec (G_VFS_BACKEND (backend)),
+                             "favicon:/etc/favicon.png");
+      g_vfs_backend_set_icon (G_VFS_BACKEND (backend), icon);
+      g_object_unref (icon);
+    }
+  else
+    {
+      g_vfs_backend_set_icon_name (G_VFS_BACKEND (backend), "folder-remote");
+    }
+
+  g_vfs_job_succeeded (G_VFS_JOB (job));
+}
+
+/* called from do_mount(); finds out if there's an /etc/favicon.png file; if so, use it as the icon */
+static void
+setup_icon (GVfsBackendSftp *op_backend,
+            GVfsJobMount    *job)
+{
+  GDataOutputStream *command;
+
+  command = new_command_stream (op_backend, SSH_FXP_STAT);
+  put_string (command, "/etc/favicon.png");
+
+  queue_command_streams_and_free (op_backend,
+                                  &command,
+                                  1,
+                                  setup_icon_reply,
+                                  G_VFS_JOB (job),
+                                  NULL);
+}
+
+static void
 g_vfs_backend_sftp_class_init (GVfsBackendSftpClass *klass)
 {
   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
@@ -3891,6 +3968,7 @@ g_vfs_backend_sftp_class_init (GVfsBackendSftpClas
 
   backend_class->mount = do_mount;
   backend_class->try_mount = try_mount;
+  backend_class->try_open_icon_for_read = try_open_icon_for_read;
   backend_class->try_open_for_read = try_open_for_read;
   backend_class->try_read = try_read;
   backend_class->try_seek_on_read = try_seek_on_read;
Index: daemon/gvfsbackendsmbbrowse.c
===================================================================
--- daemon/gvfsbackendsmbbrowse.c	(revision 2073)
+++ daemon/gvfsbackendsmbbrowse.c	(working copy)
@@ -1067,7 +1067,6 @@ try_query_info (GVfsBackend *backend,
 		GFileAttributeMatcher *matcher)
 {
   GVfsBackendSmbBrowse *op_backend = G_VFS_BACKEND_SMB_BROWSE (backend);
-  const char *icon_name;
   GIcon *icon;
 
   if (is_root (filename))
@@ -1075,13 +1074,9 @@ try_query_info (GVfsBackend *backend,
       g_file_info_set_file_type (info, G_FILE_TYPE_DIRECTORY);
       g_file_info_set_name (info, "/");
       g_file_info_set_display_name (info, g_vfs_backend_get_display_name (backend));
-      icon_name = g_vfs_backend_get_icon_name (backend);
-      if (icon_name)
-	{
-	  icon = g_themed_icon_new (icon_name);
-	  g_file_info_set_icon (info, icon);
-	  g_object_unref (icon);
-	}
+      icon = g_vfs_backend_get_icon (backend);
+      if (icon != NULL)
+        g_file_info_set_icon (info, icon);
       g_vfs_job_succeeded (G_VFS_JOB (job));
       
       return TRUE;
Index: common/gmounttracker.c
===================================================================
--- common/gmounttracker.c	(revision 2073)
+++ common/gmounttracker.c	(working copy)
@@ -90,7 +90,7 @@ g_mount_info_dup (GMountInfo *info)
   copy->display_name = g_strdup (info->display_name);
   copy->stable_name = g_strdup (info->stable_name);
   copy->x_content_types = g_strdup (info->x_content_types);
-  copy->icon = g_strdup (info->icon);
+  copy->icon = g_object_ref (info->icon);
   copy->dbus_id = g_strdup (info->dbus_id);
   copy->object_path = g_strdup (info->object_path);
   copy->mount_spec = g_mount_spec_copy (info->mount_spec);
@@ -116,7 +116,7 @@ g_mount_info_unref (GMountInfo *info)
       g_free (info->display_name);
       g_free (info->stable_name);
       g_free (info->x_content_types);
-      g_free (info->icon);
+      g_object_unref (info->icon);
       g_free (info->dbus_id);
       g_free (info->object_path);
       g_mount_spec_unref (info->mount_spec);
@@ -161,11 +161,13 @@ g_mount_info_from_dbus (DBusMessageIter *iter)
   char *display_name;
   char *stable_name;
   char *x_content_types;
-  char *icon;
+  char *icon_str;
   char *prefered_filename_encoding;
   char *dbus_id;
   char *obj_path;
   char *fuse_mountpoint;
+  GIcon *icon;
+  GError *error;
 
   if (dbus_message_iter_get_arg_type (iter) != DBUS_TYPE_STRUCT)
     return NULL;
@@ -178,7 +180,7 @@ g_mount_info_from_dbus (DBusMessageIter *iter)
 				      DBUS_TYPE_STRING, &display_name,
 				      DBUS_TYPE_STRING, &stable_name,
                                       DBUS_TYPE_STRING, &x_content_types,
-				      DBUS_TYPE_STRING, &icon,
+				      DBUS_TYPE_STRING, &icon_str,
 				      DBUS_TYPE_STRING, &prefered_filename_encoding,
 				      DBUS_TYPE_BOOLEAN, &user_visible,
 				      G_DBUS_TYPE_CSTRING, &fuse_mountpoint,
@@ -191,12 +193,23 @@ g_mount_info_from_dbus (DBusMessageIter *iter)
     return NULL;
   }
 
+  if (icon_str == NULL || strlen (icon_str) == 0)
+    icon_str = "drive-removable-media";
+  error = NULL;
+  icon = g_icon_new_for_string (icon_str, &error);
+  if (icon == NULL)
+    {
+      g_warning ("Malformed icon string '%s': %s", icon_str, error->message);
+      g_error_free (error);
+      icon = g_themed_icon_new ("gtk-missing-image"); /* TODO: maybe choose a better name */
+    }
+
   info = g_new0 (GMountInfo, 1);
   info->ref_count = 1;
   info->display_name = g_strdup (display_name);
   info->stable_name = g_strdup (stable_name);
   info->x_content_types = g_strdup (x_content_types);
-  info->icon = g_strdup (icon);
+  info->icon = icon;
   info->dbus_id = g_strdup (dbus_id);
   info->object_path = g_strdup (obj_path);
   info->mount_spec = mount_spec;
Index: common/gmounttracker.h
===================================================================
--- common/gmounttracker.h	(revision 2073)
+++ common/gmounttracker.h	(working copy)
@@ -24,6 +24,7 @@
 #define __G_MOUNT_TRACKER_H__
 
 #include <glib-object.h>
+#include <gio/gio.h>
 #include <gmountspec.h>
 
 G_BEGIN_DECLS
@@ -43,7 +44,7 @@ typedef struct {
   char *display_name;
   char *stable_name;
   char *x_content_types;
-  char *icon;
+  GIcon *icon;
   char *dbus_id;
   char *object_path;
   gboolean user_visible;
Index: client/gdaemonmount.c
===================================================================
--- client/gdaemonmount.c	(revision 2073)
+++ client/gdaemonmount.c	(working copy)
@@ -120,7 +116,7 @@ g_daemon_mount_get_icon (GMount *mount)
 {
   GDaemonMount *daemon_mount = G_DAEMON_MOUNT (mount);
 
-  return g_themed_icon_new_with_default_fallbacks (daemon_mount->mount_info->icon);
+  return g_object_ref (daemon_mount->mount_info->icon);
 }
 
 static char *

