Index: gtk/gtkfilechooserdefault.c
===================================================================
--- gtk/gtkfilechooserdefault.c	(revision 17214)
+++ gtk/gtkfilechooserdefault.c	(working copy)
@@ -3694,6 +3694,65 @@
   bookmarks_add_selected_folder (impl);
 }
 
+static void
+remove_file_idle_cb (GtkFileSystemHandle *handle,
+		     const GtkFilePath   *path,
+		     const GError        *error,
+		     gpointer             data)
+{
+  gboolean cancelled = handle->cancelled;
+  GtkFileChooserDefault *impl = data;
+
+  if (!g_slist_find (impl->pending_handles, handle))
+    goto out;
+
+  impl->pending_handles = g_slist_remove (impl->pending_handles, handle);
+
+  if (cancelled)
+    goto out;
+
+  /*
+  if (!error)
+    change_folder_and_display_error (impl, path);
+  else
+    error_dialog (impl, _("Could not remove file"), path, g_error_copy(error));
+  */
+  if (error)
+    error_dialog (impl, _("Could not remove file"), path, g_error_copy(error));
+
+
+ out:
+  g_object_unref (impl);
+  g_object_unref (handle);
+}
+
+/* Callback used when the "Remove File" menu item is activated */
+static void
+remove_file_cb (GtkMenuItem                *item,
+		GtkFileChooserDefault      *impl)
+{
+  const GtkFilePath *path;
+  GtkFileSystemHandle *handle;
+  
+  path = get_selected_path (impl);
+  if (path)
+    {
+      handle = gtk_file_system_remove_file (impl->file_system, path,
+					    remove_file_idle_cb,
+					    g_object_ref (impl));
+      impl->pending_handles = g_slist_append (impl->pending_handles, handle);
+    }
+
+  //change_folder_and_display_error (impl, impl->current_folder);
+}
+
+/* Callback used when the "Rename File" menu item is activated */
+static void
+rename_file_cb (GtkMenuItem                *item,
+		GtkFileChooserDefault      *impl)
+{
+}
+
 /* Callback used when the "Show Hidden Files" menu item is toggled */
 static void
 show_hidden_toggled_cb (GtkCheckMenuItem      *item,
@@ -3919,6 +3978,24 @@
   gtk_widget_show (item);
   gtk_menu_shell_append (GTK_MENU_SHELL (impl->browse_files_popup_menu), item);
 
+  item = gtk_image_menu_item_new_with_label (_("Remove File"));
+  gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item),
+				 gtk_image_new_from_stock (GTK_STOCK_DELETE, GTK_ICON_SIZE_MENU));
+  /* XXX: Special item reference? */
+  g_signal_connect (item, "activate",
+		    G_CALLBACK (remove_file_cb), impl);
+  gtk_widget_show (item);
+  gtk_menu_shell_append (GTK_MENU_SHELL (impl->browse_files_popup_menu), item);
+
+  item = gtk_image_menu_item_new_with_label (_("Rename File"));
+  gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item),
+				 gtk_image_new_from_stock (GTK_STOCK_EDIT, GTK_ICON_SIZE_MENU));
+  /* XXX: Special item reference? */
+  g_signal_connect (item, "activate",
+		    G_CALLBACK (rename_file_cb), impl);
+  gtk_widget_show (item);
+  gtk_menu_shell_append (GTK_MENU_SHELL (impl->browse_files_popup_menu), item);
+
   item = gtk_check_menu_item_new_with_mnemonic (_("Show _Hidden Files"));
   impl->browse_files_popup_menu_hidden_files_item = item;
   g_signal_connect (item, "toggled",
Index: gtk/gtkfilesystem.c
===================================================================
--- gtk/gtkfilesystem.c	(revision 17214)
+++ gtk/gtkfilesystem.c	(working copy)
@@ -496,6 +496,34 @@
   return GTK_FILE_SYSTEM_GET_IFACE (file_system)->create_folder (file_system, path, callback, data);
 }
 
+GtkFileSystemHandle *
+gtk_file_system_remove_file   (GtkFileSystem                     *file_system,
+			       const GtkFilePath                 *path,
+			       GtkFileSystemCreateFolderCallback  callback,
+			       gpointer                           data)
+{
+  g_return_val_if_fail (GTK_IS_FILE_SYSTEM (file_system), NULL);
+  g_return_val_if_fail (path != NULL, NULL);
+  g_return_val_if_fail (callback != NULL, NULL);
+
+  return GTK_FILE_SYSTEM_GET_IFACE (file_system)->remove_file (file_system, path, callback, data);
+}
+
+GtkFileSystemHandle *
+gtk_file_system_rename_file   (GtkFileSystem                     *file_system,
+			       const GtkFilePath                 *path,
+			       const gchar                       *new_file_name,
+			       GtkFileSystemRenameFileCallback    callback,
+			       gpointer                           data)
+{
+  g_return_val_if_fail (GTK_IS_FILE_SYSTEM (file_system), NULL);
+  g_return_val_if_fail (path != NULL, NULL);
+  g_return_val_if_fail (new_file_name != NULL, NULL);
+  g_return_val_if_fail (callback != NULL, NULL);
+
+  return GTK_FILE_SYSTEM_GET_IFACE (file_system)->rename_file (file_system, path, new_file_name, callback, data);
+}
+
 void
 gtk_file_system_cancel_operation (GtkFileSystemHandle *handle)
 {
Index: gtk/gtkfilesystem.h
===================================================================
--- gtk/gtkfilesystem.h	(revision 17214)
+++ gtk/gtkfilesystem.h	(working copy)
@@ -166,6 +166,15 @@
 						    const GtkFilePath   *path,
 						    const GError        *error,
 						    gpointer             data);
+typedef void (* GtkFileSystemRemoveFileCallback) (GtkFileSystemHandle *handle,
+						    const GtkFilePath   *path,
+						    const GError        *error,
+						    gpointer             data);
+typedef void (* GtkFileSystemRenameFileCallback) (GtkFileSystemHandle *handle,
+						    const GtkFilePath   *path,
+						    const gchar         *new_file_name,
+						    const GError        *error,
+						    gpointer             data);
 typedef void (* GtkFileSystemVolumeMountCallback) (GtkFileSystemHandle *handle,
 						   GtkFileSystemVolume *volume,
 						   const GError        *error,
@@ -198,6 +207,15 @@
 					   const GtkFilePath                 *path,
 					   GtkFileSystemCreateFolderCallback  callback,
 					   gpointer                           data);
+  GtkFileSystemHandle * (*remove_file)  (GtkFileSystem                       *file_system,
+					 const GtkFilePath                   *path,
+					 GtkFileSystemRemoveFileCallback      callback,
+					 gpointer                             data);
+  GtkFileSystemHandle * (*rename_file)  (GtkFileSystem                       *file_system,
+					 const GtkFilePath                   *path,
+					 const gchar                         *new_file_name,
+					 GtkFileSystemRenameFileCallback      callback,
+					 gpointer                             data);
 
   void               (*cancel_operation) (GtkFileSystemHandle *handle);
 
@@ -315,6 +333,15 @@
 						    const GtkFilePath                 *path,
 						    GtkFileSystemCreateFolderCallback  callback,
 						    gpointer                           data);
+GtkFileSystemHandle *gtk_file_system_remove_file   (GtkFileSystem                     *file_system,
+						    const GtkFilePath                 *path,
+						    GtkFileSystemRemoveFileCallback    callback,
+						    gpointer                           data);
+GtkFileSystemHandle *gtk_file_system_rename_file   (GtkFileSystem                     *file_system,
+						    const GtkFilePath                 *path,
+						    const gchar                       *new_file_name,
+						    GtkFileSystemRenameFileCallback    callback,
+						    gpointer                           data);
 void              gtk_file_system_cancel_operation (GtkFileSystemHandle *handle);
 GtkFilePath *     gtk_file_system_make_path      (GtkFileSystem     *file_system,
 						  const GtkFilePath *base_path,
Index: gtk/gtkfilesystemunix.c
===================================================================
--- gtk/gtkfilesystemunix.c	(revision 17214)
+++ gtk/gtkfilesystemunix.c	(working copy)
@@ -164,6 +164,15 @@
 							        const GtkFilePath  *path,
 								GtkFileSystemCreateFolderCallback callback,
 								gpointer data);
+static GtkFileSystemHandle *gtk_file_system_unix_remove_file (GtkFileSystem                     *file_system,
+							      const GtkFilePath                 *path,
+							      GtkFileSystemRemoveFileCallback    callback,
+							      gpointer                           data);
+static GtkFileSystemHandle *gtk_file_system_unix_rename_file (GtkFileSystem                     *file_system,
+							      const GtkFilePath                 *path,
+							      const gchar                       *new_file_name,
+							      GtkFileSystemRenameFileCallback    callback,
+							      gpointer                           data);
 static void         gtk_file_system_unix_cancel_operation        (GtkFileSystemHandle *handle);
 
 static void         gtk_file_system_unix_volume_free             (GtkFileSystem       *file_system,
@@ -319,6 +328,8 @@
   iface->get_folder = gtk_file_system_unix_get_folder;
   iface->get_info = gtk_file_system_unix_get_info;
   iface->create_folder = gtk_file_system_unix_create_folder;
+  iface->remove_file = gtk_file_system_unix_remove_file;
+  iface->rename_file = gtk_file_system_unix_rename_file;
   iface->cancel_operation = gtk_file_system_unix_cancel_operation;
   iface->volume_free = gtk_file_system_unix_volume_free;
   iface->volume_get_base_path = gtk_file_system_unix_volume_get_base_path;
@@ -506,6 +517,8 @@
   CALLBACK_GET_INFO,
   CALLBACK_GET_FOLDER,
   CALLBACK_CREATE_FOLDER,
+	CALLBACK_REMOVE_FILE,
+	CALLBACK_RENAME_FILE,
   CALLBACK_VOLUME_MOUNT
 };
 
@@ -643,6 +656,102 @@
 }
 
 
+struct remove_file_callback
+{
+  GtkFileSystemRemoveFileCallback callback;
+  GtkFileSystemHandle *handle;
+  GtkFilePath *path;
+  GError *error;
+  gpointer data;
+};
+
+static inline void
+dispatch_remove_file_callback (struct remove_file_callback *info)
+{
+  (* info->callback) (info->handle, info->path, info->error, info->data);
+
+  if (info->error)
+    g_error_free (info->error);
+
+  if (info->path)
+    gtk_file_path_free (info->path);
+
+  g_object_unref (info->handle);
+
+  g_free (info);
+}
+
+static inline void
+queue_remove_file_callback   (GtkFileSystemRemoveFileCallback  callback,
+			      GtkFileSystemHandle               *handle,
+			      const GtkFilePath                 *path,
+			      GError                            *error,
+			      gpointer                           data)
+{
+  struct remove_file_callback *info;
+
+  info = g_new (struct remove_file_callback, 1);
+  info->callback = callback;
+  info->handle = handle;
+  info->path = gtk_file_path_copy (path);
+  info->error = error;
+  info->data = data;
+
+  queue_callback (GTK_FILE_SYSTEM_UNIX (handle->file_system), CALLBACK_REMOVE_FILE, info);
+}
+
+
+struct rename_file_callback
+{
+  GtkFileSystemRenameFileCallback callback;
+  GtkFileSystemHandle *handle;
+  GtkFilePath *path;
+  gchar *new_file_name;
+  GError *error;
+  gpointer data;
+};
+
+static inline void
+dispatch_rename_file_callback (struct rename_file_callback *info)
+{
+  (* info->callback) (info->handle, info->path, info->new_file_name, info->error, info->data);
+
+  if (info->error)
+    g_error_free (info->error);
+
+  if (info->path)
+    gtk_file_path_free (info->path);
+
+  if (info->new_file_name)
+    g_free (info->new_file_name);
+
+  g_object_unref (info->handle);
+
+  g_free (info);
+}
+
+static inline void
+queue_rename_file_callback   (GtkFileSystemRenameFileCallback  callback,
+			      GtkFileSystemHandle               *handle,
+			      const GtkFilePath                 *path,
+			      const gchar                       *new_file_name,
+			      GError                            *error,
+			      gpointer                           data)
+{
+  struct rename_file_callback *info;
+
+  info = g_new (struct rename_file_callback, 1);
+  info->callback = callback;
+  info->handle = handle;
+  info->path = gtk_file_path_copy (path);
+  info->new_file_name = g_strdup (new_file_name);
+  info->error = error;
+  info->data = data;
+
+  queue_callback (GTK_FILE_SYSTEM_UNIX (handle->file_system), CALLBACK_RENAME_FILE, info);
+}
+
+
 struct volume_mount_callback
 {
   GtkFileSystemVolumeMountCallback callback;
@@ -694,6 +803,8 @@
     struct get_info_callback *get_info;
     struct get_folder_callback *get_folder;
     struct create_folder_callback *create_folder;
+    struct remove_file_callback *remove_file;
+    struct rename_file_callback *rename_file;
     struct volume_mount_callback *volume_mount;
   } info;
 };
@@ -730,6 +841,14 @@
 	    dispatch_create_folder_callback (info->info.create_folder);
 	    break;
 
+	  case CALLBACK_REMOVE_FILE:
+	    dispatch_remove_file_callback (info->info.remove_file);
+	    break;
+
+	  case CALLBACK_RENAME_FILE:
+	    dispatch_rename_file_callback (info->info.rename_file);
+	    break;
+
 	  case CALLBACK_VOLUME_MOUNT:
 	    dispatch_volume_mount_callback (info->info.volume_mount);
 	    break;
@@ -783,6 +902,14 @@
 	info->info.create_folder = data;
 	break;
 
+      case CALLBACK_REMOVE_FILE:
+	info->info.remove_file = data;
+	break;
+
+      case CALLBACK_RENAME_FILE:
+	info->info.rename_file = data;
+	break;
+
       case CALLBACK_VOLUME_MOUNT:
 	info->info.volume_mount = data;
 	break;
@@ -1119,6 +1246,218 @@
   return handle;
 }
 
+static GtkFileSystemHandle *
+gtk_file_system_unix_remove_file (GtkFileSystem                     *file_system,
+				  const GtkFilePath                 *path,
+				  GtkFileSystemRemoveFileCallback    callback,
+				  gpointer                           data)
+{
+  GError *error = NULL;
+  GtkFileSystemUnix *system_unix;
+  GtkFileSystemHandle *handle;
+  GtkFileFolderUnix *folder_unix;
+  const char *filename;
+  struct stat stat_buf;
+  gboolean result;
+  char *parent, *tmp;
+  int save_errno = errno;
+
+  system_unix = GTK_FILE_SYSTEM_UNIX (file_system);
+
+  filename = gtk_file_path_get_string (path);
+  g_return_val_if_fail (filename != NULL, FALSE);
+  g_return_val_if_fail (g_path_is_absolute (filename), FALSE);
+
+  handle = create_handle (file_system);
+
+  tmp = remove_trailing_slash (filename);
+  errno = 0;
+  result = lstat (filename, &stat_buf);
+  save_errno = errno;
+  if (-1 == result)
+    {
+      gchar *display_name = g_filename_display_name (filename);
+      g_set_error (&error,
+		   GTK_FILE_SYSTEM_ERROR,
+		   GTK_FILE_SYSTEM_ERROR_FAILED,
+		   _("Error retrieving file stats '%s': %s"),
+		   display_name,
+		   g_strerror (save_errno));
+
+      g_object_ref (handle);
+      queue_remove_file_callback (callback, handle, path, error, data);
+
+      g_free (display_name);
+      return handle;
+    }
+
+  if (S_ISDIR(stat_buf.st_mode))
+    {
+      errno = 0;
+      result = rmdir (tmp);
+      save_errno = errno;
+    }
+  else
+    {
+      errno = 0;
+      result = unlink (tmp);
+      save_errno = errno;
+    }
+
+  g_free (tmp);
+
+  if (-1 == result)
+    {
+      gchar *display_name = g_filename_display_name (filename);
+      g_set_error (&error,
+		   GTK_FILE_SYSTEM_ERROR,
+		   GTK_FILE_SYSTEM_ERROR_FAILED,
+		   _("Error removing file '%s': %s"),
+		   display_name,
+		   g_strerror (save_errno));
+
+      g_object_ref (handle);
+      queue_remove_file_callback (callback, handle, path, error, data);
+
+      g_free (display_name);
+      return handle;
+    }
+
+  g_object_ref (handle);
+  queue_remove_file_callback (callback, handle, path, NULL, data);
+
+  /* Remove the folder from the system stats and emit deleted */
+  folder_unix = g_hash_table_lookup (system_unix->folder_hash, filename);
+  if (folder_unix)
+    {
+      /* XXX: Fairly certain this will leak the key */
+      if (!g_hash_table_steal (system_unix->folder_hash, filename))
+	{
+	  g_warning ("Could not steal folder from system hash");
+	}
+      g_signal_emit_by_name (folder_unix, "deleted");
+      g_free (folder_unix);
+    }
+  /* Update the parent and emit files-removed */
+  parent = get_parent_dir (filename);
+  if (parent)
+    {
+      folder_unix = g_hash_table_lookup (system_unix->folder_hash, parent);
+      if (folder_unix)
+	{
+	  GSList *paths;
+	  char *basename;
+	  struct stat_info_entry *entry;
+
+	  basename = g_path_get_basename (filename);
+	  entry = g_hash_table_lookup (folder_unix->stat_info, basename);
+	  if (entry)
+	    {
+	      if (!g_hash_table_remove(folder_unix->stat_info, basename))
+		g_warning ("Could not remove file from parent folder");
+	    }
+	  else
+	    {
+	      g_warning ("File not a member of its parent");
+	    }
+
+	  fill_in_stats (folder_unix);
+	  
+	  paths = g_slist_append (NULL, (GtkFilePath *) path);
+	  g_signal_emit_by_name (folder_unix, "files-removed", paths);
+	  g_slist_free (paths);
+	}
+    }
+  g_free (parent);
+  
+  return handle;
+}
+
+static GtkFileSystemHandle *
+gtk_file_system_unix_rename_file (GtkFileSystem                     *file_system,
+				  const GtkFilePath                 *path,
+				  const gchar                       *new_file_name,
+				  GtkFileSystemRenameFileCallback    callback,
+				  gpointer                           data)
+{
+  GError *error = NULL;
+  GtkFileSystemUnix *system_unix;
+  GtkFileSystemHandle *handle;
+  const char *filename;
+  gboolean result;
+  char *parent, *tmp, *full_new_file_name;
+  int save_errno = errno;
+
+  system_unix = GTK_FILE_SYSTEM_UNIX (file_system);
+
+  filename = gtk_file_path_get_string (path);
+  g_return_val_if_fail (filename != NULL, FALSE);
+  g_return_val_if_fail (g_path_is_absolute (filename), FALSE);
+
+  /* We don't want the file to change directories */
+  g_return_val_if_fail (!g_path_is_absolute (new_file_name), FALSE);
+
+  handle = create_handle (file_system);
+
+  tmp = remove_trailing_slash (filename);
+  parent = get_parent_dir (filename);
+  if (parent)
+    full_new_file_name = g_strconcat (parent, "/", new_file_name, NULL);
+  else
+    full_new_file_name = g_strdup (new_file_name);
+  errno = 0;
+  result = rename (tmp, full_new_file_name);
+  save_errno = errno;
+  g_free (tmp);
+
+  if (!result)
+    {
+      gchar *display_name = g_filename_display_name (filename);
+      g_set_error (&error,
+		   GTK_FILE_SYSTEM_ERROR,
+		   GTK_FILE_SYSTEM_ERROR_FAILED,
+		   _("Error renaming directory '%s' to '%s': %s"),
+		   display_name,
+		   full_new_file_name,
+		   g_strerror (save_errno));
+      
+      g_object_ref (handle);
+      queue_rename_file_callback (callback, handle, path, new_file_name, error, data);
+
+      g_free (display_name);
+      if (parent)
+	g_free (parent);
+      g_free (full_new_file_name);
+      return handle;
+    }
+
+  g_free (full_new_file_name);
+
+  g_object_ref (handle);
+  queue_rename_file_callback (callback, handle, path, new_file_name, NULL, data);
+
+  if (parent)
+    {
+      GtkFileFolderUnix *folder_unix;
+
+      folder_unix = g_hash_table_lookup (system_unix->folder_hash, parent);
+      if (folder_unix)
+	{
+	  GSList *paths;
+
+	  fill_in_stats (folder_unix);
+
+	  paths = g_slist_append (NULL, (GtkFilePath *) path);
+	  g_signal_emit_by_name (folder_unix, "files-changed", paths);
+	  g_slist_free (paths);
+	}
+
+      g_free (parent);
+    }
+
+  return handle;
+}
+
 static void
 gtk_file_system_unix_cancel_operation (GtkFileSystemHandle *handle)
 {
