Index: src/file-manager/fm-list-model.c
===================================================================
--- src/file-manager/fm-list-model.c	(revision 14459)
+++ src/file-manager/fm-list-model.c	(working copy)
@@ -991,11 +991,14 @@
 	return TRUE;
 }
 
+static void
+fm_list_model_remove (FMListModel *model, GtkTreeIter *iter);
+
 void
 fm_list_model_file_changed (FMListModel *model, NautilusFile *file,
 			    NautilusDirectory *directory)
 {
-	FileEntry *parent_file_entry;
+	FileEntry *file_entry, *parent_file_entry;
 	GtkTreeIter iter;
 	GtkTreePath *path, *parent_path;
 	GSequenceIter *ptr;
@@ -1051,9 +1054,19 @@
 		gtk_tree_path_free (parent_path);
 		g_free (new_order);
 	}
-	
+
+	/*  Reflect directory <--> file changes */
 	fm_list_model_ptr_to_iter (model, ptr, &iter);
 	path = gtk_tree_model_get_path (GTK_TREE_MODEL (model), &iter);
+	ptr = iter.user_data;
+	file_entry = g_sequence_get (ptr);
+
+	if ((! nautilus_file_is_directory (file) && file_entry->files) ||
+		(nautilus_file_is_directory (file) && ! file_entry->files)) {
+		fm_list_model_remove (model, &iter);
+		fm_list_model_add_file (model, file, directory);
+	}
+	
 	gtk_tree_model_row_changed (GTK_TREE_MODEL (model), path, &iter);
 	gtk_tree_path_free (path);
 }
Index: src/file-manager/fm-directory-view.c
===================================================================
--- src/file-manager/fm-directory-view.c	(revision 14459)
+++ src/file-manager/fm-directory-view.c	(working copy)
@@ -3053,6 +3053,9 @@
 }
 
 static void
+file_changed_callback (NautilusFile *file, gpointer callback_data);
+
+static void
 files_added_callback (NautilusDirectory *directory,
 		      GList *files,
 		      gpointer callback_data)
@@ -3060,6 +3063,8 @@
 	FMDirectoryView *view;
 	GtkWindow *window;
 	char *uri;
+	GList *l;
+	NautilusFile *file;
 
 	view = FM_DIRECTORY_VIEW (callback_data);
 
@@ -3071,6 +3076,15 @@
 					   uri ? uri : "(no directory)");
 	g_free (uri);
 
+	for (l = files; l; l = l->next) {
+		file = NAUTILUS_FILE (l->data);
+		
+		if (file->details->symlink_name)
+		{
+			file->details->symlink_monitor = nautilus_monitor_symlink (nautilus_file_get_location (file));
+		}
+	}
+	
 	schedule_changes (view);
 
 	queue_pending_files (view, directory, files, &view->details->new_added_files);
Index: libnautilus-private/nautilus-file-private.h
===================================================================
--- libnautilus-private/nautilus-file-private.h	(revision 14459)
+++ libnautilus-private/nautilus-file-private.h	(working copy)
@@ -144,6 +144,9 @@
 	GHashTable *extension_attributes;
 	GHashTable *pending_extension_attributes;
 
+	/* Symlink monitor */
+	NautilusMonitor *symlink_monitor;
+	
 	/* Mount for mountpoint or the references GMount for a "mountable" */
 	GMount *mount;
 	
Index: libnautilus-private/nautilus-monitor.c
===================================================================
--- libnautilus-private/nautilus-monitor.c	(revision 14459)
+++ libnautilus-private/nautilus-monitor.c	(working copy)
@@ -34,6 +34,7 @@
 
 struct NautilusMonitor {
 	GFileMonitor *monitor;
+	gboolean is_symlink;
 };
 
 gboolean
@@ -78,13 +79,25 @@
 	     gpointer user_data)
 {
 	char *uri, *to_uri;
+	NautilusMonitor *mon;
+
+	/*  Remember that this callback is called for symlinks as well,
+	 *  not just for directories  */
 	
+	mon = (NautilusMonitor *) user_data;
+	
 	uri = g_file_get_uri (child);
 	to_uri = NULL;
 	if (other_file) {
 		to_uri = g_file_get_uri (other_file);
 	}
 
+	/*  Mask *some* events on symlinks; we don't want to remove the file 
+	 *  from the list when symlink target gets deleted  */ 
+	if (mon->is_symlink || event_type == G_FILE_MONITOR_EVENT_DELETED) {
+		event_type = G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT;
+	}
+	
 	switch (event_type) {
 	default:
 	case G_FILE_MONITOR_EVENT_CHANGED:
@@ -137,6 +150,26 @@
 	return ret;
 }
 
+NautilusMonitor *
+nautilus_monitor_symlink (GFile *location)
+{
+	GFileMonitor *file_monitor;
+	NautilusMonitor *ret;
+
+	file_monitor = g_file_monitor_file (location, G_FILE_MONITOR_NONE, NULL, NULL);
+
+	ret = g_new0 (NautilusMonitor, 1);
+	ret->monitor = file_monitor;
+	ret->is_symlink = TRUE;
+
+	if (ret->monitor) {
+		g_signal_connect (ret->monitor, "changed", (GCallback)dir_changed, ret);
+	}
+
+	/* We return a monitor even on failure, so we can avoid later trying again */
+	return ret;
+}
+
 void 
 nautilus_monitor_cancel (NautilusMonitor *monitor)
 {
Index: libnautilus-private/nautilus-monitor.h
===================================================================
--- libnautilus-private/nautilus-monitor.h	(revision 14459)
+++ libnautilus-private/nautilus-monitor.h	(working copy)
@@ -33,6 +33,7 @@
 
 gboolean         nautilus_monitor_active    (void);
 NautilusMonitor *nautilus_monitor_directory (GFile *location);
+NautilusMonitor *nautilus_monitor_symlink   (GFile *location);
 void             nautilus_monitor_cancel    (NautilusMonitor *monitor);
 
 #endif /* NAUTILUS_MONITOR_H */
Index: libnautilus-private/nautilus-file.c
===================================================================
--- libnautilus-private/nautilus-file.c	(revision 14459)
+++ libnautilus-private/nautilus-file.c	(working copy)
@@ -645,6 +645,11 @@
 
 	remove_from_link_hash_table (file);
 
+	/*  remove symlink monitor if present  */
+	if (file->details->symlink_monitor) {
+		nautilus_monitor_cancel (file->details->symlink_monitor);
+	}
+	
 	directory = file->details->directory;
 	
 	if (nautilus_file_is_self_owned (file)) {
