diff --git a/libnautilus-private/nautilus-icon-info.c b/libnautilus-private/nautilus-icon-info.c
index f1ddd7c..b165e90 100644
--- a/libnautilus-private/nautilus-icon-info.c
+++ b/libnautilus-private/nautilus-icon-info.c
@@ -32,7 +32,7 @@ struct _NautilusIconInfo
 	gboolean sole_owner;
 	guint64 last_use_time;
 	GdkPixbuf *pixbuf;
-	
+
 	gboolean got_embedded_rect;
 	GdkRectangle embedded_rect;
 	gint n_attach_points;
@@ -71,9 +71,9 @@ pixbuf_toggle_notify (gpointer      info,
 		      gboolean      is_last_ref)
 {
 	NautilusIconInfo  *icon = info;
-	
+
 	if (is_last_ref) {
-		icon->sole_owner = TRUE;	
+		icon->sole_owner = TRUE;
 		g_object_remove_toggle_ref (object,
 					    pixbuf_toggle_notify,
 					    info);
@@ -125,8 +125,8 @@ nautilus_icon_info_new_for_pixbuf (GdkPixbuf *pixbuf)
 
 	if (pixbuf) {
 		icon->pixbuf = g_object_ref (pixbuf);
-	} 
-	
+	}
+
 	return icon;
 }
 
@@ -162,7 +162,7 @@ nautilus_icon_info_new_for_icon_info (GtkIconInfo *icon_info)
 		}
 		icon->icon_name = basename;
 	}
-	
+
 	return icon;
 }
 
@@ -177,8 +177,14 @@ typedef struct {
 	int size;
 } ThemedIconKey;
 
+typedef struct {
+	char *filename;
+	int size;
+} FileIconKey;
+
 static GHashTable *loadable_icon_cache = NULL;
 static GHashTable *themed_icon_cache = NULL;
+static GHashTable *file_icon_cache = NULL;
 static guint reap_cache_timeout = 0;
 
 #define NSEC_PER_SEC ((guint64)1000000000L)
@@ -202,7 +208,7 @@ reap_old_icon (gpointer  key,
 			*reapable_icons_left = TRUE;
 		}
 	}
-	
+
 	return FALSE;
 }
 
@@ -214,19 +220,25 @@ reap_cache (gpointer data)
 	reapable_icons_left = TRUE;
 
 	time_now = g_thread_gettime ();
-	
+
 	if (loadable_icon_cache) {
 		g_hash_table_foreach_remove (loadable_icon_cache,
 					     reap_old_icon,
 					     &reapable_icons_left);
 	}
-	
+
 	if (themed_icon_cache) {
 		g_hash_table_foreach_remove (themed_icon_cache,
 					     reap_old_icon,
 					     &reapable_icons_left);
 	}
-	
+
+	if (file_icon_cache) {
+		g_hash_table_foreach_remove (file_icon_cache,
+					     reap_old_icon,
+					     &reapable_icons_left);
+	}
+
 	if (reapable_icons_left) {
 		return TRUE;
 	} else {
@@ -251,10 +263,14 @@ nautilus_icon_info_clear_caches (void)
 	if (loadable_icon_cache) {
 		g_hash_table_remove_all (loadable_icon_cache);
 	}
-	
+
 	if (themed_icon_cache) {
 		g_hash_table_remove_all (themed_icon_cache);
 	}
+
+	if (file_icon_cache) {
+		g_hash_table_remove_all (file_icon_cache);
+	}
 }
 
 static guint
@@ -323,93 +339,201 @@ themed_icon_key_free (ThemedIconKey *key)
 	g_slice_free (ThemedIconKey, key);
 }
 
-NautilusIconInfo *
-nautilus_icon_info_lookup (GIcon *icon,
-			   int size)
+static guint
+file_icon_key_hash (FileIconKey *key)
+{
+	return g_str_hash (key->filename) ^ key->size;
+}
+
+static gboolean
+file_icon_key_equal (const FileIconKey *a,
+		       const FileIconKey *b)
+{
+	return a->size == b->size &&
+		g_str_equal (a->filename, b->filename);
+}
+
+static FileIconKey *
+file_icon_key_new (const char *filename, int size)
+{
+	FileIconKey *key;
+
+	key = g_slice_new (FileIconKey);
+	key->filename = g_strdup (filename);
+	key->size = size;
+
+	return key;
+}
+
+static void
+file_icon_key_free (FileIconKey *key)
+{
+	g_free (key->filename);
+	g_slice_free (FileIconKey, key);
+}
+
+static NautilusIconInfo *
+icon_info_file_lookup (GIcon *icon,
+			int size)
 {
 	NautilusIconInfo *icon_info;
 	GdkPixbuf *pixbuf;
-	
-	if (G_IS_LOADABLE_ICON (icon)) {
-		LoadableIconKey lookup_key;
-		LoadableIconKey *key;
-		GInputStream *stream;
-		
-		if (loadable_icon_cache == NULL) {
-			loadable_icon_cache =
-				g_hash_table_new_full ((GHashFunc)loadable_icon_key_hash,
-						       (GEqualFunc)loadable_icon_key_equal,
-						       (GDestroyNotify) loadable_icon_key_free,
-						       (GDestroyNotify) g_object_unref);
-		}
-		
-		lookup_key.icon = icon;
-		lookup_key.size = size;
+	FileIconKey lookup_key;
+	FileIconKey *key;
+	GError *error = NULL;
+	GFile *file;
+	gchar *name;
+
+	if (file_icon_cache == NULL) {
+		file_icon_cache =
+				g_hash_table_new_full ((GHashFunc) file_icon_key_hash,
+									   (GEqualFunc) file_icon_key_equal,
+									   (GDestroyNotify) file_icon_key_free,
+									   (GDestroyNotify) g_object_unref);
+	}
 
-		icon_info = g_hash_table_lookup (loadable_icon_cache, &lookup_key);
-		if (icon_info) {
-			return g_object_ref (icon_info);
-		}
+	file = g_file_icon_get_file (G_FILE_ICON (icon));
+	name = g_file_get_path (file);
+	g_object_unref (file);
+
+	lookup_key.filename = (char *) name;
+	lookup_key.size = size;
 
+	icon_info = g_hash_table_lookup (file_icon_cache, &lookup_key);
+	if (icon_info) {
+		return g_object_ref (icon_info);
+	}
+
+	pixbuf = gdk_pixbuf_new_from_file_at_size (name, size, size, &error);
+	if (error) {
+		g_warning ("error=%s", error->message);
+		g_error_free (error);
+		error = NULL;
 		pixbuf = NULL;
-		stream = g_loadable_icon_load (G_LOADABLE_ICON (icon),
-					       size,
-					       NULL, NULL, NULL);
-		if (stream) {
-			pixbuf = eel_gdk_pixbuf_load_from_stream_at_size (stream, size);
-			g_object_unref (stream);
-		}
+	}
 
+	if (pixbuf) {
 		icon_info = nautilus_icon_info_new_for_pixbuf (pixbuf);
 
-		key = loadable_icon_key_new (icon, size);
-		g_hash_table_insert (loadable_icon_cache, key, icon_info);
+		key = file_icon_key_new ((const char *) name, size);
+		g_hash_table_insert (file_icon_cache, key, icon_info);
 
+		g_free( name );
 		return g_object_ref (icon_info);
-	} else if (G_IS_THEMED_ICON (icon)) {
-		const char * const *names;
-		ThemedIconKey lookup_key;
-		ThemedIconKey *key;
-		GtkIconTheme *icon_theme;
-		GtkIconInfo *gtkicon_info;
-		const char *filename;
-
-		if (themed_icon_cache == NULL) {
-			themed_icon_cache =
-				g_hash_table_new_full ((GHashFunc)themed_icon_key_hash,
-						       (GEqualFunc)themed_icon_key_equal,
-						       (GDestroyNotify) themed_icon_key_free,
-						       (GDestroyNotify) g_object_unref);
-		}
-		
-		names = g_themed_icon_get_names (G_THEMED_ICON (icon));
+	}
+
+	g_free( name );
+	return NULL;
+}
 
-		icon_theme = gtk_icon_theme_get_default ();
-		gtkicon_info = gtk_icon_theme_choose_icon (icon_theme, (const char **)names, size, 0);
+static NautilusIconInfo *
+icon_info_loadable_lookup (GIcon *icon,
+			int size)
+{
+	NautilusIconInfo *icon_info;
+	GdkPixbuf *pixbuf;
+	LoadableIconKey lookup_key;
+	LoadableIconKey *key;
+	GInputStream *stream;
+
+	if (loadable_icon_cache == NULL) {
+		loadable_icon_cache =
+			g_hash_table_new_full ((GHashFunc)loadable_icon_key_hash,
+								   (GEqualFunc)loadable_icon_key_equal,
+								   (GDestroyNotify) loadable_icon_key_free,
+								   (GDestroyNotify) g_object_unref);
+	}
 
-		if (gtkicon_info == NULL) {
-			return nautilus_icon_info_new_for_pixbuf (NULL);
-		}
+	lookup_key.icon = icon;
+	lookup_key.size = size;
 
-		filename = gtk_icon_info_get_filename (gtkicon_info);
+	icon_info = g_hash_table_lookup (loadable_icon_cache, &lookup_key);
+	if (icon_info) {
+		return g_object_ref (icon_info);
+	}
+
+	pixbuf = NULL;
+	stream = g_loadable_icon_load (G_LOADABLE_ICON (icon),
+					       size,
+					       NULL, NULL, NULL);
+	if (stream) {
+		pixbuf = eel_gdk_pixbuf_load_from_stream_at_size (stream, size);
+		g_object_unref (stream);
+	}
 
-		lookup_key.filename = (char *)filename;
-		lookup_key.size = size;
+	icon_info = nautilus_icon_info_new_for_pixbuf (pixbuf);
 
-		icon_info = g_hash_table_lookup (themed_icon_cache, &lookup_key);
-		if (icon_info) {
-			gtk_icon_info_free (gtkicon_info);
-			return g_object_ref (icon_info);
-		}
-		
-		icon_info = nautilus_icon_info_new_for_icon_info (gtkicon_info);
-		
-		key = themed_icon_key_new (filename, size);
-		g_hash_table_insert (themed_icon_cache, key, icon_info);
+	key = loadable_icon_key_new (icon, size);
+	g_hash_table_insert (loadable_icon_cache, key, icon_info);
 
-		gtk_icon_info_free (gtkicon_info);
+	return g_object_ref (icon_info);
+}
+
+static NautilusIconInfo *
+icon_info_themed_lookup (GIcon *icon,
+			int size)
+{
+	NautilusIconInfo *icon_info;
+	const char * const *names;
+	ThemedIconKey lookup_key;
+	ThemedIconKey *key;
+	GtkIconTheme *icon_theme;
+	GtkIconInfo *gtkicon_info;
+	const char *filename;
+
+	if (themed_icon_cache == NULL) {
+		themed_icon_cache =
+			g_hash_table_new_full ((GHashFunc)themed_icon_key_hash,
+									(GEqualFunc)themed_icon_key_equal,
+									(GDestroyNotify) themed_icon_key_free,
+									(GDestroyNotify) g_object_unref);
+	}
+
+	names = g_themed_icon_get_names (G_THEMED_ICON (icon));
+
+	icon_theme = gtk_icon_theme_get_default ();
+	gtkicon_info = gtk_icon_theme_choose_icon (icon_theme, (const char **)names, size, 0);
+
+	if (gtkicon_info == NULL) {
+		return nautilus_icon_info_new_for_pixbuf (NULL);
+	}
+
+	filename = gtk_icon_info_get_filename (gtkicon_info);
 
+	lookup_key.filename = (char *)filename;
+	lookup_key.size = size;
+
+	icon_info = g_hash_table_lookup (themed_icon_cache, &lookup_key);
+	if (icon_info) {
+		gtk_icon_info_free (gtkicon_info);
 		return g_object_ref (icon_info);
+	}
+
+	icon_info = nautilus_icon_info_new_for_icon_info (gtkicon_info);
+
+	key = themed_icon_key_new (filename, size);
+	g_hash_table_insert (themed_icon_cache, key, icon_info);
+
+	gtk_icon_info_free (gtkicon_info);
+
+	return g_object_ref (icon_info);
+}
+
+NautilusIconInfo *
+nautilus_icon_info_lookup (GIcon *icon,
+			   int size)
+{
+	NautilusIconInfo *icon_info;
+
+	if (G_IS_FILE_ICON (icon)) {
+		icon_info = icon_info_file_lookup (icon, size);
+
+	} else if (G_IS_LOADABLE_ICON (icon)) {
+		icon_info = icon_info_loadable_lookup (icon, size);
+
+	} else if (G_IS_THEMED_ICON (icon)) {
+		icon_info = icon_info_themed_lookup (icon, size);
+
 	} else {
                 GdkPixbuf *pixbuf;
                 GtkIconInfo *gtk_icon_info;
@@ -425,8 +549,10 @@ nautilus_icon_info_lookup (GIcon *icon,
                         pixbuf = NULL;
                 }
 
-                return nautilus_icon_info_new_for_pixbuf (pixbuf);
+                icon_info = nautilus_icon_info_new_for_pixbuf (pixbuf);
         }
+
+	return icon_info;
 }
 
 NautilusIconInfo *
@@ -434,11 +560,25 @@ nautilus_icon_info_lookup_from_name (const char *name,
 				     int size)
 {
 	GIcon *icon;
+	GFile *icon_file;
 	NautilusIconInfo *info;
-	
-	icon = g_themed_icon_new (name);
-	info = nautilus_icon_info_lookup (icon, size);
-	g_object_unref (icon);
+
+	info = NULL;
+
+	if (g_str_has_prefix (name, "/")) {
+		icon_file = g_file_new_for_path (name);
+		icon = g_file_icon_new (icon_file);
+		g_object_unref (icon_file);
+
+	} else {
+		icon = g_themed_icon_new (name);
+	}
+
+	if (icon) {
+		info = nautilus_icon_info_lookup (icon, size);
+		g_object_unref (icon);
+	}
+
 	return info;
 }
 
@@ -460,7 +600,7 @@ nautilus_icon_info_get_pixbuf_nodefault (NautilusIconInfo  *icon)
 						 icon);
 		}
 	}
-	
+
 	return res;
 }
 
@@ -481,8 +621,8 @@ nautilus_icon_info_get_pixbuf (NautilusIconInfo *icon)
 						nautilus_default_file_icon_width * 4, /* stride */
 						NULL, /* don't destroy info */
 						NULL);
-	} 
-	
+	}
+
 	return res;
 }
 
@@ -498,7 +638,7 @@ nautilus_icon_info_get_pixbuf_nodefault_at_size (NautilusIconInfo  *icon,
 
 	if (pixbuf == NULL)
 	  return NULL;
-	  
+
 	w = gdk_pixbuf_get_width (pixbuf);
 	h = gdk_pixbuf_get_height (pixbuf);
 	s = MAX (w, h);
@@ -572,7 +712,7 @@ nautilus_icon_info_get_used_name (NautilusIconInfo  *icon)
 
 /* Return nominal icon size for given zoom level.
  * @zoom_level: zoom level for which to find matching icon size.
- * 
+ *
  * Return value: icon size between NAUTILUS_ICON_SIZE_SMALLEST and
  * NAUTILUS_ICON_SIZE_LARGEST, inclusive.
  */
@@ -659,7 +799,7 @@ nautilus_get_icon_size_for_stock_size (GtkIconSize size)
 
   if (gtk_icon_size_lookup (size, &w, &h)) {
     return MAX (w, h);
-  } 
+  }
   return NAUTILUS_ZOOM_LEVEL_STANDARD;
 }
 
@@ -677,6 +817,6 @@ nautilus_icon_get_emblem_size_for_icon_size (guint size)
 		return 16;
 	if (size >= 16)
 		return 12;
-	
+
 	return 0; /* no emblems for smaller sizes */
 }
