Index: gedit/gedit-tab.c
===================================================================
--- gedit/gedit-tab.c	(revisione 6382)
+++ gedit/gedit-tab.c	(copia locale)
@@ -1483,6 +1483,17 @@ view_focused_in (GtkWidget     *widget,
 	return FALSE;
 }
 
+static GMountOperation *
+tab_mount_operation_factory (GeditDocument *doc,
+			     gpointer userdata)
+{
+	GeditTab *tab = GEDIT_TAB (userdata);
+	GtkWidget *window;
+
+	window = gtk_widget_get_toplevel (GTK_WIDGET (tab));
+	return gtk_mount_operation_new (GTK_WINDOW (window));
+}
+
 static void
 gedit_tab_init (GeditTab *tab)
 {
@@ -1522,6 +1533,8 @@ gedit_tab_init (GeditTab *tab)
 	doc = gedit_document_new ();
 	g_object_set_data (G_OBJECT (doc), GEDIT_TAB_KEY, tab);
 
+	gedit_document_set_mount_operation_factory (doc, tab_mount_operation_factory, tab);
+
 	tab->priv->view = gedit_view_new (doc);
 	g_object_unref (doc);
 	gtk_widget_show (tab->priv->view);
Index: gedit/gedit-document-loader.c
===================================================================
--- gedit/gedit-document-loader.c	(revisione 6382)
+++ gedit/gedit-document-loader.c	(copia locale)
@@ -44,7 +44,7 @@
 
 /* Those are for the the gedit_document_loader_new() factory */
 #include "gedit-mmap-document-loader.h"
-#include "gedit-gnomevfs-document-loader.h"
+#include "gedit-gio-document-loader.h"
 
 G_DEFINE_ABSTRACT_TYPE(GeditDocumentLoader, gedit_document_loader, G_TYPE_OBJECT)
 
@@ -367,7 +367,7 @@ gedit_document_loader_new (GeditDocument
 	if (gedit_utils_uri_has_file_scheme (uri))
 		loader_type = GEDIT_TYPE_MMAP_DOCUMENT_LOADER;
 	else
-		loader_type = GEDIT_TYPE_GNOMEVFS_DOCUMENT_LOADER;
+		loader_type = GEDIT_TYPE_GIO_DOCUMENT_LOADER;
 
 	loader = GEDIT_DOCUMENT_LOADER (g_object_new (loader_type,
 						      "document", doc,
Index: gedit/gedit-local-document-saver.c
===================================================================
--- gedit/gedit-local-document-saver.c	(revisione 6382)
+++ gedit/gedit-local-document-saver.c	(copia locale)
@@ -40,7 +40,6 @@
 
 #include <glib/gi18n.h>
 #include <glib/gfileutils.h>
-#include <libgnomevfs/gnome-vfs.h>
 
 #include "gedit-local-document-saver.h"
 #include "gedit-debug.h"
@@ -196,12 +195,10 @@ copy_file_data (gint     sfd,
 		bytes_read = read (sfd, buffer, BUFSIZE);
 		if (bytes_read == -1)
 		{
-			GnomeVFSResult result = gnome_vfs_result_from_errno ();
-
 			g_set_error (error,
 				     GEDIT_DOCUMENT_ERROR,
-				     result,
-				     gnome_vfs_result_to_string (result));
+				     g_io_error_from_errno (errno),
+				     g_strerror (errno));
 
 			ret = FALSE;
 
@@ -216,17 +213,13 @@ copy_file_data (gint     sfd,
 			bytes_written = write (dfd, write_buffer, bytes_to_write);
 			if (bytes_written == -1)
 			{
-				GnomeVFSResult result;
-
 				if (errno == EINTR)
 					continue;
 
-				result = gnome_vfs_result_from_errno ();
-
 				g_set_error (error,
 					     GEDIT_DOCUMENT_ERROR,
-					     result,
-					     gnome_vfs_result_to_string (result));
+					     g_io_error_from_errno (errno),
+					     g_strerror (errno));
 
 				ret = FALSE;
 
@@ -252,21 +245,31 @@ copy_file_data (gint     sfd,
 static gchar *
 get_slow_mime_type (const char *text_uri)
 {
-	GnomeVFSFileInfo *info;
-	char *mime_type;
-	GnomeVFSResult result;
-
-	info = gnome_vfs_file_info_new ();
-	result = gnome_vfs_get_file_info (text_uri, info,
-					  GNOME_VFS_FILE_INFO_GET_MIME_TYPE |
-					  GNOME_VFS_FILE_INFO_FORCE_SLOW_MIME_TYPE |
-					  GNOME_VFS_FILE_INFO_FOLLOW_LINKS);
-	if (info->mime_type == NULL || result != GNOME_VFS_OK)
-		mime_type = NULL;
-	else
-		mime_type = g_strdup (info->mime_type);
+	GFile *gfile;
+	GFileInfo *info;
+	char *mime_type = NULL;
+
+	gfile = g_file_new_for_uri (text_uri);
+
+	/* FIXME: we somehow seem to do a lot of sync stats for mime type
+	   querying */
+	info = g_file_query_info (gfile,
+	                          G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE,
+	                          G_FILE_QUERY_INFO_NONE,
+	                          NULL,
+	                          NULL);
+
+	g_object_unref (gfile);
+
+	if (info != NULL &&
+	    g_file_info_has_attribute (info,
+				       G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE))
+	{
+		mime_type = g_strdup (g_file_info_get_content_type (info));
+	}
 
-	gnome_vfs_file_info_unref (info);
+	if (info != NULL)
+		g_object_unref (info);
 
 	return mime_type;
 }
@@ -295,12 +298,10 @@ save_existing_local_file (GeditLocalDocu
 
 	if (fstat (lsaver->priv->fd, &statbuf) != 0) 
 	{
-		GnomeVFSResult result = gnome_vfs_result_from_errno ();
-
 		g_set_error (&lsaver->priv->error,
 			     GEDIT_DOCUMENT_ERROR,
-			     result,
-			     gnome_vfs_result_to_string (result));
+			     g_io_error_from_errno (errno),
+			     g_strerror (errno));
 
 		goto out;
 	}
@@ -312,14 +313,14 @@ save_existing_local_file (GeditLocalDocu
 		{
 			g_set_error (&lsaver->priv->error,
 				     GEDIT_DOCUMENT_ERROR,
-				     GNOME_VFS_ERROR_IS_DIRECTORY,
-				     gnome_vfs_result_to_string (GNOME_VFS_ERROR_IS_DIRECTORY));
+				     G_IO_ERROR_IS_DIRECTORY,
+				     "Is a directory");
 		}
 		else
 		{
 			g_set_error (&lsaver->priv->error,
 				     GEDIT_DOCUMENT_ERROR,
-				     GEDIT_DOCUMENT_ERROR_NOT_REGULAR_FILE,
+				     G_IO_ERROR_NOT_REGULAR_FILE,
 				     "Not a regular file");
 		}
 
@@ -331,8 +332,8 @@ save_existing_local_file (GeditLocalDocu
 	{
 		g_set_error (&lsaver->priv->error,
 			     GEDIT_DOCUMENT_ERROR,
-			     GNOME_VFS_ERROR_READ_ONLY,
-			     gnome_vfs_result_to_string (GNOME_VFS_ERROR_READ_ONLY));
+			     G_IO_ERROR_READ_ONLY,
+			     "File is read only");
 
 		goto out;
 	}
@@ -362,8 +363,8 @@ save_existing_local_file (GeditLocalDocu
 
 		g_set_error (&lsaver->priv->error,
 			     GEDIT_DOCUMENT_ERROR,
-			     GNOME_VFS_ERROR_GENERIC,
-			     gnome_vfs_result_to_string (GNOME_VFS_ERROR_GENERIC));
+			     G_IO_ERROR_FAILED,
+			     "Failure");
 
 		goto out;
 	}
@@ -466,14 +467,12 @@ save_existing_local_file (GeditLocalDocu
 		/* original -> backup */
 		if (rename (lsaver->priv->local_path, backup_filename) != 0)
 		{
-			GnomeVFSResult result = gnome_vfs_result_from_errno ();
-
 			gedit_debug_message (DEBUG_SAVER, "could not rename original -> backup");
 
 			g_set_error (&lsaver->priv->error,
 				     GEDIT_DOCUMENT_ERROR,
-				     result,
-				     gnome_vfs_result_to_string (result));
+				     g_io_error_from_errno (errno),
+				     g_strerror (errno));
 
 			close (tmpfd);
 			unlink (tmp_filename);
@@ -485,14 +484,12 @@ save_existing_local_file (GeditLocalDocu
 		/* tmp -> original */
 		if (rename (tmp_filename, lsaver->priv->local_path) != 0)
 		{
-			GnomeVFSResult result = gnome_vfs_result_from_errno ();
-
 			gedit_debug_message (DEBUG_SAVER, "could not rename tmp -> original");
 
 			g_set_error (&lsaver->priv->error,
 				     GEDIT_DOCUMENT_ERROR,
-				     result,
-				     gnome_vfs_result_to_string (result));
+				     g_io_error_from_errno (errno),
+				     g_strerror (errno));
 
 			/* try to restore... no error checking */
 			rename (backup_filename, lsaver->priv->local_path);
@@ -509,12 +506,10 @@ save_existing_local_file (GeditLocalDocu
 		/* restat and get the mime type */
 		if (fstat (tmpfd, &new_statbuf) != 0)
 		{
-			GnomeVFSResult result = gnome_vfs_result_from_errno ();
-
 			g_set_error (&lsaver->priv->error,
 				     GEDIT_DOCUMENT_ERROR,
-				     result,
-				     gnome_vfs_result_to_string (result));
+				     g_io_error_from_errno (errno),
+				     g_strerror (errno));
 
 			close (tmpfd);
 			goto out;
@@ -697,12 +692,10 @@ save_existing_local_file (GeditLocalDocu
 	/* re stat the file and refetch the mime type */
 	if (fstat (lsaver->priv->fd, &new_statbuf) != 0)
 	{
-		GnomeVFSResult result = gnome_vfs_result_from_errno ();
-
 		g_set_error (&lsaver->priv->error,
 			     GEDIT_DOCUMENT_ERROR,
-			     result,
-			     gnome_vfs_result_to_string (result));
+			     g_io_error_from_errno (errno),
+			     g_strerror (errno));
 
 		goto out;
 	}
@@ -745,12 +738,10 @@ save_new_local_file (GeditLocalDocumentS
 	/* stat the file and fetch the mime type */
 	if (fstat (lsaver->priv->fd, &statbuf) != 0)
 	{
-		GnomeVFSResult result = gnome_vfs_result_from_errno ();
-
 		g_set_error (&lsaver->priv->error,
 			     GEDIT_DOCUMENT_ERROR,
-			     result,
-			     gnome_vfs_result_to_string (result));
+			     g_io_error_from_errno (errno),
+			     g_strerror (errno));
 
 		goto out;
 	}
@@ -792,7 +783,6 @@ save_file (GeditLocalDocumentSaver *lsav
 {
 	GeditDocumentSaver *saver = GEDIT_DOCUMENT_SAVER (lsaver);
 	GSourceFunc next_phase;
-	GnomeVFSResult result;
 
 	gedit_debug (DEBUG_SAVER);
 
@@ -821,12 +811,10 @@ save_file (GeditLocalDocumentSaver *lsav
 	}
 
 	/* else error */
-	result = gnome_vfs_result_from_errno (); //may it happen that no errno?
-
 	g_set_error (&lsaver->priv->error,
 		     GEDIT_DOCUMENT_ERROR,
-		     result,
-		     gnome_vfs_result_to_string (result));
+		     g_io_error_from_errno (errno),
+		     g_strerror (errno));
 
 	next_phase = (GSourceFunc) open_local_failed;
 
@@ -844,10 +832,14 @@ gedit_local_document_saver_save (GeditDo
 				 time_t              old_mtime)
 {
 	GeditLocalDocumentSaver *lsaver = GEDIT_LOCAL_DOCUMENT_SAVER (saver);
-
+	GFile *gfile;
+	
 	lsaver->priv->doc_mtime = old_mtime;
 
-	lsaver->priv->local_path = gnome_vfs_get_local_path_from_uri (saver->uri);
+	gfile = g_file_new_for_uri (saver->uri);
+	lsaver->priv->local_path = g_file_get_path (gfile);
+	g_object_unref (gfile);
+
 	if (lsaver->priv->local_path != NULL)
 	{
 		save_file (lsaver);
@@ -856,8 +848,8 @@ gedit_local_document_saver_save (GeditDo
 	{
 		g_set_error (&lsaver->priv->error,
 			     GEDIT_DOCUMENT_ERROR,
-			     GNOME_VFS_ERROR_NOT_SUPPORTED,
-			     gnome_vfs_result_to_string (GNOME_VFS_ERROR_NOT_SUPPORTED));
+			     G_IO_ERROR_NOT_SUPPORTED,
+			     "Operation is not supported");
 	}
 }
 
Index: gedit/gedit.c
===================================================================
--- gedit/gedit.c	(revisione 6382)
+++ gedit/gedit.c	(copia locale)
@@ -524,10 +524,6 @@ main (int argc, char *argv[])
 	gedit_debug_message (DEBUG_APP, "Init prefs manager");
 	gedit_prefs_manager_app_init ();
 
-	/* Initialize authentication manager */
-	gedit_debug_message (DEBUG_APP, "Init authentication manager");	
-	gnome_authentication_manager_init ();
-	
 	/* Init plugins engine */
 	gedit_debug_message (DEBUG_APP, "Init plugins");
 	engine = gedit_plugins_engine_get_default ();
Index: gedit/gedit-gio-document-saver.c
===================================================================
--- gedit/gedit-gio-document-saver.c	(revisione 0)
+++ gedit/gedit-gio-document-saver.c	(revisione 0)
@@ -0,0 +1,776 @@
+/*
+ * gedit-gio-document-saver.c
+ * This file is part of gedit
+ *
+ * Copyright (C) 2005-2006 - Paolo Borelli and Paolo Maggi
+ * Copyright (C) 2007 - Paolo Borelli, Paolo Maggi, Steve Frécinaux
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Modified by the gedit Team, 2005-2006. See the AUTHORS file for a
+ * list of people on the gedit Team.
+ * See the ChangeLog files for a list of changes.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <glib/gi18n.h>
+#include <glib/gfileutils.h>
+#include <gio/gio.h>
+#include <string.h>
+
+#include "gedit-convert.h"
+#include "gedit-gio-document-saver.h"
+#include "gedit-debug.h"
+
+typedef struct
+{
+	GeditGioDocumentSaver *saver;
+	gchar 		      *buffer;
+	GCancellable 	      *cancellable;
+	gboolean	       tried_mount;
+} AsyncData;
+
+#define WRITE_CHUNK_SIZE 8192
+#define REMOTE_QUERY_ATTRIBUTES G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE "," \
+				G_FILE_ATTRIBUTE_TIME_MODIFIED
+				
+#define GEDIT_GIO_DOCUMENT_SAVER_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), \
+							  GEDIT_TYPE_GIO_DOCUMENT_SAVER, \
+							  GeditGioDocumentSaverPrivate))
+
+static void	     gedit_gio_document_saver_save		    (GeditDocumentSaver *saver,
+								     time_t              old_mtime);
+static const gchar *gedit_gio_document_saver_get_mime_type	    (GeditDocumentSaver *saver);
+static time_t       gedit_gio_document_saver_get_mtime		    (GeditDocumentSaver *saver);
+static goffset	     gedit_gio_document_saver_get_file_size	    (GeditDocumentSaver *saver);
+static goffset	     gedit_gio_document_saver_get_bytes_written	    (GeditDocumentSaver *saver);
+
+
+static void 	    check_modified_async 			    (AsyncData          *async);
+
+struct _GeditGioDocumentSaverPrivate
+{
+	time_t                    doc_mtime;
+	gchar                    *mime_type; //CHECK use FileInfo instead?
+
+	goffset			  size;
+	goffset			  bytes_written;
+
+	GFile			 *gfile;
+	GCancellable		 *cancellable;
+	GFileOutputStream	 *stream;
+	
+	GError                   *error;
+};
+
+G_DEFINE_TYPE(GeditGioDocumentSaver, gedit_gio_document_saver, GEDIT_TYPE_DOCUMENT_SAVER)
+
+static void
+gedit_gio_document_saver_finalize (GObject *object)
+{
+	GeditGioDocumentSaverPrivate *priv = GEDIT_GIO_DOCUMENT_SAVER (object)->priv;
+
+	if (priv->cancellable)
+	{
+		g_cancellable_cancel (priv->cancellable);
+		g_object_unref (priv->cancellable);
+	}
+
+	if (priv->gfile)
+		g_object_unref (priv->gfile);
+
+	g_free (priv->mime_type);
+
+	if (priv->error)
+		g_error_free (priv->error);
+		
+	if (priv->stream)
+		g_object_unref (priv->stream);
+
+	G_OBJECT_CLASS (gedit_gio_document_saver_parent_class)->finalize (object);
+}
+
+static AsyncData *
+async_data_new (GeditGioDocumentSaver *gvsaver)
+{
+	AsyncData *async;
+	
+	async = g_new (AsyncData, 1);
+	async->saver = gvsaver;
+	async->buffer = NULL;
+	async->cancellable = g_object_ref (gvsaver->priv->cancellable);
+	async->tried_mount = FALSE;
+	
+	return async;
+}
+
+static void
+async_data_free (AsyncData *async)
+{
+	g_object_unref (async->cancellable);
+	g_free (async->buffer);
+	g_free (async);
+}
+
+static void 
+gedit_gio_document_saver_class_init (GeditGioDocumentSaverClass *klass)
+{
+	GObjectClass *object_class = G_OBJECT_CLASS (klass);
+	GeditDocumentSaverClass *saver_class = GEDIT_DOCUMENT_SAVER_CLASS (klass);
+
+	object_class->finalize = gedit_gio_document_saver_finalize;
+
+	saver_class->save = gedit_gio_document_saver_save;
+	saver_class->get_mime_type = gedit_gio_document_saver_get_mime_type;
+	saver_class->get_mtime = gedit_gio_document_saver_get_mtime;
+	saver_class->get_file_size = gedit_gio_document_saver_get_file_size;
+	saver_class->get_bytes_written = gedit_gio_document_saver_get_bytes_written;
+
+	g_type_class_add_private (object_class, sizeof(GeditGioDocumentSaverPrivate));
+}
+
+static void
+gedit_gio_document_saver_init (GeditGioDocumentSaver *gvsaver)
+{
+	gvsaver->priv = GEDIT_GIO_DOCUMENT_SAVER_GET_PRIVATE (gvsaver);
+
+	gvsaver->priv->cancellable = g_cancellable_new ();
+	gvsaver->priv->error = NULL;
+}
+
+static void
+remote_save_completed_or_failed (GeditGioDocumentSaver *gvsaver, AsyncData *async)
+{
+	if (async)
+		async_data_free (async);
+
+	gedit_document_saver_saving (GEDIT_DOCUMENT_SAVER (gvsaver),
+				     TRUE,
+				     gvsaver->priv->error);
+}
+
+/* prototype, because they call each other... isn't C lovely */
+static void write_file_chunk (AsyncData *async);
+
+static void
+handle_file_info (AsyncData *async,
+		  GFileInfo *info,
+		  GError    *error)
+{
+	GeditGioDocumentSaver *saver;
+
+	saver = async->saver;
+
+	if (!info)
+	{
+		gedit_debug_message (DEBUG_SAVER, "Query info failed: %s", error->message);
+		g_set_error (&saver->priv->error,
+			     GEDIT_DOCUMENT_ERROR,
+			     error->code,
+			     error->message);
+		g_error_free (error);
+	}
+	else
+	{
+		GTimeVal mtime;
+
+		gedit_debug_message (DEBUG_SAVER, "Query info finished");
+
+		if (g_file_info_has_attribute (info,
+					       G_FILE_ATTRIBUTE_TIME_MODIFIED))
+		{
+			g_file_info_get_modification_time (info, &mtime);
+			saver->priv->doc_mtime = mtime.tv_sec;
+		}
+
+		if (g_file_info_has_attribute (info,
+					       G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE))
+		{
+			saver->priv->mime_type = g_strdup (g_file_info_get_content_type (info));
+		}
+
+		g_object_unref (info);
+	}
+}
+
+static void
+remote_reget_info_cb (GFile        *source,
+		      GAsyncResult *res,
+		      AsyncData    *async)
+{
+	GFileInfo *info;
+	GError *error = NULL;
+
+	/* check cancelled state manually */
+	if (g_cancellable_is_cancelled (async->cancellable))
+	{
+		async_data_free (async);
+		return;
+	}
+	
+	gedit_debug_message (DEBUG_SAVER, "Finished query info on file");
+	info = g_file_query_info_finish (source, res, &error);
+	
+	handle_file_info (async, info, error);
+	remote_save_completed_or_failed (async->saver, async);
+}
+
+static void
+close_async_ready_get_info_cb (GOutputStream *stream,
+			       GAsyncResult  *res,
+			       AsyncData     *async)
+{
+	GError *error = NULL;
+	
+	/* check cancelled state manually */
+	if (g_cancellable_is_cancelled (async->cancellable))
+	{
+		async_data_free (async);
+		return;
+	}
+	
+	gedit_debug_message (DEBUG_SAVER, "Finished closing stream");
+	
+	if (!g_output_stream_close_finish (stream, res, &error))
+	{
+		gedit_debug_message (DEBUG_SAVER, "Closing stream error: %s", error->message);
+
+		g_set_error (&async->saver->priv->error,
+		             GEDIT_DOCUMENT_ERROR,
+		             error->code,
+		             error->message);
+		g_error_free (error);
+		
+		remote_save_completed_or_failed (async->saver, async);
+		return;
+	}
+	
+	gedit_debug_message (DEBUG_SAVER, "Query info on file");
+	g_file_query_info_async (async->saver->priv->gfile,
+			         REMOTE_QUERY_ATTRIBUTES,
+			         G_FILE_QUERY_INFO_NONE,
+			         G_PRIORITY_HIGH,
+			         async->cancellable,
+			         (GAsyncReadyCallback) remote_reget_info_cb,
+			         async);
+}
+
+static void
+close_async_ready_cb (GOutputStream *stream,
+		      GAsyncResult  *res,
+		      AsyncData     *async)
+{
+	GError *error = NULL;
+
+	/* check cancelled state manually */
+	if (g_cancellable_is_cancelled (async->cancellable))
+	{
+		async_data_free (async);
+		return;
+	}
+
+	if (!g_output_stream_close_finish (stream, res, &error))
+	{
+		g_set_error (&async->saver->priv->error,
+		             GEDIT_DOCUMENT_ERROR,
+		             error->code,
+		             error->message);
+		g_error_free (error);
+	}
+
+	remote_save_completed_or_failed (async->saver, async);
+}
+
+static void
+remote_get_info_cb (GFileOutputStream *stream,
+		    GAsyncResult      *res,
+		    AsyncData         *async)
+{
+	GFileInfo *info;
+	GError *error = NULL;
+	GAsyncReadyCallback next_callback;
+
+	/* check cancelled state manually */
+	if (g_cancellable_is_cancelled (async->cancellable))
+	{
+		async_data_free (async);
+		return;
+	}
+	
+	gedit_debug_message (DEBUG_SAVER, "Finishing info query");
+	info = g_file_output_stream_query_info_finish (stream, res, &error);
+	gedit_debug_message (DEBUG_SAVER, "Query info result: %s", info ? "ok" : "fail");
+	
+	if (!info && (error->code == G_IO_ERROR_NOT_SUPPORTED || error->code == G_IO_ERROR_CLOSED))
+	{
+		gedit_debug_message (DEBUG_SAVER, "Query info not supported on stream, trying on file");
+
+		/* apparently the output stream does not support query info.
+		 * we're forced to restat on the file. But first we make sure
+		 * to close the stream
+		 */
+		g_error_free (error);
+		next_callback = (GAsyncReadyCallback) close_async_ready_get_info_cb;
+	}
+	else
+	{
+		handle_file_info (async, info, error);
+		g_object_unref (info);
+
+		next_callback = (GAsyncReadyCallback) close_async_ready_cb;
+	}
+	
+	g_output_stream_close_async (G_OUTPUT_STREAM (async->saver->priv->stream),
+			     G_PRIORITY_HIGH,
+			     async->cancellable,
+			     next_callback,
+			     async);
+}
+
+static void
+write_complete (AsyncData *async)
+{
+	/* document is succesfully saved. we know requery for the mime type and
+	 * the mtime. I'm not sure this is actually necessary, can't we just use
+	 * g_content_type_guess (since we have the file name and the data)
+	 */
+	gedit_debug_message (DEBUG_SAVER, "Write complete, query info on stream");
+	
+	/* query info on the stream */
+	g_file_output_stream_query_info_async (async->saver->priv->stream, 
+					       REMOTE_QUERY_ATTRIBUTES,
+					       G_PRIORITY_HIGH,
+					       async->cancellable,
+					       (GAsyncReadyCallback) remote_get_info_cb,
+					       async);
+}
+
+static void
+async_write_cb (GOutputStream *stream,
+	        GAsyncResult  *res,
+	        AsyncData     *async)
+{
+	GError *error = NULL;
+	GeditGioDocumentSaver *gvsaver;
+	gssize bytes_written;
+	
+	gedit_debug (DEBUG_SAVER);
+	
+	/* manually check cancelled state */
+	if (g_cancellable_is_cancelled (async->cancellable))
+	{
+		async_data_free (async);
+		return;
+	}
+
+	gvsaver = async->saver;
+	bytes_written = g_output_stream_write_finish (stream, res, &error);
+	
+	gedit_debug_message (DEBUG_SAVER, "Written: %d", bytes_written);
+	
+	if (bytes_written == -1)
+	{
+		gedit_debug_message (DEBUG_SAVER, "Write error: %s", error->message);
+
+		g_set_error (&gvsaver->priv->error,
+			     GEDIT_DOCUMENT_ERROR,
+			     error->code,
+			     error->message);
+
+		remote_save_completed_or_failed (gvsaver, async);
+		return;
+	}
+	
+	gvsaver->priv->bytes_written += bytes_written;
+	
+	/* if nothing is written we're done */
+	if (gvsaver->priv->bytes_written == gvsaver->priv->size)
+	{
+		write_complete (async);
+		return;
+	}
+	
+	/* otherwise emit progress and write some more */
+
+	/* note that this signal blocks the write... check if it isn't
+	 * a performance problem
+	 */
+	gedit_document_saver_saving (GEDIT_DOCUMENT_SAVER (gvsaver),
+				     FALSE,
+				     NULL);
+
+	write_file_chunk (async);
+}
+
+static void
+write_file_chunk (AsyncData *async)
+{
+	GeditGioDocumentSaver *gvsaver;
+
+	gvsaver = async->saver;
+
+	gedit_debug_message (DEBUG_SAVER, "Writing next chunk: %Ld/%Ld", gvsaver->priv->bytes_written, gvsaver->priv->size);
+
+	g_output_stream_write_async (G_OUTPUT_STREAM (gvsaver->priv->stream),
+				     async->buffer + gvsaver->priv->bytes_written,
+				     MIN (WRITE_CHUNK_SIZE, gvsaver->priv->size - 
+				     			    gvsaver->priv->bytes_written),
+				     G_PRIORITY_HIGH,
+				     async->cancellable,
+				     (GAsyncReadyCallback) async_write_cb,
+				     async);
+}
+
+static void
+async_replace_ready_callback (GFile        *source,
+			      GAsyncResult *res,
+			      AsyncData    *async)
+{
+	GeditGioDocumentSaver *gvsaver;
+	GError *error = NULL;
+
+	/* Check cancelled state manually */
+	if (g_cancellable_is_cancelled (async->cancellable))
+	{
+		async_data_free (async);
+		return;
+	}
+	
+	gvsaver = async->saver;
+	gvsaver->priv->stream = g_file_replace_finish (source, res, &error);
+	
+	/* handle any error that might occur */
+	if (!gvsaver->priv->stream)
+	{
+		gedit_debug_message (DEBUG_SAVER, "Opening file failed: %s", error->message);
+		g_set_error (&gvsaver->priv->error,
+			     GEDIT_DOCUMENT_ERROR,
+			     error->code,
+			     error->message);
+
+		remote_save_completed_or_failed (gvsaver, async);
+		return;
+	}
+
+	/* now that we have the stream, start writing async to it */
+	write_file_chunk (async);
+}
+
+static gchar *
+append_new_line (GeditGioDocumentSaver  *gvsaver, 
+		 gchar 		        *buffer, 
+		 gsize 		        *len, 
+		 GError 	       **error)
+{
+	GeditDocumentSaver *saver = GEDIT_DOCUMENT_SAVER (gvsaver);
+	gchar *converted_n = NULL;
+	gsize n_len;
+	gchar *n_buffer;
+	
+	if (saver->encoding != gedit_encoding_get_utf8 ())
+	{
+		converted_n = gedit_convert_from_utf8 ("\n", 
+						       -1, 
+						       saver->encoding, 
+						       &n_len, 
+						       NULL);
+		
+		if (!converted_n)
+		{
+			/* we do not error out for this */
+			g_warning ("Cannot add '\\n' at the end of the file.");
+			return buffer;
+		}
+	}
+	else
+	{
+		converted_n = g_strdup ("\n");
+		n_len = 1;
+	}
+	
+	n_buffer = g_try_realloc (buffer, *len + n_len + 1);
+
+	if (!n_buffer)
+	{
+		g_free (converted_n);
+		g_set_error (error,
+			     GEDIT_DOCUMENT_ERROR,
+			     GEDIT_DOCUMENT_ERROR_TOO_BIG,
+			     "File is too big");
+		return NULL;
+	}
+	
+	/* Copy newline */
+	memcpy (n_buffer + *len, converted_n, n_len);
+	g_free (converted_n);
+	*len += n_len;
+	
+	n_buffer[*len] = '\0';
+	return n_buffer;
+}
+
+static void
+begin_write (AsyncData *async)
+{
+	GeditGioDocumentSaver *gvsaver;
+	gsize len;
+	GError *error = NULL;
+
+	gedit_debug_message (DEBUG_SAVER, "Start replacing file contents");
+
+	/* For remote files we simply use g_file_replace_async. There is no
+	 * backup as of yet
+	 */
+	gvsaver = async->saver;
+	gchar *buffer = gedit_document_saver_get_document_contents (GEDIT_DOCUMENT_SAVER (gvsaver), &len, &error);
+	
+	if (buffer)
+	{
+		/* Append new line to buffer */
+		buffer = append_new_line (gvsaver, buffer, &len, &error);
+	}
+	
+	if (!buffer)
+	{
+		g_set_error (&gvsaver->priv->error,
+			     GEDIT_DOCUMENT_ERROR,
+			     error->code,
+			     error->message);
+
+		remote_save_completed_or_failed (gvsaver, async);
+		return;
+	}
+
+	async->buffer = buffer;
+	gvsaver->priv->size = len;
+	
+	gedit_debug_message (DEBUG_SAVER, "File contents size: %Ld", gvsaver->priv->size);
+	gedit_debug_message (DEBUG_SAVER, "Calling replace_async");
+	
+	g_file_replace_async (gvsaver->priv->gfile, 
+			      NULL,
+			      FALSE,
+			      G_FILE_CREATE_NONE,
+			      G_PRIORITY_HIGH,
+			      async->cancellable,
+			      (GAsyncReadyCallback) async_replace_ready_callback,
+			      async);
+}
+
+static void
+mount_ready_callback (GFile        *file,
+		      GAsyncResult *res,
+		      AsyncData    *async)
+{
+	GError *error = NULL;
+	gboolean mounted;
+	
+	/* manual check for cancelled state */
+	if (g_cancellable_is_cancelled (async->cancellable))
+	{
+		async_data_free (async);
+		return;
+	}
+
+	mounted = g_file_mount_enclosing_volume_finish (file, res, &error);
+	
+	if (!mounted)
+	{
+		g_set_error (&async->saver->priv->error,
+			     GEDIT_DOCUMENT_ERROR,
+			     error->code,
+			     error->message);
+
+		g_error_free (error);
+		remote_save_completed_or_failed (async->saver, async);
+	}
+	else
+	{
+		/* try again to get the modified state */
+		check_modified_async (async);
+	}
+}
+
+static void
+recover_not_mounted (AsyncData *async)
+{
+	GeditDocumentSaver *saver;
+	GMountOperation *mount_operation;
+	
+	gedit_debug_message (DEBUG_SAVER, "Try mount enclosing volume");
+	
+	async->tried_mount = TRUE;
+	saver = GEDIT_DOCUMENT_SAVER (async->saver);
+	mount_operation = gedit_document_create_mount_operation (saver->document);
+	
+	g_file_mount_enclosing_volume (async->saver->priv->gfile,
+				       G_MOUNT_MOUNT_NONE,
+				       mount_operation,
+				       async->cancellable,
+				       (GAsyncReadyCallback) mount_ready_callback,
+				       async);	
+
+	g_object_unref (mount_operation);			
+}
+
+static void
+check_modification_callback (GFile        *source,
+			     GAsyncResult *res,
+			     AsyncData    *async)
+{
+	GeditGioDocumentSaver *gvsaver;
+	GError *error;
+	GFileInfo *info;
+	
+	/* manually check cancelled state */
+	if (g_cancellable_is_cancelled (async->cancellable))
+	{
+		async_data_free (async);
+		return;
+	}
+	
+	gvsaver = async->saver;
+	info = g_file_query_info_finish (source, res, &error);
+	if (info == NULL)
+	{
+		if (error->code == G_IO_ERROR_NOT_MOUNTED && !async->tried_mount)
+		{
+			recover_not_mounted (async);
+			g_error_free (error);
+			return;
+		}
+		
+		gedit_debug_message (DEBUG_SAVER, "Error getting modification: %s", error->message);
+		g_set_error (&gvsaver->priv->error,
+			     GEDIT_DOCUMENT_ERROR,
+			     error->code,
+			     error->message);
+
+		remote_save_completed_or_failed (gvsaver, async);
+
+		return;
+	}
+
+	/* check if the mtime is > what we know about it (if we have it) */
+	if (g_file_info_has_attribute (info,
+				       G_FILE_ATTRIBUTE_TIME_MODIFIED))
+	{
+		GTimeVal mtime;
+
+		g_file_info_get_modification_time (info, &mtime);
+
+		if (gvsaver->priv->doc_mtime > 0 &&
+		    mtime.tv_sec != gvsaver->priv->doc_mtime &&
+		    (GEDIT_DOCUMENT_SAVER (gvsaver)->flags & GEDIT_DOCUMENT_SAVE_IGNORE_MTIME) == 0)
+		{
+			gedit_debug_message (DEBUG_SAVER, "File is externally modified");
+			g_set_error (&gvsaver->priv->error,
+				     GEDIT_DOCUMENT_ERROR,
+				     GEDIT_DOCUMENT_ERROR_EXTERNALLY_MODIFIED,
+				     "Externally modified");
+
+			remote_save_completed_or_failed (gvsaver, async);
+			g_object_unref (info);
+
+			return;
+		}
+	}
+
+	g_object_unref (info);
+
+	/* modification check passed, start write */
+	begin_write (async);
+}
+
+static void
+check_modified_async (AsyncData *async)
+{
+	gedit_debug_message (DEBUG_SAVER, "Check externally modified");
+
+	g_file_query_info_async (async->saver->priv->gfile, 
+				 G_FILE_ATTRIBUTE_TIME_MODIFIED,
+				 G_FILE_QUERY_INFO_NONE,
+				 G_PRIORITY_HIGH,
+				 async->cancellable,
+				 (GAsyncReadyCallback) check_modification_callback,
+				 async);
+}
+
+static gboolean
+save_remote_file_real (GeditGioDocumentSaver *gvsaver)
+{
+	AsyncData *async;
+
+	gedit_debug_message (DEBUG_SAVER, "Starting gio save");
+	
+	/* First find out if the file is modified externally. This requires
+	 * a stat, but I don't think we can do this any other way
+	 */
+	async = async_data_new (gvsaver);
+	
+	check_modified_async (async);
+	
+	/* return false to stop timeout */
+	return FALSE;
+}
+
+static void
+gedit_gio_document_saver_save (GeditDocumentSaver *saver,
+			       time_t              old_mtime)
+{
+	GeditGioDocumentSaver *gvsaver = GEDIT_GIO_DOCUMENT_SAVER (saver);
+
+	gvsaver->priv->doc_mtime = old_mtime;
+	gvsaver->priv->gfile = g_file_new_for_uri (saver->uri);
+
+	/* saving start */
+	gedit_document_saver_saving (saver, FALSE, NULL);
+
+	g_timeout_add_full (G_PRIORITY_HIGH,
+			    0,
+			    (GSourceFunc) save_remote_file_real,
+			    gvsaver,
+			    NULL);
+}
+
+static const gchar *
+gedit_gio_document_saver_get_mime_type (GeditDocumentSaver *saver)
+{
+	return GEDIT_GIO_DOCUMENT_SAVER (saver)->priv->mime_type;
+}
+
+static time_t
+gedit_gio_document_saver_get_mtime (GeditDocumentSaver *saver)
+{
+	return GEDIT_GIO_DOCUMENT_SAVER (saver)->priv->doc_mtime;
+}
+
+static goffset
+gedit_gio_document_saver_get_file_size (GeditDocumentSaver *saver)
+{
+	return GEDIT_GIO_DOCUMENT_SAVER (saver)->priv->size;
+}
+
+static goffset
+gedit_gio_document_saver_get_bytes_written (GeditDocumentSaver *saver)
+{
+	return GEDIT_GIO_DOCUMENT_SAVER (saver)->priv->bytes_written;
+}
Index: gedit/gedit-gio-document-saver.h
===================================================================
--- gedit/gedit-gio-document-saver.h	(revisione 0)
+++ gedit/gedit-gio-document-saver.h	(revisione 0)
@@ -0,0 +1,75 @@
+/*
+ * gedit-gio-document-saver.h
+ * This file is part of gedit
+ *
+ * Copyright (C) 2005 - Paolo Maggi
+ * Copyrhing (C) 2007 - Paolo Maggi, Steve Frécinaux
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+ 
+/*
+ * Modified by the gedit Team, 2005-2007. See the AUTHORS file for a
+ * list of people on the gedit Team.
+ * See the ChangeLog files for a list of changes.
+ */
+
+#ifndef __GEDIT_GIO_DOCUMENT_SAVER_H__
+#define __GEDIT_GIO_DOCUMENT_SAVER_H__
+
+#include <gedit/gedit-document-saver.h>
+
+G_BEGIN_DECLS
+
+/*
+ * Type checking and casting macros
+ */
+#define GEDIT_TYPE_GIO_DOCUMENT_SAVER              (gedit_gio_document_saver_get_type())
+#define GEDIT_GIO_DOCUMENT_SAVER(obj)              (G_TYPE_CHECK_INSTANCE_CAST((obj), GEDIT_TYPE_GIO_DOCUMENT_SAVER, GeditGioDocumentSaver))
+#define GEDIT_GIO_DOCUMENT_SAVER_CLASS(klass)      (G_TYPE_CHECK_CLASS_CAST((klass), GEDIT_TYPE_GIO_DOCUMENT_SAVER, GeditGioDocumentSaverClass))
+#define GEDIT_IS_GIO_DOCUMENT_SAVER(obj)           (G_TYPE_CHECK_INSTANCE_TYPE((obj), GEDIT_TYPE_GIO_DOCUMENT_SAVER))
+#define GEDIT_IS_GIO_DOCUMENT_SAVER_CLASS(klass)   (G_TYPE_CHECK_CLASS_TYPE ((klass), GEDIT_TYPE_GIO_DOCUMENT_SAVER))
+#define GEDIT_GIO_DOCUMENT_SAVER_GET_CLASS(obj)    (G_TYPE_INSTANCE_GET_CLASS((obj), GEDIT_TYPE_GIO_DOCUMENT_SAVER, GeditGioDocumentSaverClass))
+
+/* Private structure type */
+typedef struct _GeditGioDocumentSaverPrivate GeditGioDocumentSaverPrivate;
+
+/*
+ * Main object structure
+ */
+typedef struct _GeditGioDocumentSaver GeditGioDocumentSaver;
+
+struct _GeditGioDocumentSaver 
+{
+	GeditDocumentSaver saver;
+
+	/*< private > */
+	GeditGioDocumentSaverPrivate *priv;
+};
+
+/*
+ * Class definition
+ */
+typedef GeditDocumentSaverClass GeditGioDocumentSaverClass;
+
+/*
+ * Public methods
+ */
+GType 		 	 gedit_gio_document_saver_get_type	(void) G_GNUC_CONST;
+
+G_END_DECLS
+
+#endif  /* __GEDIT_GIO_DOCUMENT_SAVER_H__  */
Index: gedit/gedit-io-error-message-area.c
===================================================================
--- gedit/gedit-io-error-message-area.c	(revisione 6382)
+++ gedit/gedit-io-error-message-area.c	(copia locale)
@@ -40,7 +40,7 @@
 #include <string.h>
 
 #include <glib/gi18n.h>
-#include <libgnomevfs/gnome-vfs.h>
+#include <gio/gio.h>
 
 #include "gedit-utils.h"
 #include "gedit-convert.h"
@@ -60,14 +60,13 @@ is_recoverable_error (const GError *erro
 	if (error->domain == GEDIT_DOCUMENT_ERROR)
 	{
 		switch (error->code) {
-		case GNOME_VFS_ERROR_ACCESS_DENIED:
-		case GNOME_VFS_ERROR_TOO_MANY_OPEN_FILES:
-		case GNOME_VFS_ERROR_NO_MEMORY:
-		case GNOME_VFS_ERROR_HOST_NOT_FOUND:
-		case GNOME_VFS_ERROR_HOST_HAS_NO_ADDRESS:
-		case GNOME_VFS_ERROR_LOGIN_FAILED:
-		case GNOME_VFS_ERROR_TIMEOUT:
-
+		case G_IO_ERROR_PERMISSION_DENIED:
+		case G_IO_ERROR_NOT_FOUND:
+		case G_IO_ERROR_HOST_NOT_FOUND:
+		case G_IO_ERROR_TIMED_OUT:
+		case G_IO_ERROR_NOT_MOUNTABLE_FILE:
+		case G_IO_ERROR_NOT_MOUNTED:
+		case G_IO_ERROR_BUSY:
 			is_recoverable = TRUE;
 		}
 	}
@@ -149,151 +148,106 @@ create_io_loading_error_message_area (co
 	return message_area;
 }
 
-GtkWidget *
-gedit_io_loading_error_message_area_new (const gchar  *uri,
-					 const GError *error)
+static void
+parse_error (const GError *error, 
+	     gchar       **error_message, 
+	     gchar       **message_details, 
+	     const gchar  *uri, 
+	     const gchar  *uri_for_display)
 {
-	gchar *error_message = NULL;
-	gchar *message_details = NULL;
-	gchar *full_formatted_uri;
-	gchar *scheme_string;
-	gchar *scheme_markup;
-       	gchar *uri_for_display;
-       	gchar *temp_uri_for_display;
-	GtkWidget *message_area;
-
-	g_return_val_if_fail (uri != NULL, NULL);
-	g_return_val_if_fail (error != NULL, NULL);
-	g_return_val_if_fail (error->domain == GEDIT_DOCUMENT_ERROR, NULL);
-
-	full_formatted_uri = gedit_utils_uri_for_display (uri);
-
-	/* Truncate the URI so it doesn't get insanely wide. Note that even
-	 * though the dialog uses wrapped text, if the URI doesn't contain
-	 * white space then the text-wrapping code is too stupid to wrap it.
-	 */
-	temp_uri_for_display = gedit_utils_str_middle_truncate (full_formatted_uri, 
-								MAX_URI_IN_DIALOG_LENGTH);								
-	g_free (full_formatted_uri);
-
-	uri_for_display = g_markup_printf_escaped ("<i>%s</i>", temp_uri_for_display);
-	g_free (temp_uri_for_display);
-
 	switch (error->code)
 	{
-	case GNOME_VFS_ERROR_NOT_FOUND:
-		error_message = g_strdup_printf (_("Could not find the file %s."),
-						 uri_for_display);
-		message_details = g_strdup (_("Please check that you typed the "
-				      	      "location correctly and try again."));
-	break;
-
-	case GNOME_VFS_ERROR_CORRUPTED_DATA:
-		message_details = g_strdup (_("The file contains corrupted data."));
+	case G_IO_ERROR_NOT_FOUND:
+		*error_message = g_strdup_printf (_("Could not find the file %s."),
+						  uri_for_display);
+		*message_details = g_strdup (_("Please check that you typed the "
+				      	       "location correctly and try again."));
 		break;
+	case G_IO_ERROR_NOT_SUPPORTED:
+		{
+			gchar *scheme_string;
+			gchar *scheme_markup;
+			
+			scheme_string = g_uri_parse_scheme (uri);
 
-	case GNOME_VFS_ERROR_NOT_SUPPORTED:
-		scheme_string = gnome_vfs_get_uri_scheme (uri);
+			if ((scheme_string != NULL) && g_utf8_validate (scheme_string, -1, NULL))
+			{
+	  			scheme_markup = g_markup_printf_escaped ("<i>%s:</i>", scheme_string);
 
-		if ((scheme_string != NULL) && g_utf8_validate (scheme_string, -1, NULL))
-		{
-  			scheme_markup = g_markup_printf_escaped ("<i>%s:</i>", scheme_string);
+				/* Translators: %s is a URI scheme (like for example http:, ftp:, etc.) */
+				*message_details = g_strdup_printf (_("gedit cannot handle %s locations."),
+								   scheme_markup);
+				g_free (scheme_markup);
+			}
+			else
+			{
+				*message_details = g_strdup (_("gedit cannot handle this location."));
+			}	
 
-			/* Translators: %s is a URI scheme (like for example http:, ftp:, etc.) */
-			message_details = g_strdup_printf (_("gedit cannot handle %s locations."),
-							   scheme_markup);
-			g_free (scheme_markup);
-		}
-		else
-		{
-			message_details = g_strdup (_("gedit cannot handle this location."));
+			g_free (scheme_string);
 		}
-
-		g_free (scheme_string);
 		break;
 
-	case GNOME_VFS_ERROR_WRONG_FORMAT:
-		message_details = g_strdup (_("The file contains data in an invalid format."));
+	case GEDIT_DOCUMENT_ERROR_TOO_BIG:
+		*message_details = g_strdup (_("The file is too big."));
 		break;
 
-	case GNOME_VFS_ERROR_TOO_BIG:
-		message_details = g_strdup (_("The file is too big."));
+	case G_IO_ERROR_NOT_MOUNTABLE_FILE:
+		*message_details = g_strdup (_("The location of the file cannot be mounted."));
 		break;
+	
+	case G_IO_ERROR_NOT_MOUNTED:
+		*message_details = g_strdup( _("The location of the file cannot be accessed because it is not mounted."));
 
-	case GNOME_VFS_ERROR_INVALID_URI:
-		error_message = g_strdup_printf (_("%s is not a valid location."),
+		break;	
+	case G_IO_ERROR_IS_DIRECTORY:
+		*error_message = g_strdup_printf (_("%s is a directory."),
 						 uri_for_display);
-		message_details = g_strdup (_("Please check that you typed the "
+		*message_details = g_strdup (_("Please check that you typed the "
 					      "location correctly and try again."));
 		break;
-
-	case GNOME_VFS_ERROR_ACCESS_DENIED:
-		message_details = g_strdup (_("You do not have the permissions necessary to open the file."));
-		break;
-
-	case GNOME_VFS_ERROR_TOO_MANY_OPEN_FILES:
-		message_details = g_strdup (_("There are too many open files. Please "
-					      "close some applications and try again."));
-		break;
-
-	case GNOME_VFS_ERROR_IS_DIRECTORY:
-		error_message = g_strdup_printf (_("%s is a directory."),
+		
+	case G_IO_ERROR_INVALID_FILENAME:
+		*error_message = g_strdup_printf (_("%s is not a valid location."),
 						 uri_for_display);
-		message_details = g_strdup (_("Please check that you typed the "
+		*message_details = g_strdup (_("Please check that you typed the "
 					      "location correctly and try again."));
 		break;
-
-	case GNOME_VFS_ERROR_NO_MEMORY:
-		message_details = g_strdup (_("Not enough available memory to open "
-					      "the file. Please close some running "
-					      "applications and try again."));
-		break;
-
-	case GNOME_VFS_ERROR_HOST_NOT_FOUND:
+		
+	case G_IO_ERROR_HOST_NOT_FOUND:
 		/* This case can be hit for user-typed strings like "foo" due to
 		 * the code that guesses web addresses when there's no initial "/".
 		 * But this case is also hit for legitimate web addresses when
 		 * the proxy is set up wrong.
 		 */
 		{
-			GnomeVFSURI *vfs_uri;
-
-			vfs_uri = gnome_vfs_uri_new (uri);
+			gchar *hn = NULL;
 
-			if (vfs_uri != NULL)
+			if (gedit_utils_decode_uri (uri, NULL, NULL, &hn, NULL, NULL))
 			{
-				const gchar *hn = gnome_vfs_uri_get_host_name (vfs_uri);
-
 				if (hn != NULL)
 				{
 					gchar *host_name = gedit_utils_make_valid_utf8 (hn);
+					g_free (hn);
+
 					gchar *host_markup = g_markup_printf_escaped ("<i>%s</i>", host_name);
 					g_free (host_name);
 
 					/* Translators: %s is a host name */
-					message_details = g_strdup_printf (
+					*message_details = g_strdup_printf (
 						_("Host %s could not be found. "
-	        		  	  	  "Please check that your proxy settings "
-				  	  	  "are correct and try again."),
+	        		  	  	"Please check that your proxy settings "
+				  	  	"are correct and try again."),
 					  	host_markup);
 
 					g_free (host_markup);
 				}
-				else
-				{
-					/* use the same string as INVALID_HOST */
-					message_details = g_strdup_printf (
-						_("Host name was invalid. "
-						  "Please check that you typed the location "
-						  "correctly and try again."));
-				}
-
-				gnome_vfs_uri_unref (vfs_uri);		
 			}
-			else
+			
+			if (!*message_details)
 			{
 				/* use the same string as INVALID_HOST */
-				message_details = g_strdup_printf (
+				*message_details = g_strdup_printf (
 					_("Host name was invalid. "
 					  "Please check that you typed the location "
 					  "correctly and try again."));
@@ -301,80 +255,67 @@ gedit_io_loading_error_message_area_new 
 		}
 		break;
 
-	case GNOME_VFS_ERROR_INVALID_HOST_NAME:
-		message_details = g_strdup_printf (_("Host name was invalid. "
-						     "Please check that you typed the location "
-						     "correctly and try again."));
-        		break;
-
-	case GNOME_VFS_ERROR_HOST_HAS_NO_ADDRESS:
-		message_details = g_strdup (_("Host name was empty. "
-					      "Please check that your proxy settings "
-					      "are correct and try again."));
+	case G_IO_ERROR_NOT_REGULAR_FILE:
+		*message_details = g_strdup_printf (_("%s is not a regular file."),
+						   uri_for_display);
 		break;
 
-	case GNOME_VFS_ERROR_LOGIN_FAILED:
-		message_details = g_strdup (_("Attempt to log in failed. "
-					      "Please check that you typed the location "
-					      "correctly and try again."));
+	case G_IO_ERROR_TIMED_OUT:
+		*message_details = g_strdup (_("Connection timed out. Please try again."));
 		break;
-
-	case GEDIT_DOCUMENT_ERROR_NOT_REGULAR_FILE:
-		message_details = g_strdup (_("The file you are trying to open is not a regular file."));
+	
+	case G_IO_ERROR_FAILED:
 		break;
-
-	case GNOME_VFS_ERROR_TIMEOUT:
-		message_details = g_strdup (_("Connection timed out. Please try again."));
+	
+	default:
+		g_warning ("Hit unhandled case %d (%s) in %s.", 
+			   error->code, error->message, G_STRFUNC);	
+		*message_details = g_strdup_printf (_("Unexpected error: %s"), 
+						   error->message);
 		break;
+	}
+}
+
+GtkWidget *
+gedit_io_loading_error_message_area_new (const gchar  *uri,
+					 const GError *error)
+{
+	gchar *error_message = NULL;
+	gchar *message_details = NULL;
+	gchar *full_formatted_uri;
+       	gchar *uri_for_display;
+       	gchar *temp_uri_for_display;
+	GtkWidget *message_area;
 
-	case GNOME_VFS_ERROR_IO:
-		/* FIXME: add a specific message when I are out
-		 * of string freeze
+	g_return_val_if_fail (uri != NULL, NULL);
+	g_return_val_if_fail (error != NULL, NULL);
+	g_return_val_if_fail (error->domain == GEDIT_DOCUMENT_ERROR, NULL);
 
-		message_details = g_strdup ();
+	full_formatted_uri = gedit_utils_uri_for_display (uri);
 
-		*/
+	/* Truncate the URI so it doesn't get insanely wide. Note that even
+	 * though the dialog uses wrapped text, if the URI doesn't contain
+	 * white space then the text-wrapping code is too stupid to wrap it.
+	 */
+	temp_uri_for_display = gedit_utils_str_middle_truncate (full_formatted_uri, 
+								MAX_URI_IN_DIALOG_LENGTH);								
+	g_free (full_formatted_uri);
 
-		break;
+	uri_for_display = g_markup_printf_escaped ("<i>%s</i>", temp_uri_for_display);
+	g_free (temp_uri_for_display);
 
-	case GNOME_VFS_ERROR_GENERIC:
+	switch (error->code)
+	{
+	case G_IO_ERROR_TOO_MANY_LINKS:
+		message_details = g_strdup (_("The number of followed links is limited and the actual file could not be found within this limit."));
 		break;
 
-	/*
-	case GNOME_VFS_ERROR_INTERNAL:
-	case GNOME_VFS_ERROR_BAD_PARAMETERS:
-	case GNOME_VFS_ERROR_IO:
-	case GNOME_VFS_ERROR_BAD_FILE:
-	case GNOME_VFS_ERROR_NO_SPACE:
-	case GNOME_VFS_ERROR_READ_ONLY:
-	case GNOME_VFS_ERROR_NOT_OPEN:
-	case GNOME_VFS_ERROR_INVALID_OPEN_MODE:
-	case GNOME_VFS_ERROR_EOF:
-	case GNOME_VFS_ERROR_NOT_A_DIRECTORY:
-	case GNOME_VFS_ERROR_IN_PROGRESS:
-	case GNOME_VFS_ERROR_INTERRUPTED:
-	case GNOME_VFS_ERROR_FILE_EXISTS:
-	case GNOME_VFS_ERROR_LOOP:
-	case GNOME_VFS_ERROR_NOT_PERMITTED:
-	case GNOME_VFS_ERROR_CANCELLED:
-	case GNOME_VFS_ERROR_DIRECTORY_BUSY:
-	case GNOME_VFS_ERROR_DIRECTORY_NOT_EMPTY:
-	case GNOME_VFS_ERROR_TOO_MANY_LINKS:
-	case GNOME_VFS_ERROR_READ_ONLY_FILE_SYSTEM:
-	case GNOME_VFS_ERROR_NOT_SAME_FILE_SYSTEM:
-	case GNOME_VFS_ERROR_NAME_TOO_LONG:
-	case GNOME_VFS_ERROR_SERVICE_NOT_AVAILABLE:
-	case GNOME_VFS_ERROR_SERVICE_OBSOLETE,
-	case GNOME_VFS_ERROR_PROTOCOL_ERROR,
-	case GNOME_VFS_NUM_ERRORS:
-	*/
+	case G_IO_ERROR_PERMISSION_DENIED:
+		message_details = g_strdup (_("You do not have the permissions necessary to open the file."));
+		break;		
 
 	default:
-		/* We should invent decent error messages for every case we actually experience. */
-		g_warning ("Hit unhandled case %d (%s) in %s.", 
-			   error->code, gnome_vfs_result_to_string (error->code), G_STRFUNC);	
-		message_details = g_strdup_printf (_("Unexpected error: %s"), 
-						   gnome_vfs_result_to_string (error->code));								 
+		parse_error (error, &error_message, &message_details, uri, uri_for_display);
 		break;
 	}
 
@@ -407,8 +348,6 @@ gedit_unrecoverable_reverting_error_mess
 	gchar *error_message = NULL;
 	gchar *message_details = NULL;
 	gchar *full_formatted_uri;
-	gchar *scheme_string;
-	gchar *scheme_markup;
        	gchar *uri_for_display;
        	gchar *temp_uri_for_display;
 	GtkWidget *message_area;
@@ -432,183 +371,13 @@ gedit_unrecoverable_reverting_error_mess
 
 	switch (error->code)
 	{
-	case GNOME_VFS_ERROR_NOT_FOUND:
-		message_details = g_strdup (_("gedit cannot find it. "
+	case G_IO_ERROR_NOT_FOUND:
+		message_details = g_strdup (_("gedit cannot find the file. "
 					      "Perhaps it has recently been deleted."));
 		break;
 
-	case GNOME_VFS_ERROR_CORRUPTED_DATA:
-		message_details = g_strdup (_("The file contains corrupted data."));
-		break;
-
-	case GNOME_VFS_ERROR_NOT_SUPPORTED:
-		scheme_string = gnome_vfs_get_uri_scheme (uri);
-
-		if ((scheme_string != NULL) && g_utf8_validate (scheme_string, -1, NULL))
-		{
-  			scheme_markup = g_markup_printf_escaped ("<i>%s:</i>", scheme_string);
-
-			/* Translators: %s is a URI scheme (like for example http:, ftp:, etc.) */
-			message_details = g_strdup_printf (_("gedit cannot handle %s locations."),
-							   scheme_markup);
-			g_free (scheme_markup);
-		}
-		else
-		{
-			message_details = g_strdup (_("gedit cannot handle this location."));
-		}	
-
-		g_free (scheme_string);
-       	        break;
-
-	case GNOME_VFS_ERROR_WRONG_FORMAT:
-		message_details = g_strdup (_("The file contains data in an invalid format."));
-		break;
-
-	case GNOME_VFS_ERROR_TOO_BIG:
-		message_details = g_strdup (_("The file is too big."));
-		break;
-
-	case GNOME_VFS_ERROR_ACCESS_DENIED:
-		message_details = g_strdup (_("You do not have the permissions necessary to open the file."));
-		break;
-
-	case GNOME_VFS_ERROR_TOO_MANY_OPEN_FILES:
-		message_details = g_strdup (_("There are too many open files. Please "
-					      "close some applications and try again."));
-		break;
-
-	case GNOME_VFS_ERROR_IS_DIRECTORY:
-		message_details = g_strdup_printf (_("%s is a directory."),
-						   uri_for_display);
-		break;
-
-	case GNOME_VFS_ERROR_NO_MEMORY:
-		message_details = g_strdup (_("Not enough available memory to open "
-					      "the file. Please close some running "
-					      "applications and try again."));
-		break;
-
-	case GNOME_VFS_ERROR_HOST_NOT_FOUND:
-		/* This case can be hit for user-typed strings like "foo" due to
-		 * the code that guesses web addresses when there's no initial "/".
-		 * But this case is also hit for legitimate web addresses when
-		 * the proxy is set up wrong.
-		 */
-		{
-			GnomeVFSURI *vfs_uri;
-
-			vfs_uri = gnome_vfs_uri_new (uri);
-
-			if (vfs_uri != NULL)
-			{
-				const gchar *hn = gnome_vfs_uri_get_host_name (vfs_uri);
-
-				if (hn != NULL)
-				{
-					gchar *host_name = gedit_utils_make_valid_utf8 (hn);
-					gchar *host_markup = g_markup_printf_escaped ("<i>%s</i>", host_name);
-					g_free (host_name);
-
-					/* Translators: %s is a host name */
-					message_details = g_strdup_printf (
-						_("Host %s could not be found. "
-	        		  	  	"Please check that your proxy settings "
-				  	  	"are correct and try again."),
-					  	host_markup);
-
-					g_free (host_markup);
-				}
-				else
-				{
-					/* use the same string as INVALID_HOST */
-					message_details = g_strdup_printf (
-						_("Host name was invalid. "
-						  "Please check that you typed the location "
-						  "correctly and try again."));
-				}
-
-				gnome_vfs_uri_unref (vfs_uri);		
-			}
-			else
-			{
-				/* use the same string as INVALID_HOST */
-				message_details = g_strdup_printf (
-					_("Host name was invalid. "
-					  "Please check that you typed the location "
-					  "correctly and try again."));
-			}
-		}
-		break;
-
-	case GNOME_VFS_ERROR_HOST_HAS_NO_ADDRESS:
-		message_details = g_strdup (_("Host name was empty. "
-					      "Please check that your proxy settings "
-					      "are correct and try again."));
-		break;
-
-	case GNOME_VFS_ERROR_LOGIN_FAILED:
-		message_details = g_strdup (_("Attempt to log in failed."));
-		break;
-
-	case GEDIT_DOCUMENT_ERROR_NOT_REGULAR_FILE:
-		message_details = g_strdup_printf (_("%s is not a regular file."),
-						   uri_for_display);
-		break;
-
-	case GNOME_VFS_ERROR_TIMEOUT:
-		message_details = g_strdup (_("Connection timed out. Please try again."));
-		break;
-
-	/* this should never happen, revert should be insensitive */
-//CHECK: we used to have this before new_mdi... is it really useful (see comment above)
-/*
-	case GEDIT_ERROR_UNTITLED:
-		message_details = g_strdup (_("It is not possible to revert an Untitled document."));
-		break;
-*/
-
-	case GNOME_VFS_ERROR_GENERIC:
-		break;
-
-	/*
-	case GNOME_VFS_ERROR_INVALID_URI:
-	case GNOME_VFS_ERROR_INVALID_HOST_NAME:
-	case GNOME_VFS_ERROR_GENERIC:
-	case GNOME_VFS_ERROR_INTERNAL:
-	case GNOME_VFS_ERROR_BAD_PARAMETERS:
-	case GNOME_VFS_ERROR_IO:
-	case GNOME_VFS_ERROR_BAD_FILE:
-	case GNOME_VFS_ERROR_NO_SPACE:
-	case GNOME_VFS_ERROR_READ_ONLY:
-	case GNOME_VFS_ERROR_NOT_OPEN:
-	case GNOME_VFS_ERROR_INVALID_OPEN_MODE:
-	case GNOME_VFS_ERROR_EOF:
-	case GNOME_VFS_ERROR_NOT_A_DIRECTORY:
-	case GNOME_VFS_ERROR_IN_PROGRESS:
-	case GNOME_VFS_ERROR_INTERRUPTED:
-	case GNOME_VFS_ERROR_FILE_EXISTS:
-	case GNOME_VFS_ERROR_LOOP:
-	case GNOME_VFS_ERROR_NOT_PERMITTED:
-	case GNOME_VFS_ERROR_CANCELLED:
-	case GNOME_VFS_ERROR_DIRECTORY_BUSY:
-	case GNOME_VFS_ERROR_DIRECTORY_NOT_EMPTY:
-	case GNOME_VFS_ERROR_TOO_MANY_LINKS:
-	case GNOME_VFS_ERROR_READ_ONLY_FILE_SYSTEM:
-	case GNOME_VFS_ERROR_NOT_SAME_FILE_SYSTEM:
-	case GNOME_VFS_ERROR_NAME_TOO_LONG:
-	case GNOME_VFS_ERROR_SERVICE_NOT_AVAILABLE:
-	case GNOME_VFS_ERROR_SERVICE_OBSOLETE,
-	case GNOME_VFS_ERROR_PROTOCOL_ERROR,
-	case GNOME_VFS_NUM_ERRORS:
-	case GNOME_VFS_ERROR_IS_DIRECTORY:
-	*/
-	
-	default: 
-		g_warning ("Hit unhandled case %d (%s) in %s.", 
-			   error->code, gnome_vfs_result_to_string (error->code), G_STRFUNC);	
-		message_details = g_strdup_printf (_("Unexpected error: %s"), 
-						   gnome_vfs_result_to_string (error->code));								 
+	default:
+		parse_error (error, &error_message, &message_details, uri, uri_for_display);
 		break;
 	}
 
@@ -1181,8 +950,8 @@ gedit_unrecoverable_saving_error_message
 
 	switch (error->code)
 	{
-		case GNOME_VFS_ERROR_NOT_SUPPORTED:
-			scheme_string = gnome_vfs_get_uri_scheme (uri);
+		case G_IO_ERROR_NOT_SUPPORTED:
+			scheme_string = g_uri_parse_scheme (uri);
 
 			if ((scheme_string != NULL) && g_utf8_validate (scheme_string, -1, NULL))
 			{
@@ -1205,180 +974,54 @@ gedit_unrecoverable_saving_error_message
 			g_free (scheme_string);
 			break;
 
-		case GNOME_VFS_ERROR_TOO_BIG:
+		case GEDIT_DOCUMENT_ERROR_TOO_BIG:
 			message_details = g_strdup (_("The disk where you are trying to save the file has "
 						      "a limitation on file sizes.  Please try saving "
 						      "a smaller file or saving it to a disk that does not "
 						      "have this limitation."));
 			break;
 
-		case GNOME_VFS_ERROR_INVALID_URI:
+		case G_IO_ERROR_INVALID_FILENAME:
 			message_details = g_strdup (_("%s is not a valid location. " 
 						      "Please check that you typed the "
 						      "location correctly and try again."));
 			break;
 
-		case GNOME_VFS_ERROR_ACCESS_DENIED:
-		case GNOME_VFS_ERROR_NOT_PERMITTED:		
+		case G_IO_ERROR_PERMISSION_DENIED:
 			message_details = g_strdup (_("You do not have the permissions necessary to save the file. "
 						      "Please check that you typed the "
 						      "location correctly and try again."));
 
 			break;
 
-		case GNOME_VFS_ERROR_TOO_MANY_OPEN_FILES:
-			message_details = g_strdup (_("There are too many open files. Please "
-						      "close some applications and try again."));
-			break;
-
-		case GNOME_VFS_ERROR_IS_DIRECTORY:
-			message_details = g_strdup (_("%s is a directory. "
-						      "Please check that you typed the "
-						      "location correctly and try again."));
-			break;
-
-		case GNOME_VFS_ERROR_NO_MEMORY:
-			message_details = g_strdup (_("Not enough available memory to save "
-						      "the file. Please close some running "
-						      "applications and try again."));
-			break;
-
-		case GNOME_VFS_ERROR_HOST_NOT_FOUND:
-			/* This case can be hit for user-typed strings like "foo" due to
-			 * the code that guesses web addresses when there's no initial "/".
-			 * But this case is also hit for legitimate web addresses when
-			 * the proxy is set up wrong.
-			 */
-			{
-				GnomeVFSURI *vfs_uri;
-
-				vfs_uri = gnome_vfs_uri_new (uri);
-
-				if (vfs_uri != NULL)
-				{
-					const gchar *hn = gnome_vfs_uri_get_host_name (vfs_uri);
-
-					if (hn != NULL)
-					{
-						gchar *host_name = gedit_utils_make_valid_utf8 (hn);
-						gchar *host_markup = g_markup_printf_escaped ("<i>%s</i>", host_name);
-						g_free (host_name);		
-
-						/* Translators: %s is a host name */
-						message_details = g_strdup_printf (
-							_("Host %s could not be found. "
-		        		  	  	  "Please check that your proxy settings "
-					  	  	  "are correct and try again."),
-						  	host_markup);
-
-						g_free (host_markup);
-					}
-					else
-					{
-						/* use the same string as INVALID_HOST */
-						message_details = g_strdup_printf (
-							_("Host name was invalid. "
-							  "Please check that you typed the location "
-							  "correctly and try again."));
-					}
-
-					gnome_vfs_uri_unref (vfs_uri);		
-				}
-				else
-				{
-					/* use the same string as INVALID_HOST */
-					message_details = g_strdup_printf (
-						_("Host name was invalid. "
-						  "Please check that you typed the location "
-						  "correctly and try again."));
-				}
-			}
-			break;
-
-		case GNOME_VFS_ERROR_INVALID_HOST_NAME:
-			message_details = g_strdup_printf (_("Host name was invalid. "
-							     "Please check that you typed the location "
-							     "correctly and try again."));
-				break;
-
-		case GNOME_VFS_ERROR_HOST_HAS_NO_ADDRESS:
-			message_details = g_strdup (_("Host name was empty. "
-						      "Please check that your proxy settings "
-						      "are correct and try again."));
-			break;
-
-		case GNOME_VFS_ERROR_LOGIN_FAILED:
-			message_details = g_strdup (_("Attempt to log in failed. "
-						      "Please check that you typed the location "
-						      "correctly and try again."));
-			break;
-
-		case GNOME_VFS_ERROR_NO_SPACE:
+		case G_IO_ERROR_NO_SPACE:
 			message_details = g_strdup (_("There is not enough disk space to save the file. "
 						      "Please free some disk space and try again."));
 			break;
 			
-		case GNOME_VFS_ERROR_READ_ONLY:
-		case GNOME_VFS_ERROR_READ_ONLY_FILE_SYSTEM:		
+		case G_IO_ERROR_READ_ONLY:	
 			message_details = g_strdup (_("You are trying to save the file on a read-only disk. "
 						      "Please check that you typed the location "
 						      "correctly and try again."));
 			break;
 			
-		case GNOME_VFS_ERROR_FILE_EXISTS:
+		case G_IO_ERROR_EXISTS:
 			message_details = g_strdup (_("A file with the same name already exists. "
 						      "Please use a different name."));
 			break;
 			
-		case GNOME_VFS_ERROR_NAME_TOO_LONG:
+		case G_IO_ERROR_FILENAME_TOO_LONG:
 			message_details = g_strdup (_("The disk where you are trying to save the file has "
 						      "a limitation on length of the file names. "
 						      "Please use a shorter name."));
-
-		case GNOME_VFS_ERROR_TIMEOUT:
-			message_details = g_strdup (_("Connection timed out. Please try again."));
-			break;
-
-		case GEDIT_DOCUMENT_ERROR_NOT_REGULAR_FILE:
-			message_details = g_strdup_printf (_("%s is not a regular file. "
-							     "Please check that you typed the location "
-							     "correctly and try again."),
-							   uri_for_display);
-
-		case GNOME_VFS_ERROR_GENERIC:
 			break;
 
-		/*
-		case GNOME_VFS_ERROR_NOT_FOUND:
-		case GNOME_VFS_ERROR_CORRUPTED_DATA:
-		case GNOME_VFS_ERROR_WRONG_FORMAT:
-		case GNOME_VFS_ERROR_INTERNAL:
-		case GNOME_VFS_ERROR_BAD_PARAMETERS:
-		case GNOME_VFS_ERROR_IO:
-		case GNOME_VFS_ERROR_BAD_FILE:
-		case GNOME_VFS_ERROR_NOT_OPEN:
-		case GNOME_VFS_ERROR_INVALID_OPEN_MODE:
-		case GNOME_VFS_ERROR_EOF:
-		case GNOME_VFS_ERROR_NOT_A_DIRECTORY:
-		case GNOME_VFS_ERROR_IN_PROGRESS:
-		case GNOME_VFS_ERROR_INTERRUPTED:
-		case GNOME_VFS_ERROR_LOOP:
-		case GNOME_VFS_ERROR_CANCELLED:
-		case GNOME_VFS_ERROR_DIRECTORY_BUSY:
-		case GNOME_VFS_ERROR_DIRECTORY_NOT_EMPTY:
-		case GNOME_VFS_ERROR_TOO_MANY_LINKS:
-		case GNOME_VFS_ERROR_NOT_SAME_FILE_SYSTEM:
-		case GNOME_VFS_ERROR_SERVICE_NOT_AVAILABLE:
-		case GNOME_VFS_ERROR_SERVICE_OBSOLETE,
-		case GNOME_VFS_ERROR_PROTOCOL_ERROR,
-		case GNOME_VFS_NUM_ERRORS:
-		*/
-
-		default: 
-			g_warning ("Hit unhandled case %d (%s) in %s.", 
-				   error->code, gnome_vfs_result_to_string (error->code), G_STRFUNC);	
-			message_details = g_strdup_printf (_("Unexpected error: %s"), 
-							   gnome_vfs_result_to_string (error->code));								 
+		default:
+			parse_error (error, 
+				     &error_message, 
+				     &message_details, 
+				     uri, 
+				     uri_for_display);
 			break;
 	}
 
Index: gedit/gedit-gio-document-loader.c
===================================================================
--- gedit/gedit-gio-document-loader.c	(revisione 0)
+++ gedit/gedit-gio-document-loader.c	(revisione 0)
@@ -0,0 +1,650 @@
+/*
+ * gedit-gio-document-loader.c
+ * This file is part of gedit
+ *
+ * Copyright (C) 2005 - Paolo Maggi
+ * Copyright (C) 2007 - Paolo Maggi, Steve Frécinaux
+ * Copyright (C) 2008 - Jesse van den Kieboom
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+ 
+/*
+ * Modified by the gedit Team, 2005-2008. See the AUTHORS file for a
+ * list of people on the gedit Team.
+ * See the ChangeLog files for a list of changes.
+ *
+ * $Id$
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <glib/gi18n.h>
+#include <glib/gstdio.h>
+#include <gio/gio.h>
+
+#include "gedit-gio-document-loader.h"
+#include "gedit-debug.h"
+#include "gedit-metadata-manager.h"
+#include "gedit-utils.h"
+
+typedef struct
+{
+	GeditGioDocumentLoader *loader;
+	GCancellable 	       *cancellable;
+	gboolean		tried_mount;
+} AsyncData;
+
+#define READ_CHUNK_SIZE 8192
+#define REMOTE_QUERY_ATTRIBUTES G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE "," \
+				G_FILE_ATTRIBUTE_STANDARD_TYPE "," \
+				G_FILE_ATTRIBUTE_TIME_MODIFIED "," \
+				G_FILE_ATTRIBUTE_STANDARD_SIZE "," \
+				G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE
+
+#define GEDIT_GIO_DOCUMENT_LOADER_GET_PRIVATE(object) \
+				(G_TYPE_INSTANCE_GET_PRIVATE ((object), \
+				 GEDIT_TYPE_GIO_DOCUMENT_LOADER,   \
+				 GeditGioDocumentLoaderPrivate))
+
+static void	    gedit_gio_document_loader_load		(GeditDocumentLoader *loader);
+static gboolean     gedit_gio_document_loader_cancel		(GeditDocumentLoader *loader);
+static const gchar *gedit_gio_document_loader_get_mime_type	(GeditDocumentLoader *loader);
+static time_t	    gedit_gio_document_loader_get_mtime		(GeditDocumentLoader *loader);
+static goffset	    gedit_gio_document_loader_get_file_size	(GeditDocumentLoader *loader);
+static goffset	    gedit_gio_document_loader_get_bytes_read	(GeditDocumentLoader *loader);
+static gboolean	    gedit_gio_document_loader_get_readonly	(GeditDocumentLoader *loader);
+
+static void open_async_read (AsyncData *async);
+
+struct _GeditGioDocumentLoaderPrivate
+{
+	/* Info on the current file */
+	GFile            *gfile;
+
+	GFileInfo        *info;
+	goffset           bytes_read;
+
+	/* Handle for remote files */
+	GCancellable 	 *cancellable;
+	GFileInputStream *stream;
+
+	gchar            *buffer;
+
+	GError           *error;
+};
+
+G_DEFINE_TYPE(GeditGioDocumentLoader, gedit_gio_document_loader, GEDIT_TYPE_DOCUMENT_LOADER)
+
+static void
+gedit_gio_document_loader_finalize (GObject *object)
+{
+	GeditGioDocumentLoaderPrivate *priv;
+
+	priv = GEDIT_GIO_DOCUMENT_LOADER (object)->priv;
+
+	if (priv->cancellable != NULL)
+	{
+		g_cancellable_cancel (priv->cancellable);
+		g_object_unref (priv->cancellable);
+	}
+
+	if (priv->info)
+		g_object_unref (priv->info);
+	
+	if (priv->stream)
+		g_object_unref (priv->stream);
+
+	g_free (priv->buffer);
+
+	if (priv->gfile)
+		g_object_unref (priv->gfile);
+
+	if (priv->error)
+		g_error_free (priv->error);
+
+	G_OBJECT_CLASS (gedit_gio_document_loader_parent_class)->finalize (object);
+}
+
+static void
+gedit_gio_document_loader_class_init (GeditGioDocumentLoaderClass *klass)
+{
+	GObjectClass *object_class = G_OBJECT_CLASS (klass);
+	GeditDocumentLoaderClass *loader_class = GEDIT_DOCUMENT_LOADER_CLASS (klass);
+
+	object_class->finalize = gedit_gio_document_loader_finalize;
+
+	loader_class->load = gedit_gio_document_loader_load;
+	loader_class->cancel = gedit_gio_document_loader_cancel;
+	loader_class->get_mime_type = gedit_gio_document_loader_get_mime_type;
+	loader_class->get_mtime = gedit_gio_document_loader_get_mtime;
+	loader_class->get_file_size = gedit_gio_document_loader_get_file_size;
+	loader_class->get_bytes_read = gedit_gio_document_loader_get_bytes_read;
+	loader_class->get_readonly = gedit_gio_document_loader_get_readonly;
+
+	g_type_class_add_private (object_class, sizeof(GeditGioDocumentLoaderPrivate));
+}
+
+static void
+gedit_gio_document_loader_init (GeditGioDocumentLoader *gvloader)
+{
+	gvloader->priv = GEDIT_GIO_DOCUMENT_LOADER_GET_PRIVATE (gvloader);
+	gvloader->priv->error = NULL;
+}
+
+static AsyncData *
+async_data_new (GeditGioDocumentLoader *gvloader)
+{
+	AsyncData *async;
+	
+	async = g_new (AsyncData, 1);
+	async->loader = gvloader;
+	async->cancellable = g_object_ref (gvloader->priv->cancellable);
+	async->tried_mount = FALSE;
+	
+	return async;
+}
+
+static void
+async_data_free (AsyncData *async)
+{
+	g_object_unref (async->cancellable);
+	g_free (async);
+}
+
+static void
+remote_load_completed_or_failed (GeditGioDocumentLoader *gvloader, AsyncData *async)
+{
+	/* free the buffer */
+	g_free (gvloader->priv->buffer);
+	gvloader->priv->buffer = NULL;
+
+	if (async)
+		async_data_free (async);
+		
+	if (gvloader->priv->stream)
+		g_input_stream_close_async (G_INPUT_STREAM (gvloader->priv->stream), G_PRIORITY_HIGH, NULL, NULL, NULL);
+
+	gedit_document_loader_loading (GEDIT_DOCUMENT_LOADER (gvloader),
+				       TRUE,
+				       gvloader->priv->error);
+}
+
+/* prototype, because they call each other... isn't C lovely */
+static void	read_file_chunk		(AsyncData *async);
+
+static void
+async_read_cb (GInputStream *stream,
+	       GAsyncResult *res,
+	       AsyncData    *async)
+{
+	gedit_debug (DEBUG_LOADER);
+	GError *error = NULL;
+	GeditGioDocumentLoader *gvloader;
+	gssize bytes_read;
+	
+	/* manually check cancelled state */
+	if (g_cancellable_is_cancelled (async->cancellable))
+	{
+		g_input_stream_close_async (stream, G_PRIORITY_HIGH, NULL, NULL, NULL);
+		async_data_free (async);
+		return;
+	}
+
+	gvloader = async->loader;
+	bytes_read = g_input_stream_read_finish (stream, res, &error);
+	
+	/* error occurred */
+	if (bytes_read == -1)
+	{
+		g_set_error (&gvloader->priv->error,
+			     GEDIT_DOCUMENT_ERROR,
+			     error->code,
+			     error->message);
+
+		remote_load_completed_or_failed (gvloader, async);
+
+		return;
+	}
+
+	/* Check for the extremely unlikely case where the file size overflows. */
+	if (gvloader->priv->bytes_read + bytes_read < gvloader->priv->bytes_read)
+	{
+		g_set_error (&gvloader->priv->error,
+			     GEDIT_DOCUMENT_ERROR,
+			     GEDIT_DOCUMENT_ERROR_TOO_BIG,
+			     _("File too big"));
+
+		remote_load_completed_or_failed (gvloader, async);
+
+		return;
+	}
+
+	/* Bump the size. */
+	gvloader->priv->bytes_read += bytes_read;
+
+	/* end of the file, we are done! */
+	if (bytes_read == 0)
+	{
+		gedit_document_loader_update_document_contents (
+						GEDIT_DOCUMENT_LOADER (gvloader),
+						gvloader->priv->buffer,
+						gvloader->priv->bytes_read,
+						&gvloader->priv->error);
+		
+		remote_load_completed_or_failed (gvloader, async);
+
+		return;
+	}
+
+	/* otherwise emit progress and read some more */
+
+	/* note that this signal blocks the read... check if it isn't
+	 * a performance problem
+	 */
+	gedit_document_loader_loading (GEDIT_DOCUMENT_LOADER (gvloader),
+				       FALSE,
+				       NULL);
+
+	read_file_chunk (async);
+}
+
+static void
+read_file_chunk (AsyncData *async)
+{
+	GeditGioDocumentLoader *gvloader;
+	
+	gvloader = async->loader;
+	gvloader->priv->buffer = g_realloc (gvloader->priv->buffer,
+					    gvloader->priv->bytes_read + READ_CHUNK_SIZE);
+
+	g_input_stream_read_async (G_INPUT_STREAM (gvloader->priv->stream),
+				   gvloader->priv->buffer + gvloader->priv->bytes_read,
+				   READ_CHUNK_SIZE,
+				   G_PRIORITY_HIGH,
+				   async->cancellable,
+				   (GAsyncReadyCallback) async_read_cb,
+				   async);
+}
+
+static void
+finish_query_info (AsyncData *async)
+{
+	GeditGioDocumentLoader *gvloader;
+	
+	gvloader = async->loader;
+
+	/* if it's not a regular file, error out... */
+	if (g_file_info_has_attribute (gvloader->priv->info, G_FILE_ATTRIBUTE_STANDARD_TYPE) &&
+	    g_file_info_get_file_type (gvloader->priv->info) != G_FILE_TYPE_REGULAR)
+	{
+		g_set_error (&gvloader->priv->error,
+			     GEDIT_DOCUMENT_ERROR,
+			     G_IO_ERROR_NOT_REGULAR_FILE,
+			     _("Not a regular file"));
+
+		remote_load_completed_or_failed (gvloader, async);
+
+		return;
+	}
+
+	/* start reading */
+	read_file_chunk (async);
+}
+
+static void
+remote_get_file_info_cb (GFile        *source,
+			 GAsyncResult *res,
+			 AsyncData    *async)
+{
+	GeditGioDocumentLoader *gvloader;
+	GError *error = NULL;
+	
+	gedit_debug (DEBUG_LOADER);
+	
+	/* manually check the cancelled state */
+	if (g_cancellable_is_cancelled (async->cancellable))
+	{
+		async_data_free (async);
+		return;
+	}
+
+	gvloader = async->loader;
+	
+	/* finish the info query */
+	gvloader->priv->info = g_file_query_info_finish (gvloader->priv->gfile,
+	                                                 res, 
+	                                                 &error);
+
+	if (!gvloader->priv->info)
+	{
+		/* propagate the error and clean up */
+		g_set_error (&gvloader->priv->error,
+			     GEDIT_DOCUMENT_ERROR,
+			     error->code,
+			     error->message);
+		
+		g_error_free (error);
+
+		remote_load_completed_or_failed (gvloader, async);
+
+		return;
+	}
+
+	finish_query_info (async);
+}
+
+static void
+remote_get_info_cb (GFileInputStream *source,
+		    GAsyncResult     *res,
+		    AsyncData        *async)
+{
+	GeditGioDocumentLoader *gvloader;
+	GError *error = NULL;
+	
+	gedit_debug (DEBUG_LOADER);
+
+	/* manually check the cancelled state */
+	if (g_cancellable_is_cancelled (async->cancellable))
+	{
+		async_data_free (async);
+		return;
+	}	
+
+	gvloader = async->loader;
+	
+	/* finish the info query */
+	gvloader->priv->info = g_file_input_stream_query_info_finish (gvloader->priv->stream,
+	                                                              res, 
+	                                                              &error);
+
+	if (!gvloader->priv->info)
+	{
+		if (error->code == G_IO_ERROR_NOT_SUPPORTED)
+		{
+			gedit_debug_message (DEBUG_LOADER,
+					     "input_stream_query_info not supported, "
+					     "fall back to file_query_info");
+
+			/* then try to query the info using g_file_query_info */
+			g_file_query_info_async (gvloader->priv->gfile,
+						 REMOTE_QUERY_ATTRIBUTES,
+						 G_FILE_QUERY_INFO_NONE,
+						 G_PRIORITY_HIGH,
+						 async->cancellable,
+						 (GAsyncReadyCallback)remote_get_file_info_cb,
+						 async);
+			return;
+		}
+		
+		/* propagate the error and clean up */
+		g_set_error (&gvloader->priv->error,
+			     GEDIT_DOCUMENT_ERROR,
+			     error->code,
+			     error->message);
+		
+		g_error_free (error);
+
+		remote_load_completed_or_failed (gvloader, async);
+
+		return;
+	}
+	
+	finish_query_info (async);
+}
+
+static void
+mount_ready_callback (GFile        *file,
+		      GAsyncResult *res,
+		      AsyncData    *async)
+{
+	GError *error = NULL;
+	gboolean mounted;
+	
+	/* manual check for cancelled state */
+	if (g_cancellable_is_cancelled (async->cancellable))
+	{
+		async_data_free (async);
+		return;
+	}
+
+	mounted = g_file_mount_enclosing_volume_finish (file, res, &error);
+	
+	if (!mounted)
+	{
+		g_set_error (&async->loader->priv->error,
+			     GEDIT_DOCUMENT_ERROR,
+			     error->code,
+			     error->message);
+
+		g_error_free (error);
+		remote_load_completed_or_failed (async->loader, async);
+	}
+	else
+	{
+		/* try again to open the file for reading */
+		open_async_read (async);
+	}
+}
+
+static void
+recover_not_mounted (AsyncData *async)
+{
+	GeditDocumentLoader *loader;
+	GMountOperation *mount_operation;
+
+	gedit_debug (DEBUG_LOADER);
+
+	async->tried_mount = TRUE;
+	loader = GEDIT_DOCUMENT_LOADER (async->loader);
+	mount_operation = gedit_document_create_mount_operation (loader->document);
+	
+	g_file_mount_enclosing_volume (async->loader->priv->gfile,
+				       G_MOUNT_MOUNT_NONE,
+				       mount_operation,
+				       async->cancellable,
+				       (GAsyncReadyCallback) mount_ready_callback,
+				       async);
+
+	g_object_unref (mount_operation);
+}
+
+static void
+async_read_ready_callback (GObject      *source,
+			   GAsyncResult *res,
+		           AsyncData    *async)
+{
+	GError *error = NULL;
+	GeditGioDocumentLoader *gvloader;
+	
+	gedit_debug (DEBUG_LOADER);
+
+	/* manual check for cancelled state */
+	if (g_cancellable_is_cancelled (async->cancellable))
+	{
+		async_data_free (async);
+		return;
+	}
+	
+	gvloader = async->loader;
+	gvloader->priv->stream = g_file_read_finish (gvloader->priv->gfile, res, &error);
+
+	if (!gvloader->priv->stream)
+	{		
+		if (error->code == G_IO_ERROR_NOT_MOUNTED && !async->tried_mount)
+		{
+			recover_not_mounted (async);
+			g_error_free (error);
+			return;
+		}
+		
+		/* Propagate error using GEDIT_DOCUMENT_ERROR for the domain */
+		g_set_error (&gvloader->priv->error,
+			     GEDIT_DOCUMENT_ERROR,
+			     error->code,
+			     error->message);
+			     
+		gedit_document_loader_loading (GEDIT_DOCUMENT_LOADER (gvloader),
+					       TRUE,
+					       gvloader->priv->error);
+
+		g_error_free (error);
+		async_data_free (async);
+	}
+	else
+	{
+		/* get the file info from the input stream */
+		g_file_input_stream_query_info_async (gvloader->priv->stream,
+						      REMOTE_QUERY_ATTRIBUTES,
+						      G_PRIORITY_HIGH,
+						      gvloader->priv->cancellable,
+						      (GAsyncReadyCallback) remote_get_info_cb,
+						      async);
+	}
+}
+
+static void
+open_async_read (AsyncData *async)
+{
+	g_file_read_async (async->loader->priv->gfile, 
+	                   G_PRIORITY_HIGH,
+	                   async->cancellable,
+	                   (GAsyncReadyCallback) async_read_ready_callback,
+	                   async);
+}
+
+static void
+gedit_gio_document_loader_load (GeditDocumentLoader *loader)
+{
+	GeditGioDocumentLoader *gvloader = GEDIT_GIO_DOCUMENT_LOADER (loader);
+	AsyncData *async;
+	
+	gedit_debug (DEBUG_LOADER);
+
+	/* make sure no load operation is currently running */
+	g_return_if_fail (gvloader->priv->cancellable == NULL);
+
+	gvloader->priv->gfile = g_file_new_for_uri (loader->uri);
+
+	/* loading start */
+	gedit_document_loader_loading (GEDIT_DOCUMENT_LOADER (gvloader),
+				       FALSE,
+				       NULL);
+
+	gvloader->priv->cancellable = g_cancellable_new ();
+	async = async_data_new (gvloader);
+	
+	open_async_read (async);
+}
+
+static const gchar *
+gedit_gio_document_loader_get_mime_type (GeditDocumentLoader *loader)
+{
+	GeditGioDocumentLoader *gvloader = GEDIT_GIO_DOCUMENT_LOADER (loader);
+
+	if (gvloader->priv->info != NULL &&
+	    g_file_info_has_attribute (gvloader->priv->info,
+				       G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE))
+	{
+		/* CHECK: should we use g_content_type_get_mime_type here for 
+		   windows? with what does gsv work on windows? */
+		return g_file_info_get_content_type (gvloader->priv->info);
+	}
+
+	return NULL;
+}
+
+static time_t
+gedit_gio_document_loader_get_mtime (GeditDocumentLoader *loader)
+{
+	GeditGioDocumentLoader *gvloader = GEDIT_GIO_DOCUMENT_LOADER (loader);
+
+	if (gvloader->priv->info != NULL &&
+	    g_file_info_has_attribute (gvloader->priv->info,
+				       G_FILE_ATTRIBUTE_TIME_MODIFIED))
+	{
+		GTimeVal timeval;
+
+		g_file_info_get_modification_time (gvloader->priv->info, &timeval);
+
+		return timeval.tv_sec;
+	}
+
+	return 0;
+}
+
+/* Returns 0 if file size is unknown */
+static goffset
+gedit_gio_document_loader_get_file_size (GeditDocumentLoader *loader)
+{
+	GeditGioDocumentLoader *gvloader = GEDIT_GIO_DOCUMENT_LOADER (loader);
+
+	if (gvloader->priv->info != NULL &&
+	    g_file_info_has_attribute (gvloader->priv->info,
+				       G_FILE_ATTRIBUTE_STANDARD_SIZE))
+	{
+		return g_file_info_get_size (gvloader->priv->info);
+	}
+
+	return 0;
+}
+
+static goffset
+gedit_gio_document_loader_get_bytes_read (GeditDocumentLoader *loader)
+{
+	return GEDIT_GIO_DOCUMENT_LOADER (loader)->priv->bytes_read;
+}
+
+static gboolean
+gedit_gio_document_loader_cancel (GeditDocumentLoader *loader)
+{
+	GeditGioDocumentLoader *gvloader = GEDIT_GIO_DOCUMENT_LOADER (loader);
+
+	if (gvloader->priv->cancellable == NULL)
+		return FALSE;
+
+	g_cancellable_cancel (gvloader->priv->cancellable);
+
+	g_set_error (&gvloader->priv->error,
+		     GEDIT_DOCUMENT_ERROR,
+		     G_IO_ERROR_CANCELLED,
+		     "Operation cancelled");
+
+	remote_load_completed_or_failed (gvloader, NULL);
+
+	return TRUE;
+}
+
+/* In the case the loader does not know if the file is readonly, for example 
+   for most remote files, the function returns FALSE, so that we can try writing
+   and if needed handle the error. */
+static gboolean
+gedit_gio_document_loader_get_readonly (GeditDocumentLoader *loader)
+{
+	GeditGioDocumentLoader *gvloader = GEDIT_GIO_DOCUMENT_LOADER (loader);
+
+	if (gvloader->priv->info != NULL &&
+	    g_file_info_has_attribute (gvloader->priv->info,
+				       G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE))
+	{
+		return !g_file_info_get_attribute_boolean (gvloader->priv->info,
+							   G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE);
+	}
+
+	return FALSE;
+}
Index: gedit/gedit-gio-document-loader.h
===================================================================
--- gedit/gedit-gio-document-loader.h	(revisione 0)
+++ gedit/gedit-gio-document-loader.h	(revisione 0)
@@ -0,0 +1,79 @@
+/*
+ * gedit-gio-document-loader.h
+ * This file is part of gedit
+ *
+ * Copyright (C) 2005 - Paolo Maggi
+ * Copyright (C) 2007 - Paolo Maggi, Steve Frécinaux
+ * Copyright (C) 2008 - Jesse van den Kieboom
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, 
+ * Boston, MA 02111-1307, USA.
+ */
+ 
+/*
+ * Modified by the gedit Team, 2005-2008. See the AUTHORS file for a
+ * list of people on the gedit Team.
+ * See the ChangeLog files for a list of changes.
+ *
+ * $Id$
+ */
+
+#ifndef __GEDIT_GIO_DOCUMENT_LOADER_H__
+#define __GEDIT_GIO_DOCUMENT_LOADER_H__
+
+#include <gedit/gedit-document.h>
+#include "gedit-document-loader.h"
+
+G_BEGIN_DECLS
+
+/*
+ * Type checking and casting macros
+ */
+#define GEDIT_TYPE_GIO_DOCUMENT_LOADER              (gedit_gio_document_loader_get_type())
+#define GEDIT_GIO_DOCUMENT_LOADER(obj)              (G_TYPE_CHECK_INSTANCE_CAST((obj), GEDIT_TYPE_GIO_DOCUMENT_LOADER, GeditGioDocumentLoader))
+#define GEDIT_GIO_DOCUMENT_LOADER_CLASS(klass)      (G_TYPE_CHECK_CLASS_CAST((klass), GEDIT_TYPE_GIO_DOCUMENT_LOADER, GeditGioDocumentLoaderClass))
+#define GEDIT_IS_GIO_DOCUMENT_LOADER(obj)           (G_TYPE_CHECK_INSTANCE_TYPE((obj), GEDIT_TYPE_GIO_DOCUMENT_LOADER))
+#define GEDIT_IS_GIO_DOCUMENT_LOADER_CLASS(klass)   (G_TYPE_CHECK_CLASS_TYPE ((klass), GEDIT_TYPE_GIO_DOCUMENT_LOADER))
+#define GEDIT_GIO_DOCUMENT_LOADER_GET_CLASS(obj)    (G_TYPE_INSTANCE_GET_CLASS((obj), GEDIT_TYPE_GIO_DOCUMENT_LOADER, GeditGioDocumentLoaderClass))
+
+/* Private structure type */
+typedef struct _GeditGioDocumentLoaderPrivate GeditGioDocumentLoaderPrivate;
+
+/*
+ * Main object structure
+ */
+typedef struct _GeditGioDocumentLoader GeditGioDocumentLoader;
+
+struct _GeditGioDocumentLoader
+{
+	GeditDocumentLoader loader;
+
+	/*< private > */
+	GeditGioDocumentLoaderPrivate *priv;
+};
+
+/*
+ * Class definition
+ */
+typedef GeditDocumentLoaderClass GeditGioDocumentLoaderClass;
+
+/*
+ * Public methods
+ */
+GType 		 	 gedit_gio_document_loader_get_type	(void) G_GNUC_CONST;
+
+G_END_DECLS
+
+#endif  /* __GEDIT_GIO_DOCUMENT_LOADER_H__  */
Index: gedit/gedit-mmap-document-loader.c
===================================================================
--- gedit/gedit-mmap-document-loader.c	(revisione 6382)
+++ gedit/gedit-mmap-document-loader.c	(copia locale)
@@ -44,7 +44,6 @@
 
 #include <glib/gi18n.h>
 #include <glib/gstdio.h>
-#include <libgnomevfs/gnome-vfs.h>
 
 #include "gedit-mmap-document-loader.h"
 #include "gedit-debug.h"
@@ -149,19 +148,16 @@ mmap_sigbus_handler (int signo)
 static gboolean
 load_file_real (GeditMmapDocumentLoader *mloader)
 {
-	GnomeVFSResult result;
 	gint ret;
 
 	g_return_val_if_fail (mloader->priv->fd != -1, FALSE);
 
 	if (fstat (mloader->priv->fd, &mloader->priv->statbuf) != 0) 
 	{
-		result = gnome_vfs_result_from_errno ();
-
 		g_set_error (&mloader->priv->error,
 			     GEDIT_DOCUMENT_ERROR,
-			     result,
-			     gnome_vfs_result_to_string (result));
+			     g_io_error_from_errno (errno),
+			     g_strerror (errno));
 
 		goto done;
 	}
@@ -173,14 +169,14 @@ load_file_real (GeditMmapDocumentLoader 
 		{
 			g_set_error (&mloader->priv->error,
 				     GEDIT_DOCUMENT_ERROR,
-				     GNOME_VFS_ERROR_IS_DIRECTORY,
-				     gnome_vfs_result_to_string (GNOME_VFS_ERROR_IS_DIRECTORY));
+				     G_IO_ERROR_IS_DIRECTORY,
+				     "Is a directory");
 		}
 		else
 		{
 			g_set_error (&mloader->priv->error,
 				     GEDIT_DOCUMENT_ERROR,
-				     GEDIT_DOCUMENT_ERROR_NOT_REGULAR_FILE,
+				     G_IO_ERROR_NOT_REGULAR_FILE,
 				     "Not a regular file");
 		}
 
@@ -217,12 +213,10 @@ load_file_real (GeditMmapDocumentLoader 
 		{
 			gedit_debug_message (DEBUG_LOADER, "mmap failed");
 
-			result = gnome_vfs_result_from_errno ();
-
 			g_set_error (&mloader->priv->error,
 				     GEDIT_DOCUMENT_ERROR,
-				     result,
-				     gnome_vfs_result_to_string (result));
+				     g_io_error_from_errno (errno),
+				     g_strerror (errno));
 
 			goto done;
 		}
@@ -243,8 +237,8 @@ load_file_real (GeditMmapDocumentLoader 
 
 			g_set_error (&mloader->priv->error,
 				     GEDIT_DOCUMENT_ERROR,
-				     GNOME_VFS_ERROR_IO,
-				     gnome_vfs_result_to_string (GNOME_VFS_ERROR_IO));
+				     G_IO_ERROR_FAILED,
+				     "I/O error");
 
 			ret = munmap (mapped_file, mloader->priv->statbuf.st_size);
 			if (ret != 0)
@@ -275,13 +269,13 @@ load_file_real (GeditMmapDocumentLoader 
 		/* restore the default sigbus handler */
 		sigaction (SIGBUS, &old_sigbusact, 0);
 
-		mime_type = gnome_vfs_get_mime_type_for_name_and_data (mloader->priv->local_file_name,
-								       mapped_file,
-								       MIN (mloader->priv->bytes_read,
-									    MAX_MIME_SNIFF_SIZE));
+		mime_type = g_content_type_guess (mloader->priv->local_file_name,
+						  (const guchar *)mapped_file,
+						  MIN (mloader->priv->bytes_read,
+						       MAX_MIME_SNIFF_SIZE),
+						  NULL);
 
-		if ((mime_type != NULL) &&
-		     strcmp (mime_type, GNOME_VFS_MIME_TYPE_UNKNOWN) != 0)
+		if ((mime_type != NULL) && !g_content_type_is_unknown (mime_type))
 		{
 			mloader->priv->mime_type = g_strdup (mime_type);
 		}
@@ -335,12 +329,10 @@ load_file (GeditMmapDocumentLoader *mloa
 	mloader->priv->fd = open (fname, O_RDONLY);
 	if (mloader->priv->fd == -1)
 	{
-		GnomeVFSResult result = gnome_vfs_result_from_errno ();
-
 		g_set_error (&mloader->priv->error,
 			     GEDIT_DOCUMENT_ERROR,
-			     result,
-			     gnome_vfs_result_to_string (result));
+			     g_io_error_from_errno (errno),
+			     g_strerror (errno));
 
 		g_timeout_add_full (G_PRIORITY_HIGH,
 				    0,
@@ -366,8 +358,12 @@ gedit_mmap_document_loader_load (GeditDo
 {
 	GeditMmapDocumentLoader *mloader = GEDIT_MMAP_DOCUMENT_LOADER (loader);
 	gchar *local_path;
+	GFile *gfile;
+	
+	gfile = g_file_new_for_uri (loader->uri);
+	local_path = g_file_get_path (gfile);
+	g_object_unref (gfile);
 
-	local_path = gnome_vfs_get_local_path_from_uri (loader->uri);
 	if (local_path != NULL)
 	{
 		load_file (mloader, local_path);
@@ -377,8 +373,8 @@ gedit_mmap_document_loader_load (GeditDo
 	{
 		g_set_error (&mloader->priv->error,
 			     GEDIT_DOCUMENT_ERROR,
-			     GNOME_VFS_ERROR_NOT_SUPPORTED,
-			     gnome_vfs_result_to_string (GNOME_VFS_ERROR_NOT_SUPPORTED));
+			     G_IO_ERROR_NOT_SUPPORTED,
+			     "Not supported");
 	}
 }
 
@@ -404,8 +400,8 @@ gedit_mmap_document_loader_get_file_size
 	GeditMmapDocumentLoader *mloader = GEDIT_MMAP_DOCUMENT_LOADER (loader);
 
 	if (!mloader->priv->statbuf_filled)
-		return (goffset) 0;
-	return (goffset) mloader->priv->statbuf.st_size;
+		return 0;
+	return mloader->priv->statbuf.st_size;
 }
 
 static goffset
@@ -421,8 +417,8 @@ gedit_mmap_document_loader_cancel (Gedit
 
 	g_set_error (&mloader->priv->error,
 		     GEDIT_DOCUMENT_ERROR,
-		     GNOME_VFS_ERROR_CANCELLED,
-		     gnome_vfs_result_to_string (GNOME_VFS_ERROR_CANCELLED));
+		     G_IO_ERROR_CANCELLED,
+		     "Cancelled");
 
 	gedit_document_loader_loading (GEDIT_DOCUMENT_LOADER (mloader),
 				       TRUE,
Index: gedit/gedit-document.c
===================================================================
--- gedit/gedit-document.c	(revisione 6382)
+++ gedit/gedit-document.c	(copia locale)
@@ -132,6 +132,10 @@ struct _GeditDocumentPrivate
 	/* Search highlighting support variables */	
 	GeditTextRegion *to_search_region;
 	GtkTextTag      *found_tag;
+	
+	/* Mount operation factory */
+	GeditMountOperationFactory  mount_operation_factory;
+	gpointer		    mount_operation_userdata;
 };
 
 enum {
@@ -1039,7 +1043,7 @@ document_loader_loaded (GeditDocumentLoa
 
 	/* special case creating a named new doc */
 	else if (doc->priv->create &&
-	         (error->code == GNOME_VFS_ERROR_NOT_FOUND) &&
+	         (error->code == G_IO_ERROR_NOT_FOUND) &&
 	         (gedit_utils_uri_has_file_scheme (doc->priv->uri)))
 	{
 		reset_temp_loading_data (doc);
@@ -2179,3 +2183,26 @@ gedit_document_get_enable_search_highlig
 	
 	return (doc->priv->to_search_region != NULL);
 }
+
+void
+gedit_document_set_mount_operation_factory (GeditDocument 	       *doc,
+					    GeditMountOperationFactory	callback,
+					    gpointer	                userdata)
+{
+	g_return_if_fail (GEDIT_IS_DOCUMENT (doc));
+	
+	doc->priv->mount_operation_factory = callback;
+	doc->priv->mount_operation_userdata = userdata;
+}
+
+GMountOperation *
+gedit_document_create_mount_operation (GeditDocument *doc)
+{
+	g_return_val_if_fail (GEDIT_IS_DOCUMENT (doc), NULL);
+	
+	if (doc->priv->mount_operation_factory == NULL)
+		return g_mount_operation_new ();
+	else
+		return doc->priv->mount_operation_factory (doc, 
+						           doc->priv->mount_operation_userdata);
+}
Index: gedit/gedit-document.h
===================================================================
--- gedit/gedit-document.h	(revisione 6382)
+++ gedit/gedit-document.h	(copia locale)
@@ -135,16 +135,17 @@ struct _GeditDocumentClass
 					 GtkTextIter      *end);
 };
 
+typedef GMountOperation *(*GeditMountOperationFactory)(GeditDocument *doc, 
+						       gpointer       userdata);
 
 #define GEDIT_DOCUMENT_ERROR gedit_document_error_quark ()
 
 enum
 {
-	/* start at GNOME_VFS_NUM_ERRORS since we use GnomeVFSResult 
-	 * for the error codes */ 
-	GEDIT_DOCUMENT_ERROR_EXTERNALLY_MODIFIED = GNOME_VFS_NUM_ERRORS,
-	GEDIT_DOCUMENT_ERROR_NOT_REGULAR_FILE,
+	/* we use GIO error codes, so start at some high number? */
+	GEDIT_DOCUMENT_ERROR_EXTERNALLY_MODIFIED = 1 << 10,
 	GEDIT_DOCUMENT_ERROR_CANT_CREATE_BACKUP,
+	GEDIT_DOCUMENT_ERROR_TOO_BIG,
 	GEDIT_DOCUMENT_NUM_ERRORS 
 };
 
@@ -242,6 +243,15 @@ void		 gedit_document_set_enable_search_
 gboolean	 gedit_document_get_enable_search_highlighting
 						(GeditDocument       *doc);
 
+void		 gedit_document_set_mount_operation_factory
+						(GeditDocument	            *doc,
+						 GeditMountOperationFactory  callback,
+						 gpointer	             userdata);
+GMountOperation
+		*gedit_document_create_mount_operation
+						(GeditDocument	     *doc);
+		
+
 /* 
  * Non exported functions
  */
Index: gedit/gedit-document-saver.c
===================================================================
--- gedit/gedit-document-saver.c	(revisione 6382)
+++ gedit/gedit-document-saver.c	(copia locale)
@@ -45,7 +45,7 @@
 #include "gedit-enum-types.h"
 
 #include "gedit-local-document-saver.h"
-#include "gedit-gnomevfs-document-saver.h"
+#include "gedit-gio-document-saver.h"
 
 G_DEFINE_ABSTRACT_TYPE(GeditDocumentSaver, gedit_document_saver, G_TYPE_OBJECT)
 
@@ -221,7 +221,7 @@ gedit_document_saver_new (GeditDocument 
 	if (gedit_utils_uri_has_file_scheme (uri))
 		saver_type = GEDIT_TYPE_LOCAL_DOCUMENT_SAVER;
 	else
-		saver_type = GEDIT_TYPE_GNOMEVFS_DOCUMENT_SAVER;
+		saver_type = GEDIT_TYPE_GIO_DOCUMENT_SAVER;
 
 	if (encoding == NULL)
 		encoding = gedit_encoding_get_utf8 ();
@@ -236,28 +236,20 @@ gedit_document_saver_new (GeditDocument 
 	return saver;
 }
 
-/*
- * Write the document contents in fd.
- */
-gboolean
-gedit_document_saver_write_document_contents (GeditDocumentSaver  *saver,
-					      gint                 fd,
-					      GError             **error)
+gchar *
+gedit_document_saver_get_document_contents (GeditDocumentSaver *saver,
+					    gsize 	       *len,
+					    GError 	      **error)
 {
 	GtkTextBuffer *buffer = GTK_TEXT_BUFFER (saver->document);
 	GtkTextIter start_iter;
 	GtkTextIter end_iter;
 	gchar *contents;
-	gsize len;
-	ssize_t written;
-	gboolean res;
-
-	gedit_debug (DEBUG_SAVER);
-
+	
 	gtk_text_buffer_get_bounds (buffer, &start_iter, &end_iter);
 	contents = gtk_text_buffer_get_slice (buffer, &start_iter, &end_iter, TRUE);
 
-	len = strlen (contents);
+	*len = strlen (contents);
 
 	if (saver->encoding != gedit_encoding_get_utf8 ())
 	{
@@ -265,7 +257,7 @@ gedit_document_saver_write_document_cont
 		gsize new_len;
 
 		converted_contents = gedit_convert_from_utf8 (contents, 
-							      len, 
+							      *len, 
 							      saver->encoding,
 							      &new_len,
 							      error);
@@ -274,14 +266,34 @@ gedit_document_saver_write_document_cont
 		if (*error != NULL)
 		{
 			/* Conversion error */
-			return FALSE;
+			return NULL;
 		}
 		else
 		{
 			contents = converted_contents;
-			len = new_len;
+			*len = new_len;
 		}
 	}
+	
+	return contents;
+}
+
+/*
+ * Write the document contents in fd.
+ */
+gboolean
+gedit_document_saver_write_document_contents (GeditDocumentSaver  *saver,
+					      gint                 fd,
+					      GError             **error)
+{
+	gsize len;
+	ssize_t written;
+	gboolean res;
+	gchar *contents;
+
+	gedit_debug (DEBUG_SAVER);
+
+	contents = gedit_document_saver_get_document_contents (saver, &len, error);
 
 	/* make sure we are at the start */
 	res = (lseek (fd, 0, SEEK_SET) != -1);
@@ -352,12 +364,10 @@ gedit_document_saver_write_document_cont
 
 	if (!res)
 	{
-		GnomeVFSResult result = gnome_vfs_result_from_errno ();
-
 		g_set_error (error,
 			     GEDIT_DOCUMENT_ERROR,
-			     result,
-			     gnome_vfs_result_to_string (result));
+			     g_io_error_from_errno (errno),
+			     g_strerror (errno));
 	}
 
 	return res;
Index: gedit/Makefile.am
===================================================================
--- gedit/Makefile.am	(revisione 6382)
+++ gedit/Makefile.am	(copia locale)
@@ -63,10 +63,10 @@ NOINST_H_FILES =			\
 	gedit-documents-panel.h		\
 	gedit-document-loader.h		\
 	gedit-mmap-document-loader.h	\
-	gedit-gnomevfs-document-loader.h\
+	gedit-gio-document-loader.h	\
 	gedit-document-saver.h		\
 	gedit-local-document-saver.h	\
-	gedit-gnomevfs-document-saver.h	\
+	gedit-gio-document-saver.h	\
 	gedit-history-entry.h		\
 	gedit-print-job.h		\
 	gedit-print-preview.h		\
@@ -127,10 +127,10 @@ libgedit_la_SOURCES = 			\
 	gedit-document.c 		\
 	gedit-document-loader.c		\
 	gedit-mmap-document-loader.c	\
-	gedit-gnomevfs-document-loader.c\
+	gedit-gio-document-loader.c	\
 	gedit-document-saver.c		\
 	gedit-local-document-saver.c	\
-	gedit-gnomevfs-document-saver.c	\
+	gedit-gio-document-saver.c	\
 	gedit-documents-panel.c		\
 	gedit-encodings.c		\
 	gedit-encodings-option-menu.c	\
Index: gedit/gedit-document-saver.h
===================================================================
--- gedit/gedit-document-saver.h	(revisione 6382)
+++ gedit/gedit-document-saver.h	(copia locale)
@@ -103,6 +103,11 @@ GeditDocumentSaver 	*gedit_document_save
 								 const GeditEncoding  *encoding,
 								 GeditDocumentSaveFlags flags);
 
+gchar			*gedit_document_saver_get_document_contents (
+								 GeditDocumentSaver  *saver,
+								 gsize		     *len,
+								 GError             **error);
+
 gboolean		 gedit_document_saver_write_document_contents (
 								 GeditDocumentSaver  *saver,
 								 gint                 fd,
Index: configure.ac
===================================================================
--- configure.ac	(revisione 6382)
+++ configure.ac	(copia locale)
@@ -164,11 +164,10 @@ dnl ====================================
 
 PKG_CHECK_MODULES(GEDIT, [
 	glib-2.0 >= 2.13.0
+	gio-2.0 >= 2.16.0
 	gtk+-2.0 >= 2.13.0
 	gtksourceview-2.0 >= 2.2.0
 	libgnomeui-2.0 >= 2.16.0
-	gnome-vfs-2.0 >= 2.16.0
-	gio-2.0 >= 2.16.0
 ])
 GEDIT_LIBS="${GEDIT_LIBS}"
 AC_SUBST(GEDIT_LIBS)
