Index: configure.in
===================================================================
--- configure.in	(revision 389)
+++ configure.in	(working copy)
@@ -71,7 +71,7 @@
 AC_SUBST(NAUTILUS_EXTENSION_DIR)
 
 # The full list of plugins
-allowed_plugins="balsa bluetooth empathy evolution gaim gajim nautilus-burn pidgin sylpheed-claws thunderbird upnp"
+allowed_plugins="balsa bluetooth empathy evolution gaim gajim nautilus-burn pidgin removable-devices sylpheed-claws thunderbird upnp"
 
 plugin_error_or_ignore()
 {
@@ -226,6 +226,14 @@
 				add_plugin="0"
 			fi
 		;;
+		removable-devices)
+			PKG_CHECK_MODULES(GIO, gio-2.0,
+					  enable_removable=yes, enable_removable=no)
+			if test "${enable_removable}" != "yes" ; then
+				plugin_error_or_ignore "you need gio-2.0 to build the removable-devices plugin"
+				add_plugin="0"
+			fi
+		;;
 		sylpheed-claws)
 			add_plugin="1"
 		;;
@@ -303,6 +311,7 @@
 src/plugins/gajim/Makefile
 src/plugins/nautilus-burn/Makefile
 src/plugins/pidgin/Makefile
+src/plugins/removable-devices/Makefile
 src/plugins/sylpheed-claws/Makefile
 src/plugins/thunderbird/Makefile
 src/plugins/upnp/Makefile
Index: src/plugins/removable-devices/Makefile.am
===================================================================
--- src/plugins/removable-devices/Makefile.am	(revision 0)
+++ src/plugins/removable-devices/Makefile.am	(revision 0)
@@ -0,0 +1,18 @@
+plugindir = $(libdir)/nautilus-sendto/plugins
+
+INCLUDES =                                      \
+        -DDATADIR=\"$(datadir)\"                \
+        -DICONDIR=\"$(icondir)\"                \
+	-DLOCALEDIR="\"$(datadir)/locale\""	\
+        -I$(top_srcdir)/src                     \
+        -I$(top_builddir)                       \
+        -DGLADEDIR=\""$(gladedir)"\"            \
+        $(NAUTILUS_SENDTO_CFLAGS)               \
+	$(WARN_CFLAGS)
+
+plugin_LTLIBRARIES = libnstremovable_devices.la
+
+libnstremovable_devices_la_SOURCES = removable-devices.c
+libnstremovable_devices_la_LDFLAGS = -module -avoid-version
+libnstremovable_devices_la_LIBADD = $(DBUS_LIBS)
+
Index: src/plugins/removable-devices/removable-devices.c
===================================================================
--- src/plugins/removable-devices/removable-devices.c	(revision 0)
+++ src/plugins/removable-devices/removable-devices.c	(revision 0)
@@ -0,0 +1,277 @@
+/*
+ *
+ * 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 av.
+ *
+ * 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., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301  USA.
+ *
+ * Author:  Maxim Ermilov <ermilov.maxim@gmail.com>
+ */
+
+#include "config.h"
+#include <string.h>
+#include <glib/gi18n-lib.h>
+#include <gio/gio.h>
+#include "nautilus-sendto-plugin.h"
+
+GVolumeMonitor* vol_monitor = NULL;
+GList *volumes;
+GtkWidget *cb;
+
+static void
+cb_mount_removed (GVolumeMonitor *volume_monitor,
+                  GMount         *mount,
+                  NstPlugin      *plugin)
+{
+	char *uuid;
+	GtkTreeIter iter;
+	GList *i = volumes;
+	gboolean b;
+
+	uuid = g_mount_get_uuid (mount);
+	GtkListStore *store = GTK_LIST_STORE (gtk_combo_box_get_model (GTK_COMBO_BOX (cb)));
+	b = gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter);
+	while (b) {
+		char *tuuid;
+		gtk_tree_model_get (GTK_TREE_MODEL (store), &iter, 2, &tuuid, -1);
+		if (tuuid != NULL && uuid != NULL && strcmp (tuuid, uuid) == 0) {
+			gtk_list_store_remove (store, &iter);
+			volumes = g_list_remove_link (volumes, i);
+			g_free (tuuid);
+			break;
+		}
+		b = gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter);
+		i = i->next; 
+		g_free (tuuid);
+	}
+	g_free (uuid);
+}
+
+static void
+cb_mount_changed (GVolumeMonitor *volume_monitor,
+                  GMount         *mount,
+                  NstPlugin      *plugin)
+{
+	char *uuid;
+	GtkTreeIter iter;
+	gboolean b;
+	uuid = g_mount_get_uuid (mount);
+	GtkListStore *store = GTK_LIST_STORE (gtk_combo_box_get_model (GTK_COMBO_BOX (cb)));
+	b = gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter);
+	while (b) {
+		char *tuuid;
+		gtk_tree_model_get (GTK_TREE_MODEL (store), &iter, 2, &tuuid, -1);
+		if (tuuid != NULL && uuid != NULL && strcmp (tuuid, uuid) == 0) {
+			char *name;
+			name = g_mount_get_name (mount);
+			gtk_list_store_set (store, &iter, 0, name, 1, g_mount_get_icon (mount), 2, uuid, -1);
+			g_free (tuuid);
+			g_free (name);
+			break;
+		}
+		b = gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter);
+		g_free (tuuid);
+	}
+	g_free (uuid);
+}
+
+static void
+cb_mount_added (GVolumeMonitor *volume_monitor,
+                GMount         *mount,
+                NstPlugin      *plugin)
+{
+	char *uuid, *name;
+	GtkTreeIter iter;
+	name = g_mount_get_name (mount);
+	uuid = g_mount_get_uuid (mount);
+	GtkListStore *store = GTK_LIST_STORE (gtk_combo_box_get_model (GTK_COMBO_BOX (cb)));
+
+	gtk_list_store_append (store, &iter);
+	gtk_list_store_set (store, &iter, 0, name, 1, g_mount_get_icon (mount), 2, uuid, -1);
+	volumes = g_list_append (volumes, mount);
+
+	g_free (uuid);
+	g_free (name);
+}
+
+static gboolean
+init (NstPlugin *plugin)
+{
+	g_print ("Init removable-devices plugin\n");
+	vol_monitor = g_volume_monitor_get ();
+	cb = gtk_combo_box_new ();
+	return TRUE;
+}
+
+static GtkWidget*
+get_contacts_widget (NstPlugin *plugin)
+{
+	GtkListStore *store;
+	GList *l;
+	GtkTreeIter iter;
+	GtkCellRenderer *text_renderer, *icon_renderer;
+
+	volumes = g_volume_monitor_get_mounts (vol_monitor);
+
+	store = gtk_list_store_new (3, G_TYPE_STRING, G_TYPE_ICON, G_TYPE_STRING);
+
+	for (l = volumes; l != NULL; l = l->next) {
+		char *name, *uuid;
+
+		name = g_mount_get_name (l->data);
+		uuid = g_mount_get_uuid (l->data);
+		gtk_list_store_append (store, &iter);
+		gtk_list_store_set (store, &iter, 0, name, 1, g_mount_get_icon (l->data), 2, uuid, -1);
+		g_free (name);
+		g_free (uuid);
+	}
+
+	gtk_cell_layout_clear (GTK_CELL_LAYOUT (cb));
+	gtk_combo_box_set_model (GTK_COMBO_BOX (cb), GTK_TREE_MODEL (store));
+
+	text_renderer = gtk_cell_renderer_text_new ();
+	icon_renderer = gtk_cell_renderer_pixbuf_new ();
+	gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (cb), icon_renderer, FALSE);
+	gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (cb), text_renderer, TRUE);
+
+	gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (cb), text_renderer, "text", 0,  NULL);
+	gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (cb), icon_renderer, "gicon", 1,  NULL);
+	gtk_combo_box_set_active (GTK_COMBO_BOX (cb), 0);
+
+	g_signal_connect (G_OBJECT (vol_monitor), "mount-removed", G_CALLBACK (cb_mount_removed), plugin);
+	g_signal_connect (G_OBJECT (vol_monitor), "mount-added", G_CALLBACK (cb_mount_added), plugin);
+	g_signal_connect (G_OBJECT (vol_monitor), "mount-changed", G_CALLBACK (cb_mount_changed), plugin);
+	return cb;
+}
+
+static gboolean
+copy_fobject (GFile* source, GFile* dst)
+{
+	GFileEnumerator* en;
+	GFileInfo* info;
+	GError *err = NULL;
+	char *file_name;
+	GFile *dest;
+
+	file_name = g_file_get_basename (source);
+	dest = g_file_get_child (dst, file_name);
+	g_free (file_name);
+
+	if (g_file_query_file_type (source, G_FILE_QUERY_INFO_NONE, NULL) != G_FILE_TYPE_DIRECTORY) {
+		gboolean ret;
+		ret = g_file_copy (source, dest, G_FILE_COPY_NONE, NULL, NULL, NULL, NULL);
+
+		g_object_unref (dest);
+
+		return ret;
+	}
+
+	en = g_file_enumerate_children (source, "*", G_FILE_QUERY_INFO_NONE, NULL, NULL);
+	if (!g_file_make_directory (dest, NULL, NULL)) {
+		g_object_unref (en);
+		g_object_unref (dest);
+		return FALSE;
+	}
+
+	while ((info = g_file_enumerator_next_file (en, NULL, &err)) != NULL) {
+		const char *name;
+
+		name = g_file_info_get_name (G_FILE_INFO (info));
+
+		if (name != NULL) {
+			GFile *child;
+
+			child = g_file_get_child (source, name);
+
+			if (!copy_fobject (child, dest)) {
+				g_object_unref (en);
+				g_object_unref (dest);
+				g_object_unref (child);
+
+				return FALSE;
+			}
+			g_object_unref (child);
+		}
+
+		g_object_unref (info);
+	}
+	g_object_unref (en);
+	g_object_unref (dest);
+
+	if (err != NULL)
+		return FALSE;
+	return TRUE;
+}
+
+static gboolean
+send_files (NstPlugin *plugin, GtkWidget *contact_widget,
+			 GList *file_list)
+{
+	int choice;
+	GMount *dest_vol;
+	GFile *vol_root;
+	char *vol_uri;
+	GList *l;
+
+	choice = gtk_combo_box_get_active (GTK_COMBO_BOX (contact_widget));
+	if (choice < 0)
+		return TRUE;
+
+	dest_vol = g_list_nth_data (volumes, choice);
+	if (!G_IS_MOUNT (dest_vol))
+		return TRUE;
+	vol_root = g_mount_get_root (dest_vol);
+	vol_uri = g_file_get_uri (vol_root);
+
+	for (l = file_list; l != NULL; l = l->next) {
+		GFile *source;
+
+		source = g_file_new_for_commandline_arg (l->data);
+
+		copy_fobject (source, vol_root);
+
+		g_object_unref (source);
+	}
+
+	g_object_unref (vol_root);
+	g_free (vol_uri);
+
+	return TRUE;
+}
+
+static gboolean
+destroy (NstPlugin *plugin)
+{
+	g_list_foreach (volumes, (GFunc)g_object_unref, NULL);
+	g_list_free (volumes);
+
+	g_object_unref (vol_monitor);
+	return TRUE;
+}
+
+static
+NstPluginInfo plugin_info = {
+	"folder-remote",
+	"folder-remote",
+	N_("Mounted volumes"),
+	FALSE,
+	init,
+	get_contacts_widget,
+	NULL,
+	send_files,
+	destroy
+};
+
+NST_INIT_PLUGIN (plugin_info)
+
+
