Index: gtk2_ardour/editor_ops.cc
===================================================================
--- gtk2_ardour/editor_ops.cc	(revision 3300)
+++ gtk2_ardour/editor_ops.cc	(working copy)
@@ -196,6 +196,56 @@
 }
 
 void
+Editor::remove_region ()
+{
+
+	RegionSelection rs; 
+	get_regions_for_action (rs);
+	
+	if (!session) {
+		return;
+	}
+
+	if (rs.empty()) {
+		cerr << "rs.empty()" << endl;
+		return;
+	}
+
+	begin_reversible_command (_("remove region"));
+
+	list<boost::shared_ptr<Region> > regions_to_remove;
+
+	for (RegionSelection::iterator i = rs.begin(); i != rs.end(); ++i) {
+		// we can't just remove the region(s) in this loop because
+		// this removes them from the RegionSelection, and they thus
+		// disappear from underneath the iterator, and the ++i above
+		// SEGVs in a puzzling fashion.
+
+		// so, first iterate over the regions to be removed from rs and
+		// add them to the regions_to_remove list, and then
+		// iterate over the list to actually remove them.
+	        
+		regions_to_remove.push_back ((*i)->region());
+	}
+	
+	for (list<boost::shared_ptr<Region> >::iterator rl = regions_to_remove.begin(); rl != regions_to_remove.end(); ++rl) {
+		boost::shared_ptr<Playlist> playlist = (*rl)->playlist();
+	        if (!playlist) {
+			// is this check necessary?
+			cerr << "(*i)->region()->playlist() is NULL!" << endl;
+	        	continue;
+	        }
+
+	        XMLNode &before = playlist->get_state();
+		playlist->remove_region (*rl);
+	        XMLNode &after = playlist->get_state();
+		session->add_command(new MementoCommand<Playlist>(*playlist, &before, &after));
+	}
+	commit_reversible_command ();
+}
+
+#if 0
+void
 Editor::destroy_clicked_region ()
 {
 	uint32_t selected = selection->regions.size();
@@ -237,6 +287,7 @@
 		session->destroy_regions (r);
 	} 
 }
+#endif
 
 boost::shared_ptr<Region>
 Editor::select_region_for_operation (int dir, TimeAxisView **tv)
@@ -3136,15 +3187,23 @@
 void
 Editor::remove_region_sync ()
 {
-	if (clicked_regionview) {
-		boost::shared_ptr<Region> region (clicked_regionview->region());
-		begin_reversible_command (_("remove sync"));
-                XMLNode &before = region->playlist()->get_state();
-		region->clear_sync_position ();
-                XMLNode &after = region->playlist()->get_state();
-		session->add_command(new MementoCommand<Playlist>(*(region->playlist()), &before, &after));
-		commit_reversible_command ();
+	RegionSelection rs; 
+
+	get_regions_for_action (rs);
+
+	if (rs.empty()) {
+		return;
 	}
+
+	begin_reversible_command (_("remove sync"));
+	for (RegionSelection::iterator i = rs.begin(); i != rs.end(); ++i) {
+
+                XMLNode &before = (*i)->region()->playlist()->get_state();
+		(*i)->region()->clear_sync_position ();
+                XMLNode &after = (*i)->region()->playlist()->get_state();
+		session->add_command(new MementoCommand<Playlist>(*((*i)->region()->playlist()), &before, &after));
+	}
+	commit_reversible_command ();
 }
 
 void
@@ -4433,6 +4492,7 @@
 void
 Editor::external_edit_region ()
 {
+	// XXX shouldn't this use get_regions_for_action(rs) too?	
 	if (!clicked_regionview) {
 		return;
 	}
Index: gtk2_ardour/editor.cc
===================================================================
--- gtk2_ardour/editor.cc	(revision 3300)
+++ gtk2_ardour/editor.cc	(working copy)
@@ -1599,8 +1599,16 @@
 		
 		if ((ds = atv->get_diskstream()) && ((pl = ds->playlist()))) {
 			Playlist::RegionList* regions = pl->regions_at ((nframes_t) floor ( (double)frame * ds->speed()));
-			for (Playlist::RegionList::iterator i = regions->begin(); i != regions->end(); ++i) {
-				add_region_context_items (atv->audio_view(), (*i), edit_items);
+			if (selection->regions.size() > 1) {
+				// there's already a multiple selection: just add a 
+				// single region context menu that will act on all 
+				// selected regions
+				boost::shared_ptr<Region> dummy_region; // = NULL		
+				add_region_context_items (atv->audio_view(), dummy_region, edit_items);			
+			} else {
+				for (Playlist::RegionList::iterator i = regions->begin(); i != regions->end(); ++i) {
+					add_region_context_items (atv->audio_view(), (*i), edit_items);
+				}
 			}
 			delete regions;
 		}
@@ -1638,10 +1646,17 @@
 				add_crossfade_context_items (atv->audio_view(), (*i), edit_items, many);
 			}
 
-			for (Playlist::RegionList::iterator i = regions->begin(); i != regions->end(); ++i) {
-				add_region_context_items (atv->audio_view(), (*i), edit_items);
+			if (selection->regions.size() > 1) {
+				// there's already a multiple selection: just add a 
+				// single region context menu that will act on all 
+				// selected regions
+				boost::shared_ptr<Region> dummy_region; // = NULL		
+				add_region_context_items (atv->audio_view(), dummy_region, edit_items);			
+			} else {
+				for (Playlist::RegionList::iterator i = regions->begin(); i != regions->end(); ++i) {
+					add_region_context_items (atv->audio_view(), (*i), edit_items);
+				}
 			}
-
 			delete regions;
 		}
 	}
@@ -1772,18 +1787,27 @@
 	
 	boost::shared_ptr<AudioRegion> ar;
 
+	cerr << "add_region_context_items()" << endl;
+
 	if (region) {
 		ar = boost::dynamic_pointer_cast<AudioRegion> (region);
-	}
 
-	/* when this particular menu pops up, make the relevant region 
-	   become selected.
-	*/
+		/* when this particular menu pops up, make the relevant region 
+		   become selected.
+		*/
 
-	region_menu->signal_map_event().connect (bind (mem_fun(*this, &Editor::set_selected_regionview_from_map_event), sv, boost::weak_ptr<Region>(region)));
+		region_menu->signal_map_event().connect (
+			bind (
+				mem_fun(*this, &Editor::set_selected_regionview_from_map_event), 
+				sv, 
+				boost::weak_ptr<Region>(region)
+			)
+		);
 
-	items.push_back (MenuElem (_("Rename"), mem_fun(*this, &Editor::rename_region)));
-	items.push_back (MenuElem (_("Popup region editor"), mem_fun(*this, &Editor::edit_region)));
+		items.push_back (MenuElem (_("Rename"), mem_fun(*this, &Editor::rename_region)));
+		items.push_back (MenuElem (_("Popup region editor"), mem_fun(*this, &Editor::edit_region)));
+	}
+
 	items.push_back (MenuElem (_("Raise to top layer"), mem_fun(*this, &Editor::raise_region_to_top)));
 	items.push_back (MenuElem (_("Lower to bottom layer"), mem_fun  (*this, &Editor::lower_region_to_bottom)));
 	items.push_back (SeparatorElem());
@@ -1803,49 +1827,51 @@
 
 	sigc::connection fooc;
 
-	items.push_back (CheckMenuElem (_("Lock")));
-	CheckMenuItem* region_lock_item = static_cast<CheckMenuItem*>(&items.back());
-	if (region->locked()) {
-		region_lock_item->set_active();
-	}
-	region_lock_item->signal_activate().connect (mem_fun(*this, &Editor::toggle_region_lock));
+	if (region) {
+		items.push_back (CheckMenuElem (_("Lock")));
+		CheckMenuItem* region_lock_item = static_cast<CheckMenuItem*>(&items.back());
+		if (region->locked()) {
+			region_lock_item->set_active();
+		}
+		region_lock_item->signal_activate().connect (mem_fun(*this, &Editor::toggle_region_lock));
 
-	items.push_back (CheckMenuElem (_("Glue to Bars&Beats")));
-	CheckMenuItem* bbt_glue_item = static_cast<CheckMenuItem*>(&items.back());
+		items.push_back (CheckMenuElem (_("Glue to Bars&Beats")));
+		CheckMenuItem* bbt_glue_item = static_cast<CheckMenuItem*>(&items.back());
 
-	switch (region->positional_lock_style()) {
-	case Region::MusicTime:
-		bbt_glue_item->set_active (true);
-		break;
-	default:
-		bbt_glue_item->set_active (false);
-		break;
-	}
+		switch (region->positional_lock_style()) {
+		case Region::MusicTime:
+			bbt_glue_item->set_active (true);
+			break;
+		default:
+			bbt_glue_item->set_active (false);
+			break;
+		}
 
-	bbt_glue_item->signal_activate().connect (bind (mem_fun (*this, &Editor::set_region_lock_style), Region::MusicTime));
+		bbt_glue_item->signal_activate().connect (bind (mem_fun (*this, &Editor::set_region_lock_style), Region::MusicTime));
 
-	items.push_back (CheckMenuElem (_("Mute")));
-	CheckMenuItem* region_mute_item = static_cast<CheckMenuItem*>(&items.back());
-	fooc = region_mute_item->signal_activate().connect (mem_fun(*this, &Editor::toggle_region_mute));
-	if (region->muted()) {
-		fooc.block (true);
-		region_mute_item->set_active();
-		fooc.block (false);
-	}
-	
-	if (!Profile->get_sae()) {
-		items.push_back (CheckMenuElem (_("Opaque")));
-		CheckMenuItem* region_opaque_item = static_cast<CheckMenuItem*>(&items.back());
-		fooc = region_opaque_item->signal_activate().connect (mem_fun(*this, &Editor::toggle_region_opaque));
-		if (region->opaque()) {
+		items.push_back (CheckMenuElem (_("Mute")));
+		CheckMenuItem* region_mute_item = static_cast<CheckMenuItem*>(&items.back());
+		fooc = region_mute_item->signal_activate().connect (mem_fun(*this, &Editor::toggle_region_mute));
+		if (region->muted()) {
 			fooc.block (true);
-			region_opaque_item->set_active();
+			region_mute_item->set_active();
 			fooc.block (false);
 		}
+	
+		if (!Profile->get_sae()) {
+			items.push_back (CheckMenuElem (_("Opaque")));
+			CheckMenuItem* region_opaque_item = static_cast<CheckMenuItem*>(&items.back());
+			fooc = region_opaque_item->signal_activate().connect (mem_fun(*this, &Editor::toggle_region_opaque));
+			if (region->opaque()) {
+				fooc.block (true);
+				region_opaque_item->set_active();
+				fooc.block (false);
+			}
+		}
 	}
 
 	items.push_back (CheckMenuElem (_("Original position"), mem_fun(*this, &Editor::naturalize)));
-	if (region->at_natural_position()) {
+	if (region && region->at_natural_position()) {
 		items.back().set_sensitive (false);
 	}
 	
@@ -1933,7 +1959,7 @@
 	items.push_back (MenuElem (_("Multi-Duplicate"), (bind (mem_fun(*this, &Editor::duplicate_dialog), true))));
 	items.push_back (MenuElem (_("Fill Track"), (mem_fun(*this, &Editor::region_fill_track))));
 	items.push_back (SeparatorElem());
-	items.push_back (MenuElem (_("Remove"), mem_fun(*this, &Editor::remove_clicked_region)));
+	items.push_back (MenuElem (_("Remove"), mem_fun(*this, &Editor::remove_region)));
 
 	/* OK, stick the region submenu at the top of the list, and then add
 	   the standard items.
@@ -1944,7 +1970,7 @@
 	*/
 
 	string::size_type pos = 0;
-	string menu_item_name = region->name();
+	string menu_item_name = (region) ? region->name() : _("Selected regions");
 
 	while ((pos = menu_item_name.find ("_", pos)) != string::npos) {
 		menu_item_name.replace (pos, 1, "__");
Index: gtk2_ardour/editor.h
===================================================================
--- gtk2_ardour/editor.h	(revision 3300)
+++ gtk2_ardour/editor.h	(working copy)
@@ -995,8 +995,11 @@
 	void align_selection_relative (ARDOUR::RegionPoint point, nframes_t position, const RegionSelection&);
 	void align_region (boost::shared_ptr<ARDOUR::Region>, ARDOUR::RegionPoint point, nframes_t position);
 	void align_region_internal (boost::shared_ptr<ARDOUR::Region>, ARDOUR::RegionPoint point, nframes_t position);
+	void remove_region ();
 	void remove_clicked_region ();
+#if 0
 	void destroy_clicked_region ();
+#endif
 	void edit_region ();
 	void rename_region ();
 	void duplicate_some_regions (RegionSelection&, float times);

