diff --git a/plugins/audiocd/audiocd-ui.xml b/plugins/audiocd/audiocd-ui.xml
index f90439b..7b5ea16 100644
--- a/plugins/audiocd/audiocd-ui.xml
+++ b/plugins/audiocd/audiocd-ui.xml
@@ -1,6 +1,8 @@
 <ui>
   <popup name="AudioCdSourcePopup">
-    <menuitem name="AudioCdSourcePopupCopyAllTracks" action="RemovableSourceCopyAllTracks"/>
+    <menuitem name="AudioCdSourcePopupSelectAll" action="AudioCdSelectAll"/>
+    <menuitem name="AudioCdSourcePopupDeselectAll" action="AudioCdDeselectAll"/>
+    <menuitem name="AudioCdSourcePopupCopyAllTracks" action="AudioCdCopyTracks"/>
     <placeholder name="PluginPlaceholder"/>
     <menuitem name="AudioCdSourcePopupEjectCd" action="RemovableSourceEject"/>
   </popup>
diff --git a/plugins/audiocd/rb-audiocd-plugin.c b/plugins/audiocd/rb-audiocd-plugin.c
index 1484cde..83cffd0 100644
--- a/plugins/audiocd/rb-audiocd-plugin.c
+++ b/plugins/audiocd/rb-audiocd-plugin.c
@@ -65,6 +65,7 @@ typedef struct
 
 	RBShell    *shell;
 	guint       ui_merge_id;
+	GtkActionGroup *actions;
 
 	GHashTable *sources;
 	char       *playing_uri;
@@ -84,8 +85,24 @@ static void rb_audiocd_plugin_finalize (GObject *object);
 static void impl_activate (RBPlugin *plugin, RBShell *shell);
 static void impl_deactivate (RBPlugin *plugin, RBShell *shell);
 
+static void copy_tracks_cmd (GtkAction *action, RBAudioCdPlugin *plugin);
+static void select_all_cmd (GtkAction *action, RBAudioCdPlugin *plugin);
+static void deselect_all_cmd (GtkAction *action, RBAudioCdPlugin *plugin);
+
 RB_PLUGIN_REGISTER(RBAudioCdPlugin, rb_audiocd_plugin)
 
+static GtkActionEntry rb_audiocd_plugin_actions[] = {
+	{ "AudioCdCopyTracks", GTK_STOCK_CDROM, N_("_Extract to Library"), NULL,
+	  N_("Copy tracks to the library"),
+	  G_CALLBACK (copy_tracks_cmd) },
+	{ "AudioCdSelectAll", NULL, N_("_Select All Tracks"), NULL,
+	  N_("Select all tracks for extraction"),
+	  G_CALLBACK (select_all_cmd) },
+	{ "AudioCdDeselectAll", NULL, N_("_Deselect All Tracks"), NULL,
+	  N_("Deselect all tracks for extraction"),
+	  G_CALLBACK (deselect_all_cmd) },
+};
+
 static void
 rb_audiocd_plugin_class_init (RBAudioCdPluginClass *klass)
 {
@@ -249,7 +266,7 @@ create_source_cb (RBRemovableMediaManager *rmm,
 
 		volume = g_mount_get_volume (mount);
 		if (volume != NULL) {
-			source = RB_SOURCE (rb_audiocd_source_new (RB_PLUGIN (plugin), plugin->shell, volume));
+			source = rb_audiocd_source_new (RB_PLUGIN (plugin), plugin->shell, plugin->actions, volume);
 			g_object_unref (volume);
 		}
 	}
@@ -287,6 +304,24 @@ impl_activate (RBPlugin *plugin,
 		      "ui-manager", &uimanager,
 		      NULL);
 
+	if (pi->actions == NULL) {
+		GtkAction *action;
+
+		pi->actions = gtk_action_group_new ("AudioCdActions");
+		gtk_action_group_set_translation_domain (pi->actions, GETTEXT_PACKAGE);
+		gtk_action_group_add_actions (pi->actions,
+					      rb_audiocd_plugin_actions,
+					      G_N_ELEMENTS (rb_audiocd_plugin_actions),
+					      pi);
+
+		action = gtk_action_group_get_action (pi->actions,
+						      "AudioCdCopyTracks");
+		/* Translators: this is the toolbar button label
+		   for Copy to Library action. */
+		g_object_set (G_OBJECT (action), "short-label", _("Extract"), NULL);
+	}
+	gtk_ui_manager_insert_action_group (uimanager, pi->actions, 0);
+
 	filename = rb_plugin_find_file (plugin, "audiocd-ui.xml");
 	if (filename != NULL) {
 		pi->ui_merge_id = gtk_ui_manager_add_ui_from_file (uimanager,
@@ -386,7 +421,57 @@ impl_deactivate	(RBPlugin *bplugin,
 		gtk_ui_manager_remove_ui (uimanager, plugin->ui_merge_id);
 		plugin->ui_merge_id = 0;
 	}
+	gtk_ui_manager_remove_action_group (uimanager, plugin->actions);
 
 	g_object_unref (uimanager);
 	g_object_unref (rmm);
 }
+
+static void
+copy_tracks_cmd (GtkAction *action, RBAudioCdPlugin *plugin)
+{
+	RBSource *source;
+
+	g_object_get (plugin->shell, "selected-source", &source, NULL);
+	if (RB_IS_AUDIOCD_SOURCE (source) == FALSE) {
+		rb_debug ("audiocd copy tracks command called for non-audiocd source");
+		g_object_unref (source);
+		return;
+	}
+
+	rb_audiocd_source_copy_tracks (RB_AUDIOCD_SOURCE (source));
+	g_object_unref (source);
+}
+
+static void
+select_all_cmd (GtkAction *action, RBAudioCdPlugin *plugin)
+{
+	RBSource *source;
+
+	g_object_get (plugin->shell, "selected-source", &source, NULL);
+	if (RB_IS_AUDIOCD_SOURCE (source) == FALSE) {
+		rb_debug ("audiocd select all command called for non-audiocd source");
+		g_object_unref (source);
+		return;
+	}
+
+	rb_audiocd_source_select_all_tracks (RB_AUDIOCD_SOURCE (source), TRUE);
+	g_object_unref (source);
+}
+
+static void
+deselect_all_cmd (GtkAction *action, RBAudioCdPlugin *plugin)
+{
+	RBSource *source;
+
+	g_object_get (plugin->shell, "selected-source", &source, NULL);
+	if (RB_IS_AUDIOCD_SOURCE (source) == FALSE) {
+		rb_debug ("audiocd deselect all command called for non-audiocd source");
+		g_object_unref (source);
+		return;
+	}
+
+	rb_audiocd_source_select_all_tracks (RB_AUDIOCD_SOURCE (source), FALSE);
+	g_object_unref (source);
+}
+
diff --git a/plugins/audiocd/rb-audiocd-source.c b/plugins/audiocd/rb-audiocd-source.c
index 899f072..61832d6 100644
--- a/plugins/audiocd/rb-audiocd-source.c
+++ b/plugins/audiocd/rb-audiocd-source.c
@@ -59,7 +59,8 @@
 enum
 {
 	PROP_0,
-	PROP_SEARCH_TYPE
+	PROP_SEARCH_TYPE,
+	PROP_ACTION_GROUP
 };
 
 static void rb_audiocd_source_dispose (GObject *object);
@@ -91,6 +92,22 @@ static gboolean update_genre_cb (GtkWidget *widget, GdkEventFocus *event, RBAudi
 static gboolean update_year_cb (GtkWidget *widget, GdkEventFocus *event, RBAudioCdSource *source);
 static gboolean update_disc_number_cb (GtkWidget *widget, GdkEventFocus *event, RBAudioCdSource *source);
 
+static void extract_cell_data_func (GtkTreeViewColumn *column,
+				    GtkCellRenderer *renderer,
+				    GtkTreeModel *model,
+				    GtkTreeIter *iter,
+				    RBAudioCdSource *source);
+static void extract_toggled_cb (GtkCellRendererToggle *renderer,
+				char *path,
+				RBAudioCdSource *source);
+
+static void update_select_actions (RBAudioCdSource *source);
+
+typedef struct
+{
+	gboolean extract;
+} RBAudioCDEntryData;
+
 typedef struct
 {
 	gchar *device_path;
@@ -111,6 +128,8 @@ typedef struct
 #ifdef HAVE_SJ_METADATA_GETTER
 	SjMetadataGetter *metadata;
 #endif
+
+	GtkActionGroup *action_group;
 } RBAudioCdSourcePrivate;
 
 RB_PLUGIN_DEFINE_TYPE (RBAudioCdSource, rb_audiocd_source, RB_TYPE_REMOVABLE_MEDIA_SOURCE)
@@ -167,6 +186,14 @@ rb_audiocd_source_class_init (RBAudioCdSourceClass *klass)
 					  PROP_SEARCH_TYPE,
 					  "search-type");
 
+	g_object_class_install_property (object_class,
+					 PROP_ACTION_GROUP,
+					 g_param_spec_object ("action-group",
+							      "action-group",
+							      "action group",
+							      GTK_TYPE_ACTION_GROUP,
+							      G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+
 	g_type_class_add_private (klass, sizeof (RBAudioCdSourcePrivate));
 }
 
@@ -210,9 +237,12 @@ rb_audiocd_source_constructor (GType type,
 {
 	RBAudioCdSource *source;
 	RBEntryView *entry_view;
+	GtkCellRenderer *renderer;
+	GtkTreeViewColumn *extract;
 	RhythmDB *db;
 	RBPlugin *plugin;
 	char *ui_file;
+	int toggle_width;
 
 	source = RB_AUDIOCD_SOURCE (G_OBJECT_CLASS (rb_audiocd_source_parent_class)->
 			constructor (type, n_construct_properties, construct_properties));
@@ -223,6 +253,25 @@ rb_audiocd_source_constructor (GType type,
 	entry_view = rb_source_get_entry_view (RB_SOURCE (source));
 	rb_entry_view_set_sorting_order (entry_view, "Track", GTK_SORT_ASCENDING);
 
+	/* create the 'extract' column */
+	renderer = gtk_cell_renderer_toggle_new ();
+	extract = gtk_tree_view_column_new ();
+	gtk_tree_view_column_pack_start (extract, renderer, FALSE);
+	gtk_tree_view_column_set_cell_data_func (extract,
+						 renderer,
+						 (GtkTreeCellDataFunc) extract_cell_data_func,
+						 source,
+						 NULL);
+	g_signal_connect_object (renderer, "toggled", G_CALLBACK (extract_toggled_cb), source, 0);
+
+	/* set column width */
+	gtk_cell_renderer_get_size (renderer, GTK_WIDGET (entry_view), NULL, NULL, NULL, &toggle_width, NULL);
+	gtk_tree_view_column_set_sizing (extract, GTK_TREE_VIEW_COLUMN_FIXED);
+	gtk_tree_view_column_set_fixed_width (extract, toggle_width + 5);
+
+	rb_entry_view_insert_column_custom (entry_view, extract, "", "Extract", NULL, NULL, NULL, 1);
+	gtk_widget_set_tooltip_text (GTK_WIDGET (extract->button), _("Select tracks to be extracted"));
+
 	/* hide the 'album' column */
 	gtk_tree_view_column_set_visible (rb_entry_view_get_column (entry_view, RB_ENTRY_VIEW_COL_ALBUM), FALSE);
 
@@ -279,9 +328,10 @@ rb_audiocd_source_constructor (GType type,
 	return G_OBJECT (source);
 }
 
-RBRemovableMediaSource *
+RBSource *
 rb_audiocd_source_new (RBPlugin *plugin,
 		       RBShell *shell,
+		       GtkActionGroup *actions,
 		       GVolume *volume)
 {
 	GObject *source;
@@ -303,6 +353,7 @@ rb_audiocd_source_new (RBPlugin *plugin,
 	entry_type->can_sync_metadata = (RhythmDBEntryCanSyncFunc)rb_true_function;
 	/* TODO save the metadata somewhere */
 	entry_type->sync_metadata = (RhythmDBEntrySyncFunc)rb_null_function;
+	entry_type->entry_type_data_size = sizeof(RBAudioCDEntryData);
 
 	source = g_object_new (RB_TYPE_AUDIOCD_SOURCE,
 			       "entry-type", entry_type,
@@ -311,20 +362,26 @@ rb_audiocd_source_new (RBPlugin *plugin,
 			       "sorting-key", NULL,
 			       "source-group", RB_SOURCE_GROUP_DEVICES,
 			       "plugin", plugin,
+			       "action-group", actions,
 			       NULL);
 
 	rb_shell_register_entry_type_for_source (shell, RB_SOURCE (source), entry_type);
 
-	return RB_REMOVABLE_MEDIA_SOURCE (source);
+	return RB_SOURCE (source);
 }
 
 static void
 impl_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
 {
+	RBAudioCdSourcePrivate *priv = AUDIOCD_SOURCE_GET_PRIVATE (object);
+
 	switch (prop_id) {
 	case PROP_SEARCH_TYPE:
 		/* ignored */
 		break;
+	case PROP_ACTION_GROUP:
+		priv->action_group = g_value_get_object (value);
+		break;
 	default:
 		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 		break;
@@ -334,10 +391,14 @@ impl_set_property (GObject *object, guint prop_id, const GValue *value, GParamSp
 static void
 impl_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
 {
+	RBAudioCdSourcePrivate *priv = AUDIOCD_SOURCE_GET_PRIVATE (object);
 	switch (prop_id) {
 	case PROP_SEARCH_TYPE:
 		g_value_set_enum (value, RB_SOURCE_SEARCH_NONE);
 		break;
+	case PROP_ACTION_GROUP:
+		g_value_set_object (value, priv->action_group);
+		break;
 	default:
 		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 		break;
@@ -393,6 +454,7 @@ rb_audiocd_create_track_entry (RBAudioCdSource *source,
 	GValue value = {0, };
 	gchar *str;
 	RhythmDBEntryType entry_type;
+	RBAudioCDEntryData *extra_data;
 
 	audio_path = g_strdup_printf ("cdda://%d#%s", track_number, priv->device_path);
 
@@ -440,6 +502,9 @@ rb_audiocd_create_track_entry (RBAudioCdSource *source,
 	entry_set_string_prop (db, entry, FALSE, RHYTHMDB_PROP_GENRE, NULL);
 	entry_set_string_prop (db, entry, FALSE, RHYTHMDB_PROP_MIMETYPE, "audio/x-raw-int");
 
+	extra_data = RHYTHMDB_ENTRY_GET_TYPE_DATA (entry, RBAudioCDEntryData);
+	extra_data->extract = TRUE;
+
 	rhythmdb_commit (db);
 	g_free (audio_path);
 
@@ -939,7 +1004,7 @@ impl_get_ui_actions (RBSource *source)
 {
 	GList *actions = NULL;
 
-	actions = g_list_prepend (actions, g_strdup ("RemovableSourceCopyAllTracks"));
+	actions = g_list_prepend (actions, g_strdup ("AudioCdCopyTracks"));
 	actions = g_list_prepend (actions, g_strdup ("RemovableSourceEject"));
 
 	return actions;
@@ -1126,3 +1191,167 @@ update_disc_number_cb (GtkWidget *widget, GdkEventFocus *event, RBAudioCdSource
 	return FALSE;
 }
 
+static void
+extract_cell_data_func (GtkTreeViewColumn *column,
+			GtkCellRenderer *renderer,
+			GtkTreeModel *tree_model,
+			GtkTreeIter *iter,
+			RBAudioCdSource *source)
+{
+	RBAudioCDEntryData *extra_data;
+	RhythmDBEntry *entry;
+
+	entry = rhythmdb_query_model_iter_to_entry (RHYTHMDB_QUERY_MODEL (tree_model), iter);
+	if (entry != NULL) {
+		extra_data = RHYTHMDB_ENTRY_GET_TYPE_DATA (entry, RBAudioCDEntryData);
+		gtk_cell_renderer_toggle_set_active (GTK_CELL_RENDERER_TOGGLE (renderer), extra_data->extract);
+		rhythmdb_entry_unref (entry);
+	}
+}
+
+static void
+update_select_actions (RBAudioCdSource *source)
+{
+	RBAudioCdSourcePrivate *priv = AUDIOCD_SOURCE_GET_PRIVATE (source);
+	RhythmDBQueryModel *model;
+	RBAudioCDEntryData *extra_data;
+	GtkTreeIter iter;
+	GtkAction *action;
+	int selected_tracks = 0;
+	int unselected_tracks = 0;
+
+	/* count selected and unselected tracks */
+	g_object_get (source, "query-model", &model, NULL);
+	if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (model), &iter)) {
+		do {
+			RhythmDBEntry *entry;
+			entry = rhythmdb_query_model_iter_to_entry (model, &iter);
+			extra_data = RHYTHMDB_ENTRY_GET_TYPE_DATA (entry, RBAudioCDEntryData);
+			if (extra_data->extract) {
+				selected_tracks++;
+			} else {
+				unselected_tracks++;
+			}
+		} while (gtk_tree_model_iter_next (GTK_TREE_MODEL (model), &iter));
+	}
+
+	g_object_unref (model);
+
+	/* update the sensitivity of the actions accordingly */
+	action = gtk_action_group_get_action (priv->action_group, "AudioCdSelectAll");
+	gtk_action_set_sensitive (action, (unselected_tracks > 0));
+
+	action = gtk_action_group_get_action (priv->action_group, "AudioCdDeselectAll");
+	gtk_action_set_sensitive (action, (selected_tracks > 0));
+}
+
+static void
+extract_toggled_cb (GtkCellRendererToggle *renderer, char *path_str, RBAudioCdSource *source)
+{
+	RhythmDBQueryModel *model;
+	GtkTreePath *path;
+	GtkTreeIter iter;
+
+	g_object_get (source, "query-model", &model, NULL);
+
+	path = gtk_tree_path_new_from_string (path_str);
+	if (gtk_tree_model_get_iter (GTK_TREE_MODEL (model), &iter, path)) {
+		RhythmDBEntry *entry;
+
+		entry = rhythmdb_query_model_iter_to_entry (model, &iter);
+		if (entry != NULL) {
+			RBAudioCDEntryData *extra_data;
+
+			extra_data = RHYTHMDB_ENTRY_GET_TYPE_DATA (entry, RBAudioCDEntryData);
+			extra_data->extract = !extra_data->extract;
+			rhythmdb_entry_unref (entry);
+
+			gtk_tree_model_row_changed (GTK_TREE_MODEL (model), path, &iter);
+
+			update_select_actions (source);
+		}
+	}
+	gtk_tree_path_free (path);
+	g_object_unref (model);
+}
+
+static gboolean
+copy_entry (RhythmDBQueryModel *model,
+	    GtkTreePath *path,
+	    GtkTreeIter *iter,
+	    GList **list)
+{
+	RBAudioCDEntryData *extra_data;
+	RhythmDBEntry *entry;
+	GList *l;
+
+	entry = rhythmdb_query_model_iter_to_entry (model, iter);
+	extra_data = RHYTHMDB_ENTRY_GET_TYPE_DATA (entry, RBAudioCDEntryData);
+	if (extra_data->extract) {
+		rb_debug ("adding track %s to transfer list",
+			  rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_LOCATION));
+		l = g_list_append (*list, entry);
+		*list = l;
+	} else {
+		rb_debug ("skipping track %s",
+			  rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_LOCATION));
+		rhythmdb_entry_unref (entry);
+	}
+	return FALSE;
+}
+
+void
+rb_audiocd_source_copy_tracks (RBAudioCdSource *source)
+{
+	RBShell *shell;
+	RBSource *library;
+	RhythmDBQueryModel *model;
+	GList *list = NULL;
+
+	g_object_get (source, "shell", &shell, NULL);
+	g_object_get (shell, "library-source", &library, NULL);
+	g_object_unref (shell);
+
+	g_object_get (source, "query-model", &model, NULL);
+
+	gtk_tree_model_foreach (GTK_TREE_MODEL (model), (GtkTreeModelForeachFunc)copy_entry, &list);
+	if (list != NULL) {
+		rb_source_paste (library, list);
+		g_list_free (list);
+	}
+
+	g_object_unref (model);
+	g_object_unref (library);
+}
+
+static gboolean
+select_entry (RhythmDBQueryModel *model,
+	      GtkTreePath *path,
+	      GtkTreeIter *iter,
+	      gpointer yesno)
+{
+	RBAudioCDEntryData *extra_data;
+	RhythmDBEntry *entry;
+
+	entry = rhythmdb_query_model_iter_to_entry (model, iter);
+	extra_data = RHYTHMDB_ENTRY_GET_TYPE_DATA (entry, RBAudioCDEntryData);
+	extra_data->extract = (yesno != NULL);
+
+	gtk_tree_model_row_changed (GTK_TREE_MODEL (model), path, iter);
+	return FALSE;
+}
+
+void
+rb_audiocd_source_select_all_tracks (RBAudioCdSource *source, gboolean select)
+{
+	RhythmDBQueryModel *model;
+	g_object_get (source, "query-model", &model, NULL);
+
+	gtk_tree_model_foreach (GTK_TREE_MODEL (model),
+				(GtkTreeModelForeachFunc)select_entry,
+				GINT_TO_POINTER (select));
+	g_object_unref (model);
+
+	update_select_actions (source);
+}
+
diff --git a/plugins/audiocd/rb-audiocd-source.h b/plugins/audiocd/rb-audiocd-source.h
index 000cc54..a4f3376 100644
--- a/plugins/audiocd/rb-audiocd-source.h
+++ b/plugins/audiocd/rb-audiocd-source.h
@@ -53,14 +53,18 @@ typedef struct
 	RBRemovableMediaSourceClass parent;
 } RBAudioCdSourceClass;
 
-RBRemovableMediaSource *	rb_audiocd_source_new		(RBPlugin *plugin,
+RBSource *		rb_audiocd_source_new			(RBPlugin *plugin,
 								 RBShell  *shell,
+								 GtkActionGroup *actions,
 								 GVolume  *volume);
 GType			rb_audiocd_source_get_type		(void);
 GType			rb_audiocd_source_register_type		(GTypeModule *module);
 
 gboolean		rb_audiocd_is_mount_audiocd		(GMount *mount);
 
+void			rb_audiocd_source_copy_tracks		(RBAudioCdSource *source);
+void			rb_audiocd_source_select_all_tracks	(RBAudioCdSource *source, gboolean select);
+
 G_END_DECLS
 
 #endif /* __RB_AUDIOCD_SOURCE_H */
diff --git a/shell/rb-removable-media-manager.c b/shell/rb-removable-media-manager.c
index 9c93602..02ad6e8 100644
--- a/shell/rb-removable-media-manager.c
+++ b/shell/rb-removable-media-manager.c
@@ -92,8 +92,6 @@ static void mount_added_cb (GVolumeMonitor *monitor, GMount *mount, RBRemovableM
 static void mount_removed_cb (GVolumeMonitor *monitor, GMount *mount, RBRemovableMediaManager *manager);
 
 static void do_transfer (RBRemovableMediaManager *manager);
-static void rb_removable_media_manager_cmd_copy_tracks (GtkAction *action,
-							RBRemovableMediaManager *mgr);
 
 typedef struct
 {
@@ -150,9 +148,6 @@ static GtkActionEntry rb_removable_media_manager_actions [] =
 	{ "RemovableSourceEject", GNOME_MEDIA_EJECT, N_("_Eject"), NULL,
 	  N_("Eject this medium"),
 	  G_CALLBACK (rb_removable_media_manager_cmd_eject_medium) },
-	{ "RemovableSourceCopyAllTracks", GTK_STOCK_CDROM, N_("_Extract to Library"), NULL,
-	  N_("Copy all tracks to the library"),
-	  G_CALLBACK (rb_removable_media_manager_cmd_copy_tracks) },
 	{ "MusicScanMedia", NULL, N_("_Scan Removable Media"), NULL,
 	  N_("Scan for new Removable Media"),
 	  G_CALLBACK (rb_removable_media_manager_cmd_scan_media) },
@@ -672,7 +667,6 @@ rb_removable_media_manager_set_uimanager (RBRemovableMediaManager *mgr,
 					  GtkUIManager *uimanager)
 {
 	RBRemovableMediaManagerPrivate *priv = GET_PRIVATE (mgr);
-	GtkAction *action;
 
 	if (priv->uimanager != NULL) {
 		if (priv->actiongroup != NULL) {
@@ -702,13 +696,6 @@ rb_removable_media_manager_set_uimanager (RBRemovableMediaManager *mgr,
 	gtk_ui_manager_insert_action_group (priv->uimanager,
 					    priv->actiongroup,
 					    0);
-
-	action = gtk_action_group_get_action (priv->actiongroup,
-					      "RemovableSourceCopyAllTracks");
-	/* Translators: this is the toolbar button label
-	   for Copy to Library action. */
-	g_object_set (G_OBJECT (action), "short-label", _("Extract"), NULL);
-
 }
 
 static void
@@ -1081,35 +1068,3 @@ rb_removable_media_manager_queue_transfer (RBRemovableMediaManager *manager,
 	do_transfer (manager);
 }
 
-static gboolean
-copy_entry (RhythmDBQueryModel *model,
-	    GtkTreePath *path,
-	    GtkTreeIter *iter,
-	    GList **list)
-{
-	GList *l;
-	l = g_list_append (*list, rhythmdb_query_model_iter_to_entry (model, iter));
-	*list = l;
-	return FALSE;
-}
-
-static void
-rb_removable_media_manager_cmd_copy_tracks (GtkAction *action, RBRemovableMediaManager *mgr)
-{
-	RBRemovableMediaManagerPrivate *priv = GET_PRIVATE (mgr);
-	RBRemovableMediaSource *source;
-	RBLibrarySource *library;
-	RhythmDBQueryModel *model;
-	GList *list = NULL;
-
-	source = RB_REMOVABLE_MEDIA_SOURCE (priv->selected_source);
-	g_object_get (source, "query-model", &model, NULL);
-	g_object_get (priv->shell, "library-source", &library, NULL);
-
-	gtk_tree_model_foreach (GTK_TREE_MODEL (model), (GtkTreeModelForeachFunc)copy_entry, &list);
-	rb_source_paste (RB_SOURCE (library), list);
-	g_list_free (list);
-
-	g_object_unref (model);
-	g_object_unref (library);
-}
