diff --git a/libnautilus-private/nautilus-bookmark.c b/libnautilus-private/nautilus-bookmark.c
index 07ab5f9..e73003b 100644
--- a/libnautilus-private/nautilus-bookmark.c
+++ b/libnautilus-private/nautilus-bookmark.c
@@ -311,6 +311,7 @@ nautilus_bookmark_set_name (NautilusBookmark *bookmark, const char *new_name)
 	bookmark->details->name = g_strdup (new_name);
 
 	g_signal_emit (bookmark, signals[APPEARANCE_CHANGED], 0);
+	g_signal_emit (bookmark, signals[CONTENTS_CHANGED], 0);
 
 	return TRUE;
 }
@@ -416,6 +417,7 @@ bookmark_file_changed_callback (NautilusFile *file, NautilusBookmark *bookmark)
 			g_free (bookmark->details->name);
 			bookmark->details->name = display_name;
 			should_emit_appearance_changed_signal = TRUE;
+			should_emit_contents_changed_signal = TRUE;
 		} else {
 			g_free (display_name);
 		}
diff --git a/src/nautilus-bookmark-list.c b/src/nautilus-bookmark-list.c
index 0d401fc..5dd5d4a 100644
--- a/src/nautilus-bookmark-list.c
+++ b/src/nautilus-bookmark-list.c
@@ -37,11 +37,27 @@
 
 #define MAX_BOOKMARK_LENGTH 80
 
+#define NAUTILUS_BOOKMARK_LIST_GET_PRIVATE(o)  \
+   (G_TYPE_INSTANCE_GET_PRIVATE ((o), NAUTILUS_TYPE_BOOKMARK_LIST, NautilusBookmarkListDetails))
+
 enum {
 	CONTENTS_CHANGED,
 	LAST_SIGNAL
 };
 
+typedef struct {
+	NautilusBookmarkList *bookmarks;
+	GFile *file;
+	GCancellable *cancellable;
+} IOJob;
+
+struct _NautilusBookmarkListDetails {
+	GList *list; 
+	GFileMonitor *monitor;
+	IOJob *load_job;
+	IOJob *save_job;
+};
+
 static guint signals[LAST_SIGNAL];
 static char *window_geometry;
 
@@ -50,8 +66,10 @@ static char *window_geometry;
 static void        destroy                              (GtkObject            *object);
 static void        nautilus_bookmark_list_load_file     (NautilusBookmarkList *bookmarks);
 static void        nautilus_bookmark_list_save_file     (NautilusBookmarkList *bookmarks);
+static void        nautilus_bookmark_list_class_init    (NautilusBookmarkListClass *class);
+static void        nautilus_bookmark_list_init          (NautilusBookmarkList *bookmarks);
 
-G_DEFINE_TYPE(NautilusBookmarkList, nautilus_bookmark_list, GTK_TYPE_OBJECT)
+G_DEFINE_TYPE (NautilusBookmarkList, nautilus_bookmark_list, GTK_TYPE_OBJECT);
 
 static NautilusBookmark *
 new_bookmark_from_uri (const char *uri, const char *label)
@@ -138,6 +156,8 @@ nautilus_bookmark_list_class_init (NautilusBookmarkListClass *class)
 		              NULL, NULL,
 		              g_cclosure_marshal_VOID__VOID,
 		              G_TYPE_NONE, 0);
+
+	g_type_class_add_private (class, sizeof (NautilusBookmarkListDetails));
 }
 
 static void
@@ -147,27 +167,42 @@ bookmark_monitor_changed_cb (GFileMonitor      *monitor,
 			     GFileMonitorEvent  eflags,
 			     gpointer           user_data)
 {
+	NautilusBookmarkList *bookmarks = user_data;
+
+	g_return_if_fail (NAUTILUS_IS_BOOKMARK_LIST (bookmarks));
+
 	if (eflags == G_FILE_MONITOR_EVENT_CHANGED ||
 	    eflags == G_FILE_MONITOR_EVENT_CREATED) {
-		g_return_if_fail (NAUTILUS_IS_BOOKMARK_LIST (NAUTILUS_BOOKMARK_LIST (user_data)));
-		nautilus_bookmark_list_load_file (NAUTILUS_BOOKMARK_LIST (user_data));
-		g_signal_emit (user_data, signals[CONTENTS_CHANGED], 0);
+		nautilus_bookmark_list_load_file (bookmarks);
+		/* the "contents-changed" signal is emitted in the load_file
+		 * async callback.
+		 */
 	}
 }
 
 static void
+start_monitoring (NautilusBookmarkList *bookmarks, GFile *file)
+{
+	/* re-enable bookmark file monitoring */
+	bookmarks->details->monitor = g_file_monitor_file (file, 0, NULL, NULL);
+
+	g_signal_connect (bookmarks->details->monitor, "changed",
+			  G_CALLBACK (bookmark_monitor_changed_cb), bookmarks);
+}
+
+static void
 nautilus_bookmark_list_init (NautilusBookmarkList *bookmarks)
 {
+	NautilusBookmarkListDetails *details;
 	GFile *file;
 
-	nautilus_bookmark_list_load_file (bookmarks);
+	details = bookmarks->details = NAUTILUS_BOOKMARK_LIST_GET_PRIVATE (bookmarks);
 
 	file = nautilus_bookmark_list_get_file ();
-	bookmarks->monitor = g_file_monitor_file (file, 0, NULL, NULL);
-	g_signal_connect (bookmarks->monitor, "changed",
-			  G_CALLBACK (bookmark_monitor_changed_cb), bookmarks);
-
+	start_monitoring (bookmarks, file);
 	g_object_unref (file);
+
+	nautilus_bookmark_list_load_file (bookmarks);
 }
 
 static void
@@ -203,20 +238,23 @@ stop_monitoring_one (gpointer data, gpointer user_data)
 static void
 clear (NautilusBookmarkList *bookmarks)
 {
-	g_list_foreach (bookmarks->list, stop_monitoring_one, bookmarks);
-	eel_g_object_list_free (bookmarks->list);
-	bookmarks->list = NULL;
+	g_list_foreach (bookmarks->details->list, stop_monitoring_one, bookmarks);
+	eel_g_object_list_free (bookmarks->details->list);
+	bookmarks->details->list = NULL;
 }
 
 static void
 destroy (GtkObject *object)
 {
-	if (NAUTILUS_BOOKMARK_LIST (object)->monitor != NULL) {
-		g_file_monitor_cancel (NAUTILUS_BOOKMARK_LIST (object)->monitor);
-		NAUTILUS_BOOKMARK_LIST (object)->monitor = NULL;
+	NautilusBookmarkList *bookmarks;
+	
+	bookmarks = NAUTILUS_BOOKMARK_LIST (object);
+	if (bookmarks->details->monitor != NULL) {
+		g_file_monitor_cancel (bookmarks->details->monitor);
+		bookmarks->details->monitor = NULL;
 	}
 
-	clear (NAUTILUS_BOOKMARK_LIST (object));
+	clear (bookmarks);
 }
 
 static void
@@ -224,10 +262,8 @@ insert_bookmark_internal (NautilusBookmarkList *bookmarks,
 			  NautilusBookmark     *bookmark,
 			  int                   index)
 {
-	bookmarks->list = g_list_insert (bookmarks->list, bookmark, index);
+	bookmarks->details->list = g_list_insert (bookmarks->details->list, bookmark, index);
 
-	g_signal_connect_object (bookmark, "appearance_changed",
-				 G_CALLBACK (bookmark_in_list_changed_callback), bookmarks, 0);
 	g_signal_connect_object (bookmark, "contents_changed",
 				 G_CALLBACK (bookmark_in_list_changed_callback), bookmarks, 0);
 }
@@ -269,7 +305,7 @@ nautilus_bookmark_list_contains (NautilusBookmarkList *bookmarks,
 	g_return_val_if_fail (NAUTILUS_IS_BOOKMARK_LIST (bookmarks), FALSE);
 	g_return_val_if_fail (NAUTILUS_IS_BOOKMARK (bookmark), FALSE);
 
-	return g_list_find_custom (bookmarks->list,
+	return g_list_find_custom (bookmarks->details->list,
 				   (gpointer)bookmark, 
 				   nautilus_bookmark_compare_with) 
 		!= NULL;
@@ -300,14 +336,16 @@ nautilus_bookmark_list_contents_changed (NautilusBookmarkList *bookmarks)
 void
 nautilus_bookmark_list_delete_item_at (NautilusBookmarkList *bookmarks, 
 				       guint                 index)
-{
+{	
 	GList *doomed;
+	NautilusBookmarkListDetails *details;
 
 	g_return_if_fail (NAUTILUS_IS_BOOKMARK_LIST (bookmarks));
-	g_return_if_fail (index < g_list_length (bookmarks->list));
+	details = bookmarks->details;
+	g_return_if_fail (index < g_list_length (details->list));
 
-	doomed = g_list_nth (bookmarks->list, index);
-	bookmarks->list = g_list_remove_link (bookmarks->list, doomed);
+	doomed = g_list_nth (details->list, index);
+	details->list = g_list_remove_link (details->list, doomed);
 
 	g_assert (NAUTILUS_IS_BOOKMARK (doomed->data));
 	stop_monitoring_bookmark (bookmarks, NAUTILUS_BOOKMARK (doomed->data));
@@ -332,17 +370,20 @@ nautilus_bookmark_list_delete_items_with_uri (NautilusBookmarkList *bookmarks,
 	GList *node, *next;
 	gboolean list_changed;
 	char *bookmark_uri;
+	NautilusBookmarkListDetails *details;
 
 	g_return_if_fail (NAUTILUS_IS_BOOKMARK_LIST (bookmarks));
 	g_return_if_fail (uri != NULL);
 
+	details = bookmarks->details;
+
 	list_changed = FALSE;
-	for (node = bookmarks->list; node != NULL;  node = next) {
+	for (node = details->list; node != NULL;  node = next) {
 		next = node->next;
 
 		bookmark_uri = nautilus_bookmark_get_uri (NAUTILUS_BOOKMARK (node->data));
 		if (eel_strcmp (bookmark_uri, uri) == 0) {
-			bookmarks->list = g_list_remove_link (bookmarks->list, node);
+			details->list = g_list_remove_link (details->list, node);
 			stop_monitoring_bookmark (bookmarks, NAUTILUS_BOOKMARK (node->data));
 			g_object_unref (node->data);
 			g_list_free_1 (node);
@@ -386,7 +427,7 @@ nautilus_bookmark_list_insert_item (NautilusBookmarkList *bookmarks,
 				    guint                 index)
 {
 	g_return_if_fail (NAUTILUS_IS_BOOKMARK_LIST (bookmarks));
-	g_return_if_fail (index <= g_list_length (bookmarks->list));
+	g_return_if_fail (index <= g_list_length (bookmarks->details->list));
 
 	insert_bookmark_internal (bookmarks,
 				  nautilus_bookmark_copy (new_bookmark), 
@@ -408,9 +449,9 @@ NautilusBookmark *
 nautilus_bookmark_list_item_at (NautilusBookmarkList *bookmarks, guint index)
 {
 	g_return_val_if_fail (NAUTILUS_IS_BOOKMARK_LIST (bookmarks), NULL);
-	g_return_val_if_fail (index < g_list_length (bookmarks->list), NULL);
+	g_return_val_if_fail (index < g_list_length (bookmarks->details->list), NULL);
 
-	return NAUTILUS_BOOKMARK (g_list_nth_data (bookmarks->list, index));
+	return NAUTILUS_BOOKMARK (g_list_nth_data (bookmarks->details->list, index));
 }
 
 /**
@@ -426,28 +467,57 @@ nautilus_bookmark_list_length (NautilusBookmarkList *bookmarks)
 {
 	g_return_val_if_fail (NAUTILUS_IS_BOOKMARK_LIST(bookmarks), 0);
 
-	return g_list_length (bookmarks->list);
+	return g_list_length (bookmarks->details->list);
 }
 
-/**
- * nautilus_bookmark_list_load_file:
- * 
- * Reads bookmarks from file, clobbering contents in memory.
- * @bookmarks: the list of bookmarks to fill with file contents.
- **/
 static void
-nautilus_bookmark_list_load_file (NautilusBookmarkList *bookmarks)
+io_job_free (IOJob *j)
 {
-	GFile *file;
+	g_object_unref (j->file);
+	g_object_unref (j->cancellable);
+	g_slice_free (IOJob, j);
+}
+
+static gboolean
+load_job_done (gpointer data)
+{
+	IOJob *j = data;
+
+	j->bookmarks->details->load_job = NULL;
+	io_job_free (j);
+
+	return TRUE;
+}
+
+static gboolean
+load_job_cancelled (gpointer data)
+{
+	IOJob *j = data;
+
+	io_job_free (j);
+
+	return FALSE;
+}
+
+static gboolean
+load_job (GIOSchedulerJob *io_job,
+	  GCancellable *cancellable,
+	  gpointer user_data)
+{
+	IOJob *job = user_data;
+	GError *error;
+	NautilusBookmarkList *bookmarks;
 	char *contents;
-	GError *error = NULL;
+	GSourceFunc func;
 
-	file = nautilus_bookmark_list_get_file ();
+	error = NULL;
+	bookmarks = job->bookmarks;
 
 	/* Wipe out old list. */
 	clear (bookmarks);
 
-	if (g_file_load_contents (file, NULL, &contents, NULL, NULL, &error)) {
+	if (g_file_load_contents (job->file, job->cancellable,
+				  &contents, NULL, NULL, &error)) {
         	char **lines;
       		int i;
 
@@ -474,13 +544,57 @@ nautilus_bookmark_list_load_file (NautilusBookmarkList *bookmarks)
 		}
       		g_free (contents);
        		g_strfreev (lines);
-	}
-	else if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND)) {
+
+		/* emit now the contents_changed signal */
+		g_signal_emit (bookmarks, signals[CONTENTS_CHANGED], 0);
+
+	} else if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
+		func = load_job_cancelled;
+		goto out;
+	} else if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND)) {
 		g_warning ("Could not load bookmark file: %s\n", error->message);
+	}
+	
+	func = load_job_done;
+out:
+	if (error) {
 		g_error_free (error);
 	}
+	g_io_scheduler_job_send_to_mainloop_async (io_job, func, job, NULL);
 
-	g_object_unref (file);
+	return FALSE;
+}
+
+/**
+ * nautilus_bookmark_list_load_file:
+ * 
+ * Reads bookmarks from file, clobbering contents in memory.
+ * @bookmarks: the list of bookmarks to fill with file contents.
+ **/
+static void
+nautilus_bookmark_list_load_file (NautilusBookmarkList *bookmarks)
+{
+	NautilusBookmarkListDetails *details;
+	IOJob *job;
+
+	details = bookmarks->details;
+
+	if (details->load_job != NULL) {
+		/* there's already a load job running, abort it and start
+		 * a new one.
+		 */
+		g_cancellable_cancel (details->load_job->cancellable);
+	}
+
+	job = g_slice_new0 (IOJob);
+	job->file = nautilus_bookmark_list_get_file ();
+	job->cancellable = g_cancellable_new ();
+	job->bookmarks = bookmarks;
+
+	g_io_scheduler_push_job (load_job,
+				 job,
+				 NULL, 0,
+				 job->cancellable);
 }
 
 /**
@@ -500,35 +614,59 @@ nautilus_bookmark_list_new (void)
 	return g_object_ref_sink (list);
 }
 
-/**
- * nautilus_bookmark_list_save_file:
- * 
- * Save bookmarks to disk.
- * @bookmarks: the list of bookmarks to save.
- **/
-static void
-nautilus_bookmark_list_save_file (NautilusBookmarkList *bookmarks)
+static gboolean
+save_job_cancelled (gpointer user_data)
 {
-	GFile *file;
-	GOutputStream *out;
-	GError *error = NULL;
-	GList *l;
+	IOJob *job = user_data;
 
-	/* temporarily disable bookmark file monitoring when writing file */
-	if (bookmarks->monitor != NULL) {
-		g_file_monitor_cancel (bookmarks->monitor);
-		bookmarks->monitor = NULL;
-	}
+	/* do not resume monitoring, as a new op will start anyway */
+	io_job_free (job);
 
-	file = nautilus_bookmark_list_get_file ();
+	return FALSE;
+}
+
+static gboolean
+save_job_done (gpointer user_data)
+{
+	IOJob *job = user_data;
+
+	/* resume monitoring */
+	start_monitoring (job->bookmarks, job->file);
+	job->bookmarks->details->save_job = NULL;
+	io_job_free (job);
+
+	return FALSE;
+}
 
-	out = (GOutputStream *)g_file_replace (file, NULL, FALSE, 0, NULL, &error);
+static gboolean
+save_job (GIOSchedulerJob *io_job,
+	  GCancellable *cancellable,
+	  gpointer user_data)
+{
+	IOJob *job = user_data;
+	GOutputStream *out;
+	GError *error;
+	NautilusBookmarkList *bookmarks;
+	GList *l;
+	GSourceFunc func;
+
+	error = NULL;
+	bookmarks = job->bookmarks;
+	out = (GOutputStream *) g_file_replace (job->file,
+						NULL, FALSE, 0,
+						job->cancellable,
+						&error);
 	if (out == NULL) {
-		g_warning ("Error opening bookmark file: %s\n", error->message);
-		goto error;
+		if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
+			func = save_job_cancelled;
+		} else {
+			g_warning ("Error opening bookmark file: %s\n", error->message);
+			func = save_job_done;
+		}
+		goto end;
 	}
 
-      	for (l = bookmarks->list; l; l = l->next) {
+	for (l = bookmarks->details->list; l; l = l->next) {
 		NautilusBookmark *bookmark;
 		char *bookmark_string;
 
@@ -549,36 +687,82 @@ nautilus_bookmark_list_save_file (NautilusBookmarkList *bookmarks)
 			g_free (uri);
 		}
 
-		if (!g_output_stream_write_all (out,
-						bookmark_string,
+		if (!g_output_stream_write_all (out, bookmark_string,
 						strlen (bookmark_string),
-						NULL, NULL,
+						NULL, job->cancellable,
 						&error)) {
-			g_warning ("writing %s to bookmark file failed: %s\n",
-				   bookmark_string, error->message); 
+			/* (try to) close the stream anyway */
+			g_output_stream_close (out, job->cancellable, NULL);
+			if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
+				func = save_job_cancelled;
+			} else {
+				g_warning ("writing %s to bookmark file failed: %s\n",
+					   bookmark_string, error->message);
+				func = save_job_done;
+			}
 			g_free (bookmark_string);
-    			goto error;
+			goto end;
 		}
-
 		g_free (bookmark_string);
 	}
 
-	if (!g_output_stream_close (out, NULL, &error)) {
-		g_warning ("Error closing bookmark file: %s\n", error->message);
+	if (!g_output_stream_close (out, job->cancellable, &error)) {
+		if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
+			func = save_job_cancelled;
+		} else {
+			g_warning ("Error closing bookmark file: %s\n", error->message);
+			func = save_job_done;
+		}
+		goto end;
 	}
 
-error:
-	if (error)
+	func = save_job_done;
+end:
+	if (error) {
 		g_error_free (error);
+	}
+	g_io_scheduler_job_send_to_mainloop_async (io_job,
+						   func,
+						   job, NULL);
+	return FALSE;
+}
 
-	/* re-enable bookmark file monitoring */
-	bookmarks->monitor = g_file_monitor_file (file, 0, NULL, NULL);
-	g_signal_connect (bookmarks->monitor, "changed",
-			  G_CALLBACK (bookmark_monitor_changed_cb), bookmarks);
+/**
+ * nautilus_bookmark_list_save_file:
+ * 
+ * Save bookmarks to disk.
+ * @bookmarks: the list of bookmarks to save.
+ **/
+static void
+nautilus_bookmark_list_save_file (NautilusBookmarkList *bookmarks)
+{
+	IOJob *job;
+	NautilusBookmarkListDetails *details;
 
-	if (out)
-		g_object_unref (out);
-	g_object_unref (file);
+	details = bookmarks->details;
+
+	/* abort the current save job if any is running */
+	if (details->save_job != NULL) {
+		g_cancellable_cancel (details->save_job->cancellable);
+	}
+
+	/* temporarily disable bookmark file monitoring when writing file */
+	if (details->monitor != NULL) {
+		g_file_monitor_cancel (details->monitor);
+		details->monitor = NULL;
+	}
+
+	job = g_slice_new0 (IOJob);
+	job->file = nautilus_bookmark_list_get_file ();
+	job->cancellable = g_cancellable_new ();
+	job->bookmarks = bookmarks;
+	details->save_job = job;
+
+	g_io_scheduler_push_job (save_job,
+				 job,
+				 NULL, /* destroy notify */
+				 0,    /* priority       */
+				 job->cancellable);
 }
 
 /**
diff --git a/src/nautilus-bookmark-list.h b/src/nautilus-bookmark-list.h
index 0f2dd0d..f569b11 100644
--- a/src/nautilus-bookmark-list.h
+++ b/src/nautilus-bookmark-list.h
@@ -31,8 +31,9 @@
 #include <libnautilus-private/nautilus-bookmark.h>
 #include <gio/gio.h>
 
-typedef struct NautilusBookmarkList NautilusBookmarkList;
-typedef struct NautilusBookmarkListClass NautilusBookmarkListClass;
+typedef struct _NautilusBookmarkList        NautilusBookmarkList;
+typedef struct _NautilusBookmarkListDetails NautilusBookmarkListDetails;
+typedef struct _NautilusBookmarkListClass   NautilusBookmarkListClass;
 
 #define NAUTILUS_TYPE_BOOKMARK_LIST \
 	(nautilus_bookmark_list_get_type ())
@@ -45,13 +46,12 @@ typedef struct NautilusBookmarkListClass NautilusBookmarkListClass;
 #define NAUTILUS_IS_BOOKMARK_LIST_CLASS(klass) \
 	(GTK_CHECK_CLASS_TYPE ((klass), NAUTILUS_TYPE_BOOKMARK_LIST))
 
-struct NautilusBookmarkList {
+struct _NautilusBookmarkList {
 	GtkObject object;
-	GList *list; 
-	GFileMonitor *monitor;
+	NautilusBookmarkListDetails *details;
 };
 
-struct NautilusBookmarkListClass {
+struct _NautilusBookmarkListClass {
 	GtkObjectClass parent_class;
 	void (* contents_changed) (NautilusBookmarkList *bookmarks);
 };
