rhythmbox r5825 - in trunk: . backends backends/gstreamer bindings/python lib metadata plugins plugins/audiocd plugins/audioscrobbler plugins/cd-recorder plugins/daap plugins/generic-player plugins/ipod plugins/iradio plugins/magnatune/magnatune plugins/mtpdevice plugins/rb po podcast remote/dbus rhythmdb shell sources tests widgets



Author: jmatthew
Date: Tue Jul 29 13:17:53 2008
New Revision: 5825
URL: http://svn.gnome.org/viewvc/rhythmbox?rev=5825&view=rev

Log:
2008-07-29  Jonathan Matthew  <jonathan d14n org>

	GIO port, 6+ months in the making.
	magnatune and jamendo plugins still need to be ported, and something
	still needs to happen with the mtp plugin too.

	* configure.ac:
	* backends/gstreamer/Makefile.am:
	* lib/Makefile.am:
	Increase required versions of glib and nautilus-cd-burner (for gio),
	and libsoup and gstreamer.  Drop howl mdns support.

	* lib/gsequence.c:
	* lib/gsequence.h:
	* shell/rb-history.c:
	* rhythmdb/rhythmdb-property-model.c:
	* rhythmdb/rhythmdb-query-model.c:
	Drop our internal copy of gsequence.  It was added to glib in 2.14, we
	require 2.16 now.

	* shell/Makefile.am:
	* backends/rb-player.c: (rb_player_new):
	* backends/gstreamer/rb-player-gst-xfade.c:
	(rb_player_gst_xfade_class_init),
	(rb_player_gst_xfade_handle_missing_plugin_message),
	(rb_player_gst_xfade_bus_cb):
	* backends/gstreamer/rb-player-gst.c: (rb_player_gst_class_init),
	(rb_player_gst_handle_missing_plugin_message),
	(rb_player_gst_bus_cb):
	Always compile in the crossfading player backend and GStreamer missing
	plugin support.

	* lib/rb-proxy-config.c: (rb_proxy_config_get_libsoup_uri):
	* lib/rb-proxy-config.h:
	* lib/rb-soup-compat.h:
	Drop libsoup 2.2.

	* backends/gstreamer/rb-encoder-gst.c:
	(rb_encoder_gst_emit_completed), (new_decoded_pad_cb),
	(prompt_for_overwrite), (attach_output_pipeline),
	(rb_encoder_gst_encode):
	Where possible, use giostreamsink.  When creating the output stream,
	prompt for overwriting if the target file already exists.  If
	giostreamsink can't write to the target location, use whatever sink
	gstreamer wants to use, without the overwrite prompt.

	* lib/eel-gconf-extensions.c:
	* lib/rb-file-helpers.c:
	* lib/rb-file-helpers.h:
	* lib/rb-util.c:
	* lib/rb-util.h:
	Rewrite file helper functions using gio, dropping some we don't need
	any more (rb_uri_resolve_relative, mostly).  rb_uri_handle_recursively
	and rb_uri_handle_recursively_async are now mostly our own
	implementation, as gio doesn't provide anything like these functions.
	Add some functions to check for free space on the drive containing a
	directory, and something like g_file_make_directory_with_parents.

	Leave URI canonicalisation up to gio entirely - just create a GFile
	from the URI (or whatever) and extract the URI from it.

	* metadata/rb-metadata-dbus-service.c: (main):
	* metadata/rb-metadata-gst.c: (rb_metadata_init),
	(make_undecodable_error), (rb_metadata_gst_unknown_type_cb),
	(rb_metadata_handle_missing_plugin_message),
	(rb_metadata_bus_handler), (rb_metadata_load), (rb_metadata_save),
	(rb_metadata_has_missing_plugins),
	(rb_metadata_get_missing_plugins):
	* metadata/rb-metadata.h:
	Remove gnome-vfs and gnome-authentication calls, remove #ifdefs for
	missing plugin support, and use giostreamsink to create temporary
	tag-writing output files and rename them over the original file.

	* plugins/Makefile.am:
	* plugins/audiocd/rb-audiocd-plugin.c:
	* plugins/audiocd/rb-audiocd-source.c:
	* plugins/audiocd/rb-audiocd-source.h:
	* plugins/audiocd/sj-metadata-musicbrainz.c:
	Instead of nautilus-cd-burner, ask HAL to identify audio CDs for us.
	n-c-b wasn't really helping us much here.

	* plugins/audioscrobbler/rb-audioscrobbler-entry.c:
	* plugins/audioscrobbler/rb-audioscrobbler-entry.h:
	* plugins/audioscrobbler/rb-audioscrobbler.c:
	* plugins/audioscrobbler/rb-lastfm-source.c:
	Drop libsoup 2.2 compatibility, use gio to load and save the queue
	file.

	* plugins/cd-recorder/rb-cd-recorder-plugin.c:
	* plugins/cd-recorder/rb-playlist-source-recorder.c:
	* plugins/cd-recorder/rb-recorder-gst.c:
	Drop heaps of #ifdefs for old n-c-b versions, move free space checks
	to rb-util.

	* plugins/daap/Makefile.am:
	* plugins/daap/rb-daap-connection.c:
	* plugins/daap/rb-daap-plugin.c:
	* plugins/daap/rb-daap-share.c:
	* plugins/daap/rb-daap-src.c:
	* plugins/daap/rb-daap-mdns-browser-howl.c:
	* plugins/daap/rb-daap-mdns-publisher-howl.c:
	Drop howl mdns and libsoup 2.2 support.  Use gio to send files to
	clients.

	* plugins/generic-player/rb-generic-player-playlist-source.c:
	* plugins/generic-player/rb-generic-player-plugin.c:
	* plugins/generic-player/rb-generic-player-source.c:
	* plugins/generic-player/rb-generic-player-source.h:
	* plugins/generic-player/rb-nokia770-source.c:
	* plugins/generic-player/rb-nokia770-source.h:
	* plugins/generic-player/rb-psp-source.c:
	* plugins/generic-player/rb-psp-source.h:
	Rewrite all file handling code with gio, create sources based off
	GMounts.  Probably not using the right drive/volume name yet.
	PSP and nokia770 sources are completely untested.

	* plugins/ipod/rb-ipod-db.c:
	* plugins/ipod/rb-ipod-db.h:
	* plugins/ipod/rb-ipod-plugin.c:
	* plugins/ipod/rb-ipod-source.c:
	* plugins/ipod/rb-ipod-source.h:
	Rewrite file/path handling code with gio.

	* plugins/iradio/rb-iradio-source.c:
	* plugins/iradio/rb-station-properties-dialog.c:
	Use gio URI/file functions, replace gnome_vfs_uri_list_parse with
	rb_uri_list_parse.

	* plugins/magnatune/magnatune/BuyAlbumHandler.py:
	* plugins/magnatune/magnatune/__init__.py:
	Remove unnecessary gnomevfs imports

	* plugins/mtpdevice/rb-mtp-plugin.c:
	* plugins/mtpdevice/rb-mtp-source.c:
	Rewrite some file handling code using gio, use new free space checking
	function in rb-file-helpers.

	* plugins/rb-plugins-engine.c:
	Rewrite plugin scanning code with gio.

	* plugins/rb/Loader.py:
	Add a gio loader implementation that probably doesn't work, drop the
	urllib implementation (we'll require a new enough version of pygobject
	to allow us to just use the gio implementation soon)

	* podcast/rb-feed-podcast-properties-dialog.c:
	* podcast/rb-podcast-manager.c:
	* podcast/rb-podcast-parse.c:
	* podcast/rb-podcast-properties-dialog.c:
	* podcast/test-podcast-parse.c: (main):
	gio doesn't provide anything like gnome_vfs_async_xfer (thankfully!),
	so add our own simple download thread.  Implement simple easily-fooled
	download resume by seeking to an offset equal to the current size of
	the local file.  Rewrite content type checking and URI display code
	with gio.

	* remote/dbus/Makefile.am:
	* remote/dbus/rb-client.c: (main):
	Remove glib version checks, rewrite argument handling using gio.

	* rhythmdb/rhythmdb-import-job.c:
	Update for rb_uri_handle_recursively_async changes, use a GCancellable
	to cancel the import.
	
	* rhythmdb/rhythmdb-monitor.c:
	Use gio file/directory monitoring.  Not quite using it fully yet -
	G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT is probably useful.

	* rhythmdb/rhythmdb-tree.c:
	Bump database format number, as URIs need to be canonicalised yet
	again.  Use a GCancellable to cancel loading.

	* rhythmdb/Makefile.am:
	* rhythmdb/rhythmdb-private.h:
	* lib/rb-marshal.list:
	* rhythmdb/rhythmdb.c:
	* rhythmdb/rhythmdb.h:
	gio doesn't have a 'stat 10000 files' function, so implement it ourselves
	with a thread.  Attempt to mount volumes as required, emitting a
	signal to create a mount operation (rhythmdb theoretically shouldn't
	use gtk).  Move directory recursion into the action thread, rather
	than creating a new thread each time.  Use GSlice to allocate
	RhythmDBEvent and RhythmDBAction structures; we often have quite a lot
	of them.  Remove the gnome-vfs trash code, leaving the gio code added
	before 0.11.5.

	* shell/main.c: (main), (load_uri_args):
	Remove gnome authentication manager calls.  Use gio to process
	commandline args.

	* shell/rb-missing-plugins.c: (rb_missing_plugins_init):
	* shell/rb-playlist-manager.c:
	* shell/rb-shell-player.c: (rb_shell_player_class_init),
	(volume_pre_unmount_cb), (rb_shell_player_init),
	(missing_plugins_cb):
	* shell/rb-shell-preferences.c: (help_cb),
	(rb_shell_preferences_init), (rb_shell_preferences_sync):
	* shell/rb-shell.c: (rb_shell_create_mount_op_cb), (construct_db),
	(rb_shell_cmd_contents), (rb_shell_load_uri):
	* shell/rb-tray-icon.c: (rb_tray_icon_drop_cb):
	Various bits of rewriting for gio.  With new enough gtk+, use
	gtk_show_uri to display help rather than gnome_help_display, and
	create gtk mount operations when requested by rhythmdb.

	* bindings/python/rb.override:
	* shell/rb-removable-media-manager.c:
	* shell/rb-removable-media-manager.h:
	* sources/rb-removable-media-source.c:
	Use gio's drive/volume/mount monitor.  Handle both mounts and volumes
	because in some cases (audio CDs, mostly) we don't require the volume
	to be mounted, but mostly we do.  If a source is created for a volume,
	don't allow one to be created for the corresponding mount, and vice
	versa.  When asked to 'eject', first try ejecting the volume, then the
	mount, and then unmount instead.  If eject or unmount fails, don't
	remove the corresponding source.

	* sources/rb-auto-playlist-source.c:
	* sources/rb-browser-source.c:
	* sources/rb-library-source.c:
	* sources/rb-play-queue-source.c:
	* sources/rb-playlist-source.c:
	* sources/rb-podcast-source.c:
	* sources/rb-static-playlist-source.c:
	Rewrite file handling, URI formatting, list parsing, etc. code with
	gio equivalents.

	* widgets/rb-entry-view.c: (rb_entry_view_location_cell_data_func):
	* widgets/rb-entry-view.h:
	* widgets/rb-property-view.c:
	* widgets/rb-query-creator-properties.c:
	(escapedStringCriteriaSetWidgetData),
	(escapedStringCriteriaGetWidgetData):
	* widgets/rb-song-info.c: (rb_song_info_update_filesize),
	(rb_song_info_update_location):
	* widgets/rb-uri-dialog.c:
	Replace gnome-vfs URI formatting and unescaping functions with gio
	equivalents.

	* tests/bench-rhythmdb-load.c: (main):
	* tests/test-audioscrobbler.c: (START_TEST):
	* tests/test-file-helpers.c: (main):
	* tests/test-rhythmdb-property-model.c: (main):
	* tests/test-rhythmdb-query-model.c: (main):
	* tests/test-rhythmdb.c: (main):
	Update test programs, mostly removing gnome_vfs_init() and
	gnome_vfs_shutdown().

	* lib/rb-debug.c: (rb_debug_init_match):
	Add gio log domain to the set we handle to interrupt debuggers.

	From #510392, fixes #319758.


Removed:
   trunk/lib/gsequence.c
   trunk/lib/gsequence.h
   trunk/lib/rb-soup-compat.h
   trunk/plugins/daap/rb-daap-mdns-browser-howl.c
   trunk/plugins/daap/rb-daap-mdns-publisher-howl.c
Modified:
   trunk/ChangeLog
   trunk/backends/gstreamer/Makefile.am
   trunk/backends/gstreamer/rb-encoder-gst.c
   trunk/backends/gstreamer/rb-player-gst-xfade.c
   trunk/backends/gstreamer/rb-player-gst.c
   trunk/backends/rb-player.c
   trunk/bindings/python/rb.override
   trunk/configure.ac
   trunk/lib/Makefile.am
   trunk/lib/eel-gconf-extensions.c
   trunk/lib/rb-debug.c
   trunk/lib/rb-file-helpers.c
   trunk/lib/rb-file-helpers.h
   trunk/lib/rb-marshal.list
   trunk/lib/rb-proxy-config.c
   trunk/lib/rb-proxy-config.h
   trunk/lib/rb-util.c
   trunk/lib/rb-util.h
   trunk/metadata/rb-metadata-dbus-service.c
   trunk/metadata/rb-metadata-gst.c
   trunk/metadata/rb-metadata.h
   trunk/plugins/Makefile.am
   trunk/plugins/audiocd/rb-audiocd-plugin.c
   trunk/plugins/audiocd/rb-audiocd-source.c
   trunk/plugins/audiocd/rb-audiocd-source.h
   trunk/plugins/audiocd/sj-metadata-musicbrainz.c
   trunk/plugins/audioscrobbler/rb-audioscrobbler-entry.c
   trunk/plugins/audioscrobbler/rb-audioscrobbler-entry.h
   trunk/plugins/audioscrobbler/rb-audioscrobbler.c
   trunk/plugins/audioscrobbler/rb-lastfm-source.c
   trunk/plugins/cd-recorder/rb-cd-recorder-plugin.c
   trunk/plugins/cd-recorder/rb-playlist-source-recorder.c
   trunk/plugins/cd-recorder/rb-recorder-gst.c
   trunk/plugins/daap/Makefile.am
   trunk/plugins/daap/rb-daap-connection.c
   trunk/plugins/daap/rb-daap-plugin.c
   trunk/plugins/daap/rb-daap-share.c
   trunk/plugins/daap/rb-daap-src.c
   trunk/plugins/generic-player/rb-generic-player-playlist-source.c
   trunk/plugins/generic-player/rb-generic-player-plugin.c
   trunk/plugins/generic-player/rb-generic-player-source.c
   trunk/plugins/generic-player/rb-generic-player-source.h
   trunk/plugins/generic-player/rb-nokia770-source.c
   trunk/plugins/generic-player/rb-nokia770-source.h
   trunk/plugins/generic-player/rb-psp-source.c
   trunk/plugins/generic-player/rb-psp-source.h
   trunk/plugins/ipod/rb-ipod-db.c
   trunk/plugins/ipod/rb-ipod-db.h
   trunk/plugins/ipod/rb-ipod-plugin.c
   trunk/plugins/ipod/rb-ipod-source.c
   trunk/plugins/ipod/rb-ipod-source.h
   trunk/plugins/iradio/rb-iradio-source.c
   trunk/plugins/iradio/rb-station-properties-dialog.c
   trunk/plugins/magnatune/magnatune/BuyAlbumHandler.py
   trunk/plugins/magnatune/magnatune/__init__.py
   trunk/plugins/mtpdevice/rb-mtp-plugin.c
   trunk/plugins/mtpdevice/rb-mtp-source.c
   trunk/plugins/rb-plugins-engine.c
   trunk/plugins/rb/Loader.py
   trunk/po/ChangeLog
   trunk/po/POTFILES.in
   trunk/podcast/rb-feed-podcast-properties-dialog.c
   trunk/podcast/rb-podcast-manager.c
   trunk/podcast/rb-podcast-parse.c
   trunk/podcast/rb-podcast-properties-dialog.c
   trunk/podcast/test-podcast-parse.c
   trunk/remote/dbus/Makefile.am
   trunk/remote/dbus/rb-client.c
   trunk/rhythmdb/Makefile.am
   trunk/rhythmdb/rhythmdb-import-job.c
   trunk/rhythmdb/rhythmdb-monitor.c
   trunk/rhythmdb/rhythmdb-private.h
   trunk/rhythmdb/rhythmdb-property-model.c
   trunk/rhythmdb/rhythmdb-query-model.c
   trunk/rhythmdb/rhythmdb-tree.c
   trunk/rhythmdb/rhythmdb.c
   trunk/rhythmdb/rhythmdb.h
   trunk/shell/Makefile.am
   trunk/shell/main.c
   trunk/shell/rb-history.c
   trunk/shell/rb-missing-plugins.c
   trunk/shell/rb-playlist-manager.c
   trunk/shell/rb-removable-media-manager.c
   trunk/shell/rb-removable-media-manager.h
   trunk/shell/rb-shell-player.c
   trunk/shell/rb-shell-preferences.c
   trunk/shell/rb-shell.c
   trunk/shell/rb-tray-icon.c
   trunk/sources/rb-auto-playlist-source.c
   trunk/sources/rb-browser-source.c
   trunk/sources/rb-library-source.c
   trunk/sources/rb-play-queue-source.c
   trunk/sources/rb-playlist-source.c
   trunk/sources/rb-podcast-source.c
   trunk/sources/rb-removable-media-source.c
   trunk/sources/rb-static-playlist-source.c
   trunk/tests/bench-rhythmdb-load.c
   trunk/tests/test-audioscrobbler.c
   trunk/tests/test-file-helpers.c
   trunk/tests/test-rhythmdb-property-model.c
   trunk/tests/test-rhythmdb-query-model.c
   trunk/tests/test-rhythmdb.c
   trunk/widgets/rb-entry-view.c
   trunk/widgets/rb-entry-view.h
   trunk/widgets/rb-property-view.c
   trunk/widgets/rb-query-creator-properties.c
   trunk/widgets/rb-song-info.c
   trunk/widgets/rb-uri-dialog.c

Modified: trunk/backends/gstreamer/Makefile.am
==============================================================================
--- trunk/backends/gstreamer/Makefile.am	(original)
+++ trunk/backends/gstreamer/Makefile.am	Tue Jul 29 13:17:53 2008
@@ -5,10 +5,13 @@
 librbbackendsgstreamer_la_SOURCES =			\
 	rb-player-gst.h					\
 	rb-player-gst.c					\
+	rb-player-gst-xfade.h				\
+	rb-player-gst-xfade.c				\
 	$(NULL)
 
 librbbackendsgstreamer_la_LIBADD =			\
 	-lgstpbutils-0.10				\
+	-lgstcontroller-0.10
 	$(RHYTHMBOX_LIBS)
 
 librbbackendsgstreamer_la_LDFLAGS = -export-dynamic
@@ -31,9 +34,3 @@
 	rb-encoder-gst.c
 endif
 
-if USE_GSTREAMER_0_10_XFADE
-librbbackendsgstreamer_la_SOURCES +=	\
-	rb-player-gst-xfade.h		\
-	rb-player-gst-xfade.c
-librbbackendsgstreamer_la_LIBADD += -lgstcontroller-0.10
-endif

Modified: trunk/backends/gstreamer/rb-encoder-gst.c
==============================================================================
--- trunk/backends/gstreamer/rb-encoder-gst.c	(original)
+++ trunk/backends/gstreamer/rb-encoder-gst.c	Tue Jul 29 13:17:53 2008
@@ -34,15 +34,12 @@
 #include <config.h>
 
 #include <glib/gi18n.h>
-#include <libgnomevfs/gnome-vfs-utils.h>
-#include <libgnomevfs/gnome-vfs-uri.h>
-#include <libgnomevfs/gnome-vfs-ops.h>
 #include <gst/gst.h>
 #include <gst/tag/tag.h>
 #include <string.h>
 #include <profiles/gnome-media-profiles.h>
 #include <gtk/gtk.h>
-
+#include <gio/gio.h>
 
 #include "rhythmdb.h"
 #include "eel-gconf-extensions.h"
@@ -51,6 +48,7 @@
 #include "rb-encoder-gst.h"
 #include "rb-debug.h"
 #include "rb-util.h"
+#include "rb-file-helpers.h"
 
 static void rb_encoder_gst_class_init (RBEncoderGstClass *klass);
 static void rb_encoder_gst_init       (RBEncoderGst *encoder);
@@ -182,8 +180,8 @@
 {
 	GError *error = NULL;
 	guint64 dest_size;
-	GnomeVFSFileInfo *file_info;
-	GnomeVFSResult result;
+	GFile *file;
+	GFileInfo *file_info;
 
 	g_return_if_fail (encoder->priv->completion_emitted == FALSE);
 
@@ -205,19 +203,21 @@
 		g_error_free (error);
 	}
 
-	/* find the size of the output file, assuming we can get at it with gnome-vfs */
+	/* find the size of the output file, assuming we can get at it with gio */
 	dest_size = 0;
-	file_info = gnome_vfs_file_info_new ();
-	result = gnome_vfs_get_file_info (encoder->priv->dest_uri, file_info, GNOME_VFS_FILE_INFO_FOLLOW_LINKS);
-	if (result == GNOME_VFS_OK && (file_info->valid_fields & GNOME_VFS_FILE_INFO_FIELDS_SIZE)) {
-		dest_size = file_info->size;
-		rb_debug ("destination file size: %" G_GUINT64_FORMAT, dest_size);
-	} else {
+	file = g_file_new_for_uri (encoder->priv->dest_uri);
+	file_info = g_file_query_info (file, G_FILE_ATTRIBUTE_STANDARD_SIZE, G_FILE_QUERY_INFO_NONE, NULL, &error);
+	if (error != NULL) {
 		rb_debug ("couldn't get size of destination %s: %s",
 			  encoder->priv->dest_uri,
-			  gnome_vfs_result_to_string (result));
+			  error->message);
+		g_clear_error (&error);
+	} else {
+		dest_size = g_file_info_get_attribute_uint64 (file_info, G_FILE_ATTRIBUTE_STANDARD_SIZE);
+		rb_debug ("destination file size: %" G_GUINT64_FORMAT, dest_size);
+		g_object_unref (file_info);
 	}
-	gnome_vfs_file_info_unref (file_info);
+	g_object_unref (file);
 
 	encoder->priv->completion_emitted = TRUE;
 	_rb_encoder_emit_completed (RB_ENCODER (encoder), dest_size);
@@ -488,34 +488,8 @@
 	return result;
 }
 
-static gboolean
-gnomevfs_allow_overwrite_cb (GstElement *element, GnomeVFSURI *uri, RBEncoderGst *encoder)
-{
-	GtkWidget *dialog;
-	gint response;
-	char *name;
-	char *display_name;
-
-	name = gnome_vfs_uri_to_string (uri, GNOME_VFS_URI_HIDE_USER_NAME | GNOME_VFS_URI_HIDE_PASSWORD);
-	display_name = gnome_vfs_format_uri_for_display (name);
-
-	dialog = gtk_message_dialog_new (NULL, 0,
-					 GTK_MESSAGE_QUESTION, GTK_BUTTONS_YES_NO,
-					 _("Do you want to overwrite the file \"%s\"?"),
-					 display_name);
-	response = gtk_dialog_run (GTK_DIALOG (dialog));
-	gtk_widget_destroy (dialog);
-
-	g_free (display_name);
-	g_free (name);
-
-	return (response == GTK_RESPONSE_YES);
-}
-
 static void
-new_decoded_pad_cb (GstElement *decodebin,
-		GstPad *new_pad, gboolean arg1,
-		RBEncoderGst *encoder)
+new_decoded_pad_cb (GstElement *decodebin, GstPad *new_pad, gboolean arg1, RBEncoderGst *encoder)
 {
 	GstPad *enc_sinkpad;
 	GstCaps *caps;
@@ -574,22 +548,95 @@
 }
 
 static gboolean
+prompt_for_overwrite (GFile *file)
+{
+	GtkWidget *dialog;
+	GFileInfo *info;
+	gint response;
+	char *free_name;
+	const char *display_name;
+
+	free_name = NULL;
+	display_name = NULL;
+	info = g_file_query_info (file,
+				  G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME,
+				  G_FILE_QUERY_INFO_NONE,
+				  NULL,
+				  NULL);
+	if (info != NULL) {
+		display_name = g_file_info_get_display_name (info);
+		g_object_unref (info);
+	}
+
+	if (display_name == NULL) {
+		free_name = g_file_get_uri (file);
+		display_name = free_name;
+	}
+
+	dialog = gtk_message_dialog_new (NULL, 0,
+					 GTK_MESSAGE_QUESTION, GTK_BUTTONS_YES_NO,
+					 _("Do you want to overwrite the file \"%s\"?"),
+					 display_name);
+	response = gtk_dialog_run (GTK_DIALOG (dialog));
+	gtk_widget_destroy (dialog);
+	g_free (free_name);
+
+	return (response == GTK_RESPONSE_YES);
+}
+
+static gboolean
 attach_output_pipeline (RBEncoderGst *encoder,
 			GstElement *end,
 			const char *dest,
 			GError **error)
 {
+	GFile *file;
+	GFileOutputStream *stream;
 	GstElement *sink;
+	GError *local_error = NULL;
 
-	sink = gst_element_make_from_uri (GST_URI_SINK, dest, "sink");
-
-	/* handle overwriting if we are using gnomevfssink
-	 * it would be nice if GST had an interface for sinks with thi, but it doesn't
+	/* if we can get to the location with gio, open the file here
+	 * (prompting for overwrite if it already exists) and use giostreamsink.
+	 * otherwise, create whatever sink element we can.
 	 */
-	if (g_type_is_a (G_OBJECT_TYPE (sink), g_type_from_name ("GstGnomeVFSSink"))) {
-		g_signal_connect_object (G_OBJECT (sink),
-					 "allow-overwrite", G_CALLBACK (gnomevfs_allow_overwrite_cb),
-					 encoder, 0);
+	file = g_file_new_for_uri (dest);
+	
+	sink = NULL;
+	stream = g_file_create (file, G_FILE_CREATE_NONE, NULL, &local_error);
+	if (local_error != NULL) {
+		if (g_error_matches (local_error,
+				     G_IO_ERROR,
+				     G_IO_ERROR_NOT_SUPPORTED)) {
+			rb_debug ("gio can't write to %s, so using whatever sink will work", dest);
+			sink = gst_element_make_from_uri (GST_URI_SINK, dest, "sink");
+			if (sink == NULL) {
+				g_propagate_error (error, local_error);		/* close enough */
+				return FALSE;
+			} else {
+				g_error_free (local_error);
+			}
+		} else if (g_error_matches (local_error,
+					    G_IO_ERROR,
+					    G_IO_ERROR_EXISTS)) {
+			if (prompt_for_overwrite (file)) {
+				g_error_free (local_error);
+				stream = g_file_replace (file, NULL, FALSE, G_FILE_CREATE_NONE, NULL, error);
+				if (stream == NULL) {
+					return FALSE;
+				}
+			} else {
+				g_propagate_error (error, local_error);
+				return FALSE;
+			}
+		} else {
+			g_propagate_error (error, local_error);
+			return FALSE;
+		}
+	}
+
+	if (sink == NULL) {
+		sink = gst_element_factory_make ("giostreamsink", NULL);
+		g_object_set (sink, "stream", stream, NULL);
 	}
 
 	gst_bin_add (GST_BIN (encoder->priv->pipeline), sink);
@@ -935,41 +982,6 @@
 	return FALSE;
 }
 
-static GnomeVFSResult
-create_parent_dirs_uri (GnomeVFSURI *uri)
-{
-	GnomeVFSURI *parent_uri;
-	GnomeVFSResult result;
-
-	if (gnome_vfs_uri_exists (uri))
-		return GNOME_VFS_OK;
-
-	parent_uri = gnome_vfs_uri_get_parent (uri);
-	result = create_parent_dirs_uri (parent_uri);
-	gnome_vfs_uri_unref (parent_uri);
-	if (result != GNOME_VFS_OK)
-		return result;
-
-	return gnome_vfs_make_directory_for_uri (uri, 0750);
-}
-
-static GnomeVFSResult
-create_parent_dirs (const char *uri)
-{
-	GnomeVFSURI *vfs_uri;
-	GnomeVFSURI *parent_uri;
-	GnomeVFSResult result;
-
-	vfs_uri = gnome_vfs_uri_new (uri);
-	parent_uri = gnome_vfs_uri_get_parent (vfs_uri);
-
-	result = create_parent_dirs_uri (parent_uri);
-
-	gnome_vfs_uri_unref (parent_uri);
-	gnome_vfs_uri_unref (vfs_uri);
-	return result;
-}
-
 static void
 rb_encoder_gst_cancel (RBEncoder *encoder)
 {
@@ -997,7 +1009,6 @@
 	gboolean was_raw;
 	gboolean result;
 	GError *error = NULL;
-	GnomeVFSResult vfsresult;
 
 	g_return_val_if_fail (priv->pipeline == NULL, FALSE);
 
@@ -1017,11 +1028,10 @@
 		entry_mime_type = "audio/flac";
 	}
 
-	vfsresult = create_parent_dirs (dest);
-	if (vfsresult != GNOME_VFS_OK) {
+	if (rb_uri_create_parent_dirs (dest, &error) == FALSE) {
 		error = g_error_new_literal (RB_ENCODER_ERROR,
 					     RB_ENCODER_ERROR_FILE_ACCESS,
-					     gnome_vfs_result_to_string (vfsresult));
+					     error->message);		/* I guess */
 
 		_rb_encoder_emit_error (encoder, error);
 		_rb_encoder_emit_completed (encoder, 0);

Modified: trunk/backends/gstreamer/rb-player-gst-xfade.c
==============================================================================
--- trunk/backends/gstreamer/rb-player-gst-xfade.c	(original)
+++ trunk/backends/gstreamer/rb-player-gst-xfade.c	Tue Jul 29 13:17:53 2008
@@ -159,10 +159,7 @@
 #include <gst/gst.h>
 #include <gst/controller/gstcontroller.h>
 #include <gst/base/gstbasetransform.h>
-
-#ifdef HAVE_GSTREAMER_0_10_MISSING_PLUGINS
 #include <gst/pbutils/pbutils.h>
-#endif /* HAVE_GSTREAMER_0_10_MISSING_PLUGINS */
 
 #include "rb-player.h"
 #include "rb-player-gst-xfade.h"
@@ -326,10 +323,9 @@
 	gboolean emitted_error;
 	gulong error_idle_id;
 	GError *error;
-#ifdef HAVE_GSTREAMER_0_10_MISSING_PLUGINS
+
 	GSList *missing_plugins;
 	gulong  emit_missing_plugins_id;
-#endif
 } RBXFadeStream;
 
 #define RB_TYPE_XFADE_STREAM 	(rb_xfade_stream_get_type ())
@@ -662,7 +658,6 @@
 			      G_TYPE_NONE,
 			      3,
 			      G_TYPE_STRING, G_TYPE_STRING, GST_TYPE_ELEMENT);
-#ifdef HAVE_GSTREAMER_0_10_MISSING_PLUGINS
 	signals[MISSING_PLUGINS] =
 		g_signal_new ("missing-plugins",
 			      G_OBJECT_CLASS_TYPE (object_class),
@@ -673,7 +668,6 @@
 			      G_TYPE_NONE,
 			      3,
 			      G_TYPE_POINTER, G_TYPE_STRV, G_TYPE_STRV);
-#endif
 
 	g_type_class_add_private (klass, sizeof (RBPlayerGstXFadePrivate));
 }
@@ -1472,7 +1466,6 @@
 	g_value_unset (&newval);
 }
 
-#ifdef HAVE_GSTREAMER_0_10_MISSING_PLUGINS
 
 static gboolean
 emit_missing_plugins (RBXFadeStream *stream)
@@ -1548,7 +1541,6 @@
 		break;
 	}
 }
-#endif
 
 /* gstreamer message bus callback */
 static gboolean
@@ -1725,12 +1717,10 @@
 		const GstStructure *s;
 		const char *name;
 
-#ifdef HAVE_GSTREAMER_0_10_MISSING_PLUGINS
 		if (gst_is_missing_plugin_message (message)) {
 			rb_player_gst_xfade_handle_missing_plugin_message (player, stream, message);
 			break;
 		}
-#endif
 
 		s = gst_message_get_structure (message);
 		name = gst_structure_get_name (s);

Modified: trunk/backends/gstreamer/rb-player-gst.c
==============================================================================
--- trunk/backends/gstreamer/rb-player-gst.c	(original)
+++ trunk/backends/gstreamer/rb-player-gst.c	Tue Jul 29 13:17:53 2008
@@ -37,12 +37,7 @@
 #include <glib/gi18n.h>
 #include <gdk/gdk.h>
 #include <gst/tag/tag.h>
-#include <libgnomevfs/gnome-vfs-ops.h>
-#include <libgnomevfs/gnome-vfs-utils.h>
-
-#ifdef HAVE_GSTREAMER_0_10_MISSING_PLUGINS
 #include <gst/pbutils/pbutils.h>
-#endif /* HAVE_GSTREAMER_0_10_MISSING_PLUGINS */
 
 #include "rb-debug.h"
 #include "rb-marshal.h"
@@ -102,7 +97,6 @@
 	PROP_PLAYBIN
 };
 
-#ifdef HAVE_GSTREAMER_0_10_MISSING_PLUGINS
 enum
 {
 	MISSING_PLUGINS,
@@ -110,7 +104,6 @@
 };
 
 static guint signals[LAST_SIGNAL] = { 0 };
-#endif
 
 struct _RBPlayerGstPrivate
 {
@@ -183,7 +176,6 @@
 							      GST_TYPE_ELEMENT,
 							      G_PARAM_READABLE));
 	
-#ifdef HAVE_GSTREAMER_0_10_MISSING_PLUGINS
 	signals[MISSING_PLUGINS] =
 		g_signal_new ("missing-plugins",
 			      G_OBJECT_CLASS_TYPE (object_class),
@@ -194,7 +186,6 @@
 			      G_TYPE_NONE,
 			      3,
 			      G_TYPE_POINTER, G_TYPE_STRV, G_TYPE_STRV);
-#endif
 
 	g_type_class_add_private (klass, sizeof (RBPlayerGstPrivate));
 }
@@ -425,7 +416,6 @@
 	g_hash_table_insert (player->priv->idle_info_ids, GUINT_TO_POINTER (signal->id), NULL);
 }
 
-#ifdef HAVE_GSTREAMER_0_10_MISSING_PLUGINS
 static void
 rb_player_gst_handle_missing_plugin_message (RBPlayerGst *player, GstMessage *message)
 {
@@ -459,7 +449,6 @@
 
 	gst_message_unref (message);
 }
-#endif
 
 static gboolean
 rb_player_gst_bus_cb (GstBus * bus, GstMessage * message, RBPlayerGst *mp)
@@ -576,14 +565,12 @@
 		g_value_set_string (signal->info, gst_structure_get_name (structure));
 		g_idle_add ((GSourceFunc) emit_signal_idle, signal);
 	}
-#ifdef HAVE_GSTREAMER_0_10_MISSING_PLUGINS
 	case GST_MESSAGE_ELEMENT: {
 		if (gst_is_missing_plugin_message (message)) {
 			rb_player_gst_handle_missing_plugin_message (mp, message);
 		}
 		break;
 	}
-#endif
 	default:
 		break;
 	}

Modified: trunk/backends/rb-player.c
==============================================================================
--- trunk/backends/rb-player.c	(original)
+++ trunk/backends/rb-player.c	Tue Jul 29 13:17:53 2008
@@ -510,11 +510,9 @@
 RBPlayer*
 rb_player_new (gboolean want_crossfade, GError **error)
 {
-#ifdef HAVE_GSTREAMER_0_10_XFADE
 	if (want_crossfade)
 		return rb_player_gst_xfade_new (error);
 	else
-#endif
 		return rb_player_gst_new (error);
 }
 

Modified: trunk/bindings/python/rb.override
==============================================================================
--- trunk/bindings/python/rb.override	(original)
+++ trunk/bindings/python/rb.override	Tue Jul 29 13:17:53 2008
@@ -1343,7 +1343,7 @@
    	mimes = _helper_unwrap_string_pylist (py_mimes, FALSE);
 
 	rb_removable_media_manager_queue_transfer(RB_REMOVABLE_MEDIA_MANAGER(self->obj), entry, dest, mimes,
-		(RBTranferCompleteCallback)_rb_removable_media_manager_queue_transfer_func, data);
+		(RBTransferCompleteCallback)_rb_removable_media_manager_queue_transfer_func, data);
 
 	g_list_free (mimes);
 	Py_INCREF(Py_None);

Modified: trunk/configure.ac
==============================================================================
--- trunk/configure.ac	(original)
+++ trunk/configure.ac	Tue Jul 29 13:17:53 2008
@@ -26,16 +26,14 @@
 AC_CHECK_SIZEOF(long)
 
 DBUS_MIN_REQS=0.35
-GST_0_10_REQS=0.10.4
-GST_0_10_XFADE_REQS=0.10.12
-GST_0_10_MISSING_PLUGIN_REQS=0.10.12
+GST_0_10_REQS=0.10.12
 GTK_REQS=2.8.0
+GLIB_REQS=2.15.5
 GNOME_MEDIA_PROFILES_REQS=2.8
-GNOME_VFS_REQS=2.8.0
 LIBNOTIFY_REQS=0.3.2
 LIBGPOD_REQS=0.6
 MUSICBRAINZ_REQS=2.1.0
-NCB_MIN_REQS=2.9.0
+NCB_MIN_REQS=2.21.6
 TOTEM_PLPARSER_REQS=2.22.0
 VALA_REQS=0.1.0
 
@@ -59,38 +57,22 @@
     mkdtemp_missing=true)
 AM_CONDITIONAL(MKDTEMP_MISSING, test x$mkdtemp_missing = xtrue)
 
-PKG_CHECK_MODULES(GLIB_TESTS, glib-2.0)
-AC_CHECK_LIB(glib-2.0, g_utf8_collate_key_for_filename,
-    [AC_DEFINE([HAVE_COLLATE_KEY_FILENAME], 1, [Have glib function to collate filename sort keys])],
-    ,[$GLIB_TESTS_LIBS $GLIB_TESTS_CFLAGS])
-AC_CHECK_LIB(glib-2.0, g_mapped_file_new,
-    [AC_DEFINE([HAVE_G_MAPPED_FILE], 1, [Have glib mmap wrapper])],
-    ,[$GLIB_TESTS_LIBS $GLIB_TESTS_CFLAGS])
-AC_CHECK_LIB(glib-2.0, g_get_user_special_dir,
-    [AC_DEFINE([HAVE_G_GET_USER_SPECIAL_DIR], 1, [Have glib function to find user special dirs])],
-    ,[$GLIB_TESTS_LIBS $GLIB_TESTS_CFLAGS])
-
 PKG_PROG_PKG_CONFIG
 
-PKG_CHECK_MODULES(RB_CLIENT, gnome-vfs-2.0 >= $GNOME_VFS_REQS)
+PKG_CHECK_MODULES(RB_CLIENT, glib-2.0 >= $GLIB_REQS gio-2.0 >= $GLIB_REQS)
 
 PKG_CHECK_MODULES(RHYTHMBOX,				\
 		  gtk+-2.0 >= $GTK_REQS			\
+		  glib-2.0 >= $GLIB_REQS		\
+		  gio-2.0 >= $GLIB_REQS			\
 		  libgnomeui-2.0			\
-		  libglade-2.0				\
-		  gnome-vfs-2.0 >= $GNOME_VFS_REQS	\
-		  gnome-vfs-module-2.0)
+		  libglade-2.0)
 
 PKG_CHECK_MODULES(TOTEM_PLPARSER, totem-plparser >= $TOTEM_PLPARSER_REQS, have_totem_plparser=yes, have_totem_plparser=no)
 if test x$have_totem_plparser != xyes; then
    AC_MSG_ERROR([totem playlist parsing library not found or too old])
 fi
 
-PKG_CHECK_MODULES(GIO, gio-2.0, have_gio=yes, have_gio=no)
-if test x$have_gio == "xyes"; then
-  AC_DEFINE(HAVE_GIO, 1, [Define to use gio instead of gnome-vfs (for trash only)])
-fi
-
 AC_ARG_WITH(hal,
 	      AC_HELP_STRING([--without-hal],
 			     [Disable HAL support]))
@@ -258,23 +240,6 @@
 RHYTHMBOX_CFLAGS="$RHYTHMBOX_CFLAGS $GSTREAMER_0_10_CFLAGS"
 RHYTHMBOX_LIBS="$RHYTHMBOX_LIBS $GSTREAMER_0_10_LIBS"
 
-PKG_CHECK_MODULES(GSTREAMER_0_10_XFADE, \
-	gstreamer-0.10 >= $GST_0_10_XFADE_REQS,
-	have_gstreamer_0_10_xfade=yes,have_gstreamer_0_10_xfade=no)
-
-if test x"$have_gstreamer_0_10_xfade" = xyes; then
-	AC_DEFINE(HAVE_GSTREAMER_0_10_XFADE,1,[Define if you want to use the crossfading GStreamer 0.10 backend])
-fi
-AM_CONDITIONAL(USE_GSTREAMER_0_10_XFADE, test x"$have_gstreamer_0_10_xfade" = xyes)
-
-PKG_CHECK_MODULES(GSTREAMER_0_10_MISSING_PLUGINS, \
-		  gstreamer-plugins-base-0.10 >= $GST_0_10_MISSING_PLUGIN_REQS,
-		  have_gstreamer_0_10_missing_plugins=yes,have_gstreamer_0_10_missing_plugins=no)
-if test x"$have_gstreamer_0_10_missing_plugins" = xyes; then
-	AC_DEFINE(HAVE_GSTREAMER_0_10_MISSING_PLUGINS,1,[Define if you want to enable GStreamer plugin installation])
-fi
-AM_CONDITIONAL(USE_GSTREAMER_0_10_MISSING_PLUGINS, test x"$have_gstreamer_0_10_missing_plugins" = xyes)
-
 dnl Tag writing
 AC_ARG_ENABLE(tag-writing,
 	      AC_HELP_STRING([--disable-tag-writing],
@@ -294,14 +259,14 @@
 			     [Disable Digital Audio Access Protocol (music sharing) in rhythmbox]))
 
 AC_ARG_WITH(mdns,
-   AC_HELP_STRING([--with-mdns=auto|howl|avahi],
+   AC_HELP_STRING([--with-mdns=auto|avahi],
    [Select the mDNS/DNS-SD implementation to use (default auto)]),,
    with_mdns=auto)
 
-have_howl=no
+#have_howl=no
 have_avahi=no
 have_mdns=no
-use_howl=no
+#use_howl=no
 use_avahi=no
 
 PKG_CHECK_MODULES(AVAHI,
@@ -322,11 +287,6 @@
    have_avahi=no
 fi
 
-PKG_CHECK_MODULES(HOWL,
-   howl,
-   have_howl=yes,
-   have_howl=no)
-
 if test x"$with_mdns" = xauto; then
    if test x"$have_avahi" = xyes; then
       MDNS_CFLAGS=$AVAHI_CFLAGS
@@ -341,33 +301,12 @@
       fi
 
       have_mdns=yes
-   elif test x"$have_howl" = xyes; then
-      MDNS_CFLAGS=$HOWL_CFLAGS
-      MDNS_LIBS=$HOWL_LIBS
-      AC_DEFINE(WITH_HOWL, 1, [Define if mDNS/DNS-SD implementation uses Howl])
-      use_howl=yes
-      AC_MSG_NOTICE([Detected Howl, using it for mDNS/DNS-SD])
-
-      have_mdns=yes
    fi
 fi
 
-if test x"$with_mdns" = xhowl; then
-   if test x"$have_howl" = xno; then
-      AC_MSG_ERROR([Howl explicitly requested but not found.  Install Howl or try --with-mdns=avahi])
-   fi
-
-   MDNS_CFLAGS=$HOWL_CFLAGS
-   MDNS_LIBS=$HOWL_LIBS
-   AC_DEFINE(WITH_HOWL, 1, [Define if mDNS/DNS-SD implementation uses Howl])
-   use_howl=yes
-   AC_MSG_NOTICE([Using Howl for mDNS/DNS-SD])
-   have_mdns=yes
-fi
-
 if test x"$with_mdns" = xavahi; then
    if test x"$have_avahi" = xno; then
-      AC_MSG_ERROR([Avahi explicitly requested but not found.  Install Avahi or try --with-mdns=howl])
+      AC_MSG_ERROR([Avahi explicitly requested but not found.])
    fi
 
    MDNS_CFLAGS=$AVAHI_CFLAGS
@@ -385,7 +324,6 @@
    have_mdns=yes
 fi
 
-AM_CONDITIONAL(USE_HOWL, test "x$use_howl" = "xyes")
 AM_CONDITIONAL(USE_AVAHI, test "x$use_avahi" = "xyes")
 
 AC_ARG_ENABLE(libnotify,
@@ -436,22 +374,10 @@
 		libsoup-2.4,
 		have_libsoup24=yes,
 		have_libsoup24=no)
-	if test x"$have_libsoup24" = "xno"; then
-		PKG_CHECK_MODULES(SOUP,
-			libsoup-2.2,
-			have_libsoup22=yes,
-			have_libsoup22=no)
-	fi
-	if test x"$have_libsoup24" = "xyes" || test x"$have_libsoup22" = "xyes"; then
+	if test x"$have_libsoup24" = "xyes"; then
 		have_libsoup=yes
 		AC_DEFINE(HAVE_LIBSOUP, 1, [Define if libsoup support is enabled])
 	fi
-	if test x"$have_libsoup24" = "xyes"; then
-		AC_DEFINE(HAVE_LIBSOUP_2_4, 1, [Define if libsoup 2.4 support is enabled])
-	fi
-	if test x"$have_libsoup22" = "xyes"; then
-		AC_DEFINE(HAVE_LIBSOUP_2_2, 1, [Define if libsoup 2.2 support is enabled])
-	fi
 fi
 
 AM_CONDITIONAL(USE_LIBSOUP, test x"$have_libsoup" = "xyes")
@@ -480,7 +406,7 @@
 		enable_daap=no
 	elif test x"$have_mdns" = xno; then
 		if test "x$enable_daap" = "xyes"; then
-			AC_MSG_ERROR([DAAP support explicitly requested, but no mDNS implementation found.  Install Howl or Avahi])
+			AC_MSG_ERROR([DAAP support explicitly requested, but no mDNS implementation found.  Install Avahi])
 		fi
 		enable_daap=no
 	else
@@ -553,19 +479,6 @@
     PKG_CHECK_MODULES(LIBNAUTILUS_BURN, [libnautilus-burn >= $NCB_MIN_REQS], have_libnautilus_burn=yes, have_libnautilus_burn=no)
 fi
 if test "x$have_libnautilus_burn" = xyes; then
-    AC_CHECK_LIB(nautilus-burn, nautilus_burn_drive_door_is_open,
-       [AC_DEFINE([HAVE_BURN_DRIVE_DOOR], 1, [Have nautilus-burn function to check drive door state])],
-       ,[$LIBNAUTILUS_BURN_LIBS $LIBNAUTILUS_BURN_CFLAGS])
-    AC_CHECK_LIB(nautilus-burn, nautilus_burn_drive_unref,
-       [AC_DEFINE([HAVE_BURN_DRIVE_UNREF], 1, [Have nautilus-burn 2.13 drive unref function])],
-       ,[$LIBNAUTILUS_BURN_LIBS $LIBNAUTILUS_BURN_CFLAGS])
-    AC_CHECK_LIB(nautilus-burn, nautilus_burn_drive_new_from_path,
-       [AC_DEFINE([HAVE_BURN_DRIVE_NEW_FROM_PATH], 1, [Have nautilus-burn 2.13 drive new_from_path function])],
-       ,[$LIBNAUTILUS_BURN_LIBS $LIBNAUTILUS_BURN_CFLAGS])
-    AC_CHECK_LIB(nautilus-burn, nautilus_burn_drive_get_write_speeds,
-       [AC_DEFINE([HAVE_BURN_DRIVE_GET_WRITE_SPEEDS], 1, [Have nautilus-burn 2.13 drive get_write_speeds])],
-       ,[$LIBNAUTILUS_BURN_LIBS $LIBNAUTILUS_BURN_CFLAGS])
-
     AC_DEFINE([HAVE_NAUTILUS_BURN], 1, [Have nautilus-burn])
 fi
 AM_CONDITIONAL(HAVE_NAUTILUS_BURN, test x$have_libnautilus_burn = xyes)
@@ -591,8 +504,6 @@
 
 AC_SUBST(RHYTHMBOX_CFLAGS)
 AC_SUBST(RHYTHMBOX_LIBS)
-AC_SUBST(RB_CLIENT_CFLAGS)
-AC_SUBST(RB_CLIENT_LIBS)
 
 AC_TRY_RUN([#include <time.h>
                 int main ()
@@ -682,18 +593,6 @@
 AM_CONDITIONAL(WITH_INTERNAL_LIBSEXY, test "x$with_internal_libsexy" = "xyes")
 
 
-dnl we've copies gsequence from glib 2.13, and should just link to that
-dnl if the system version has it
-AC_ARG_WITH(internal-gsequence,
-            AC_HELP_STRING([--with-internal-gsequence],
-			   [Build using internal cope of gsequence]),,
-	      with_internal_gsequence=no)
-if test "x$with_internal_gsequence" = "xno"; then
-	PKG_CHECK_MODULES(GLIB, glib-2.0 >= 2.13.0, with_internal_gsequence=no,
-		          with_internal_gsequence=yes)
-fi
-AM_CONDITIONAL(WITH_INTERNAL_GSEQUENCE, test "x$with_internal_gsequence" = "xyes")
-
 dnl warnings bits, copied from gnome-keyring configure.in
 dnl Turn on the additional warnings last, so -Werror doesn't affect other tests.
 
@@ -1123,12 +1022,6 @@
 	AC_MSG_NOTICE([** MusicBrainz support is enabled])
 fi
 
-if test x"$have_gstreamer_0_10_xfade" != xyes; then
-	AC_MSG_NOTICE([   Crossfading player is disabled])
-else
-	AC_MSG_NOTICE([** Crossfading player is enabled])
-fi
-
 if test x"$use_ipod" = xyes; then
 	if test x"$enable_ipod_writing" != xno; then
 		AC_MSG_NOTICE([** iPod integration enabled])
@@ -1149,11 +1042,7 @@
 	AC_MSG_NOTICE([   CD burning support disabled])
 fi
 if test x"$enable_daap" = xyes; then
-	if test x"$have_libsoup24" = "xyes"; then
-		AC_MSG_NOTICE([** DAAP (music sharing) support is enabled (using libsoup 2.4)])
-	elif test x"$have_libsoup22" = "xyes"; then
-		AC_MSG_NOTICE([** DAAP (music sharing) support is enabled (using libsoup 2.2)])
-	fi
+	AC_MSG_NOTICE([** DAAP (music sharing) support is enabled])
 else
 	AC_MSG_NOTICE([   DAAP (music sharing) support is disabled])
 fi
@@ -1183,11 +1072,7 @@
 	AC_MSG_NOTICE([   gnome-keyring support disabled])
 fi
 if test x"$enable_audioscrobbler" != xno; then
-	if test x"$have_libsoup24" = "xyes"; then
-		AC_MSG_NOTICE([** Audioscrobbler support enabled (using libsoup 2.4)])
-	elif test x"$have_libsoup22" = "xyes"; then
-		AC_MSG_NOTICE([** Audioscrobbler support enabled (using libsoup 2.2)])
-	fi
+	AC_MSG_NOTICE([** Audioscrobbler support enabled])
 else
 	AC_MSG_NOTICE([   Audioscrobbler support disabled])
 fi
@@ -1201,11 +1086,6 @@
 else
 	AC_MSG_NOTICE([** using system-wide libsexy])
 fi
-if test x"$with_internal_gsequence" = xyes; then
-	AC_MSG_NOTICE([   using internal copy of gsequence])
-else
-	AC_MSG_NOTICE([** using glib 2.13 version of gsequence])
-fi
 if test "x$enable_fm_radio" != xno; then
 	AC_MSG_NOTICE([** FM radio support enabled])
 else

Modified: trunk/lib/Makefile.am
==============================================================================
--- trunk/lib/Makefile.am	(original)
+++ trunk/lib/Makefile.am	Tue Jul 29 13:17:53 2008
@@ -34,12 +34,7 @@
 	rb-string-value-map.c				\
 	rb-string-value-map.h				\
 	rb-async-queue-watch.c				\
-	rb-async-queue-watch.h				\
-	rb-soup-compat.h
-
-if WITH_INTERNAL_GSEQUENCE
-librb_la_SOURCES += gsequence.c gsequence.h
-endif
+	rb-async-queue-watch.h
 
 INCLUDES =						\
 	-DGNOMELOCALEDIR=\""$(datadir)/locale"\"        \

Modified: trunk/lib/eel-gconf-extensions.c
==============================================================================
--- trunk/lib/eel-gconf-extensions.c	(original)
+++ trunk/lib/eel-gconf-extensions.c	Tue Jul 29 13:17:53 2008
@@ -26,7 +26,7 @@
 #include <stdlib.h>
 #include <gconf/gconf-client.h>
 #include <gconf/gconf.h>
-#include <libgnome/gnome-i18n.h>
+#include <glib/gi18n.h>
 
 #include "eel-gconf-extensions.h"
 #include "rb-dialog.h"

Modified: trunk/lib/rb-debug.c
==============================================================================
--- trunk/lib/rb-debug.c	(original)
+++ trunk/lib/rb-debug.c	Tue Jul 29 13:17:53 2008
@@ -203,6 +203,7 @@
 		"libglade",
 		"libgnomevfs",
 		"librsvg",
+		"GLib-GIO",
 	};
 
 	debug_match = match;

Modified: trunk/lib/rb-file-helpers.c
==============================================================================
--- trunk/lib/rb-file-helpers.c	(original)
+++ trunk/lib/rb-file-helpers.c	Tue Jul 29 13:17:53 2008
@@ -29,18 +29,15 @@
 
 #include <gtk/gtk.h>
 #include <glib.h>
+#include <glib/gi18n.h>
 #include <stdio.h>
 #include <string.h>
 #include <config.h>
-#include <libgnome/gnome-i18n.h>
-#include <libgnome/gnome-init.h>
-#include <libgnomevfs/gnome-vfs-utils.h>
-#include <libgnomevfs/gnome-vfs-file-info.h>
-#include <libgnomevfs/gnome-vfs-ops.h>
-#include <libgnomevfs/gnome-vfs-directory.h>
 #include <unistd.h>
 #include <stdlib.h>
 
+#include <libgnome/gnome-init.h>		/* for GNOME_DOT_GNOME */
+
 #include "rb-file-helpers.h"
 #include "rb-debug.h"
 #include "rb-util.h"
@@ -48,9 +45,6 @@
 static GHashTable *files = NULL;
 
 static char *dot_dir = NULL;
-#ifndef HAVE_G_GET_USER_SPECIAL_DIR
-static char *music_dir = NULL;
-#endif
 
 const char *
 rb_file (const char *filename)
@@ -104,140 +98,6 @@
 }
 
 
-#ifndef HAVE_G_GET_USER_SPECIAL_DIR
-
-/* Copied from xdg-user-dir-lookup.c */
-
-static char *
-xdg_user_dir_lookup (const char *type)
-{
-  FILE *file;
-  char *home_dir, *config_home, *config_file;
-  char buffer[512];
-  char *user_dir;
-  char *p, *d;
-  int len;
-  int relative;
-  
-  home_dir = getenv ("HOME");
-
-  if (home_dir == NULL)
-    return strdup ("/tmp");
-
-  config_home = getenv ("XDG_CONFIG_HOME");
-  if (config_home == NULL || config_home[0] == 0)
-    {
-      config_file = malloc (strlen (home_dir) + strlen ("/.config/user-dirs.dirs") + 1);
-      strcpy (config_file, home_dir);
-      strcat (config_file, "/.config/user-dirs.dirs");
-    }
-  else
-    {
-      config_file = malloc (strlen (config_home) + strlen ("/user-dirs.dirs") + 1);
-      strcpy (config_file, config_home);
-      strcat (config_file, "/user-dirs.dirs");
-    }
-
-  file = fopen (config_file, "r");
-  free (config_file);
-  if (file == NULL)
-    goto error;
-
-  user_dir = NULL;
-  while (fgets (buffer, sizeof (buffer), file))
-    {
-      /* Remove newline at end */
-      len = strlen (buffer);
-      if (len > 0 && buffer[len-1] == '\n')
-	buffer[len-1] = 0;
-      
-      p = buffer;
-      while (*p == ' ' || *p == '\t')
-	p++;
-      
-      if (strncmp (p, "XDG_", 4) != 0)
-	continue;
-      p += 4;
-      if (strncmp (p, type, strlen (type)) != 0)
-	continue;
-      p += strlen (type);
-      if (strncmp (p, "_DIR", 4) != 0)
-	continue;
-      p += 4;
-
-      while (*p == ' ' || *p == '\t')
-	p++;
-
-      if (*p != '=')
-	continue;
-      p++;
-      
-      while (*p == ' ' || *p == '\t')
-	p++;
-
-      if (*p != '"')
-	continue;
-      p++;
-      
-      relative = 0;
-      if (strncmp (p, "$HOME/", 6) == 0)
-	{
-	  p += 6;
-	  relative = 1;
-	}
-      else if (*p != '/')
-	continue;
-      
-      if (relative)
-	{
-	  user_dir = malloc (strlen (home_dir) + 1 + strlen (p) + 1);
-	  strcpy (user_dir, home_dir);
-	  strcat (user_dir, "/");
-	}
-      else
-	{
-	  user_dir = malloc (strlen (p) + 1);
-	  *user_dir = 0;
-	}
-      
-      d = user_dir + strlen (user_dir);
-      while (*p && *p != '"')
-	{
-	  if ((*p == '\\') && (*(p+1) != 0))
-	    p++;
-	  *d++ = *p++;
-	}
-      *d = 0;
-    }  
-  fclose (file);
-
-  if (user_dir)
-    return user_dir;
-
- error:
-  /* Special case desktop for historical compatibility */
-  if (strcmp (type, "DESKTOP") == 0)
-    {
-      user_dir = malloc (strlen (home_dir) + strlen ("/Desktop") + 1);
-      strcpy (user_dir, home_dir);
-      strcat (user_dir, "/Desktop");
-      return user_dir;
-    }
-  else
-    return strdup (home_dir);
-}
-
-const char *
-rb_music_dir (void)
-{
-	if (music_dir != NULL)
-		return (const char *) music_dir;
-	music_dir = xdg_user_dir_lookup ("MUSIC");
-	return (const char *) music_dir;
-}
-
-#else		/* HAVE_G_GET_USER_SPECIAL_DIR */
-
 const char *
 rb_music_dir (void)
 {
@@ -253,8 +113,6 @@
 	return dir;
 }
 
-#endif
-
 void
 rb_file_helpers_init (void)
 {
@@ -269,105 +127,127 @@
 {
 	g_hash_table_destroy (files);
 	g_free (dot_dir);
-#ifndef HAVE_G_GET_USER_SPECIAL_DIR
-	g_free (music_dir);
-#endif
 }
 
 #define MAX_LINK_LEVEL 5
 
+/* not sure this is really useful */
+
 char *
-rb_uri_resolve_symlink (const char *uri)
+rb_uri_resolve_symlink (const char *uri, GError **error)
 {
-	gint link_count;
-	GnomeVFSFileInfo *info;
-	char *followed;
+	GFile *file = NULL;
+	GFileInfo *file_info = NULL;
+	int link_count = 0;
+	char *result = NULL;
+	const char *attr = G_FILE_ATTRIBUTE_STANDARD_SYMLINK_TARGET;
+	GError *l_error = NULL;
+	
+	file = g_file_new_for_uri (uri);
 
-	g_return_val_if_fail (uri != NULL, NULL);
+	while (link_count < MAX_LINK_LEVEL) {
+		GFile *parent;
+		GFile *new_file;
+		char *target;
+
+		/* look for a symlink target */
+		file_info = g_file_query_info (file,
+					       attr,
+					       G_FILE_QUERY_INFO_NONE,
+					       NULL, &l_error);
+		if (l_error != NULL) {
+			/* argh */
+			result = g_file_get_uri (file);
+			rb_debug ("error querying %s: %s", result, l_error->message);
+			g_free (result);
+			result = NULL;
+			break;
+		} else if (g_file_info_has_attribute (file_info, attr) == FALSE) {
+			/* no symlink, so return the path */
+			result = g_file_get_uri (file);
+			if (link_count > 0) {
+				rb_debug ("resolved symlinks: %s -> %s", uri, result);
+			}
+			break;
+		}
 
-	info = gnome_vfs_file_info_new ();
-	gnome_vfs_get_file_info (uri, info, GNOME_VFS_FILE_INFO_DEFAULT);
+		/* resolve it and try again */
+		new_file = NULL;
+		parent = g_file_get_parent (file);
+		if (parent == NULL) {
+			/* dang */
+			break;
+		}
 
-	if (info->type != GNOME_VFS_FILE_TYPE_SYMBOLIC_LINK) {
-		gnome_vfs_file_info_unref (info);
-		return g_strdup (uri);
-	}
+		target = g_file_info_get_attribute_as_string (file_info, attr);
 
-	link_count = 0;
-	followed = g_strdup (uri);
-	while (link_count < MAX_LINK_LEVEL) {
-		GnomeVFSURI *vfs_uri;
-		GnomeVFSURI *new_vfs_uri;
-		char *escaped_path;
-
-		vfs_uri = gnome_vfs_uri_new (followed);
-		escaped_path = gnome_vfs_escape_path_string (info->symlink_name);
-		new_vfs_uri = gnome_vfs_uri_resolve_relative (vfs_uri,
-							      escaped_path);
-		g_free (escaped_path);
-
-		g_free (followed);
-		followed = gnome_vfs_uri_to_string (new_vfs_uri,
-						    GNOME_VFS_URI_HIDE_NONE); 
-		link_count++;
+		new_file = g_file_resolve_relative_path (parent, target);
+		g_free (target);
+		g_object_unref (parent);
+
+		g_object_unref (file_info);
+		file_info = NULL;
 
-		gnome_vfs_uri_unref (new_vfs_uri);
-		gnome_vfs_uri_unref (vfs_uri);
+		g_object_unref (file);
+		file = new_file;
 
-		gnome_vfs_file_info_clear (info);
-		gnome_vfs_get_file_info (followed, info,
-					 GNOME_VFS_FILE_INFO_DEFAULT);
-
-		if (info->type != GNOME_VFS_FILE_TYPE_SYMBOLIC_LINK) {
-			gnome_vfs_file_info_unref (info);
-			return followed;
+		if (file == NULL) {
+			/* dang */
+			break;
 		}
-	}
 
-	/* Too many symlinks */
+		link_count++;
+	}
 
-	gnome_vfs_file_info_unref (info);
+	if (file != NULL) {
+		g_object_unref (file);
+	}
+	if (file_info != NULL) {
+		g_object_unref (file_info);
+	}
+	if (result == NULL && error == NULL) {
+		rb_debug ("too many symlinks while resolving %s", uri);
+		l_error = g_error_new (G_IO_ERROR,
+				       G_IO_ERROR_TOO_MANY_LINKS,
+				       _("Too many symlinks"));
+	}
+	if (l_error != NULL) {
+		g_propagate_error (error, l_error);
+	}
 
-	return NULL;
+	return result;
 }
 
 gboolean
 rb_uri_is_directory (const char *uri)
 {
-	GnomeVFSFileInfo *info;
-	gboolean dir;
-
-	g_return_val_if_fail (uri != NULL, FALSE);
-
-	info = gnome_vfs_file_info_new ();
-
-	gnome_vfs_get_file_info (uri, info,
-				 GNOME_VFS_FILE_INFO_FORCE_FAST_MIME_TYPE |
-				 GNOME_VFS_FILE_INFO_FOLLOW_LINKS);
-
-	if (info->type == GNOME_VFS_FILE_TYPE_DIRECTORY)
-		dir = TRUE;
-	else
-		dir = FALSE;
-
-	gnome_vfs_file_info_unref (info);
+	GFile *f;
+	GFileInfo *fi;
+	GFileType ftype;
+
+	f = g_file_new_for_uri (uri);
+	fi = g_file_query_info (f, G_FILE_ATTRIBUTE_STANDARD_TYPE, 0, NULL, NULL);
+	g_object_unref (f);
+	if (fi == NULL) {
+		/* ? */
+		return FALSE;
+	}
 
-	return dir;
+	ftype = g_file_info_get_attribute_uint32 (fi, G_FILE_ATTRIBUTE_STANDARD_TYPE);
+	g_object_unref (fi);
+	return (ftype == G_FILE_TYPE_DIRECTORY);
 }
 
 gboolean
 rb_uri_exists (const char *uri)
 {
-	GnomeVFSURI *vuri;
-	gboolean ret;
-	
-	g_return_val_if_fail (uri != NULL, FALSE);
-
-	vuri = gnome_vfs_uri_new (uri);
-	ret = gnome_vfs_uri_exists (vuri);
-	gnome_vfs_uri_unref (vuri);
+	GFile *f;
+	gboolean exists;
 
-	return ret;
+	f = g_file_new_for_uri (uri);
+	exists = g_file_query_exists (f, NULL);
+	g_object_unref (f);
+	return exists;
 }
 
 static gboolean
@@ -376,270 +256,8 @@
 	return g_ascii_isalnum (c) || c == '+' || c == '-' || c == '.';
 }
 
-/*
- * FIXME this is not the simplest or most time-efficent way
- * to do this.  Probably a far more clear way of doing this processing
- * is to split the path into segments, rather than doing the processing
- * in place.
- */
-static void
-remove_internal_relative_components (char *uri_current)
-{
-	char *segment_prev, *segment_cur;
-	size_t len_prev, len_cur;
-
-	len_prev = len_cur = 0;
-	segment_prev = NULL;
-
-	g_return_if_fail (uri_current != NULL);
-
-	segment_cur = uri_current;
-
-	while (*segment_cur) {
-		len_cur = strcspn (segment_cur, "/");
-
-		if (len_cur == 1 && segment_cur[0] == '.') {
-			/* Remove "." 's */
-			if (segment_cur[1] == '\0') {
-				segment_cur[0] = '\0';
-				break;
-			} else {
-				memmove (segment_cur, segment_cur + 2, strlen (segment_cur + 2) + 1);
-				continue;
-			}
-		} else if (len_cur == 2 && segment_cur[0] == '.' && segment_cur[1] == '.' ) {
-			/* Remove ".."'s (and the component to the left of it) that aren't at the
-			 * beginning or to the right of other ..'s
-			 */
-			if (segment_prev) {
-				if (! (len_prev == 2
-				       && segment_prev[0] == '.'
-				       && segment_prev[1] == '.')) {
-				       	if (segment_cur[2] == '\0') {
-						segment_prev[0] = '\0';
-						break;
-				       	} else {
-						memmove (segment_prev, segment_cur + 3, strlen (segment_cur + 3) + 1);
-
-						segment_cur = segment_prev;
-						len_cur = len_prev;
-
-						/* now we find the previous segment_prev */
-						if (segment_prev == uri_current) {
-							segment_prev = NULL;
-						} else if (segment_prev - uri_current >= 2) {
-							segment_prev -= 2;
-							for ( ; segment_prev > uri_current && segment_prev[0] != '/' 
-							      ; segment_prev-- );
-							if (segment_prev[0] == '/') {
-								segment_prev++;
-							}
-						}
-						continue;
-					}
-				}
-			}
-		}
-
-		/*Forward to next segment */
-
-		if (segment_cur [len_cur] == '\0') {
-			break;
-		}
-		 
-		segment_prev = segment_cur;
-		len_prev = len_cur;
-		segment_cur += len_cur + 1;	
-	}	
-}
-
-static gboolean
-is_uri_partial (const char *uri)
-{
-	const char *current;
-
-        /* RFC 2396 section 3.1 */
-        for (current = uri ;
-		*current
-	        &&      ((*current >= 'a' && *current <= 'z')
-	                 || (*current >= 'A' && *current <= 'Z')
-	                 || (*current >= '0' && *current <= '9')
-	                 || ('-' == *current)
-			 || ('+' == *current)
-                         || ('.' == *current)) ;
-		current++);
-
-	return  !(':' == *current);
-}
-
-/**
- * eel_uri_make_full_from_relative:
- * 
- * Returns a full URI given a full base URI, and a secondary URI which may
- * be relative.
- *
- * Return value: the URI (NULL for some bad errors).
- *
- * FIXME: This code has been copied from eel-mozilla-content-view
- * because eel-mozilla-content-view cannot link with libeel-extensions
- * due to lame license issues.  Really, this belongs in gnome-vfs, but was added
- * after the Gnome 1.4 gnome-vfs API freeze
- **/
-
-static char *
-eel_uri_make_full_from_relative (const char *base_uri, const char *relative_uri)
-{
-	char *result = NULL;
-
-	/* See section 5.2 in RFC 2396 */
-
-	if (base_uri == NULL && relative_uri == NULL) {
-		result = NULL;
-	} else if (base_uri == NULL) {
-		result = g_strdup (relative_uri);
-	} else if (relative_uri == NULL) {
-		result = g_strdup (base_uri);
-	} else if (!is_uri_partial (relative_uri)) {
-		result = g_strdup (relative_uri);
-	} else {
-		char *mutable_base_uri;
-		char *mutable_uri;
-
-		char *uri_current;
-		size_t base_uri_length;
-		char *separator;
-
-		mutable_base_uri = g_strdup (base_uri);
-		uri_current = mutable_uri = g_strdup (relative_uri);
-
-		/* Chew off Fragment and Query from the base_url */
-
-		separator = strrchr (mutable_base_uri, '#'); 
-
-		if (separator) {
-			*separator = '\0';
-		}
-
-		separator = strrchr (mutable_base_uri, '?');
-
-		if (separator) {
-			*separator = '\0';
-		}
-
-		if ('/' == uri_current[0] && '/' == uri_current [1]) {
-			/* Relative URI's beginning with the authority
-			 * component inherit only the scheme from their parents
-			 */
-
-			separator = strchr (mutable_base_uri, ':');
-
-			if (separator) {
-				separator[1] = '\0';
-			}			  
-		} else if ('/' == uri_current[0]) {
-			/* Relative URI's beginning with '/' absolute-path based
-			 * at the root of the base uri
-			 */
-
-			separator = strchr (mutable_base_uri, ':');
-
-			/* g_assert (separator), really */
-			if (separator) {
-				/* If we start with //, skip past the authority section */
-				if ('/' == separator[1] && '/' == separator[2]) {
-					separator = strchr (separator + 3, '/');
-					if (separator) {
-						separator[0] = '\0';
-					}
-				} else {
-				/* If there's no //, just assume the scheme is the root */
-					separator[1] = '\0';
-				}
-			}
-		} else if ('#' != uri_current[0]) {
-			/* Handle the ".." convention for relative uri's */
-
-			/* If there's a trailing '/' on base_url, treat base_url
-			 * as a directory path.
-			 * Otherwise, treat it as a file path, and chop off the filename
-			 */
-
-			base_uri_length = strlen (mutable_base_uri);
-			if ('/' == mutable_base_uri[base_uri_length-1]) {
-				/* Trim off '/' for the operation below */
-				mutable_base_uri[base_uri_length-1] = 0;
-			} else {
-				separator = strrchr (mutable_base_uri, '/');
-				if (separator) {
-					*separator = '\0';
-				}
-			}
-
-			remove_internal_relative_components (uri_current);
-
-			/* handle the "../"'s at the beginning of the relative URI */
-			while (0 == strncmp ("../", uri_current, 3)) {
-				uri_current += 3;
-				separator = strrchr (mutable_base_uri, '/');
-				if (separator) {
-					*separator = '\0';
-				} else {
-					/* <shrug> */
-					break;
-				}
-			}
-
-			/* handle a ".." at the end */
-			if (uri_current[0] == '.' && uri_current[1] == '.' 
-			    && uri_current[2] == '\0') {
-
-			    	uri_current += 2;
-				separator = strrchr (mutable_base_uri, '/');
-				if (separator) {
-					*separator = '\0';
-				}
-			}
-
-			/* Re-append the '/' */
-			mutable_base_uri [strlen(mutable_base_uri)+1] = '\0';
-			mutable_base_uri [strlen(mutable_base_uri)] = '/';
-		}
-
-		result = g_strconcat (mutable_base_uri, uri_current, NULL);
-		g_free (mutable_base_uri); 
-		g_free (mutable_uri); 
-	}
-	
-	return result;
-}
-
-/* Note that NULL's and full paths are also handled by this function.
- * A NULL location will return the current working directory
- */
-static char *
-file_uri_from_local_relative_path (const char *location)
-{
-	char *current_dir;
-	char *base_uri, *base_uri_slash;
-	char *location_escaped;
-	char *uri;
-
-	current_dir = g_get_current_dir ();
-	base_uri = gnome_vfs_get_uri_from_local_path (current_dir);
-	/* g_get_current_dir returns w/o trailing / */
-	base_uri_slash = g_strconcat (base_uri, "/", NULL);
 
-	location_escaped = gnome_vfs_escape_path_string (location);
 
-	uri = eel_uri_make_full_from_relative (base_uri_slash, location_escaped);
-
-	g_free (location_escaped);
-	g_free (base_uri_slash);
-	g_free (base_uri);
-	g_free (current_dir);
-
-	return uri;
-}
 
 static gboolean
 has_valid_scheme (const char *uri)
@@ -659,114 +277,40 @@
         return *p == ':';
 }
 
-/**
- * eel_make_uri_from_shell_arg:
- * @location: a possibly mangled "uri"
- *
- * Similar to eel_make_uri_from_input, except that:
- * 
- * 1) guesses relative paths instead of http domains
- * 2) doesn't bother stripping leading/trailing white space
- * 3) doesn't bother with ~ expansion--that's done by the shell
- *
- * Return value: a newly allocated uri
- **/
-char *
-rb_uri_resolve_relative (const char *location)
-{
-	char *uri;
-
-	g_return_val_if_fail (location != NULL, g_strdup (""));
-
-	switch (location[0]) {
-	case '\0':
-		uri = g_strdup ("");
-		break;
-	case '/':
-		uri = gnome_vfs_get_uri_from_local_path (location);
-		break;
-	default:
-		if (has_valid_scheme (location)) {
-			uri = g_strdup (location);
-		} else {
-			uri = file_uri_from_local_relative_path (location);
-		}
-	}
-
-	return uri;
-}
-
 static gboolean
-have_uid (guint uid)
+get_uri_perm (const char *uri, const char *perm_attribute)
 {
-	return (uid == getuid ());
-}
-
-static gboolean
-have_gid (guint gid)
-{
-	gid_t gids[100];
-	int n_groups, i;
-
-	n_groups = getgroups (100, gids);
-
-	for (i = 0; i < n_groups; i++)
-	{
-		if (gids[i] == getegid ())
-			continue;
-		if (gids[i] == gid)
-			return TRUE;
+	GFile *f;
+	GFileInfo *info;
+	GError *error = NULL;
+	gboolean result;
+
+	f = g_file_new_for_uri (uri);
+	info = g_file_query_info (f, perm_attribute, 0, NULL, &error);
+	if (error != NULL) {
+		result = FALSE;
+		g_error_free (error);
+	} else {
+		result = g_file_info_get_attribute_boolean (info, perm_attribute);
 	}
 
-	return FALSE;
+	if (info != NULL) {
+		g_object_unref (info);
+	}
+	g_object_unref (f);
+	return result;
 }
 
 gboolean
 rb_uri_is_readable (const char *text_uri)
 {
-	GnomeVFSFileInfo *info;
-	gboolean ret = FALSE;
-
-	info = gnome_vfs_file_info_new ();
-	if (info == NULL)
-		return FALSE;
-	if (gnome_vfs_get_file_info (text_uri, info, GNOME_VFS_FILE_INFO_FOLLOW_LINKS) != GNOME_VFS_OK)
-		return FALSE;
-
-	if ((info->permissions & GNOME_VFS_PERM_OTHER_READ) ||
-	    ((info->permissions & GNOME_VFS_PERM_USER_READ) &&
-	     (have_uid (info->uid) == TRUE)) ||
-	    ((info->permissions & GNOME_VFS_PERM_GROUP_READ) &&
-	     (have_gid (info->gid) == TRUE)))
-		ret = TRUE;
-
-	gnome_vfs_file_info_unref (info);
-
-	return ret;
+	return get_uri_perm (text_uri, G_FILE_ATTRIBUTE_ACCESS_CAN_READ);
 }
 
 gboolean
 rb_uri_is_writable (const char *text_uri)
 {
-	GnomeVFSFileInfo *info;
-	gboolean ret = FALSE;
-
-	info = gnome_vfs_file_info_new ();
-	if (info == NULL)
-		return FALSE;
-	if (gnome_vfs_get_file_info (text_uri, info, GNOME_VFS_FILE_INFO_FOLLOW_LINKS) != GNOME_VFS_OK)
-		return FALSE;
-
-	if ((info->permissions & GNOME_VFS_PERM_OTHER_WRITE) ||
-	    ((info->permissions & GNOME_VFS_PERM_USER_WRITE) &&
-	     (have_uid (info->uid) == TRUE)) ||
-	    ((info->permissions & GNOME_VFS_PERM_GROUP_WRITE) &&
-	     (have_gid (info->gid) == TRUE)))
-		ret = TRUE;
-
-	gnome_vfs_file_info_unref (info);
-
-	return ret;
+	return get_uri_perm (text_uri, G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE);
 }
 
 gboolean
@@ -778,7 +322,7 @@
 gboolean
 rb_uri_is_hidden (const char *text_uri)
 {
-	return g_utf8_strrchr (text_uri, -1, GNOME_VFS_URI_PATH_CHR)[1] == '.';
+	return g_utf8_strrchr (text_uri, -1, '/')[1] == '.';
 }
 
 gboolean
@@ -843,163 +387,174 @@
 char *
 rb_uri_make_hidden (const char *text_uri)
 {
-	GnomeVFSURI *uri;
-	GnomeVFSURI *parent;
+	GFile *file;
+	GFile *parent;
 	char *shortname;
 	char *dotted;
-	char *ret;
+	char *ret = NULL;
 
 	if (rb_uri_is_hidden (text_uri))
 		return g_strdup (text_uri);
 
-	uri = gnome_vfs_uri_new (text_uri);
-	if (uri == NULL) {
-		return g_strdup (text_uri);
+	file = g_file_new_for_uri (text_uri);
+
+	shortname = g_file_get_basename (file);
+	if (shortname == NULL) {
+		g_object_unref (file);
+		return NULL;
 	}
 
-	parent = gnome_vfs_uri_get_parent (uri);
+	parent = g_file_get_parent (file);
 	if (parent == NULL) {
-		gnome_vfs_uri_unref (uri);
-		return g_strdup (text_uri);
+		g_object_unref (file);
+		g_free (shortname);
+		return NULL;
 	}
-
-	shortname = gnome_vfs_uri_extract_short_name (uri);
-	gnome_vfs_uri_unref (uri);
+	g_object_unref (file);
 
 	dotted = g_strdup_printf (".%s", shortname);
 	g_free (shortname);
 
-	uri = gnome_vfs_uri_append_file_name (parent, dotted);
-	gnome_vfs_uri_unref (parent);
+	file = g_file_get_child (parent, dotted);
+	g_object_unref (parent);
 	g_free (dotted);
 
-	ret = gnome_vfs_uri_to_string (uri, GNOME_VFS_URI_HIDE_NONE);
-	gnome_vfs_uri_unref (uri);
-	return ret;
-}
-
-/*
- * gnome_vfs_uri_new escapes a few extra characters that
- * gnome_vfs_escape_path doesn't ('&' and '=').  If we
- * don't adjust our URIs to match, we end up with duplicate
- * entries, one with the characters encoded and one without.
- */
-static char *
-escape_extra_gnome_vfs_chars (char *uri)
-{
-	if (strspn (uri, "&=") != strlen (uri)) {
-		char *tmp = gnome_vfs_escape_set (uri, "&=");
-		g_free (uri);
-		return tmp;
+	if (file != NULL) {
+		ret = g_file_get_uri (file);
+		g_object_unref (file);
 	}
-
-	return uri;
+	return ret;
 }
 
 typedef struct {
 	char *uri;
+	GCancellable *cancel;
 	RBUriRecurseFunc func;
 	gpointer user_data;
-	gboolean *cancel_flag;
 	GDestroyNotify data_destroy;
-} RBUriHandleRecursivelyData;
-
-typedef struct {
-	RBUriHandleRecursivelyData data;
-
-	/* real data */
-	RBUriRecurseFunc func;
-	gpointer user_data;
 
 	GMutex *results_lock;
 	guint results_idle_id;
-	GList *uri_results;
+	GList *file_results;
 	GList *dir_results;
 } RBUriHandleRecursivelyAsyncData;
 
 static void
-_rb_uri_recurse_data_free (RBUriHandleRecursivelyData *data)
-{
-	g_free (data->uri);
-	if (data->data_destroy)
-		data->data_destroy (data->user_data);
+_uri_handle_recurse (GFile *dir,
+		     GCancellable *cancel,
+		     GHashTable *handled,
+		     RBUriRecurseFunc func,
+		     gpointer user_data)
+{
+	GFileEnumerator *files;
+	GFileInfo *info;
+	GError *error = NULL;
+	GFileType file_type;
+	const char *file_id;
+	gboolean file_handled;
+	const char *attributes = 
+		G_FILE_ATTRIBUTE_STANDARD_NAME ","
+		G_FILE_ATTRIBUTE_STANDARD_TYPE ","
+		G_FILE_ATTRIBUTE_STANDARD_IS_HIDDEN ","
+		G_FILE_ATTRIBUTE_ID_FILE ","
+		G_FILE_ATTRIBUTE_ACCESS_CAN_READ;
+
+	files = g_file_enumerate_children (dir, attributes, G_FILE_QUERY_INFO_NONE, cancel, &error);
+	if (error != NULL) {
+		char *where;
+		where = g_file_get_uri (dir);
+		rb_debug ("error enumerating %s: %s", where, error->message);
+		g_free (where);
+		g_error_free (error);
+		return;
+	}
+
+	while (1) {
+		GFile *child;
+		gboolean is_dir;
+		gboolean ret;
 
-	g_free (data);
-}
+		ret = TRUE;
+		info = g_file_enumerator_next_file (files, cancel, &error);
+		if (error != NULL) {
+			rb_debug ("error enumerating files: %s", error->message);
+			break;
+		} else if (info == NULL) {
+			break;
+		}
 
-static gboolean
-_gnomevfs_info_unreadable (GnomeVFSFileInfo *info)
-{
-	return (info->valid_fields & GNOME_VFS_FILE_INFO_FIELDS_ACCESS) &&
-		!(info->permissions & GNOME_VFS_PERM_ACCESS_READABLE);
-}
+		child = g_file_get_child (dir, g_file_info_get_name (info));
 
-static gboolean
-rb_uri_handle_recursively_cb (const gchar *rel_path,
-			      GnomeVFSFileInfo *info,
-			      gboolean recursing_will_loop,
-			      RBUriHandleRecursivelyData *data,
-			      gboolean *recurse)
-{
-	char *path, *escaped_rel_path;
-	char *sep;
-	gboolean dir;
-	gboolean ret;
+		/* is non-hidden and readable? */
+		if (g_file_info_get_attribute_boolean (info, G_FILE_ATTRIBUTE_ACCESS_CAN_READ) == FALSE ||
+		    g_file_info_get_attribute_boolean (info, G_FILE_ATTRIBUTE_STANDARD_IS_HIDDEN)) {
+			g_object_unref (info);
+			g_object_unref (child);
+			continue;
+		}
 
-	dir = (info->type == GNOME_VFS_FILE_TYPE_DIRECTORY);
+		/* already handled? */
+		file_id = g_file_info_get_attribute_string (info, G_FILE_ATTRIBUTE_ID_FILE);
+		if (file_id == NULL) {
+			/* have to hope for the best, I guess */
+			file_handled = FALSE;
+		} else if (g_hash_table_lookup (handled, file_id) != NULL) {
+			file_handled = TRUE;
+		} else {
+			file_handled = FALSE;
+			g_hash_table_insert (handled, g_strdup (file_id), GINT_TO_POINTER (1));
+		}
 
-	if (data->cancel_flag && *data->cancel_flag)
-		return FALSE;
+		/* type? */
+		file_type = g_file_info_get_attribute_uint32 (info, G_FILE_ATTRIBUTE_STANDARD_TYPE);
+		switch (file_type) {
+		case G_FILE_TYPE_DIRECTORY:
+		case G_FILE_TYPE_MOUNTABLE:
+			is_dir = TRUE;
+			break;
+		
+		default:
+			is_dir = FALSE;
+			break;
+		}
 
-	/* skip hidden and unreadable files and directories */
-	sep = strrchr (rel_path, G_DIR_SEPARATOR);
-	if ((sep != NULL && g_str_has_prefix (sep + 1, ".")) ||
-	    (sep == NULL && g_str_has_prefix (rel_path, ".")) ||
-	    _gnomevfs_info_unreadable (info)) {
-		*recurse = FALSE;
-		return TRUE;
-	}
+		if (file_handled == FALSE) {
+			ret = (func) (child, is_dir, user_data);
 
-	escaped_rel_path = gnome_vfs_escape_path_string (rel_path);
-	escaped_rel_path = escape_extra_gnome_vfs_chars (escaped_rel_path);
-	path = g_build_filename (data->uri, escaped_rel_path, NULL);
-	ret = (data->func) (path, dir, data->user_data);
-	g_free (escaped_rel_path);
-	g_free (path);
+			if (is_dir) {
+				_uri_handle_recurse (child, cancel, handled, func, user_data);
+			}
+		}
+	
+		g_object_unref (info);
+		g_object_unref (child);
 
-	/* if recursing will not loop, and function wants to recurse, then do so */
-	*recurse = !recursing_will_loop && ret;
-	return TRUE;
+		if (ret == FALSE)
+			break;
+	}
+
+	g_object_unref (files);
 }
 
 void
 rb_uri_handle_recursively (const char *text_uri,
-		           RBUriRecurseFunc func,
-			   gboolean *cancelflag,
-		           gpointer user_data)
-{
-	RBUriHandleRecursivelyData *data = g_new0 (RBUriHandleRecursivelyData, 1);
-	GnomeVFSFileInfoOptions flags;
-	GnomeVFSResult result;
-	
-	data->uri = g_strdup (text_uri);
-	data->func = func;
-	data->user_data = user_data;
-	data->cancel_flag = cancelflag;
-	data->data_destroy = NULL;
+			   GCancellable *cancel,
+			   RBUriRecurseFunc func,
+			   gpointer user_data)
+{
+	GFile *file;
+	GHashTable *handled;
+
+	file = g_file_new_for_uri (text_uri);
+	handled = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
+
+	_uri_handle_recurse (file, cancel, handled, func, user_data);
 
-	flags = GNOME_VFS_FILE_INFO_GET_MIME_TYPE |
-		GNOME_VFS_FILE_INFO_FORCE_FAST_MIME_TYPE |
-		GNOME_VFS_FILE_INFO_FOLLOW_LINKS |
-		GNOME_VFS_FILE_INFO_GET_ACCESS_RIGHTS;
-	result = gnome_vfs_directory_visit (text_uri,
-					    flags,
-					    GNOME_VFS_DIRECTORY_VISIT_LOOPCHECK,
-					    (GnomeVFSDirectoryVisitFunc)rb_uri_handle_recursively_cb,
-					    data);
-	_rb_uri_recurse_data_free (data);
+	g_hash_table_destroy (handled);
+	g_object_unref (file);
 }
 
+
 /* runs in main thread */
 static gboolean
 _recurse_async_idle_cb (RBUriHandleRecursivelyAsyncData *data)
@@ -1008,19 +563,18 @@
 
 	g_mutex_lock (data->results_lock);
 
-	for (ul = data->uri_results, dl = data->dir_results;
+	for (ul = data->file_results, dl = data->dir_results;
 	     ul != NULL;
 	     ul = g_list_next (ul), dl = g_list_next (dl)) {
 		g_assert (dl != NULL);
 
-		data->func ((const char*)ul->data, (GPOINTER_TO_INT (dl->data) == 1), data->user_data);
-		g_free (ul->data);
+		data->func (G_FILE (ul->data), (GPOINTER_TO_INT (dl->data) == 1), data->user_data);
+		g_object_unref (ul->data);
 	}
 	g_assert (dl == NULL);
 
-
-	g_list_free (data->uri_results);
-	data->uri_results = NULL;
+	g_list_free (data->file_results);
+	data->file_results = NULL;
 	g_list_free (data->dir_results);
 	data->dir_results = NULL;
 
@@ -1033,32 +587,46 @@
 static gboolean
 _recurse_async_data_free (RBUriHandleRecursivelyAsyncData *data)
 {
+	GList *i;
+
 	if (data->results_idle_id) {
 		g_source_remove (data->results_idle_id);
 		_recurse_async_idle_cb (data); /* process last results */
 	}
 
-	g_list_free (data->uri_results);
-	data->uri_results = NULL;
+	for (i = data->file_results; i != NULL; i = i->next) {
+		GFile *file = G_FILE (i->data);
+		g_object_unref (file);
+	}
+
+	g_list_free (data->file_results);
+	data->file_results = NULL;
 	g_list_free (data->dir_results);
 	data->dir_results = NULL;
 
-	g_mutex_free (data->results_lock);
-	_rb_uri_recurse_data_free (&data->data);
+	if (data->data_destroy != NULL) {
+		(data->data_destroy) (data->user_data);
+	}
+	if (data->cancel != NULL) {
+		g_object_unref (data->cancel);
+	}
 
+	g_free (data->uri);
+	g_mutex_free (data->results_lock);
 	return FALSE;
 }
 
 /* runs in worker thread */
 static gboolean
-_recurse_async_cb (const char *uri, gboolean dir, RBUriHandleRecursivelyAsyncData *data)
+_recurse_async_cb (GFile *file, gboolean dir, RBUriHandleRecursivelyAsyncData *data)
 {
 	g_mutex_lock (data->results_lock);
 
-	data->uri_results = g_list_prepend (data->uri_results, g_strdup (uri));
+	data->file_results = g_list_prepend (data->file_results, g_object_ref (file));
 	data->dir_results = g_list_prepend (data->dir_results, GINT_TO_POINTER (dir ? 1 : 0));
-	if (data->results_idle_id == 0)
+	if (data->results_idle_id == 0) {
 		g_idle_add ((GSourceFunc)_recurse_async_idle_cb, data);
+	}
 
 	g_mutex_unlock (data->results_lock);
 	return TRUE;
@@ -1067,107 +635,83 @@
 static gpointer
 _recurse_async_func (RBUriHandleRecursivelyAsyncData *data)
 {
-	GnomeVFSFileInfoOptions flags;
-	GnomeVFSResult result;
+	rb_uri_handle_recursively (data->uri,
+				   data->cancel,
+				   (RBUriRecurseFunc) _recurse_async_cb,
+				   data);
 
-	flags = GNOME_VFS_FILE_INFO_GET_MIME_TYPE |
-		GNOME_VFS_FILE_INFO_FORCE_FAST_MIME_TYPE |
-		GNOME_VFS_FILE_INFO_FOLLOW_LINKS |
-		GNOME_VFS_FILE_INFO_GET_ACCESS_RIGHTS;
-	result = gnome_vfs_directory_visit (data->data.uri,
-					    flags,
-					    GNOME_VFS_DIRECTORY_VISIT_LOOPCHECK,
-					    (GnomeVFSDirectoryVisitFunc)rb_uri_handle_recursively_cb,
-					    &data->data);
-	
 	g_idle_add ((GSourceFunc)_recurse_async_data_free, data);
 	return NULL;
 }
 
 void
 rb_uri_handle_recursively_async (const char *text_uri,
+				 GCancellable *cancel,
 			         RBUriRecurseFunc func,
-				 gboolean *cancelflag,
 			         gpointer user_data,
 				 GDestroyNotify data_destroy)
 {
 	RBUriHandleRecursivelyAsyncData *data = g_new0 (RBUriHandleRecursivelyAsyncData, 1);
 	
-	data->data.uri = g_strdup (text_uri);
-	data->func = (RBUriRecurseFunc)_recurse_async_cb;
-	data->data.user_data = user_data;
-	data->data.cancel_flag = cancelflag;
-	data->data.data_destroy = data_destroy;
+	data->uri = g_strdup (text_uri);
+	data->user_data = user_data;
+	if (cancel != NULL) {
+		data->cancel = g_object_ref (cancel);
+	}
+	data->data_destroy = data_destroy;
 
 	data->results_lock = g_mutex_new ();
-	data->data.func = func;
-	data->user_data = data;
+	data->func = func;
+	data->user_data = user_data;
 
 	g_thread_create ((GThreadFunc)_recurse_async_func, data, FALSE, NULL);
 }
 
-
-GnomeVFSResult
-rb_uri_mkstemp (const char *prefix, char **uri_ret, GnomeVFSHandle **ret)
+gboolean
+rb_uri_mkstemp (const char *prefix, char **uri_ret, GOutputStream **stream, GError **error)
 {
-	GnomeVFSHandle *handle = NULL;
+	GFile *file;
 	char *uri = NULL;
-	GnomeVFSResult result = GNOME_VFS_ERROR_FILE_EXISTS;
-	
-	
+	GFileOutputStream *fstream;
+	GError *e = NULL;
+
 	do {
 		g_free (uri);
 		uri = g_strdup_printf ("%s%06X", prefix, g_random_int_range (0, 0xFFFFFF));
-		result = gnome_vfs_create (&handle, uri, GNOME_VFS_OPEN_WRITE | GNOME_VFS_OPEN_RANDOM, TRUE,  0644);
-	} while (result == GNOME_VFS_ERROR_FILE_EXISTS);
 
-	if (result == GNOME_VFS_OK) {
+		file = g_file_new_for_uri (uri);
+		fstream = g_file_create (file, G_FILE_CREATE_PRIVATE, NULL, &e);
+		if (e != NULL) {
+			if (g_error_matches (e, G_IO_ERROR, G_IO_ERROR_EXISTS)) {
+				g_error_free (e);
+				e = NULL;
+			}
+		}
+	} while (e == NULL && fstream == NULL);
+
+	if (fstream != NULL) {
 		*uri_ret = uri;
-		*ret = handle;
+		*stream = G_OUTPUT_STREAM (stream);
+		return TRUE;
 	} else {
 		g_free (uri);
+		return FALSE;
 	}
-	return result;
 }
 
 
 char *
 rb_canonicalise_uri (const char *uri)
 {
+	GFile *file;
 	char *result = NULL;
 
 	g_return_val_if_fail (uri != NULL, NULL);
 
-	if (uri[0] == '/') {
-		/* local path */
-		char *tmp;
-		result = gnome_vfs_make_path_name_canonical (uri);
-		tmp = gnome_vfs_get_uri_from_local_path (result);
-		g_free (result);
-		if (tmp == NULL)
-			return NULL;
-		result = tmp;
-	} else if (strstr (uri, "://") == NULL) {
-		/* local relative path */
-		char *curdir, *escaped, *curdir_withslash;
-
-		curdir = g_get_current_dir ();
-		escaped = gnome_vfs_escape_path_string (curdir);
-		curdir_withslash = g_strdup_printf ("file://%s%c",
-						    escaped, G_DIR_SEPARATOR);
-		g_free (escaped);
-		g_free (curdir);
-
-		escaped = gnome_vfs_escape_path_string (uri);
-		result = gnome_vfs_uri_make_full_from_relative
-			(curdir_withslash, escaped);
-		g_free (curdir_withslash);
-		g_free (escaped);
-	} else {
-		result = gnome_vfs_make_uri_canonical (uri);
-		if (result == NULL)
-			result = g_strdup (uri);
-	}
+	/* gio does more or less what we want, I think */
+	file = g_file_new_for_commandline_arg (uri);
+	result = g_file_get_uri (file);
+	g_object_unref (file);
 
 	return result;
 }
@@ -1175,18 +719,22 @@
 char*
 rb_uri_append_path (const char *uri, const char *path)
 {
-	GnomeVFSURI *vfs_uri, *full_uri;
+	GFile *file;
+	GFile *relfile;
 	char *result;
 
-	vfs_uri = gnome_vfs_uri_new (uri);
-	if (vfs_uri == NULL) {
-		return NULL;
+	/* all paths we get are relative, so skip
+	 * leading slashes.
+	 */
+	while (path[0] == '/') {
+		path++;
 	}
 
-	full_uri = gnome_vfs_uri_append_path (vfs_uri, path);
-	gnome_vfs_uri_unref (vfs_uri);
-	result = gnome_vfs_uri_to_string (full_uri, GNOME_VFS_URI_HIDE_NONE);
-	gnome_vfs_uri_unref (full_uri);
+	file = g_file_new_for_uri (uri);
+	relfile = g_file_resolve_relative_path (file, path);
+	result = g_file_get_uri (relfile);
+	g_object_unref (relfile);
+	g_object_unref (file);
 
 	return result;
 }
@@ -1194,14 +742,6 @@
 char*
 rb_uri_append_uri (const char *uri, const char *fragment)
 {
-	GnomeVFSURI *vfs_uri, *full_uri;
-	char *result;
-
-	vfs_uri = gnome_vfs_uri_new (uri);
-	if (vfs_uri == NULL) {
-		return NULL;
-	}
-
 	/* skip scheme component of the fragment */
 	if (has_valid_scheme (fragment)) {
 		while (is_valid_scheme_character (*fragment))
@@ -1209,28 +749,23 @@
 	}
 	fragment++;
 
-	full_uri = gnome_vfs_uri_append_string (vfs_uri, fragment);
-	gnome_vfs_uri_unref (vfs_uri);
-	result = gnome_vfs_uri_to_string (full_uri, GNOME_VFS_URI_HIDE_NONE);
-	gnome_vfs_uri_unref (full_uri);
-
-	return result;
+	return rb_uri_append_path (uri, fragment);
 }
 
 char *
 rb_uri_get_dir_name (const char *uri)
 {
-	GnomeVFSURI *vfs_uri;
+	GFile *file;
+	GFile *parent;
 	char *dirname;
 
-	vfs_uri = gnome_vfs_uri_new (uri);
-	if (vfs_uri == NULL) {
-		return NULL;
-	}
-
-	dirname = gnome_vfs_uri_extract_dirname (vfs_uri);
-	gnome_vfs_uri_unref (vfs_uri);
+	file = g_file_new_for_uri (uri);
+	parent = g_file_get_parent (file);
+	
+	dirname = g_file_get_uri (parent);
 
+	g_object_unref (parent);
+	g_object_unref (file);
 	return dirname;
 }
 
@@ -1246,13 +781,13 @@
 	/* skip query string */
 	end = g_utf8_strchr (uri, -1, '?');
 
-	start = g_utf8_strrchr (uri, end ? (end - uri) : -1, GNOME_VFS_URI_PATH_CHR);
+	start = g_utf8_strrchr (uri, end ? (end - uri) : -1, '/');
 	if (start == NULL) {
 		/* no separator, just a single file name */
 	} else if ((start + 1 == end) || *(start + 1) == '\0') {
 		/* last character is the separator, so find the previous one */
 		end = start;
-		start = g_utf8_strrchr (uri, (end - uri)-1, GNOME_VFS_URI_PATH_CHR);
+		start = g_utf8_strrchr (uri, (end - uri)-1, '/');
 
 		if (start != NULL)
 			start++;
@@ -1270,46 +805,181 @@
 	}
 }
 
+gboolean
+rb_check_dir_has_space (GFile *file,
+			guint64 bytes_needed)
+{
+	GFileInfo *fs_info;
+	GError *error = NULL;
+	guint64 free_bytes;
+
+	fs_info = g_file_query_filesystem_info (file,
+						G_FILE_ATTRIBUTE_FILESYSTEM_FREE,
+						NULL,
+						&error);
+	if (error != NULL) {
+		char *uri;
+		uri = g_file_get_uri (file);
+		g_warning (_("Cannot get free space at %s: %s"), uri, error->message);
+		g_free (uri);
+		return FALSE;
+	}
+
+	free_bytes = g_file_info_get_attribute_uint64 (fs_info,
+						       G_FILE_ATTRIBUTE_FILESYSTEM_FREE);
+	g_object_unref (fs_info);
+	if (bytes_needed >= free_bytes)
+		return FALSE;
+
+	return TRUE;
+}
+
+gboolean
+rb_check_dir_has_space_uri (const char *uri,
+			    guint64 bytes_needed)
+{
+	GFile *file;
+	gboolean result;
+
+	file = g_file_new_for_uri (uri);
+	result = rb_check_dir_has_space (file, bytes_needed);
+	g_object_unref (file);
+
+	return result;
+}
+
+gchar *
+rb_uri_get_mount_point (const char *uri)
+{
+	GFile *file;
+	GMount *mount;
+	char *mountpoint;
+	GError *error = NULL;
+
+	file = g_file_new_for_uri (uri);
+	mount = g_file_find_enclosing_mount (file, NULL, &error);
+	if (error != NULL) {
+		if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND) == FALSE) {
+			rb_debug ("finding mount for %s: %s", uri, error->message);
+		}
+		g_error_free (error);
+		mountpoint = NULL;
+	} else {
+		GFile *root;
+		root = g_mount_get_root (mount);
+		mountpoint = g_file_get_uri (root);
+		g_object_unref (root);
+		g_object_unref (mount);
+	}
+
+	g_object_unref (file);
+	return mountpoint;
+}
+
+#if !GLIB_CHECK_VERSION(2,17,1)
+static gboolean
+create_parent_dirs (GFile *file, GError **error)
+{
+	GFileInfo *info;
+	gboolean ret;
+	GFile *parent;
+
+	info = g_file_query_info (file, G_FILE_ATTRIBUTE_STANDARD_TYPE, G_FILE_QUERY_INFO_NONE, NULL, error);
+	if (*error == NULL) {
+		/* check it's a directory */
+		GFileType filetype;
+
+		filetype = g_file_info_get_attribute_uint32 (info, G_FILE_ATTRIBUTE_STANDARD_TYPE);
+		if (filetype != G_FILE_TYPE_DIRECTORY) {
+			/* um.. */
+			return FALSE;
+		}
+		return TRUE;		
+	}
+
+	if (g_error_matches (*error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND) == FALSE) {
+		return FALSE;
+	}
+	g_clear_error (error);
+
+	parent = g_file_get_parent (file);
+	ret = create_parent_dirs (parent, error);
+	g_object_unref (parent);
+	if (ret == FALSE) {
+		return FALSE;
+	}
+
+	return g_file_make_directory (file, NULL, error);
+}
+#endif
+
+gboolean
+rb_uri_create_parent_dirs (const char *uri, GError **error)
+{
+	GFile *file;
+	GFile *parent;
+	gboolean ret;
+#if !GLIB_CHECK_VERSION(2,17,1)
+	GError *l_error = NULL;
+#endif
+
+	file = g_file_new_for_uri (uri);
+	parent = g_file_get_parent (file);
+	g_object_unref (file);
+
+#if GLIB_CHECK_VERSION(2,17,1)
+	ret = g_file_make_directory_with_parents (parent, NULL, error);
+#else
+	ret = create_parent_dirs (parent, &l_error);
+
+	if (l_error != NULL) {
+		g_propagate_error (error, l_error);
+	}
+#endif
+	g_object_unref (parent);
+	return ret;
+}
+
 char *
-rb_sanitize_uri_for_filesystem(gchar *uri)
+rb_sanitize_uri_for_filesystem (char *uri)
 {
-	gchar *filesystem = rb_uri_get_filesystem_type(uri);
-	gchar *sane_uri = NULL;
+	char *filesystem = rb_uri_get_filesystem_type (uri);
+	char *sane_uri = NULL;
 
 	if (!filesystem)
-		return g_strdup(uri);
+		return g_strdup (uri);
 
-	if (!strcmp(filesystem, "fat") ||
-	    !strcmp(filesystem, "vfat") ) {
-	    	gchar *hostname = NULL;
+	if (!strcmp (filesystem, "fat") ||
+	    !strcmp (filesystem, "vfat") ) {
+	    	char *hostname = NULL;
 		GError *error = NULL;
-	    	gchar *full_path = g_filename_from_uri(uri, &hostname, &error);
+	    	char *full_path = g_filename_from_uri (uri, &hostname, &error);
 
 		if (error) {
-			g_error_free(error);
-			g_free(filesystem);
-			g_free(full_path);
-			return g_strdup(uri);
+			g_error_free (error);
+			g_free (filesystem);
+			g_free (full_path);
+			return g_strdup (uri);
 		}
 
 		g_strdelimit (full_path, "\"", '\'');
 		g_strdelimit (full_path, ":|<>*?\\", '_');
 
 		/* create a new uri from this */
-		sane_uri = g_filename_to_uri(full_path, hostname, &error);
+		sane_uri = g_filename_to_uri (full_path, hostname, &error);
 
-		g_free(hostname);
-		g_free(full_path);
+		g_free (hostname);
+		g_free (full_path);
 
 		if (error) {
-			g_error_free(error);
-			g_free(filesystem);
-			return g_strdup(uri);
+			g_error_free (error);
+			g_free (filesystem);
+			return g_strdup (uri);
 		}
 	}
 
 	/* add workarounds for other filesystems limitations here */
 
-	g_free(filesystem);
-	return sane_uri ? sane_uri : g_strdup(uri);
+	g_free (filesystem);
+	return sane_uri ? sane_uri : g_strdup (uri);
 }

Modified: trunk/lib/rb-file-helpers.h
==============================================================================
--- trunk/lib/rb-file-helpers.h	(original)
+++ trunk/lib/rb-file-helpers.h	Tue Jul 29 13:17:53 2008
@@ -31,7 +31,7 @@
 #define __RB_FILE_HELPERS_H
 
 #include <glib.h>
-#include <libgnomevfs/gnome-vfs.h>
+#include <gio/gio.h>
 
 G_BEGIN_DECLS
 
@@ -41,13 +41,12 @@
 
 char *		rb_canonicalise_uri	(const char *uri);
 
-GnomeVFSResult	rb_uri_mkstemp		(const char *prefix, char **uri,
-					 GnomeVFSHandle **handle);
+gboolean	rb_uri_mkstemp		(const char *prefix, char **uri,
+					 GOutputStream **handle, GError **error);
 
-char *		rb_uri_resolve_symlink	(const char *uri);
+char *		rb_uri_resolve_symlink	(const char *uri, GError **error);
 gboolean	rb_uri_is_directory	(const char *uri);
 gboolean	rb_uri_exists		(const char *uri);
-char *		rb_uri_resolve_relative	(const char *uri);
 gboolean	rb_uri_is_readable	(const char *uri);
 gboolean	rb_uri_is_writable	(const char *uri);
 gboolean	rb_uri_is_local		(const char *uri);
@@ -56,18 +55,19 @@
 char *		rb_uri_make_hidden      (const char *uri);
 char *		rb_uri_get_dir_name	(const char *uri);
 char *		rb_uri_get_short_path_name (const char *uri);
+char *		rb_uri_get_mount_point  (const char *uri);
 
 /* return TRUE to recurse further, FALSE to stop */
-typedef gboolean (*RBUriRecurseFunc) (const char *uri, gboolean dir, gpointer data);
+typedef gboolean (*RBUriRecurseFunc) (GFile *file, gboolean dir, gpointer data);
 
 void		rb_uri_handle_recursively(const char *uri,
+					  GCancellable *cancel,
 					  RBUriRecurseFunc func,
-					  gboolean *cancelflag,
 					  gpointer user_data);
 
 void		rb_uri_handle_recursively_async(const char *uri,
+						GCancellable *cancel,
 						RBUriRecurseFunc func,
-						gboolean *cancelflag,
 						gpointer user_data,
 						GDestroyNotify data_destroy);
 
@@ -76,6 +76,11 @@
 char*		rb_uri_append_uri	(const char *uri,
 					 const char *fragment);
 
+gboolean	rb_check_dir_has_space	(GFile *dir, guint64 bytes_needed);
+gboolean	rb_check_dir_has_space_uri (const char *uri, guint64 bytes_needed);
+
+gboolean	rb_uri_create_parent_dirs (const char *uri, GError **error);
+
 void		rb_file_helpers_init	(void);
 void		rb_file_helpers_shutdown(void);
 

Modified: trunk/lib/rb-marshal.list
==============================================================================
--- trunk/lib/rb-marshal.list	(original)
+++ trunk/lib/rb-marshal.list	Tue Jul 29 13:17:53 2008
@@ -6,6 +6,7 @@
 BOOLEAN:STRING,STRING,OBJECT
 INT:VOID
 OBJECT:OBJECT
+OBJECT:VOID
 STRING:STRING
 VOID:BOOLEAN,BOOLEAN
 BOXED:BOXED

Modified: trunk/lib/rb-proxy-config.c
==============================================================================
--- trunk/lib/rb-proxy-config.c	(original)
+++ trunk/lib/rb-proxy-config.c	Tue Jul 29 13:17:53 2008
@@ -266,7 +266,6 @@
  *
  * Return value: a libsoup URI object containing the current HTTP proxy configuration.
  */
-#if defined(HAVE_LIBSOUP_2_4)
 SoupURI *
 rb_proxy_config_get_libsoup_uri (RBProxyConfig *config)
 {
@@ -287,26 +286,4 @@
 
 	return uri;
 }
-#elif defined(HAVE_LIBSOUP_2_2)
-SoupUri *
-rb_proxy_config_get_libsoup_uri (RBProxyConfig *config)
-{
-	SoupUri *uri = NULL;
-
-	if (!config->enabled)
-		return NULL;
-
-	uri = g_new0 (SoupUri, 1);
-	uri->protocol = SOUP_PROTOCOL_HTTP;
-
-	uri->host = g_strdup (config->host);
-	uri->port = config->port;
-	if (config->auth_enabled) {
-		uri->user = g_strdup (config->username);
-		uri->passwd = g_strdup (config->password);
-	}
-
-	return uri;
-}
-#endif
 

Modified: trunk/lib/rb-proxy-config.h
==============================================================================
--- trunk/lib/rb-proxy-config.h	(original)
+++ trunk/lib/rb-proxy-config.h	Tue Jul 29 13:17:53 2008
@@ -32,7 +32,6 @@
 #include <glib-object.h>
 
 #if defined(HAVE_LIBSOUP)
-#include "rb-soup-compat.h"
 #include <libsoup/soup.h>
 #endif
 

Modified: trunk/lib/rb-util.c
==============================================================================
--- trunk/lib/rb-util.c	(original)
+++ trunk/lib/rb-util.c	Tue Jul 29 13:17:53 2008
@@ -34,10 +34,9 @@
 #include <stdlib.h>
 
 #include <gtk/gtk.h>
-#include <libgnome/gnome-i18n.h>
-#include <libgnomevfs/gnome-vfs.h>
-#include <libgnomevfs/gnome-vfs-mime-handlers.h>
+#include <glib/gi18n.h>
 #include <gobject/gvaluecollector.h>
+#include <gio/gio.h>
 
 #include "rb-util.h"
 #include "rb-debug.h"
@@ -324,133 +323,21 @@
 	}
 }
 
-static GList *
-get_mount_points (void)
-{
-	GnomeVFSVolumeMonitor *monitor;
-	GList *volumes;
-	GList *it;
-	GList *mount_points = NULL;
-
-	monitor = gnome_vfs_get_volume_monitor ();
-	/* FIXME: should also get the list of connected drivers (network
-	 * shares I assume)
-	 */
-	volumes = gnome_vfs_volume_monitor_get_mounted_volumes (monitor);
-
-	for (it = volumes; it != NULL; it = it->next) {
-		gchar *uri;
-		GnomeVFSVolume *volume;
-
-		volume = GNOME_VFS_VOLUME (it->data);
-		uri = gnome_vfs_volume_get_activation_uri (volume);
-		g_assert (uri != NULL);
-		mount_points = g_list_prepend (mount_points, uri);
-	}
-
-	g_list_foreach (volumes, (GFunc)gnome_vfs_volume_unref, NULL);
-	g_list_free (volumes);
-
-	return mount_points;
-}
-
-
-gchar *
-rb_uri_get_mount_point (const char *uri)
-{
-	GList *mount_points = get_mount_points ();
-	GList *it;
-	gchar *mount_point = NULL;
-
-	for (it = mount_points; it != NULL; it = it->next) {
-		if (g_str_has_prefix (uri, it->data)) {
-			if ((mount_point == NULL) || (strlen (mount_point) < strlen (it->data))) {
-				g_free (mount_point);
-				mount_point = g_strdup (it->data);
-			}
-		}
-	}
-	g_list_foreach (mount_points, (GFunc)g_free, NULL);
-	g_list_free (mount_points);
-
-	return mount_point;
-}
-
-gchar *
+char *
 rb_uri_get_filesystem_type(const char *uri)
 {
-	GnomeVFSVolume *volume = NULL;
-	GnomeVFSVolumeMonitor *monitor = NULL;
-	gchar *mount_point_uri = NULL, *mount_point_path = NULL;
-	gchar *fstype = NULL;
-	GError *error = NULL;
-	
-	g_return_val_if_fail(uri != NULL, NULL);
-
-	monitor = gnome_vfs_get_volume_monitor ();
-	if (monitor == NULL) {
-		goto error;
-	}
-
-	mount_point_uri = rb_uri_get_mount_point(uri);
-	if (mount_point_uri == NULL) {
-		goto error;
+	GFile *file;
+	GFileInfo *info;
+	char *fstype = NULL;
+
+	file = g_file_new_for_uri (uri);
+	info = g_file_query_filesystem_info (file, G_FILE_ATTRIBUTE_FILESYSTEM_TYPE, NULL, NULL);
+	if (info != NULL) {
+		fstype = g_file_info_get_attribute_as_string (info, G_FILE_ATTRIBUTE_FILESYSTEM_TYPE);
+		g_object_unref (info);
 	}
-	
-	mount_point_path = g_filename_from_uri(mount_point_uri, NULL, &error);
-	if (error) {
-		g_warning("%s", error->message);
-		g_error_free(error);
-		goto error;
-	}
-
-	volume = gnome_vfs_volume_monitor_get_volume_for_path(monitor, mount_point_path);
-	if (volume  == NULL) {
- 		goto error;
-	}
-	g_free(mount_point_path);
-	g_free(mount_point_uri);
-
-	fstype = gnome_vfs_volume_get_filesystem_type(volume);
-	
-	gnome_vfs_volume_unref(volume);
-	
+	g_object_unref (file);
 	return fstype;
-
- error:
-	if (volume != NULL) {
-		gnome_vfs_volume_unref(volume);
-	}
-	g_free(mount_point_path);
-	g_free(mount_point_uri);
-	return NULL;
-}
-
-gboolean
-rb_uri_is_mounted (const char *uri)
-{
-	GList *mount_points = get_mount_points ();
-	GList *it;
-	gboolean found = FALSE;
-
-	if ((uri == NULL) || (*uri == '\0')) {
-		return TRUE;
-	}
-
-	for (it = mount_points; it != NULL; it = it->next) {
-		if (strcmp (it->data, uri) == 0) {
-			found = TRUE;
-			break;
-		}
-	}
-	g_list_foreach (mount_points, (GFunc)g_free, NULL);
-	g_list_free (mount_points);
-
-/*	if (found == FALSE) {
-		g_print ("%s not mounted\n", uri);
-		}*/
-
-	return found;
 }
 
 gboolean
@@ -935,13 +822,13 @@
 	return g_list_reverse (result);
 }
 
-const gchar*
-rb_mime_get_friendly_name (const gchar *mime_type)
+char*
+rb_mime_get_friendly_name (const char *mime_type)
 {
-	const gchar *name = NULL;
+	gchar *name = NULL;
 	
 	if (name == NULL && mime_type)
-		name = gnome_vfs_mime_get_description (mime_type);
+		name = g_content_type_get_description (mime_type);
 	if (name == NULL)
 		name = _("Unknown");
 

Modified: trunk/lib/rb-util.h
==============================================================================
--- trunk/lib/rb-util.h	(original)
+++ trunk/lib/rb-util.h	Tue Jul 29 13:17:53 2008
@@ -54,11 +54,7 @@
 
 GtkWidget *rb_image_new_from_stock (const gchar *stock_id, GtkIconSize size);
 
-gchar *rb_uri_get_mount_point (const char *uri);
-gchar *rb_uri_get_filesystem_type(const char *uri);
-
-gboolean rb_uri_is_mounted (const char *uri);
-
+char *rb_uri_get_filesystem_type(const char *uri);
 
 void rb_threads_init (void);
 gboolean rb_is_main_thread (void);
@@ -80,7 +76,7 @@
 GList* rb_collate_hash_table_values (GHashTable *table);
 
 GList* rb_uri_list_parse (const char *uri_list);
-const gchar* rb_mime_get_friendly_name (const gchar *mime_type);
+char* rb_mime_get_friendly_name (const char *mime_type);
 
 gboolean rb_signal_accumulator_object_handled (GSignalInvocationHint *hint,
 					       GValue *return_accu,

Modified: trunk/metadata/rb-metadata-dbus-service.c
==============================================================================
--- trunk/metadata/rb-metadata-dbus-service.c	(original)
+++ trunk/metadata/rb-metadata-dbus-service.c	Tue Jul 29 13:17:53 2008
@@ -35,8 +35,6 @@
 #include <unistd.h>
 
 #include <glib/gi18n.h>
-#include <libgnomeui/gnome-authentication-manager.h>
-#include <libgnomevfs/gnome-vfs.h>
 #include <gst/gst.h>
 
 #include <dbus/dbus.h>
@@ -495,8 +493,6 @@
 	textdomain (GETTEXT_PACKAGE);
 #endif
 	g_type_init ();
-	gnome_vfs_init ();
-	gnome_authentication_manager_init ();
 	gst_init (NULL, NULL);
 	g_set_prgname ("rhythmbox-metadata");
 

Modified: trunk/metadata/rb-metadata-gst.c
==============================================================================
--- trunk/metadata/rb-metadata-gst.c	(original)
+++ trunk/metadata/rb-metadata-gst.c	Tue Jul 29 13:17:53 2008
@@ -36,10 +36,8 @@
 #include <gst/gsttagsetter.h>
 #include <gst/tag/tag.h>
 #include <gst/gsturi.h>
-
-#ifdef HAVE_GSTREAMER_0_10_MISSING_PLUGINS
+#include <gio/gio.h>
 #include <gst/pbutils/pbutils.h>
-#endif /* HAVE_GSTREAMER_0_10_MISSING_PLUGINS */
 
 #include "rb-metadata.h"
 #include "rb-debug.h"
@@ -329,7 +327,7 @@
 rb_metadata_init (RBMetaData *md)
 {
 	RBAddTaggerElem tagger;
-	gboolean has_gnomevfssink = FALSE;
+	gboolean has_giosink = FALSE;
 	gboolean has_id3 = FALSE;
 
 	md->priv = RB_METADATA_GET_PRIVATE (md);
@@ -345,10 +343,9 @@
  	 * only registering types we have plugins for defeats the second
 	 * purpose.
  	 */
-	has_gnomevfssink = (gst_element_factory_find ("gnomevfssrc") != NULL &&
-			    gst_element_factory_find ("gnomevfssink") != NULL);
+	has_giosink = (gst_element_factory_find ("giostreamsink") != NULL);
 	has_id3 = (gst_element_factory_find ("id3v2mux") != NULL);
-	tagger = (has_gnomevfssink && has_id3) ?  rb_add_id3_tagger : NULL;
+	tagger = (has_giosink && has_id3) ?  rb_add_id3_tagger : NULL;
 	add_supported_type (md, "application/x-id3", tagger, "MP3");
 	add_supported_type (md, "audio/mpeg", tagger, "MP3");
 
@@ -359,7 +356,7 @@
 			      gst_default_registry_check_feature_version ("vorbisparse", 0, 10, 6) &&
 			      gst_default_registry_check_feature_version ("oggmux", 0, 10, 6) &&
 			      gst_default_registry_check_feature_version ("oggdemux", 0, 10, 6));
-		tagger = (has_gnomevfssink && has_vorbis) ?  rb_add_ogg_tagger : NULL;
+		tagger = (has_giosink && has_vorbis) ?  rb_add_ogg_tagger : NULL;
 	}
 	add_supported_type (md, "application/ogg", tagger, "Ogg Vorbis");
 	add_supported_type (md, "audio/x-vorbis", tagger, "Ogg Vorbis");
@@ -368,7 +365,7 @@
 	add_supported_type (md, "audio/x-wav", NULL, "WAV");
 	add_supported_type (md, "video/x-ms-asf", NULL, "ASF");
 
-	tagger = (has_gnomevfssink && gst_element_factory_find ("flactag")) ?  rb_add_flac_tagger : NULL;
+	tagger = (has_giosink && gst_element_factory_find ("flactag")) ?  rb_add_flac_tagger : NULL;
 	add_supported_type (md, "audio/x-flac", tagger, "FLAC");
 
 }
@@ -585,10 +582,13 @@
 make_undecodable_error (RBMetaData *md)
 {
 	const char *human_name;
+	char *free_name = NULL;
 
-	human_name= rb_metadata_gst_type_to_name (md, md->priv->type);
-	if (human_name == NULL)
-		human_name = rb_mime_get_friendly_name (md->priv->type);
+	human_name = rb_metadata_gst_type_to_name (md, md->priv->type);
+	if (human_name == NULL) {
+		free_name = rb_mime_get_friendly_name (md->priv->type);
+		human_name = free_name;
+	}
 
 	if (human_name) {
 		return g_strdup_printf (_("The GStreamer plugins to decode \"%s\" files cannot be found"),
@@ -597,6 +597,8 @@
 		return g_strdup_printf (_("The file contains a stream of type %s, which is not decodable"),
 					md->priv->type);
 	}
+
+	g_free (free_name);
 }
 
 static void
@@ -785,16 +787,6 @@
 	}
 
 	md->priv->has_non_audio = TRUE;
-#ifndef HAVE_GSTREAMER_0_10_MISSING_PLUGINS
-	/* try to shortcut it a bit */
-	{
-		char *msg;
-
-		msg = make_undecodable_error (md);
-		GST_ELEMENT_ERROR (md->priv->pipeline, STREAM, CODEC_NOT_FOUND, ("%s", msg), (NULL));
-		g_free (msg);
-	}
-#endif
 }
 
 static GstElement *make_pipeline_element (GstElement *pipeline, const char *element, GError **error)
@@ -813,7 +805,6 @@
 	return elem;
 }
 
-#ifdef HAVE_GSTREAMER_0_10_MISSING_PLUGINS
 static void
 rb_metadata_handle_missing_plugin_message (RBMetaData *md, GstMessage *message)
 {
@@ -822,7 +813,6 @@
 		  gst_missing_plugin_message_get_installer_detail (message));
 	md->priv->missing_plugins = g_slist_prepend (md->priv->missing_plugins, gst_message_ref (message));
 }
-#endif
 
 static gboolean
 rb_metadata_bus_handler (GstBus *bus, GstMessage *message, RBMetaData *md)
@@ -891,11 +881,9 @@
 	}
 	case GST_MESSAGE_ELEMENT:
 	{
-#ifdef HAVE_GSTREAMER_0_10_MISSING_PLUGINS
 		if (gst_is_missing_plugin_message (message)) {
 			rb_metadata_handle_missing_plugin_message (md, message);
 		}
-#endif
 		break;
 	}
 	default:
@@ -985,9 +973,7 @@
 						    NULL, (GDestroyNotify) free_gvalue);
 
 	/* The main tagfinding pipeline looks like this:
- 	 * gnomevfssrc ! decodebin ! fakesink
-	 * or
-	 * filesrc ! decodebin ! fakesink
+ 	 * <src> ! decodebin ! fakesink
  	 *
  	 * but we can only link the fakesink in when the decodebin
  	 * creates an audio source pad.  we do this in the 'new-decoded-pad'
@@ -1252,13 +1238,13 @@
 rb_metadata_save (RBMetaData *md, GError **error)
 {
 	GstElement *pipeline = NULL;
-	GstElement *gnomevfssrc = NULL;
+	GstElement *source = NULL;
         GstElement *retag_end = NULL; /* the last element after retagging subpipeline */
 	const char *plugin_name = NULL;
 	char *tmpname_prefix = NULL;
 	char *tmpname = NULL;
-	GnomeVFSHandle *handle = NULL;
-	GnomeVFSResult result;
+	GOutputStream *stream = NULL;
+	GError *io_error = NULL;
 	RBAddTaggerElem add_tagger_func;
 
 	g_return_if_fail (md->priv->uri != NULL);
@@ -1269,27 +1255,29 @@
 	tmpname_prefix = rb_uri_make_hidden (md->priv->uri);
 	rb_debug ("temporary file name prefix: %s", tmpname_prefix);
 
-	result = rb_uri_mkstemp (tmpname_prefix, &tmpname, &handle);
+	rb_uri_mkstemp (tmpname_prefix, &tmpname, &stream, &io_error);
 	g_free (tmpname_prefix);
-	if (result != GNOME_VFS_OK)
-		goto vfs_error;
+	if (io_error != NULL) {
+		goto gio_error;
+	}
 
 	pipeline = gst_pipeline_new ("pipeline");
 	md->priv->pipeline = pipeline;
 
 	/* Source */
-	plugin_name = "gnomevfssrc";
-	if (!(gnomevfssrc = gst_element_factory_make (plugin_name, plugin_name)))
-		goto missing_plugin;
-	gst_bin_add (GST_BIN (pipeline), gnomevfssrc);
-	g_object_set (G_OBJECT (gnomevfssrc), "location", md->priv->uri, NULL);
+	source = gst_element_make_from_uri (GST_URI_SRC, md->priv->uri, "urisrc");
+	if (source == NULL) {
+		plugin_name = "urisrc";
+		goto missing_plugin;	
+	}
+	gst_bin_add (GST_BIN (pipeline), source);
 
 	/* Sink */
-	plugin_name = "gnomevfssink";
+	plugin_name = "giostreamsink";
 	if (!(md->priv->sink = gst_element_factory_make (plugin_name, plugin_name)))
 		goto missing_plugin;
 
-	g_object_set (G_OBJECT (md->priv->sink), "handle", handle, NULL);
+	g_object_set (G_OBJECT (md->priv->sink), "stream", stream, NULL);
 
 	md->priv->tags = gst_tag_list_new ();
 	g_hash_table_foreach (md->priv->metadata,
@@ -1307,7 +1295,7 @@
 		goto out_error;
 	}
 
-	retag_end = add_tagger_func (md, gnomevfssrc);
+	retag_end = add_tagger_func (md, source);
 	if (!retag_end) {
 		g_set_error (error,
 			     RB_METADATA_ERROR,
@@ -1336,10 +1324,15 @@
 		g_propagate_error (error, md->priv->error);
 		goto out_error;
 	}
-	if (handle != NULL) {
-		if ((result = gnome_vfs_close (handle)) != GNOME_VFS_OK)
-			goto vfs_error;
-		handle = NULL;
+	if (stream != NULL) {
+		GFile *src;
+		GFile *dest;
+
+		if (g_output_stream_close (stream, NULL, &io_error) == FALSE) {
+			goto gio_error;
+		}
+		g_object_unref (stream);
+		stream = NULL;
 
 		/* check to ensure the file isn't corrupt */
 		if (!rb_metadata_file_valid (md->priv->uri, tmpname)) {
@@ -1350,17 +1343,21 @@
 			goto out_error;
 		}
 
-		if ((result = gnome_vfs_move (tmpname, md->priv->uri, TRUE)) != GNOME_VFS_OK)
-				goto vfs_error;
+		src = g_file_new_for_uri (tmpname);
+		dest = g_file_new_for_uri (md->priv->uri);
+		g_file_move (src, dest, G_FILE_COPY_OVERWRITE, NULL, NULL, NULL, &io_error);
+		if (io_error != NULL) {
+			goto gio_error;
+		}
 	}
 
 	goto out;
-vfs_error:
+gio_error:
 	g_set_error (error,
 		     RB_METADATA_ERROR,
-		     RB_METADATA_ERROR_GNOMEVFS,
+		     RB_METADATA_ERROR_IO,
 		     "%s",
-		     gnome_vfs_result_to_string (result));
+		     io_error->message);
 	goto out_error;
 missing_plugin:
 	g_set_error (error,
@@ -1369,10 +1366,17 @@
 		     _("Failed to create %s element; check your installation"),
 		     plugin_name);
 out_error:
-	if (handle != NULL)
-		gnome_vfs_close (handle);
-	if (tmpname != NULL)
-		gnome_vfs_unlink (tmpname);
+	if (stream != NULL) {
+		g_output_stream_close (stream, NULL, NULL);
+		g_object_unref (stream);
+	}
+
+	if (tmpname != NULL) {
+		GFile *del;
+		del = g_file_new_for_uri (tmpname);
+		g_file_delete (del, NULL, NULL);
+		g_object_unref (del);
+	}
 
 out:
 	if (md->priv->tags)
@@ -1430,11 +1434,7 @@
 gboolean
 rb_metadata_has_missing_plugins (RBMetaData *md)
 {
-#ifdef HAVE_GSTREAMER_0_10_MISSING_PLUGINS
 	return (g_slist_length (md->priv->missing_plugins) > 0);
-#else
-	return FALSE;
-#endif
 }
 
 gboolean
@@ -1442,7 +1442,6 @@
 				 char ***missing_plugins,
 				 char ***plugin_descriptions)
 {
-#ifdef HAVE_GSTREAMER_0_10_MISSING_PLUGINS
 	char **mp;
 	char **pd;
 	int count;
@@ -1477,8 +1476,5 @@
 	*missing_plugins = mp;
 	*plugin_descriptions = pd;
 	return TRUE;
-#else
-	return FALSE;
-#endif
 }
 

Modified: trunk/metadata/rb-metadata.h
==============================================================================
--- trunk/metadata/rb-metadata.h	(original)
+++ trunk/metadata/rb-metadata.h	Tue Jul 29 13:17:53 2008
@@ -75,7 +75,7 @@
 
 typedef enum
 {
-	RB_METADATA_ERROR_GNOMEVFS,
+	RB_METADATA_ERROR_IO,
 	RB_METADATA_ERROR_MISSING_PLUGIN,
 	RB_METADATA_ERROR_UNRECOGNIZED,
 	RB_METADATA_ERROR_UNSUPPORTED,

Modified: trunk/plugins/Makefile.am
==============================================================================
--- trunk/plugins/Makefile.am	(original)
+++ trunk/plugins/Makefile.am	Tue Jul 29 13:17:53 2008
@@ -1,6 +1,7 @@
 ## arch-tag: Automake rules for Rhythmbox's plugin system
 
 SUBDIRS = 						\
+	audiocd						\
 	generic-player					\
 	iradio						\
 	mmkeys						\
@@ -40,7 +41,6 @@
 
 if USE_CD_BURNING
 SUBDIRS += 						\
-	audiocd						\
 	cd-recorder
 endif
 

Modified: trunk/plugins/audiocd/rb-audiocd-plugin.c
==============================================================================
--- trunk/plugins/audiocd/rb-audiocd-plugin.c	(original)
+++ trunk/plugins/audiocd/rb-audiocd-plugin.c	Tue Jul 29 13:17:53 2008
@@ -39,20 +39,6 @@
 #include <gmodule.h>
 #include <gtk/gtk.h>
 
-/* nautilus-cd-burner stuff */
-#include <nautilus-burn-drive.h>
-#ifndef NAUTILUS_BURN_CHECK_VERSION
-#define NAUTILUS_BURN_CHECK_VERSION(a,b,c) FALSE
-#endif
-
-#if NAUTILUS_BURN_CHECK_VERSION(2,15,3)
-#include <nautilus-burn.h>
-#endif
-
-#ifndef HAVE_BURN_DRIVE_UNREF
-#define nautilus_burn_drive_unref nautilus_burn_drive_free
-#endif
-
 #include <gst/gst.h>
 
 #include "rb-plugin.h"
@@ -81,10 +67,6 @@
 
 	GHashTable *sources;
 	char       *playing_uri;
-
-#if !NAUTILUS_BURN_CHECK_VERSION(2,15,3) && !HAVE_HAL
-	GHashTable *cd_drive_mapping;
-#endif
 } RBAudioCdPlugin;
 
 typedef struct
@@ -105,7 +87,7 @@
 						      const char *uri,
 						      RBAudioCdPlugin *plugin);
 static RBSource * create_source_cb (RBRemovableMediaManager *rmm,
-				    GnomeVFSVolume *volume,
+				    GVolume *volume,
 				    RBAudioCdPlugin *plugin);
 
 RB_PLUGIN_REGISTER(RBAudioCdPlugin, rb_audiocd_plugin)
@@ -128,10 +110,6 @@
 rb_audiocd_plugin_init (RBAudioCdPlugin *plugin)
 {
 	rb_debug ("RBAudioCdPlugin initialising");
-
-#if NAUTILUS_BURN_CHECK_VERSION(2,15,3)
-	nautilus_burn_init ();
-#endif
 }
 
 static void
@@ -141,157 +119,9 @@
 	RBAudioCdPlugin *plugin = RB_AUDIOCD_PLUGIN (object);
 */
 	rb_debug ("RBAudioCdPlugin finalising");
-
-#if NAUTILUS_BURN_CHECK_VERSION(2,15,3)
-	nautilus_burn_shutdown ();
-#endif
-
 	G_OBJECT_CLASS (rb_audiocd_plugin_parent_class)->finalize (object);
 }
 
-static void
-rb_audiocd_plugin_mount_volume (RBAudioCdPlugin *plugin,
-				GnomeVFSVolume  *volume)
-{
-	RBRemovableMediaManager *rmm = NULL;
-	RBSource *source;
-	gchar *device_path;
-
-	g_object_get (G_OBJECT (plugin->shell),
-		      "removable-media-manager", &rmm,
-		      NULL);
-
-	device_path = gnome_vfs_volume_get_device_path (volume);
-	rb_debug ("checking audiocd for %s", device_path);
-	g_free (device_path);
-	source = create_source_cb (rmm, volume, plugin);
-	if (source) {
-		rb_debug ("creating audio cd source behind RMMs back for %p", volume);
-		rb_shell_append_source (plugin->shell, source, NULL);
-	}
-
-	g_object_unref (rmm);
-}
-
-#if !NAUTILUS_BURN_CHECK_VERSION(2,15,3) && !HAVE_HAL
-typedef struct
-{
-	gboolean           removed;
-	gboolean           tray_opened;
-	RBAudioCdPlugin   *plugin;
-	NautilusBurnDrive *drive;
-} RbCdDriveInfo;
-
-static void
-rb_audiocd_plugin_unmount_volume (RBAudioCdPlugin *plugin,
-				  GnomeVFSVolume  *volume)
-{
-	RBSource *source;
-
-	source = g_hash_table_lookup (plugin->sources, volume);
-	if (source != NULL) {
-		rb_source_delete_thyself (source);
-	}
-}
-
-#ifdef HAVE_BURN_DRIVE_DOOR
-static
-gboolean poll_tray_opened (RbCdDriveInfo *info)
-{
-	GnomeVFSVolumeMonitor *monitor =  gnome_vfs_get_volume_monitor ();
-	gboolean new_status;
-	GnomeVFSVolume *volume;
-
-	if (info->removed) {
-		nautilus_burn_drive_unref (info->drive);
-		g_free (info);
-		return FALSE;
-	}
-
-	new_status = nautilus_burn_drive_door_is_open (info->drive);
-
-	if (new_status != info->tray_opened) {
-		volume = gnome_vfs_volume_monitor_get_volume_for_path (monitor, info->drive->device);
-		rb_debug ("found volume for %s",  info->drive->device);
-		if (volume) {
-			if (new_status) {
-				rb_audiocd_plugin_unmount_volume (info->plugin, volume);
-			} else {
-				rb_audiocd_plugin_mount_volume (info->plugin, volume);
-			}
-			gnome_vfs_volume_unref (volume);
-		}
-	}
-	info->tray_opened = new_status;
-
-	return TRUE;
-}
-#endif
-
-static
-void end_cd_drive_monitor (RbCdDriveInfo *info,
-			   gpointer       data)
-{
-	/* this will be freed when the poll next gets called */
-	info->removed = TRUE;
-}
-
-static
-void begin_cd_drive_monitor (NautilusBurnDrive *drive,
-			     RBAudioCdPlugin   *plugin)
-{
-#ifdef HAVE_BURN_DRIVE_DOOR
-	RbCdDriveInfo *info = g_new0 (RbCdDriveInfo, 1);
-	GnomeVFSVolumeMonitor *monitor=  gnome_vfs_get_volume_monitor ();
-	GnomeVFSVolume *volume;
-
-	info->drive = drive;
-	info->tray_opened = nautilus_burn_drive_door_is_open (drive);
-	info->plugin = plugin;
-
-	g_hash_table_insert (plugin->cd_drive_mapping, drive, info);
-	g_timeout_add (1000, (GSourceFunc)poll_tray_opened, info);
-
-	volume = gnome_vfs_volume_monitor_get_volume_for_path (monitor, drive->device);
-	rb_debug ("found volume for %s", drive->device);
-
-	if (volume) {
-		if (!nautilus_burn_drive_door_is_open (drive)) {
-			rb_audiocd_plugin_mount_volume (plugin, volume);
-		} else {
-			/* it may have got ejected while we weren't monitoring */
-			rb_audiocd_plugin_unmount_volume (plugin, volume);
-		}
-	}
-#endif
-}
-
-static NautilusBurnDrive *
-get_nautilus_burn_drive_for_path (const char *path)
-{
-#ifdef HAVE_BURN_DRIVE_NEW_FROM_PATH
-	return nautilus_burn_drive_new_from_path (path);
-#else
-	GList *drives, *l;
-	NautilusBurnDrive *path_drive = NULL;
-
-	drives = nautilus_burn_drive_get_list (FALSE, FALSE);
-	for (l = drives; l != NULL; l = g_list_next (l)) {
-		NautilusBurnDrive *drive = (NautilusBurnDrive*)l->data;
-
-		if (path_drive == NULL && strcmp (drive->device, path) == 0) {
-			path_drive = drive;
-		} else {
-			nautilus_burn_drive_unref (drive);
-		}
-	}
-	g_list_free (drives);
-
-	return path_drive;
-#endif
-}
-#endif /* NAUTILUS_BURN < 2.15.3 */
-
 static char *
 split_drive_from_cdda_uri (const char *uri)
 {
@@ -335,30 +165,6 @@
 		new_drive = split_drive_from_cdda_uri (uri);
 	}
 
-#if !NAUTILUS_BURN_CHECK_VERSION(2,15,3) && !HAVE_HAL
-	/* if the drive we're playing from has changed, adjust the polling */
-	if (old_drive == NULL || new_drive == NULL || strcmp (old_drive, new_drive) != 0) {
-		if (old_drive != NULL) {
-			NautilusBurnDrive *drive;
-
-			rb_debug ("restarting monitoring of drive %s after playing", old_drive);
-			drive = get_nautilus_burn_drive_for_path (old_drive);
-			begin_cd_drive_monitor (drive, plugin);
-			nautilus_burn_drive_unref (drive);
-		}
-
-		if (new_drive != NULL) {
-			NautilusBurnDrive *drive;
-
-			rb_debug ("stopping monitoring of drive %s while playing", new_drive);
-			drive = get_nautilus_burn_drive_for_path (new_drive);
-			/* removing it from the hash table makes it stop monitoring */
-			g_hash_table_remove (plugin->cd_drive_mapping, drive);
-			nautilus_burn_drive_unref (drive);
-		}
-	}
-#endif
-
 	g_free (plugin->playing_uri);
 	plugin->playing_uri = uri ? g_strdup (uri) : NULL;
 }
@@ -428,21 +234,11 @@
 	gst_object_unref (pad);
 }
 
-#if !NAUTILUS_BURN_CHECK_VERSION(2,15,3)
-static const char *
-nautilus_burn_drive_get_device (NautilusBurnDrive *drive)
-{
-	g_return_val_if_fail (drive != NULL, NULL);
-
-	return drive->device;
-}
-#endif
-
 static void
 rb_audiocd_plugin_source_deleted (RBAudioCdSource *source,
 				  RBAudioCdPlugin *plugin)
 {
-	GnomeVFSVolume *volume;
+	GVolume *volume;
 
 	g_object_get (source, "volume", &volume, NULL);
 	g_hash_table_remove (plugin->sources, volume);
@@ -451,7 +247,7 @@
 
 static RBSource *
 create_source_cb (RBRemovableMediaManager *rmm,
-		  GnomeVFSVolume          *volume,
+		  GVolume                 *volume,
 		  RBAudioCdPlugin         *plugin)
 {
 	RBSource *source = NULL;
@@ -477,9 +273,6 @@
 	RBAudioCdPlugin         *pi = RB_AUDIOCD_PLUGIN (plugin);
 	RBRemovableMediaManager *rmm;
 	gboolean                 scanned;
-	GList                   *drives;
-	GList                   *it;
-	GnomeVFSVolumeMonitor   *monitor;
 	GObject                 *shell_player;
 	RBPlayer                *player_backend;
 	GtkUIManager            *uimanager;
@@ -512,7 +305,7 @@
 	 * plugins for more specific device types can get in first.
 	 */
 	g_signal_connect_after (rmm,
-				"create-source", G_CALLBACK (create_source_cb),
+				"create-source-volume", G_CALLBACK (create_source_cb),
 				pi);
 
 	/* only scan if we're being loaded after the initial scan has been done */
@@ -547,44 +340,10 @@
 	g_signal_connect_object (shell_player, "playing-uri-changed",
 				 G_CALLBACK (rb_audiocd_plugin_playing_uri_changed_cb),
 				 plugin, 0);
-
-	/*
-	 * Monitor all cd drives for inserted audio cds
-	 *
-	 * This needs to be done seperately from the above, because non-HAL systems don't
-	 * (currently) report audio cd insertions as mount events.
-	 */
-#if !NAUTILUS_BURN_CHECK_VERSION(2,15,3) && !HAVE_HAL
-	pi->cd_drive_mapping = g_hash_table_new_full (NULL, NULL, NULL, (GDestroyNotify)end_cd_drive_monitor);
-	drives = nautilus_burn_drive_get_list (FALSE, FALSE);
-	g_list_foreach (drives, (GFunc)begin_cd_drive_monitor, plugin);
-	g_list_free (drives);
-#endif
-
-	/* scan cd drives */
-#if NAUTILUS_BURN_CHECK_VERSION(2,15,3)
-	drives = nautilus_burn_drive_monitor_get_drives (nautilus_burn_get_drive_monitor ());
-#else
-	drives = nautilus_burn_drive_get_list (FALSE, FALSE);
-#endif
-
-	monitor = gnome_vfs_get_volume_monitor ();
-	for  (it = drives; it != NULL; it = g_list_next (it)) {
-		NautilusBurnDrive *drive = (NautilusBurnDrive *)it->data;
-		GnomeVFSVolume    *volume;
-
-		volume = gnome_vfs_volume_monitor_get_volume_for_path (monitor, nautilus_burn_drive_get_device (drive));
-		rb_debug ("found volume for %s", nautilus_burn_drive_get_device (drive));
-		if (volume != NULL) {
-			rb_audiocd_plugin_mount_volume (pi, volume);
-			gnome_vfs_volume_unref (volume);
-		}
-	}
-	g_list_free (drives);
 }
 
 static void
-_delete_cb (GnomeVFSVolume  *volume,
+_delete_cb (GVolume         *volume,
 	    RBSource        *source,
 	    RBAudioCdPlugin *plugin)
 {
@@ -619,8 +378,4 @@
 
 	g_object_unref (uimanager);
 	g_object_unref (rmm);
-
-#if !NAUTILUS_BURN_CHECK_VERSION(2,15,3) && !HAVE_HAL
-	g_hash_table_destroy (plugin->cd_drive_mapping);
-#endif
 }

Modified: trunk/plugins/audiocd/rb-audiocd-source.c
==============================================================================
--- trunk/plugins/audiocd/rb-audiocd-source.c	(original)
+++ trunk/plugins/audiocd/rb-audiocd-source.c	Tue Jul 29 13:17:53 2008
@@ -38,10 +38,8 @@
 #include <string.h>
 #include <gtk/gtk.h>
 #include <glib/gi18n.h>
-#include <libgnomevfs/gnome-vfs-volume.h>
-#include <libgnomevfs/gnome-vfs-volume-monitor.h>
 #include <gst/gst.h>
-#include <totem-disc.h>
+/*#include <totem-disc.h>*/
 
 #include "rb-plugin.h"
 #include "rhythmdb.h"
@@ -52,6 +50,11 @@
 #include "rb-dialog.h"
 #include "rb-glade-helpers.h"
 
+#ifdef HAVE_HAL
+#include <libhal.h>
+#include <dbus/dbus.h>
+#endif
+
 #ifdef HAVE_MUSICBRAINZ
 #include "sj-metadata-musicbrainz.h"
 #include "sj-structures.h"
@@ -130,10 +133,8 @@
 {
 	RBAudioCdSourcePrivate *priv = AUDIOCD_SOURCE_GET_PRIVATE (object);
 
-	if (priv->device_path) {
-		g_free (priv->device_path);
-		priv->device_path = NULL;
-	}
+	g_free (priv->device_path);
+
 	if (priv->tracks) {
 		g_list_free (priv->tracks);
 		priv->tracks = NULL;
@@ -172,9 +173,8 @@
 RBRemovableMediaSource *
 rb_audiocd_source_new (RBPlugin *plugin,
 		       RBShell *shell,
-		       GnomeVFSVolume *volume)
+		       GVolume *volume)
 {
-	char *device_path;
 	GObject *source;
 	RhythmDBEntryType entry_type;
 	RhythmDB *db;
@@ -184,21 +184,20 @@
 	if (!rb_audiocd_is_volume_audiocd (volume))
 		return NULL;
 
-	g_object_get (G_OBJECT (shell), "db", &db, NULL);
-	path = gnome_vfs_volume_get_device_path (volume);
+	g_object_get (shell, "db", &db, NULL);
+
+	path = g_volume_get_identifier (volume, G_VOLUME_IDENTIFIER_KIND_UNIX_DEVICE);
 	name = g_strdup_printf ("audiocd: %s", path);
 	entry_type = rhythmdb_entry_register_type (db, name);
-	g_object_unref (G_OBJECT (db));
 	g_free (name);
 	g_free (path);
+	g_object_unref (db);
 
 	entry_type->category = RHYTHMDB_ENTRY_NORMAL;
 	entry_type->can_sync_metadata = (RhythmDBEntryCanSyncFunc)rb_true_function;
-	/* TODO same the metadata somewhere */
+	/* TODO save the metadata somewhere */
 	entry_type->sync_metadata = (RhythmDBEntrySyncFunc)rb_null_function;
 
-	device_path = gnome_vfs_volume_get_device_path (volume);
-
 	source = g_object_new (RB_TYPE_AUDIOCD_SOURCE,
 			       "entry-type", entry_type,
 			       "volume", volume,
@@ -208,8 +207,6 @@
 			       "plugin", plugin,
 			       NULL);
 
-	g_free (device_path);
-
 	rb_shell_register_entry_type_for_source (shell, RB_SOURCE (source), entry_type);
 
 	return RB_REMOVABLE_MEDIA_SOURCE (source);
@@ -665,10 +662,11 @@
 {
 	RBAudioCdSourcePrivate *priv = AUDIOCD_SOURCE_GET_PRIVATE (source);
 	RhythmDB *db;
-	GnomeVFSVolume *volume;
+	GVolume *volume;
 
 	g_object_get (source, "volume", &volume, NULL);
-	priv->device_path = gnome_vfs_volume_get_device_path (volume);
+	priv->device_path = g_volume_get_identifier (volume,
+						     G_VOLUME_IDENTIFIER_KIND_UNIX_DEVICE);
 	g_object_unref (volume);
 
 	db = get_db_for_source (source);
@@ -722,38 +720,191 @@
 	g_object_unref (db);
 }
 
+#if  0
 gboolean
-rb_audiocd_is_volume_audiocd (GnomeVFSVolume *volume)
+rb_audiocd_is_volume_audiocd (GVolume *volume)
 {
 	char *device_path;
-	GnomeVFSDeviceType device_type;
-	gboolean result = FALSE;
 
-	device_type = gnome_vfs_volume_get_device_type (volume);
-	device_path = gnome_vfs_volume_get_device_path (volume);
-
-	if (device_path == NULL)
-		return FALSE;
-
-	/* for sometimes device_type is GNOME_VFS_DEVICE_TYPE_CDROM */
-	if (device_type == GNOME_VFS_DEVICE_TYPE_AUDIO_CD || device_type == GNOME_VFS_DEVICE_TYPE_CDROM) {
+	device_path = g_volume_get_identifier (volume, G_VOLUME_IDENTIFIER_KIND_UNIX_DEVICE);
+	if (device_path != NULL) {
+		gboolean result;
+		TotemDiscMediaType media_type;
 		GError *error = NULL;
-		MediaType media_type;
 
+		/* should we do any kind of checking before we make this call? */
 		media_type = totem_cd_detect_type (device_path, &error);
-		g_free (device_path);
 		if (error != NULL) {
-			rb_debug ("error while detecting cd: %s", error->message);
+			rb_debug ("error detecting if volume is an audio CD: %s", error->message);
 			g_error_free (error);
-			return FALSE;
+			result = FALSE;
+		} else if (media_type == MEDIA_TYPE_CDDA) {
+			rb_debug ("totem-disc says this is an audio CD");
+			result = TRUE;
+		} else {
+			rb_debug ("totem-disc says this is not an audio CD");
+			result = FALSE;
 		}
-		rb_debug ("detecting new cd - totem cd media type=%d", media_type);
-		return (media_type == MEDIA_TYPE_CDDA);
+
+		g_free (device_path);
+		return result;
+	} else {
+		rb_debug ("couldn't get device path");
+		return FALSE;
+	}
+}
+#endif
+
+
+#ifdef HAVE_HAL
+
+/* copied this stuff from the generic player plugin,
+ * so it should probably go somewhere common.
+ */
+
+static void
+free_dbus_error (const char *what, DBusError *error)
+{
+	if (dbus_error_is_set (error)) {
+		rb_debug ("%s: dbus error: %s", what, error->message);
+		dbus_error_free (error);
+	}
+}
+
+static LibHalContext *
+get_hal_context (void)
+{
+	LibHalContext *ctx = NULL;
+	DBusConnection *conn = NULL;
+	DBusError error;
+	gboolean result = FALSE;
+
+	dbus_error_init (&error);
+	ctx = libhal_ctx_new ();
+	if (ctx == NULL)
+		return NULL;
+
+	conn = dbus_bus_get (DBUS_BUS_SYSTEM, &error);
+	if (conn != NULL && !dbus_error_is_set (&error)) {
+		libhal_ctx_set_dbus_connection (ctx, conn);
+		if (libhal_ctx_init (ctx, &error))
+			result = TRUE;
+	}
+
+	if (dbus_error_is_set (&error)) {
+		free_dbus_error ("setting up hal context", &error);
+		result = FALSE;
 	}
 
+	if (!result) {
+		libhal_ctx_free (ctx);
+		ctx = NULL;
+	}
+	return ctx;
+}
+
+static void
+cleanup_hal_context (LibHalContext *ctx)
+{
+	DBusError error;
+	if (ctx == NULL)
+		return;
+
+	dbus_error_init (&error);
+	libhal_ctx_shutdown (ctx, &error);
+	libhal_ctx_free (ctx);
+	free_dbus_error ("cleaning up hal context", &error);
+}
+
+#endif
+
+gboolean
+rb_audiocd_is_volume_audiocd (GVolume *volume)
+{
+	GMount *mount;
+#ifdef HAVE_HAL
+	LibHalContext *ctx;
+	char *udi;
+	char *device_path;
+
+	/* get device path for debug purposes */
+	device_path = g_volume_get_identifier (volume, G_VOLUME_IDENTIFIER_KIND_UNIX_DEVICE);
+	if (device_path == NULL) {
+		device_path = g_strdup ("unknown device");
+	}
+
+	/* look at HAL properties to see if it's an audio CD */
+	udi = g_volume_get_identifier (volume, G_VOLUME_IDENTIFIER_KIND_HAL_UDI);
+	if (udi != NULL) {
+		ctx = get_hal_context ();
+		if (ctx != NULL) {
+			gboolean result = FALSE;
+			DBusError error;
+			dbus_error_init (&error);
+
+			/* check if it's a disc at all */
+			if (libhal_device_query_capability (ctx, udi, "volume.disc", &error) &&
+			    !dbus_error_is_set (&error)) {
+				/* check it's a CD with audio; maybe check it's not blank? */
+				char *disc_type;
+				dbus_bool_t is_audio;
+
+				disc_type = libhal_device_get_property_string (ctx, udi, "volume.disc.type", &error);
+				if (dbus_error_is_set (&error)) {
+					free_dbus_error ("checking volume disc type", &error);
+					disc_type = NULL;
+				}
+
+				is_audio = libhal_device_get_property_bool (ctx, udi, "volume.disc.has_audio", &error);
+				if (dbus_error_is_set (&error)) {
+					free_dbus_error ("checking if disc has audio", &error);
+					is_audio = FALSE;
+				}
+
+				if (is_audio && disc_type != NULL && strcmp (disc_type, "cd_rom") == 0) {
+					rb_debug ("disc in %s is an audio CD", device_path);
+					result = TRUE;
+				} else {
+					rb_debug ("disc %s is not an audio CD", device_path);
+				}
+				libhal_free_string (disc_type);
+				
+			} else if (dbus_error_is_set (&error)) {
+				free_dbus_error ("checking volume type", &error);
+			} else {
+				rb_debug ("volume in %s is not a disc", device_path);
+			}
+
+			cleanup_hal_context (ctx);
+			return result;
+		}
+	}
 	g_free (device_path);
+	rb_debug ("HAL couldn't tell us if this is an audio CD or not");
+#endif
 
-	return result;
+	/* if it's mounted, we can check the mount root URI scheme */
+	mount = g_volume_get_mount (volume);
+	if (mount != NULL) {
+		GFile *mount_root;
+		char *uri_scheme;
+		gboolean result = FALSE;
+
+		mount_root = g_mount_get_root (mount);
+		if (mount_root != NULL) {
+			uri_scheme = g_file_get_uri_scheme (mount_root);
+			rb_debug ("URI scheme of mounted volume is %s", uri_scheme);
+			result = (strcmp (uri_scheme, "cdda") == 0);
+
+			g_free (uri_scheme);
+			g_object_unref (mount_root);
+		}
+
+		g_object_unref (mount);
+		return result;
+	}
+
+	return FALSE;
 }
 
 static gboolean
@@ -776,39 +927,19 @@
 	return actions;
 }
 
-static char *
-_gnome_vfs_to_gvfs_cdda_uri (const char *gnome_vfs_uri)
-{
-	GString *retval;
-	guint i;
-
-	if (strstr (gnome_vfs_uri, "/dev/") == NULL)
-		return NULL;
-
-	retval = g_string_new ("");
-	for (i = 0; gnome_vfs_uri[i] != '\0' ;) {
-		if (strncmp (gnome_vfs_uri + i, "/dev/", 5) == 0)
-			i += 5;
-		else {
-			g_string_append_c (retval, gnome_vfs_uri[i]);
-			i++;
-		}
-	}
-
-	return g_string_free (retval, FALSE);
-}
-
 static guint
 impl_want_uri (RBSource *source, const char *uri)
 {
-	GnomeVFSVolume *volume;
-	char *activation_uri;
+	GVolume *volume;
+	const char *uri_path;
+	char *device_path;
 	int retval;
 
 	retval = 0;
 
 	if (g_str_has_prefix (uri, "cdda://") == FALSE)
 		return 0;
+	uri_path = uri + strlen ("cdda://");
 
 	g_object_get (G_OBJECT (source),
 		      "volume", &volume,
@@ -816,25 +947,11 @@
 	if (volume == NULL)
 		return 0;
 
-	activation_uri = gnome_vfs_volume_get_activation_uri (volume);
-	if (activation_uri == NULL)
-		return 0;
-
-	if (strcmp (activation_uri, uri) == 0)
+	device_path = g_volume_get_identifier (volume, G_VOLUME_IDENTIFIER_KIND_UNIX_DEVICE);
+	if (device_path != NULL && strcmp (device_path, uri_path) == 0) {
 		retval = 100;
-	else {
-		char *gvfs_uri;
-
-		/* FIXME work-around "new" gvfs style URLs:
-		 * cdda://sr0/ instead of cdda:///dev/sr0 */
-		gvfs_uri = _gnome_vfs_to_gvfs_cdda_uri (activation_uri);
-		if (strncmp (gvfs_uri, uri, strlen (gvfs_uri - 1)) == 0)
-			retval = 100;
-		g_free (gvfs_uri);
 	}
-
-	g_free (activation_uri);
-
+	g_free (device_path);
 	return retval;
 }
 

Modified: trunk/plugins/audiocd/rb-audiocd-source.h
==============================================================================
--- trunk/plugins/audiocd/rb-audiocd-source.h	(original)
+++ trunk/plugins/audiocd/rb-audiocd-source.h	Tue Jul 29 13:17:53 2008
@@ -54,12 +54,12 @@
 } RBAudioCdSourceClass;
 
 RBRemovableMediaSource *	rb_audiocd_source_new		(RBPlugin *plugin,
-								 RBShell *shell,
-								 GnomeVFSVolume *volume);
+								 RBShell  *shell,
+								 GVolume  *volume);
 GType			rb_audiocd_source_get_type		(void);
 GType			rb_audiocd_source_register_type		(GTypeModule *module);
 
-gboolean		rb_audiocd_is_volume_audiocd		(GnomeVFSVolume *volume);
+gboolean		rb_audiocd_is_volume_audiocd		(GVolume *volume);
 
 G_END_DECLS
 

Modified: trunk/plugins/audiocd/sj-metadata-musicbrainz.c
==============================================================================
--- trunk/plugins/audiocd/sj-metadata-musicbrainz.c	(original)
+++ trunk/plugins/audiocd/sj-metadata-musicbrainz.c	Tue Jul 29 13:17:53 2008
@@ -44,18 +44,7 @@
 #include <stdlib.h>
 #include <unistd.h>
 
-#include <nautilus-burn-drive.h>
-#ifndef NAUTILUS_BURN_CHECK_VERSION
-#define NAUTILUS_BURN_CHECK_VERSION(a,b,c) FALSE
-#endif
-
-#if NAUTILUS_BURN_CHECK_VERSION(2,15,3)
-#include <nautilus-burn.h>
-#endif
-
-#ifndef HAVE_BURN_DRIVE_UNREF
-#define nautilus_burn_drive_unref nautilus_burn_drive_free
-#endif
+#include <totem-disc.h>
 
 #include "sj-metadata-musicbrainz.h"
 #include "sj-structures.h"
@@ -487,35 +476,6 @@
   g_free (cdindex);
 }
 
-static NautilusBurnMediaType
-get_drive_media_type (SjMetadata *metadata)
-{
-  SjMetadataMusicbrainzPrivate *priv;
-  NautilusBurnDrive *drive;
-  NautilusBurnMediaType type;
-#if NAUTILUS_BURN_CHECK_VERSION(2,15,3)
-  NautilusBurnDriveMonitor *monitor;
-#endif
-
-  priv = SJ_METADATA_MUSICBRAINZ (metadata)->priv;
-#if NAUTILUS_BURN_CHECK_VERSION(2,15,3)
-  if (! nautilus_burn_initialized ()) {
-    nautilus_burn_init ();
-  }
-  monitor = nautilus_burn_get_drive_monitor ();
-  drive = nautilus_burn_drive_monitor_get_drive_for_device (monitor, priv->cdrom);
-#else
-  drive = nautilus_burn_drive_new_from_path (priv->cdrom);
-#endif
-
-  if (drive == NULL) {
-    return NAUTILUS_BURN_MEDIA_TYPE_ERROR;
-  }
-  type = nautilus_burn_drive_get_media_type (drive);
-  nautilus_burn_drive_unref (drive);
-  return type;
-}
-
 static gpointer
 lookup_cd (SjMetadata *metadata)
 {
@@ -525,7 +485,8 @@
   GList *al, *tl;
   char data[256];
   int num_albums, i, j;
-  NautilusBurnMediaType type;
+  TotemDiscMediaType type;
+  GError *totem_error = NULL;
 
   /* TODO: fire error signal */
   g_return_val_if_fail (metadata != NULL, NULL);
@@ -534,22 +495,11 @@
   g_return_val_if_fail (priv->cdrom != NULL, NULL);
   priv->error = NULL; /* TODO: hack */
 
-  type = get_drive_media_type (metadata);
-
-  if (type == NAUTILUS_BURN_MEDIA_TYPE_ERROR) {
-    char *msg;
-    SjError err;
-
-    if (access (priv->cdrom, W_OK) == 0) {
-      msg = g_strdup_printf (_("Device '%s' does not contain any media"), priv->cdrom);
-      err = SJ_ERROR_CD_NO_MEDIA;
-    } else {
-      msg = g_strdup_printf (_("Device '%s' could not be opened. Check the access permissions on the device."), priv->cdrom);
-      err = SJ_ERROR_CD_PERMISSION_ERROR;
-    }
-    priv->error = g_error_new (SJ_ERROR, err, _("Cannot read CD: %s"), msg);
-    g_free (msg);
+  type = totem_cd_detect_type (priv->cdrom, &totem_error);
 
+  if (totem_error != NULL) {
+    priv->error = g_error_new (SJ_ERROR, SJ_ERROR_CD_NO_MEDIA, _("Cannot read CD: %s"), totem_error->message);
+    g_error_free (totem_error);
     priv->albums = NULL;
     g_idle_add ((GSourceFunc)fire_signal_idle, metadata);
     return NULL;

Modified: trunk/plugins/audioscrobbler/rb-audioscrobbler-entry.c
==============================================================================
--- trunk/plugins/audioscrobbler/rb-audioscrobbler-entry.c	(original)
+++ trunk/plugins/audioscrobbler/rb-audioscrobbler-entry.c	Tue Jul 29 13:17:53 2008
@@ -38,7 +38,6 @@
 
 #include "rb-debug.h"
 #include "rhythmdb.h"
-#include "rb-soup-compat.h"
 #include <libsoup/soup.h>
 
 #include "rb-audioscrobbler-entry.h"
@@ -130,19 +129,6 @@
 	return encoded;
 }
 
-static char *
-rb_uri_decode (const char *uri)
-{
-#if defined(HAVE_LIBSOUP_2_4)
-    return soup_uri_decode (uri);
-#else 
-    char *result;
-    result = g_strdup (uri);
-    soup_uri_decode (result);
-    return result;
-#endif
-}
-
 AudioscrobblerEntry*
 rb_audioscrobbler_entry_load_from_string (const char *string)
 {
@@ -161,19 +147,19 @@
 		if (breaks2[0] != NULL && breaks2[1] != NULL) {
 			if (g_str_has_prefix (breaks2[0], "a")) {
 				g_free (entry->artist);
-				entry->artist = rb_uri_decode (breaks2[1]);
+				entry->artist = soup_uri_decode (breaks2[1]);
 			}
 			if (g_str_has_prefix (breaks2[0], "t")) {
 				g_free (entry->title);
-				entry->title = rb_uri_decode (breaks2[1]);
+				entry->title = soup_uri_decode (breaks2[1]);
 			}
 			if (g_str_has_prefix (breaks2[0], "b")) {
 				g_free (entry->album);
-				entry->album = rb_uri_decode (breaks2[1]);
+				entry->album = soup_uri_decode (breaks2[1]);
 			}
 			if (g_str_has_prefix (breaks2[0], "m")) {
 				g_free (entry->mbid);
-				entry->mbid = rb_uri_decode (breaks2[1]);
+				entry->mbid = soup_uri_decode (breaks2[1]);
 			}
 			if (g_str_has_prefix (breaks2[0], "l")) {
 				entry->length = atoi (breaks2[1]);
@@ -203,22 +189,21 @@
 	return entry;
 }
 
-char *
-rb_audioscrobbler_entry_save_to_string (AudioscrobblerEntry *entry)
+void
+rb_audioscrobbler_entry_save_to_string (GString *string, AudioscrobblerEntry *entry)
 {
-	char *result;
 	AudioscrobblerEncodedEntry *encoded;
 
 	encoded = rb_audioscrobbler_entry_encode (entry);
-	result = g_strdup_printf ("a=%s&t=%s&b=%s&m=%s&l=%d&I=%ld\n",
-				  encoded->artist, 
-				  encoded->title,
-				  encoded->album, 
-				  encoded->mbid,
-				  encoded->length,
-				  entry->play_time);
+	g_string_append_printf (string,
+				"a=%s&t=%s&b=%s&m=%s&l=%d&I=%ld\n",
+				encoded->artist,
+				encoded->title,
+				encoded->album,
+				encoded->mbid,
+				encoded->length,
+				entry->play_time);
 	rb_audioscrobbler_encoded_entry_free (encoded);
-	return result;
 }
 
 void

Modified: trunk/plugins/audioscrobbler/rb-audioscrobbler-entry.h
==============================================================================
--- trunk/plugins/audioscrobbler/rb-audioscrobbler-entry.h	(original)
+++ trunk/plugins/audioscrobbler/rb-audioscrobbler-entry.h	Tue Jul 29 13:17:53 2008
@@ -63,7 +63,7 @@
 AudioscrobblerEntry *		rb_audioscrobbler_entry_create (RhythmDBEntry *rb_entry);
 
 AudioscrobblerEntry *		rb_audioscrobbler_entry_load_from_string (const char *string);
-char *				rb_audioscrobbler_entry_save_to_string (AudioscrobblerEntry *entry);
+void				rb_audioscrobbler_entry_save_to_string (GString *string, AudioscrobblerEntry *entry);
 
 void				rb_audioscrobbler_entry_debug (AudioscrobblerEntry *entry, int index);
 

Modified: trunk/plugins/audioscrobbler/rb-audioscrobbler.c
==============================================================================
--- trunk/plugins/audioscrobbler/rb-audioscrobbler.c	(original)
+++ trunk/plugins/audioscrobbler/rb-audioscrobbler.c	Tue Jul 29 13:17:53 2008
@@ -45,7 +45,6 @@
 #include <gtk/gtk.h>
 #include <gconf/gconf-value.h>
 
-#include "rb-soup-compat.h"
 #include <libsoup/soup.h>
 
 #include "eel-gconf-extensions.h"
@@ -181,13 +180,8 @@
 						char *url,
 						char *post_data,
 						SoupSessionCallback response_handler);
-#if defined(HAVE_LIBSOUP_2_4)
 static void	     rb_audioscrobbler_do_handshake_cb (SoupSession *session, SoupMessage *msg, gpointer user_data);
 static void	     rb_audioscrobbler_submit_queue_cb (SoupSession *session, SoupMessage *msg, gpointer user_data);
-#else
-static void	     rb_audioscrobbler_do_handshake_cb (SoupMessage *msg, gpointer user_data);
-static void	     rb_audioscrobbler_submit_queue_cb (SoupMessage *msg, gpointer user_data);
-#endif
 
 static void	     rb_audioscrobbler_import_settings (RBAudioscrobbler *audioscrobbler);
 static void	     rb_audioscrobbler_preferences_sync (RBAudioscrobbler *audioscrobbler);
@@ -679,27 +673,12 @@
 	rb_debug ("Parsing response, status=%d", msg->status_code);
 	
 	successful = FALSE;
-#if defined(HAVE_LIBSOUP_2_4)
 	if (SOUP_STATUS_IS_SUCCESSFUL (msg->status_code) && msg->response_body->length != 0)
 		successful = TRUE;
-#else
-	if (SOUP_STATUS_IS_SUCCESSFUL (msg->status_code) && (msg->response).body != NULL)
-		successful = TRUE;
-#endif
 	if (successful) {
 		gchar **breaks;
 		int i;
-#if defined(HAVE_LIBSOUP_2_2)
-		gchar *body;
-
-		body = g_malloc0 ((msg->response).length + 1);
-		memcpy (body, (msg->response).body, (msg->response).length);
-
-		g_strstrip (body);
-		breaks = g_strsplit (body, "\n", 4);
-#else
 		breaks = g_strsplit (msg->response_body->data, "\n", 4);
-#endif
 
 		g_free (audioscrobbler->priv->status_msg);
 		audioscrobbler->priv->status = STATUS_OK;
@@ -771,9 +750,6 @@
 			audioscrobbler->priv->submit_next = time(NULL) + audioscrobbler->priv->submit_interval;
 
 		g_strfreev (breaks);
-#if defined(HAVE_LIBSOUP_2_2)
-		g_free (body);
-#endif
 	} else {
 		audioscrobbler->priv->status = REQUEST_FAILED;
 		audioscrobbler->priv->status_msg = g_strdup (msg->reason_phrase);
@@ -894,13 +870,8 @@
 }
 
 
-#if defined(HAVE_LIBSOUP_2_4)
 static void
 rb_audioscrobbler_do_handshake_cb (SoupSession *session, SoupMessage *msg, gpointer user_data)
-#else
-static void
-rb_audioscrobbler_do_handshake_cb (SoupMessage *msg, gpointer user_data)
-#endif
 {
 	RBAudioscrobbler *audioscrobbler = RB_AUDIOSCROBBLER(user_data);
 
@@ -1057,13 +1028,8 @@
 	}
 }
 
-#if defined(HAVE_LIBSOUP_2_4)
 static void
 rb_audioscrobbler_submit_queue_cb (SoupSession *session, SoupMessage *msg, gpointer user_data)
-#else
-static void
-rb_audioscrobbler_submit_queue_cb (SoupMessage *msg, gpointer user_data)
-#endif
 {
 	RBAudioscrobbler *audioscrobbler = RB_AUDIOSCROBBLER (user_data);
 
@@ -1394,101 +1360,95 @@
 static gboolean
 rb_audioscrobbler_load_queue (RBAudioscrobbler *audioscrobbler)
 {
-	char *pathname, *uri;
-	GnomeVFSResult result;
+	char *pathname;
+	GFile *file;
+	GError *error = NULL;
 	char *data;
-	int size;
+	char *start;
+	char *end;
+	gsize size;
 
 	pathname = g_build_filename (rb_dot_dir (), "audioscrobbler.queue", NULL);
-	uri = g_filename_to_uri (pathname, NULL, NULL);
+	file = g_file_new_for_path (pathname);
+	rb_debug ("loading Audioscrobbler queue from \"%s\"", pathname);
 	g_free (pathname);
-	rb_debug ("Loading Audioscrobbler queue from \"%s\"", uri);
 
-	result = gnome_vfs_read_entire_file (uri, &size, &data);
-	g_free (uri);
+	if (g_file_load_contents (file, NULL, &data, &size, NULL, &error) == FALSE) {
+		rb_debug ("unable to load audioscrobbler queue: %s", error->message);
+		g_error_free (error);
+		return FALSE;
+	}
 
-	/* do stuff */
-	if (result == GNOME_VFS_OK) {
-		char *start = data, *end;
-
-		/* scan along the file's data, turning each line into a string */
-		while (start < (data + size)) {
-			AudioscrobblerEntry *entry;
-
-			/* find the end of the line, to terminate the string */
-			end = g_utf8_strchr (start, -1, '\n');
-			if (end == NULL)
-				break;
-			*end = 0;
-
-			entry = rb_audioscrobbler_entry_load_from_string (start);
-			if (entry) {
-				g_queue_push_tail (audioscrobbler->priv->queue,
-						   entry);
-				audioscrobbler->priv->queue_count++;
-			}
+	start = data;
+	while (start < (data + size)) {
+		AudioscrobblerEntry *entry;
 
-			start = end + 1;
+		/* find the end of the line, to terminate the string */
+		end = g_utf8_strchr (start, -1, '\n');
+		if (end == NULL)
+			break;
+		*end = 0;
+
+		entry = rb_audioscrobbler_entry_load_from_string (start);
+		if (entry) {
+			g_queue_push_tail (audioscrobbler->priv->queue,
+					   entry);
+			audioscrobbler->priv->queue_count++;
 		}
-	}
 
-	if (result != GNOME_VFS_OK) {
-		rb_debug ("Unable to load Audioscrobbler queue from disk: %s",
-			  gnome_vfs_result_to_string (result));
+		start = end + 1;
 	}
 
 	g_free (data);
-	return (result == GNOME_VFS_OK);
+	return TRUE;
 }
 
-
 static gboolean
 rb_audioscrobbler_save_queue (RBAudioscrobbler *audioscrobbler)
 {
 	char *pathname;
-	GnomeVFSHandle *handle = NULL;
-	GnomeVFSResult result;
+	GFile *file;
+	GError *error = NULL;
+	GList *l;
+	GString *str;
 
 	if (!audioscrobbler->priv->queue_changed) {
 		return TRUE;
 	}
 
+	str = g_string_new ("");
+	for (l = audioscrobbler->priv->queue->head; l != NULL; l = g_list_next (l)) {
+		AudioscrobblerEntry *entry;
+
+		entry = (AudioscrobblerEntry *) l->data;
+		rb_audioscrobbler_entry_save_to_string (str, entry);
+	}
+
 	pathname = g_build_filename (rb_dot_dir (), "audioscrobbler.queue", NULL);
 	rb_debug ("Saving Audioscrobbler queue to \"%s\"", pathname);
 
-	result = gnome_vfs_create (&handle, pathname, GNOME_VFS_OPEN_WRITE, FALSE, 0600);
+	file = g_file_new_for_path (pathname);
 	g_free (pathname);
 
-	if (result == GNOME_VFS_OK) {
-		GString *s = g_string_new (NULL);
-		GList *l;
-
-		for (l = audioscrobbler->priv->queue->head;
-		     l != NULL;
-		     l = g_list_next (l)) {
-			AudioscrobblerEntry *entry;
-			char *str;
-			entry = (AudioscrobblerEntry *) l->data;
-			str = rb_audioscrobbler_entry_save_to_string (entry);
-			result = gnome_vfs_write (handle, str, strlen (str), 
-						  NULL);
-			g_free (str);
-			if (result != GNOME_VFS_OK)
-				break;
-		}
-		g_string_free (s, TRUE);
-	}
+	g_file_replace_contents (file,
+				 str->str, str->len,
+				 NULL,
+				 FALSE,
+				 G_FILE_CREATE_NONE,
+				 NULL,
+				 NULL,
+				 &error);
+	g_string_free (str, TRUE);
 
-	if (result != GNOME_VFS_OK) {
-		rb_debug ("Unable to save Audioscrobbler queue to disk: %s",
-			  gnome_vfs_result_to_string (result));
-	} else {
+	if (error == NULL) {
 		audioscrobbler->priv->queue_changed = FALSE;
+		return TRUE;
+	} else {
+		rb_debug ("error saving audioscrobbler queue: %s",
+			  error->message);
+		g_error_free (error);
+		return FALSE;
 	}
-
-	if (handle)
-		gnome_vfs_close (handle);
-	return (result == GNOME_VFS_OK);
 }
 
 static void

Modified: trunk/plugins/audioscrobbler/rb-lastfm-source.c
==============================================================================
--- trunk/plugins/audioscrobbler/rb-lastfm-source.c	(original)
+++ trunk/plugins/audioscrobbler/rb-lastfm-source.c	Tue Jul 29 13:17:53 2008
@@ -44,6 +44,7 @@
 
 #include <string.h>
 #include <math.h>
+#include <unistd.h>
 
 #include <glib/gi18n.h>
 #include <glib/gstdio.h>
@@ -54,7 +55,6 @@
 
 #include <totem-pl-parser.h>
 
-#include "rb-soup-compat.h"
 #include <libsoup/soup.h>
 
 #include "md5.h"
@@ -140,6 +140,7 @@
 
 static void rb_lastfm_source_songs_view_sort_order_changed_cb (RBEntryView *view,
 							       RBLastfmSource *source);
+/* source-specific methods */
 
 static void rb_lastfm_source_drag_cb (GtkWidget *widget,
 				      GdkDragContext *dc,
@@ -1124,7 +1125,7 @@
 	}
 
 	g_strfreev (data);
-	unesc_title = gnome_vfs_unescape_string (title, NULL);
+	unesc_title = g_uri_unescape_string (title, G_URI_RESERVED_CHARS_ALLOWED_IN_PATH);
 	g_free (title);
 	return unesc_title;
 }
@@ -1256,33 +1257,14 @@
 	g_free (action);
 }
 
-#if defined(HAVE_LIBSOUP_2_4)
 static void
 http_response_cb (SoupSession *session, SoupMessage *req, gpointer user_data)
-#else
-static void
-http_response_cb (SoupMessage *req, gpointer user_data)
-#endif
 {
 	RBLastfmAction *action = (RBLastfmAction *)user_data;
 	RBLastfmSource *source = action->source;
 	char *free_body;
 	const char *body;
 
-#if defined(HAVE_LIBSOUP_2_2)
-
-	if ((req->response).body == NULL) {
-		body = NULL;
-		free_body = NULL;
-		rb_debug ("server failed to respond");
-	} else {
-		free_body = g_malloc0 ((req->response).length + 1);
-		memcpy (free_body, (req->response).body, (req->response).length);
-		g_strstrip (free_body);
-
-		body = free_body;
-	}
-#else
 	free_body = NULL;
 	if (req->response_body->length == 0) {
 		rb_debug ("server failed to respond");
@@ -1290,7 +1272,6 @@
 	} else {
 		body = req->response_body->data;
 	}
-#endif
 
 	/* call the action's response handler */
 	if (action->handle_response != NULL) {
@@ -1405,7 +1386,6 @@
 
 /* common protocol utility stuff */
 
-#if defined(HAVE_LIBSOUP_2_4)
 static char *
 auth_challenge (RBLastfmSource *source)
 {
@@ -1415,7 +1395,6 @@
 	 */
 	return g_strdup_printf ("%ld", time (NULL));
 }
-#endif
 
 static gchar *
 mkmd5 (char *string, char *string2)
@@ -1665,7 +1644,9 @@
 		return NULL;
 	}
 
-	lastfm_url = gnome_vfs_escape_string (rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_LOCATION));
+	lastfm_url = g_uri_escape_string (rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_LOCATION),
+					  G_URI_RESERVED_CHARS_ALLOWED_IN_PATH,
+					  FALSE);
 
 	url = g_strdup_printf("http://%s%s/adjust.php?session=%s&url=%s&debug=0";,
 			      source->priv->base_url ? source->priv->base_url : LASTFM_URL,
@@ -2056,24 +2037,6 @@
 
 /* XMLRPC requests */
 
-/* can't be bothered implementing this stuff for libsoup 2.2. */
-#if defined(HAVE_LIBSOUP_2_2)
-
-static SoupMessage *
-create_action_request (RBLastfmSource *source, RhythmDBEntry *entry, const char *action)
-{
-	g_warning ("xmlrpc stuff not implemented for libsoup 2.2");
-	return NULL;
-}
-
-static void
-handle_xmlrpc_response (RBLastfmSource *source, const char *body, RhythmDBEntry *entry)
-{
-	/* nothing */
-}
-
-#else
-
 static SoupMessage *
 create_action_request (RBLastfmSource *source, RhythmDBEntry *entry, const char *action)
 {
@@ -2142,7 +2105,6 @@
 
 	g_value_unset (&v);
 }
-#endif
 
 /* XMLRPC: banTrack */
 

Modified: trunk/plugins/cd-recorder/rb-cd-recorder-plugin.c
==============================================================================
--- trunk/plugins/cd-recorder/rb-cd-recorder-plugin.c	(original)
+++ trunk/plugins/cd-recorder/rb-cd-recorder-plugin.c	Tue Jul 29 13:17:53 2008
@@ -47,14 +47,7 @@
 #include "rb-recorder.h"
 #include "rb-playlist-source-recorder.h"
 
-#include <nautilus-burn-drive.h>
-#ifndef NAUTILUS_BURN_CHECK_VERSION
-#define NAUTILUS_BURN_CHECK_VERSION(a,b,c) FALSE
-#endif
-
-#if NAUTILUS_BURN_CHECK_VERSION(2,15,3)
 #include <nautilus-burn.h>
-#endif
 
 #define RB_TYPE_CD_RECORDER_PLUGIN		(rb_cd_recorder_plugin_get_type ())
 #define RB_CD_RECORDER_PLUGIN(o)		(G_TYPE_CHECK_INSTANCE_CAST ((o), RB_TYPE_CD_RECORDER_PLUGIN, RBCdRecorderPlugin))
@@ -115,9 +108,7 @@
 {
 	rb_debug ("RBCdRecorderPlugin initializing");
 
-#if NAUTILUS_BURN_CHECK_VERSION(2,15,3)
 	nautilus_burn_init ();
-#endif
 }
 
 static void
@@ -128,9 +119,7 @@
 */
 	rb_debug ("RBCdRecorderPlugin finalizing");
 
-#if NAUTILUS_BURN_CHECK_VERSION(2,15,3)
 	nautilus_burn_shutdown ();
-#endif
 
 	G_OBJECT_CLASS (rb_cd_recorder_plugin_parent_class)->finalize (object);
 }

Modified: trunk/plugins/cd-recorder/rb-playlist-source-recorder.c
==============================================================================
--- trunk/plugins/cd-recorder/rb-playlist-source-recorder.c	(original)
+++ trunk/plugins/cd-recorder/rb-playlist-source-recorder.c	Tue Jul 29 13:17:53 2008
@@ -41,19 +41,10 @@
 #include <glib/gprintf.h>
 #include <glib/gi18n.h>
 #include <gtk/gtk.h>
-#include <libgnomevfs/gnome-vfs-uri.h>
-#include <libgnomevfs/gnome-vfs-utils.h>
 #include <glade/glade.h>
-#include <nautilus-burn-drive.h>
-#include <nautilus-burn-drive-selection.h>
+#include <gio/gio.h>
 
-#ifndef NAUTILUS_BURN_CHECK_VERSION
-#define NAUTILUS_BURN_CHECK_VERSION(a,b,c) FALSE
-#endif
-
-#if NAUTILUS_BURN_CHECK_VERSION(2,15,3)
 #include <nautilus-burn.h>
-#endif
 
 #include "rb-file-helpers.h"
 #include "rb-glade-helpers.h"
@@ -73,18 +64,6 @@
 extern char *mkdtemp (char *template);
 #endif
 
-/* NAUTILUS_BURN_DRIVE_SIZE_TO_TIME was added in 2.12 */
-#ifndef NAUTILUS_BURN_DRIVE_SIZE_TO_TIME
-#define nautilus_burn_drive_eject _nautilus_burn_drive_eject
-#define nautilus_burn_drive_new_from_path _nautilus_burn_drive_new_from_path
-#define nautilus_burn_drive_media_type_get_string _nautilus_burn_drive_media_type_get_string
-#endif
-/* NAUTILUS_BURN_DRIVE_SIZE_TO_TIME was added in 2.14 */
-#ifndef HAVE_BURN_DRIVE_UNREF
-#define nautilus_burn_drive_unref nautilus_burn_drive_free
-#define nautilus_burn_drive_ref nautilus_burn_drive_copy
-#endif
-
 #include "rb-recorder.h"
 
 #define CONF_STATE_BURN_SPEED CONF_PREFIX "/state/burn_speed"
@@ -300,30 +279,6 @@
         return speed;
 }
 
-#ifndef HAVE_BURN_DRIVE_GET_WRITE_SPEEDS
-
-#define nautilus_burn_drive_get_write_speeds get_write_speeds
-
-static const int *
-get_write_speeds (NautilusBurnDrive *drive)
-{
-	int  max_speed;
-	int  i;
-        static int *write_speeds = NULL;
-
-	if (write_speeds == NULL) {
-		max_speed = drive->max_speed_write;
-		write_speeds = g_new0 (int, max_speed + 1);
-
-		for (i = 0; i < max_speed; i++) {
-			write_speeds [i] = max_speed - i;
-		}
-	}
-
-        return (const int*)write_speeds;
-}
-#endif
-
 static void
 update_speed_combobox (RBPlaylistSourceRecorder *source)
 {
@@ -361,11 +316,7 @@
 
                 for (i = 0; write_speeds [i] > 0; i++) {
 
-#ifdef NAUTILUS_BURN_DRIVE_CD_SPEED
                         name = g_strdup_printf ("%d \303\227", (int)NAUTILUS_BURN_DRIVE_CD_SPEED (write_speeds [i]));
-#else
-                        name = g_strdup_printf ("%d \303\227", write_speeds [i]);
-#endif
 
                         if (write_speeds [i] == default_speed) {
                                 default_speed_index = i + 1;
@@ -573,89 +524,6 @@
         gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (progress), fraction);
 }
 
-#ifndef NAUTILUS_BURN_DRIVE_SIZE_TO_TIME
-/* copied from nautilus-burn-drive 2.12 */
-static gboolean
-_nautilus_burn_drive_eject (NautilusBurnDrive *drive)
-{
-        char    *cmd;
-        gboolean res;
-
-        g_return_val_if_fail (drive != NULL, FALSE);
-
-        if (drive->device == NULL)
-                return FALSE;
-
-        cmd = g_strdup_printf ("eject %s", drive->device);
-        res = g_spawn_command_line_sync (cmd, NULL, NULL, NULL, NULL);
-        g_free (cmd);
-
-        /* delay a bit to make sure eject finishes */
-        sleep (2);
-
-        return res;
-}
-/* copied from nautilus-burn-drive 2.12 */
-static NautilusBurnDrive *
-_nautilus_burn_drive_new_from_path (const char *device)
-{
-        GList             *drives, *l;
-        NautilusBurnDrive *drive;
-
-        drives = nautilus_burn_drive_get_list (FALSE, FALSE);
-
-        drive = NULL;
-
-        for (l = drives; l != NULL; l = l->next) {
-                NautilusBurnDrive *d = l->data;
-                if (g_str_equal (device, d->device)) {
-                        drive = nautilus_burn_drive_ref (d);
-                }
-        }
-
-        g_list_foreach (drives, (GFunc)nautilus_burn_drive_unref, NULL);
-        g_list_free (drives);
-
-        return drive;
-}
-
-/* copied from nautilus-burn-drive 2.12 */
-static const char *
-_nautilus_burn_drive_media_type_get_string (NautilusBurnMediaType type)
-{
-        switch (type) {
-        case NAUTILUS_BURN_MEDIA_TYPE_BUSY:
-                return _("Could not determine media type because CD drive is busy");
-        case NAUTILUS_BURN_MEDIA_TYPE_ERROR:
-                return _("Couldn't open media");
-        case NAUTILUS_BURN_MEDIA_TYPE_UNKNOWN:
-                return _("Unknown Media");
-        case NAUTILUS_BURN_MEDIA_TYPE_CD:
-                return _("Commercial CD or Audio CD");
-        case NAUTILUS_BURN_MEDIA_TYPE_CDR:
-                return _("CD-R");
-        case NAUTILUS_BURN_MEDIA_TYPE_CDRW:
-                return _("CD-RW");
-        case NAUTILUS_BURN_MEDIA_TYPE_DVD:
-                return _("DVD");
-        case NAUTILUS_BURN_MEDIA_TYPE_DVDR:
-                return _("DVD-R, or DVD-RAM");
-        case NAUTILUS_BURN_MEDIA_TYPE_DVDRW:
-                return _("DVD-RW");
-        case NAUTILUS_BURN_MEDIA_TYPE_DVD_RAM:
-                return _("DVD-RAM");
-        case NAUTILUS_BURN_MEDIA_TYPE_DVD_PLUS_R:
-                return _("DVD+R");
-        case NAUTILUS_BURN_MEDIA_TYPE_DVD_PLUS_RW:
-                return _("DVD+RW");
-        default:
-                break;
-        }
-
-        return _("Broken media type");
-}
-#endif /* NAUTILUS_BURN_DRIVE_SIZE_TO_TIME */
-
 static int
 burn_cd (RBPlaylistSourceRecorder *source,
          GError                  **error)
@@ -1105,12 +973,8 @@
         char                 *msg;
         NautilusBurnDrive    *drive;
 
-#if NAUTILUS_BURN_CHECK_VERSION(2,15,3)
         drive = nautilus_burn_drive_monitor_get_drive_for_device (nautilus_burn_get_drive_monitor (),
                                                                   device);
-#else
-        drive = nautilus_burn_drive_new_from_path (device);
-#endif
 
         type = nautilus_burn_drive_get_media_type (drive);
 
@@ -1654,35 +1518,19 @@
 }
 
 static gboolean
-check_dir_has_space (const char *path,
-                     guint64     bytes_needed)
+try_tmp_dir (const char *dir, guint64 bytes_needed)
 {
-        GnomeVFSResult   result     = GNOME_VFS_OK;
-        GnomeVFSURI     *dir_uri    = NULL;
-        GnomeVFSFileSize free_bytes = 0;
-
-        if (!g_file_test (path, G_FILE_TEST_IS_DIR))
-                return FALSE;
+	GFile *file;
+	gboolean r;
 
-        dir_uri = gnome_vfs_uri_new (path);
-	if (dir_uri == NULL) {
-		g_warning (_("Cannot get free space at %s"), path);
+	if (dir == NULL) {
 		return FALSE;
 	}
 
-        result = gnome_vfs_get_volume_free_space (dir_uri, &free_bytes);
-
-        gnome_vfs_uri_unref (dir_uri);
-
-        if (result != GNOME_VFS_OK) {
-                g_warning (_("Cannot get free space at %s"), path);
-                return FALSE;
-        }
-
-        if (bytes_needed >= free_bytes)
-                return FALSE;
-
-        return TRUE;
+	file = g_file_new_for_path (dir);
+	r = rb_check_dir_has_space (file, bytes_needed);
+	g_object_unref (file);
+	return r;
 }
 
 static char *
@@ -1690,24 +1538,17 @@
               guint64                   bytes_needed,
               GError                  **error)
 {
-        char *path;
-
         g_return_val_if_fail (source != NULL, NULL);
         g_return_val_if_fail (RB_IS_PLAYLIST_SOURCE_RECORDER (source), NULL);
 
         /* Use a configurable temporary directory? */
-        path = NULL;
-        if (path && strcmp (path, "")
-            && check_dir_has_space (path, bytes_needed))
-                return path;
-        else if (g_get_tmp_dir () &&
-                   check_dir_has_space (g_get_tmp_dir (), bytes_needed))
-                return g_strdup (g_get_tmp_dir ());
-        else if (g_get_home_dir () &&
-                   check_dir_has_space (g_get_home_dir (), bytes_needed))
-                return g_strdup (g_get_home_dir ());
-        else
-                return NULL;
+	if (try_tmp_dir (g_get_tmp_dir (), bytes_needed)) {
+		return g_strdup (g_get_tmp_dir ());
+	} else if (try_tmp_dir (g_get_home_dir (), bytes_needed)) {
+		return g_strdup (g_get_home_dir ());
+	} else {
+		return NULL;
+	}
 }
 
 static gboolean

Modified: trunk/plugins/cd-recorder/rb-recorder-gst.c
==============================================================================
--- trunk/plugins/cd-recorder/rb-recorder-gst.c	(original)
+++ trunk/plugins/cd-recorder/rb-recorder-gst.c	Tue Jul 29 13:17:53 2008
@@ -41,36 +41,22 @@
 
 #include <glib/gi18n.h>
 #include <gdk/gdk.h>
-#include <libgnomevfs/gnome-vfs-utils.h>
 #include <gst/gst.h>
 
-#include <nautilus-burn-drive.h>
-#include <nautilus-burn-recorder.h>
-#ifndef NAUTILUS_BURN_CHECK_VERSION 	 
-#define NAUTILUS_BURN_CHECK_VERSION(a,b,c) FALSE 	 
-#endif
-
-#if NAUTILUS_BURN_CHECK_VERSION(2,15,3)
 #include <nautilus-burn.h>
-#endif
 
 #include "rb-recorder.h"
 
 #include "rb-debug.h"
 #include "rb-marshal.h"
 
-#ifndef HAVE_BURN_DRIVE_UNREF
-#define nautilus_burn_drive_unref nautilus_burn_drive_free
-#define nautilus_burn_drive_ref nautilus_burn_drive_copy
-#endif
-
 static void rb_recorder_class_init (RBRecorderClass *klass);
 static void rb_recorder_init       (RBRecorder      *recorder);
 static void rb_recorder_finalize   (GObject         *object);
 
 struct _RBRecorderPrivate {
         char       *src_uri;
-        char       *dest_file;
+        char       *dest_uri;
         char       *tmp_dir;
         
         GstElement *pipeline;
@@ -218,13 +204,9 @@
         NautilusBurnDrive *drive  = NULL;
         GList             *drives = NULL;
 
-#if NAUTILUS_BURN_CHECK_VERSION(2,15,3)
         NautilusBurnDriveMonitor *monitor;
         monitor = nautilus_burn_get_drive_monitor ();
         drives = nautilus_burn_drive_monitor_get_recorder_drives (monitor);
-#else
-        drives = nautilus_burn_drive_get_list (TRUE, FALSE);
-#endif
 
         if (drives) {
                 drive = nautilus_burn_drive_ref ((NautilusBurnDrive*) drives->data);
@@ -293,16 +275,16 @@
            const char *cdtext)
 {
         NautilusBurnRecorderTrack *track;
-        char                      *filename;
+        char                      *uri;
 
         g_return_val_if_fail (RB_IS_RECORDER (recorder), FALSE);
 
-        filename = g_strdup (recorder->priv->dest_file);
+        uri = g_strdup (recorder->priv->dest_uri);
 
         track = g_new0 (NautilusBurnRecorderTrack, 1);
 
         track->type = NAUTILUS_BURN_RECORDER_TRACK_TYPE_AUDIO;
-        track->contents.audio.filename = filename;
+        track->contents.audio.filename = uri;
         if (cdtext) {
                 track->contents.audio.cdtext = g_strdup (cdtext);
         }
@@ -405,7 +387,8 @@
 
 static void
 rb_recorder_construct (RBRecorder *recorder,
-                       const char *uri,
+                       const char *src_uri,
+		       const char *dest_file,
                        GError    **error)
 {
         char    *element_name = NULL;
@@ -446,8 +429,15 @@
         /* Construct elements */
 
         /* The source */
+	recorder->priv->src = gst_element_make_from_uri (GST_URI_SRC, src_uri, NULL);
+	if (!recorder->priv->src) {
+		goto missing_element;
+	}
 
-        MAKE_ELEMENT_OR_LOSE(gnomevfssrc, src);
+	if (g_object_class_find_property (G_OBJECT_GET_CLASS (recorder->priv->src),
+					  "iradio-mode")) {
+		g_object_set (recorder->priv->src, "iradio-mode", FALSE, NULL);
+	}
         gst_bin_add (GST_BIN (recorder->priv->pipeline), recorder->priv->src);
 
         /* The queue */
@@ -478,8 +468,10 @@
         gst_bin_add (GST_BIN (recorder->priv->pipeline), recorder->priv->encoder);
 
         /* Output sink */
-
-        MAKE_ELEMENT_OR_LOSE(gnomevfssink, sink);
+	recorder->priv->sink = gst_element_factory_make ("filesink", NULL);
+	if (!recorder->priv->sink) {
+		goto missing_element;
+	}
         gst_bin_add (GST_BIN (recorder->priv->pipeline), recorder->priv->sink);
 
         filtercaps = gst_caps_new_simple ("audio/x-raw-int",
@@ -604,7 +596,8 @@
                 return FALSE;
         }
 
-        if (!gst_element_query_position (recorder->priv->src, &format, &position) || !gst_element_query_duration (recorder->priv->src, &format, &total)) {
+        if (!gst_element_query_position (recorder->priv->src, &format, &position) ||
+	    !gst_element_query_duration (recorder->priv->src, &format, &total)) {
                 g_warning (_("Could not get current track position"));
                 return TRUE;
         }
@@ -693,8 +686,8 @@
         g_free (recorder->priv->src_uri);
         recorder->priv->src_uri = NULL;
 
-        g_free (recorder->priv->dest_file);
-        recorder->priv->dest_file = NULL;
+        g_free (recorder->priv->dest_uri);
+        recorder->priv->dest_uri = NULL;
 
         if (recorder->priv->pipeline == NULL) {
                 return;
@@ -723,7 +716,8 @@
                    const char *src_uri)
 {
         char *lock_filename;
-        char *filename;
+	char *wav_filename;
+	char *uri;
         int   fd;
 
         lock_filename = g_build_filename (tmp_dir, "rb-burn-tmp.XXXXXX", NULL);
@@ -733,10 +727,12 @@
         /* keep empty file around until finalize
            it will serve as a lock file to protect our new filename */
 
-        filename = g_strdup_printf ("%s.wav", lock_filename);
+	wav_filename = g_strconcat (lock_filename, ".wav", NULL);
+	uri = g_filename_to_uri (wav_filename, NULL, NULL);
         g_free (lock_filename);
+        g_free (wav_filename);
 
-        return filename;
+        return uri;
 }
 
 void
@@ -745,7 +741,7 @@
                   const char   *cdtext,
                   GError      **error)
 {
-        char    *dest_file;
+        char    *dest_uri;
         gboolean audiocd_mode = src_uri && g_str_has_prefix (src_uri, "audiocd://");
         
         g_return_if_fail (recorder != NULL);
@@ -759,28 +755,22 @@
                 recorder->priv->playing = FALSE;
                 return;
         }
+        
+	dest_uri = get_dest_from_uri (recorder->priv->tmp_dir, src_uri);
 
-        rb_recorder_construct (recorder, src_uri, error);
+        rb_recorder_construct (recorder, src_uri, dest_uri, error);
         if (error && *error) {
+		g_free (dest_uri);
                 return;
         }
                 
 	recorder->priv->got_audio_pad = FALSE;
 
-        g_object_set (G_OBJECT (recorder->priv->src), "iradio-mode", FALSE, NULL);
-        gst_element_set_state (recorder->priv->src, GST_STATE_NULL);
-        g_object_set (G_OBJECT (recorder->priv->src), "location", src_uri, NULL);
-
         g_free (recorder->priv->src_uri);
         recorder->priv->src_uri = g_strdup (src_uri);
 
-        dest_file = get_dest_from_uri (recorder->priv->tmp_dir, src_uri);
-        gst_element_set_state (recorder->priv->sink, GST_STATE_NULL);
-        g_object_set (G_OBJECT (recorder->priv->sink), "location", dest_file, NULL);
-        
-        g_free (recorder->priv->dest_file);
-        recorder->priv->dest_file = g_strdup (dest_file);
-        g_free (dest_file);
+        g_free (recorder->priv->dest_uri);
+        recorder->priv->dest_uri = dest_uri;
 
         recorder->priv->playing = FALSE;
 
@@ -832,16 +822,6 @@
         rb_recorder_sync_pipeline (recorder, NULL);
 }
 
-#if !NAUTILUS_BURN_CHECK_VERSION(2,15,3)
-static const char *
-nautilus_burn_drive_get_device (NautilusBurnDrive *drive)
-{
-	g_return_val_if_fail (drive != NULL, NULL);
-
-	return drive->device;
-}
-#endif
-
 char *
 rb_recorder_get_device (RBRecorder  *recorder,
                         GError     **error)
@@ -873,12 +853,7 @@
                         const char  *device,
                         GError     **error)
 {
-#if NAUTILUS_BURN_CHECK_VERSION(2,15,3)
         NautilusBurnDriveMonitor *monitor;
-#else
-        GList *drives;
-        GList *tmp;
-#endif
         int type;
 
         g_return_val_if_fail (recorder != NULL, FALSE);
@@ -896,29 +871,11 @@
 
         type = 0;
 
-#if NAUTILUS_BURN_CHECK_VERSION(2,15,3)
         monitor = nautilus_burn_get_drive_monitor ();
         recorder->priv->drive = nautilus_burn_drive_monitor_get_drive_for_device (monitor, device);
         if (recorder->priv->drive != NULL) {
                 type = nautilus_burn_drive_get_drive_type (recorder->priv->drive);
         }
-#else
-        drives = nautilus_burn_drive_get_list (TRUE, FALSE);
-
-        for (tmp = drives; tmp != NULL; tmp = tmp->next) {
-                NautilusBurnDrive *drive = (NautilusBurnDrive *) tmp->data;
-
-                if (strcmp (drive->device, device) == 0) {
-                        recorder->priv->drive = drive;
-                        break;
-                }
-
-                nautilus_burn_drive_unref (drive);
-        }
-        g_list_free (drives);
-
-        type = recorder->priv->drive->type;
-#endif
 
         if (! recorder->priv->drive) {
                 g_set_error (error,
@@ -973,8 +930,6 @@
                        action);
 }
 
-#ifdef NAUTILUS_BURN_DRIVE_SIZE_TO_TIME
-/* If nautilus-cd-burner >= 2.12 */
 static void
 rb_recorder_burn_progress_cb (NautilusBurnRecorder *cdrecorder,
                               gdouble               fraction,
@@ -989,23 +944,6 @@
                        fraction,
                        secs);
 }
-#else
-/* If nautilus-cd-burner == 2.10 */
-static void
-rb_recorder_burn_progress_cb (NautilusBurnRecorder *cdrecorder,
-                              gdouble               fraction,
-                              gpointer              data)
-{
-        RBRecorder *recorder = (RBRecorder*) data;
-        long        secs     = -1;
-
-        g_signal_emit (recorder,
-                       rb_recorder_signals [BURN_PROGRESS_CHANGED],
-                       0,
-                       fraction,
-                       secs);
-}
-#endif
 
 static gboolean
 rb_recorder_insert_cd_request_cb (NautilusBurnRecorder *cdrecorder,
@@ -1033,39 +971,20 @@
                                RBRecorder           *recorder)
 {
         int res = 0;
-        int ret = 0;
-        int retry_val;
-        int cancel_val;
-        int erase_val;
 
         g_signal_emit (G_OBJECT (recorder),
                        rb_recorder_signals [WARN_DATA_LOSS],
                        0, &res);
 
-#ifdef NAUTILUS_BURN_DRIVE_SIZE_TO_TIME
-        retry_val  = NAUTILUS_BURN_RECORDER_RESPONSE_RETRY;
-        cancel_val = NAUTILUS_BURN_RECORDER_RESPONSE_CANCEL;
-        erase_val  = NAUTILUS_BURN_RECORDER_RESPONSE_ERASE;
-#else
-        retry_val  = TRUE;
-        cancel_val = TRUE;
-        erase_val  = FALSE;
-#endif
-
         switch (res) {
         case RB_RECORDER_RESPONSE_RETRY:
-                ret = retry_val;
-                break;
+		return NAUTILUS_BURN_RECORDER_RESPONSE_RETRY;
         case RB_RECORDER_RESPONSE_ERASE:
-                ret = erase_val;
-                break;
+		return NAUTILUS_BURN_RECORDER_RESPONSE_ERASE;
         case RB_RECORDER_RESPONSE_CANCEL:
         default:
-                ret = cancel_val;
-                break;
+		return NAUTILUS_BURN_RECORDER_RESPONSE_CANCEL;
         }
-
-        return ret;
 }
 
 char *
@@ -1104,18 +1023,10 @@
                 return -1;
         }
 
-#if NAUTILUS_BURN_CHECK_VERSION(2,15,3)
         size = nautilus_burn_drive_get_media_capacity (recorder->priv->drive);
-#else
-        size = nautilus_burn_drive_get_media_size (recorder->priv->drive);
-#endif
 
         if (size > 0) {
-#ifdef NAUTILUS_BURN_DRIVE_SIZE_TO_TIME
                 secs = NAUTILUS_BURN_DRIVE_SIZE_TO_TIME (size);
-#else
-                secs = SIZE_TO_TIME (size);
-#endif
         } else {
                 secs = size;
         }
@@ -1326,22 +1237,12 @@
                 flags |= NAUTILUS_BURN_RECORDER_WRITE_DISC_AT_ONCE;
 
 	GDK_THREADS_LEAVE ();
-#ifdef NAUTILUS_BURN_DRIVE_SIZE_TO_TIME
-        /* If nautilus-cd-burner >= 2.12 */
         res = nautilus_burn_recorder_write_tracks (cdrecorder,
                                                    recorder->priv->drive,
                                                    recorder->priv->tracks,
                                                    speed,
                                                    flags,
                                                    &local_error);
-#else
-        /* If nautilus-cd-burner == 2.10 */
-        res = nautilus_burn_recorder_write_tracks (cdrecorder,
-                                                   recorder->priv->drive,
-                                                   recorder->priv->tracks,
-                                                   speed,
-                                                   flags);
-#endif
 	GDK_THREADS_ENTER ();
 
         if (res == NAUTILUS_BURN_RECORDER_RESULT_FINISHED) {

Modified: trunk/plugins/daap/Makefile.am
==============================================================================
--- trunk/plugins/daap/Makefile.am	(original)
+++ trunk/plugins/daap/Makefile.am	Tue Jul 29 13:17:53 2008
@@ -24,20 +24,9 @@
 	rb-daap-src.h				\
 	rb-daap-dialog.c			\
 	rb-daap-dialog.h			\
-	$(NULL)
-
-if USE_HOWL
-libdaap_la_SOURCES += \
-	rb-daap-mdns-publisher-howl.c		\
-	rb-daap-mdns-browser-howl.c		\
-	$(NULL)
-else
-libdaap_la_SOURCES += \
 	rb-daap-mdns-publisher-avahi.c		\
 	rb-daap-mdns-browser-avahi.c		\
 	$(NULL)
-endif
-
 
 libdaap_la_LDFLAGS = $(PLUGIN_LIBTOOL_FLAGS)
 libdaap_la_LIBADD = 					\

Modified: trunk/plugins/daap/rb-daap-connection.c
==============================================================================
--- trunk/plugins/daap/rb-daap-connection.c	(original)
+++ trunk/plugins/daap/rb-daap-connection.c	Tue Jul 29 13:17:53 2008
@@ -41,7 +41,6 @@
 #include <glib/gi18n.h>
 #include <gdk/gdk.h>
 
-#include "rb-soup-compat.h"
 #include <libsoup/soup.h>
 
 #include "rb-daap-hash.h"
@@ -357,11 +356,7 @@
 		char *token;
 
 		user_pass = g_strdup_printf ("%s:%s", priv->username, priv->password);
-#if defined(HAVE_LIBSOUP_2_4)
 		token = g_base64_encode ((guchar *)user_pass, strlen (user_pass));
-#else
-		token = soup_base64_encode (user_pass, strlen (user_pass));
-#endif
 		h = g_strdup_printf ("Basic %s", token);
 
 		g_free (token);
@@ -443,13 +438,8 @@
 	priv = data->connection->priv;
 	structure = NULL;
 	encoding_header = NULL;
-#if defined(HAVE_LIBSOUP_2_4)
 	response = data->message->response_body->data;
 	response_length = data->message->response_body->length;
-#else
-	response = data->message->response.body;
-	response_length = data->message->response.length;
-#endif
 
 	message_path = soup_uri_to_string (soup_message_get_uri (data->message), FALSE);
 
@@ -596,16 +586,10 @@
 	g_free (data);
 }
 
-#if defined(HAVE_LIBSOUP_2_4)
 static void
 http_response_handler (SoupSession      *session,
 		       SoupMessage      *message,
 		       RBDAAPConnection *connection)
-#else
-static void
-http_response_handler (SoupMessage      *message,
-		       RBDAAPConnection *connection)
-#endif
 {
 	DAAPResponseData *data;
 	int response_length;
@@ -617,11 +601,7 @@
 
 	data = g_new0 (DAAPResponseData, 1);
 	data->status = message->status_code;
-#if defined(HAVE_LIBSOUP_2_4)
 	response_length = message->response_body->length;
-#else
-	response_length = message->response.length;
-#endif
 
 	g_object_ref (G_OBJECT (connection));
 	data->connection = connection;
@@ -1696,11 +1676,7 @@
 		char *token;
 
 		user_pass = g_strdup_printf ("%s:%s", priv->username, priv->password);
-#if defined(HAVE_LIBSOUP_2_4)
 		token = g_base64_encode ((guchar *)user_pass, strlen (user_pass));
-#else
-		token = soup_base64_encode (user_pass, strlen (user_pass));
-#endif
 		g_string_append_printf (headers, "Authentication: Basic %s\r\n", token);
 		g_free (token);
 		g_free (user_pass);

Modified: trunk/plugins/daap/rb-daap-plugin.c
==============================================================================
--- trunk/plugins/daap/rb-daap-plugin.c	(original)
+++ trunk/plugins/daap/rb-daap-plugin.c	Tue Jul 29 13:17:53 2008
@@ -37,7 +37,6 @@
 #include <glib.h>
 #include <glib-object.h>
 
-#include "rb-soup-compat.h"
 #include <libsoup/soup.h>
 
 #include "rb-daap-plugin.h"
@@ -655,9 +654,7 @@
 	g_free (host);
 
 	soup_address_resolve_async (addr,
-#if defined(HAVE_LIBSOUP_2_4)
 				    NULL, NULL,
-#endif
 				    (SoupAddressCallback) new_daap_share_resolve_cb,
 				    data);
 }

Modified: trunk/plugins/daap/rb-daap-share.c
==============================================================================
--- trunk/plugins/daap/rb-daap-share.c	(original)
+++ trunk/plugins/daap/rb-daap-share.c	Tue Jul 29 13:17:53 2008
@@ -36,9 +36,11 @@
 #include <glib/gi18n.h>
 #include <gtk/gtk.h>
 
-#include "rb-soup-compat.h"
 #include <libsoup/soup.h>
-#include <libgnomevfs/gnome-vfs.h>
+#include <libsoup/soup-address.h>
+#include <libsoup/soup-message.h>
+#include <libsoup/soup-uri.h>
+#include <libsoup/soup-server.h>
 
 #include "rb-daap-share.h"
 #include "rb-daap-structure.h"
@@ -517,19 +519,6 @@
 static void
 message_add_standard_headers (SoupMessage *message)
 {
-#if defined(HAVE_LIBSOUP_2_2)
-	gchar *s;
-	time_t t;
-	struct tm *tm;
-
-	t = time (NULL);
-	tm = gmtime (&t);
-	s = g_new (gchar, 100);
-	strftime (s, 100, "%a, %d %b %Y %T GMT", tm);
-	soup_message_headers_append (message->response_headers, "Date", s);
-	g_free (s);
-#endif
-	
 	soup_message_headers_append (message->response_headers, "DAAP-Server", "Rhythmbox " VERSION);
 
 	soup_message_headers_append (message->response_headers, "Content-Type", "application/x-dmap-tagged");
@@ -551,10 +540,6 @@
 
 	soup_message_set_response (message, "application/x-dmap-tagged", SOUP_MEMORY_TAKE, resp, length);
 
-#if defined(HAVE_LIBSOUP_2_2)
-	soup_server_message_set_encoding (SOUP_SERVER_MESSAGE (message), SOUP_TRANSFER_CONTENT_LENGTH);
-#endif
-
 	message_add_standard_headers (message);
 
 	soup_message_set_status (message, SOUP_STATUS_OK);
@@ -566,7 +551,6 @@
 #define DAAP_VERSION 3.0
 #define DMAP_TIMEOUT 1800
 
-#if defined(HAVE_LIBSOUP_2_4)
 static void
 server_info_cb (SoupServer        *server,
 		SoupMessage       *message,
@@ -574,12 +558,6 @@
 		GHashTable        *query,
 		SoupClientContext *context,
 		RBDAAPShare       *share)
-#else
-static void
-server_info_cb (RBDAAPShare *share,
-		SoupServerContext *context,
-		SoupMessage *message)
-#endif
 {
 /* MSRV	server info response
  * 	MSTT status
@@ -636,7 +614,6 @@
 	rb_daap_structure_destroy (msrv);
 }
 
-#if defined(HAVE_LIBSOUP_2_4)
 static void
 content_codes_cb (SoupServer        *server,
 		  SoupMessage       *message,
@@ -644,12 +621,6 @@
 		  GHashTable        *query,
 		  SoupClientContext *context,
 		  RBDAAPShare       *share)
-#else
-static void
-content_codes_cb (RBDAAPShare *share,
-		  SoupServerContext *context,
-		  SoupMessage *message)
-#endif
 {
 /* MCCR content codes response
  * 	MSTT status
@@ -683,7 +654,6 @@
 	rb_daap_structure_destroy (mccr);
 }
 
-#if defined(HAVE_LIBSOUP_2_4)
 static gboolean
 get_session_id (GHashTable *query,
 		guint32    *id)
@@ -724,87 +694,11 @@
 	return TRUE;
 }
 
-#else
-static gboolean
-message_get_session_id (SoupMessage *message,
-			guint32     *id)
-{
-	const SoupUri *uri;
-	char          *position;
-	guint32        session_id;
-
-	if (id) {
-		*id = 0;
-	}
-
-	uri = soup_message_get_uri (message);
-	if (uri == NULL) {
-		return FALSE;
-	}
-
-	if (uri->query != NULL)
-		position = strstr (uri->query, "session-id=");
-	else
-		position = NULL;
-
-	if (position == NULL) {
-		rb_debug ("session id not found");
-		return FALSE;
-	}
-
-	position += 11;
-	session_id = (guint32) strtoul (position, NULL, 10);
-
-	if (id) {
-		*id = session_id;
-	}
-
-	return TRUE;
-}
-
-static gboolean
-message_get_revision_number (SoupMessage *message,
-			     guint       *number)
-{
-	const SoupUri *uri;
-	char          *position;
-	guint          revision_number;
-
-	if (number) {
-		*number = 0;
-	}
-
-	uri = soup_message_get_uri (message);
-	if (uri == NULL) {
-		return FALSE;
-	}
-
-	if (uri->query != NULL)
-		position = strstr (uri->query, "revision-number=");
-	else
-		position = NULL;
-
-	if (position == NULL) {
-		rb_debug ("client asked for an update without a revision number?!?\n");
-		return FALSE;
-	}
-
-	position += 16;
-	revision_number = atoi (position);
-
-	if (number) {
-		*number = revision_number;
-	}
-
-	return TRUE;
-}
-#endif
-
 static gboolean
 session_id_validate (RBDAAPShare       *share,
 		     SoupClientContext *context,
 		     SoupMessage       *message,
-		     GHashTable        *query,		/* NULL w/ libsoup 2.2 */
+		     GHashTable        *query,
 		     guint32           *id)
 {
 	guint32     session_id;
@@ -816,11 +710,7 @@
 		*id = 0;
 	}
 
-#if defined(HAVE_LIBSOUP_2_4)
 	res = get_session_id (query, &session_id);
-#else
-	res = message_get_session_id (message, &session_id);
-#endif
 	if (! res) {
 		rb_debug ("Validation failed: Unable to parse session id from message");
 		return FALSE;
@@ -891,7 +781,6 @@
 	g_hash_table_remove (share->priv->session_ids, GUINT_TO_POINTER (id));
 }
 
-#if defined(HAVE_LIBSOUP_2_4)
 static void
 login_cb (SoupServer        *server,
 	  SoupMessage       *message,
@@ -899,12 +788,6 @@
 	  GHashTable        *query,
 	  SoupClientContext *context,
 	  RBDAAPShare       *share)
-#else
-static void
-login_cb (RBDAAPShare       *share,
-	  SoupServerContext *context,
-	  SoupMessage       *message)
-#endif
 {
 /* MLOG login response
  * 	MSTT status
@@ -925,7 +808,6 @@
 	rb_daap_structure_destroy (mlog);
 }
 
-#if defined(HAVE_LIBSOUP_2_4)
 static void
 logout_cb (SoupServer        *server,
 	   SoupMessage       *message,
@@ -933,18 +815,9 @@
 	   GHashTable        *query,
 	   SoupClientContext *context,
 	   RBDAAPShare       *share)
-#else
-static void
-logout_cb (RBDAAPShare *share,
-	   SoupServerContext *context,
-	   SoupMessage *message)
-#endif
 {
 	int     status;
 	guint32 id;
-#if defined(HAVE_LIBSOUP_2_2)
-	GHashTable *query = NULL;
-#endif
 
 	if (session_id_validate (share, context, message, query, &id)) {
 		rb_debug ("Handling logout session id %u", id);
@@ -956,12 +829,8 @@
 	}
 
 	soup_message_set_status (message, status);
-#if defined(HAVE_LIBSOUP_2_2)
-	soup_server_message_set_encoding (SOUP_SERVER_MESSAGE (message), SOUP_TRANSFER_CONTENT_LENGTH);
-#endif
 }
 
-#if defined(HAVE_LIBSOUP_2_4)
 static void
 update_cb (SoupServer        *server,
 	   SoupMessage       *message,
@@ -969,21 +838,11 @@
 	   GHashTable        *query,
 	   SoupClientContext *context,
 	   RBDAAPShare       *share)
-#else
-static void
-update_cb (RBDAAPShare *share,
-	   SoupServerContext *context,
-	   SoupMessage *message)
-#endif
 {
 	guint    revision_number;
 	gboolean res;
 
-#if defined(HAVE_LIBSOUP_2_4)
 	res = get_revision_number (query, &revision_number);
-#else
-	res = message_get_revision_number (message, &revision_number);
-#endif
 
 	if (res && revision_number != share->priv->revision_number) {
 		/* MUPD update response
@@ -1003,11 +862,7 @@
 		 * message (and socket) without ever replying.
 		 */
 		g_object_ref (message);
-#if defined(HAVE_LIBSOUP_2_4)
 		soup_server_pause_message (server, message);
-#else
-		soup_message_io_pause (message);
-#endif
 	}
 }
 
@@ -1295,7 +1150,6 @@
 	return bits;
 }
 
-#if defined(HAVE_LIBSOUP_2_4)
 static bitwise
 parse_meta (GHashTable *query)
 {
@@ -1308,105 +1162,70 @@
 	return parse_meta_str (attrs);
 }
 
-#else
-static bitwise
-parse_meta (const gchar *s)
-{
-	bitwise bits;
-	gchar *start_of_attrs;
-	gchar *end_of_attrs;
-	gchar *attrs;
-
-	start_of_attrs = strstr (s, "meta=");
-	if (start_of_attrs == NULL) {
-		return 0;
-	}
-	start_of_attrs += 5;
-
-	end_of_attrs = strchr (start_of_attrs, '&');
-	if (end_of_attrs) {
-		attrs = g_strndup (start_of_attrs, end_of_attrs - start_of_attrs);
-	} else {
-		attrs = g_strdup (start_of_attrs);
-	}
-
-	bits = parse_meta_str (attrs);
-	g_free (attrs);
-
-	return bits;
-}
-#endif
-
 static void
-write_next_chunk (SoupMessage *message, GnomeVFSHandle *handle)
+write_next_chunk (SoupMessage *message, GInputStream *instream)
 {
-	GnomeVFSFileSize read_size;
-	GnomeVFSResult result;
+	gssize read_size;
+	GError *error = NULL;
 	gchar *chunk = g_malloc (DAAP_SHARE_CHUNK_SIZE);
 
-	result = gnome_vfs_read (handle, chunk, DAAP_SHARE_CHUNK_SIZE, &read_size);
-	if (result == GNOME_VFS_OK && read_size > 0) {
-#if defined(HAVE_LIBSOUP_2_4)
+	read_size = g_input_stream_read (instream, chunk, DAAP_SHARE_CHUNK_SIZE, NULL, &error);
+	if (read_size > 0) {
 		soup_message_body_append (message->response_body, SOUP_MEMORY_TAKE, chunk, read_size);
-#else
-		soup_message_add_chunk (message, SOUP_BUFFER_SYSTEM_OWNED, chunk, read_size);
-#endif
 	} else {
+		if (error != NULL) {
+			rb_debug ("error reading from input stream: %s", error->message);
+			g_error_free (error);
+		}
 		g_free (chunk);
-#if defined(HAVE_LIBSOUP_2_4)
 		soup_message_body_complete (message->response_body);
-#else
-		soup_message_add_final_chunk (message);
-#endif
 	}
 }
 
 static void
-chunked_message_finished (SoupMessage *message, GnomeVFSHandle *handle)
+chunked_message_finished (SoupMessage *message, GInputStream *instream)
 {
 	rb_debug ("finished sending chunked file");
-	gnome_vfs_close (handle);
+	g_input_stream_close (instream, NULL, NULL);
 }
 
 static void
 send_chunked_file (SoupMessage *message, RhythmDBEntry *entry, guint64 file_size, guint64 offset)
 {
-	GnomeVFSResult result;
-	GnomeVFSHandle *handle;
+	GFile *file;
+	GInputStream *stream;
 	const char *location;
+	GError *error = NULL;
 
 	location = rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_LOCATION);
 
 	rb_debug ("sending %s chunked from offset %" G_GUINT64_FORMAT, location, offset);
-	result = gnome_vfs_open (&handle, location, GNOME_VFS_OPEN_READ);
-	if (result != GNOME_VFS_OK) {
+	file = g_file_new_for_uri (location);
+	stream = G_INPUT_STREAM (g_file_read (file, NULL, &error));
+	if (error != NULL) {
+		rb_debug ("couldn't open %s: %s", location, error->message);
+		g_error_free (error);
 		soup_message_set_status (message, SOUP_STATUS_INTERNAL_SERVER_ERROR);
 		return;
 	}
 
 	if (offset != 0) {
-		result = gnome_vfs_seek (handle, GNOME_VFS_SEEK_START, offset);
-		if (result != GNOME_VFS_OK) {
-			g_warning ("Error seeking: %s", gnome_vfs_result_to_string (result));
-			gnome_vfs_close (handle);
+		if (g_seekable_seek (G_SEEKABLE (stream), offset, G_SEEK_SET, NULL, &error) == FALSE) {
+			g_warning ("error seeking: %s", error->message);
+			g_input_stream_close (stream, NULL, NULL);
 			soup_message_set_status (message, SOUP_STATUS_INTERNAL_SERVER_ERROR);
 			return;
 		}
 		file_size -= offset;
 	}
 
-#if defined(HAVE_LIBSOUP_2_4)
 	soup_message_headers_set_encoding (message->response_headers, SOUP_ENCODING_CHUNKED);
-#else
-	soup_server_message_set_encoding (SOUP_SERVER_MESSAGE (message), SOUP_TRANSFER_CHUNKED);
-#endif
 
-	g_signal_connect (message, "wrote_chunk", G_CALLBACK (write_next_chunk), handle);
-	g_signal_connect (message, "finished", G_CALLBACK (chunked_message_finished), handle);
-	write_next_chunk (message, handle);
+	g_signal_connect (message, "wrote_chunk", G_CALLBACK (write_next_chunk), stream);
+	g_signal_connect (message, "finished", G_CALLBACK (chunked_message_finished), stream);
+	write_next_chunk (message, stream);
 }
 
-#ifdef HAVE_G_MAPPED_FILE
 static void
 mapped_file_message_finished (SoupMessage *message, GMappedFile *file)
 {
@@ -1417,11 +1236,20 @@
 static void
 send_mapped_file (SoupMessage *message, RhythmDBEntry *entry, guint64 file_size, guint64 offset)
 {
+	GFile *file;
 	GMappedFile *mapped_file;
 	char *path;
 	GError *error = NULL;
 
-	path = gnome_vfs_get_local_path_from_uri (rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_LOCATION));
+	file = g_file_new_for_uri (rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_LOCATION));
+	path = g_file_get_path (file);
+	if (path == NULL) {
+		rb_debug ("couldn't send %s mmapped: couldn't get path", path);
+		soup_message_set_status (message, SOUP_STATUS_INTERNAL_SERVER_ERROR);
+		g_object_unref (file);
+		return;
+	}
+	g_object_unref (file);
 	rb_debug ("sending file %s mmapped, from offset %" G_GUINT64_FORMAT, path, offset);
 
 	mapped_file = g_mapped_file_new (path, FALSE, &error);
@@ -1433,10 +1261,6 @@
 					   SOUP_MEMORY_TEMPORARY,
 					   g_mapped_file_get_contents (mapped_file) + offset,
 					   file_size);
-#if defined(HAVE_LIBSOUP_2_2)
-		soup_server_message_set_encoding (SOUP_SERVER_MESSAGE (message),
-						  SOUP_TRANSFER_CONTENT_LENGTH);
-#endif
 
 		g_signal_connect (message,
 				  "finished",
@@ -1445,9 +1269,7 @@
 	}
 	g_free (path);
 }
-#endif
 
-#if defined(HAVE_LIBSOUP_2_4)
 static void
 databases_cb (SoupServer        *server,
 	      SoupMessage       *message,
@@ -1456,32 +1278,15 @@
 	      SoupClientContext *context,
 	      RBDAAPShare       *share)
 
-#else
-static void
-databases_cb (RBDAAPShare *share,
-	      SoupServerContext *context,
-	      SoupMessage *message)
-#endif
 {
 	const char *rest_of_path;
 	/*guint revision_number;*/
-#if defined(HAVE_LIBSOUP_2_2)
-	GHashTable *query = NULL;
-	gchar *path;
-#endif
 
 	if (! session_id_validate (share, context, message, query, NULL)) {
 		soup_message_set_status (message, SOUP_STATUS_FORBIDDEN);
-#if defined(HAVE_LIBSOUP_2_2)
-		soup_server_message_set_encoding (SOUP_SERVER_MESSAGE (message), SOUP_TRANSFER_CONTENT_LENGTH);
-#endif
 		return;
 	}
 
-#if defined(HAVE_LIBSOUP_2_2)
-	path = soup_uri_to_string (soup_message_get_uri (message), TRUE);
-#endif
-
 	rest_of_path = strchr (path + 1, '/');
 
 	if (rest_of_path == NULL) {
@@ -1517,11 +1322,7 @@
 
 		message_set_from_rb_daap_structure (message, avdb);
 		rb_daap_structure_destroy (avdb);
-#if defined(HAVE_LIBSOUP_2_4)
 	} else if (g_ascii_strcasecmp ("/1/items", rest_of_path) == 0) {
-#else
-	} else if (g_ascii_strncasecmp ("/1/items?", rest_of_path, 9) == 0) {
-#endif
 	/* ADBS database songs
 	 * 	MSTT status
 	 * 	MUTY update type
@@ -1537,11 +1338,7 @@
 		gint32 num_songs = rhythmdb_entry_count_by_type (share->priv->db, share->priv->entry_type);
 		struct MLCL_Bits mb = {NULL,0};
 
-#if defined(HAVE_LIBSOUP_2_4)
 		mb.bits = parse_meta (query);
-#else
-		mb.bits = parse_meta (rest_of_path);
-#endif
 
 		adbs = rb_daap_structure_add (NULL, RB_DAAP_CC_ADBS);
 		rb_daap_structure_add (adbs, RB_DAAP_CC_MSTT, (gint32) DMAP_STATUS_OK);
@@ -1555,11 +1352,7 @@
 		message_set_from_rb_daap_structure (message, adbs);
 		rb_daap_structure_destroy (adbs);
 		adbs = NULL;
-#if defined(HAVE_LIBSOUP_2_4)
 	} else if (g_ascii_strcasecmp ("/1/containers", rest_of_path) == 0) {
-#else
-	} else if (g_ascii_strncasecmp ("/1/containers?", rest_of_path, 14) == 0) {
-#endif
 	/* APLY database playlists
 	 * 	MSTT status
 	 * 	MUTY update type
@@ -1615,11 +1408,7 @@
 		struct MLCL_Bits mb = {NULL,0};
 		gint pl_id = atoi (rest_of_path + 14);
 
-#if defined(HAVE_LIBSOUP_2_4)
 		mb.bits = parse_meta (query);
-#else
-		mb.bits = parse_meta (rest_of_path);
-#endif
 
 		apso = rb_daap_structure_add (NULL, RB_DAAP_CC_APSO);
 		rb_daap_structure_add (apso, RB_DAAP_CC_MSTT, (gint32) DMAP_STATUS_OK);
@@ -1646,12 +1435,7 @@
 						  _find_by_id);
 			if (idl == NULL) {
 				soup_message_set_status (message, SOUP_STATUS_NOT_FOUND);
-#if defined(HAVE_LIBSOUP_2_2)
-				soup_server_message_set_encoding (SOUP_SERVER_MESSAGE (message),
-								  SOUP_TRANSFER_CONTENT_LENGTH);
-				soup_message_set_response (message, "text/plain", SOUP_BUFFER_USER_OWNED, "", 0);
-#endif
-				goto out;
+				return;
 			}
 			id = (RBPlaylistID *)idl->data;
 
@@ -1707,27 +1491,17 @@
 			soup_message_set_status (message, SOUP_STATUS_OK);
 		}
 
-#ifdef HAVE_G_MAPPED_FILE
 		/* don't use chunked transfers if we can send the file mmapped,
 		 * as itunes clients can't seek properly when we do.
 		 */
 		if (rb_uri_is_local (location)) {
 			send_mapped_file (message, entry, file_size, offset);
-		} else 
-#endif
-		{
+		} else {
 			send_chunked_file (message, entry, file_size, offset);
 		}
 	} else {
 		rb_debug ("unhandled: %s\n", path);
 	}
-
-out:
-#if defined(HAVE_LIBSOUP_2_2)
-	g_free (path);
-#else
-	;
-#endif
 }
 
 static void
@@ -1766,8 +1540,6 @@
 	}
 }
 
-#if defined(HAVE_LIBSOUP_2_4)
-
 static gboolean
 soup_auth_filter (SoupAuthDomain *auth_domain,
 		  SoupMessage    *msg,
@@ -1808,91 +1580,6 @@
 	return allowed;
 }
 
-#else
-typedef void (* DAAPPathFunction) (RBDAAPShare       *share,
-				   SoupServerContext *context,
-				   SoupMessage       *message);
-
-struct DAAPPath {
-	const gchar *path;
-	guint path_length;
-	DAAPPathFunction function;
-};
-
-static const struct DAAPPath paths_to_functions[] = {
-	{"/server-info", 12, server_info_cb},
-	{"/content-codes", 14, content_codes_cb},
-	{"/login", 6, login_cb},
-	{"/logout", 7, logout_cb},
-	{"/update", 7, update_cb},
-	{"/databases", 10, databases_cb}
-};
-
-static void
-server_cb (SoupServerContext *context,
-	   SoupMessage *message,
-	   RBDAAPShare *share)
-{
-	gchar *path;
-	guint i;
-
-	path = soup_uri_to_string (soup_message_get_uri (message), TRUE);
-	rb_debug ("request for %s", path);
-
-	for (i = 0; i < G_N_ELEMENTS (paths_to_functions); i++) {
-		if (g_ascii_strncasecmp (paths_to_functions[i].path, path, paths_to_functions[i].path_length) == 0) {
-			paths_to_functions[i].function (share, context, message);
-			return;
-		}
-	}
-
-	g_warning ("unhandled path %s\n", path);
-
-	g_free (path);
-}
-
-static gboolean
-soup_auth_callback (SoupServerAuthContext *auth_ctx,
-                    SoupServerAuth        *auth,
-                    SoupMessage           *message,
-                    RBDAAPShare           *share)
-{
-	const char *username;
-	gboolean    allowed;
-	char       *path;
-
-	path = soup_uri_to_string (soup_message_get_uri (message), TRUE);
-	rb_debug ("Auth request for %s", path);
-
-	if (auth == NULL) {
-
-		/* This is to workaround libsoup looking up handlers by directory.
-		   We require auth for "/databases?" but not "/databases/" */
-		if (g_str_has_prefix (path, "/databases/")) {
-			allowed = TRUE;
-			goto done;
-		}
-
-		rb_debug ("Auth DENIED: information not provided");
-		allowed = FALSE;
-		goto done;
-	}
-
-	username = soup_server_auth_get_user (auth);
-	rb_debug ("Auth request for user: %s", username);
-
-	allowed = soup_server_auth_check_passwd (auth, share->priv->password);
-	rb_debug ("Auth request: %s", allowed ? "ALLOWED" : "DENIED");
-
- done:
-	g_free (path);
-
-	return allowed;
-}
-
-#endif
-
-
 static gboolean
 rb_daap_share_server_start (RBDAAPShare *share)
 {
@@ -1916,7 +1603,6 @@
 	password_required = (share->priv->auth_method != RB_DAAP_SHARE_AUTH_METHOD_NONE);
 
 	if (password_required) {
-#if defined(HAVE_LIBSOUP_2_4)
 		SoupAuthDomain *auth_domain;
 
 		auth_domain = soup_auth_domain_basic_new (SOUP_AUTH_DOMAIN_REALM, "Music Sharing",
@@ -1930,35 +1616,8 @@
 							  g_object_ref (share),
 							  g_object_unref);
 		soup_server_add_auth_domain (share->priv->server, auth_domain);
-#else
-		SoupServerAuthContext auth_ctx = { 0 };
-		auth_ctx.types = SOUP_AUTH_TYPE_BASIC;
-		auth_ctx.callback = (SoupServerAuthCallbackFn)soup_auth_callback;
-		auth_ctx.user_data = share;
-		auth_ctx.basic_info.realm = "Music Sharing";
-
-		soup_server_add_handler (share->priv->server,
-					 "/login",
-					 &auth_ctx,
-					 (SoupServerCallbackFn)server_cb,
-					 NULL,
-					 share);
-		soup_server_add_handler (share->priv->server,
-					 "/update",
-					 &auth_ctx,
-					 (SoupServerCallbackFn)server_cb,
-					 NULL,
-					 share);
-		soup_server_add_handler (share->priv->server,
-					 "/databases",
-					 &auth_ctx,
-					 (SoupServerCallbackFn)server_cb,
-					 NULL,
-					 share);
-#endif
 	}
 
-#if defined(HAVE_LIBSOUP_2_4)
 	soup_server_add_handler (share->priv->server, "/server-info",
 				 (SoupServerCallback) server_info_cb,
 				 share, NULL);
@@ -1977,14 +1636,6 @@
 	soup_server_add_handler (share->priv->server, "/databases",
 				 (SoupServerCallback) databases_cb,
 				 share, NULL);
-#else
-	soup_server_add_handler (share->priv->server,
-				 NULL,
-				 NULL,
-				 (SoupServerCallbackFn)server_cb,
-				 NULL,
-				 share);
-#endif
 	soup_server_run_async (share->priv->server);
 
 	/* using direct since there is no g_uint_hash or g_uint_equal */

Modified: trunk/plugins/daap/rb-daap-src.c
==============================================================================
--- trunk/plugins/daap/rb-daap-src.c	(original)
+++ trunk/plugins/daap/rb-daap-src.c	Tue Jul 29 13:17:53 2008
@@ -42,7 +42,6 @@
 #include <unistd.h>
 #include <ctype.h>
 
-#include "rb-soup-compat.h"
 #include <libsoup/soup.h>
 
 #include <glib/gi18n.h>
@@ -440,12 +439,7 @@
 	gchar *host;
 	guint port;
 	gchar *path;
-#if defined(HAVE_LIBSOUP_2_4)
 	SoupMessageHeaders *header_table;
-#else
-	GHashTable *header_table;
-	char *dup_headers;
-#endif
 	gchar *request;
 	gchar *response;
 	gchar *end_headers;
@@ -548,7 +542,6 @@
 		return FALSE;
 	}
 
-#if defined(HAVE_LIBSOUP_2_4)
 	header_table = soup_message_headers_new (SOUP_MESSAGE_HEADERS_RESPONSE);
 	parse_result = soup_headers_parse_response (response,
 						    ((end_headers+2) - response),
@@ -556,58 +549,13 @@
 						    NULL,
 						    &http_status,
 						    &http_status_phrase);
-#else
-	/* for compatibility with older versions of libsoup, we may need to retry
-	 * the soup_headers_parse_response call with slightly different arguments.
-	 * since this function modifies the string passed in, we need to copy it
-	 * before the first call.
-	 *
-	 * > 2.2.99 wants the full response header, including the trailing blank line,
-	 * with the length passed in up to the start of the start of the trailing
-	 * blank line.
-	 */
-	dup_headers = g_strndup (response, (end_headers + 4) - response);
-
-	header_table = g_hash_table_new (soup_str_case_hash, soup_str_case_equal);
-	parse_result = soup_headers_parse_response (dup_headers,
-						    ((end_headers+2) - response),
-						    header_table,
-						    NULL,
-						    &http_status,
-						    &http_status_phrase);
-	g_free (dup_headers);
-	if (parse_result == FALSE) {
-		/*
-		 * < 2.2.98 wants the headers terminated before the trailing blank line.
-		 */
-		end_headers[2] = '\0';
-		parse_result = soup_headers_parse_response (response,
-							    (end_headers+2 - response),
-							    header_table,
-							    NULL,
-							    &http_status,
-							    &http_status_phrase);
-	}
-#endif
 
 	if (parse_result) {
 		if (http_status == 200 || http_status == 206) {
 			const char *enc_str = NULL;
 			const char *len_str = NULL;
-#if defined(HAVE_LIBSOUP_2_4)
 			enc_str = soup_message_headers_get (header_table, "Transfer-Encoding");
 			len_str = soup_message_headers_get (header_table, "Content-Length");
-#else
-			GSList *val;
-			val = g_hash_table_lookup (header_table, "Transfer-Encoding");
-			if (val) {
-				enc_str = ((const char *)val->data);
-			}
-			val = g_hash_table_lookup (header_table, "Content-Length");
-			if (val) {
-				len_str = ((const char *)val->data);
-			}
-#endif
 
 			if (enc_str) {
 				if (g_strcasecmp (enc_str, "chunked") == 0) {
@@ -645,12 +593,7 @@
 	}
 	g_free (http_status_phrase);
 
-#if defined(HAVE_LIBSOUP_2_4)
 	soup_message_headers_free (header_table);
-#else
-	soup_message_clear_headers (header_table);
-	g_hash_table_destroy (header_table);
-#endif
 
 	end_headers += 4;
 

Modified: trunk/plugins/generic-player/rb-generic-player-playlist-source.c
==============================================================================
--- trunk/plugins/generic-player/rb-generic-player-playlist-source.c	(original)
+++ trunk/plugins/generic-player/rb-generic-player-playlist-source.c	Tue Jul 29 13:17:53 2008
@@ -41,7 +41,7 @@
 
 typedef struct
 {
-	char *playlist_path;
+	char *playlist_path;		/* hmm, replace with GFile? */
 	char *device_root;
 	gint save_playlist_id;
 	RBGenericPlayerSource *player_source;
@@ -138,7 +138,8 @@
 		char *mount_uri;
 		char *filename;
 		const char *ext;
-		GnomeVFSURI *uri, *nuri;
+		GFile *dir;
+		GFile *playlist;
 
 		ext = playlist_format_extension (playlist_type);
 
@@ -152,21 +153,22 @@
 		playlist_dir = rb_generic_player_source_get_playlist_path (priv->player_source);
 		mount_uri = rb_generic_player_source_get_mount_path (priv->player_source);
 
-		uri = gnome_vfs_uri_new (mount_uri);
+		dir = g_file_new_for_uri (mount_uri);
 		if (playlist_dir != NULL) {
-			nuri = gnome_vfs_uri_append_path (uri, playlist_dir);
-			gnome_vfs_uri_unref (uri);
-			uri = nuri;
+			GFile *pdir;
+
+			pdir = g_file_resolve_relative_path (dir, playlist_dir);
+			g_object_unref (dir);
+			dir = pdir;
 		}
 
-		nuri = gnome_vfs_uri_append_path (uri, filename);
-		gnome_vfs_uri_unref (uri);
+		playlist = g_file_resolve_relative_path (dir, filename);
+		priv->playlist_path = g_file_get_path (playlist);
 		
 		g_free (mount_uri);
 		g_free (playlist_dir);
 
-		priv->playlist_path = gnome_vfs_uri_to_string (nuri, GNOME_VFS_URI_HIDE_NONE);
-		gnome_vfs_uri_unref (nuri);
+		g_object_unref (dir);
 	}
 
 	temp_uri = g_strdup_printf ("%s%06X", priv->playlist_path, g_random_int_range (0, 0xFFFFFF));
@@ -186,14 +188,19 @@
 		/* XXX report this more usefully */
 		g_warning ("Playlist save failed: %s", error->message);
 	} else {
-		/* rename the new file over the old one */
-		GnomeVFSResult result;
+		GFile *dest;
+		GFile *src;
 
-		result = gnome_vfs_move (temp_uri, priv->playlist_path, TRUE);
-		if (result != GNOME_VFS_OK) {
+		dest = g_file_new_for_path (priv->playlist_path);
+		src = g_file_new_for_path (temp_uri);
+		g_file_move (src, dest, G_FILE_COPY_OVERWRITE | G_FILE_COPY_NO_FALLBACK_FOR_MOVE, NULL, NULL, NULL, &error);
+		if (error != NULL) {
 			/* XXX report this more usefully */
-			g_warning ("Replacing playlist failed: %s", gnome_vfs_result_to_string (result));
+			g_warning ("Replacing playlist failed: %s", error->message);
 		}
+
+		g_object_unref (dest);
+		g_object_unref (src);
 	}
 
 	g_clear_error (&error);
@@ -249,7 +256,9 @@
 	RBGenericPlayerPlaylistSourcePrivate *priv = GET_PRIVATE (source);
 	TotemPlParser *parser;
 	gboolean result;
-	char *path;
+	GFile *file;
+	char *name;
+	char *uri;
 
 	if (priv->playlist_path == NULL) {
 		/* this happens when we're creating a new playlist */
@@ -259,16 +268,12 @@
 	}
 
 	priv->loading = TRUE;
+	file = g_file_new_for_path (priv->playlist_path);
 
 	/* make a default name for the playlist based on the filename */
-	path = g_filename_from_uri (priv->playlist_path, NULL, NULL);
-	if (path != NULL) {
-		char *name = g_path_get_basename (path);
-
-		g_object_set (source, "name", name, NULL);
-		g_free (name);
-		g_free (path);
-	}
+	name = g_file_get_basename (file);
+	g_object_set (source, "name", name, NULL);
+	g_free (name);
 
 	parser = totem_pl_parser_new ();
 	if (rb_debug_matches ("totem_pl_parser_parse", "totem-pl-parser.c")) {
@@ -284,7 +289,8 @@
 			  source);
 	g_object_set (G_OBJECT (parser), "recurse", FALSE, NULL);
 
-	switch (totem_pl_parser_parse_with_base (parser, priv->playlist_path, priv->device_root, FALSE)) {
+	uri = g_file_get_uri (file);
+	switch (totem_pl_parser_parse_with_base (parser, uri, priv->device_root, FALSE)) {
 	case TOTEM_PL_PARSER_RESULT_SUCCESS:
 		rb_debug ("playlist parsed successfully");
 		result = TRUE;
@@ -307,6 +313,8 @@
 	default:
 		g_assert_not_reached ();
 	}
+	g_free (uri);
+	g_object_unref (file);
 
 	priv->loading = FALSE;
 	return result;
@@ -354,12 +362,16 @@
 	RBGenericPlayerPlaylistSourcePrivate *priv = GET_PRIVATE (source);
 
 	if (priv->playlist_path != NULL) {
-		GnomeVFSResult result;
-		result = gnome_vfs_unlink (priv->playlist_path);
+		GError *error = NULL;
+		GFile *playlist;
 
-		if (result != GNOME_VFS_OK) {
-			/* now what? */
+		playlist = g_file_new_for_uri (priv->playlist_path);
+		g_file_delete (playlist, NULL, &error);
+		if (error != NULL) {
+			g_warning ("Deleting playlist failed: %s", error->message);
+			g_clear_error (&error);
 		}
+		g_object_unref (playlist);
 	} else {
 		rb_debug ("playlist was never saved: nothing to delete");
 	}

Modified: trunk/plugins/generic-player/rb-generic-player-plugin.c
==============================================================================
--- trunk/plugins/generic-player/rb-generic-player-plugin.c	(original)
+++ trunk/plugins/generic-player/rb-generic-player-plugin.c	Tue Jul 29 13:17:53 2008
@@ -196,18 +196,18 @@
 }
 
 static RBSource *
-create_source_cb (RBRemovableMediaManager *rmm, GnomeVFSVolume *volume, RBGenericPlayerPlugin *plugin)
+create_source_cb (RBRemovableMediaManager *rmm, GMount *mount, RBGenericPlayerPlugin *plugin)
 {
 	RBSource *source = NULL;
 
-	if (rb_psp_is_volume_player (volume))
-		source = RB_SOURCE (rb_psp_source_new (plugin->shell, volume));
+	if (rb_psp_is_mount_player (mount))
+		source = RB_SOURCE (rb_psp_source_new (plugin->shell, mount));
 #ifdef HAVE_HAL
-	if (source == NULL && rb_nokia770_is_volume_player (volume))
-		source = RB_SOURCE (rb_nokia770_source_new (plugin->shell, volume));
+	if (source == NULL && rb_nokia770_is_mount_player (mount))
+		source = RB_SOURCE (rb_nokia770_source_new (plugin->shell, mount));
 #endif
-	if (source == NULL && rb_generic_player_is_volume_player (volume))
-		source = RB_SOURCE (rb_generic_player_source_new (plugin->shell, volume));
+	if (source == NULL && rb_generic_player_is_mount_player (mount))
+		source = RB_SOURCE (rb_generic_player_source_new (plugin->shell, mount));
 
 	if (plugin->actions == NULL) {
 		plugin->actions = gtk_action_group_new ("GenericPlayerActions");
@@ -263,7 +263,7 @@
 	 * plugins for more specific device types can get in first.
 	 */
 	g_signal_connect_after (G_OBJECT (rmm),
-				"create-source", G_CALLBACK (create_source_cb),
+				"create-source-mount", G_CALLBACK (create_source_cb),
 				pi);
 
 	/* only scan if we're being loaded after the initial scan has been done */

Modified: trunk/plugins/generic-player/rb-generic-player-source.c
==============================================================================
--- trunk/plugins/generic-player/rb-generic-player-source.c	(original)
+++ trunk/plugins/generic-player/rb-generic-player-source.c	Tue Jul 29 13:17:53 2008
@@ -41,8 +41,6 @@
 #include <libhal.h>
 #include <dbus/dbus.h>
 #endif
-#include <libgnomevfs/gnome-vfs-volume.h>
-#include <libgnomevfs/gnome-vfs-volume-monitor.h>
 #include <totem-pl-parser.h>
 
 #include "eel-gconf-extensions.h"
@@ -87,7 +85,7 @@
 				  const char *mimetype,
 				  const char *extension);
 
-static gchar *default_get_mount_path (RBGenericPlayerSource *source);
+static char *default_get_mount_path (RBGenericPlayerSource *source);
 static void default_load_playlists (RBGenericPlayerSource *source);
 static char * default_uri_from_playlist_uri (RBGenericPlayerSource *source,
 					     const char *uri);
@@ -97,7 +95,7 @@
 #if HAVE_HAL
 static LibHalContext *get_hal_context (void);
 static void cleanup_hal_context (LibHalContext *ctx);
-static char * get_hal_udi_for_player (LibHalContext *ctx, GnomeVFSVolume *volume);
+static char * get_hal_udi_for_player (LibHalContext *ctx, GMount *mount);
 static void free_dbus_error (const char *what, DBusError *error);
 #endif
 
@@ -123,7 +121,7 @@
 	RhythmDBEntryType ignore_type;
 	RhythmDBEntryType error_type;
 
-	/* information derived from gnome-vfs volume */
+	/* information derived from volume */
 	gboolean read_only;
 	gboolean handles_trash;
 
@@ -200,8 +198,12 @@
 {
 	RBGenericPlayerSource *source;
 	RBGenericPlayerSourcePrivate *priv;
-	GnomeVFSVolume *volume;
+	GMount *mount;
+	char *mount_name;
 	RBShell *shell;
+	GFile *root;
+	GFileInfo *info;
+	GError *error = NULL;
 
 	source = RB_GENERIC_PLAYER_SOURCE (G_OBJECT_CLASS (rb_generic_player_source_parent_class)->
 					   constructor (type, n_construct_properties, construct_properties));
@@ -216,10 +218,34 @@
 
 	g_object_unref (shell);
 
-	g_object_get (source, "volume", &volume, NULL);
-	priv->handles_trash = gnome_vfs_volume_handles_trash (volume);
-	priv->read_only = gnome_vfs_volume_is_read_only (volume);
-	g_object_unref (volume);
+	g_object_get (source, "mount", &mount, NULL);
+
+	root = g_mount_get_root (mount);
+	mount_name = g_mount_get_name (mount);
+
+	info = g_file_query_filesystem_info (root, G_FILE_ATTRIBUTE_FILESYSTEM_READONLY, NULL, &error);
+	if (error != NULL) {
+		rb_debug ("error querying filesystem info for %s: %s", mount_name, error->message);
+		g_error_free (error);
+		priv->read_only = FALSE;
+	} else {
+		priv->read_only = g_file_info_get_attribute_boolean (info, G_FILE_ATTRIBUTE_FILESYSTEM_READONLY);
+		g_object_unref (info);
+	}
+
+	info = g_file_query_info (root, G_FILE_ATTRIBUTE_ACCESS_CAN_TRASH, G_FILE_QUERY_INFO_NONE, NULL, &error);
+	if (error != NULL) {
+		rb_debug ("error querying file info for %s: %s", mount_name, error->message);
+		g_error_free (error);
+		priv->handles_trash = FALSE;		/* hmm */
+	} else {
+		priv->handles_trash = g_file_info_get_attribute_boolean (info, G_FILE_ATTRIBUTE_ACCESS_CAN_TRASH);
+		g_object_unref (info);
+	}
+
+	g_free (mount_name);
+	g_object_unref (root);
+	g_object_unref (mount);
 
 	priv->folder_depth = -1;	/* 0 is a possible value, I guess */
 	priv->playlist_format_unknown = TRUE;
@@ -267,19 +293,22 @@
 	}
 }
 
-static char *
-get_is_audio_player_path (GnomeVFSVolume *volume)
+static GFile *
+get_is_audio_player_file (GMount *mount)
 {
-	char *path = gnome_vfs_volume_get_activation_uri (volume);
-	char *file = g_build_filename (path, ".is_audio_player", NULL);
-	g_free (path);
+	GFile *root;
+	GFile *is_audio_player;
 
-	if (rb_uri_is_local (file) && rb_uri_exists (file)) {
-		return file;
+	root = g_mount_get_root (mount);
+	is_audio_player = g_file_resolve_relative_path (root, ".is_audio_player");
+
+	if (g_file_query_exists (is_audio_player, NULL) == FALSE) {
+		g_object_unref (is_audio_player);
+		is_audio_player = NULL;
 	}
 
-	g_free (file);
-	return NULL;
+	g_object_unref (root);
+	return is_audio_player;
 }
 
 static void
@@ -344,15 +373,18 @@
 }
 
 static void
-debug_device_info (RBGenericPlayerSource *source, GnomeVFSVolume *volume, const char *what)
+debug_device_info (RBGenericPlayerSource *source, GMount *mount, const char *what)
 {
 	char *dbg;
 	char *path;
 	RBGenericPlayerSourcePrivate *priv = GENERIC_PLAYER_SOURCE_GET_PRIVATE (source);
+	GVolume *volume;
 
-	path = gnome_vfs_volume_get_activation_uri (volume);
+	volume = g_mount_get_volume (mount);
+	path = g_volume_get_identifier (volume, G_VOLUME_IDENTIFIER_KIND_UNIX_DEVICE);
 	rb_debug ("device information for %s from %s", path, what);
 	g_free (path);
+	g_object_unref (volume);
 
 	if (priv->audio_folders != NULL) {
 		dbg = g_strjoinv (", ", priv->audio_folders);
@@ -398,19 +430,20 @@
 get_device_info (RBGenericPlayerSource *source)
 {
 	RBGenericPlayerSourcePrivate *priv = GENERIC_PLAYER_SOURCE_GET_PRIVATE (source);
-	GnomeVFSVolume *volume;
-	char *is_audio_player;
+	GMount *mount;
+	GFile *is_audio_player;
+	GError *error = NULL;
 #ifdef HAVE_HAL
 	LibHalContext *ctx;
 #endif
-	g_object_get (source, "volume", &volume, NULL);
+	g_object_get (source, "mount", &mount, NULL);
 
 #ifdef HAVE_HAL
 	ctx = get_hal_context ();
 	if (ctx != NULL) {
-		gchar *udi;
+		char *udi;
 
-		udi = get_hal_udi_for_player (ctx, volume);
+		udi = get_hal_udi_for_player (ctx, mount);
 
 		if (udi != NULL) {
 			DBusError error;
@@ -468,7 +501,7 @@
 			}
 			free_dbus_error ("getting max folder depth", &error);
 
-			debug_device_info (source, volume, "HAL");
+			debug_device_info (source, mount, "HAL");
 		} else {
 			rb_debug ("no player info available (HAL doesn't recognise it as a player");
 		}
@@ -478,17 +511,18 @@
 #endif
 
 	/* allow HAL info to be overridden with .is_audio_player file */
-	is_audio_player = get_is_audio_player_path (volume);
+	is_audio_player = get_is_audio_player_file (mount);
 	if (is_audio_player != NULL) {
 		char *data = NULL;
-		int data_size = 0;
-		GnomeVFSResult result;
+		gsize data_size = 0;
 
-		rb_debug ("reading .is_audio_player file %s", is_audio_player);
-		result = gnome_vfs_read_entire_file (is_audio_player, &data_size, &data);
-		if (result != GNOME_VFS_OK) {
+		rb_debug ("reading .is_audio_player file");
+
+		g_file_load_contents (is_audio_player, NULL, &data, &data_size, NULL, &error);
+		if (error != NULL) {
 			/* can we sensibly report this anywhere? */
-			rb_debug ("error reading .is_audio_player file: %s", gnome_vfs_result_to_string (result));
+			rb_debug ("error reading .is_audio_player file: %s", error->message);
+			g_clear_error (&error);
 		} else {
 			GKeyFile *keyfile;
 			GError *error = NULL;
@@ -548,16 +582,16 @@
 			g_key_file_free (keyfile);
 			g_free (munged);
 			
-			debug_device_info (source, volume, ".is_audio_player file");
+			debug_device_info (source, mount, ".is_audio_player file");
 		}
 		g_free (data);
 
-		g_free (is_audio_player);
+		g_object_unref (is_audio_player);
 	} else {
 		rb_debug ("no .is_audio_player file found on this device");
 	}
 
-	g_object_unref (volume);
+	g_object_unref (mount);
 }
 
 static void
@@ -610,20 +644,23 @@
 }
 
 RBRemovableMediaSource *
-rb_generic_player_source_new (RBShell *shell, GnomeVFSVolume *volume)
+rb_generic_player_source_new (RBShell *shell, GMount *mount)
 {
 	RBGenericPlayerSource *source;
 	RhythmDBEntryType entry_type;
 	RhythmDBEntryType error_type;
 	RhythmDBEntryType ignore_type;
 	RhythmDB *db;
+	GVolume *volume;
 	char *name;
 	char *path;
 
-	g_assert (rb_generic_player_is_volume_player (volume));
+	g_assert (rb_generic_player_is_mount_player (mount));
+
+	volume = g_mount_get_volume (mount);
 
 	g_object_get (G_OBJECT (shell), "db", &db, NULL);
-	path = gnome_vfs_volume_get_device_path (volume);
+	path = g_volume_get_identifier (volume, G_VOLUME_IDENTIFIER_KIND_UNIX_DEVICE);
 
 	name = g_strdup_printf ("generic audio player: %s", path);
 	entry_type = rhythmdb_entry_register_type (db, name);
@@ -638,13 +675,14 @@
 	g_free (name);
 
 	g_object_unref (db);
+	g_object_unref (volume);
 	g_free (path);
 
 	source = RB_GENERIC_PLAYER_SOURCE (g_object_new (RB_TYPE_GENERIC_PLAYER_SOURCE,
 							 "entry-type", entry_type,
 							 "ignore-entry-type", ignore_type,
 							 "error-entry-type", error_type,
-							 "volume", volume,
+							 "mount", mount,
 							 "shell", shell,
 							 "source-group", RB_SOURCE_GROUP_DEVICES,
 							 NULL));
@@ -710,8 +748,9 @@
 {
 	RBGenericPlayerSourcePrivate *priv = GENERIC_PLAYER_SOURCE_GET_PRIVATE (source);
 	RhythmDBEntryType entry_type;
+	char *mount_path;
 
-	priv->mount_path = rb_generic_player_source_get_mount_path (source);
+	mount_path = rb_generic_player_source_get_mount_path (source);
 	g_object_get (G_OBJECT (source), "entry-type", &entry_type, NULL);
 
 	/* if HAL gives us a set of folders on the device containing audio files,
@@ -726,19 +765,20 @@
 		int af;
 		for (af=0; priv->audio_folders[af] != NULL; af++) {
 			char *path;
-			path = rb_uri_append_path (priv->mount_path, priv->audio_folders[af]);
+			path = rb_uri_append_path (mount_path, priv->audio_folders[af]);
 			rb_debug ("loading songs from device audio folder %s", path);
 			rhythmdb_import_job_add_uri (priv->import_job, path);
 			g_free (path);
 		}
 	} else {
-		rb_debug ("loading songs from device mount path %s", priv->mount_path);
-		rhythmdb_import_job_add_uri (priv->import_job, priv->mount_path);
+		rb_debug ("loading songs from device mount path %s", mount_path);
+		rhythmdb_import_job_add_uri (priv->import_job, mount_path);
 	}
 
 	rhythmdb_import_job_start (priv->import_job);
 
 	g_boxed_free (RHYTHMDB_TYPE_ENTRY_TYPE, entry_type);
+	g_free (mount_path);
 }
 
 char *
@@ -749,21 +789,31 @@
 	return klass->impl_get_mount_path (source);
 }
 
-static gchar *
+static char *
 default_get_mount_path (RBGenericPlayerSource *source)
 {
-	gchar *uri;
-	GnomeVFSVolume *volume;
+	RBGenericPlayerSourcePrivate *priv = GENERIC_PLAYER_SOURCE_GET_PRIVATE (source);
 
-	g_object_get (source, "volume", &volume, NULL);
-	uri = gnome_vfs_volume_get_activation_uri (volume);
-	g_object_unref (volume);
+	if (priv->mount_path == NULL) {
+		GMount *mount;
+		GFile *root;
+
+		g_object_get (source, "mount", &mount, NULL);
+
+		root = g_mount_get_root (mount);
+		if (root != NULL) {
+			priv->mount_path = g_file_get_uri (root);
+			g_object_unref (root);
+		}
+
+		g_object_unref (mount);
+	}
 
-	return uri;
+	return g_strdup (priv->mount_path);
 }
 
 gboolean
-rb_generic_player_is_volume_player (GnomeVFSVolume *volume)
+rb_generic_player_is_mount_player (GMount *mount)
 {
 	gboolean result = FALSE;
 #ifdef HAVE_HAL
@@ -771,7 +821,7 @@
 
 	ctx = get_hal_context ();
 	if (ctx != NULL) {
-		gchar *udi = get_hal_udi_for_player (ctx, volume);
+		char *udi = get_hal_udi_for_player (ctx, mount);
 		if (udi != NULL) {
 			DBusError error;
 			char *prop;
@@ -800,11 +850,12 @@
 
 	/* treat as audio player if ".is_audio_player" exists in the root of the volume  */
 	if (!result) {
-		char *path;
-		path = get_is_audio_player_path (volume);
-		result = (path != NULL);
-
-		g_free (path);
+		GFile *is_audio_player;
+		is_audio_player = get_is_audio_player_file (mount);
+		if (is_audio_player != NULL) {
+			result = TRUE;
+			g_object_unref (is_audio_player);
+		}
 	}
 
 	return result;
@@ -934,50 +985,78 @@
 {
 	RhythmDBEntryType entry_type;
 	RBGenericPlayerPlaylistSource *playlist;
-	RBGenericPlayerSourcePrivate *priv = GENERIC_PLAYER_SOURCE_GET_PRIVATE (source);
 	RBShell *shell;
+	char *mount_path;
 
 	g_object_get (G_OBJECT (source),
 		      "shell", &shell,
 		      "entry-type", &entry_type,
 		      NULL);
 
+	mount_path = rb_generic_player_source_get_mount_path (source);
 	rb_debug ("loading playlist %s", playlist_path);
 	playlist = RB_GENERIC_PLAYER_PLAYLIST_SOURCE (
 			rb_generic_player_playlist_source_new (shell,
 							       source,
 							       playlist_path,
-							       priv->mount_path,
+							       mount_path,
 							       entry_type));
-	g_boxed_free (RHYTHMDB_TYPE_ENTRY_TYPE, entry_type);
 
 	if (playlist != NULL) {
 		rb_generic_player_source_add_playlist (source, shell, RB_SOURCE (playlist));
 	}
 
+	g_boxed_free (RHYTHMDB_TYPE_ENTRY_TYPE, entry_type);
 	g_object_unref (shell);
+	g_free (mount_path);
 }
 
 static gboolean
-visit_playlist_dirs (const gchar *rel_path,
-		     GnomeVFSFileInfo *info,
-		     gboolean recursing_will_loop,
-		     RBGenericPlayerSource *source,
-		     gboolean *recurse)
-{
-	char *main_path;
-	char *playlist_path;
+visit_playlist_dirs (GFile *file,
+		     gboolean dir,
+		     RBGenericPlayerSource *source)
+{
+	char *basename;
+	char *uri;
+	RhythmDBEntry *entry;
+	RhythmDBEntryType entry_type;
+	RBGenericPlayerSourcePrivate *priv = GENERIC_PLAYER_SOURCE_GET_PRIVATE (source);
 
-	*recurse = TRUE;
-	if (strcmp (rel_path, ".is_audio_player") == 0)
+	if (dir) {
 		return TRUE;
+	}
 
-	main_path = rb_generic_player_source_get_mount_path (source);
-	playlist_path = rb_uri_append_path (main_path, rel_path);
-	g_free (main_path);
+	/* check if we've already got an entry 
+	 * for this file, just to save some i/o.
+	 */
+	uri = g_file_get_uri (file);
+	entry = rhythmdb_entry_lookup_by_location (priv->db, uri);
+	g_free (uri);
+	if (entry != NULL) {
+		gboolean is_song;
+
+		is_song = FALSE;
+
+		g_object_get (G_OBJECT (source), "entry-type", &entry_type, NULL);
+		is_song = (rhythmdb_entry_get_entry_type (entry) == entry_type);
+		g_boxed_free (RHYTHMDB_TYPE_ENTRY_TYPE, entry_type);
+
+		if (is_song) {
+			rb_debug ("%s was loaded as a song",
+				  rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_LOCATION));
+			return TRUE;
+		}
+	}
 
-	load_playlist_file (source, playlist_path, rel_path);
-	g_free (playlist_path);
+	basename = g_file_get_basename (file);
+	if (strcmp (basename, ".is_audio_player") != 0) {
+		char *playlist_path;
+		playlist_path = g_file_get_path (file);
+		load_playlist_file (source, playlist_path, basename);
+		g_free (playlist_path);
+	}
+
+	g_free (basename);
 
 	return TRUE;
 }
@@ -1011,10 +1090,9 @@
 
 	}
 
-	gnome_vfs_directory_visit (playlist_path ? playlist_path : mount_path,
-				   GNOME_VFS_FILE_INFO_DEFAULT,
-				   GNOME_VFS_DIRECTORY_VISIT_DEFAULT,
-				   (GnomeVFSDirectoryVisitFunc) visit_playlist_dirs,
+	rb_uri_handle_recursively (playlist_path ? playlist_path : mount_path,
+				   NULL,
+				   (RBUriRecurseFunc) visit_playlist_dirs,
 				   source);
 
 	g_free (playlist_path);
@@ -1033,8 +1111,8 @@
 static char *
 sanitize_path (const char *str)
 {
-	gchar *res = NULL;
-	gchar *s;
+	char *res = NULL;
+	char *s;
 
 	/* Skip leading periods, otherwise files disappear... */
 	while (*str == '.')
@@ -1080,6 +1158,7 @@
 	char *artist, *album, *title;
 	gulong track_number, disc_number;
 	const char *folders;
+	char *mount_path;
 	char *number;
 	char *file = NULL;
 	char *path;
@@ -1156,8 +1235,10 @@
 	else
 		folders = "";
 
-	path = g_build_filename (priv->mount_path, folders, file, NULL);
+	mount_path = rb_generic_player_source_get_mount_path (RB_GENERIC_PLAYER_SOURCE (source));
+	path = g_build_filename (mount_path, folders, file, NULL);
 	g_free (file);
+	g_free (mount_path);
 
 	/* TODO: check for duplicates, or just overwrite by default? */
 	rb_debug ("dest file is %s", path);
@@ -1263,15 +1344,23 @@
 }
 
 static char *
-get_hal_udi_for_player (LibHalContext *ctx, GnomeVFSVolume *volume)
+get_hal_udi_for_player (LibHalContext *ctx, GMount *mount)
 {
 	DBusError error;
-	gchar *udi;
+	char *udi;
+	GVolume *volume;
+
+	volume = g_mount_get_volume (mount);
+	if (volume == NULL) {
+		return NULL;
+	}
 
-	udi = gnome_vfs_volume_get_hal_udi (volume);
+	udi = g_volume_get_identifier (volume, G_VOLUME_IDENTIFIER_KIND_HAL_UDI);
 
-	if (udi == NULL)
+	if (udi == NULL) {
+		g_object_unref (volume);
 		return NULL;
+	}
 
 	dbus_error_init (&error);
 	/* find the udi of the player itself */
@@ -1306,6 +1395,7 @@
 		free_dbus_error ("finding audio player udi", &error);
 	}
 
+	g_object_unref (volume);
 	return udi;
 }
 

Modified: trunk/plugins/generic-player/rb-generic-player-source.h
==============================================================================
--- trunk/plugins/generic-player/rb-generic-player-source.h	(original)
+++ trunk/plugins/generic-player/rb-generic-player-source.h	Tue Jul 29 13:17:53 2008
@@ -35,7 +35,6 @@
 #include "rhythmdb.h"
 
 #include <totem-pl-parser.h>
-#include <libgnomevfs/gnome-vfs-volume.h>
 
 G_BEGIN_DECLS
 
@@ -68,7 +67,7 @@
 #endif
 } RBGenericPlayerSourceClass;
 
-RBRemovableMediaSource *rb_generic_player_source_new			(RBShell *shell, GnomeVFSVolume *volume);
+RBRemovableMediaSource *rb_generic_player_source_new			(RBShell *shell, GMount *mount);
 GType			rb_generic_player_source_get_type		(void);
 GType			rb_generic_player_source_register_type		(GTypeModule *module);
 
@@ -82,7 +81,7 @@
 TotemPlParserType	rb_generic_player_source_get_playlist_format	(RBGenericPlayerSource *source);
 char *			rb_generic_player_source_get_playlist_path	(RBGenericPlayerSource *source);
 
-gboolean		rb_generic_player_is_volume_player		(GnomeVFSVolume *volume);
+gboolean		rb_generic_player_is_mount_player		(GMount *mount);
 
 
 /* for subclasses */

Modified: trunk/plugins/generic-player/rb-nokia770-source.c
==============================================================================
--- trunk/plugins/generic-player/rb-nokia770-source.c	(original)
+++ trunk/plugins/generic-player/rb-nokia770-source.c	Tue Jul 29 13:17:53 2008
@@ -38,8 +38,6 @@
 #include <gtk/gtk.h>
 #include <dbus/dbus.h>
 #include <libhal.h>
-#include <libgnomevfs/gnome-vfs-volume.h>
-#include <libgnomevfs/gnome-vfs-volume-monitor.h>
 
 #include "eel-gconf-extensions.h"
 #include "rb-nokia770-source.h"
@@ -82,27 +80,31 @@
 }
 
 RBRemovableMediaSource *
-rb_nokia770_source_new (RBShell *shell, GnomeVFSVolume *volume)
+rb_nokia770_source_new (RBShell *shell, GMount *mount)
 {
 	RBNokia770Source *source;
 	RhythmDBEntryType entry_type;
 	RhythmDB *db;
+	GVolume *volume;
 	char *name;
 	char *path;
 
-	g_assert (rb_nokia770_is_volume_player (volume));
+	g_assert (rb_nokia770_is_mount_player (mount));
+
+	volume = g_mount_get_volume (mount);
 
 	g_object_get (G_OBJECT (shell), "db", &db, NULL);
-	path = gnome_vfs_volume_get_device_path (volume);
+	path = g_volume_get_identifier (volume, G_VOLUME_IDENTIFIER_KIND_UNIX_DEVICE);
 	name = g_strdup_printf ("nokia770: %s", path);
 	entry_type = rhythmdb_entry_register_type (db, name);
-	g_object_unref (G_OBJECT (db));
+	g_object_unref (db);
 	g_free (name);
 	g_free (path);
+	g_object_unref (volume);
 
 	source = RB_NOKIA770_SOURCE (g_object_new (RB_TYPE_NOKIA770_SOURCE,
 						   "entry-type", entry_type,
-						   "volume", volume,
+						   "mount", mount,
 						   "shell", shell,
 						   "source-group", RB_SOURCE_GROUP_DEVICES,
 						   NULL));
@@ -224,22 +226,20 @@
 #endif
 
 gboolean
-rb_nokia770_is_volume_player (GnomeVFSVolume *volume)
+rb_nokia770_is_mount_player (GMount *mount)
 {
 	gboolean result = FALSE;
 	gchar *str;
+	GVolume *volume;
 
-	if (gnome_vfs_volume_get_volume_type (volume) != GNOME_VFS_VOLUME_TYPE_MOUNTPOINT) {
-		return FALSE;
-	}
-
-	str = gnome_vfs_volume_get_hal_udi (volume);
-	if (str != NULL) {
-		gboolean result;
-
-		result = hal_udi_is_nokia770 (str);
-		g_free (str);
-		return result;
+	volume = g_mount_get_volume (mount);
+	if (volume != NULL) {
+		str = g_volume_get_identifier (volume, G_VOLUME_IDENTIFIER_KIND_HAL_UDI);
+		if (str != NULL) {
+			result = hal_udi_is_nokia770 (str);
+			g_free (str);
+		}
+		g_object_unref (volume);
 	}
 
 	return result;

Modified: trunk/plugins/generic-player/rb-nokia770-source.h
==============================================================================
--- trunk/plugins/generic-player/rb-nokia770-source.h	(original)
+++ trunk/plugins/generic-player/rb-nokia770-source.h	Tue Jul 29 13:17:53 2008
@@ -53,11 +53,11 @@
 	RBGenericPlayerSourceClass parent;
 } RBNokia770SourceClass;
 
-RBRemovableMediaSource *	rb_nokia770_source_new		(RBShell *shell, GnomeVFSVolume *volume);
+RBRemovableMediaSource *	rb_nokia770_source_new		(RBShell *shell, GMount *mount);
 GType				rb_nokia770_source_get_type	(void);
 GType				rb_nokia770_source_register_type (GTypeModule *module);
 
-gboolean			rb_nokia770_is_volume_player	(GnomeVFSVolume *volume);
+gboolean			rb_nokia770_is_mount_player	(GMount *mount);
 
 G_END_DECLS
 

Modified: trunk/plugins/generic-player/rb-psp-source.c
==============================================================================
--- trunk/plugins/generic-player/rb-psp-source.c	(original)
+++ trunk/plugins/generic-player/rb-psp-source.c	Tue Jul 29 13:17:53 2008
@@ -36,8 +36,6 @@
 
 #include <glib/gi18n.h>
 #include <gtk/gtk.h>
-#include <libgnomevfs/gnome-vfs-volume.h>
-#include <libgnomevfs/gnome-vfs-volume-monitor.h>
 
 #ifdef HAVE_HAL
 #include <libhal.h>
@@ -86,27 +84,31 @@
 }
 
 RBRemovableMediaSource *
-rb_psp_source_new (RBShell *shell, GnomeVFSVolume *volume)
+rb_psp_source_new (RBShell *shell, GMount *mount)
 {
 	RBPspSource *source;
 	RhythmDBEntryType entry_type;
 	RhythmDB *db;
 	char *name;
 	char *path;
+	GVolume *volume;
 
-	g_assert (rb_psp_is_volume_player (volume));
+	g_assert (rb_psp_is_mount_player (mount));
+
+	volume = g_mount_get_volume (mount);
 
 	g_object_get (G_OBJECT (shell), "db", &db, NULL);
-	path = gnome_vfs_volume_get_device_path (volume);
+	path = g_volume_get_identifier (volume, G_VOLUME_IDENTIFIER_KIND_UNIX_DEVICE);
 	name = g_strdup_printf ("psp: %s", path);
 	entry_type = rhythmdb_entry_register_type (db, name);
-	g_object_unref (G_OBJECT (db));
+	g_object_unref (db);
 	g_free (name);
 	g_free (path);
+	g_object_unref (volume);
 
 	source = RB_PSP_SOURCE (g_object_new (RB_TYPE_PSP_SOURCE,
 					  "entry-type", entry_type,
-					  "volume", volume,
+					  "mount", mount,
 					  "shell", shell,
 					  "source-group", RB_SOURCE_GROUP_DEVICES,
 					  NULL));
@@ -117,55 +119,69 @@
 }
 
 static char *
+find_music_dir (GMount *mount)
+{
+	char *path = NULL;
+	GFile *root;
+	GFile *music_dir;
+
+	root = g_mount_get_root (mount);
+	if (root != NULL) {
+		int i;
+		char *paths[] = {
+			"PSP/MUSIC",
+			"MUSIC",
+			NULL
+		};
+
+		i = 0;
+		while (paths[i] != NULL && path == NULL) {
+			music_dir = g_file_resolve_relative_path (root, "PSP/MUSIC");
+			if (g_file_query_exists (music_dir, NULL)) {
+				path = g_file_get_path (music_dir);
+			}
+			g_object_unref (music_dir);
+		}
+
+		g_object_unref (root);
+	}
+
+	return path;
+}
+
+static char *
 impl_get_mount_path (RBGenericPlayerSource *source)
 {
-	char *uri;
+	GMount *mount;
 	char *path;
-	GnomeVFSVolume *volume;
 
-	g_object_get (G_OBJECT (source), "volume", &volume, NULL);
-	uri = gnome_vfs_volume_get_activation_uri (volume);
-	g_object_unref (volume);
+	g_object_get (G_OBJECT (source), "mount", &mount, NULL);
 
-	path = rb_uri_append_path (uri, "PSP/MUSIC");
-	/* For Firmware versions 2.80+ */
-	if (!rb_uri_exists(path)) {
-		g_free (path);
-		path = rb_uri_append_path(uri, "MUSIC");
-	}
-
-	g_free (uri);
+	path = find_music_dir (mount);
+	g_object_unref (mount);
 
 	return path;
 }
 
 static gboolean
-visit_playlist_dirs (const gchar *rel_path,
-		     GnomeVFSFileInfo *info,
-		     gboolean recursing_will_loop,
-		     RBPspSource *source,
-		     gboolean *recurse)
+visit_playlist_dirs (GFile *file,
+		     gboolean dir,
+		     RBPspSource *source)
 {
 	RBShell *shell;
 	RhythmDB *db;
 	RhythmDBEntryType entry_type;
-	char *main_path;
 	char *playlist_path;
+	char *playlist_name;
 	RBSource *playlist;
 	GPtrArray *query;
 
-	*recurse = FALSE;
-
-	/* add playlist */
-	main_path = rb_generic_player_source_get_mount_path (RB_GENERIC_PLAYER_SOURCE (source));
-	playlist_path = rb_uri_append_path (main_path, rel_path);
-	g_free (main_path);
-
-	if (!rb_uri_is_directory (playlist_path)) {
-		g_free (playlist_path);
+	if (dir == FALSE) {
 		return TRUE;
 	}
 
+	playlist_path = g_file_get_uri (file);		/* or _get_path? */
+
 	g_object_get (source,
 		      "shell", &shell,
 		      "entry-type", &entry_type,
@@ -181,7 +197,10 @@
 	g_free (playlist_path);
         g_boxed_free (RHYTHMDB_TYPE_ENTRY_TYPE, entry_type);
 
-	playlist = rb_auto_playlist_source_new (shell, rel_path, FALSE);
+	playlist_name = g_file_get_basename (file);
+	playlist = rb_auto_playlist_source_new (shell, playlist_name, FALSE);
+	g_free (playlist_name);
+
 	rb_auto_playlist_source_set_query (RB_AUTO_PLAYLIST_SOURCE (playlist), query,
 					   RHYTHMDB_QUERY_MODEL_LIMIT_NONE, NULL,
 					   NULL, 0);
@@ -201,10 +220,9 @@
 	char *mount_path;
 
 	mount_path = rb_generic_player_source_get_mount_path (source);
-	gnome_vfs_directory_visit (mount_path,
-				   GNOME_VFS_FILE_INFO_DEFAULT,
-				   GNOME_VFS_DIRECTORY_VISIT_DEFAULT,
-				   (GnomeVFSDirectoryVisitFunc) visit_playlist_dirs,
+	rb_uri_handle_recursively (mount_path,
+				   NULL,
+				   (RBUriRecurseFunc) visit_playlist_dirs,
 				   source);
 	g_free (mount_path);
 }
@@ -280,39 +298,29 @@
 #endif
 
 gboolean
-rb_psp_is_volume_player (GnomeVFSVolume *volume)
+rb_psp_is_mount_player (GMount *mount)
 {
+#ifndef HAVE_HAL
+	char *music_dir;
+#else
+	GVolume *volume;
+#endif
 	gboolean result = FALSE;
 	gchar *str;
 
-	if (gnome_vfs_volume_get_volume_type (volume) != GNOME_VFS_VOLUME_TYPE_MOUNTPOINT) {
-		return FALSE;
-	}
-
 #ifndef HAVE_HAL
-	str = gnome_vfs_volume_get_activation_uri (volume);
-	if (str) {
-		char *path;
-
-		path = rb_uri_append_path (str, "PSP/MUSIC");
-		g_free (str);
-		result = rb_uri_exists (path);
-		if (!result) {
-			g_free (path);
-			path = rb_uri_append_path (str, "MUSIC");
-			result = rb_uri_exists (path);
-		}
-		g_free (path);
-		return result;
-	}
+	music_dir = find_music_dir (mount);
+	result = (music_dir != NULL);
+	g_free (music_dir);
 #else
-	str = gnome_vfs_volume_get_hal_udi (volume);
-	if (str != NULL) {
-		gboolean result;
-
-		result = hal_udi_is_psp (str);
-		g_free (str);
-		return result;
+	volume = g_mount_get_volume (mount);
+	if (volume != NULL) {
+		str = g_volume_get_identifier (volume, G_VOLUME_IDENTIFIER_KIND_HAL_UDI);
+		if (str != NULL) {
+			result = hal_udi_is_psp (str);
+			g_free (str);
+		}
+		g_object_unref (volume);
 	}
 #endif
 	return result;

Modified: trunk/plugins/generic-player/rb-psp-source.h
==============================================================================
--- trunk/plugins/generic-player/rb-psp-source.h	(original)
+++ trunk/plugins/generic-player/rb-psp-source.h	Tue Jul 29 13:17:53 2008
@@ -53,11 +53,11 @@
 	RBGenericPlayerSourceClass parent;
 } RBPspSourceClass;
 
-RBRemovableMediaSource *	rb_psp_source_new		(RBShell *shell, GnomeVFSVolume *volume);
+RBRemovableMediaSource *	rb_psp_source_new		(RBShell *shell, GMount *mount);
 GType			rb_psp_source_get_type		(void);
 GType			rb_psp_source_register_type	(GTypeModule *module);
 
-gboolean		rb_psp_is_volume_player		(GnomeVFSVolume *volume);
+gboolean		rb_psp_is_mount_player		(GMount *mount);
 
 G_END_DECLS
 

Modified: trunk/plugins/ipod/rb-ipod-db.c
==============================================================================
--- trunk/plugins/ipod/rb-ipod-db.c	(original)
+++ trunk/plugins/ipod/rb-ipod-db.c	Tue Jul 29 13:17:53 2008
@@ -739,36 +739,29 @@
 	g_queue_push_tail (priv->delayed_actions, action);
 }
 
-static gchar *
-rb_ipod_db_get_volume_path (GnomeVFSVolume *volume)
-{
-	gchar *path;
-	gchar *uri;
-
-	uri = gnome_vfs_volume_get_activation_uri (volume);
-	path = g_filename_from_uri (uri, NULL, NULL);
-	g_assert (path != NULL);
-	g_free (uri);
-
-	return path;
-}
-
 static gboolean
-rb_ipod_db_load (RbIpodDb *ipod_db, GnomeVFSVolume *volume)
+rb_ipod_db_load (RbIpodDb *ipod_db, GMount *mount)
 {
+	GFile *mount_root;
 	char *mount_path;
 	const Itdb_IpodInfo *info;
 	RbIpodDbPrivate *priv = IPOD_DB_GET_PRIVATE (ipod_db);
 
-	mount_path = rb_ipod_db_get_volume_path (volume);
+	mount_root = g_mount_get_root (mount);
+	if (mount_root == NULL) {
+		return FALSE;
+	}
+	mount_path = g_file_get_path (mount_root);
+	g_object_unref (mount_root);
+
  	priv->itdb = itdb_parse (mount_path, NULL);
 	g_free (mount_path);
 
         if (priv->itdb == NULL) {
-            return FALSE;
+		return FALSE;
         }
 
-	info = itdb_device_get_ipod_info(priv->itdb->device);
+	info = itdb_device_get_ipod_info (priv->itdb->device);
 	if (info->ipod_generation == ITDB_IPOD_GENERATION_UNKNOWN ||
 	    info->ipod_generation == ITDB_IPOD_GENERATION_SHUFFLE_1 ||
 	    info->ipod_generation == ITDB_IPOD_GENERATION_SHUFFLE_2 ||
@@ -781,26 +774,25 @@
         return TRUE;
 }
 
-RbIpodDb *
-rb_ipod_db_new (GnomeVFSVolume *volume)
+RbIpodDb *rb_ipod_db_new (GMount *mount)
 {
 	RbIpodDb *db;
         gboolean success;
 
-	g_return_val_if_fail (volume != NULL, NULL);
+	g_return_val_if_fail (mount != NULL, NULL);
 
 	db = g_object_new (RB_TYPE_IPOD_DB, NULL);
 	if (db == NULL) {
 		return NULL;
 	}
 
-	success = rb_ipod_db_load (db, volume);
+	success = rb_ipod_db_load (db, mount);
 
-        if (success == FALSE) {
-            return NULL;
-        } else {
-	return db;
-}
+	if (success == FALSE) {
+		return NULL;
+	} else {
+		return db;
+	}
 }
 
 

Modified: trunk/plugins/ipod/rb-ipod-db.h
==============================================================================
--- trunk/plugins/ipod/rb-ipod-db.h	(original)
+++ trunk/plugins/ipod/rb-ipod-db.h	Tue Jul 29 13:17:53 2008
@@ -29,10 +29,9 @@
 #ifndef __RB_IPOD_DB_H
 #define __RB_IPOD_DB_H
 
+#include <gio/gio.h>
 #include <gdk-pixbuf/gdk-pixbuf.h>
 #include <gpod/itdb.h>
-#include <libgnomevfs/gnome-vfs-volume.h>
-#include <libgnomevfs/gnome-vfs-volume-monitor.h>
 
 
 G_BEGIN_DECLS
@@ -54,7 +53,7 @@
 	GObjectClass parent;
 } RbIpodDbClass;
 
-RbIpodDb *rb_ipod_db_new (GnomeVFSVolume *volume);
+RbIpodDb *rb_ipod_db_new (GMount *mount);
 GType rb_ipod_db_get_type (void);
 
 void rb_ipod_db_save_async (RbIpodDb *db);

Modified: trunk/plugins/ipod/rb-ipod-plugin.c
==============================================================================
--- trunk/plugins/ipod/rb-ipod-plugin.c	(original)
+++ trunk/plugins/ipod/rb-ipod-plugin.c	Tue Jul 29 13:17:53 2008
@@ -35,7 +35,6 @@
 #include <gtk/gtk.h>
 #include <glib.h>
 #include <glib-object.h>
-#include <libgnomevfs/gnome-vfs.h>
 
 #include "rb-removable-media-manager.h"
 #include "rb-sourcelist.h"
@@ -82,7 +81,7 @@
 static void impl_deactivate (RBPlugin *plugin, RBShell *shell);
 
 static RBSource * create_source_cb (RBRemovableMediaManager *rmm,
-				    GnomeVFSVolume *volume,
+				    GMount *mount,
 				    RBIpodPlugin *plugin);
 static void  rb_ipod_plugin_cmd_rename (GtkAction *action,
 					RBIpodPlugin *plugin);
@@ -178,7 +177,7 @@
 
 	/* watch for new removable media, and cause a rescan */
 	g_signal_connect (G_OBJECT (rmm),
-			  "create-source", G_CALLBACK (create_source_cb),
+			  "create-source-mount", G_CALLBACK (create_source_cb),
 			  plugin);
 
 	/* only scan if we're being loaded after the initial scan has been done */
@@ -223,11 +222,11 @@
 }
 
 static RBSource *
-create_source_cb (RBRemovableMediaManager *rmm, GnomeVFSVolume *volume, RBIpodPlugin *plugin)
+create_source_cb (RBRemovableMediaManager *rmm, GMount *mount, RBIpodPlugin *plugin)
 {
-	if (rb_ipod_is_volume_ipod (volume)) {
+	if (rb_ipod_is_mount_ipod (mount)) {
 		RBSource *src;
-		src = RB_SOURCE (rb_ipod_source_new (plugin->shell, volume));
+		src = RB_SOURCE (rb_ipod_source_new (plugin->shell, mount));
 
 		plugin->ipod_sources = g_list_prepend (plugin->ipod_sources, src);
 		g_signal_connect_object (G_OBJECT (src),

Modified: trunk/plugins/ipod/rb-ipod-source.c
==============================================================================
--- trunk/plugins/ipod/rb-ipod-source.c	(original)
+++ trunk/plugins/ipod/rb-ipod-source.c	Tue Jul 29 13:17:53 2008
@@ -39,9 +39,6 @@
 #include <libhal.h>
 #include <dbus/dbus.h>
 #endif
-#include <libgnomevfs/gnome-vfs-utils.h>
-#include <libgnomevfs/gnome-vfs-volume.h>
-#include <libgnomevfs/gnome-vfs-volume-monitor.h>
 #include <gpod/itdb.h>
 
 #include "eel-gconf-extensions.h"
@@ -270,18 +267,22 @@
 
 RBRemovableMediaSource *
 rb_ipod_source_new (RBShell *shell,
-		    GnomeVFSVolume *volume)
+		    GMount *mount)
 {
 	RBiPodSource *source;
 	RhythmDBEntryType entry_type;
 	RhythmDB *db;
+	GVolume *volume;
 	char *name;
 	char *path;
 
-	g_assert (rb_ipod_is_volume_ipod (volume));
+	g_assert (rb_ipod_is_mount_ipod (mount));
 
+	volume = g_mount_get_volume (mount);
+	path = g_volume_get_identifier (volume, G_VOLUME_IDENTIFIER_KIND_UNIX_DEVICE);
+	g_object_unref (volume);
+	
 	g_object_get (shell, "db", &db, NULL);
-	path = gnome_vfs_volume_get_device_path (volume);
 	name = g_strdup_printf ("ipod: %s", path);
 	entry_type =  rhythmdb_entry_register_type (db, name);
 	entry_type->save_to_disk = FALSE;
@@ -292,7 +293,7 @@
 
 	source = RB_IPOD_SOURCE (g_object_new (RB_TYPE_IPOD_SOURCE,
 					       "entry-type", entry_type,
-					       "volume", volume,
+					       "mount", mount,
 					       "shell", shell,
 					       "source-group", RB_SOURCE_GROUP_DEVICES,
 					       NULL));
@@ -932,10 +933,10 @@
 rb_ipod_load_songs (RBiPodSource *source)
 {
 	RBiPodSourcePrivate *priv = IPOD_SOURCE_GET_PRIVATE (source);
-	GnomeVFSVolume *volume;
+	GMount *mount;
 
-	g_object_get (source, "volume", &volume, NULL);
- 	priv->ipod_db = rb_ipod_db_new (volume);
+	g_object_get (source, "mount", &mount, NULL);
+ 	priv->ipod_db = rb_ipod_db_new (mount);
 	priv->entry_map = g_hash_table_new (g_direct_hash, g_direct_equal);
 
 	if ((priv->ipod_db != NULL) && (priv->entry_map != NULL)) {
@@ -951,39 +952,37 @@
                                   NULL);
 		priv->load_idle_id = g_idle_add ((GSourceFunc)load_ipod_db_idle_cb, source);
 	}
-	g_object_unref (volume);
+	g_object_unref (mount);
 }
 
 static gchar *
-rb_ipod_get_itunesdb_path (GnomeVFSVolume *volume)
+rb_ipod_get_itunesdb_path (GMount *mount)
 {
-	gchar *mount_point_uri;
+	GFile *root;
 	gchar *mount_point;
-	gchar *result;
+	gchar *result = NULL;
 
-	mount_point_uri = gnome_vfs_volume_get_activation_uri (volume);
-	if (mount_point_uri == NULL) {
-		return NULL;
-	}
-	mount_point = g_filename_from_uri (mount_point_uri, NULL, NULL);
-	g_free (mount_point_uri);
-	if (mount_point == NULL) {
-		return NULL;
-	}
+	root = g_mount_get_root (mount);
+	if (root != NULL) {
+		mount_point = g_file_get_path (root);
+		if (mount_point != NULL) {
+			result = itdb_get_itunes_dir (mount_point);
+		}
 
-	result = itdb_get_itunes_dir(mount_point);
+		g_free (mount_point);
+		g_object_unref (root);
+	}
 
-	g_free (mount_point);
 	return result;
 }
 
 static gboolean
-rb_ipod_volume_has_ipod_db (GnomeVFSVolume *volume)
+rb_ipod_mount_has_ipod_db (GMount *mount)
 {
 	char *itunesdb_path;
 	gboolean result;
 
-	itunesdb_path = rb_ipod_get_itunesdb_path (volume);
+	itunesdb_path = rb_ipod_get_itunesdb_path (mount);
 
 	if (itunesdb_path != NULL) {
 		result = g_file_test (itunesdb_path, G_FILE_TEST_EXISTS);
@@ -996,17 +995,16 @@
 }
 
 gboolean
-rb_ipod_is_volume_ipod (GnomeVFSVolume *volume)
+rb_ipod_is_mount_ipod (GMount *mount)
 {
 #ifdef HAVE_HAL
 	gchar *udi;
-#endif
-	if (gnome_vfs_volume_get_volume_type (volume) != GNOME_VFS_VOLUME_TYPE_MOUNTPOINT) {
-		return FALSE;
-	}
+	GVolume *volume;
+
+	volume = g_mount_get_volume (mount);
+	udi = g_volume_get_identifier (volume, G_VOLUME_IDENTIFIER_KIND_HAL_UDI);
+	g_object_unref (volume);
 
-#ifdef HAVE_HAL
-	udi = gnome_vfs_volume_get_hal_udi (volume);
 	if (udi != NULL) {
 		gboolean result;
 
@@ -1018,7 +1016,7 @@
 	}
 #endif
 
-	return rb_ipod_volume_has_ipod_db (volume);
+	return rb_ipod_mount_has_ipod_db (mount);
 }
 
 #ifdef HAVE_HAL
@@ -1571,7 +1569,7 @@
 	if (escaped == NULL) {
 		return NULL;
 	}
-	filename = gnome_vfs_unescape_string (escaped, G_DIR_SEPARATOR_S);
+	filename = g_uri_unescape_string (escaped, G_URI_RESERVED_CHARS_ALLOWED_IN_PATH);
 	g_free (escaped);
 	if (filename == NULL) {
 		return NULL;

Modified: trunk/plugins/ipod/rb-ipod-source.h
==============================================================================
--- trunk/plugins/ipod/rb-ipod-source.h	(original)
+++ trunk/plugins/ipod/rb-ipod-source.h	Tue Jul 29 13:17:53 2008
@@ -30,8 +30,6 @@
 #ifndef __RB_IPOD_SOURCE_H
 #define __RB_IPOD_SOURCE_H
 
-#include <libgnomevfs/gnome-vfs.h>
-
 #include "rb-shell.h"
 #include "rb-removable-media-source.h"
 #include "rhythmdb.h"
@@ -55,11 +53,11 @@
 	RBRemovableMediaSourceClass parent;
 } RBiPodSourceClass;
 
-RBRemovableMediaSource *	rb_ipod_source_new		(RBShell *shell, GnomeVFSVolume *volume);
+RBRemovableMediaSource *	rb_ipod_source_new		(RBShell *shell, GMount *mount);
 GType			rb_ipod_source_get_type		(void);
 GType                   rb_ipod_source_register_type    (GTypeModule *module);
 
-gboolean		rb_ipod_is_volume_ipod		(GnomeVFSVolume *volume);
+gboolean		rb_ipod_is_mount_ipod		(GMount *mount);
 
 void			rb_ipod_source_new_playlist	(RBiPodSource *source);
 void			rb_ipod_source_remove_playlist	(RBiPodSource *ipod_source,

Modified: trunk/plugins/iradio/rb-iradio-source.c
==============================================================================
--- trunk/plugins/iradio/rb-iradio-source.c	(original)
+++ trunk/plugins/iradio/rb-iradio-source.c	Tue Jul 29 13:17:53 2008
@@ -35,7 +35,6 @@
 #include <glib/gi18n.h>
 #include <gtk/gtk.h>
 #include <glade/glade.h>
-#include <libgnomevfs/gnome-vfs-uri.h>
 #include <libxml/tree.h>
 
 #include "rb-iradio-source.h"
@@ -507,7 +506,7 @@
 	if (title) {
 		fixed_title = rb_make_valid_utf8 (title, '?');
 	} else {
-		fixed_title = gnome_vfs_format_uri_for_display (uri);
+		fixed_title = g_uri_unescape_string (uri, G_URI_RESERVED_CHARS_ALLOWED_IN_PATH);
 	}
 	g_value_take_string (&val, fixed_title);
 
@@ -927,8 +926,14 @@
 	g_object_get (source, "plugin", &plugin, NULL);
 	file = rb_plugin_find_file (plugin, "iradio-initial.pls");
 	if (file != NULL) {
-		uri = gnome_vfs_get_uri_from_local_path (file);
+		GFile *f;
+
+		f = g_file_new_for_path (file);
+		uri = g_file_get_uri (f);
+
 		rb_iradio_source_add_from_playlist (source, uri);
+
+		g_object_unref (f);
 		g_free (uri);
 	}
 	g_free (file);
@@ -946,26 +951,13 @@
 				     guint time,
 				     RBIRadioSource *source)
 {
-	GList *list, *uri_list, *i;
+	GList *uri_list, *i;
 
 	rb_debug ("parsing uri list");
-	list = gnome_vfs_uri_list_parse ((char *)selection_data->data);
-
-	if (list == NULL)
-		return;
-
-	uri_list = NULL;
-
-	for (i = list; i != NULL; i = g_list_next (i))
-		uri_list = g_list_prepend (uri_list, gnome_vfs_uri_to_string ((const GnomeVFSURI *) i->data, 0));
-
-	gnome_vfs_uri_list_free (list);
-
+	uri_list = rb_uri_list_parse ((char *)selection_data->data);
 	if (uri_list == NULL)
 		return;
 
-	rb_debug ("adding uris");
-
 	i = uri_list;
 	while (i != NULL) {
 		char *uri = NULL;

Modified: trunk/plugins/iradio/rb-station-properties-dialog.c
==============================================================================
--- trunk/plugins/iradio/rb-station-properties-dialog.c	(original)
+++ trunk/plugins/iradio/rb-station-properties-dialog.c	Tue Jul 29 13:17:53 2008
@@ -36,7 +36,6 @@
 #include <glib/gi18n.h>
 #include <gtk/gtk.h>
 #include <glade/glade.h>
-#include <libgnomevfs/gnome-vfs.h>
 
 #include "rb-station-properties-dialog.h"
 #include "rb-file-helpers.h"
@@ -427,7 +426,7 @@
 	char *unescaped;
 
 	location = rhythmdb_entry_get_string (dialog->priv->current_entry, RHYTHMDB_PROP_LOCATION);
-	unescaped = gnome_vfs_unescape_string_for_display (location);
+	unescaped = g_uri_unescape_string (location, G_URI_RESERVED_CHARS_ALLOWED_IN_PATH);
 	gtk_entry_set_text (GTK_ENTRY (dialog->priv->location), unescaped);
 	g_free (unescaped);
 }

Modified: trunk/plugins/magnatune/magnatune/BuyAlbumHandler.py
==============================================================================
--- trunk/plugins/magnatune/magnatune/BuyAlbumHandler.py	(original)
+++ trunk/plugins/magnatune/magnatune/BuyAlbumHandler.py	Tue Jul 29 13:17:53 2008
@@ -25,7 +25,6 @@
 # along with this program; if not, write to the Free Software
 # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA.
 
-import gnomevfs
 import xml.sax, xml.sax.handler
 
 class BuyAlbumHandler(xml.sax.handler.ContentHandler): # Class to download the track, etc.

Modified: trunk/plugins/magnatune/magnatune/__init__.py
==============================================================================
--- trunk/plugins/magnatune/magnatune/__init__.py	(original)
+++ trunk/plugins/magnatune/magnatune/__init__.py	Tue Jul 29 13:17:53 2008
@@ -28,7 +28,7 @@
 import rhythmdb, rb
 import gobject
 import gtk, gtk.glade
-import gconf, gnomevfs, gnome
+import gconf, gnome
 
 import urllib
 import zipfile

Modified: trunk/plugins/mtpdevice/rb-mtp-plugin.c
==============================================================================
--- trunk/plugins/mtpdevice/rb-mtp-plugin.c	(original)
+++ trunk/plugins/mtpdevice/rb-mtp-plugin.c	Tue Jul 29 13:17:53 2008
@@ -36,7 +36,6 @@
 #include <gtk/gtk.h>
 #include <glib.h>
 #include <glib-object.h>
-#include <libgnomevfs/gnome-vfs.h>
 #include <libmtp.h>
 #include <hal/libhal.h>
 #include <dbus/dbus.h>
@@ -95,7 +94,7 @@
 
 static RBSource* create_source_cb (RBMtpPlugin *plugin, LIBMTP_mtpdevice_t *device, const char *udi);
 /*static RBSource * create_source_cb (RBRemovableMediaManager *rmm,
-				    GnomeVFSVolume *volume,
+				    GVolume *volume,
 				    RBMtpPlugin *plugin);*/
 static void rb_mtp_plugin_eject  (GtkAction *action, RBMtpPlugin *plugin);
 static void rb_mtp_plugin_rename (GtkAction *action, RBMtpPlugin *plugin);

Modified: trunk/plugins/mtpdevice/rb-mtp-source.c
==============================================================================
--- trunk/plugins/mtpdevice/rb-mtp-source.c	(original)
+++ trunk/plugins/mtpdevice/rb-mtp-source.c	Tue Jul 29 13:17:53 2008
@@ -31,10 +31,7 @@
 
 #include <string.h>
 #include <gtk/gtktreeview.h>
-#include <libgnome/gnome-i18n.h>
-#include <libgnomevfs/gnome-vfs-utils.h>
-#include <libgnomevfs/gnome-vfs-volume.h>
-#include <libgnomevfs/gnome-vfs-volume-monitor.h>
+#include <glib/gi18n.h>
 
 #include "rhythmdb.h"
 #include "eel-gconf-extensions.h"
@@ -545,65 +542,24 @@
 	return (strcmp (udi, priv->udi) == 0);
 }
 
-/*Borowed from rb-playlist-source-recorder*/
-static gboolean
-check_dir_has_space (const char *path,
-		     guint64 bytes_needed)
-{
-	GnomeVFSResult result;
-	GnomeVFSURI *dir_uri = NULL;
-	GnomeVFSFileSize free_bytes;
-
-	if (!g_file_test (path, G_FILE_TEST_IS_DIR))
-		return FALSE;
-
-	dir_uri = gnome_vfs_uri_new (path);
-	if (dir_uri == NULL) {
-		rb_debug ("Cannot get free space at %s\n", path);
-		return FALSE;
-	}
-
-	result = gnome_vfs_get_volume_free_space (dir_uri, &free_bytes);
-	gnome_vfs_uri_unref (dir_uri);
-
-	if (result != GNOME_VFS_OK) {
-		rb_debug ("Cannot get free space at %s\n", path);
-		return FALSE;
-	}
-
-	if (bytes_needed >= free_bytes) {
-		return FALSE;
-	}
-
-	return TRUE;
-}
-
 static gboolean
 rb_mtp_source_transfer_track_to_disk (LIBMTP_mtpdevice_t *device,
 				      LIBMTP_track_t *track,
 				      const char *uri)
 {
 	int ret = -1;
-	GnomeVFSURI* guri = NULL;
 
 	if (device == NULL || track == NULL || strlen (uri) == 0) {
 		return FALSE;
 	}
 
-	guri = gnome_vfs_uri_new (uri);
-	if (!check_dir_has_space (gnome_vfs_uri_get_path (gnome_vfs_uri_get_parent (guri)), track->filesize)) {
-		gnome_vfs_uri_unref (guri);
+	if (rb_check_dir_has_space_uri (uri, track->filesize) == FALSE) {
 		return FALSE;
 	}
-	gnome_vfs_uri_unref (guri);
 
 	ret = LIBMTP_Get_Track_To_File (device, track->item_id, uri, NULL, NULL);
 
-	if (ret == 0) {
-		return TRUE;
-	} else {
-		return FALSE;
-	}
+	return (ret == 0);
 }
 
 static char *
@@ -756,13 +712,16 @@
 {
 	RBMtpSource *source = RB_MTP_SOURCE (isource);
 	RBMtpSourcePrivate *priv = MTP_SOURCE_GET_PRIVATE (source);
-	char *filename = NULL;
+	GFile *file;
+	char *path;
 	LIBMTP_track_t *track = NULL;
 
-	filename = g_filename_from_uri (dest, NULL, NULL);
-	track = transfer_track (source, priv->device, entry, filename, filesize, mimetype);
-	gnome_vfs_unlink (filename);
-	g_free (filename);
+	file = g_file_new_for_uri (dest);
+	path = g_file_get_path (file);
+	track = transfer_track (source, priv->device, entry, path, filesize, mimetype);
+	g_free (path);
+
+	g_file_delete (file, NULL, NULL);
 
 	if (track != NULL) {
 		/*request_artwork (isource, entry, song);*/

Modified: trunk/plugins/rb-plugins-engine.c
==============================================================================
--- trunk/plugins/rb-plugins-engine.c	(original)
+++ trunk/plugins/rb-plugins-engine.c	Tue Jul 29 13:17:53 2008
@@ -254,19 +254,19 @@
 }
 
 static gboolean
-rb_plugins_engine_load_cb (const char *uri, gboolean dir, gpointer userdata)
+rb_plugins_engine_load_cb (GFile *file, gboolean dir, gpointer userdata)
 {
-	gchar *plugin_file;
+	char *plugin_path;
 	RBPluginInfo *info;
 	char *key_name;
 	gboolean activate;
 	const char *sep;
 
-	plugin_file = gnome_vfs_get_local_path_from_uri (uri);
+	plugin_path = g_file_get_path (file);
 
-	sep = strrchr (plugin_file, G_DIR_SEPARATOR);
+	sep = strrchr (plugin_path, G_DIR_SEPARATOR);
 	if (sep == NULL)
-		sep = plugin_file;
+		sep = plugin_path;
 	else
 		sep += 1;
 	
@@ -274,18 +274,18 @@
 	 * most are already covered by excluding hidden files/directories.
 	 */
 	if (dir && (g_str_has_prefix (sep, "_darcs") || g_str_has_prefix (sep, "CVS"))) {
-		rb_debug ("not loading plugin from hidden/VCS directory %s", plugin_file);
-		g_free (plugin_file);
+		rb_debug ("not loading plugin from hidden/VCS directory %s", plugin_path);
+		g_free (plugin_path);
 		return FALSE;
 	}
 
-	if (dir || !g_str_has_suffix (uri, PLUGIN_EXT)) {
-		g_free (plugin_file);
+	if (dir || !g_str_has_suffix (plugin_path, PLUGIN_EXT)) {
+		g_free (plugin_path);
 		return TRUE;
 	}
 
-	info = rb_plugins_engine_load (plugin_file);
-	g_free (plugin_file);
+	info = rb_plugins_engine_load (plugin_path);
+	g_free (plugin_path);
 
 	if (info == NULL)
 		return TRUE;
@@ -318,13 +318,18 @@
 }
 
 static void
-rb_plugins_engine_load_dir (const gchar *path)
+rb_plugins_engine_load_dir (const char *path)
 {
-	char *uri;
+	GFile *plugindir;
+	char *plugin_uri;
 
-	uri = rb_uri_resolve_relative (path);
-	rb_uri_handle_recursively (uri, rb_plugins_engine_load_cb, NULL, NULL);
-	g_free (uri);
+	plugindir = g_file_new_for_commandline_arg (path);
+	plugin_uri = g_file_get_uri (plugindir);
+
+	rb_uri_handle_recursively (plugin_uri, NULL, (RBUriRecurseFunc) rb_plugins_engine_load_cb, NULL);
+
+	g_object_unref (plugindir);
+	g_free (plugin_uri);
 }
 
 static void

Modified: trunk/plugins/rb/Loader.py
==============================================================================
--- trunk/plugins/rb/Loader.py	(original)
+++ trunk/plugins/rb/Loader.py	Tue Jul 29 13:17:53 2008
@@ -25,13 +25,32 @@
 # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA.
 
 import gobject
-
 try:
-	import gnomevfs
-	use_gnomevfs = True
+	import gio
+	use_gio = True
 except:
-	import urllib
-	use_gnomevfs = False
+	import gnomevfs
+	use_gio = False
+	# meh
+
+class GioSrc(object):
+	def __init__ (self):
+		self.chunk = 4096
+
+	def _contents_cb(self, result, (callback, args)):
+		try:
+			(contents, etag) = self.file.read_contents_finish(result)
+			# should actually use etag.. hrm.
+			callback(contents, args)
+		except:
+			callback(None, args)
+
+	def get_url (self, url, callback, *args):
+		try:
+			self.file = gio.file_new_for_uri(url)
+			self.file.read_contents_async(callback = self._contents_cb, user_data=(callback, args))
+		except:
+			callback(None, *args)
 
 
 class GnomeVFSAsyncSrc (object):  
@@ -61,21 +80,9 @@
 	def get_url (self, url, callback, *args):
 		gnomevfs.async.open (url, self.open_cb, data=("", callback, args))
 
-
-class URLLibSrc (object):
-    def get_url (self, url, callback, *args):
-			try:
-				sock = urllib.urlopen (url)
-				data = sock.read ()
-				sock.close ()
-				callback (data, *args)
-			except:
-				callback (None, *args)
-				raise
-
-
 def Loader ():
-	if use_gnomevfs:
-		return GnomeVFSAsyncSrc ()
+	if use_gio:
+		return GioSrc()
 	else:
-		return URLLibSrc ()
+		return GnomeVFSAsyncSrc()
+

Modified: trunk/po/POTFILES.in
==============================================================================
--- trunk/po/POTFILES.in	(original)
+++ trunk/po/POTFILES.in	Tue Jul 29 13:17:53 2008
@@ -54,9 +54,7 @@
 plugins/daap/rb-daap-connection.c
 plugins/daap/rb-daap-dialog.c
 plugins/daap/rb-daap-mdns-browser-avahi.c
-plugins/daap/rb-daap-mdns-browser-howl.c
 plugins/daap/rb-daap-mdns-publisher-avahi.c
-plugins/daap/rb-daap-mdns-publisher-howl.c
 plugins/daap/rb-daap-plugin.c
 plugins/daap/rb-daap-sharing.c
 plugins/daap/rb-daap-source.c

Modified: trunk/podcast/rb-feed-podcast-properties-dialog.c
==============================================================================
--- trunk/podcast/rb-feed-podcast-properties-dialog.c	(original)
+++ trunk/podcast/rb-feed-podcast-properties-dialog.c	Tue Jul 29 13:17:53 2008
@@ -36,7 +36,7 @@
 #include <glib/gi18n.h>
 #include <gtk/gtk.h>
 #include <glade/glade.h>
-#include <libgnomevfs/gnome-vfs.h>
+#include <glib/gurifuncs.h>
 
 #include "rb-feed-podcast-properties-dialog.h"
 #include "rb-file-helpers.h"
@@ -244,7 +244,7 @@
 	char *unescaped;
 
 	location = rhythmdb_entry_get_string (dialog->priv->current_entry, RHYTHMDB_PROP_LOCATION);
-	unescaped = gnome_vfs_unescape_string_for_display (location);
+	unescaped = g_uri_unescape_string (location, G_URI_RESERVED_CHARS_ALLOWED_IN_PATH);
 	gtk_label_set_text (GTK_LABEL (dialog->priv->location), unescaped);
 	g_free (unescaped);
 }

Modified: trunk/podcast/rb-podcast-manager.c
==============================================================================
--- trunk/podcast/rb-podcast-manager.c	(original)
+++ trunk/podcast/rb-podcast-manager.c	Tue Jul 29 13:17:53 2008
@@ -36,8 +36,8 @@
 
 #include <glib/gi18n.h>
 #include <glib/gstdio.h>
+#include <gio/gio.h>
 #include <gtk/gtk.h>
-#include <libgnomevfs/gnome-vfs-uri.h>
 
 #include "rb-preferences.h"
 #include "eel-gconf-extensions.h"
@@ -78,9 +78,7 @@
 	FINISH_DOWNLOAD,
 	PROCESS_ERROR,
 	FEED_UPDATES_AVAILABLE,
-#ifdef HAVE_GSTREAMER_0_10_MISSING_PLUGINS
 	MISSING_PLUGINS,
-#endif
 	LAST_SIGNAL
 };
 
@@ -96,15 +94,21 @@
 typedef struct
 {
 	RBPodcastManager *pd;
+
 	RhythmDBEntry *entry;
-	GnomeVFSAsyncHandle *read_handle;
-	GnomeVFSURI *write_uri;
-	GnomeVFSURI *read_uri;
 	char *query_string;
 
-	guint total_size;
+	GFile *source;
+	GFile *destination;
+	GFileInputStream *in_stream;
+	GFileOutputStream *out_stream;
+
+	guint64 download_offset;
+	guint64 download_size;
 	guint progress;
-	gboolean cancelled;
+
+	GCancellable *cancel;
+	GThread *thread;
 } RBPodcastManagerInfo;
 
 typedef struct
@@ -149,8 +153,8 @@
 							 guint prop_id,
 		                                	 GValue *value,
                 		                	 GParamSpec *pspec);
-static void rb_podcast_manager_download_file_info_cb	(GnomeVFSAsyncHandle *handle,
-							 GList *results,
+static void download_file_info_cb			(GFile *source,
+							 GAsyncResult *result,
 							 RBPodcastManagerInfo *data);
 static void rb_podcast_manager_abort_download		(RBPodcastManagerInfo *data);
 static gboolean rb_podcast_manager_sync_head_cb 	(gpointer data);
@@ -159,8 +163,7 @@
 							 GtkTreeIter *iter,
 						   	 RBPodcastManager *data);
 static void rb_podcast_manager_save_metadata		(RBPodcastManager *pd,
-						  	 RhythmDBEntry *entry,
-						  	 const char *uri);
+						  	 RhythmDBEntry *entry);
 static void rb_podcast_manager_db_entry_added_cb 	(RBPodcastManager *pd,
 							 RhythmDBEntry *entry);
 static void rb_podcast_manager_db_entry_deleted_cb 	(RBPodcastManager *pd,
@@ -174,16 +177,9 @@
 
 static gpointer rb_podcast_manager_thread_parse_feed	(RBPodcastThreadInfo *info);
 
-/* async read file functions */
-static guint download_progress_cb			(GnomeVFSXferProgressInfo *info,
-							 gpointer data);
-static guint download_progress_update_cb		(GnomeVFSAsyncHandle *handle,
-							 GnomeVFSXferProgressInfo *info,
-							 gpointer data);
-
 /* internal functions */
 static void download_info_free				(RBPodcastManagerInfo *data);
-static void start_job					(RBPodcastManagerInfo *data);
+static gpointer podcast_download_thread			(RBPodcastManagerInfo *data);
 static gboolean end_job					(RBPodcastManagerInfo *data);
 static void cancel_job					(RBPodcastManagerInfo *pd);
 static void rb_podcast_manager_update_synctime		(RBPodcastManager *pd);
@@ -271,7 +267,6 @@
 				G_TYPE_STRING,
 				G_TYPE_BOOLEAN);
 
-#ifdef HAVE_GSTREAMER_0_10_MISSING_PLUGINS
 	rb_podcast_manager_signals[MISSING_PLUGINS] =
 		g_signal_new ("missing-plugins",
 			      G_OBJECT_CLASS_TYPE (object_class),
@@ -282,8 +277,6 @@
 			      G_TYPE_BOOLEAN,
 			      3,
 			      G_TYPE_STRV, G_TYPE_STRV, G_TYPE_CLOSURE);
-#endif
-
 
 	g_type_class_add_private (klass, sizeof (RBPodcastManagerPrivate));
 }
@@ -582,12 +575,35 @@
         return FALSE;
 }
 
+static void
+download_error (RBPodcastManagerInfo *data, GError *error)
+{
+	GValue val = {0,};
+	rb_debug ("error downloading %s: %s",
+		  rhythmdb_entry_get_string (data->entry, RHYTHMDB_PROP_LOCATION),
+		  error->message);
+
+	g_value_init (&val, G_TYPE_ULONG);
+	g_value_set_ulong (&val, RHYTHMDB_PODCAST_STATUS_ERROR);
+	rhythmdb_entry_set (data->pd->priv->db, data->entry, RHYTHMDB_PROP_STATUS, &val);
+	g_value_unset (&val);
+
+	g_value_init (&val, G_TYPE_STRING);
+	g_value_set_string (&val, error->message);
+	rhythmdb_entry_set (data->pd->priv->db, data->entry, RHYTHMDB_PROP_PLAYBACK_ERROR, &val);
+	g_value_unset (&val);
+
+	rhythmdb_commit (data->pd->priv->db);
+	g_idle_add ((GSourceFunc)end_job, data);
+}
+
 static gboolean
 rb_podcast_manager_next_file (RBPodcastManager * pd)
 {
 	const char *location;
 	RBPodcastManagerInfo *data;
 	char *query_string;
+	const char *attrs;
 	GList *d;
 
 	g_assert (rb_is_main_thread ());
@@ -620,66 +636,39 @@
 	location = rhythmdb_entry_get_string (data->entry, RHYTHMDB_PROP_LOCATION);
 	rb_debug ("processing %s", location);
 
-	/* gnome-vfs currently doesn't handle HTTP query strings correctly.
-	 * so we do it ourselves.
+	/* extract the query string so we can remove it later if it appears
+	 * in download URLs
 	 */
 	query_string = strchr (location, '?');
 	if (query_string != NULL) {
-		char *base_uri;
-
-		base_uri = g_strdup (location);
-		query_string = strchr (base_uri, '?');
-		*query_string++ = '\0';
-		rb_debug ("hiding query string %s from gnome-vfs", query_string);
-
-		data->read_uri = gnome_vfs_uri_new (base_uri);
-		if (data->read_uri != NULL) {
-			char *full_uri;
-
-			full_uri = g_strdup_printf ("%s?%s",
-						    data->read_uri->text,
-						    query_string);
-			g_free (data->read_uri->text);
-			data->read_uri->text = full_uri;
-
-			/* include the question mark in data->query_string to make
-			 * the later check easier.
-			 */
-			query_string--;
-			*query_string = '?';
-			data->query_string = g_strdup (query_string);
-		}
-		g_free (base_uri);
-	} else {
-		data->read_uri = gnome_vfs_uri_new (location);
+		query_string--;
+		data->query_string = g_strdup (query_string);
 	}
 
-	if (data->read_uri == NULL) {
-		rb_debug ("Error downloading podcast: could not create remote uri");
-		rb_podcast_manager_abort_download (data);
-	} else {
-		GList *l;
+	data->source = g_file_new_for_uri (location);
 
-		l = g_list_prepend (NULL, data->read_uri);
-		gnome_vfs_async_get_file_info (&data->read_handle,
-					       l,
-					       GNOME_VFS_FILE_INFO_FOLLOW_LINKS,
-					       GNOME_VFS_PRIORITY_DEFAULT,
-					       (GnomeVFSAsyncGetFileInfoCallback) rb_podcast_manager_download_file_info_cb,
-					       data);
-		g_list_free (l);
-	}
+	attrs = G_FILE_ATTRIBUTE_STANDARD_SIZE ","
+		G_FILE_ATTRIBUTE_STANDARD_COPY_NAME ","
+		G_FILE_ATTRIBUTE_STANDARD_EDIT_NAME;
+	g_file_query_info_async (data->source,
+				 attrs,
+				 G_FILE_QUERY_INFO_NONE,
+				 0,
+				 data->cancel,
+				 (GAsyncReadyCallback) download_file_info_cb,
+				 data);
 
 	GDK_THREADS_LEAVE ();
 	return FALSE;
 }
 
 static void
-rb_podcast_manager_download_file_info_cb (GnomeVFSAsyncHandle *handle,
-					  GList *results,
-					  RBPodcastManagerInfo *data)
+download_file_info_cb (GFile *source,
+		       GAsyncResult *result,
+		       RBPodcastManagerInfo *data)
 {
-	GnomeVFSGetFileInfoResult *result = results->data;
+	GError *error = NULL;
+	GFileInfo *src_info;
 	char *local_file_name;
 	char *local_file_path;
 	char *dir_name;
@@ -690,27 +679,31 @@
 	rb_debug ("got file info results for %s",
 		  rhythmdb_entry_get_string (data->entry, RHYTHMDB_PROP_LOCATION));
 
-	if (result->result != GNOME_VFS_OK) {
-
+	src_info = g_file_query_info_finish (source, result, &error);
+	if (error != NULL) {
 		GValue val = {0,};
 
+		rb_debug ("file info query failed: %s", error->message);
+
 		g_value_init (&val, G_TYPE_ULONG);
 		g_value_set_ulong (&val, RHYTHMDB_PODCAST_STATUS_ERROR);
 		rhythmdb_entry_set (data->pd->priv->db, data->entry, RHYTHMDB_PROP_STATUS, &val);
 		g_value_unset (&val);
 
 		g_value_init (&val, G_TYPE_STRING);
-		g_value_set_string (&val, gnome_vfs_result_to_string (result->result));
+		g_value_set_string (&val, error->message);
 		rhythmdb_entry_set (data->pd->priv->db, data->entry, RHYTHMDB_PROP_PLAYBACK_ERROR, &val);
 		g_value_unset (&val);
 
 		rhythmdb_commit (data->pd->priv->db);
 
-		rb_debug ("get_file_info request failed");
+		g_error_free (error);
 		rb_podcast_manager_abort_download (data);
 		return;
 	}
 
+	data->download_size = g_file_info_get_attribute_uint64 (src_info, G_FILE_ATTRIBUTE_STANDARD_SIZE);
+
 	/* construct download directory */
 	conf_dir_name = rb_podcast_manager_get_podcast_dir (data->pd);
 	dir_name = g_build_filename (conf_dir_name,
@@ -726,16 +719,26 @@
 		return;
 	}
 
+	/* this should probably be the target of any redirects.  hmm. */
+	local_file_name = g_file_info_get_attribute_as_string (src_info, G_FILE_ATTRIBUTE_STANDARD_COPY_NAME);
+	if (local_file_name == NULL) {
+		/* probably shouldn't be using this, but the gvfs http backend doesn't
+		 * set the copy name (yet)
+		 */
+		local_file_name = g_strdup (g_file_info_get_edit_name (src_info));
+		if (local_file_name == NULL) {
+			/* um, grab the original filename? */
+			local_file_name = g_strdup ("mysterious podcast download.mp3");
+		}
+	}
+
 	/* if the filename ends with the query string from the original URI,
 	 * remove it.
 	 */
 	if (data->query_string &&
-	    g_str_has_suffix (result->file_info->name, data->query_string)) {
-		local_file_name = g_strdup (result->file_info->name);
+	    g_str_has_suffix (local_file_name, data->query_string)) {
 		local_file_name[strlen (local_file_name) - strlen (data->query_string)] = '\0';
 		rb_debug ("removing query string \"%s\" -> local file name \"%s\"", data->query_string, local_file_name);
-	} else {
-		local_file_name = result->file_info->name;
 	}
 
 	/* construct local filename */
@@ -743,54 +746,39 @@
 					    local_file_name,
 					    NULL);
 
-	if (local_file_name != result->file_info->name)
-		g_free (local_file_name);
+	g_free (local_file_name);
 
 	g_free (dir_name);
 	rb_debug ("creating file %s", local_file_path);
 
-	local_file_name = g_filename_to_uri (local_file_path, NULL, NULL);
-	g_free (local_file_path);
-	local_file_path = local_file_name;
-
-	data->write_uri = gnome_vfs_uri_new (local_file_path);
-	if (data->write_uri == NULL) {
-		g_warning ("Could not create local podcast URI for %s", local_file_path);
-		rb_podcast_manager_abort_download (data);
-		return;
-	}
-
-	if (rb_uri_exists (local_file_path)) {
+	data->destination = g_file_new_for_path (local_file_path);
+	if (g_file_query_exists (data->destination, NULL)) {
+		GFileInfo *dest_info;
 		guint64 local_size;
-		GnomeVFSFileInfo *local_info;
-		GnomeVFSResult local_result;
-
-		local_info = gnome_vfs_file_info_new ();
-		local_result = gnome_vfs_get_file_info (local_file_path,
-							local_info,
-							GNOME_VFS_FILE_INFO_FOLLOW_LINKS);
-		local_size = local_info->size;
-		gnome_vfs_file_info_unref (local_info);
-
-		rb_debug ("local file %s already exists: size is %u vs remote size %u",
-			  local_file_path, (guint) local_size, (guint)result->file_info->size);
-
-		if (local_result != GNOME_VFS_OK) {
-			g_warning ("Could not get info on downloaded podcast file %s",
-				   local_file_path);
+	
+		dest_info = g_file_query_info (data->destination,
+					       G_FILE_ATTRIBUTE_STANDARD_SIZE,
+					       G_FILE_QUERY_INFO_NONE,
+					       NULL,
+					       &error);
+		if (error != NULL) {
+			/* hrm */
+			g_warning ("Looking at downloaded podcast file %s: %s",
+				   local_file_path, error->message);
+			g_error_free (error);
 			rb_podcast_manager_abort_download (data);
 			return;
-		} else if (result->file_info->size == local_size) {
-			GValue val = {0,};
-			char *uri;
-			char *canon_uri;
+		}
 
-			uri = gnome_vfs_uri_to_string (data->write_uri, GNOME_VFS_URI_HIDE_NONE);
-			canon_uri = rb_canonicalise_uri (uri);
-			g_free (uri);
+		/* check size */
+		local_size = g_file_info_get_attribute_uint64 (dest_info,
+							       G_FILE_ATTRIBUTE_STANDARD_SIZE);
+		g_object_unref (dest_info);
+		if (local_size == data->download_size) {
+			GValue val = {0,};
 
-			rb_debug ("podcast %s already downloaded",
-				  rhythmdb_entry_get_string (data->entry, RHYTHMDB_PROP_LOCATION));
+			rb_debug ("local file is the same size as the download (%" G_GUINT64_FORMAT ")",
+				  local_size);
 
 			g_value_init (&val, G_TYPE_ULONG);
 			g_value_set_ulong (&val, RHYTHMDB_PODCAST_STATUS_COMPLETE);
@@ -798,27 +786,40 @@
 			g_value_unset (&val);
 
 			g_value_init (&val, G_TYPE_STRING);
-			g_value_set_string (&val, canon_uri);
+			g_value_take_string (&val, g_file_get_uri (data->destination));
 			rhythmdb_entry_set (data->pd->priv->db, data->entry, RHYTHMDB_PROP_MOUNTPOINT, &val);
 			g_value_unset (&val);
 
-			rb_podcast_manager_save_metadata (data->pd, data->entry, canon_uri);
-
-			g_free (canon_uri);
+			rb_podcast_manager_save_metadata (data->pd, data->entry);
 
 			rb_podcast_manager_abort_download (data);
+			g_free (local_file_path);
 			return;
-		} else if (result->file_info->size > local_size) {
-			/* TODO: support resume file */
-			rb_debug ("podcast episode already partially downloaded, but we can't resume downloads");
+		} else if (local_size < data->download_size) {
+			rb_debug ("podcast partly downloaded (%" G_GUINT64_FORMAT " of %" G_GUINT64_FORMAT ")",
+				  local_size, data->download_size);
+			data->download_offset = local_size;
 		} else {
-			/* the local file is larger. replace it */
+			rb_debug ("replacing local file as it's larger than the download");
 		}
 	}
 
 	g_free (local_file_path);
-	start_job (data);
 
+	GDK_THREADS_ENTER ();
+	g_signal_emit (data->pd, rb_podcast_manager_signals[START_DOWNLOAD],
+		       0, data->entry);
+	GDK_THREADS_LEAVE ();
+
+	data->cancel = g_cancellable_new ();
+	data->thread = g_thread_create ((GThreadFunc) podcast_download_thread,
+					data,
+					TRUE,
+					&error);
+	if (error != NULL) {
+		download_error (data, error);
+		g_error_free (error);
+	}
 }
 
 static void
@@ -844,26 +845,31 @@
 rb_podcast_manager_subscribe_feed (RBPodcastManager *pd, const char *url, gboolean automatic)
 {
 	RBPodcastThreadInfo *info;
-	gchar *valid_url;
+	GFile *feed;
+	char *feed_url;
 	gboolean existing_feed;
 
 	if (g_str_has_prefix (url, "feed://") || g_str_has_prefix (url, "itpc://")) {
 		char *tmp;
 
 		tmp = g_strdup_printf ("http://%s";, url + strlen ("feed://"));
-		valid_url = gnome_vfs_make_uri_from_input (tmp);
+		feed = g_file_new_for_uri (tmp);
 		g_free (tmp);
 	} else {
-		valid_url = gnome_vfs_make_uri_from_input (url);
+		feed = g_file_new_for_uri (url);
 	}
 
+	/* hmm.  can we check if the GFile we got is something useful? */
+#if 0
 	if (valid_url == NULL) {
 		rb_error_dialog (NULL, _("Invalid URL"),
 				 _("The URL \"%s\" is not valid, please check it."), url);
 		return FALSE;
 	}
+#endif
 
-	RhythmDBEntry *entry = rhythmdb_entry_lookup_by_location (pd->priv->db, valid_url);
+	feed_url = g_file_get_uri (feed);		/* not sure this buys us anything at all */
+	RhythmDBEntry *entry = rhythmdb_entry_lookup_by_location (pd->priv->db, feed_url);
 	if (entry) {
 		if (rhythmdb_entry_get_entry_type (entry) != RHYTHMDB_ENTRY_TYPE_PODCAST_FEED) {
 			/* added as something else, probably iradio */
@@ -879,7 +885,7 @@
 
 	info = g_new0 (RBPodcastThreadInfo, 1);
 	info->pd = g_object_ref (pd);
-	info->url = valid_url;
+	info->url = feed_url;
 	info->automatic = automatic;
 	info->existing_feed = existing_feed;
 
@@ -1112,7 +1118,6 @@
 	return entry;
 }
 
-#ifdef HAVE_GSTREAMER_0_10_MISSING_PLUGINS
 typedef struct {
 	RhythmDBEntry *entry;
 	RBPodcastManager *mgr;
@@ -1121,12 +1126,10 @@
 static void
 missing_plugins_retry_cb (gpointer inst, gboolean retry, MissingPluginRetryData *retry_data)
 {
-	const char *uri;
 	if (retry == FALSE)
 		return;
 
-	uri = rhythmdb_entry_get_string (retry_data->entry, RHYTHMDB_PROP_MOUNTPOINT);
-	rb_podcast_manager_save_metadata (retry_data->mgr, retry_data->entry, uri);
+	rb_podcast_manager_save_metadata (retry_data->mgr, retry_data->entry);
 }
 
 static void
@@ -1137,24 +1140,22 @@
 	g_free (retry);
 }
 
-#endif
 
 static void
-rb_podcast_manager_save_metadata (RBPodcastManager *pd, RhythmDBEntry *entry, const char *uri)
+rb_podcast_manager_save_metadata (RBPodcastManager *pd, RhythmDBEntry *entry)
 {
 	RBMetaData *md = rb_metadata_new ();
 	GError *error = NULL;
 	GValue val = { 0, };
 	const char *mime;
-#ifdef HAVE_GSTREAMER_0_10_MISSING_PLUGINS
+	const char *uri;
 	char **missing_plugins;
 	char **plugin_descriptions;
-#endif
 
+	uri = rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_MOUNTPOINT);
 	rb_debug ("loading podcast metadata from %s", uri);
         rb_metadata_load (md, uri, &error);
 
-#ifdef HAVE_GSTREAMER_0_10_MISSING_PLUGINS
 	if (rb_metadata_get_missing_plugins (md, &missing_plugins, &plugin_descriptions)) {
 		GClosure *closure;
 		gboolean processing;
@@ -1177,7 +1178,6 @@
 			return;
 		}
 	}
-#endif
 
 	if (error != NULL) {
 		/* this probably isn't an audio enclosure. or some other error */
@@ -1240,15 +1240,23 @@
 static void
 download_info_free (RBPodcastManagerInfo *data)
 {
-	if (data->write_uri) {
-		gnome_vfs_uri_unref (data->write_uri);
-		data->write_uri = NULL;
+	/* what should this do about the thread and etc.? */
+
+	if (data->cancel != NULL) {
+		g_object_unref (data->cancel);
+		data->cancel = NULL;
+	}
+
+	if (data->source) {
+		g_object_unref (data->source);
+		data->source = NULL;
 	}
 
-	if (data->read_uri) {
-		gnome_vfs_uri_unref (data->read_uri);
-		data->read_uri = NULL;
+	if (data->destination) {
+		g_object_unref (data->destination);
+		data->destination = NULL;
 	}
+
 	if (data->query_string) {
 		g_free (data->query_string);
 		data->query_string = NULL;
@@ -1262,33 +1270,176 @@
 }
 
 static void
-start_job (RBPodcastManagerInfo *data)
+download_progress (RBPodcastManagerInfo *data, gsize downloaded, guint64 total, gboolean complete)
 {
-	GList *source_uri_list;
-	GList *target_uri_list;
+	guint local_progress = 0;
 
-	GDK_THREADS_ENTER ();
-	g_signal_emit (data->pd, rb_podcast_manager_signals[START_DOWNLOAD],
-		       0, data->entry);
-	GDK_THREADS_LEAVE ();
+	rb_debug ("%s: %lu / %" G_GUINT64_FORMAT,
+		  rhythmdb_entry_get_string (data->entry, RHYTHMDB_PROP_LOCATION),
+		  (gulong)downloaded, total);
+
+	if (downloaded > 0 && total > 0)
+		local_progress = (gint) (100 * downloaded) / total;
+
+	if (local_progress != data->progress) {
+		GValue val = {0,};
+
+		GDK_THREADS_ENTER ();
+
+		g_value_init (&val, G_TYPE_ULONG);
+		g_value_set_ulong (&val, local_progress);
+		rhythmdb_entry_set (data->pd->priv->db, data->entry, RHYTHMDB_PROP_STATUS, &val);
+		g_value_unset (&val);
 
-	source_uri_list = g_list_prepend (NULL, data->read_uri);
-	target_uri_list = g_list_prepend (NULL, data->write_uri);
+		rhythmdb_commit (data->pd->priv->db);
+
+		g_signal_emit (data->pd, rb_podcast_manager_signals[STATUS_CHANGED],
+			       0, data->entry, local_progress);
+
+		GDK_THREADS_LEAVE ();
+
+		data->progress = local_progress;
+	}
+
+	if (complete) {
+		if (g_cancellable_is_cancelled (data->cancel) == FALSE) {
+			GValue val = {0,};
+			rb_debug ("download of %s completed",
+				  rhythmdb_entry_get_string (data->entry, RHYTHMDB_PROP_LOCATION));
 
-	gnome_vfs_async_xfer (&data->read_handle,
-			      source_uri_list,
-			      target_uri_list,
-			      GNOME_VFS_XFER_DEFAULT ,
-			      GNOME_VFS_XFER_ERROR_MODE_ABORT,
-			      GNOME_VFS_XFER_OVERWRITE_MODE_REPLACE,
-			      GNOME_VFS_PRIORITY_DEFAULT,
-			      (GnomeVFSAsyncXferProgressCallback) download_progress_update_cb,
-			      data,
-			      (GnomeVFSXferProgressCallback) download_progress_cb,
-			      data);
+			g_value_init (&val, G_TYPE_UINT64);
+			g_value_set_uint64 (&val, downloaded);
+			rhythmdb_entry_set (data->pd->priv->db, data->entry, RHYTHMDB_PROP_FILE_SIZE, &val);
+			g_value_unset (&val);
 
-	g_list_free (source_uri_list);
-	g_list_free (target_uri_list);
+			g_value_init (&val, G_TYPE_ULONG);
+			g_value_set_ulong (&val, RHYTHMDB_PODCAST_STATUS_COMPLETE);
+			rhythmdb_entry_set (data->pd->priv->db, data->entry, RHYTHMDB_PROP_STATUS, &val);
+			g_value_unset (&val);
+
+			rb_podcast_manager_save_metadata (data->pd,
+							  data->entry);
+		}
+		g_idle_add ((GSourceFunc)end_job, data);
+	}
+}
+
+static gpointer
+podcast_download_thread (RBPodcastManagerInfo *data)
+{
+	GError *error = NULL;
+	char buf[8192];
+	gssize n_read;
+	gssize n_written;
+	gsize downloaded;
+	
+	/* open remote file */
+	data->in_stream = g_file_read (data->source, data->cancel, &error);
+	if (error != NULL) {
+		download_error (data, error);
+		g_error_free (error);
+		return NULL;
+	}
+
+	/* if we have an offset to download from, try the seek
+	 * before anything else.  if we can't seek, we'll have to
+	 * grab the whole thing.
+	 */
+	downloaded = 0;
+	if (data->download_offset != 0) {
+		g_seekable_seek (G_SEEKABLE (data->in_stream),
+				 data->download_offset,
+				 G_SEEK_SET,
+				 data->cancel,
+				 &error);
+		if (error == NULL) {
+			/* ok, now we can open the output file for appending */
+			rb_debug ("seek to offset %" G_GUINT64_FORMAT " successful", data->download_offset);
+			data->out_stream = g_file_append_to (data->destination,
+							     G_FILE_CREATE_NONE,
+							     data->cancel,
+							     &error);
+			downloaded = data->download_offset;
+		} else if (error->domain == G_IO_ERROR &&
+			   error->code == G_IO_ERROR_NOT_SUPPORTED) {
+			/* can't seek, download the whole thing */
+			rb_debug ("seeking failed: %s", error->message);
+			g_clear_error (&error);
+		}
+	}
+	if (error != NULL) {
+		download_error (data, error);
+		g_error_free (error);
+		return NULL;
+	}
+
+	/* open local file */
+	if (data->out_stream == NULL) {
+		data->out_stream = g_file_create (data->destination,
+						  G_FILE_CREATE_NONE,
+						  data->cancel,
+						  &error);
+		if (error != NULL) {
+			download_error (data, error);
+			g_error_free (error);
+			return NULL;
+		}
+	}
+	
+	/* set the downloaded location for the episode */
+	if (rhythmdb_entry_get_string (data->entry, RHYTHMDB_PROP_MOUNTPOINT) == NULL) {
+		GValue val = {0,};
+		char *uri = g_file_get_uri (data->destination);
+
+		g_value_init (&val, G_TYPE_STRING);
+		g_value_set_string (&val, uri);
+		rhythmdb_entry_set (data->pd->priv->db, data->entry, RHYTHMDB_PROP_MOUNTPOINT, &val);
+		g_value_unset (&val);
+
+		rhythmdb_commit (data->pd->priv->db);
+		g_free (uri);
+	}
+
+	/* loop, copying from input stream to output stream */
+	while (TRUE) {
+		char *p;
+		n_read = g_input_stream_read (G_INPUT_STREAM (data->in_stream),
+					      buf, sizeof (buf),
+					      data->cancel,
+					      &error);
+		if (n_read < 1) {
+			break;
+		}
+
+		p = buf;
+		while (n_read > 0) {
+			n_written = g_output_stream_write (G_OUTPUT_STREAM (data->out_stream),
+							   p, n_read,
+							   data->cancel,
+							   &error);
+			if (n_written == -1) {
+				break;
+			}
+			p += n_written;
+			n_read -= n_written;
+			downloaded += n_written;
+		}
+
+		download_progress (data, downloaded, data->download_size, FALSE);
+	}
+
+	if (error != NULL) {
+		download_error (data, error);
+	} else {
+		download_progress (data, downloaded, data->download_size, TRUE);
+	}
+
+	/* close everything */
+	g_input_stream_close (G_INPUT_STREAM (data->in_stream), data->cancel, NULL);
+	/* probably should actually care about this.. */
+	g_output_stream_close (G_OUTPUT_STREAM (data->out_stream), data->cancel, NULL);
+
+	return NULL;
 }
 
 static gboolean
@@ -1329,11 +1480,7 @@
 
 	/* is this the active download? */
 	if (data == data->pd->priv->active_download) {
-		data->cancelled = TRUE;
-		if (data->read_handle != NULL) {
-			gnome_vfs_async_cancel (data->read_handle);
-			data->read_handle = NULL;
-		}
+		g_cancellable_cancel (data->cancel);
 
 		/* download data will be cleaned up after next progress callback */
 	} else {
@@ -1343,123 +1490,6 @@
 	}
 }
 
-static guint
-download_progress_cb (GnomeVFSXferProgressInfo *info, gpointer cb_data)
-{
-	GValue val = {0, };
-	RBPodcastManagerInfo *data = (RBPodcastManagerInfo *) cb_data;
-
-	if (data == NULL) {
-		return GNOME_VFS_XFER_ERROR_ACTION_ABORT;
-	}
-
-	if (info->status != GNOME_VFS_XFER_PROGRESS_STATUS_OK ||
-	    ((info->phase == GNOME_VFS_XFER_PHASE_COMPLETED) && (info->file_size == 0))) {
-
-		rb_debug ("error downloading %s",
-			  rhythmdb_entry_get_string (data->entry, RHYTHMDB_PROP_LOCATION));
-
-		g_value_init (&val, G_TYPE_ULONG);
-		g_value_set_ulong (&val, RHYTHMDB_PODCAST_STATUS_ERROR);
-		rhythmdb_entry_set (data->pd->priv->db, data->entry, RHYTHMDB_PROP_STATUS, &val);
-		g_value_unset (&val);
-
-		if (info->vfs_status != GNOME_VFS_OK) {
-			g_value_init (&val, G_TYPE_STRING);
-			g_value_set_string (&val, gnome_vfs_result_to_string (info->vfs_status));
-			rhythmdb_entry_set (data->pd->priv->db, data->entry, RHYTHMDB_PROP_PLAYBACK_ERROR, &val);
-			g_value_unset (&val);
-		}
-
-		rhythmdb_commit (data->pd->priv->db);
-		g_idle_add ((GSourceFunc)end_job, data);
-		return GNOME_VFS_XFER_ERROR_ACTION_ABORT;
-	}
-
-	if (rhythmdb_entry_get_string (data->entry, RHYTHMDB_PROP_MOUNTPOINT) == NULL) {
-		char *uri = gnome_vfs_uri_to_string (data->write_uri, GNOME_VFS_URI_HIDE_NONE);
-		char *canon_uri = rb_canonicalise_uri (uri);
-		g_free (uri);
-
-		g_value_init (&val, G_TYPE_STRING);
-		g_value_set_string (&val, canon_uri);
-		rhythmdb_entry_set (data->pd->priv->db, data->entry, RHYTHMDB_PROP_MOUNTPOINT, &val);
-		g_value_unset (&val);
-
-		rhythmdb_commit (data->pd->priv->db);
-		g_free (canon_uri);
-	}
-
-	if (info->phase == GNOME_VFS_XFER_PHASE_COMPLETED) {
-		if (data->cancelled == FALSE) {
-			char *uri;
-			char *canon_uri;
-
-			uri = gnome_vfs_uri_to_string (data->write_uri,
-						       GNOME_VFS_URI_HIDE_NONE);
-			canon_uri = rb_canonicalise_uri (uri);
-			g_free (uri);
-			rb_debug ("download of %s completed", canon_uri);
-
-			g_value_init (&val, G_TYPE_UINT64);
-			g_value_set_uint64 (&val, info->file_size);
-			rhythmdb_entry_set (data->pd->priv->db, data->entry, RHYTHMDB_PROP_FILE_SIZE, &val);
-			g_value_unset (&val);
-
-			g_value_init (&val, G_TYPE_ULONG);
-			g_value_set_ulong (&val, RHYTHMDB_PODCAST_STATUS_COMPLETE);
-			rhythmdb_entry_set (data->pd->priv->db, data->entry, RHYTHMDB_PROP_STATUS, &val);
-			g_value_unset (&val);
-
-			rb_podcast_manager_save_metadata (data->pd,
-							  data->entry,
-							  canon_uri);
-			g_free (canon_uri);
-		}
-		g_idle_add ((GSourceFunc)end_job, data);
-		return GNOME_VFS_XFER_ERROR_ACTION_SKIP;
-	}
-
-	return 1;
-}
-
-static guint
-download_progress_update_cb (GnomeVFSAsyncHandle *handle, GnomeVFSXferProgressInfo *info, gpointer cb_data)
-{
-	RBPodcastManagerInfo *data = (RBPodcastManagerInfo *) cb_data;
-
-	if (data == NULL) {
-		return GNOME_VFS_XFER_ERROR_ACTION_ABORT;
-	}
-
-	if ((info->phase == GNOME_VFS_XFER_PHASE_COPYING) &&
-	    (data->entry != NULL)) {
-		guint local_progress = 0;
-
-		if (info->file_size > 0)
-			local_progress = (gint) 100 * info->total_bytes_copied / info->file_size;
-
-		if (local_progress != data->progress) {
-			GValue val = {0,};
-
-			GDK_THREADS_ENTER ();
-
-			g_value_init (&val, G_TYPE_ULONG);
-			g_value_set_ulong (&val, local_progress);
-			rhythmdb_entry_set (data->pd->priv->db, data->entry, RHYTHMDB_PROP_STATUS, &val);
-			g_value_unset (&val);
-
-			g_signal_emit (data->pd, rb_podcast_manager_signals[STATUS_CHANGED],
-				       0, data->entry, local_progress);
-
-			GDK_THREADS_LEAVE ();
-
-			data->progress = local_progress;
-		}
-	}
-
-	return GNOME_VFS_XFER_ERROR_ACTION_SKIP;
-}
 
 void
 rb_podcast_manager_unsubscribe_feed (RhythmDB *db, const char *url)
@@ -1502,7 +1532,8 @@
 		const char *file_name;
 		const char *dir_name;
 		const char *conf_dir_name;
-		GnomeVFSResult result;
+		GFile *file;
+		GError *error = NULL;
 
 		rb_debug ("Handling entry deleted");
 
@@ -1516,20 +1547,30 @@
 			return;
 		}
 
-		result = gnome_vfs_unlink (file_name);
-		if (result != GNOME_VFS_OK) {
-			rb_debug ("Removing episode failed: %s", gnome_vfs_result_to_string (result));
-			return;
-		}
+		file = g_file_new_for_uri (file_name);
+		g_file_delete (file, NULL, &error);
+		if (error != NULL) {
+			rb_debug ("Removing episode failed: %s", error->message);
+			g_clear_error (&error);
+		} else {
+			/* try to remove the directory
+			 * (will only work once it's empty)
+			 */
+			rb_debug ("removing dir");
+			conf_dir_name = eel_gconf_get_string (CONF_STATE_PODCAST_DOWNLOAD_DIR);
 
-		/* remove dir */
-		rb_debug ("removing dir");
-		conf_dir_name = eel_gconf_get_string (CONF_STATE_PODCAST_DOWNLOAD_DIR);
-
-		dir_name = g_build_filename (conf_dir_name,
-					     rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_ALBUM),
-					     NULL);
-		gnome_vfs_remove_directory (dir_name);
+			dir_name = g_build_filename (conf_dir_name,
+						     rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_ALBUM),
+						     NULL);
+			file = g_file_new_for_uri (conf_dir_name);
+			g_file_delete (file, NULL, &error);
+			if (error != NULL) {
+				rb_debug ("couldn't remove podcast feed directory: %s",
+					  error->message);
+				g_clear_error (&error);
+			}
+		}
+		g_object_unref (file);
 
 	} else if (type == RHYTHMDB_ENTRY_TYPE_PODCAST_FEED) {
 		GtkTreeModel *query_model;

Modified: trunk/podcast/rb-podcast-parse.c
==============================================================================
--- trunk/podcast/rb-podcast-parse.c	(original)
+++ trunk/podcast/rb-podcast-parse.c	Tue Jul 29 13:17:53 2008
@@ -33,8 +33,8 @@
 #include <string.h>
 
 #include <totem-pl-parser.h>
-#include <libgnomevfs/gnome-vfs.h>
 #include <glib/gi18n.h>
+#include <gio/gio.h>
 #include <glib.h>
 #include <glib/gprintf.h>
 
@@ -141,8 +141,8 @@
 			    gboolean existing_feed,
 			    GError **error)
 {
-	GnomeVFSResult result;
-	GnomeVFSFileInfo *info;
+	GFile *file;
+	GFileInfo *fileinfo;
 	TotemPlParser *plparser;
 
 	data->url = g_strdup (file_name);
@@ -154,37 +154,46 @@
 		rb_debug ("not checking mime type for %s (should be %s file)", file_name,
 			  data->is_opml ? "OPML" : "Podcast");
 	} else {
+		GError *ferror = NULL;
+		char *content_type;
+
 		rb_debug ("checking mime type for %s", file_name);
-		info = gnome_vfs_file_info_new ();
 
-		result = gnome_vfs_get_file_info (file_name, info, GNOME_VFS_FILE_INFO_DEFAULT);
-		if (result != GNOME_VFS_OK) {
+		file = g_file_new_for_uri (file_name);
+		fileinfo = g_file_query_info (file, G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE, 0, NULL, &ferror);
+		if (ferror != NULL) {
 			g_set_error (error,
 				     RB_PODCAST_PARSE_ERROR,
 				     RB_PODCAST_PARSE_ERROR_FILE_INFO,
 				     _("Unable to check file type: %s"),
-				     gnome_vfs_result_to_string (result));
-			gnome_vfs_file_info_unref (info);
+				     ferror->message);
+			g_object_unref (file);
+			g_clear_error (&ferror);
 			return FALSE;
 		}
 
-		if (info->mime_type != NULL
-		    && strstr (info->mime_type, "html") == NULL
-		    && strstr (info->mime_type, "xml") == NULL
-		    && strstr (info->mime_type, "rss") == NULL
-		    && strstr (info->mime_type, "opml") == NULL) {
+		content_type = g_file_info_get_attribute_as_string (fileinfo, G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE);
+		g_object_unref (file);
+		g_object_unref (fileinfo);
+
+		if (content_type != NULL
+		    && strstr (content_type, "html") == NULL
+		    && strstr (content_type, "xml") == NULL
+		    && strstr (content_type, "rss") == NULL
+		    && strstr (content_type, "opml") == NULL) {
 			g_set_error (error,
 				     RB_PODCAST_PARSE_ERROR,
 				     RB_PODCAST_PARSE_ERROR_MIME_TYPE,
 				     _("Unexpected file type: %s"),
-				     info->mime_type);
-			gnome_vfs_file_info_unref (info);
+				     content_type);
+			g_free (content_type);
 			return FALSE;
-		} else if (info->mime_type != NULL
-			   && strstr (info->mime_type, "opml") != NULL) {
+		} else if (content_type != NULL
+			   && strstr (content_type, "opml") != NULL) {
 			data->is_opml = TRUE;
 		}
-		gnome_vfs_file_info_unref (info);
+
+		g_free (content_type);
 	}
 
 	plparser = totem_pl_parser_new ();

Modified: trunk/podcast/rb-podcast-properties-dialog.c
==============================================================================
--- trunk/podcast/rb-podcast-properties-dialog.c	(original)
+++ trunk/podcast/rb-podcast-properties-dialog.c	Tue Jul 29 13:17:53 2008
@@ -36,7 +36,7 @@
 #include <glib/gi18n.h>
 #include <gtk/gtk.h>
 #include <glade/glade.h>
-#include <libgnomevfs/gnome-vfs.h>
+#include <glib/gurifuncs.h>
 
 #include "rb-podcast-properties-dialog.h"
 #include "rb-file-helpers.h"
@@ -403,7 +403,7 @@
 	char *display;
 
 	location = rhythmdb_entry_get_string (dialog->priv->current_entry, RHYTHMDB_PROP_LOCATION);
-	display = gnome_vfs_format_uri_for_display (location);
+	display = g_uri_unescape_string (location, G_URI_RESERVED_CHARS_ALLOWED_IN_PATH);
 	gtk_label_set_text (GTK_LABEL (dialog->priv->location), display);
 	g_free (display);
 }
@@ -416,7 +416,7 @@
 	location = rhythmdb_entry_get_string (dialog->priv->current_entry, RHYTHMDB_PROP_MOUNTPOINT);
 	if (location != NULL && location[0] != '\0') {
 		char *display;
-		display = gnome_vfs_format_uri_for_display (location);
+		display = g_uri_unescape_string (location, G_URI_RESERVED_CHARS_ALLOWED_IN_PATH);
 		gtk_label_set_text (GTK_LABEL (dialog->priv->download_location), display);
 		g_free (display);
 	} else {

Modified: trunk/podcast/test-podcast-parse.c
==============================================================================
--- trunk/podcast/test-podcast-parse.c	(original)
+++ trunk/podcast/test-podcast-parse.c	Tue Jul 29 13:17:53 2008
@@ -31,8 +31,6 @@
 #include <glib.h>
 #include <glib/gi18n.h>
 
-#include <libgnomevfs/gnome-vfs.h>
-
 #include "rb-podcast-parse.h"
 
 #include <string.h>
@@ -79,8 +77,6 @@
 	bindtextdomain (GETTEXT_PACKAGE, GNOMELOCALEDIR);
 	bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
 
-	gnome_vfs_init ();
-
 	if (argv[2] != NULL && strcmp (argv[2], "--debug") == 0) {
 		debug = TRUE;
 	}

Modified: trunk/remote/dbus/Makefile.am
==============================================================================
--- trunk/remote/dbus/Makefile.am	(original)
+++ trunk/remote/dbus/Makefile.am	Tue Jul 29 13:17:53 2008
@@ -4,8 +4,8 @@
 rhythmbox_client_SOURCES = rb-client.c
 rhythmbox_client_LDADD =				\
 	$(top_builddir)/lib/librb.la			\
-	$(DBUS_LIBS)					\
-	$(RB_CLIENT_LIBS)
+	$(RB_CLIENT_LIBS)				\
+	$(DBUS_LIBS)
 
 INCLUDES = 						\
         -DGNOMELOCALEDIR=\""$(datadir)/locale"\"        \

Modified: trunk/remote/dbus/rb-client.c
==============================================================================
--- trunk/remote/dbus/rb-client.c	(original)
+++ trunk/remote/dbus/rb-client.c	Tue Jul 29 13:17:53 2008
@@ -34,7 +34,7 @@
 #include <glib/gi18n.h>
 #include <glib-object.h>
 #include <dbus/dbus-glib.h>
-#include <libgnomevfs/gnome-vfs-utils.h>
+#include <gio/gio.h>
 
 #include "rb-debug.h"
 #include "rb-shell-binding.h"
@@ -101,9 +101,7 @@
 	{ "print-playing", 0, 0, G_OPTION_ARG_NONE, &print_playing, N_("Print the title and artist of the playing song"), NULL },
 	{ "print-playing-format", 0, 0, G_OPTION_ARG_STRING, &print_playing_format, N_("Print formatted details of the song"), NULL },
 
-#if GLIB_CHECK_VERSION(2,12,0)
 	{ "set-volume", 0, 0, G_OPTION_ARG_DOUBLE, &set_volume, N_("Set the playback volume"), NULL },
-#endif
 	{ "volume-up", 0, 0, G_OPTION_ARG_NONE, &volume_up, N_("Increase the playback volume"), NULL },
 	{ "volume-down", 0, 0, G_OPTION_ARG_NONE, &volume_down, N_("Decrease the playback volume"), NULL },
 	{ "print-volume", 0, 0, G_OPTION_ARG_NONE, &print_volume, N_("Print the current playback volume"), NULL },
@@ -566,35 +564,45 @@
 	if (other_stuff) {
 		int i;
 		for (i = 0; other_stuff[i] != NULL; i++) {
-			char *uri = gnome_vfs_make_uri_from_shell_arg (other_stuff[i]);
-			if (uri == NULL) {
+			GFile *file;
+			char *fileuri;
+
+			file = g_file_new_for_commandline_arg (other_stuff[i]);
+			fileuri = g_file_get_uri (file);
+			if (fileuri == NULL) {
 				g_warning ("couldn't convert \"%s\" to a URI", other_stuff[i]);
 				continue;
 			}
 
 			if (enqueue) {
-				rb_debug ("enqueueing %s", uri);
-				org_gnome_Rhythmbox_Shell_add_to_queue (shell_proxy, uri, &error);
+				rb_debug ("enqueueing %s", fileuri);
+				org_gnome_Rhythmbox_Shell_add_to_queue (shell_proxy, fileuri, &error);
 			} else {
-				rb_debug ("importing %s", uri);
-				org_gnome_Rhythmbox_Shell_load_ur_i (shell_proxy, uri, FALSE, &error);
+				rb_debug ("importing %s", fileuri);
+				org_gnome_Rhythmbox_Shell_load_ur_i (shell_proxy, fileuri, FALSE, &error);
 			}
 			annoy (&error);
-			g_free (uri);
+			g_free (fileuri);
+			g_object_unref (file);
 		}
 	}
 
 	/* play uri */
 	if (play_uri) {
-		char *uri = gnome_vfs_make_uri_from_shell_arg (play_uri);
-		if (uri == NULL) {
+		GFile *file;
+		char *fileuri;
+
+		file = g_file_new_for_commandline_arg (play_uri);
+		fileuri = g_file_get_uri (file);
+		if (fileuri == NULL) {
 			g_warning ("couldn't convert \"%s\" to a URI", play_uri);
 		} else {
-			rb_debug ("loading and playing %s", uri);
-			org_gnome_Rhythmbox_Shell_load_ur_i (shell_proxy, uri, TRUE, &error);
+			rb_debug ("loading and playing %s", fileuri);
+			org_gnome_Rhythmbox_Shell_load_ur_i (shell_proxy, fileuri, TRUE, &error);
 			annoy (&error);
 		}
-		g_free (uri);
+		g_free (fileuri);
+		g_object_unref (file);
 	}
 
 	/* 5. play/pause/stop */
@@ -615,13 +623,10 @@
 	}
 
 	/* 6. get/set volume, mute/unmute */
-#if GLIB_CHECK_VERSION(2,12,0)
 	if (set_volume > -0.01) {
 		org_gnome_Rhythmbox_Player_set_volume (player_proxy, set_volume, &error);
 		annoy (&error);
-	} else
-#endif
-	if (volume_up || volume_down) {
+	} else if (volume_up || volume_down) {
 		org_gnome_Rhythmbox_Player_set_volume_relative (player_proxy, volume_up ? 0.1 : -0.1, &error);
 		annoy (&error);
 	} else if (unmute || mute) {

Modified: trunk/rhythmdb/Makefile.am
==============================================================================
--- trunk/rhythmdb/Makefile.am	(original)
+++ trunk/rhythmdb/Makefile.am	Tue Jul 29 13:17:53 2008
@@ -3,8 +3,7 @@
 noinst_LTLIBRARIES = librhythmdb.la
 
 librhythmdb_la_LDFLAGS = -export-dynamic
-librhythmdb_la_LIBADD = 				\
-	$(GIO_LIBS)					
+librhythmdb_la_LIBADD =
 
 INCLUDES = 						\
         -DGNOMELOCALEDIR=\""$(datadir)/locale"\"        \
@@ -15,7 +14,6 @@
 	-I$(top_srcdir)/metadata			\
 	-I$(top_builddir)/lib                           \
 	$(RHYTHMBOX_CFLAGS)				\
-	$(GIO_CFLAGS)					\
 	$(NO_STRICT_ALIASING_CFLAGS)
 
 librhythmdb_la_SOURCES =				\

Modified: trunk/rhythmdb/rhythmdb-import-job.c
==============================================================================
--- trunk/rhythmdb/rhythmdb-import-job.c	(original)
+++ trunk/rhythmdb/rhythmdb-import-job.c	Tue Jul 29 13:17:53 2008
@@ -69,7 +69,7 @@
 	GStaticMutex    lock;
 	GSList		*uri_list;
 	gboolean	started;
-	gboolean	cancel;
+	GCancellable    *cancel;
 
 	int		status_changed_id;
 	gboolean	scan_complete;
@@ -163,14 +163,17 @@
 }
 
 static void
-uri_recurse_func (const char *uri, gboolean dir, RhythmDBImportJob *job)
+uri_recurse_func (GFile *file, gboolean dir, RhythmDBImportJob *job)
 {
 	RhythmDBEntry *entry;
+	char *uri;
 
 	if (dir) {
 		return;
 	}
 
+	uri = g_file_get_uri (file);
+
 	/* only add the entry to the map of entries we're waiting for
 	 * if it's not already in the db.
 	 */
@@ -193,6 +196,7 @@
 				     job->priv->entry_type,
 				     job->priv->ignore_type,
 				     job->priv->error_type);
+	g_free (uri);
 }
 
 static gboolean
@@ -219,8 +223,8 @@
 
 		rb_debug ("scanning uri %s", uri);
 		rb_uri_handle_recursively_async (uri,
+						 job->priv->cancel,
 						 (RBUriRecurseFunc) uri_recurse_func,
-						 &job->priv->cancel,
 						 job,
 						 (GDestroyNotify) next_uri);
 
@@ -317,7 +321,7 @@
 rhythmdb_import_job_cancel (RhythmDBImportJob *job)
 {
 	g_static_mutex_lock (&job->priv->lock);
-	job->priv->cancel = TRUE;
+	g_cancellable_cancel (job->priv->cancel);
 	g_static_mutex_unlock (&job->priv->lock);
 }
 
@@ -355,6 +359,8 @@
 
 	g_static_mutex_init (&job->priv->lock);
 	job->priv->outstanding = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
+
+	job->priv->cancel = g_cancellable_new ();
 }
 
 static void
@@ -423,6 +429,11 @@
 		g_object_unref (job->priv->db);
 		job->priv->db = NULL;
 	}
+
+	if (job->priv->cancel != NULL) {
+		g_object_unref (job->priv->cancel);
+		job->priv->cancel = NULL;
+	}
 	
 	G_OBJECT_CLASS (rhythmdb_import_job_parent_class)->dispose (object);
 }

Modified: trunk/rhythmdb/rhythmdb-monitor.c
==============================================================================
--- trunk/rhythmdb/rhythmdb-monitor.c	(original)
+++ trunk/rhythmdb/rhythmdb-monitor.c	Tue Jul 29 13:17:53 2008
@@ -34,7 +34,7 @@
 #include <glib-object.h>
 #include <glib/gi18n.h>
 #include <gconf/gconf-client.h>
-#include <libgnomevfs/gnome-vfs-volume-monitor.h>
+#include <gio/gio.h>
 
 #include "rb-debug.h"
 #include "rb-util.h"
@@ -46,36 +46,42 @@
 
 #define RHYTHMDB_FILE_MODIFY_PROCESS_TIME 2
 
-static void rhythmdb_volume_mounted_cb (GnomeVFSVolumeMonitor *monitor,
- 					GnomeVFSVolume *volume,
- 					gpointer data);
-static void rhythmdb_volume_unmounted_cb (GnomeVFSVolumeMonitor *monitor,
- 					  GnomeVFSVolume *volume,
- 					  gpointer data);
+static void rhythmdb_directory_change_cb (GFileMonitor *monitor,
+					  GFile *file,
+					  GFile *other_file,
+					  GFileMonitorEvent event_type,
+					  RhythmDB *db);
+static void rhythmdb_mount_added_cb (GVolumeMonitor *monitor,
+				     GMount *mount,
+				     RhythmDB *db);
+static void rhythmdb_mount_removed_cb (GVolumeMonitor *monitor,
+				       GMount *mount,
+				       RhythmDB *db);
 
 void
 rhythmdb_init_monitoring (RhythmDB *db)
 {
-	db->priv->monitored_directories = g_hash_table_new_full (g_str_hash, g_str_equal,
-								 (GDestroyNotify) g_free,
-								 (GDestroyNotify)gnome_vfs_monitor_cancel);
+	db->priv->monitored_directories = g_hash_table_new_full (g_file_hash, (GEqualFunc) g_file_equal,
+								 (GDestroyNotify) g_object_unref,
+								 (GDestroyNotify)g_file_monitor_cancel);
 
 	db->priv->changed_files = g_hash_table_new_full (rb_refstring_hash, rb_refstring_equal,
 							 (GDestroyNotify) rb_refstring_unref,
 							 NULL);
 
-	g_signal_connect (G_OBJECT (gnome_vfs_get_volume_monitor ()),
-			  "volume-mounted",
-			  G_CALLBACK (rhythmdb_volume_mounted_cb),
+	db->priv->volume_monitor = g_volume_monitor_get ();
+	g_signal_connect (G_OBJECT (db->priv->volume_monitor),
+			  "mount-added",
+			  G_CALLBACK (rhythmdb_mount_added_cb),
 			  db);
 
-	g_signal_connect (G_OBJECT (gnome_vfs_get_volume_monitor ()),
-			  "volume-pre-unmount",
-			  G_CALLBACK (rhythmdb_volume_unmounted_cb),
+	g_signal_connect (G_OBJECT (db->priv->volume_monitor),
+			  "mount-removed",
+			  G_CALLBACK (rhythmdb_mount_removed_cb),
 			  db);
-	g_signal_connect (G_OBJECT (gnome_vfs_get_volume_monitor ()),
-			  "volume-unmounted",
-			  G_CALLBACK (rhythmdb_volume_unmounted_cb),
+	g_signal_connect (G_OBJECT (db->priv->volume_monitor),
+			  "mount-pre-unmount",
+			  G_CALLBACK (rhythmdb_mount_removed_cb),
 			  db);
 }
 
@@ -86,6 +92,11 @@
 		g_source_remove (db->priv->changed_files_id);
 		db->priv->changed_files_id = 0;
 	}
+
+	if (db->priv->volume_monitor != NULL) {
+		g_object_unref (db->priv->volume_monitor);
+		db->priv->volume_monitor = NULL;
+	}
 }
 
 void
@@ -106,6 +117,33 @@
 }
 
 static void
+actually_add_monitor (RhythmDB *db, GFile *directory, GError **error)
+{
+	GFileMonitor *monitor;
+	char *uri;
+
+	if (directory == NULL) {
+		return;
+	}
+
+	if (g_hash_table_lookup (db->priv->monitored_directories, directory)) {
+		return;
+	}
+
+	uri = g_file_get_uri (directory);
+	monitor = g_file_monitor_directory (directory, 0, db->priv->exiting, error);
+	if (monitor != NULL) {
+		g_signal_connect_object (G_OBJECT (monitor),
+					 "changed",
+					 G_CALLBACK (rhythmdb_directory_change_cb),
+					 db, 0);
+		g_hash_table_insert (db->priv->monitored_directories,
+				     g_object_ref (directory),
+				     monitor);
+	}
+}
+
+static void
 monitor_entry_file (RhythmDBEntry *entry, RhythmDB *db)
 {
 	if (entry->type == RHYTHMDB_ENTRY_TYPE_SONG) {
@@ -114,7 +152,7 @@
 
 		loc = rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_LOCATION);
 
-		/* don't add add monitor if it's in the library path*/
+		/* don't add add monitor if it's in the library path */
 		for (l = db->priv->library_locations; l != NULL; l = g_slist_next (l)) {
 			if (g_str_has_prefix (loc, (const char*)l->data))
 				return;
@@ -125,12 +163,23 @@
 }
 
 static gboolean
-monitor_subdirectory (const char *uri, gboolean dir, RhythmDB *db)
+monitor_subdirectory (GFile *file, gboolean dir, RhythmDB *db)
 {
-	if (dir)
-		rhythmdb_monitor_uri_path (db, uri, NULL);
-	else
-		rhythmdb_add_uri (db, uri);
+	char *uri;
+
+	uri = g_file_get_uri (file);
+	if (dir) {
+		actually_add_monitor (db, file, NULL);
+	} else {
+		/* add the file to the database if it's not already there */
+		RhythmDBEntry *entry;
+
+		entry = rhythmdb_entry_lookup_by_location (db, uri);
+		if (entry == NULL) {
+			rhythmdb_add_uri (db, uri);
+		}
+	}
+	g_free (uri);
 	return TRUE;	
 }
 
@@ -145,8 +194,11 @@
 
 	rb_debug ("beginning monitor of the library directory %s", uri);
 	rhythmdb_monitor_uri_path (db, uri, NULL);
-	rb_uri_handle_recursively_async (uri, (RBUriRecurseFunc) monitor_subdirectory, NULL,
-					 g_object_ref (db), (GDestroyNotify)g_object_unref);
+	rb_uri_handle_recursively_async (uri,
+					 NULL,
+					 (RBUriRecurseFunc) monitor_subdirectory,
+					 g_object_ref (db),
+					 (GDestroyNotify)g_object_unref);
 }
 
 static gboolean
@@ -158,7 +210,7 @@
 	g_get_current_time (&time);
 	if (time.tv_sec >= time_sec + RHYTHMDB_FILE_MODIFY_PROCESS_TIME) {
 		/* process and remove from table */
-		RhythmDBEvent *event = g_new0 (RhythmDBEvent, 1);
+		RhythmDBEvent *event = g_slice_new0 (RhythmDBEvent);
 		event->db = db;
 		event->type = RHYTHMDB_EVENT_FILE_CREATED_OR_MODIFIED;
 		event->uri = rb_refstring_ref (uri);
@@ -219,20 +271,18 @@
 }
 
 static void
-rhythmdb_directory_change_cb (GnomeVFSMonitorHandle *handle,
-			      const char *monitor_uri,
-			      const char *info_uri,
-			      GnomeVFSMonitorEventType vfsevent,
+rhythmdb_directory_change_cb (GFileMonitor *monitor,
+			      GFile *file,
+			      GFile *other_file,
+			      GFileMonitorEvent event_type,
 			      RhythmDB *db)
 {
 	char *canon_uri;
+	canon_uri = g_file_get_uri (file);
+	rb_debug ("directory event %d for %s", event_type, canon_uri);
 
-	canon_uri = rb_canonicalise_uri (info_uri);
-	rb_debug ("directory event %d for %s: %s", (int) vfsevent,
-		  monitor_uri, canon_uri);
-
-	switch (vfsevent) {
-        case GNOME_VFS_MONITOR_EVENT_CREATED:
+	switch (event_type) {
+        case G_FILE_MONITOR_EVENT_CREATED:
 		{
 			GSList *cur;
 			gboolean in_library = FALSE;
@@ -257,29 +307,32 @@
 
 		/* process directories immediately */
 		if (rb_uri_is_directory (canon_uri)) {
-			rhythmdb_monitor_uri_path (db, canon_uri, NULL);
+			actually_add_monitor (db, file, NULL);
 			rhythmdb_add_uri (db, canon_uri);
 		} else {
 			add_changed_file (db, canon_uri);
 		}
 		break;
-	case GNOME_VFS_MONITOR_EVENT_CHANGED:
-        case GNOME_VFS_MONITOR_EVENT_METADATA_CHANGED:
+	case G_FILE_MONITOR_EVENT_CHANGED:
+        case G_FILE_MONITOR_EVENT_ATTRIBUTE_CHANGED:
 		if (rhythmdb_entry_lookup_by_location (db, canon_uri)) {
 			add_changed_file (db, canon_uri);
 		}
 		break;
-	case GNOME_VFS_MONITOR_EVENT_DELETED:
+	case G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT:
+		/* hmm.. */
+		break;
+	case G_FILE_MONITOR_EVENT_DELETED:
 		if (rhythmdb_entry_lookup_by_location (db, canon_uri)) {
-			RhythmDBEvent *event = g_new0 (RhythmDBEvent, 1);
+			RhythmDBEvent *event = g_slice_new0 (RhythmDBEvent);
 			event->db = db;
 			event->type = RHYTHMDB_EVENT_FILE_DELETED;
 			event->uri = rb_refstring_new (canon_uri);
 			g_async_queue_push (db->priv->event_queue, event);
 		}
 		break;
-	case GNOME_VFS_MONITOR_EVENT_STARTEXECUTING:
-	case GNOME_VFS_MONITOR_EVENT_STOPEXECUTING:
+	case G_FILE_MONITOR_EVENT_PRE_UNMOUNT:
+	case G_FILE_MONITOR_EVENT_UNMOUNTED:
 		break;
 	}
 
@@ -289,54 +342,27 @@
 void
 rhythmdb_monitor_uri_path (RhythmDB *db, const char *uri, GError **error)
 {
-	char *directory;
-	GnomeVFSResult vfsresult;
-	GnomeVFSMonitorHandle *handle;
+	GFile *directory;
 
 	if (rb_uri_is_directory (uri)) {
+		char *dir;
 		if (g_str_has_suffix(uri, G_DIR_SEPARATOR_S)) {
-			directory = g_strdup (uri);
+			dir = g_strdup (uri);
 		} else {
-			directory = g_strconcat (uri, G_DIR_SEPARATOR_S, NULL);
-		}
-	} else {
-		GnomeVFSURI *vfsuri, *parent;
-
-		vfsuri = gnome_vfs_uri_new (uri);
-		if (vfsuri == NULL) {
-			rb_debug ("failed to monitor %s: couldn't create GnomeVFSURI", uri);
-			return;
+			dir = g_strconcat (uri, G_DIR_SEPARATOR_S, NULL);
 		}
 
-		parent = gnome_vfs_uri_get_parent (vfsuri);
-		directory = gnome_vfs_uri_to_string (parent, GNOME_VFS_URI_HIDE_NONE);
-		gnome_vfs_uri_unref (vfsuri);
-		gnome_vfs_uri_unref (parent);
-	}
+		directory = g_file_new_for_uri (dir);
+		g_free (dir);
+	} else {
+		GFile *file;
 
-	if (directory == NULL || g_hash_table_lookup (db->priv->monitored_directories, directory)) {
-		g_free (directory);
-		return;
+		file = g_file_new_for_uri (uri);
+		directory = g_file_get_parent (file);
+		g_object_unref (file);
 	}
 
-	vfsresult = gnome_vfs_monitor_add (&handle, directory,
-					   GNOME_VFS_MONITOR_DIRECTORY,
-					   (GnomeVFSMonitorCallback) rhythmdb_directory_change_cb,
-					   db);
-	if (vfsresult == GNOME_VFS_OK) {
-		rb_debug ("monitoring: %s", directory);
-		g_hash_table_insert (db->priv->monitored_directories,
-				     directory, handle);
-	} else {
-		g_set_error (error,
-			     RHYTHMDB_ERROR,
-			     RHYTHMDB_ERROR_ACCESS_FAILED,
-			     _("Couldn't monitor %s: %s"),
-			     directory,
-			     gnome_vfs_result_to_string (vfsresult));
-		rb_debug ("failed to monitor %s", directory);
-		g_free (directory);
-	}
+	actually_add_monitor (db, directory, error);
 }
 
 typedef struct
@@ -372,11 +398,11 @@
 			 * then hide any that turn out to be missing.
 			 */
 			rhythmdb_entry_set_visibility (ctxt->db, entry, TRUE);
-			queue_stat_uri (location,
-					ctxt->db,
-					RHYTHMDB_ENTRY_TYPE_SONG,
-					RHYTHMDB_ENTRY_TYPE_IGNORE,
-					RHYTHMDB_ENTRY_TYPE_IMPORT_ERROR);
+			rhythmdb_add_uri_with_types (ctxt->db,
+						     location,
+						     RHYTHMDB_ENTRY_TYPE_SONG,
+						     RHYTHMDB_ENTRY_TYPE_IGNORE,
+						     RHYTHMDB_ENTRY_TYPE_IMPORT_ERROR);
 		} else {
 			GTimeVal time;
 			GValue val = {0, };
@@ -402,45 +428,53 @@
 }
 
 static void
-rhythmdb_volume_mounted_cb (GnomeVFSVolumeMonitor *monitor,
-			    GnomeVFSVolume *volume,
-			    gpointer data)
+rhythmdb_mount_added_cb (GVolumeMonitor *monitor,
+			 GMount *mount,
+			 RhythmDB *db)
 {
 	MountCtxt ctxt;
 	char *mp;
+	GFile *root;
+
+	root = g_mount_get_root (mount);
+	mp = g_file_get_uri (root);
+	g_object_unref (root);
 
-	mp = gnome_vfs_volume_get_activation_uri (volume); 
 	ctxt.mount_point = rb_refstring_new (mp);
 	g_free (mp);
 
-	ctxt.db = RHYTHMDB (data);
+	ctxt.db = db;
 	ctxt.mounted = TRUE;
 	rb_debug ("volume %s mounted", rb_refstring_get (ctxt.mount_point));
-	rhythmdb_entry_foreach (RHYTHMDB (data),
+	rhythmdb_entry_foreach (db,
 				(GFunc)entry_volume_mounted_or_unmounted,
 				&ctxt);
-	rhythmdb_commit (RHYTHMDB (data));
+	rhythmdb_commit (db);
 	rb_refstring_unref (ctxt.mount_point);
 }
 
 static void
-rhythmdb_volume_unmounted_cb (GnomeVFSVolumeMonitor *monitor,
-			      GnomeVFSVolume *volume,
-			      gpointer data)
+rhythmdb_mount_removed_cb (GVolumeMonitor *monitor,
+			   GMount *mount,
+			   RhythmDB *db)
 {
 	MountCtxt ctxt;
 	char *mp;
+	GFile *root;
+
+	root = g_mount_get_root (mount);
+	mp = g_file_get_uri (root);
+	g_object_unref (root);
 
-	mp = gnome_vfs_volume_get_activation_uri (volume); 
 	ctxt.mount_point = rb_refstring_new (mp);
 	g_free (mp);
 
-	ctxt.db = RHYTHMDB (data);
+	ctxt.db = db;
 	ctxt.mounted = FALSE;
 	rb_debug ("volume %s unmounted", rb_refstring_get (ctxt.mount_point));
-	rhythmdb_entry_foreach (RHYTHMDB (data),
+	rhythmdb_entry_foreach (db,
 				(GFunc)entry_volume_mounted_or_unmounted,
 				&ctxt);
-	rhythmdb_commit (RHYTHMDB (data));
+	rhythmdb_commit (db);
 	rb_refstring_unref (ctxt.mount_point);
 }

Modified: trunk/rhythmdb/rhythmdb-private.h
==============================================================================
--- trunk/rhythmdb/rhythmdb-private.h	(original)
+++ trunk/rhythmdb/rhythmdb-private.h	Tue Jul 29 13:17:53 2008
@@ -36,11 +36,6 @@
 #include "rb-refstring.h"
 #include "rb-metadata.h"
 
-#include <libgnomevfs/gnome-vfs-utils.h>
-#include <libgnomevfs/gnome-vfs-file-info.h>
-#include <libgnomevfs/gnome-vfs-ops.h>
-#include <libgnomevfs/gnome-vfs-async-ops.h>
-
 G_BEGIN_DECLS
 
 RhythmDBEntry * rhythmdb_entry_allocate		(RhythmDB *db, RhythmDBEntryType type);
@@ -153,11 +148,11 @@
 	GThreadPool *query_thread_pool;
 
 	GList *stat_list;
-	GHashTable *stat_events;
-	GnomeVFSAsyncHandle *stat_handle;
 	GList *outstanding_stats;
 	GMutex *stat_mutex;
+	gboolean stat_thread_running;
 
+	GVolumeMonitor *volume_monitor;
 	GHashTable *monitored_directories;
 	GHashTable *changed_files;
 	guint library_location_notify_id;
@@ -176,7 +171,7 @@
 	GHashTable *propname_map;
 
 	GMutex *exit_mutex;
-	gboolean exiting;
+	GCancellable *exiting;		/* hrm, name? */
 
 	GCond *saving_condition;
 	GMutex *saving_mutex;
@@ -224,8 +219,7 @@
 	RhythmDB *db;
 
 	/* STAT */
-	GnomeVFSFileInfo *vfsinfo;
-	GnomeVFSAsyncHandle *handle;
+	GFileInfo *file_info;
 	/* LOAD */
 	RBMetaData *metadata;
 	/* QUERY_COMPLETE */
@@ -238,7 +232,6 @@
 } RhythmDBEvent;
 
 /* from rhythmdb.c */
-void queue_stat_uri (const char *uri, RhythmDB *db, RhythmDBEntryType type, RhythmDBEntryType ignore_type, RhythmDBEntryType error_type);
 void rhythmdb_entry_set_visibility (RhythmDB *db, RhythmDBEntry *entry,
 				    gboolean visibility);
 void rhythmdb_entry_set_internal (RhythmDB *db, RhythmDBEntry *entry,

Modified: trunk/rhythmdb/rhythmdb-property-model.c
==============================================================================
--- trunk/rhythmdb/rhythmdb-property-model.c	(original)
+++ trunk/rhythmdb/rhythmdb-property-model.c	Tue Jul 29 13:17:53 2008
@@ -34,7 +34,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <glib/gi18n.h>
-#include <gsequence.h>
+#include <glib/gsequence.h>
 
 #include "rhythmdb-property-model.h"
 #include "rb-debug.h"

Modified: trunk/rhythmdb/rhythmdb-query-model.c
==============================================================================
--- trunk/rhythmdb/rhythmdb-query-model.c	(original)
+++ trunk/rhythmdb/rhythmdb-query-model.c	Tue Jul 29 13:17:53 2008
@@ -35,7 +35,7 @@
 #include <string.h>
 #include <stdio.h>
 #include <math.h>
-#include <gsequence.h>
+#include <glib/gsequence.h>
 
 #include <gtk/gtktreednd.h>
 

Modified: trunk/rhythmdb/rhythmdb-tree.c
==============================================================================
--- trunk/rhythmdb/rhythmdb-tree.c	(original)
+++ trunk/rhythmdb/rhythmdb-tree.c	Tue Jul 29 13:17:53 2008
@@ -72,7 +72,7 @@
 
 static void rhythmdb_tree_finalize (GObject *object);
 
-static gboolean rhythmdb_tree_load (RhythmDB *rdb, gboolean *die, GError **error);
+static gboolean rhythmdb_tree_load (RhythmDB *rdb, GCancellable *cancel, GError **error);
 static void rhythmdb_tree_save (RhythmDB *rdb);
 static void rhythmdb_tree_entry_new (RhythmDB *db, RhythmDBEntry *entry);
 static void rhythmdb_tree_entry_new_internal (RhythmDB *db, RhythmDBEntry *entry);
@@ -117,8 +117,8 @@
 					gpointer data);
 
 /* Update both of those! */
-#define RHYTHMDB_TREE_XML_VERSION "1.4"
-#define RHYTHMDB_TREE_XML_VERSION_INT 140
+#define RHYTHMDB_TREE_XML_VERSION "1.5"
+#define RHYTHMDB_TREE_XML_VERSION_INT 150
 
 static void destroy_tree_property (RhythmDBTreeProperty *prop);
 static RhythmDBTreeProperty *get_or_create_album (RhythmDBTree *db, RhythmDBTreeProperty *artist,
@@ -312,7 +312,7 @@
 {
 	RhythmDBTree *db;
 	xmlParserCtxtPtr xmlctx;
-	gboolean *die;
+	GCancellable *cancel;
 	enum {
 		RHYTHMDB_TREE_PARSER_STATE_START,
 		RHYTHMDB_TREE_PARSER_STATE_RHYTHMDB,
@@ -356,7 +356,7 @@
 				    const char *name,
 				    const char **attrs)
 {
-	if (*ctx->die == TRUE) {
+	if (g_cancellable_is_cancelled (ctx->cancel)) {
 		xmlStopParser (ctx->xmlctx);
 		return;
 	}
@@ -376,6 +376,7 @@
 				if (!strcmp (*attrs, "version")) {
 					const char *version = *(attrs+1);
 
+					rb_debug ("loading database version %s (%d)", version, version_to_int (version));
 					switch (version_to_int (version)) {
 					case 100:
 					case 110:
@@ -385,9 +386,10 @@
 						rb_debug ("reloading all file metadata to get MusicBrainz tags (DB version 1.2)");
 						ctx->reload_all_metadata = TRUE;
 					case 130:
+					case 140:
 						/* Avoid being warned twice for very old DBs */
 						if (ctx->canonicalise_uris == FALSE) {
-							rb_debug ("old version of rhythmdb, performing URI canonicalisation for all entries (DB version 1.3)");
+							rb_debug ("old version of rhythmdb, performing URI canonicalisation for all entries (DB version %s)", version);
 							ctx->canonicalise_uris = TRUE;
 						}
 					case RHYTHMDB_TREE_XML_VERSION_INT:
@@ -483,7 +485,7 @@
 rhythmdb_tree_parser_end_element (struct RhythmDBTreeLoadContext *ctx,
 				  const char *name)
 {
-	if (*ctx->die == TRUE) {
+	if (g_cancellable_is_cancelled (ctx->cancel)) {
 		xmlStopParser (ctx->xmlctx);
 		return;
 	}
@@ -654,7 +656,7 @@
 				 const char *data,
 				 guint len)
 {
-	if (*ctx->die == TRUE) {
+	if (g_cancellable_is_cancelled (ctx->cancel)) {
 		xmlStopParser (ctx->xmlctx);
 		return;
 	}
@@ -677,7 +679,7 @@
 
 static gboolean
 rhythmdb_tree_load (RhythmDB *rdb,
-		    gboolean *die,
+		    GCancellable *cancel,
 		    GError **error)
 {
 	RhythmDBTree *db = RHYTHMDB_TREE (rdb);
@@ -699,7 +701,7 @@
 
 	ctx->state = RHYTHMDB_TREE_PARSER_STATE_START;
 	ctx->db = db;
-	ctx->die = die;
+	ctx->cancel = cancel;
 	ctx->buf = g_string_sized_new (RHYTHMDB_TREE_PARSER_INITIAL_BUFFER_SIZE);
 	ctx->error = &local_error;
 

Modified: trunk/rhythmdb/rhythmdb.c
==============================================================================
--- trunk/rhythmdb/rhythmdb.c	(original)
+++ trunk/rhythmdb/rhythmdb.c	Tue Jul 29 13:17:53 2008
@@ -40,13 +40,11 @@
 #include <glib.h>
 #include <glib-object.h>
 #include <glib/gi18n.h>
+#include <gio/gio.h>
 #include <gobject/gvaluecollector.h>
 #include <gdk/gdk.h>
 #include <gconf/gconf-client.h>
 
-#if defined(HAVE_GIO)
-#include <gio/gio.h>
-#endif
 
 #include "rb-marshal.h"
 #include "rb-file-helpers.h"
@@ -70,6 +68,18 @@
 #define RHYTHMDB_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), RHYTHMDB_TYPE, RhythmDBPrivate))
 G_DEFINE_ABSTRACT_TYPE(RhythmDB, rhythmdb, G_TYPE_OBJECT)
 
+/* file attributes requested in RHYTHMDB_ACTION_STAT and RHYTHMDB_ACTION_LOAD */
+#define RHYTHMDB_FILE_INFO_ATTRIBUTES			\
+	G_FILE_ATTRIBUTE_STANDARD_SIZE ","		\
+	G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME ","	\
+	G_FILE_ATTRIBUTE_STANDARD_TYPE ","		\
+	G_FILE_ATTRIBUTE_TIME_MODIFIED
+
+/* file attributes requested in RHYTHMDB_ACTION_ENUM_DIR */
+#define RHYTHMDB_FILE_CHILD_INFO_ATTRIBUTES		\
+	RHYTHMDB_FILE_INFO_ATTRIBUTES ","		\
+	G_FILE_ATTRIBUTE_STANDARD_NAME
+
 typedef struct
 {
 	RhythmDB *db;
@@ -92,6 +102,7 @@
 	enum {
 		RHYTHMDB_ACTION_STAT,
 		RHYTHMDB_ACTION_LOAD,
+		RHYTHMDB_ACTION_ENUM_DIR,
 		RHYTHMDB_ACTION_SYNC,
 		RHYTHMDB_ACTION_QUIT,
 	} type;
@@ -145,6 +156,13 @@
 						 guint cnxn_id,
 						 GConfEntry *entry,
 						 RhythmDB *db);
+static void rhythmdb_event_free (RhythmDB *db, RhythmDBEvent *event);
+static void rhythmdb_add_to_stat_list (RhythmDB *db,
+				       const char *uri,
+				       RhythmDBEntry *entry,
+				       RhythmDBEntryType type,
+				       RhythmDBEntryType ignore_type,
+				       RhythmDBEntryType error_type);
 
 enum
 {
@@ -169,6 +187,7 @@
 	SAVE_ERROR,
 	READ_ONLY,
 	MISSING_PLUGINS,
+	CREATE_MOUNT_OP,
 	LAST_SIGNAL
 };
 
@@ -330,7 +349,6 @@
 			      1,
 			      G_TYPE_BOOLEAN);
 
-#ifdef HAVE_GSTREAMER_0_10_MISSING_PLUGINS
 	rhythmdb_signals[MISSING_PLUGINS] =
 		g_signal_new ("missing-plugins",
 			      G_OBJECT_CLASS_TYPE (object_class),
@@ -341,7 +359,15 @@
 			      G_TYPE_BOOLEAN,
 			      3,
 			      G_TYPE_STRV, G_TYPE_STRV, G_TYPE_CLOSURE);
-#endif
+	rhythmdb_signals[CREATE_MOUNT_OP] =
+		g_signal_new ("create-mount-op",
+			      G_OBJECT_CLASS_TYPE (object_class),
+			      G_SIGNAL_RUN_LAST,
+			      0,		/* no need for an internal handler */
+			      rb_signal_accumulator_object_handled, NULL,
+			      rb_marshal_OBJECT__VOID,
+			      G_TYPE_MOUNT_OPERATION,
+			      0);
 
 	g_type_class_add_private (klass, sizeof (RhythmDBPrivate));
 }
@@ -521,10 +547,6 @@
 	db->priv->entry_type_mutex = g_mutex_new ();
 	rhythmdb_register_core_entry_types (db);
 
- 	db->priv->stat_events = g_hash_table_new_full (gnome_vfs_uri_hash,
-						       (GEqualFunc) gnome_vfs_uri_equal,
- 						       (GDestroyNotify) gnome_vfs_uri_unref,
- 						       NULL);
  	db->priv->stat_mutex = g_mutex_new ();
 
 	db->priv->change_mutex = g_mutex_new ();
@@ -546,7 +568,7 @@
 	db->priv->saving_mutex = g_mutex_new ();
 
 	db->priv->can_save = TRUE;
-	db->priv->exiting = FALSE;
+	db->priv->exiting = g_cancellable_new ();
 	db->priv->saving = FALSE;
 	db->priv->dirty = FALSE;
 
@@ -564,66 +586,163 @@
 }
 
 static GError *
-make_access_failed_error (const char *uri, GnomeVFSResult result)
+make_access_failed_error (const char *uri, GError *access_error)
 {
 	char *unescaped;
 	char *utf8ised;
 	GError *error;
 
 	/* make sure the URI we put in the error message is valid utf8 */
-	unescaped = gnome_vfs_unescape_string_for_display (uri);
+	unescaped = g_uri_unescape_string (uri, G_URI_RESERVED_CHARS_ALLOWED_IN_PATH);
 	utf8ised = rb_make_valid_utf8 (unescaped, '?');
 
 	error = g_error_new (RHYTHMDB_ERROR,
 			     RHYTHMDB_ERROR_ACCESS_FAILED,
 			     _("Couldn't access %s: %s"),
 			     utf8ised,
-			     gnome_vfs_result_to_string (result));
+			     access_error->message);
 	rb_debug ("got error on %s: %s", uri, error->message);
 	g_free (unescaped);
 	g_free (utf8ised);
 	return error;
 }
 
+typedef struct {
+	RhythmDBEvent *event;
+	GMutex *mutex;
+	GCond *cond;
+	GError **error;
+} RhythmDBStatThreadMountData;
+
 static void
-rhythmdb_execute_multi_stat_info_cb (GnomeVFSAsyncHandle *handle,
-				     GList *results,
-				     /* GnomeVFSGetFileInfoResult* items */
-				     RhythmDB *db)
+stat_thread_mount_done_cb (GObject *source, GAsyncResult *result, RhythmDBStatThreadMountData *data)
 {
-	g_mutex_lock (db->priv->stat_mutex);
-	while (results != NULL) {
-		GnomeVFSGetFileInfoResult *info_result = results->data;
-		RhythmDBEvent *event;
-
-		event = g_hash_table_lookup (db->priv->stat_events, info_result->uri);
-		if (event == NULL) {
-			char *uri_string;
-			uri_string = gnome_vfs_uri_to_string (info_result->uri, GNOME_VFS_URI_HIDE_NONE);
-			rb_debug ("ignoring unexpected uri in gnome_vfs_async_get_file_info response: %s",
-				  uri_string);
-			g_free (uri_string);
-			results = results->next;
+	g_mutex_lock (data->mutex);
+	g_file_mount_enclosing_volume_finish (G_FILE (source), result, data->error);
+
+	g_cond_signal (data->cond);
+	g_mutex_unlock (data->mutex);
+}
+
+typedef struct {
+	RhythmDB *db;
+	GList *stat_list;
+} RhythmDBStatThreadData;
+
+static gpointer
+stat_thread_main (RhythmDBStatThreadData *data)
+{
+	GList *i;
+	GError *error = NULL;
+	RhythmDBEvent *result;
+	int count = 0;
+
+	rb_debug ("entering stat thread: %d to process", g_list_length (data->stat_list));
+	for (i = data->stat_list; i != NULL; i = i->next) {
+		RhythmDBEvent *event = (RhythmDBEvent *)i->data;
+		GFile *file;
+
+		/* if we've been cancelled, just free the event.  this will
+		 * clean up the list and then we'll exit the thread.
+		 */
+		if (g_cancellable_is_cancelled (data->db->priv->exiting)) {
+			rhythmdb_event_free (data->db, event);
+			count = 0;
 			continue;
 		}
-		g_hash_table_remove (db->priv->stat_events, info_result->uri);
 
-		if (info_result->result == GNOME_VFS_OK) {
-			event->vfsinfo = gnome_vfs_file_info_dup (info_result->file_info);
-		} else {
-			event->error = make_access_failed_error (rb_refstring_get (event->real_uri),
-								 info_result->result);
-			event->vfsinfo = NULL;
+		if (count > 0 && count % 1000 == 0) {
+			rb_debug ("%d file info queries done", count);
 		}
-		g_async_queue_push (db->priv->event_queue, event);
 
-		results = results->next;
+		file = g_file_new_for_uri (rb_refstring_get (event->uri));
+		event->real_uri = rb_refstring_ref (event->uri);		/* what? */
+		event->file_info = g_file_query_info (file,
+						      G_FILE_ATTRIBUTE_TIME_MODIFIED,	/* anything else? */
+						      G_FILE_QUERY_INFO_NONE,
+						      data->db->priv->exiting,
+						      &error);
+		if (error != NULL) {
+			if (g_error_matches (error,
+					     G_IO_ERROR,
+					     G_IO_ERROR_NOT_MOUNTED)) {
+				GMountOperation *mount_op = NULL;
+
+				rb_debug ("got not-mounted error for %s", rb_refstring_get (event->uri));
+
+				/* check if we've tried and failed to mount this location before */
+
+				g_signal_emit (event->db, rhythmdb_signals[CREATE_MOUNT_OP], 0, &mount_op);
+				if (mount_op != NULL) {
+					RhythmDBStatThreadMountData mount_data;
+
+					mount_data.event = event;
+					mount_data.cond = g_cond_new ();
+					mount_data.mutex = g_mutex_new ();
+					mount_data.error = &error;
+
+					g_mutex_lock (mount_data.mutex);
+
+					g_file_mount_enclosing_volume (file,
+								       G_MOUNT_MOUNT_NONE,
+								       mount_op,
+								       data->db->priv->exiting,
+								       (GAsyncReadyCallback) stat_thread_mount_done_cb,
+								       &mount_data);
+					g_clear_error (&error);
+
+					/* wait for the mount to complete.  the callback occurs on the main
+					 * thread (not this thread), so we can just block until it is called.
+					 */
+					g_cond_wait (mount_data.cond, mount_data.mutex);
+					g_mutex_unlock (mount_data.mutex);
+
+					g_mutex_free (mount_data.mutex);
+					g_cond_free (mount_data.cond);
+
+					if (error == NULL) {
+						rb_debug ("mount op successful, retrying stat");
+						event->file_info = g_file_query_info (file,
+										      G_FILE_ATTRIBUTE_TIME_MODIFIED,
+										      G_FILE_QUERY_INFO_NONE,
+										      data->db->priv->exiting,
+										      &error);
+					}
+				} else {
+					rb_debug ("but couldn't create a mount op.");
+				}
+			}
+
+			if (error != NULL) {
+				event->error = make_access_failed_error (rb_refstring_get (event->uri), error);
+				g_clear_error (&error);
+			}
+		}
+
+		if (event->error != NULL) {
+			if (event->file_info != NULL) {
+				g_object_unref (event->file_info);
+				event->file_info = NULL;
+			}
+		}
+
+		g_async_queue_push (data->db->priv->event_queue, event);
+		g_object_unref (file);
+		count++;
 	}
 
-	db->priv->stat_handle = NULL;
-	g_mutex_unlock (db->priv->stat_mutex);
+	g_list_free (data->stat_list);
 
-	g_main_context_wakeup (g_main_context_default ());
+	data->db->priv->stat_thread_running = FALSE;
+	
+	rb_debug ("exiting stat thread");
+	result = g_slice_new0 (RhythmDBEvent);
+	result->db = data->db;			/* need to unref? */
+	result->type = RHYTHMDB_EVENT_THREAD_EXITED;
+	rhythmdb_push_event (data->db, result);
+
+	g_free (data);
+	return NULL;
 }
 
 void
@@ -634,13 +753,14 @@
 	rhythmdb_thread_create (db, NULL, (GThreadFunc) action_thread_main, db);
 
 	if (db->priv->stat_list != NULL) {
-		gnome_vfs_async_get_file_info (&db->priv->stat_handle, db->priv->stat_list,
-					       GNOME_VFS_FILE_INFO_FOLLOW_LINKS,
-					       GNOME_VFS_PRIORITY_MIN,
-					       (GnomeVFSAsyncGetFileInfoCallback) rhythmdb_execute_multi_stat_info_cb,
-					       db);
-		g_list_free (db->priv->stat_list);
+		RhythmDBStatThreadData *data;
+		data = g_new0 (RhythmDBStatThreadData, 1);
+		data->db = g_object_ref (db);
+		data->stat_list = db->priv->stat_list;
 		db->priv->stat_list = NULL;
+
+		db->priv->stat_thread_running = TRUE;
+		rhythmdb_thread_create (db, NULL, (GThreadFunc) stat_thread_main, data);
 	}
 
 	g_mutex_unlock (db->priv->stat_mutex);
@@ -651,7 +771,7 @@
 		      RhythmDBAction *action)
 {
 	rb_refstring_unref (action->uri);
-	g_free (action);
+	g_slice_free (RhythmDBAction, action);
 }
 
 static void
@@ -681,32 +801,30 @@
 		g_error_free (result->error);
 	rb_refstring_unref (result->uri);
 	rb_refstring_unref (result->real_uri);
-	if (result->vfsinfo)
-		gnome_vfs_file_info_unref (result->vfsinfo);
+	if (result->file_info)
+		g_object_unref (result->file_info);
 	if (result->metadata)
 		g_object_unref (result->metadata);
 	if (result->results)
 		g_object_unref (result->results);
-	if (result->handle)
-		gnome_vfs_async_cancel (result->handle);
 	if (result->entry != NULL) {
 		rhythmdb_entry_unref (result->entry);
 	}
-	g_free (result);
+	g_slice_free (RhythmDBEvent, result);
 }
 
-/**
- * rhythmdb_shutdown:
- *
- * Ceases all #RhythmDB operations, including stopping all directory monitoring, and
- * removing all actions and events currently queued.
- **/
 static void
 _shutdown_foreach_swapped (RhythmDBEvent *event, RhythmDB *db)
 {
 	rhythmdb_event_free (db, event);
 }
 
+/**
+ * rhythmdb_shutdown:
+ *
+ * Ceases all #RhythmDB operations, including stopping all directory monitoring, and
+ * removing all actions and events currently queued.
+ **/
 void
 rhythmdb_shutdown (RhythmDB *db)
 {
@@ -715,10 +833,10 @@
 
 	g_return_if_fail (RHYTHMDB_IS (db));
 
-	db->priv->exiting = TRUE;
+	g_cancellable_cancel (db->priv->exiting);
 
 	/* force the action thread to wake up and exit */
-	action = g_new0 (RhythmDBAction, 1);
+	action = g_slice_new0 (RhythmDBAction);
 	action->type = RHYTHMDB_ACTION_QUIT;
 	g_async_queue_push (db->priv->action_queue, action);
 
@@ -731,12 +849,8 @@
 	eel_gconf_notification_remove (db->priv->monitor_notify_id);
 	db->priv->monitor_notify_id = 0;
 
-	/* abort all async vfs operations */
+	/* abort all async io operations */
 	g_mutex_lock (db->priv->stat_mutex);
-	if (db->priv->stat_handle) {
-		gnome_vfs_async_cancel (db->priv->stat_handle);
-		db->priv->stat_handle = NULL;
-	}
 	g_list_foreach (db->priv->outstanding_stats, (GFunc)_shutdown_foreach_swapped, db);
 	g_list_free (db->priv->outstanding_stats);
 	db->priv->outstanding_stats = NULL;
@@ -757,12 +871,8 @@
 	while ((action = g_async_queue_try_pop (db->priv->action_queue)) != NULL) {
 		rhythmdb_action_free (db, action);
 	}
-}
 
-static void
-_shutdown_foreach_hash (gpointer uri, RhythmDBEvent *event, RhythmDB *db)
-{
-	rhythmdb_event_free (db, event);
+	g_object_unref (db->priv->exiting);
 }
 
 static void
@@ -832,8 +942,6 @@
 	g_cond_free (db->priv->saving_condition);
 
 	g_list_free (db->priv->stat_list);
-	g_hash_table_foreach (db->priv->stat_events, (GHFunc)_shutdown_foreach_hash, db);
-	g_hash_table_destroy (db->priv->stat_events);
  	g_mutex_free (db->priv->stat_mutex);
 
 	g_mutex_free (db->priv->change_mutex);
@@ -983,7 +1091,7 @@
 		RhythmDBEntryChange *change = t->data;
 		g_value_unset (&change->old);
 		g_value_unset (&change->new);
-		g_free (change);
+		g_slice_free (RhythmDBEntryChange, change);
 	}
 	g_slist_free (changes);
 
@@ -1017,7 +1125,7 @@
 				break;
 			}
 
-			action = g_new0 (RhythmDBAction, 1);
+			action = g_slice_new0 (RhythmDBAction);
 			action->type = RHYTHMDB_ACTION_SYNC;
 			action->uri = rb_refstring_ref (entry->location);
 			g_async_queue_push (db->priv->action_queue, action);
@@ -1080,11 +1188,30 @@
 		if (uri == NULL)
 			return TRUE;
 
-		queue_stat_uri (uri,
-				db,
-				RHYTHMDB_ENTRY_TYPE_INVALID,
-				RHYTHMDB_ENTRY_TYPE_IGNORE,
-				RHYTHMDB_ENTRY_TYPE_IMPORT_ERROR);
+		/* something to think about: only do the stat if the mountpoint is
+		 * NULL.  other things are likely to be removable disks and network
+		 * shares, where getting file info for a large number of files is going
+		 * to be slow.  on the other hand, we'd want to mount those on startup
+		 * rather than on first access, which may not be predictable.  hmm..
+		 *
+		 * we'd probably have to improve handling of the particular 'file not found'
+		 * playback error, though.  or perhaps stat immediately before playback?
+		 * what about crawling the filesystem to find new files?
+		 *
+		 * further: this should only be done for entries loaded from the database file,
+		 * not for newly added entries.  cripes.
+		 *
+		 * hmm, do we really need to take the stat mutex to check if the action thread is running?
+		 * maybe it should be atomicised?
+		 */
+		g_mutex_lock (db->priv->stat_mutex);
+		if (db->priv->action_thread_running == FALSE) {
+			rhythmdb_add_to_stat_list (db, uri, entry,
+						   RHYTHMDB_ENTRY_TYPE_INVALID,
+						   RHYTHMDB_ENTRY_TYPE_IGNORE,
+						   RHYTHMDB_ENTRY_TYPE_IMPORT_ERROR);
+		}
+		g_mutex_unlock (db->priv->stat_mutex);
 	}
 
 	g_assert ((entry->flags & RHYTHMDB_ENTRY_INSERTED) == 0);
@@ -1489,7 +1616,7 @@
 static void
 set_props_from_metadata (RhythmDB *db,
 			 RhythmDBEntry *entry,
-			 GnomeVFSFileInfo *vfsinfo,
+			 GFileInfo *fileinfo,
 			 RBMetaData *metadata)
 {
 	const char *mime;
@@ -1600,7 +1727,7 @@
 
 	/* filesize */
 	g_value_init (&val, G_TYPE_UINT64);
-	g_value_set_uint64 (&val, vfsinfo->size);
+	g_value_set_uint64 (&val, g_file_info_get_attribute_uint64 (fileinfo, G_FILE_ATTRIBUTE_STANDARD_SIZE));
 	rhythmdb_entry_set_internal (db, entry, TRUE, RHYTHMDB_PROP_FILE_SIZE, &val);
 	g_value_unset (&val);
 
@@ -1608,17 +1735,13 @@
 	if (!rb_metadata_get (metadata,
 			      RB_METADATA_FIELD_TITLE,
 			      &val) || g_value_get_string (&val)[0] == '\0') {
-		char *utf8name;
-		utf8name = g_filename_to_utf8 (vfsinfo->name, -1, NULL, NULL, NULL);
-		if (!utf8name) {
-			utf8name = g_strdup (_("<invalid filename>"));
-		}
+		const char *fname;
+		fname = g_file_info_get_display_name (fileinfo);
 		if (G_VALUE_HOLDS_STRING (&val))
 			g_value_reset (&val);
 		else
 			g_value_init (&val, G_TYPE_STRING);
-		g_value_set_string (&val, utf8name);
-		g_free (utf8name);
+		g_value_set_string (&val, fname);
 	}
 	rhythmdb_entry_set_internal (db, entry, TRUE, RHYTHMDB_PROP_TITLE, &val);
 	g_value_unset (&val);
@@ -1717,18 +1840,20 @@
 {
 	RhythmDBEntry *entry;
 	RhythmDBAction *action;
+	GFileType file_type;
+	
+	if (event->entry != NULL) {
+		entry = event->entry;
+	} else {
+		entry = rhythmdb_entry_lookup_by_location_refstring (db, event->real_uri);
+	}
 
-	entry = rhythmdb_entry_lookup_by_location_refstring (db, event->real_uri);
-	if (entry) {
-		time_t mtime = (time_t) entry->mtime;
-
-		if ((event->entry_type != RHYTHMDB_ENTRY_TYPE_INVALID) && (entry->type != event->entry_type))
-			g_warning ("attempt to use same location in multiple entry types");
-
-		if (entry->type == event->ignore_type)
-			rb_debug ("ignoring %p", entry);
-
-		if (event->error) {
+	/* handle errors:
+	 * - if a non-ignore entry exists, process ghostliness (hide/delete)
+	 * - otherwise, create an import error entry?  hmm.
+	 */
+	if (event->error) {
+		if (entry != NULL) {
 			if (!is_ghost_entry (entry)) {
 				rhythmdb_entry_set_visibility (db, entry, FALSE);
 			} else {
@@ -1737,24 +1862,37 @@
 				rhythmdb_entry_delete (db, entry);
 			}
 		} else {
+			/* erm.. */
+		}
+
+		return;
+	}
+
+	g_assert (event->file_info != NULL);
+
+	/* figure out what to do based on the file type */
+	file_type = g_file_info_get_attribute_uint32 (event->file_info,
+						      G_FILE_ATTRIBUTE_STANDARD_TYPE);
+	switch (file_type) {
+	case G_FILE_TYPE_UNKNOWN:
+	case G_FILE_TYPE_REGULAR:
+		if (entry != NULL) {
 			GValue val = {0, };
 			GTimeVal time;
-			const char *mount_point;
+			guint64 new_mtime;
+			guint64 new_size;
 
-			rhythmdb_entry_set_visibility (db, entry, TRUE);
+			/* update the existing entry, as long as the entry type matches */
+			if ((event->entry_type != RHYTHMDB_ENTRY_TYPE_INVALID) && (entry->type != event->entry_type))
+				g_warning ("attempt to use same location in multiple entry types");
 
-			/* Update mount point if necessary (main reason is
-			 * that we want to set the mount point in legacy
-			 * rhythmdb that doesn't have it already
-			 */
-			mount_point = rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_MOUNTPOINT);
-			if (mount_point == NULL) {
-				rhythmdb_entry_set_mount_point (db, entry,
-								rb_refstring_get (event->real_uri));
-			}
+			if (entry->type == event->ignore_type)
+				rb_debug ("ignoring %p", entry);
+
+			rhythmdb_entry_set_visibility (db, entry, TRUE);
 
 			/* Update last seen time. It will also be updated
-			 * upon saving and when a volume is unmounted
+			 * upon saving and when a volume is unmounted.
 			 */
 			g_get_current_time (&time);
 			g_value_init (&val, G_TYPE_ULONG);
@@ -1762,41 +1900,64 @@
 			rhythmdb_entry_set_internal (db, entry, TRUE,
 						     RHYTHMDB_PROP_LAST_SEEN,
 						     &val);
-			/* Old rhythmdb.xml files won't have a value for
-			 * FIRST_SEEN, so set it here
-			 */
-			if (rhythmdb_entry_get_ulong (entry, RHYTHMDB_PROP_FIRST_SEEN) == 0) {
-				rhythmdb_entry_set_internal (db, entry, TRUE,
-							     RHYTHMDB_PROP_FIRST_SEEN,
-							     &val);
-			}
 			g_value_unset (&val);
 
-			if (mtime == event->vfsinfo->mtime) {
+			/* compare modification time and size to the values in the database.
+			 * if either has changed, we'll re-read the file.
+			 */
+			new_mtime = g_file_info_get_attribute_uint64 (event->file_info, G_FILE_ATTRIBUTE_TIME_MODIFIED);
+			new_size = g_file_info_get_attribute_uint64 (event->file_info, G_FILE_ATTRIBUTE_STANDARD_SIZE);
+			if (entry->mtime == new_mtime && (new_size == 0 || entry->file_size == new_size)) {
 				rb_debug ("not modified: %s", rb_refstring_get (event->real_uri));
 			} else {
 				RhythmDBEvent *new_event;
 
 				rb_debug ("changed: %s", rb_refstring_get (event->real_uri));
-				new_event = g_new0 (RhythmDBEvent, 1);
+				new_event = g_slice_new0 (RhythmDBEvent);
 				new_event->db = db;
 				new_event->uri = rb_refstring_ref (event->real_uri);
 				new_event->type = RHYTHMDB_EVENT_FILE_CREATED_OR_MODIFIED;
 				rhythmdb_push_event (db, new_event);
 			}
+		} else {
+			/* push a LOAD action */
+			action = g_slice_new0 (RhythmDBAction);
+			action->type = RHYTHMDB_ACTION_LOAD;
+			action->uri = rb_refstring_ref (event->real_uri);
+			action->entry_type = event->entry_type;
+			action->ignore_type = event->ignore_type;
+			action->error_type = event->error_type;
+			rb_debug ("queuing a RHYTHMDB_ACTION_LOAD: %s", rb_refstring_get (action->uri));
+			g_async_queue_push (db->priv->action_queue, action);
 		}
+		break;
 
-		rhythmdb_commit (db);
-	} else {
-		action = g_new0 (RhythmDBAction, 1);
-		action->type = RHYTHMDB_ACTION_LOAD;
+	case G_FILE_TYPE_DIRECTORY:
+		rb_debug ("processing directory %s", rb_refstring_get (event->real_uri));
+		/* push an ENUM_DIR action */
+		action = g_slice_new0 (RhythmDBAction);
+		action->type = RHYTHMDB_ACTION_ENUM_DIR;
 		action->uri = rb_refstring_ref (event->real_uri);
 		action->entry_type = event->entry_type;
 		action->ignore_type = event->ignore_type;
 		action->error_type = event->error_type;
-		rb_debug ("queuing a RHYTHMDB_ACTION_LOAD: %s", rb_refstring_get (action->uri));
+		rb_debug ("queuing a RHYTHMDB_ACTION_ENUM_DIR: %s", rb_refstring_get (action->uri));
 		g_async_queue_push (db->priv->action_queue, action);
+		break;
+
+	case G_FILE_TYPE_SYMBOLIC_LINK:
+	case G_FILE_TYPE_SHORTCUT:
+		/* this shouldn't happen, but maybe we should handle it anyway? */
+		rb_debug ("ignoring stat results for %s: is link", rb_refstring_get (event->real_uri));
+		break;
+
+	case G_FILE_TYPE_SPECIAL:
+	case G_FILE_TYPE_MOUNTABLE:		/* hmm. */
+		rb_debug ("ignoring stat results for %s: is special", rb_refstring_get (event->real_uri));
+		break;
 	}
+
+	rhythmdb_commit (db);
 }
 
 typedef struct
@@ -1850,10 +2011,11 @@
 			/* no need to update the ignored file entry */
 		}
 
-		if (entry && event->vfsinfo) {
+		if (entry && event->file_info) {
 			/* mtime */
+			guint64 new_mtime = g_file_info_get_attribute_uint64 (event->file_info, G_FILE_ATTRIBUTE_TIME_MODIFIED);
 			g_value_init (&value, G_TYPE_ULONG);
-			g_value_set_ulong (&value, event->vfsinfo->mtime);
+			g_value_set_ulong (&value, new_mtime);		/* hmm, cast */
 			rhythmdb_entry_set(db, entry, RHYTHMDB_PROP_MTIME, &value);
 			g_value_unset (&value);
 		}
@@ -1878,10 +2040,11 @@
 		}
 
 		/* mtime */
-		if (event->vfsinfo) {
+		if (event->file_info) {
+			guint64 new_mtime = g_file_info_get_attribute_uint64 (event->file_info, G_FILE_ATTRIBUTE_TIME_MODIFIED);
 			g_value_init (&value, G_TYPE_ULONG);
-			g_value_set_ulong (&value, event->vfsinfo->mtime);
-			rhythmdb_entry_set (db, entry, RHYTHMDB_PROP_MTIME, &value);
+			g_value_set_ulong (&value, new_mtime);		/* hmm, cast */
+			rhythmdb_entry_set(db, entry, RHYTHMDB_PROP_MTIME, &value);
 			g_value_unset (&value);
 		}
 
@@ -1962,16 +2125,20 @@
 		g_warning ("attempt to use same location in multiple entry types");
 
 	/* mtime */
-	if (event->vfsinfo) {
+	if (event->file_info) {
+		guint64 mtime;
+
+		mtime = g_file_info_get_attribute_uint64 (event->file_info, G_FILE_ATTRIBUTE_TIME_MODIFIED);
+
 		g_value_init (&value, G_TYPE_ULONG);
-		g_value_set_ulong (&value, event->vfsinfo->mtime);
+		g_value_set_ulong (&value, (gulong)mtime);
 		rhythmdb_entry_set_internal (event->db, entry, TRUE, RHYTHMDB_PROP_MTIME, &value);
 		g_value_unset (&value);
 	}
 
 	if (event->entry_type != event->ignore_type &&
 	    event->entry_type != event->error_type) {
-		set_props_from_metadata (event->db, entry, event->vfsinfo, event->metadata);
+		set_props_from_metadata (event->db, entry, event->file_info, event->metadata);
 	}
 
 	/* we've seen this entry */
@@ -1995,8 +2162,6 @@
 	return TRUE;
 }
 
-#ifdef HAVE_GSTREAMER_0_10_MISSING_PLUGINS
-
 static void
 rhythmdb_missing_plugins_cb (gpointer duh, gboolean should_retry, RhythmDBEvent *event)
 {
@@ -2006,7 +2171,7 @@
 		RhythmDBAction *load_action;
 
 		rb_debug ("retrying RHYTHMDB_ACTION_LOAD for %s", rb_refstring_get (event->real_uri));
-		load_action = g_new0 (RhythmDBAction, 1);
+		load_action = g_slice_new0 (RhythmDBAction);
 		load_action->type = RHYTHMDB_ACTION_LOAD;
 		load_action->uri = rb_refstring_ref (event->real_uri);
 		load_action->entry_type = RHYTHMDB_ENTRY_TYPE_INVALID;
@@ -2035,13 +2200,10 @@
 	rhythmdb_event_free (event->db, event);
 }
 
-#endif /* HAVE_GSTREAMER_0_10_MISSING_PLUGINS */
-
 static gboolean
 rhythmdb_process_metadata_load (RhythmDB *db,
 				RhythmDBEvent *event)
 {
-#ifdef HAVE_GSTREAMER_0_10_MISSING_PLUGINS
 	char **missing_plugins;
 	char **plugin_descriptions;
 
@@ -2075,7 +2237,6 @@
 		g_closure_sink (closure);
 		return FALSE;
 	}
-#endif /* HAVE_GSTREAMER_0_10_MISSING_PLUGINS */
 
 	return rhythmdb_process_metadata_load_real (event);
 }
@@ -2102,7 +2263,7 @@
 {
 	RhythmDBAction *action;
 
-	action = g_new0 (RhythmDBAction, 1);
+	action = g_slice_new0 (RhythmDBAction);
 	action->type = RHYTHMDB_ACTION_LOAD;
 	action->uri = rb_refstring_ref (event->uri);
 	action->entry_type = RHYTHMDB_ENTRY_TYPE_INVALID;
@@ -2197,128 +2358,108 @@
 		rhythmdb_event_free (db, event);
 }
 
+
 static void
-rhythmdb_execute_stat_info_cb (GnomeVFSAsyncHandle *handle,
-			       GList *results,
-			       /* GnomeVFSGetFileInfoResult* items */
-			       RhythmDBEvent *event)
+rhythmdb_file_info_query (RhythmDB *db, GFile *file, RhythmDBEvent *event)
+{
+	event->file_info = g_file_query_info (file,
+					      RHYTHMDB_FILE_INFO_ATTRIBUTES,
+					      G_FILE_QUERY_INFO_NONE,
+					      db->priv->exiting,
+					      &event->error);
+}
+
+static void
+wrap_access_failed_error (RhythmDBEvent *event)
 {
-	/* this is in the main thread, so we can't do any long operation here */
-	GnomeVFSGetFileInfoResult *info_result = results->data;
+	GError *wrapped;
+
+	wrapped = make_access_failed_error (rb_refstring_get (event->real_uri), event->error);
+	g_error_free (event->error);
+	event->error = wrapped;
+}
+
+static void
+rhythmdb_execute_stat_mount_ready_cb (GObject *source, GAsyncResult *result, RhythmDBEvent *event)
+{
+	GError *error = NULL;
+	
+	g_file_mount_enclosing_volume_finish (G_FILE (source), result, &error);
+	if (error != NULL) {
+		event->error = make_access_failed_error (rb_refstring_get (event->real_uri), error);
+		g_print ("not doing file info query; error %s\n", error->message);
+		g_error_free (error);
+
+		g_object_unref (event->file_info);
+		event->file_info = NULL;
+	} else {
+		g_print ("retrying file info query after mount completed\n");
+		rhythmdb_file_info_query (event->db, G_FILE (source), event);
+	}
 
 	g_mutex_lock (event->db->priv->stat_mutex);
 	event->db->priv->outstanding_stats = g_list_remove (event->db->priv->outstanding_stats, event);
-	event->handle = NULL;
 	g_mutex_unlock (event->db->priv->stat_mutex);
 
-	if (info_result->result == GNOME_VFS_OK) {
-		event->vfsinfo = gnome_vfs_file_info_dup (info_result->file_info);
-	} else {
-		event->error = make_access_failed_error (rb_refstring_get (event->real_uri),
-							 info_result->result);
-		event->vfsinfo = NULL;
-	}
+	g_object_unref (source);
 	rhythmdb_push_event (event->db, event);
 }
 
+
 static void
 rhythmdb_execute_stat (RhythmDB *db,
 		       const char *uri,
 		       RhythmDBEvent *event)
 {
-	GList *uri_list;
-	GnomeVFSURI *vfs_uri;
+	GFile *file;
 
 	event->real_uri = rb_refstring_new (uri);
-
-	vfs_uri = gnome_vfs_uri_new (uri);
-	if (vfs_uri == NULL) {
-		event->error = make_access_failed_error (uri, GNOME_VFS_ERROR_INVALID_URI);
-		rhythmdb_push_event (db, event);
-		return;
-	}
-
-	uri_list = g_list_append (NULL, vfs_uri);
-
+	file = g_file_new_for_uri (uri);
+	
 	g_mutex_lock (db->priv->stat_mutex);
 	db->priv->outstanding_stats = g_list_prepend (db->priv->outstanding_stats, event);
 	g_mutex_unlock (db->priv->stat_mutex);
 
-	gnome_vfs_async_get_file_info (&event->handle, uri_list,
-			       GNOME_VFS_FILE_INFO_FOLLOW_LINKS,
-			       GNOME_VFS_PRIORITY_MIN,
-			       (GnomeVFSAsyncGetFileInfoCallback) rhythmdb_execute_stat_info_cb,
-			       event);
-	gnome_vfs_uri_unref (vfs_uri);
-	g_list_free (uri_list);
-}
-
-void
-queue_stat_uri (const char *uri,
-		RhythmDB *db,
-		RhythmDBEntryType type,
-		RhythmDBEntryType ignore_type,
-		RhythmDBEntryType error_type)
-{
-	RhythmDBEvent *result;
-
-	rb_debug ("queueing stat for \"%s\"", uri);
-	g_assert (uri && *uri);
-
-	result = g_new0 (RhythmDBEvent, 1);
-	result->db = db;
-	result->type = RHYTHMDB_EVENT_STAT;
-	result->entry_type = type;
-	result->ignore_type = ignore_type;
-	result->error_type = error_type;
-
-	/*
-	 * before the action thread is started, we queue up stat events,
-	 * as we're still creating and running queries, as well as loading
-	 * the database.  when we start the action thread, we'll kick off
-	 * a gnome-vfs job to run all the stat events too.
-	 *
-	 * when the action thread is already running, we can start the
-	 * async_get_file_info job directly.
-	 */
-	g_mutex_lock (db->priv->stat_mutex);
-	if (db->priv->action_thread_running) {
-		g_mutex_unlock (db->priv->stat_mutex);
-		rhythmdb_execute_stat (db, uri, result);
-	} else {
-		GnomeVFSURI *vfs_uri;
+	rhythmdb_file_info_query (db, file, event);
 
-		vfs_uri = gnome_vfs_uri_new (uri);
-		if (vfs_uri == NULL) {
-			result->real_uri = rb_refstring_new (uri);
-			result->error = make_access_failed_error (uri, GNOME_VFS_ERROR_INVALID_URI);
-			rhythmdb_push_event (db, result);
-		} else {
-			/* construct a list of URIs and a hash table containing
-			 * stat events to fill in and post on the event queue.
-			 */
-			if (g_hash_table_lookup (db->priv->stat_events, vfs_uri)) {
-				g_free (result);
-				gnome_vfs_uri_unref (vfs_uri);
-			} else {
-				result->real_uri = rb_refstring_new (uri);
-				g_hash_table_insert (db->priv->stat_events, vfs_uri, result);
-				db->priv->stat_list = g_list_prepend (db->priv->stat_list, vfs_uri);
+	if (event->error != NULL) {
+		/* if we can't get at it because the location isn't mounted, mount it and try again */
+	       	if (g_error_matches (event->error, G_IO_ERROR, G_IO_ERROR_NOT_MOUNTED)) {
+			GMountOperation *mount_op = NULL;
+
+			g_error_free (event->error);
+			event->error = NULL;
+
+			g_signal_emit (G_OBJECT (event->db), rhythmdb_signals[CREATE_MOUNT_OP], 0, &mount_op);
+			if (mount_op != NULL) {
+				g_print ("created mount op %p\n", mount_op);
+				g_file_mount_enclosing_volume (file,
+							       G_MOUNT_MOUNT_NONE,
+							       mount_op,
+							       event->db->priv->exiting,
+							       (GAsyncReadyCallback)rhythmdb_execute_stat_mount_ready_cb,
+							       event);
+				return;
 			}
 		}
 
-		g_mutex_unlock (db->priv->stat_mutex);
+		/* if it's some other error, or we couldn't attempt to mount the location, report the error */
+		wrap_access_failed_error (event);
+
+		if (event->file_info != NULL) {
+			g_object_unref (event->file_info);
+			event->file_info = NULL;
+		}
 	}
-}
+       
+	/* either way, we're done now */
 
-static gboolean
-queue_stat_uri_tad (const char *uri,
-		    gboolean dir,
-		    RhythmDBAddThreadData *data)
-{
-	if (!dir)
-		queue_stat_uri (uri, data->db, data->type, data->ignore_type, data->error_type);
-	return TRUE;	
+	g_mutex_lock (event->db->priv->stat_mutex);
+	event->db->priv->outstanding_stats = g_list_remove (event->db->priv->outstanding_stats, event);
+	g_mutex_unlock (event->db->priv->stat_mutex);
+	
+	rhythmdb_push_event (event->db, event);
+	g_object_unref (file);
 }
 
 static void
@@ -2326,56 +2467,128 @@
 		       const char *uri,
 		       RhythmDBEvent *event)
 {
-	GnomeVFSResult vfsresult;
+	GError *error = NULL;
 	char *resolved;
 
-	resolved = rb_uri_resolve_symlink (uri);
+	resolved = rb_uri_resolve_symlink (uri, &error);
 	if (resolved != NULL) {
+		GFile *file;
+	
+		file = g_file_new_for_uri (uri);
+		event->file_info = g_file_query_info (file,
+						      RHYTHMDB_FILE_INFO_ATTRIBUTES,
+						      G_FILE_QUERY_INFO_NONE,
+						      NULL,
+						      &error);
 		event->real_uri = rb_refstring_new (resolved);
-		event->vfsinfo = gnome_vfs_file_info_new ();
 
-		vfsresult = gnome_vfs_get_file_info (uri,
-						     event->vfsinfo,
-						     GNOME_VFS_FILE_INFO_FOLLOW_LINKS);
 		g_free (resolved);
+		g_object_unref (file);
 	} else {
 		event->real_uri = rb_refstring_new (uri);
-		vfsresult = GNOME_VFS_ERROR_LOOP;
 	}
 
-	if (vfsresult != GNOME_VFS_OK) {
-		event->error = make_access_failed_error (uri, vfsresult);
-		if (event->vfsinfo)
-			gnome_vfs_file_info_unref (event->vfsinfo);
-		event->vfsinfo = NULL;
-	} else {
-		if (event->type == RHYTHMDB_EVENT_METADATA_LOAD) {
-			g_mutex_lock (event->db->priv->metadata_lock);
-			while (event->db->priv->metadata_blocked) {
-				g_cond_wait (event->db->priv->metadata_cond, event->db->priv->metadata_lock);
-			}
+	if (error != NULL) {
+		event->error = make_access_failed_error (uri, error);
+		if (event->file_info) {
+			g_object_unref (event->file_info);
+			event->file_info = NULL;
+		}
+	} else if (event->type == RHYTHMDB_EVENT_METADATA_LOAD) {
+		g_mutex_lock (event->db->priv->metadata_lock);
+		while (event->db->priv->metadata_blocked) {
+			g_cond_wait (event->db->priv->metadata_cond, event->db->priv->metadata_lock);
+		}
 
-			event->metadata = rb_metadata_new ();
-			rb_metadata_load (event->metadata, rb_refstring_get (event->real_uri),
-					  &event->error);
+		event->metadata = rb_metadata_new ();
+		rb_metadata_load (event->metadata,
+				  rb_refstring_get (event->real_uri),
+				  &event->error);
 
-			/* if we're missing some plugins, block further attempts to
-			 * read metadata until we've processed them.
-			 */
-			if (!g_error_matches (event->error,
-					     RB_METADATA_ERROR,
-					     RB_METADATA_ERROR_NOT_AUDIO_IGNORE) &&
-			    rb_metadata_has_missing_plugins (event->metadata)) {
-				event->db->priv->metadata_blocked = TRUE;
-			}
-
-			g_mutex_unlock (event->db->priv->metadata_lock);
+		/* if we're missing some plugins, block further attempts to
+		 * read metadata until we've processed them.
+		 */
+		if (!g_error_matches (event->error,
+				     RB_METADATA_ERROR,
+				     RB_METADATA_ERROR_NOT_AUDIO_IGNORE) &&
+		    rb_metadata_has_missing_plugins (event->metadata)) {
+			event->db->priv->metadata_blocked = TRUE;
 		}
+
+		g_mutex_unlock (event->db->priv->metadata_lock);
 	}
 
 	rhythmdb_push_event (db, event);
 }
 
+static void
+rhythmdb_execute_enum_dir (RhythmDB *db,
+			   RhythmDBAction *action)
+{
+	GFile *dir;
+	GFileEnumerator *dir_enum;
+	GError *error = NULL;
+
+	dir = g_file_new_for_uri (rb_refstring_get (action->uri));
+	dir_enum = g_file_enumerate_children (dir,
+					      RHYTHMDB_FILE_CHILD_INFO_ATTRIBUTES,
+					      G_FILE_QUERY_INFO_NONE,
+					      db->priv->exiting,
+					      &error);
+	if (error != NULL) {
+		/* don't need to worry about mounting here, as the mount should have
+		 * occurred on the stat.
+		 */
+
+		/* um.. what now? */
+		rb_debug ("unable to enumerate children of %s: %s",
+			  rb_refstring_get (action->uri),
+			  error->message);
+		g_error_free (error);
+		g_object_unref (dir);
+		return;
+	}
+
+	while (1) {
+		RhythmDBEvent *result;
+		GFileInfo *file_info;
+		GFile *child;
+		char *child_uri;
+
+		file_info = g_file_enumerator_next_file (dir_enum, db->priv->exiting, &error);
+		if (file_info == NULL && error == NULL) {
+			/* done */
+			break;
+		}
+
+		child = g_file_get_child (dir, g_file_info_get_name (file_info));
+		child_uri = g_file_get_uri (child);
+
+		result = g_slice_new0 (RhythmDBEvent);
+		result->db = db;
+		result->type = RHYTHMDB_EVENT_STAT;
+		result->entry_type = action->entry_type;
+		result->error_type = action->error_type;
+		result->ignore_type = action->ignore_type;
+		result->real_uri = rb_refstring_new (child_uri);
+		result->file_info = file_info;
+		result->error = error;
+
+		rhythmdb_push_event (db, result);
+		g_free (child_uri);
+	}
+
+	g_file_enumerator_close (dir_enum, db->priv->exiting, &error);
+	if (error != NULL) {
+		/* hmm.. */
+		rb_debug ("error closing file enumerator: %s", error->message);
+		g_error_free (error);
+	}
+
+	g_object_unref (dir);
+	g_object_unref (dir_enum);
+}
+
 /**
  * rhythmdb_entry_get:
  * @entry: a #RhythmDBEntry.
@@ -2469,15 +2682,16 @@
 {
 	RhythmDBEvent *result;
 
-	while (!db->priv->exiting) {
+	while (!g_cancellable_is_cancelled (db->priv->exiting)) {
 		RhythmDBAction *action;
 
 		action = g_async_queue_pop (db->priv->action_queue);
 
-		if (!db->priv->exiting) {
+		/* hrm, do we need this check at all? */
+		if (!g_cancellable_is_cancelled (db->priv->exiting)) {
 			switch (action->type) {
 			case RHYTHMDB_ACTION_STAT:
-				result = g_new0 (RhythmDBEvent, 1);
+				result = g_slice_new0 (RhythmDBEvent);
 				result->db = db;
 				result->type = RHYTHMDB_EVENT_STAT;
 				result->entry_type = action->entry_type;
@@ -2490,7 +2704,7 @@
 				break;
 
 			case RHYTHMDB_ACTION_LOAD:
-				result = g_new0 (RhythmDBEvent, 1);
+				result = g_slice_new0 (RhythmDBEvent);
 				result->db = db;
 				result->type = RHYTHMDB_EVENT_METADATA_LOAD;
 				result->entry_type = action->entry_type;
@@ -2502,6 +2716,11 @@
 				rhythmdb_execute_load (db, rb_refstring_get (action->uri), result);
 				break;
 
+			case RHYTHMDB_ACTION_ENUM_DIR:
+				rb_debug ("executing RHYTHMDB_ACTION_ENUM_DIR for \"%s\"", rb_refstring_get (action->uri));
+				rhythmdb_execute_enum_dir (db, action);
+				break;
+
 			case RHYTHMDB_ACTION_SYNC:
 			{
 				GError *error = NULL;
@@ -2549,7 +2768,7 @@
 	}
 
 	rb_debug ("exiting action thread");
-	result = g_new0 (RhythmDBEvent, 1);
+	result = g_slice_new0 (RhythmDBEvent);
 	result->db = db;
 	result->type = RHYTHMDB_EVENT_THREAD_EXITED;
 	rhythmdb_push_event (db, result);
@@ -2577,6 +2796,35 @@
 				     RHYTHMDB_ENTRY_TYPE_IMPORT_ERROR);
 }
 
+static void
+rhythmdb_add_to_stat_list (RhythmDB *db,
+			   const char *uri,
+			   RhythmDBEntry *entry,
+			   RhythmDBEntryType type,
+			   RhythmDBEntryType ignore_type,
+			   RhythmDBEntryType error_type)
+{
+	RhythmDBEvent *result;
+
+	result = g_slice_new0 (RhythmDBEvent);
+	result->db = db;
+	result->type = RHYTHMDB_EVENT_STAT;
+	result->entry_type = type;
+	result->ignore_type = ignore_type;
+	result->error_type = error_type;
+		
+	if (entry != NULL) {
+		result->entry = rhythmdb_entry_ref (entry);
+	}
+
+	/* do we really need to check for duplicate requests here?  .. nah. */
+	result->uri = rb_refstring_new (uri);
+	db->priv->stat_list = g_list_prepend (db->priv->stat_list, result);
+
+	g_mutex_unlock (db->priv->stat_mutex);
+}
+
+
 /**
  * rhythmdb_add_uri_with_types:
  * @db: a #RhythmDB.
@@ -2597,41 +2845,40 @@
 			     RhythmDBEntryType ignore_type,
 			     RhythmDBEntryType error_type)
 {
-	char *realuri;
-	char *canon_uri;
+	rb_debug ("queueing stat for \"%s\"", uri);
+	g_assert (uri && *uri);
 
-	canon_uri = rb_canonicalise_uri (uri);
-	realuri = rb_uri_resolve_symlink (canon_uri);
+	/*
+	 * before the action thread is started, we queue up stat actions,
+	 * as we're still creating and running queries, as well as loading
+	 * the database.  when we start the action thread, we'll kick off
+	 * a thread to process all the stat events too.
+	 *
+	 * when the action thread is already running, stat actions go through
+	 * the normal action queue and are processed by the action thread.
+	 */
+	g_mutex_lock (db->priv->stat_mutex);
+	if (db->priv->action_thread_running) {
+		RhythmDBAction *action;
+		g_mutex_unlock (db->priv->stat_mutex);
 
-	if (realuri == NULL) {
-		/* create import error entry */
-		RhythmDBEvent *event = g_new0 (RhythmDBEvent, 1);
-
-		event->db = db;
-		event->real_uri = rb_refstring_new (canon_uri);
-		event->error = make_access_failed_error (canon_uri, GNOME_VFS_ERROR_LOOP);
-		event->ignore_type = ignore_type;
-		event->error_type = error_type;
-		rhythmdb_add_import_error_entry (db, event);
-		g_free (event);
-
-	} else if (rb_uri_is_directory (realuri)) {
-		RhythmDBAddThreadData *data = g_new0 (RhythmDBAddThreadData, 1);
-		data->db = db;
-		data->type = type;
-		data->ignore_type = ignore_type;
-		data->error_type = error_type;
+		action = g_slice_new0 (RhythmDBAction);
+		action->type = RHYTHMDB_ACTION_STAT;
+		action->uri = rb_refstring_new (uri);
+		action->entry_type = type;
+		action->ignore_type = ignore_type;
+		action->error_type = error_type;
 
-		rb_uri_handle_recursively_async (realuri, (RBUriRecurseFunc)queue_stat_uri_tad,
-						 &data->db->priv->exiting, data, (GDestroyNotify)g_free);
+		g_async_queue_push (db->priv->action_queue, action);
 	} else {
-		queue_stat_uri (realuri, db, type, ignore_type, error_type);
-	}
+		RhythmDBEntry *entry;
 
-	g_free (canon_uri);
-	g_free (realuri);
+		entry = rhythmdb_entry_lookup_by_location (db, uri);
+		rhythmdb_add_to_stat_list (db, uri, entry, type, ignore_type, error_type);
+	}
 }
 
+
 static gboolean
 rhythmdb_sync_library_idle (RhythmDB *db)
 {
@@ -2662,7 +2909,7 @@
 
 	rb_profile_start ("loading db");
 	g_mutex_lock (db->priv->saving_mutex);
-	if (klass->impl_load (db, &db->priv->exiting, &error) == FALSE) {
+	if (klass->impl_load (db, db->priv->exiting, &error) == FALSE) {
 		rb_debug ("db load failed: disabling saving");
 		db->priv->can_save = FALSE;
 
@@ -2676,12 +2923,12 @@
 	g_timeout_add (10000, (GSourceFunc) rhythmdb_sync_library_idle, db);
 
 	rb_debug ("queuing db load complete signal");
-	result = g_new0 (RhythmDBEvent, 1);
+	result = g_slice_new0 (RhythmDBEvent);
 	result->type = RHYTHMDB_EVENT_DB_LOAD;
 	g_async_queue_push (db->priv->event_queue, result);
 
 	rb_debug ("exiting");
-	result = g_new0 (RhythmDBEvent, 1);
+	result = g_slice_new0 (RhythmDBEvent);
 	result->type = RHYTHMDB_EVENT_THREAD_EXITED;
 	rhythmdb_push_event (db, result);
 
@@ -2738,12 +2985,12 @@
 	g_cond_broadcast (db->priv->saving_condition);
 
 out:
-	result = g_new0 (RhythmDBEvent, 1);
+	result = g_slice_new0 (RhythmDBEvent);
 	result->db = db;
 	result->type = RHYTHMDB_EVENT_DB_SAVED;
 	g_async_queue_push (db->priv->event_queue, result);
 
-	result = g_new0 (RhythmDBEvent, 1);
+	result = g_slice_new0 (RhythmDBEvent);
 	result->db = db;
 	result->type = RHYTHMDB_EVENT_THREAD_EXITED;
 	rhythmdb_push_event (db, result);
@@ -2835,7 +3082,7 @@
 		} else {
 			RhythmDBEvent *result;
 
-			result = g_new0 (RhythmDBEvent, 1);
+			result = g_slice_new0 (RhythmDBEvent);
 			result->db = db;
 			result->type = RHYTHMDB_EVENT_ENTRY_SET;
 
@@ -2863,7 +3110,7 @@
 	RhythmDBEntryChange *changedata;
 	GSList *changelist;
 
-	changedata = g_new0 (RhythmDBEntryChange, 1);
+	changedata = g_slice_new0 (RhythmDBEntryChange);
 	changedata->prop = propid;
 
 	g_value_init (&changedata->old, G_VALUE_TYPE (old_value));
@@ -3248,7 +3495,7 @@
  * @db: a #RhythmDB.
  * @entry: a #RhythmDBEntry.
  *
- * Delete entry @entry from the database, sending notification of it's deletion.
+ * Delete entry @entry from the database, sending notification of its deletion.
  * This is usually used by sources where entries can disappear randomly, such
  * as a network source.
  **/
@@ -3276,8 +3523,6 @@
 	db->priv->dirty = TRUE;
 }
 
-#if defined(HAVE_GIO)
-
 void
 rhythmdb_entry_move_to_trash (RhythmDB *db,
 			      RhythmDBEntry *entry)
@@ -3291,7 +3536,7 @@
 
 	g_file_trash (file, NULL, &error);
 	if (error != NULL) {
-		GValue value = {0,};
+		GValue value = { 0, };
 
 		g_value_init (&value, G_TYPE_STRING);
 		g_value_set_string (&value, error->message);
@@ -3299,136 +3544,16 @@
 		g_value_unset (&value);
 
 		rb_debug ("trashing %s failed: %s",
-			  uri, error->message);
+			  uri,
+			  error->message);
 		g_error_free (error);
+				
 	} else {
 		rhythmdb_entry_set_visibility (db, entry, FALSE);
 	}
-
 	g_object_unref (file);
 }
 
-#else
-
-static gint
-rhythmdb_entry_move_to_trash_cb (GnomeVFSXferProgressInfo *info,
-				 gpointer data)
-{
-	/* Abort immediately if anything happens */
-	if (info->status == GNOME_VFS_XFER_PROGRESS_STATUS_VFSERROR)
-		return GNOME_VFS_XFER_ERROR_ACTION_ABORT;
-	/* Don't overwrite files */
-	if (info->status == GNOME_VFS_XFER_PROGRESS_STATUS_OVERWRITE)
-		return GNOME_VFS_XFER_OVERWRITE_ACTION_ABORT; /* abort */
-	return 1; /* continue */
-}
-
-static void
-rhythmdb_entry_move_to_trash_set_error (RhythmDB *db,
-					RhythmDBEntry *entry,
-				        GnomeVFSResult res)
-{
-	GValue value = { 0, };
-
-	if (res == -1)
-		res = GNOME_VFS_ERROR_INTERNAL;
-
-	g_value_init (&value, G_TYPE_STRING);
-	g_value_set_string (&value, gnome_vfs_result_to_string (res));
-	rhythmdb_entry_set (db, entry, RHYTHMDB_PROP_PLAYBACK_ERROR, &value);
-	g_value_unset (&value);
-
-	rb_debug ("Deleting %s failed: %s", rb_refstring_get (entry->location),
-			gnome_vfs_result_to_string (res));
-}
-
-void
-rhythmdb_entry_move_to_trash (RhythmDB *db,
-			      RhythmDBEntry *entry)
-{
-	GnomeVFSResult res;
-	GnomeVFSURI *uri, *trash, *dest;
-	char *shortname;
-
-	uri = gnome_vfs_uri_new (rb_refstring_get (entry->location));
-	if (uri == NULL) {
-		rhythmdb_entry_move_to_trash_set_error (db, entry, -1);
-		return;
-	}
-
-	res = gnome_vfs_find_directory (uri,
-					GNOME_VFS_DIRECTORY_KIND_TRASH,
-					&trash,
-					TRUE, TRUE,
-					0);
-	if (res != GNOME_VFS_OK || trash == NULL) {
-		/* If the file doesn't exist, or trash isn't support,
-		 * remove it from the db */
-		if (res == GNOME_VFS_ERROR_NOT_FOUND ||
-		    res == GNOME_VFS_ERROR_NOT_SUPPORTED) {
-			rhythmdb_entry_set_visibility (db, entry, FALSE);
-		} else {
-			rhythmdb_entry_move_to_trash_set_error (db, entry, -1);
-		}
-
-		gnome_vfs_uri_unref (uri);
-		return;
-	}
-
-	/* Is the file already in the Trash? If so it should be hidden */
-	if (gnome_vfs_uri_is_parent (trash, uri, TRUE)) {
-		GValue value = { 0, };
-		g_value_init (&value, G_TYPE_BOOLEAN);
-		g_value_set_boolean (&value, TRUE);
-		rhythmdb_entry_set (db, entry, RHYTHMDB_PROP_HIDDEN, &value);
-		rhythmdb_commit (db);
-
-		gnome_vfs_uri_unref (trash);
-		gnome_vfs_uri_unref (uri);
-		return;
-	}
-
-	shortname = gnome_vfs_uri_extract_short_name (uri);
-	if (shortname == NULL) {
-		rhythmdb_entry_move_to_trash_set_error (db, entry, -1);
-		rhythmdb_commit (db);
-		gnome_vfs_uri_unref (uri);
-		gnome_vfs_uri_unref (trash);
-		return;
-	}
-
-	/* Compute the destination URI */
-	dest = gnome_vfs_uri_append_path (trash, shortname);
-	gnome_vfs_uri_unref (trash);
-	g_free (shortname);
-	if (dest == NULL) {
-		rhythmdb_entry_move_to_trash_set_error (db, entry, -1);
-		rhythmdb_commit (db);
-		gnome_vfs_uri_unref (uri);
-		return;
-	}
-
-	/* RB can't tell that a file's moved, so no unique names */
-	res = gnome_vfs_xfer_uri (uri, dest,
-				  GNOME_VFS_XFER_REMOVESOURCE,
-				  GNOME_VFS_XFER_ERROR_MODE_ABORT,
-				  GNOME_VFS_XFER_OVERWRITE_MODE_SKIP,
-				  rhythmdb_entry_move_to_trash_cb,
-				  entry);
-
-	if (res == GNOME_VFS_OK) {
-		rhythmdb_entry_set_visibility (db, entry, FALSE);
-	} else {
-		rhythmdb_entry_move_to_trash_set_error (db, entry, res);
-	}
-	rhythmdb_commit (db);
-
-	gnome_vfs_uri_unref (dest);
-	gnome_vfs_uri_unref (uri);
-}
-
-#endif
-
 /**
  * rhythmdb_entry_delete_by_type:
  * @db: a #RhythmDB.
@@ -3656,7 +3781,7 @@
 	rb_debug ("completed");
 	rhythmdb_query_results_query_complete (data->results);
 
-	result = g_new0 (RhythmDBEvent, 1);
+	result = g_slice_new0 (RhythmDBEvent);
 	result->db = data->db;
 	result->type = RHYTHMDB_EVENT_QUERY_COMPLETE;
 	result->results = data->results;
@@ -3674,7 +3799,7 @@
 
 	rhythmdb_query_internal (data);
 
-	result = g_new0 (RhythmDBEvent, 1);
+	result = g_slice_new0 (RhythmDBEvent);
 	result->db = data->db;
 	result->type = RHYTHMDB_EVENT_THREAD_EXITED;
 	rhythmdb_push_event (data->db, result);
@@ -4087,9 +4212,9 @@
 rhythmdb_is_busy (RhythmDB *db)
 {
 	return (!db->priv->action_thread_running ||
+		db->priv->stat_thread_running ||
 		!queue_is_empty (db->priv->event_queue) ||
 		!queue_is_empty (db->priv->action_queue) ||
-		(db->priv->stat_handle != NULL) ||
 		(db->priv->outstanding_stats != NULL));
 }
 
@@ -4175,7 +4300,7 @@
 		}
 	}
 
-	size_str = gnome_vfs_format_file_size_for_display (size);
+	size_str = g_format_size_for_display (size);
 
 	if (size > 0 && duration > 0) {
 		ret = g_strdup_printf ("%s, %s, %s", songcount, time, size_str);
@@ -4221,7 +4346,7 @@
 		rb_debug ("error saving metadata for %s: %s; reloading metadata to revert",
 			  rb_refstring_get (entry->location),
 			  local_error->message);
-		load_action = g_new0 (RhythmDBAction, 1);
+		load_action = g_slice_new0 (RhythmDBAction);
 		load_action->type = RHYTHMDB_ACTION_LOAD;
 		load_action->uri = rb_refstring_ref (entry->location);
 		load_action->entry_type = RHYTHMDB_ENTRY_TYPE_INVALID;

Modified: trunk/rhythmdb/rhythmdb.h
==============================================================================
--- trunk/rhythmdb/rhythmdb.h	(original)
+++ trunk/rhythmdb/rhythmdb.h	Tue Jul 29 13:17:53 2008
@@ -32,6 +32,7 @@
 
 #include <glib.h>
 #include <glib-object.h>
+#include <gio/gio.h>
 #include <stdarg.h>
 #include <libxml/tree.h>
 
@@ -298,7 +299,7 @@
 
 	/* virtual methods */
 
-	gboolean	(*impl_load)		(RhythmDB *db, gboolean *dead, GError **error);
+	gboolean	(*impl_load)		(RhythmDB *db, GCancellable *cancel, GError **error);
 	void		(*impl_save)		(RhythmDB *db);
 
 	void		(*impl_entry_new)	(RhythmDB *db, RhythmDBEntry *entry);

Modified: trunk/shell/Makefile.am
==============================================================================
--- trunk/shell/Makefile.am	(original)
+++ trunk/shell/Makefile.am	Tue Jul 29 13:17:53 2008
@@ -98,7 +98,8 @@
 	$(top_builddir)/corelib/librhythmbox-core.la	\
 	$(top_builddir)/sources/libsourcesimpl.la	\
 	$(top_builddir)/podcast/librbpodcast.la	        \
-	$(top_builddir)/plugins/librbplugins.la	
+	$(top_builddir)/plugins/librbplugins.la		\
+	-lgstpbutils-0.10
 
 if USE_LIBSOUP
 rhythmbox_LDADD += $(SOUP_LIBS)
@@ -120,11 +121,6 @@
 INCLUDES += $(GNOME_MEDIA_PROFILES_CFLAGS)
 endif
 
-if USE_GSTREAMER_0_10_MISSING_PLUGINS
-rhythmbox_LDADD +=					\
-	-lgstpbutils-0.10
-endif
-
 rb-shell-glue.h: rb-shell.xml Makefile
 	$(LIBTOOL) --mode=execute $(DBUS_GLIB_BIN)/dbus-binding-tool --prefix=rb_shell --mode=glib-server --output=$@ $<
 rb-shell-player-glue.h: rb-shell-player.xml Makefile

Modified: trunk/shell/main.c
==============================================================================
--- trunk/shell/main.c	(original)
+++ trunk/shell/main.c	Tue Jul 29 13:17:53 2008
@@ -56,7 +56,6 @@
 #include <libgnome/gnome-program.h>
 #include <libgnomeui/gnome-ui-init.h>
 #include <libgnomeui/gnome-app-helper.h>
-#include <libgnomeui/gnome-authentication-manager.h>
 
 #include <gst/gst.h>
 
@@ -167,10 +166,6 @@
 
 	rb_profile_end ("initializing gnome program");
 
-	rb_profile_start ("initializing gnome auth manager");
-	gnome_authentication_manager_init ();
-	rb_profile_end ("initializing gnome auth manager");
-
 	g_random_set_seed (time (0));
 
 #ifdef ENABLE_NLS
@@ -343,8 +338,6 @@
 		rb_file_helpers_shutdown ();
 		rb_stock_icons_shutdown ();
 		rb_refstring_system_shutdown ();
-
-		gnome_vfs_shutdown ();
 	}
 
 	gst_deinit ();
@@ -369,16 +362,24 @@
 
 	handled = FALSE;
 	for (i = 0; args && args[i]; i++) {
+		GFile *file;
 		char *uri;
 
 		rb_debug ("examining argument %s", args[i]);
 
-		uri = gnome_vfs_make_uri_from_shell_arg (args[i]);
+		file = g_file_new_for_commandline_arg (args[i]);
+		uri = g_file_get_uri (file);
 
+		/*
+		 * rb_uri_exists won't work if the location isn't mounted.
+		 * however, things that are interesting to mount are generally
+		 * non-local, so we'll process them anyway.
+		 */
 		if (rb_uri_is_local (uri) == FALSE || rb_uri_exists (uri)) {
 			handler (uri, user_data);
 		}
 		g_free (uri);
+		g_object_unref (file);
 
 		handled = TRUE;
 	}

Modified: trunk/shell/rb-history.c
==============================================================================
--- trunk/shell/rb-history.c	(original)
+++ trunk/shell/rb-history.c	Tue Jul 29 13:17:53 2008
@@ -31,7 +31,7 @@
 #include "config.h"
 
 #include <string.h>
-#include <gsequence.h>
+#include <glib/gsequence.h>
 
 #include "rb-history.h"
 

Modified: trunk/shell/rb-missing-plugins.c
==============================================================================
--- trunk/shell/rb-missing-plugins.c	(original)
+++ trunk/shell/rb-missing-plugins.c	Tue Jul 29 13:17:53 2008
@@ -25,8 +25,6 @@
 
 #include "rb-missing-plugins.h"
 
-#ifdef HAVE_GSTREAMER_0_10_MISSING_PLUGINS
-
 #include "rhythmdb.h"
 #include "rb-shell-player.h"
 #include "rb-debug.h"
@@ -263,12 +261,9 @@
 	return missing_plugins_event (shell, ctx);
 }
 
-#endif /* HAVE_GSTREAMER_0_10_MISSING_PLUGINS */
-
 void
 rb_missing_plugins_init (RBShell *shell)
 {
-#ifdef HAVE_GSTREAMER_0_10_MISSING_PLUGINS
 	RhythmDB *db;
 	RBShellPlayer *player;
 	RBSource *podcast_source;
@@ -304,6 +299,5 @@
 	gst_pb_utils_init ();
 
 	GST_INFO ("Set up support for automatic missing plugin installation");
-#endif
 }
 

Modified: trunk/shell/rb-playlist-manager.c
==============================================================================
--- trunk/shell/rb-playlist-manager.c	(original)
+++ trunk/shell/rb-playlist-manager.c	Tue Jul 29 13:17:53 2008
@@ -46,8 +46,6 @@
 #include <libxml/tree.h>
 #include <glib/gi18n.h>
 #include <gtk/gtk.h>
-#include <libgnomevfs/gnome-vfs.h>
-#include <libgnomevfs/gnome-vfs-mime-utils.h>
 
 #include "rb-playlist-manager.h"
 #include "rb-playlist-source.h"

Modified: trunk/shell/rb-removable-media-manager.c
==============================================================================
--- trunk/shell/rb-removable-media-manager.c	(original)
+++ trunk/shell/rb-removable-media-manager.c	Tue Jul 29 13:17:53 2008
@@ -33,7 +33,7 @@
 #include <string.h>
 #include <glib/gi18n.h>
 #include <gtk/gtk.h>
-#include <libgnomevfs/gnome-vfs.h>
+#include <gio/gio.h>
 
 #include "rb-removable-media-manager.h"
 #include "rb-library-source.h"
@@ -69,22 +69,22 @@
 						       RBRemovableMediaManager *manager);
 static void rb_removable_media_manager_cmd_eject_medium (GtkAction *action,
 					       RBRemovableMediaManager *mgr);
+static gboolean rb_removable_media_manager_source_can_eject (RBRemovableMediaManager *mgr);
 static void rb_removable_media_manager_set_uimanager (RBRemovableMediaManager *mgr,
 					     GtkUIManager *uimanager);
 
 static void rb_removable_media_manager_append_media_source (RBRemovableMediaManager *mgr, RBRemovableMediaSource *source);
 
-static void rb_removable_media_manager_mount_volume (RBRemovableMediaManager *mgr,
-				GnomeVFSVolume *volume);
-static void rb_removable_media_manager_unmount_volume (RBRemovableMediaManager *mgr,
-				GnomeVFSVolume *volume);
-
-static void  rb_removable_media_manager_volume_mounted_cb (GnomeVFSVolumeMonitor *monitor,
-				GnomeVFSVolume *volume,
-				gpointer data);
-static void  rb_removable_media_manager_volume_unmounted_cb (GnomeVFSVolumeMonitor *monitor,
-				GnomeVFSVolume *volume,
-				gpointer data);
+static void rb_removable_media_manager_add_volume (RBRemovableMediaManager *mgr, GVolume *volume);
+static void rb_removable_media_manager_remove_volume (RBRemovableMediaManager *mgr, GVolume *volume);
+static void rb_removable_media_manager_add_mount (RBRemovableMediaManager *mgr, GMount *mount);
+static void rb_removable_media_manager_remove_mount (RBRemovableMediaManager *mgr, GMount *mount);
+
+static void volume_added_cb (GVolumeMonitor *monitor, GVolume *volume, RBRemovableMediaManager *manager);
+static void volume_removed_cb (GVolumeMonitor *monitor, GVolume *volume, RBRemovableMediaManager *manager);
+static void mount_added_cb (GVolumeMonitor *monitor, GMount *mount, RBRemovableMediaManager *manager);
+static void mount_removed_cb (GVolumeMonitor *monitor, GMount *mount, RBRemovableMediaManager *manager);
+
 static gboolean rb_removable_media_manager_load_media (RBRemovableMediaManager *manager);
 
 #ifdef ENABLE_TRACK_TRANSFER
@@ -96,7 +96,6 @@
 typedef struct
 {
 	RBShell *shell;
-	gboolean disposed;
 
 	RBSource *selected_source;
 
@@ -105,7 +104,7 @@
 
 	GList *sources;
 	GHashTable *volume_mapping;
-	GList *cur_volume_list;
+	GHashTable *mount_mapping;
 	gboolean scanned;
 
 	GAsyncQueue *transfer_queue;
@@ -113,10 +112,17 @@
 	gint transfer_total;
 	gint transfer_done;
 	double transfer_fraction;
+
+	GVolumeMonitor *volume_monitor;
+	guint mount_added_id;
+	guint mount_pre_unmount_id;
+	guint mount_removed_id;
+	guint volume_added_id;
+	guint volume_removed_id;
 } RBRemovableMediaManagerPrivate;
 
 G_DEFINE_TYPE (RBRemovableMediaManager, rb_removable_media_manager, G_TYPE_OBJECT)
-#define REMOVABLE_MEDIA_MANAGER_GET_PRIVATE(o)   (G_TYPE_INSTANCE_GET_PRIVATE ((o), RB_TYPE_REMOVABLE_MEDIA_MANAGER, RBRemovableMediaManagerPrivate))
+#define GET_PRIVATE(o)   (G_TYPE_INSTANCE_GET_PRIVATE ((o), RB_TYPE_REMOVABLE_MEDIA_MANAGER, RBRemovableMediaManagerPrivate))
 
 enum
 {
@@ -130,7 +136,8 @@
 {
 	MEDIUM_ADDED,
 	TRANSFER_PROGRESS,
-	CREATE_SOURCE,
+	CREATE_SOURCE_VOLUME,
+	CREATE_SOURCE_MOUNT,
 	LAST_SIGNAL
 };
 
@@ -203,15 +210,24 @@
 			      G_TYPE_NONE,
 			      3, G_TYPE_INT, G_TYPE_INT, G_TYPE_DOUBLE);
 
-	rb_removable_media_manager_signals[CREATE_SOURCE] =
-		g_signal_new ("create-source",
+	rb_removable_media_manager_signals[CREATE_SOURCE_VOLUME] =
+		g_signal_new ("create-source-volume",
 			      RB_TYPE_REMOVABLE_MEDIA_MANAGER,
 			      G_SIGNAL_RUN_LAST,
-			      G_STRUCT_OFFSET (RBRemovableMediaManagerClass, create_source),
+			      G_STRUCT_OFFSET (RBRemovableMediaManagerClass, create_source_volume),
 			      rb_signal_accumulator_object_handled, NULL,
 			      rb_marshal_OBJECT__OBJECT,
 			      RB_TYPE_SOURCE,
-			      1, GNOME_VFS_TYPE_VOLUME);
+			      1, G_TYPE_VOLUME);
+	rb_removable_media_manager_signals[CREATE_SOURCE_MOUNT] =
+		g_signal_new ("create-source-mount",
+			      RB_TYPE_REMOVABLE_MEDIA_MANAGER,
+			      G_SIGNAL_RUN_LAST,
+			      G_STRUCT_OFFSET (RBRemovableMediaManagerClass, create_source_mount),
+			      rb_signal_accumulator_object_handled, NULL,
+			      rb_marshal_OBJECT__OBJECT,
+			      RB_TYPE_SOURCE,
+			      1, G_TYPE_MOUNT);
 
 	g_type_class_add_private (klass, sizeof (RBRemovableMediaManagerPrivate));
 }
@@ -219,9 +235,10 @@
 static void
 rb_removable_media_manager_init (RBRemovableMediaManager *mgr)
 {
-	RBRemovableMediaManagerPrivate *priv = REMOVABLE_MEDIA_MANAGER_GET_PRIVATE (mgr);
+	RBRemovableMediaManagerPrivate *priv = GET_PRIVATE (mgr);
 
 	priv->volume_mapping = g_hash_table_new (NULL, NULL);
+	priv->mount_mapping = g_hash_table_new (NULL, NULL);
 	priv->transfer_queue = g_async_queue_new ();
 
 	g_idle_add ((GSourceFunc)rb_removable_media_manager_load_media, mgr);
@@ -231,18 +248,28 @@
 rb_removable_media_manager_dispose (GObject *object)
 {
 	RBRemovableMediaManager *mgr = RB_REMOVABLE_MEDIA_MANAGER (object);
-	RBRemovableMediaManagerPrivate *priv = REMOVABLE_MEDIA_MANAGER_GET_PRIVATE (mgr);
+	RBRemovableMediaManagerPrivate *priv = GET_PRIVATE (mgr);
 
-	if (!priv->disposed)
-	{
-		GnomeVFSVolumeMonitor *monitor = gnome_vfs_get_volume_monitor ();
+	if (priv->volume_monitor != NULL) {
+		g_signal_handler_disconnect (priv->volume_monitor,
+					     priv->mount_added_id);
+		g_signal_handler_disconnect (priv->volume_monitor,
+					     priv->mount_pre_unmount_id);
+		g_signal_handler_disconnect (priv->volume_monitor,
+					     priv->mount_removed_id);
+		g_signal_handler_disconnect (priv->volume_monitor,
+					     priv->volume_added_id);
+		g_signal_handler_disconnect (priv->volume_monitor,
+					     priv->volume_removed_id);
+
+		priv->mount_added_id = 0;
+		priv->mount_pre_unmount_id = 0;
+		priv->mount_removed_id = 0;
+		priv->volume_added_id = 0;
+		priv->volume_removed_id = 0;
 
-		g_signal_handlers_disconnect_by_func (G_OBJECT (monitor),
-						      G_CALLBACK (rb_removable_media_manager_volume_mounted_cb),
-						      mgr);
-		g_signal_handlers_disconnect_by_func (G_OBJECT (monitor),
-						      G_CALLBACK (rb_removable_media_manager_volume_unmounted_cb),
-						      mgr);
+		g_object_unref (priv->volume_monitor);
+		priv->volume_monitor = NULL;
 	}
 
 	if (priv->sources) {
@@ -250,17 +277,16 @@
 		priv->sources = NULL;
 	}
 
-	priv->disposed = TRUE;
-
 	G_OBJECT_CLASS (rb_removable_media_manager_parent_class)->dispose (object);
 }
 
 static void
 rb_removable_media_manager_finalize (GObject *object)
 {
-	RBRemovableMediaManagerPrivate *priv = REMOVABLE_MEDIA_MANAGER_GET_PRIVATE (object);
+	RBRemovableMediaManagerPrivate *priv = GET_PRIVATE (object);
 
 	g_hash_table_destroy (priv->volume_mapping);
+	g_hash_table_destroy (priv->mount_mapping);
 	g_async_queue_unref (priv->transfer_queue);
 
 	G_OBJECT_CLASS (rb_removable_media_manager_parent_class)->finalize (object);
@@ -272,13 +298,20 @@
 				  const GValue *value,
 				  GParamSpec *pspec)
 {
-	RBRemovableMediaManagerPrivate *priv = REMOVABLE_MEDIA_MANAGER_GET_PRIVATE (object);
+	RBRemovableMediaManagerPrivate *priv = GET_PRIVATE (object);
 
 	switch (prop_id)
 	{
 	case PROP_SOURCE:
 	{
+		GtkAction *action;
+		gboolean can_eject;
+
 		priv->selected_source = g_value_get_object (value);
+		/* make 'eject' command sensitive if the source can be ejected. */
+		action = gtk_action_group_get_action (priv->actiongroup, "RemovableSourceEject");
+		can_eject = rb_removable_media_manager_source_can_eject (RB_REMOVABLE_MEDIA_MANAGER (object));
+		gtk_action_set_sensitive (action, can_eject);
 		break;
 	}
 	case PROP_SHELL:
@@ -304,7 +337,7 @@
 			      GValue *value,
 			      GParamSpec *pspec)
 {
-	RBRemovableMediaManagerPrivate *priv = REMOVABLE_MEDIA_MANAGER_GET_PRIVATE (object);
+	RBRemovableMediaManagerPrivate *priv = GET_PRIVATE (object);
 
 	switch (prop_id)
 	{
@@ -334,45 +367,82 @@
 static gboolean
 rb_removable_media_manager_load_media (RBRemovableMediaManager *manager)
 {
-	GnomeVFSVolumeMonitor *monitor = gnome_vfs_get_volume_monitor ();
+	RBRemovableMediaManagerPrivate *priv = GET_PRIVATE (manager);
 
 	GDK_THREADS_ENTER ();
 	
 	/*
-	 * Monitor new (un)mounted file systems to look for new media
+	 * Monitor new (un)mounted file systems to look for new media;
+	 * we watch for both volumes and mounts because for some devices,
+	 * we don't require the volume to actually be mounted.
 	 *
 	 * both pre-unmount and unmounted callbacks are registered because it is
 	 * better to do it before the unmount, but sometimes we don't get those
 	 * (e.g. someone pressing the eject button on a cd drive). If we get the
-	 * pre-unmount signal, the corrosponding unmounted signal is ignored
+	 * pre-unmount signal, the corresponding unmounted signal is ignored
 	 */
-	g_signal_connect (G_OBJECT (monitor), "volume-mounted",
-			  G_CALLBACK (rb_removable_media_manager_volume_mounted_cb),
-			  manager);
-	g_signal_connect (G_OBJECT (monitor), "volume-pre-unmount",
-			  G_CALLBACK (rb_removable_media_manager_volume_unmounted_cb),
-			  manager);
-	g_signal_connect (G_OBJECT (monitor), "volume-unmounted",
-			  G_CALLBACK (rb_removable_media_manager_volume_unmounted_cb),
-			  manager);
+	priv->volume_monitor = g_object_ref (g_volume_monitor_get ());
+
+	priv->volume_added_id = g_signal_connect_object (priv->volume_monitor,
+							 "volume-added",
+							 G_CALLBACK (volume_added_cb),
+							 manager, 0);
+	priv->volume_removed_id = g_signal_connect_object (priv->volume_monitor,
+							   "volume-removed",
+							   G_CALLBACK (volume_removed_cb),
+							   manager, 0);
+	priv->mount_added_id = g_signal_connect_object (priv->volume_monitor,
+							"mount-added",
+							G_CALLBACK (mount_added_cb),
+							manager, 0);
+	priv->mount_pre_unmount_id = g_signal_connect_object (priv->volume_monitor,
+							      "mount-pre-unmount",
+							      G_CALLBACK (mount_removed_cb),
+							      manager, 0);
+	priv->mount_removed_id = g_signal_connect_object (G_OBJECT (priv->volume_monitor),
+							  "mount-removed",
+							  G_CALLBACK (mount_removed_cb),
+							  manager, 0);
 
 	GDK_THREADS_LEAVE ();
 	return FALSE;
 }
 
 static void
-rb_removable_media_manager_volume_mounted_cb (GnomeVFSVolumeMonitor *monitor,
-			   GnomeVFSVolume *volume,
-			   gpointer data)
+volume_added_cb (GVolumeMonitor *monitor,
+		 GVolume *volume,
+		 RBRemovableMediaManager *mgr)
 {
-	RBRemovableMediaManager *mgr = RB_REMOVABLE_MEDIA_MANAGER (data);
+	rb_removable_media_manager_add_volume (mgr, volume);
+}
 
-	rb_removable_media_manager_mount_volume (mgr, volume);
+static void
+volume_removed_cb (GVolumeMonitor *monitor,
+		   GVolume *volume,
+		   RBRemovableMediaManager *mgr)
+{
+	rb_removable_media_manager_remove_volume (mgr, volume);
 }
 
+static void
+mount_added_cb (GVolumeMonitor *monitor,
+		GMount *mount,
+		RBRemovableMediaManager *mgr)
+{
+	rb_removable_media_manager_add_mount (mgr, mount);
+}
+
+static void
+mount_removed_cb (GVolumeMonitor *monitor,
+		  GMount *mount,
+		  RBRemovableMediaManager *mgr)
+{
+	rb_removable_media_manager_remove_mount (mgr, mount);
+}
+
+
 static gboolean
-remove_volume_by_source (GnomeVFSVolume *volume, RBSource *source,
-			 RBSource *ref_source)
+remove_by_source (gpointer thing, RBSource *source, RBSource *ref_source)
 {
 	return (ref_source == source);
 }
@@ -380,96 +450,149 @@
 static void
 rb_removable_media_manager_source_deleted_cb (RBSource *source, RBRemovableMediaManager *mgr)
 {
-	RBRemovableMediaManagerPrivate *priv = REMOVABLE_MEDIA_MANAGER_GET_PRIVATE (mgr);
+	RBRemovableMediaManagerPrivate *priv = GET_PRIVATE (mgr);
 
 	rb_debug ("removing source %p", source);
 	g_hash_table_foreach_remove (priv->volume_mapping,
-				     (GHRFunc)remove_volume_by_source,
+				     (GHRFunc)remove_by_source,
+				     source);
+	g_hash_table_foreach_remove (priv->mount_mapping,
+				     (GHRFunc)remove_by_source,
 				     source);
 	priv->sources = g_list_remove (priv->sources, source);
 }
 
 static void
-rb_removable_media_manager_volume_unmounted_cb (GnomeVFSVolumeMonitor *monitor,
-			     GnomeVFSVolume *volume,
-			     gpointer data)
+dump_volume_identifiers (GVolume *volume)
 {
-	RBRemovableMediaManager *mgr = RB_REMOVABLE_MEDIA_MANAGER (data);
+	char **identifiers;
+	int i;
 
-	g_assert (volume != NULL);
-	rb_removable_media_manager_unmount_volume (mgr, volume);
+	if (volume == NULL) {
+		rb_debug ("mount has no volume");
+		return;
+	}
+
+	/* dump all volume identifiers in debug output */
+	identifiers = g_volume_enumerate_identifiers (volume);
+	if (identifiers != NULL) {
+		for (i = 0; identifiers[i] != NULL; i++) {
+			char *ident;
+
+			ident = g_volume_get_identifier (volume, identifiers[i]);
+			rb_debug ("%s = %s", identifiers[i], ident);
+		}
+		g_strfreev (identifiers);
+	}
 }
 
 static void
-rb_removable_media_manager_mount_volume (RBRemovableMediaManager *mgr, GnomeVFSVolume *volume)
+rb_removable_media_manager_add_volume (RBRemovableMediaManager *mgr, GVolume *volume)
 {
-	RBRemovableMediaManagerPrivate *priv = REMOVABLE_MEDIA_MANAGER_GET_PRIVATE (mgr);
+	RBRemovableMediaManagerPrivate *priv = GET_PRIVATE (mgr);
 	RBRemovableMediaSource *source = NULL;
-	char *fs_type, *device_path, *display_name, *hal_udi, *icon_name;
-	GnomeVFSDeviceType device_type;
+	GMount *mount;
 
 	g_assert (volume != NULL);
 
-	if (g_hash_table_lookup (priv->volume_mapping, volume) != NULL)
+	if (g_hash_table_lookup (priv->volume_mapping, volume) != NULL) {
 		return;
+	}
 
-	if (!gnome_vfs_volume_is_mounted (volume))
+	mount = g_volume_get_mount (volume);
+	if (mount != NULL) {
+		if (g_hash_table_lookup (priv->mount_mapping, mount) != NULL) {
+			/* this can probably never happen, but it's OK */
+			rb_debug ("already created a source for the mount, so ignoring the volume");
+			g_object_unref (mount);
+			return;
+		}
+		g_object_unref (mount);
+	}
+
+	dump_volume_identifiers (volume);
+
+	g_signal_emit (G_OBJECT (mgr), rb_removable_media_manager_signals[CREATE_SOURCE_VOLUME], 0, volume, &source);
+
+	if (source) {
+		g_hash_table_insert (priv->volume_mapping, volume, source);
+		rb_removable_media_manager_append_media_source (mgr, source);
+	} else {
+		rb_debug ("Unhandled media");
+	}
+
+}
+
+static void
+rb_removable_media_manager_remove_volume (RBRemovableMediaManager *mgr, GVolume *volume)
+{
+	RBRemovableMediaManagerPrivate *priv = GET_PRIVATE (mgr);
+	RBRemovableMediaSource *source;
+
+	g_assert (volume != NULL);
+
+	rb_debug ("volume removed");
+	source = g_hash_table_lookup (priv->volume_mapping, volume);
+	if (source) {
+		rb_source_delete_thyself (RB_SOURCE (source));
+	}
+}
+
+static void
+rb_removable_media_manager_add_mount (RBRemovableMediaManager *mgr, GMount *mount)
+{
+	RBRemovableMediaManagerPrivate *priv = GET_PRIVATE (mgr);
+	RBRemovableMediaSource *source = NULL;
+	GVolume *volume;
+
+	g_assert (mount != NULL);
+
+	if (g_hash_table_lookup (priv->mount_mapping, mount) != NULL) {
 		return;
+	}
+
+	volume = g_mount_get_volume (mount);
 
-	/* ignore network volumes */
-	device_type = gnome_vfs_volume_get_device_type (volume);
-	if (device_type == GNOME_VFS_DEVICE_TYPE_NFS ||
-	    device_type == GNOME_VFS_DEVICE_TYPE_AUTOFS ||
-	    device_type == GNOME_VFS_DEVICE_TYPE_SMB ||
-	    device_type == GNOME_VFS_DEVICE_TYPE_NETWORK)
+	/* if we've already created a source for the volume,
+	 * don't do anything with the mount.
+	 */
+	if (g_hash_table_lookup (priv->volume_mapping, volume) != NULL) {
+		rb_debug ("already created a source for the volume, so ignoring the mount");
+		g_object_unref (volume);
 		return;
+	}
+
+	dump_volume_identifiers (volume);
 
-	fs_type = gnome_vfs_volume_get_filesystem_type (volume);
-	device_path = gnome_vfs_volume_get_device_path (volume);
-	display_name = gnome_vfs_volume_get_display_name (volume);
-	hal_udi = gnome_vfs_volume_get_hal_udi (volume);
-	icon_name = gnome_vfs_volume_get_icon (volume);
-	rb_debug ("detecting new media - device type=%d", device_type);
-	rb_debug ("detecting new media - volume type=%d", gnome_vfs_volume_get_volume_type (volume));
-	rb_debug ("detecting new media - fs type=%s", fs_type);
-	rb_debug ("detecting new media - device path=%s", device_path);
-	rb_debug ("detecting new media - display name=%s", display_name);
-	rb_debug ("detecting new media - hal udi=%s", hal_udi);
-	rb_debug ("detecting new media - icon=%s", icon_name);
-
-	/* rb_xxx_source_new first checks if the 'volume' parameter corresponds
-	 * to a medium of type 'xxx', and returns NULL if it doesn't.
-	 * When volume is of the appropriate type, it creates a new source
-	 * to handle this volume
+	/* might be worth trying to create a source for the volume again,
+	 * in case something wants to, but requires a mount to exist first.
 	 */
 
-	g_signal_emit (G_OBJECT (mgr), rb_removable_media_manager_signals[CREATE_SOURCE], 0,
-		       volume, &source);
+
+	g_signal_emit (G_OBJECT (mgr), rb_removable_media_manager_signals[CREATE_SOURCE_MOUNT], 0, mount, &source);
 
 	if (source) {
-		g_hash_table_insert (priv->volume_mapping, volume, source);
+		g_hash_table_insert (priv->mount_mapping, mount, source);
 		rb_removable_media_manager_append_media_source (mgr, source);
 	} else {
 		rb_debug ("Unhandled media");
 	}
 
-	g_free (fs_type);
-	g_free (device_path);
-	g_free (display_name);
-	g_free (hal_udi);
-	g_free (icon_name);
+	if (volume != NULL) {
+		g_object_unref (volume);
+	}
 }
 
 static void
-rb_removable_media_manager_unmount_volume (RBRemovableMediaManager *mgr, GnomeVFSVolume *volume)
+rb_removable_media_manager_remove_mount (RBRemovableMediaManager *mgr, GMount *mount)
 {
-	RBRemovableMediaManagerPrivate *priv = REMOVABLE_MEDIA_MANAGER_GET_PRIVATE (mgr);
+	RBRemovableMediaManagerPrivate *priv = GET_PRIVATE (mgr);
 	RBRemovableMediaSource *source;
 
-	g_assert (volume != NULL);
+	g_assert (mount != NULL);
 
-	rb_debug ("media removed");
-	source = g_hash_table_lookup (priv->volume_mapping, volume);
+	rb_debug ("mount removed");
+	source = g_hash_table_lookup (priv->mount_mapping, mount);
 	if (source) {
 		rb_source_delete_thyself (RB_SOURCE (source));
 	}
@@ -478,7 +601,7 @@
 static void
 rb_removable_media_manager_append_media_source (RBRemovableMediaManager *mgr, RBRemovableMediaSource *source)
 {
-	RBRemovableMediaManagerPrivate *priv = REMOVABLE_MEDIA_MANAGER_GET_PRIVATE (mgr);
+	RBRemovableMediaManagerPrivate *priv = GET_PRIVATE (mgr);
 
 	priv->sources = g_list_prepend (priv->sources, source);
 	g_signal_connect_object (G_OBJECT (source), "deleted",
@@ -492,7 +615,7 @@
 rb_removable_media_manager_set_uimanager (RBRemovableMediaManager *mgr,
 					  GtkUIManager *uimanager)
 {
-	RBRemovableMediaManagerPrivate *priv = REMOVABLE_MEDIA_MANAGER_GET_PRIVATE (mgr);
+	RBRemovableMediaManagerPrivate *priv = GET_PRIVATE (mgr);
 	GtkAction *action;
 
 	if (priv->uimanager != NULL) {
@@ -522,8 +645,6 @@
 
 #ifndef ENABLE_TRACK_TRANSFER
 	{
-		GtkAction *action;
-
 		action = gtk_action_group_get_action (priv->actiongroup, "RemovableSourceCopyAllTracks");
 		gtk_action_set_visible (action, FALSE);
 	}
@@ -542,89 +663,206 @@
 }
 
 static void
-rb_removable_media_manager_eject_medium_cb (gboolean succeeded,
-					   const char *error,
-					   const char *detailed_error,
-					   gpointer *data)
-{
-	if (succeeded)
-		return;
+rb_removable_media_manager_eject_cb (GObject *object,
+				     GAsyncResult *result,
+				     RBRemovableMediaManager *mgr)
+{
+	GError *error = NULL;
+
+	if (G_IS_VOLUME (object)) {
+		GVolume *volume = G_VOLUME (object);
+
+		rb_debug ("finishing ejection of volume");
+		g_volume_eject_finish (volume, result, &error);
+		if (error == NULL) {
+			rb_removable_media_manager_remove_volume (mgr, volume);
+		}
+	} else if (G_IS_MOUNT (object)) {
+		GMount *mount = G_MOUNT (object);
 
-	rb_error_dialog (NULL, error, "%s", detailed_error);
+		rb_debug ("finishing ejection of mount");
+		g_mount_eject_finish (mount, result, &error);
+		if (error == NULL) {
+			rb_removable_media_manager_remove_mount (mgr, mount);
+		}
+	}
+
+	if (error != NULL) {
+		if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_FAILED_HANDLED)) {
+			rb_error_dialog (NULL, _("Unable to eject"), "%s", error->message);
+		} else {
+			rb_debug ("eject failure has already been handled");
+		}
+		g_error_free (error);
+	}
+	g_object_unref (mgr);
 }
 
 static void
-rb_removable_media_manager_cmd_eject_medium (GtkAction *action, RBRemovableMediaManager *mgr)
+rb_removable_media_manager_unmount_cb (GObject *object,
+				       GAsyncResult *result,
+				       RBRemovableMediaManager *mgr)
 {
-	RBRemovableMediaManagerPrivate *priv = REMOVABLE_MEDIA_MANAGER_GET_PRIVATE (mgr);
-	RBRemovableMediaSource *source = RB_REMOVABLE_MEDIA_SOURCE (priv->selected_source);
-	GnomeVFSVolume *volume;
+	GMount *mount = G_MOUNT (object);
+	GError *error = NULL;
 
-	g_object_get (source, "volume", &volume, NULL);
-	rb_removable_media_manager_unmount_volume (mgr, volume);
-	gnome_vfs_volume_eject (volume, (GnomeVFSVolumeOpCallback)rb_removable_media_manager_eject_medium_cb, mgr);
-	gnome_vfs_volume_unref (volume);
+	rb_debug ("finishing unmount of mount");
+	g_mount_unmount_finish (mount, result, &error);
+	if (error != NULL) {
+		if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_FAILED_HANDLED)) {
+			rb_error_dialog (NULL, _("Unable to unmount"), "%s", error->message);
+		} else {
+			rb_debug ("unmount failure has already been handled");
+		}
+		g_error_free (error);
+	} else {
+		rb_removable_media_manager_remove_mount (mgr, mount);
+	}
+	g_object_unref (mgr);
 }
 
-static void
-rb_removable_media_manager_cmd_scan_media (GtkAction *action, RBRemovableMediaManager *manager)
+static gboolean
+rb_removable_media_manager_source_can_eject (RBRemovableMediaManager *mgr)
 {
-	rb_removable_media_manager_scan (manager);
-}
+	RBRemovableMediaManagerPrivate *priv = GET_PRIVATE (mgr);
+	GVolume *volume;
+	GMount *mount;
+	gboolean result;
 
-struct VolumeCheckData
-{
-	RBRemovableMediaManager *manager;
-	GList *volume_list;
-	GList *volumes_to_remove;
-};
+	if (RB_IS_REMOVABLE_MEDIA_SOURCE (priv->selected_source) == FALSE) {
+		return FALSE;
+	}
+
+	g_object_get (priv->selected_source, "volume", &volume, NULL);
+	if (volume != NULL) {
+		result = g_volume_can_eject (volume);
+		g_object_unref (volume);
+		return result;
+	}
+
+	g_object_get (priv->selected_source, "mount", &mount, NULL);
+	if (mount != NULL) {
+		result = g_mount_can_eject (mount) || g_mount_can_unmount (mount);
+		g_object_unref (mount);
+		return result;
+	}
+
+	return FALSE;
+}
 
 static void
-rb_removable_media_manager_check_volume (GnomeVFSVolume *volume,
-					 RBRemovableMediaSource *source,
-					 struct VolumeCheckData *check_data)
+rb_removable_media_manager_cmd_eject_medium (GtkAction *action, RBRemovableMediaManager *mgr)
 {
-	/* if the volume is no longer present, queue it for removal */
-	if (g_list_find (check_data->volume_list, volume) == NULL)
-		check_data->volumes_to_remove = g_list_prepend (check_data->volumes_to_remove, volume);
+	RBRemovableMediaManagerPrivate *priv = GET_PRIVATE (mgr);
+	RBRemovableMediaSource *source = RB_REMOVABLE_MEDIA_SOURCE (priv->selected_source);
+	GVolume *volume;
+	GMount *mount;
+
+	/* try ejecting based on volume first, then based on the mount,
+	 * and finally try unmounting.
+	 */
+
+	g_object_get (source, "volume", &volume, NULL);
+	if (volume != NULL) {
+		if (g_volume_can_eject (volume)) {
+			rb_debug ("ejecting volume");
+			g_volume_eject (volume,
+					G_MOUNT_UNMOUNT_NONE,
+					NULL,
+					(GAsyncReadyCallback) rb_removable_media_manager_eject_cb,
+					g_object_ref (mgr));
+		} else {
+			/* this should never happen; the eject command will be
+			 * insensitive if the selected source cannot be ejected.
+			 */
+			rb_debug ("don't know what to do with this volume");
+		}
+		g_object_unref (volume);
+		return;
+	}
+
+	g_object_get (source, "mount", &mount, NULL);
+	if (mount != NULL) {
+		if (g_mount_can_eject (mount)) {
+			rb_debug ("ejecting mount");
+			g_mount_eject (mount,
+				       G_MOUNT_UNMOUNT_NONE,
+				       NULL,
+				       (GAsyncReadyCallback) rb_removable_media_manager_eject_cb,
+				       g_object_ref (mgr));
+		} else if (g_mount_can_unmount (mount)) {
+			rb_debug ("unmounting mount");
+			g_mount_unmount (mount,
+					 G_MOUNT_UNMOUNT_NONE,
+					 NULL,
+					 (GAsyncReadyCallback) rb_removable_media_manager_unmount_cb,
+					 g_object_ref (mgr));
+		} else {
+			/* this should never happen; the eject command will be
+			 * insensitive if the selected source cannot be ejected.
+			 */
+			rb_debug ("don't know what to do with this mount");
+		}
+		g_object_unref (mount);
+	}
 }
 
 static void
-rb_removable_media_manager_unmount_volume_swap (GnomeVFSVolume *volume, RBRemovableMediaManager *manager)
+rb_removable_media_manager_cmd_scan_media (GtkAction *action, RBRemovableMediaManager *manager)
 {
-	rb_removable_media_manager_unmount_volume (manager, volume);
+	rb_removable_media_manager_scan (manager);
 }
 
 void
 rb_removable_media_manager_scan (RBRemovableMediaManager *manager)
 {
-	RBRemovableMediaManagerPrivate *priv = REMOVABLE_MEDIA_MANAGER_GET_PRIVATE (manager);
-	GnomeVFSVolumeMonitor *monitor = gnome_vfs_get_volume_monitor ();
+	RBRemovableMediaManagerPrivate *priv = GET_PRIVATE (manager);
+	GHashTableIter iter;
 	GList *list, *it;
-	GnomeVFSVolume *volume;
-	struct VolumeCheckData check_data;
+	gpointer hkey, hvalue;
 
 	priv->scanned = TRUE;
 
-	list = gnome_vfs_volume_monitor_get_mounted_volumes (monitor);
+	/* check volumes first */
+	list = g_volume_monitor_get_volumes (priv->volume_monitor);
+
+	/* - check for volumes that have disappeared */
+	g_hash_table_iter_init (&iter, priv->volume_mapping);
+	while (g_hash_table_iter_next (&iter, &hkey, &hvalue)) {
+		GVolume *volume = G_VOLUME (hkey);
+
+		if (g_list_index (list, volume) == -1) {
+			/* volume has vanished */
+			rb_removable_media_manager_remove_volume (manager, volume);
+		}
+	}
+
+	/* - check for newly added volumes */
+	for (it = list; it != NULL; it = g_list_next (it)) {
+		GVolume *volume = G_VOLUME (it->data);
+		rb_removable_media_manager_add_volume (manager, volume);
+		g_object_unref (volume);
+	}
+	g_list_free (list);
+
+	/* check mounts */
+	list = g_volume_monitor_get_mounts (priv->volume_monitor);
+
+	/* - check for mounts that have disappeared */
+	g_hash_table_iter_init (&iter, priv->mount_mapping);
+	while (g_hash_table_iter_next (&iter, &hkey, &hvalue)) {
+		GMount *mount = G_MOUNT (hkey);
 
-	/* see if any removable media has gone */
-	check_data.volume_list = list;
-	check_data.manager = manager;
-	check_data.volumes_to_remove = NULL;
-	g_hash_table_foreach (priv->volume_mapping,
-			      (GHFunc) rb_removable_media_manager_check_volume,
-			      &check_data);
-	g_list_foreach (check_data.volumes_to_remove,
-			(GFunc) rb_removable_media_manager_unmount_volume_swap,
-			manager);
-	g_list_free (check_data.volumes_to_remove);
+		if (g_list_index (list, mount) == -1) {
+			rb_removable_media_manager_remove_mount (manager, mount);
+		}
+	}
 
-	/* look for new volume media */
+	/* - check for newly added mounts */
 	for (it = list; it != NULL; it = g_list_next (it)) {
-		volume = GNOME_VFS_VOLUME (it->data);
-		rb_removable_media_manager_mount_volume (manager, volume);
-		gnome_vfs_volume_unref (volume);
+		GMount *mount = G_MOUNT (it->data);
+		rb_removable_media_manager_add_mount (manager, mount);
+		g_object_unref (mount);
 	}
 	g_list_free (list);
 }
@@ -639,14 +877,14 @@
 	guint64 dest_size;
 	GList *mime_types;
 	gboolean failed;
-	RBTranferCompleteCallback callback;
+	RBTransferCompleteCallback callback;
 	gpointer userdata;
 } TransferData;
 
 static void
 emit_progress (RBRemovableMediaManager *mgr)
 {
-	RBRemovableMediaManagerPrivate *priv = REMOVABLE_MEDIA_MANAGER_GET_PRIVATE (mgr);
+	RBRemovableMediaManagerPrivate *priv = GET_PRIVATE (mgr);
 
 	g_signal_emit (G_OBJECT (mgr), rb_removable_media_manager_signals[TRANSFER_PROGRESS], 0,
 		       priv->transfer_done,
@@ -667,7 +905,7 @@
 static void
 progress_cb (RBEncoder *encoder, double fraction, TransferData *data)
 {
-	RBRemovableMediaManagerPrivate *priv = REMOVABLE_MEDIA_MANAGER_GET_PRIVATE (data->manager);
+	RBRemovableMediaManagerPrivate *priv = GET_PRIVATE (data->manager);
 
 	rb_debug ("transfer progress %f", (float)fraction);
 	priv->transfer_fraction = fraction;
@@ -677,7 +915,7 @@
 static void
 completed_cb (RBEncoder *encoder, guint64 dest_size, TransferData *data)
 {
-	RBRemovableMediaManagerPrivate *priv = REMOVABLE_MEDIA_MANAGER_GET_PRIVATE (data->manager);
+	RBRemovableMediaManagerPrivate *priv = GET_PRIVATE (data->manager);
 
 	rb_debug ("completed transferring track to %s (%" G_GUINT64_FORMAT " bytes)", data->dest, dest_size);
 	if (!data->failed)
@@ -697,7 +935,7 @@
 static void
 do_transfer (RBRemovableMediaManager *manager)
 {
-	RBRemovableMediaManagerPrivate *priv = REMOVABLE_MEDIA_MANAGER_GET_PRIVATE (manager);
+	RBRemovableMediaManagerPrivate *priv = GET_PRIVATE (manager);
 	TransferData *data;
 	RBEncoder *encoder;
 
@@ -737,10 +975,10 @@
 					  RhythmDBEntry *entry,
 					  const char *dest,
 					  GList *mime_types,
-					  RBTranferCompleteCallback callback,
+					  RBTransferCompleteCallback callback,
 					  gpointer userdata)
 {
-	RBRemovableMediaManagerPrivate *priv = REMOVABLE_MEDIA_MANAGER_GET_PRIVATE (manager);
+	RBRemovableMediaManagerPrivate *priv = GET_PRIVATE (manager);
 	TransferData *data;
 
 	g_assert (rb_is_main_thread ());
@@ -775,7 +1013,7 @@
 rb_removable_media_manager_cmd_copy_tracks (GtkAction *action, RBRemovableMediaManager *mgr)
 {
 #ifdef ENABLE_TRACK_TRANSFER
-	RBRemovableMediaManagerPrivate *priv = REMOVABLE_MEDIA_MANAGER_GET_PRIVATE (mgr);
+	RBRemovableMediaManagerPrivate *priv = GET_PRIVATE (mgr);
 	RBRemovableMediaSource *source;
 	RBLibrarySource *library;
 	RhythmDBQueryModel *model;

Modified: trunk/shell/rb-removable-media-manager.h
==============================================================================
--- trunk/shell/rb-removable-media-manager.h	(original)
+++ trunk/shell/rb-removable-media-manager.h	Tue Jul 29 13:17:53 2008
@@ -30,7 +30,7 @@
 #ifndef __RB_REMOVABLE_MEDIA_MANAGER_H
 #define __RB_REMOVABLE_MEDIA_MANAGER_H
 
-#include <libgnomevfs/gnome-vfs.h>
+#include <gio/gio.h>
 
 #include "rb-source.h"
 #include "rhythmdb.h"
@@ -45,10 +45,10 @@
 #define RB_IS_REMOVABLE_MEDIA_MANAGER_CLASS(k)  (G_TYPE_CHECK_CLASS_TYPE ((k), RB_TYPE_REMOVABLE_MEDIA_MANAGER))
 #define RB_REMOVABLE_MEDIA_MANAGER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), RB_TYPE_REMOVABLE_MEDIA_MANAGER, RBRemovableMediaManagerClass))
 
-typedef void (*RBTranferCompleteCallback) (RhythmDBEntry *entry,
-					   const char *dest,
-					   guint64 dest_size,
-					   gpointer userdata);
+typedef void (*RBTransferCompleteCallback) (RhythmDBEntry *entry,
+					    const char *dest,
+					    guint64 dest_size,
+					    gpointer userdata);
 
 typedef struct
 {
@@ -66,8 +66,10 @@
 					 gint done,
 					 gint total,
 					 double fraction);
-	RBSource * (*create_source)	(RBRemovableMediaManager *mgr,
-					 GnomeVFSVolume *volume);
+	RBSource * (*create_source_mount) (RBRemovableMediaManager *mgr,
+					 GMount *mount);
+	RBSource * (*create_source_volume) (RBRemovableMediaManager *mgr,
+					 GVolume *volume);
 } RBRemovableMediaManagerClass;
 
 RBRemovableMediaManager* rb_removable_media_manager_new		(RBShell *shell);
@@ -80,7 +82,7 @@
 						   RhythmDBEntry *entry,
 						   const char *dest,
 						   GList *mime_types,
-						   RBTranferCompleteCallback callback,
+						   RBTransferCompleteCallback callback,
 						   gpointer userdata);
 #endif
 

Modified: trunk/shell/rb-shell-player.c
==============================================================================
--- trunk/shell/rb-shell-player.c	(original)
+++ trunk/shell/rb-shell-player.c	Tue Jul 29 13:17:53 2008
@@ -60,16 +60,10 @@
 #include <time.h>
 #include <string.h>
 
-#ifdef HAVE_XIDLE_EXTENSION
-#include <X11/extensions/xidle.h>
-#endif /* HAVE_XIDLE_EXTENSION */
-
 #include <glib.h>
 #include <glib/gi18n.h>
 #include <gtk/gtk.h>
 #include <glade/glade.h>
-#include <libgnomevfs/gnome-vfs-utils.h>
-#include <libgnomevfs/gnome-vfs-uri.h>
 
 #include "rb-property-view.h"
 #include "rb-shell-player.h"
@@ -161,9 +155,7 @@
                                              RhythmDBEntry *entry);
 static void tick_cb (RBPlayer *player, RhythmDBEntry *entry, long elapsed, long duration, gpointer data);
 static void error_cb (RBPlayer *player, RhythmDBEntry *entry, const GError *err, gpointer data);
-#ifdef HAVE_GSTREAMER_0_10_MISSING_PLUGINS
 static void missing_plugins_cb (RBPlayer *player, RhythmDBEntry *entry, const char **details, const char **descriptions, RBShellPlayer *sp);
-#endif
 static void playing_stream_cb (RBPlayer *player, RhythmDBEntry *entry, RBShellPlayer *shell_player);
 static void rb_shell_player_error (RBShellPlayer *player, gboolean async, const GError *err);
 
@@ -597,7 +589,6 @@
 			      G_TYPE_STRING, G_TYPE_STRING,
 			      G_TYPE_VALUE, G_TYPE_VALUE);
 
-#ifdef HAVE_GSTREAMER_0_10_MISSING_PLUGINS
 	/**
 	 * RBShellPlayer::missing-plugins:
 	 * @player: the #RBShellPlayer
@@ -619,8 +610,6 @@
 			      G_TYPE_BOOLEAN,
 			      3,
 			      G_TYPE_STRV, G_TYPE_STRV, G_TYPE_CLOSURE);
-#endif
-
 
 	g_type_class_add_private (klass, sizeof (RBShellPlayerPrivate));
 }
@@ -678,41 +667,39 @@
 }
 
 static void
-volume_pre_unmount_cb (GnomeVFSVolumeMonitor *monitor,
-		       GnomeVFSVolume *volume,
+volume_pre_unmount_cb (GVolumeMonitor *monitor,
+		       GMount *mount,
 		       RBShellPlayer *player)
 {
-	gchar *uri_mount_point;
-	gchar *volume_mount_point;
+	const char *entry_mount_point;
+	GFile *mount_root;
 	RhythmDBEntry *entry;
-	const char *uri;
-	gboolean playing;
 
-	rb_shell_player_get_playing (player, &playing, NULL);
-	if (playing) {
+	entry = rb_shell_player_get_playing_entry (player);
+	if (entry == NULL) {
 		return;
 	}
 
-	entry = rb_shell_player_get_playing_entry (player);
-	if (entry == NULL) {
-		/* At startup for example, playing path can be NULL */
+	entry_mount_point = rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_MOUNTPOINT);
+	if (entry_mount_point == NULL) {
 		return;
 	}
 
-	uri = rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_LOCATION);
-	uri_mount_point = rb_uri_get_mount_point (uri);
-	volume_mount_point = gnome_vfs_volume_get_activation_uri (volume);
+	mount_root = g_mount_get_root (mount);
+	if (mount_root != NULL) {
+		char *mount_point;
+		
+		mount_point = g_file_get_uri (mount_root);
+		if (mount_point && entry_mount_point &&
+		    strcmp (entry_mount_point, mount_point) == 0) {
+			rb_shell_player_stop (player);
+		}
 
-	if (uri_mount_point && volume_mount_point &&
-	    (strcmp (uri_mount_point, volume_mount_point) == 0)) {
-		rb_shell_player_stop (player);
+		g_free (mount_point);
+		g_object_unref (mount_root);
 	}
-	g_free (uri_mount_point);
-	g_free (volume_mount_point);
 
-	if (entry != NULL) {
-		rhythmdb_entry_unref (entry);
-	}
+	rhythmdb_entry_unref (entry);
 }
 
 static void
@@ -1014,17 +1001,19 @@
 				 G_CALLBACK (playing_stream_cb),
 				 player, 0);
 
-#ifdef HAVE_GSTREAMER_0_10_MISSING_PLUGINS
 	g_signal_connect_object (player->priv->mmplayer,
 				 "missing-plugins",
 				 G_CALLBACK (missing_plugins_cb),
 				 player, 0);
-#endif
 
-	g_signal_connect (G_OBJECT (gnome_vfs_get_volume_monitor ()),
-			  "volume-pre-unmount",
-			  G_CALLBACK (volume_pre_unmount_cb),
-			  player);
+	{
+		GVolumeMonitor *monitor = g_volume_monitor_get ();
+		g_signal_connect (G_OBJECT (monitor),
+				  "mount-pre-unmount",
+				  G_CALLBACK (volume_pre_unmount_cb),
+				  player);
+		g_object_unref (monitor);	/* hmm */
+	}
 
 	player->priv->gconf_play_order_id =
 		eel_gconf_notification_add (CONF_STATE_PLAY_ORDER,
@@ -3666,8 +3655,6 @@
 	GDK_THREADS_LEAVE ();
 }
 
-#ifdef HAVE_GSTREAMER_0_10_MISSING_PLUGINS
-
 typedef struct {
 	RhythmDBEntry *entry;
 	RBShellPlayer *player;
@@ -3745,7 +3732,6 @@
 
 	g_closure_sink (retry);
 }
-#endif
 
 /**
  * rb_shell_player_get_playing_path:

Modified: trunk/shell/rb-shell-preferences.c
==============================================================================
--- trunk/shell/rb-shell-preferences.c	(original)
+++ trunk/shell/rb-shell-preferences.c	Tue Jul 29 13:17:53 2008
@@ -55,7 +55,10 @@
 #include <glib/gi18n.h>
 #include <gtk/gtk.h>
 #include <glade/glade.h>
+
+#if !GTK_CHECK_VERSION(2,13,1)
 #include <libgnome/gnome-help.h>
+#endif
 
 #include "rb-file-helpers.h"
 #include "rb-shell-preferences.h"
@@ -87,7 +90,6 @@
 						      RBShellPreferences *shell_preferences);
 static void rb_shell_preferences_toolbar_style_cb (GtkComboBox *box,
 						   RBShellPreferences *preferences);
-#ifdef HAVE_GSTREAMER_0_10_XFADE
 static void rb_shell_preferences_player_backend_cb (GtkToggleButton *button,
 						    RBShellPreferences *preferences);
 static void rb_shell_preferences_album_crossfade_cb (GtkToggleButton *button,
@@ -97,7 +99,6 @@
 static void rb_shell_preferences_network_buffer_size_cb (GtkRange *range,
 							 RBShellPreferences *preferences);
 static void update_playback_prefs_sensitivity (RBShellPreferences *preferences);
-#endif
 
 enum
 {
@@ -123,12 +124,10 @@
 	GtkWidget *quality_check;
 	GtkWidget *year_check;
 
-#ifdef HAVE_GSTREAMER_0_10_XFADE
 	GtkWidget *xfade_backend_check;
 	GtkWidget *album_crossfade_check;
 	GtkWidget *transition_duration;
 	GtkWidget *network_buffer_size;
-#endif
 
 	GSList *browser_views_group;
 
@@ -157,7 +156,14 @@
 {
 	GError *error = NULL;
 
+#if GTK_CHECK_VERSION(2,13,1)
+	gtk_show_uri (gtk_widget_get_display (widget),
+		      "ghelp:rhythmbox",
+		      gtk_get_current_event_time (),
+		      &error);
+#else
 	gnome_help_display ("rhythmbox.xml", "prefs", &error);
+#endif
 
 	if (error != NULL) {
 		rb_error_dialog (NULL,
@@ -267,7 +273,6 @@
 				    shell_preferences);
 	g_object_unref (xml);
 
-#ifdef HAVE_GSTREAMER_0_10_XFADE
 	/* playback preferences */
 	xml = rb_glade_xml_new ("playback-prefs.glade",
 				"playback_prefs_box",
@@ -311,7 +316,6 @@
 				  glade_xml_get_widget (xml, "playback_prefs_box"),
 				  gtk_label_new (_("Playback")));
 	g_object_unref (xml);
-#endif
 
 	eel_gconf_notification_add (CONF_PLAYER_DIR,
 				    (GConfClientNotifyFunc) rb_shell_preferences_ui_pref_changed,
@@ -530,6 +534,9 @@
 	char *columns;
 	GSList  *l;
 	gint view, i;
+	gboolean b;
+	float duration;
+	int buffer_size;
 
 	shell_preferences->priv->loading = TRUE;
 
@@ -594,28 +601,20 @@
 					   G_CALLBACK (rb_shell_preferences_toolbar_style_cb),
 					   shell_preferences);
 
-#ifdef HAVE_GSTREAMER_0_10_XFADE
-	{
-		gboolean b;
-		float duration;
-		int buffer_size;
-
-		/* player preferences */
-		b = eel_gconf_get_boolean (CONF_PLAYER_USE_XFADE_BACKEND);
-		gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (shell_preferences->priv->xfade_backend_check), b);
+	/* player preferences */
+	b = eel_gconf_get_boolean (CONF_PLAYER_USE_XFADE_BACKEND);
+	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (shell_preferences->priv->xfade_backend_check), b);
 
-		b = eel_gconf_get_boolean (CONF_PLAYER_TRANSITION_ALBUM_CHECK);
-		gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (shell_preferences->priv->album_crossfade_check), !b);
+	b = eel_gconf_get_boolean (CONF_PLAYER_TRANSITION_ALBUM_CHECK);
+	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (shell_preferences->priv->album_crossfade_check), !b);
 
-		duration = eel_gconf_get_float (CONF_PLAYER_TRANSITION_TIME);
-		gtk_range_set_value (GTK_RANGE (shell_preferences->priv->transition_duration), duration);
+	duration = eel_gconf_get_float (CONF_PLAYER_TRANSITION_TIME);
+	gtk_range_set_value (GTK_RANGE (shell_preferences->priv->transition_duration), duration);
 
-		buffer_size = eel_gconf_get_integer (CONF_PLAYER_NETWORK_BUFFER_SIZE);
-		gtk_range_set_value (GTK_RANGE (shell_preferences->priv->network_buffer_size), buffer_size);
+	buffer_size = eel_gconf_get_integer (CONF_PLAYER_NETWORK_BUFFER_SIZE);
+	gtk_range_set_value (GTK_RANGE (shell_preferences->priv->network_buffer_size), buffer_size);
 
-		update_playback_prefs_sensitivity (shell_preferences);
-	}
-#endif
+	update_playback_prefs_sensitivity (shell_preferences);
 
 	shell_preferences->priv->loading = FALSE;
 }
@@ -656,8 +655,6 @@
 	eel_gconf_set_integer (CONF_UI_BROWSER_VIEWS, index);
 }
 
-#ifdef HAVE_GSTREAMER_0_10_XFADE
-
 static void
 update_playback_prefs_sensitivity (RBShellPreferences *preferences)
 {
@@ -711,4 +708,3 @@
 	eel_gconf_set_integer (CONF_PLAYER_NETWORK_BUFFER_SIZE, (int)v);
 }
 
-#endif

Modified: trunk/shell/rb-shell.c
==============================================================================
--- trunk/shell/rb-shell.c	(original)
+++ trunk/shell/rb-shell.c	Tue Jul 29 13:17:53 2008
@@ -43,14 +43,11 @@
 
 #include <X11/Xatom.h>
 
+#if !GTK_CHECK_VERSION(2,13,1)
 #include <libgnome/libgnome.h>
-#include <libgnome/gnome-init.h>
-#include <libgnome/gnome-program.h>
+#endif
 #include <libgnomeui/gnome-client.h>
 
-#include <libgnomevfs/gnome-vfs.h>
-#include <libgnomevfs/gnome-vfs-mime-utils.h>
-
 #include "rb-shell.h"
 #include "rb-debug.h"
 #include "rb-dialog.h"
@@ -990,6 +987,17 @@
 	return s;
 }
 
+static GMountOperation *
+rb_shell_create_mount_op_cb (RhythmDB *db, RBShell *shell)
+{
+	/* create a gtk mount operation if possible, otherwise don't use one at all */
+#if GTK_CHECK_VERSION(2,13,1)
+	return gtk_mount_operation_new (shell->priv->window);
+#else
+	return NULL;
+#endif
+}
+
 static void
 construct_db (RBShell *shell)
 {
@@ -1019,6 +1027,9 @@
 	g_signal_connect_object (G_OBJECT (shell->priv->db), "load-complete",
 				 G_CALLBACK (rb_shell_load_complete_cb), shell,
 				 0);
+	g_signal_connect_object (G_OBJECT (shell->priv->db), "create-mount-op",
+				 G_CALLBACK (rb_shell_create_mount_op_cb), shell,
+				 0);
 
 	rb_profile_end ("creating database object");
 }
@@ -2327,7 +2338,14 @@
 {
 	GError *error = NULL;
 
+#if GTK_CHECK_VERSION(2,13,1)
+	gtk_show_uri (gtk_widget_get_screen (shell->priv->window),
+		      "ghelp:rhythmbox",
+		      gtk_get_current_event_time (),
+		      &error);
+#else
 	gnome_help_display ("rhythmbox.xml", NULL, &error);
+#endif
 
 	if (error != NULL) {
 		rb_error_dialog (NULL, _("Couldn't display help"),
@@ -3339,16 +3357,9 @@
 			/* That happens for directories and unhandled schemes, such as CDDA */
 			playlist_source = rb_shell_guess_source_for_uri (shell, uri);
 			if (playlist_source == NULL || rb_source_uri_is_source (playlist_source, uri) == FALSE) {
-				/* Do we have a directory? */
-				if (rb_uri_is_local (uri)) {
-					rb_debug ("%s is a directory, but doesn't have a source, adding as a dir", uri);
-					if (!rb_shell_add_uri (shell, uri, NULL, NULL, error))
-						return FALSE;
-				} else {
-					/* Or something else? */
-					rb_debug ("%s is not handled as a playlist, isn't local, and doesn't have a source, doing nothing", uri);
+				rb_debug ("%s doesn't have a source, adding", uri);
+				if (!rb_shell_add_uri (shell, uri, NULL, NULL, error))
 					return FALSE;
-				}
 			}
 		} else {
 			rb_debug ("%s didn't parse as a playlist", uri);

Modified: trunk/shell/rb-tray-icon.c
==============================================================================
--- trunk/shell/rb-tray-icon.c	(original)
+++ trunk/shell/rb-tray-icon.c	Tue Jul 29 13:17:53 2008
@@ -36,8 +36,6 @@
 
 #include <glib/gi18n.h>
 #include <gtk/gtk.h>
-#include <libgnomevfs/gnome-vfs.h>
-#include <libgnomevfs/gnome-vfs-mime-utils.h>
 #include <libsexy/sexy-tooltip.h>
 
 #include "rb-tray-icon.h"
@@ -47,6 +45,7 @@
 #include "rb-preferences.h"
 #include "rb-shell.h"
 #include "rb-shell-player.h"
+#include "rb-util.h"
 
 #define TRAY_ICON_DEFAULT_TOOLTIP _("Music Player")
 #define DEFAULT_TOOLTIP_ICON "" /*"gnome-media-player"*/
@@ -574,7 +573,7 @@
 		      guint time,
 		      RBTrayIcon *icon)
 {
-	GList *list, *uri_list, *i;
+	GList *list, *i;
 	GtkTargetList *tlist;
 	gboolean ret;
 
@@ -585,26 +584,14 @@
 	if (ret == FALSE)
 		return;
 
-	list = gnome_vfs_uri_list_parse ((char *) data->data);
+	list = rb_uri_list_parse ((char *) data->data);
 
 	if (list == NULL) {
 		gtk_drag_finish (context, FALSE, FALSE, time);
 		return;
 	}
 
-	uri_list = NULL;
-
-	for (i = list; i != NULL; i = g_list_next (i))
-		uri_list = g_list_prepend (uri_list, gnome_vfs_uri_to_string ((const GnomeVFSURI *) i->data, 0));
-
-	gnome_vfs_uri_list_free (list);
-
-	if (uri_list == NULL) {
-		gtk_drag_finish (context, FALSE, FALSE, time);
-		return;
-	}
-
-	for (i = uri_list; i != NULL; i = i->next) {
+	for (i = list; i != NULL; i = i->next) {
 		char *uri = i->data;
 		if (uri != NULL)
 			rb_shell_load_uri (icon->priv->shell, uri, FALSE, NULL);
@@ -612,7 +599,7 @@
 		g_free (uri);
 	}
 
-	g_list_free (uri_list);
+	g_list_free (list);
 
 	gtk_drag_finish (context, TRUE, FALSE, time);
 }

Modified: trunk/sources/rb-auto-playlist-source.c
==============================================================================
--- trunk/sources/rb-auto-playlist-source.c	(original)
+++ trunk/sources/rb-auto-playlist-source.c	Tue Jul 29 13:17:53 2008
@@ -33,7 +33,6 @@
 #include <libxml/tree.h>
 #include <glib/gi18n.h>
 #include <gtk/gtk.h>
-#include <libgnomevfs/gnome-vfs-uri.h>
 
 #include "rb-auto-playlist-source.h"
 #include "rb-library-browser.h"

Modified: trunk/sources/rb-browser-source.c
==============================================================================
--- trunk/sources/rb-browser-source.c	(original)
+++ trunk/sources/rb-browser-source.c	Tue Jul 29 13:17:53 2008
@@ -47,7 +47,6 @@
 
 #include <gtk/gtk.h>
 #include <glib/gi18n.h>
-#include <libgnomevfs/gnome-vfs.h>
 #include <glade/glade.h>
 
 #include "rb-source.h"

Modified: trunk/sources/rb-library-source.c
==============================================================================
--- trunk/sources/rb-library-source.c	(original)
+++ trunk/sources/rb-library-source.c	Tue Jul 29 13:17:53 2008
@@ -420,7 +420,7 @@
 			uri = gtk_file_chooser_get_current_folder_uri (GTK_FILE_CHOOSER (dialog));
 		}
 
-		path = gnome_vfs_format_uri_for_display (uri);
+		path = g_uri_unescape_string (uri, G_URI_RESERVED_CHARS_ALLOWED_IN_PATH);
 
 		gtk_entry_set_text (GTK_ENTRY (source->priv->library_location_entry), path);
 		rb_library_source_library_location_cb (GTK_ENTRY (source->priv->library_location_entry),
@@ -586,7 +586,7 @@
 
 		gtk_widget_set_sensitive (source->priv->library_location_entry, TRUE);
 
-		path = gnome_vfs_format_uri_for_display (list->data);
+		path = g_uri_unescape_string (list->data, G_URI_RESERVED_CHARS_ALLOWED_IN_PATH);
 		gtk_entry_set_text (GTK_ENTRY (source->priv->library_location_entry), path);
 		g_free (path);
 	} else if (g_slist_length (list) == 0) {
@@ -643,10 +643,13 @@
 {
 	GSList *list = NULL;
 	const char *path;
+	GFile *file;
 	char *uri;
 
 	path = gtk_entry_get_text (entry);
-	uri = gnome_vfs_make_uri_from_input (path);
+	file = g_file_parse_name (path);
+	uri = g_file_get_uri (file);
+	g_object_unref (file);
 
 	if (uri && uri[0])
 		list = g_slist_prepend (NULL, (gpointer)uri);
@@ -1076,8 +1079,9 @@
 static char*
 build_filename (RBLibrarySource *source, RhythmDBEntry *entry)
 {
-	GnomeVFSURI *uri;
-	GnomeVFSURI *new;
+	GFile *library_location;
+	GFile *dir;
+	GFile *dest;
 	char *realfile;
 	char *realpath;
 	char *filename;
@@ -1104,15 +1108,11 @@
 	g_free (layout_filename);
 	layout_filename = tmp;
 
-	uri = gnome_vfs_uri_new ((const char *)list->data);
-	if (uri == NULL) {
-		goto out;
-	}
-
 	realpath = filepath_parse_pattern (layout_path, entry);
-	new = gnome_vfs_uri_append_path (uri, realpath);
-	gnome_vfs_uri_unref (uri);
-	uri = new;
+
+	library_location = g_file_new_for_uri ((const char *)list->data);
+	dir = g_file_resolve_relative_path (library_location, realpath);
+	g_object_unref (library_location);
 	g_free (realpath);
 
 	if (g_str_has_prefix (rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_MIMETYPE), "audio/x-raw")) {
@@ -1150,14 +1150,13 @@
 		filename = realfile;
 	}
 
-	new = gnome_vfs_uri_append_file_name (uri, filename);
-	gnome_vfs_uri_unref (uri);
-	uri = new;
+	dest = g_file_resolve_relative_path (dir, filename);
+	g_object_unref (dir);
 	g_free (extension);
 	g_free (filename);
 
-	string = gnome_vfs_uri_to_string (uri, 0);
-	gnome_vfs_uri_unref (uri);
+	string = g_file_get_uri (dest);
+	g_object_unref (dest);
  out:
 	rb_slist_deep_free (list);
 	g_free (layout_path);
@@ -1254,7 +1253,7 @@
 
 		rb_removable_media_manager_queue_transfer (rm_mgr, entry,
 							  dest, NULL,
-							  (RBTranferCompleteCallback)completed_cb, source);
+							  (RBTransferCompleteCallback)completed_cb, source);
 	}
 	g_boxed_free (RHYTHMDB_TYPE_ENTRY_TYPE, source_entry_type);
 
@@ -1291,26 +1290,21 @@
 	RBSource *source;
 	GPtrArray *query;
 	RBShell *shell;
-	GnomeVFSURI *uri;
 	char *name;
 	GdkPixbuf *icon;
 	RhythmDBEntryType entry_type;
 	char *sort_column;
 	int sort_order;
+	GFile *file;
 
 	g_object_get (library_source,
 		      "shell", &shell,
 		      "entry-type", &entry_type,
 		      NULL);
-	uri = gnome_vfs_uri_new (path);
-	if (uri == NULL) {
-		g_object_unref (shell);
-		g_boxed_free (RHYTHMDB_TYPE_ENTRY_TYPE, entry_type);
-		return;
-	}
 
-	name = gnome_vfs_uri_extract_short_name (uri);
-	gnome_vfs_uri_unref (uri);
+	file = g_file_new_for_uri (path);		/* ? */
+	name = g_file_get_basename (file);
+	g_object_unref (file);
 
 	rb_entry_view_get_sorting_order (rb_source_get_entry_view (RB_SOURCE (library_source)),
 					 &sort_column, &sort_order);

Modified: trunk/sources/rb-play-queue-source.c
==============================================================================
--- trunk/sources/rb-play-queue-source.c	(original)
+++ trunk/sources/rb-play-queue-source.c	Tue Jul 29 13:17:53 2008
@@ -31,7 +31,6 @@
 #include <libxml/tree.h>
 #include <glib/gi18n.h>
 #include <gtk/gtk.h>
-#include <libgnomevfs/gnome-vfs-uri.h>
 
 #include "rb-play-queue-source.h"
 #include "rb-playlist-xml.h"

Modified: trunk/sources/rb-playlist-source.c
==============================================================================
--- trunk/sources/rb-playlist-source.c	(original)
+++ trunk/sources/rb-playlist-source.c	Tue Jul 29 13:17:53 2008
@@ -37,7 +37,6 @@
 #include <libxml/tree.h>
 #include <glib/gi18n.h>
 #include <gtk/gtk.h>
-#include <libgnomevfs/gnome-vfs-uri.h>
 #include <totem-pl-parser.h>
 
 #include "rb-entry-view.h"

Modified: trunk/sources/rb-podcast-source.c
==============================================================================
--- trunk/sources/rb-podcast-source.c	(original)
+++ trunk/sources/rb-podcast-source.c	Tue Jul 29 13:17:53 2008
@@ -1356,9 +1356,17 @@
 static void
 rb_podcast_source_btn_file_change_cb (GtkFileChooserButton *widget, const char *key)
 {
-	char *uri = gtk_file_chooser_get_uri (GTK_FILE_CHOOSER (widget));
-
-	eel_gconf_set_string (key, gnome_vfs_get_local_path_from_uri (uri));
+	char *uri;
+	GFile *file;
+	char *path;
+	
+	uri = gtk_file_chooser_get_uri (GTK_FILE_CHOOSER (widget));
+	file = g_file_new_for_uri (uri);
+	path = g_file_get_path (file);
+
+	eel_gconf_set_string (key, path);
+	g_object_unref (file);
+	g_free (path);
 	g_free (uri);
 }
 
@@ -1809,29 +1817,12 @@
 static gboolean
 impl_receive_drag (RBSource *asource, GtkSelectionData *selection_data)
 {
-	GList *list, *uri_list, *i;
+	GList *list, *i;
 	RBPodcastSource *source = RB_PODCAST_SOURCE (asource);
 
-	rb_debug ("parsing uri list");
-	list = gnome_vfs_uri_list_parse ((char *)selection_data->data);
-
-	if (list == NULL)
-		return FALSE;
-
-	uri_list = NULL;
-
-	for (i = list; i != NULL; i = g_list_next (i))
-		uri_list = g_list_prepend (uri_list, gnome_vfs_uri_to_string ((const GnomeVFSURI *) i->data, 0));
-
-	gnome_vfs_uri_list_free (list);
+	list = rb_uri_list_parse ((char *)selection_data->data);
 
-	if (uri_list == NULL)
-		return FALSE;
-
-	rb_debug ("adding uris");
-
-	i = uri_list;
-	while (i != NULL) {
+	for (i = list; i != NULL; i = i->next) {
 		char *uri = NULL;
 
 		/* as totem source says, "Super _NETSCAPE_URL trick" */
@@ -1848,14 +1839,9 @@
 		    (!rhythmdb_entry_lookup_by_location (source->priv->db, uri))) {
 			rb_podcast_source_add_feed (source, uri);
 		}
-
-		g_free (uri);
-
-		if (i != NULL)
-			i = i->next;
 	}
 
-	g_list_free (uri_list);
+	g_list_free (list);
 	return TRUE;
 }
 

Modified: trunk/sources/rb-removable-media-source.c
==============================================================================
--- trunk/sources/rb-removable-media-source.c	(original)
+++ trunk/sources/rb-removable-media-source.c	Tue Jul 29 13:17:53 2008
@@ -37,8 +37,6 @@
 #include <gtk/gtktreeview.h>
 #include <gtk/gtkicontheme.h>
 #include <gtk/gtkiconfactory.h>
-#include <libgnomevfs/gnome-vfs-volume.h>
-#include <libgnomevfs/gnome-vfs-volume-monitor.h>
 
 #include "rhythmdb.h"
 #include "eel-gconf-extensions.h"
@@ -75,7 +73,8 @@
 
 typedef struct
 {
-	GnomeVFSVolume *volume;
+	GVolume *volume;
+	GMount *mount;
 } RBRemovableMediaSourcePrivate;
 
 G_DEFINE_TYPE (RBRemovableMediaSource, rb_removable_media_source, RB_TYPE_BROWSER_SOURCE)
@@ -85,6 +84,7 @@
 {
 	PROP_0,
 	PROP_VOLUME,
+	PROP_MOUNT,
 };
 
 static void
@@ -122,8 +122,15 @@
 					 PROP_VOLUME,
 					 g_param_spec_object ("volume",
 							      "Volume",
-							      "GnomeVfs Volume",
-							      GNOME_VFS_TYPE_VOLUME,
+							      "GIO Volume",
+							      G_TYPE_VOLUME,
+							      G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+	g_object_class_install_property (object_class,
+					 PROP_MOUNT,
+					 g_param_spec_object ("mount",
+							      "Mount",
+							      "GIO Mount",
+							      G_TYPE_MOUNT,
 							      G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
 
 	g_type_class_add_private (klass, sizeof (RBRemovableMediaSourcePrivate));
@@ -139,45 +146,75 @@
 				       GObjectConstructParam *construct_properties)
 {
 	GObject *source;
-	GnomeVFSVolume *volume;
-	GnomeVFSDrive *drive;
+	GVolume *volume;
+	GIcon *icon = NULL;
+	GDrive *drive;
 	char *display_name;
-	gint size;
-	char *icon_name;
-	GtkIconTheme *theme;
-	GdkPixbuf *pixbuf;
+	GdkPixbuf *pixbuf = NULL;
+	RBRemovableMediaSourcePrivate *priv;
 
 	source = G_OBJECT_CLASS(rb_removable_media_source_parent_class)
 			->constructor (type, n_construct_properties, construct_properties);
+	priv = REMOVABLE_MEDIA_SOURCE_GET_PRIVATE (source);
+
+	if (priv->mount != NULL) {
+		volume = g_mount_get_volume (priv->mount);
+	} else if (priv->volume != NULL) {
+		volume = g_object_ref (priv->volume);
+	} else {
+		volume = NULL;
+	}
 
-	g_object_get (source, "volume", &volume, NULL);
 	if (volume != NULL) {
-		drive = gnome_vfs_volume_get_drive (volume);
+		drive = g_volume_get_drive (volume);
 		if (drive != NULL) {
-			display_name = gnome_vfs_drive_get_display_name (drive);
-			gnome_vfs_drive_unref (drive);
+			display_name = g_drive_get_name (drive);
+			g_object_unref (drive);
 		} else {
-			display_name = gnome_vfs_volume_get_display_name (volume);
+			display_name = g_volume_get_name (volume);
 		}
-		icon_name = gnome_vfs_volume_get_icon (volume);
+		icon = g_volume_get_icon (volume);
 		g_object_unref (volume);
+		rb_debug ("display name = %s, icon = %p", display_name, icon);
 	} else {
 		display_name = g_strdup ("Unknown Device");
-		icon_name = g_strdup ("multimedia-player");
+		icon = g_themed_icon_new ("multimedia-player");
 	}
 
 	g_object_set (source, "name", display_name, NULL);
 	g_free (display_name);
 
-	theme = gtk_icon_theme_get_default ();
-	gtk_icon_size_lookup (RB_SOURCE_ICON_SIZE, &size, NULL);
-	pixbuf = gtk_icon_theme_load_icon (theme, icon_name, size, 0, NULL);
-	g_free (icon_name);
+	if (icon == NULL) {
+		rb_debug ("no icon set");
+		pixbuf = NULL;
+	} else if (G_IS_THEMED_ICON (icon)) {
+		GtkIconTheme *theme;
+		const char * const *names;
+		gint size;
+		int i;
+
+		theme = gtk_icon_theme_get_default ();
+		gtk_icon_size_lookup (RB_SOURCE_ICON_SIZE, &size, NULL);
+
+		i = 0;
+		names = g_themed_icon_get_names (G_THEMED_ICON (icon));
+		while (names[i] != NULL && pixbuf == NULL) {
+			rb_debug ("looking up themed icon: %s", names[i]);
+			pixbuf = gtk_icon_theme_load_icon (theme, names[i], size, 0, NULL);
+			i++;
+		}
+
+	} else if (G_IS_LOADABLE_ICON (icon)) {
+		rb_debug ("loading of GLoadableIcons is not implemented yet");
+		pixbuf = NULL;
+	}
 
 	rb_source_set_pixbuf (RB_SOURCE (source), pixbuf);
 	if (pixbuf != NULL) {
 		g_object_unref (pixbuf);
 	}
+	g_object_unref (icon);
+	g_object_unref (volume);
 
 	return source;
 }
@@ -188,9 +225,13 @@
 	RBRemovableMediaSourcePrivate *priv = REMOVABLE_MEDIA_SOURCE_GET_PRIVATE (object);
 
 	if (priv->volume) {
-		gnome_vfs_volume_unref (priv->volume);
+		g_object_unref (priv->volume);
 		priv->volume = NULL;
 	}
+	if (priv->mount) {
+		g_object_unref (priv->mount);
+		priv->mount = NULL;
+	}
 
 	G_OBJECT_CLASS (rb_removable_media_source_parent_class)->dispose (object);
 }
@@ -206,10 +247,21 @@
 	switch (prop_id) {
 	case PROP_VOLUME:
 		if (priv->volume) {
-			gnome_vfs_volume_unref (priv->volume);
+			g_object_unref (priv->volume);
 		}
 		priv->volume = g_value_get_object (value);
-		gnome_vfs_volume_ref (priv->volume);
+		if (priv->volume) {
+			g_object_ref (priv->volume);
+		}
+		break;
+	case PROP_MOUNT:
+		if (priv->mount) {
+			g_object_unref (priv->mount);
+		}
+		priv->mount = g_value_get_object (value);
+		if (priv->mount) {
+			g_object_ref (priv->mount);
+		}
 		break;
 	default:
 		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@@ -227,8 +279,10 @@
 
 	switch (prop_id) {
 	case PROP_VOLUME:
-		gnome_vfs_volume_ref (priv->volume);
-		g_value_take_object (value, priv->volume);
+		g_value_set_object (value, priv->volume);
+		break;
+	case PROP_MOUNT:
+		g_value_set_object (value, priv->mount);
 		break;
 	default:
 		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@@ -363,7 +417,7 @@
 		added_data->mimetype = g_strdup (mimetype);
 		rb_removable_media_manager_queue_transfer (rm_mgr, entry,
 							   dest, mime_types,
-							   (RBTranferCompleteCallback)_track_added_cb, added_data);
+							   (RBTransferCompleteCallback)_track_added_cb, added_data);
 impl_paste_end:
 		g_free (dest);
 		g_free (mimetype);
@@ -384,9 +438,12 @@
 static guint
 impl_want_uri (RBSource *source, const char *uri)
 {
-	GnomeVFSVolume *volume;
-	char *activation_uri;
-	int retval, len;
+	RBRemovableMediaSourcePrivate *priv = REMOVABLE_MEDIA_SOURCE_GET_PRIVATE (source);
+	GVolume *volume;
+	const char *uri_path;
+	char *device_path;
+	int retval;
+	int len;
 
 	retval = 0;
 
@@ -394,26 +451,29 @@
 	 * that use mass storage */
 	if (g_str_has_prefix (uri, "file://") == FALSE)
 		return 0;
+	uri_path = uri + strlen ("file://");
 
-	g_object_get (G_OBJECT (source),
-		      "volume", &volume,
-		      NULL);
-	if (volume == NULL)
+	if (priv->mount) {
+		volume = g_mount_get_volume (priv->mount);
+	} else if (priv->volume) {
+		volume = g_object_ref (priv->volume);
+	} else {
 		return 0;
+	}
 
-	activation_uri = gnome_vfs_volume_get_activation_uri (volume);
-	if (activation_uri == NULL)
+	device_path = g_volume_get_identifier (volume, G_VOLUME_IDENTIFIER_KIND_UNIX_DEVICE);
+	g_object_unref (volume);
+	if (device_path == NULL)
 		return 0;
 
-	len = strlen (uri);
-	if (uri[len - 1] == '/') {
-		if (strncmp (uri, activation_uri, len - 1) == 0)
+	len = strlen (uri_path);
+	if (uri_path[len - 1] == '/') {
+		if (strncmp (uri_path, device_path, len - 1) == 0)
 			retval = 100;
-	} else if (strcmp (uri, activation_uri) == 0)
+	} else if (strcmp (uri_path, device_path) == 0)
 		retval = 100;
 
-	g_free (activation_uri);
-
+	g_free (device_path);
 	return retval;
 }
 

Modified: trunk/sources/rb-static-playlist-source.c
==============================================================================
--- trunk/sources/rb-static-playlist-source.c	(original)
+++ trunk/sources/rb-static-playlist-source.c	Tue Jul 29 13:17:53 2008
@@ -34,7 +34,6 @@
 #include <libxml/tree.h>
 #include <glib/gi18n.h>
 #include <gtk/gtk.h>
-#include <libgnomevfs/gnome-vfs-uri.h>
 
 #include "rb-static-playlist-source.h"
 #include "rb-library-browser.h"
@@ -729,12 +728,17 @@
 }
 
 static gboolean
-rb_static_playlist_source_add_location_cb (const char *uri,
-					   gboolean dir,
-					   RBStaticPlaylistSource *source)
+_add_location_cb (GFile *file,
+		  gboolean dir,
+		  RBStaticPlaylistSource *source)
 {
-	if (!dir)
+	if (!dir) {
+		char *uri;
+
+		uri = g_file_get_uri (file);
 		rb_static_playlist_source_add_location_internal (source, uri, -1);
+		g_free (uri);
+	}
 	return TRUE;	
 }
 
@@ -752,8 +756,8 @@
 	/* if there is an entry, it won't be a directory */
 	if (entry == NULL && rb_uri_is_directory (location))
 		rb_uri_handle_recursively (location,
-					   (RBUriRecurseFunc) rb_static_playlist_source_add_location_cb,
 					   NULL,
+					   (RBUriRecurseFunc) _add_location_cb,
 					   source);
 	else
 		rb_static_playlist_source_add_location_internal (source, location, index);

Modified: trunk/tests/bench-rhythmdb-load.c
==============================================================================
--- trunk/tests/bench-rhythmdb-load.c	(original)
+++ trunk/tests/bench-rhythmdb-load.c	Tue Jul 29 13:17:53 2008
@@ -101,7 +101,6 @@
 	rb_threads_init ();
 	gtk_set_locale ();
 	gtk_init (&argc, &argv);
-	gnome_vfs_init ();
 	rb_debug_init (FALSE);
 	rb_refstring_system_init ();
 	rb_file_helpers_init ();
@@ -136,7 +135,6 @@
 	
 	rb_file_helpers_shutdown ();
         rb_refstring_system_shutdown ();
-        gnome_vfs_shutdown ();
 
 
 	rb_profile_end ("load test");

Modified: trunk/tests/test-audioscrobbler.c
==============================================================================
--- trunk/tests/test-audioscrobbler.c	(original)
+++ trunk/tests/test-audioscrobbler.c	Tue Jul 29 13:17:53 2008
@@ -40,7 +40,7 @@
 {
 	AudioscrobblerEntry *entry;
 	AudioscrobblerEntry *reload;
-	char *as_string;
+	GString *as_gstring;
 
 	entry = g_new0(AudioscrobblerEntry, 1);
 	entry->title = g_strdup ("something or other");
@@ -50,11 +50,12 @@
 	entry->mbid = g_strdup ("");		/* ? */
 	entry->play_time = time (0);
 
-	as_string = rb_audioscrobbler_entry_save_to_string (entry);
-	rb_debug ("string form: %s", as_string);
-	fail_unless (strlen (as_string) != 0, "entry saved as string should not be empty");
+	as_gstring = g_string_new ("");
+	rb_audioscrobbler_entry_save_to_string (as_gstring, entry);
+	rb_debug ("string form: %s", as_gstring->str);
+	fail_unless (as_gstring->len != 0, "entry saved as string should not be empty");
 
-	reload = rb_audioscrobbler_entry_load_from_string (as_string);
+	reload = rb_audioscrobbler_entry_load_from_string (as_gstring->str);
 	fail_unless (reload != NULL, "entry-as-string can be converted back to an entry");
 
 	rb_audioscrobbler_entry_debug (entry, 0);
@@ -68,7 +69,7 @@
 
 	rb_audioscrobbler_entry_free (entry);
 	rb_audioscrobbler_entry_free (reload);
-	g_free (as_string);
+	g_string_free (as_gstring, TRUE);
 }
 END_TEST
 

Modified: trunk/tests/test-file-helpers.c
==============================================================================
--- trunk/tests/test-file-helpers.c	(original)
+++ trunk/tests/test-file-helpers.c	Tue Jul 29 13:17:53 2008
@@ -112,7 +112,6 @@
 	rb_threads_init ();
 	gtk_set_locale ();
 	gtk_init (&argc, &argv);
-	gnome_vfs_init ();
 	rb_debug_init (TRUE);
 	rb_file_helpers_init ();
 
@@ -126,7 +125,6 @@
 	srunner_free (sr);
 
 	rb_file_helpers_shutdown ();
-	gnome_vfs_shutdown ();
 
 	rb_profile_end ("rb-file-helpers test suite");
 	return ret;

Modified: trunk/tests/test-rhythmdb-property-model.c
==============================================================================
--- trunk/tests/test-rhythmdb-property-model.c	(original)
+++ trunk/tests/test-rhythmdb-property-model.c	Tue Jul 29 13:17:53 2008
@@ -450,7 +450,6 @@
 	rb_threads_init ();
 	gtk_set_locale ();
 	gtk_init (&argc, &argv);
-	gnome_vfs_init ();
 	rb_debug_init (TRUE);
 	rb_refstring_system_init ();
 	rb_file_helpers_init ();
@@ -468,7 +467,6 @@
 
 	rb_file_helpers_shutdown ();
 	rb_refstring_system_shutdown ();
-	gnome_vfs_shutdown ();
 
 	rb_profile_end ("rhythmdb-property-model test suite");
 	return ret;

Modified: trunk/tests/test-rhythmdb-query-model.c
==============================================================================
--- trunk/tests/test-rhythmdb-query-model.c	(original)
+++ trunk/tests/test-rhythmdb-query-model.c	Tue Jul 29 13:17:53 2008
@@ -246,7 +246,6 @@
 	rb_threads_init ();
 	gtk_set_locale ();
 	gtk_init (&argc, &argv);
-	gnome_vfs_init ();
 	rb_debug_init (TRUE);
 	rb_refstring_system_init ();
 	rb_file_helpers_init ();
@@ -264,7 +263,6 @@
 
 	rb_file_helpers_shutdown ();
 	rb_refstring_system_shutdown ();
-	gnome_vfs_shutdown ();
 
 	rb_profile_end ("rhythmdb-query-model test suite");
 	return ret;

Modified: trunk/tests/test-rhythmdb.c
==============================================================================
--- trunk/tests/test-rhythmdb.c	(original)
+++ trunk/tests/test-rhythmdb.c	Tue Jul 29 13:17:53 2008
@@ -450,7 +450,6 @@
 	rb_threads_init ();
 	gtk_set_locale ();
 	gtk_init (&argc, &argv);
-	gnome_vfs_init ();
 	rb_debug_init (TRUE);
 	rb_refstring_system_init ();
 	rb_file_helpers_init ();
@@ -468,7 +467,6 @@
 
 	rb_file_helpers_shutdown ();
 	rb_refstring_system_shutdown ();
-	gnome_vfs_shutdown ();
 
 	rb_profile_end ("rhythmbox test suite");
 	return ret;

Modified: trunk/widgets/rb-entry-view.c
==============================================================================
--- trunk/widgets/rb-entry-view.c	(original)
+++ trunk/widgets/rb-entry-view.c	Tue Jul 29 13:17:53 2008
@@ -72,7 +72,7 @@
 
 #include <glib/gi18n.h>
 #include <gtk/gtk.h>
-#include <libgnomevfs/gnome-vfs-utils.h>
+#include <glib/gurifuncs.h>
 
 #include "rb-tree-dnd.h"
 #include "rb-entry-view.h"
@@ -1077,7 +1077,7 @@
 	entry = rhythmdb_query_model_iter_to_entry (data->view->priv->model, iter);
 
 	location = rhythmdb_entry_get_string (entry, data->propid);
-	str = gnome_vfs_unescape_string_for_display (location);
+	str = g_uri_unescape_string (location, G_URI_RESERVED_CHARS_ALLOWED_IN_PATH);
 
 	g_object_set (renderer, "text", str, NULL);
 	g_free (str);

Modified: trunk/widgets/rb-entry-view.h
==============================================================================
--- trunk/widgets/rb-entry-view.h	(original)
+++ trunk/widgets/rb-entry-view.h	Tue Jul 29 13:17:53 2008
@@ -34,7 +34,6 @@
 #include <gtk/gtkscrolledwindow.h>
 #include <gtk/gtktreeviewcolumn.h>
 #include <gtk/gtkdnd.h>
-#include <libgnomevfs/gnome-vfs-file-info.h>
 
 #include "rhythmdb.h"
 #include "rhythmdb-query-model.h"

Modified: trunk/widgets/rb-property-view.c
==============================================================================
--- trunk/widgets/rb-property-view.c	(original)
+++ trunk/widgets/rb-property-view.c	Tue Jul 29 13:17:53 2008
@@ -36,7 +36,6 @@
 #include <glib/gi18n.h>
 #include <gdk/gdkkeysyms.h>
 #include <gtk/gtk.h>
-#include <libgnomevfs/gnome-vfs-utils.h>
 
 #include "rb-property-view.h"
 #include "rb-dialog.h"

Modified: trunk/widgets/rb-query-creator-properties.c
==============================================================================
--- trunk/widgets/rb-query-creator-properties.c	(original)
+++ trunk/widgets/rb-query-creator-properties.c	Tue Jul 29 13:17:53 2008
@@ -30,9 +30,9 @@
 
 #include "config.h"
 
-#include <libgnome/gnome-i18n.h>
+#include <glib/gi18n.h>
+#include <glib/gurifuncs.h>
 #include <gtk/gtk.h>
-#include <libgnomevfs/gnome-vfs-utils.h>
 
 #include "rhythmdb.h"
 #include "rb-query-creator-private.h"
@@ -283,7 +283,7 @@
 static void
 escapedStringCriteriaSetWidgetData (GtkWidget *widget, GValue *val)
 {
-	char *text = gnome_vfs_unescape_string (g_value_get_string (val), NULL);
+	char *text = g_uri_unescape_string (g_value_get_string (val), G_URI_RESERVED_CHARS_ALLOWED_IN_PATH);
 	gtk_entry_set_text (GTK_ENTRY (widget), text);
 	g_free (text);
 }
@@ -291,7 +291,7 @@
 static void
 escapedStringCriteriaGetWidgetData (GtkWidget *widget, GValue *val)
 {
-	char *text = gnome_vfs_escape_host_and_path_string (gtk_entry_get_text (GTK_ENTRY (widget)));
+	char *text = g_uri_escape_string (gtk_entry_get_text (GTK_ENTRY (widget)), G_URI_RESERVED_CHARS_ALLOWED_IN_PATH, TRUE);
 
 	g_value_init (val, G_TYPE_STRING);
 	g_value_set_string (val, text);

Modified: trunk/widgets/rb-song-info.c
==============================================================================
--- trunk/widgets/rb-song-info.c	(original)
+++ trunk/widgets/rb-song-info.c	Tue Jul 29 13:17:53 2008
@@ -45,8 +45,6 @@
 #include <glib/gi18n.h>
 #include <gtk/gtk.h>
 #include <glade/glade.h>
-#include <libgnomevfs/gnome-vfs.h>
-#include <libgnomevfs/gnome-vfs-utils.h>
 
 #include "rhythmdb.h"
 #include "rhythmdb-property-model.h"
@@ -58,6 +56,7 @@
 #include "eel-gconf-extensions.h"
 #include "rb-source.h"
 #include "rb-shell.h"
+#include "rb-file-helpers.h"
 
 static void rb_song_info_class_init (RBSongInfoClass *klass);
 static void rb_song_info_init (RBSongInfo *song_info);
@@ -1091,7 +1090,7 @@
 	char *text = NULL;
 	guint64 filesize = 0;
 	filesize = rhythmdb_entry_get_uint64 (song_info->priv->current_entry, RHYTHMDB_PROP_FILE_SIZE);
-	text = gnome_vfs_format_file_size_for_display (filesize);
+	text = g_format_size_for_display (filesize);
 	gtk_label_set_text (GTK_LABEL (song_info->priv->filesize), text);
 	g_free (text);
 }
@@ -1110,10 +1109,12 @@
 		char *basename, *dir, *desktopdir;
 
 		basename = g_path_get_basename (text);
-		tmp = gnome_vfs_unescape_string_for_display (basename);
+		tmp = g_uri_unescape_string (basename, G_URI_RESERVED_CHARS_ALLOWED_IN_PATH);
 		g_free (basename);
 		tmp_utf8 = g_filename_to_utf8 (tmp, -1, NULL, NULL, NULL);
 		g_free (tmp);
+		tmp = NULL;
+
 		if (tmp_utf8 != NULL) {
 			gtk_entry_set_text (GTK_ENTRY (song_info->priv->name),
 					    tmp_utf8);
@@ -1124,19 +1125,22 @@
 
 		g_free (tmp_utf8);
 
-		tmp = gnome_vfs_get_local_path_from_uri (text);
-		if (tmp == NULL)
+		if (rb_uri_is_local (text)) {
+			tmp = g_filename_from_uri (text, NULL, NULL);
+		}
+		if (tmp == NULL) {
 			tmp = g_strdup (text);
+		}
+
 		dir = g_path_get_dirname (tmp);
 		g_free (tmp);
-		tmp = gnome_vfs_unescape_string_for_display (dir);
+		tmp = g_uri_unescape_string (dir, G_URI_RESERVED_CHARS_ALLOWED_IN_PATH);
 		g_free (dir);
 		tmp_utf8 = g_filename_to_utf8 (tmp, -1, NULL, NULL, NULL);
 		g_free (tmp);
 
 		desktopdir = g_build_filename (g_get_home_dir (), "Desktop", NULL);
-		if ((tmp_utf8 != NULL) && (strcmp (tmp_utf8, desktopdir) == 0))
-		{
+		if ((tmp_utf8 != NULL) && (strcmp (tmp_utf8, desktopdir) == 0)) {
 			g_free (tmp_utf8);
 			tmp_utf8 = g_strdup (_("On the desktop"));
 		}

Modified: trunk/widgets/rb-uri-dialog.c
==============================================================================
--- trunk/widgets/rb-uri-dialog.c	(original)
+++ trunk/widgets/rb-uri-dialog.c	Tue Jul 29 13:17:53 2008
@@ -36,7 +36,6 @@
 #include <glib/gi18n.h>
 #include <gtk/gtk.h>
 #include <glade/glade.h>
-#include <libgnomevfs/gnome-vfs.h>
 
 #include "rb-uri-dialog.h"
 #include "rb-glade-helpers.h"



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]