diff --git a/gtk2_ardour/editor_regions.cc b/gtk2_ardour/editor_regions.cc
index 69620d4..939d04a 100644
--- a/gtk2_ardour/editor_regions.cc
+++ b/gtk2_ardour/editor_regions.cc
@@ -457,14 +457,16 @@ EditorRegions::remove_unused_regions ()
 	prompt  = _("Do you really want to remove unused regions?"
 		    "\n(This is destructive and cannot be undone)");
 
-	choices.push_back (_("No, do nothing."));
-	choices.push_back (_("Yes, remove."));
+	choices.push_back (_("Do nothing."));
+	choices.push_back (_("Remove all."));
+	choices.push_back (_("Remove if not whole file."));
 
 	Gtkmm2ext::Choice prompter (_("Remove unused regions"), prompt, choices);
 
-	if (prompter.run () == 1) {
+    int response_id = prompter.run();
+	if (response_id > 0) {
 		_no_redisplay = true;
-		_session->cleanup_regions ();
+		_session->cleanup_regions (response_id == 2);
 		_no_redisplay = false;
 		redisplay ();
 	}
diff --git a/libs/ardour/ardour/session.h b/libs/ardour/ardour/session.h
index 38185a7..03f43ac 100644
--- a/libs/ardour/ardour/session.h
+++ b/libs/ardour/ardour/session.h
@@ -524,6 +524,7 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
 
 	/* region info  */
 
+	bool has_children (boost::shared_ptr<Region const> parent) const;
 	boost::shared_ptr<Region> find_whole_file_parent (boost::shared_ptr<Region const>) const;
 
 	std::string path_from_region_name (DataType type, std::string name, std::string identifier);
@@ -549,7 +550,7 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
 	void add_source (boost::shared_ptr<Source>);
 	void remove_source (boost::weak_ptr<Source>);
 
-	void  cleanup_regions();
+	void  cleanup_regions(bool keep_whole_files);
 	int  cleanup_sources (CleanupReport&);
 	int  cleanup_trash_sources (CleanupReport&);
 
diff --git a/libs/ardour/session.cc b/libs/ardour/session.cc
index 1de5730..4c28751 100644
--- a/libs/ardour/session.cc
+++ b/libs/ardour/session.cc
@@ -3122,6 +3122,31 @@ Session::playlist_regions_extended (list<Evoral::Range<framepos_t> > const & ran
 
 /* Region management */
 
+bool
+Session::has_children (boost::shared_ptr<Region const> parent) const
+{
+	assert(parent->whole_file());
+	const RegionFactory::RegionMap& regions (RegionFactory::regions());
+	RegionFactory::RegionMap::const_iterator i;
+	boost::shared_ptr<Region> region;
+
+	Glib::Threads::Mutex::Lock lm (region_lock);
+
+	for (i = regions.begin(); i != regions.end(); ++i) {
+
+		region = i->second;
+
+		if (!region->whole_file()) {
+
+			if (parent->source_equivalent (region)) {
+				return true;
+			}
+		}
+	}
+
+	return false;
+}
+
 boost::shared_ptr<Region>
 Session::find_whole_file_parent (boost::shared_ptr<Region const> child) const
 {
diff --git a/libs/ardour/session_state.cc b/libs/ardour/session_state.cc
index ffbe55a..e02a70f 100644
--- a/libs/ardour/session_state.cc
+++ b/libs/ardour/session_state.cc
@@ -2557,18 +2557,30 @@ Session::ask_about_playlist_deletion (boost::shared_ptr<Playlist> p)
 }
 
 void
-Session::cleanup_regions ()
+Session::cleanup_regions (bool keep_whole_files)
 {
 	const RegionFactory::RegionMap& regions (RegionFactory::regions());
 
+	/* First pass: cleanup non-whole-file regions (or everything, is keep_whole_files == false) */
 	for (RegionFactory::RegionMap::const_iterator i = regions.begin(); i != regions.end(); ++i) {
 
 		uint32_t used = playlists->region_use_count (i->second);
 
-		if (used == 0 && !i->second->automatic ()) {
+		if (used == 0 && !i->second->automatic () && !(keep_whole_files && i->second->whole_file())) {
 			RegionFactory::map_remove (i->second);
 		}
 	}
+	if (keep_whole_files) {
+		/* Second pass: cleanup whole-file regions that have no children */
+		for (RegionFactory::RegionMap::const_iterator i = regions.begin(); i != regions.end(); ++i) {
+
+			uint32_t used = playlists->region_use_count (i->second);
+
+			if (used == 0 && !i->second->automatic () && i->second->whole_file() && !has_children(i->second)) {
+				RegionFactory::map_remove (i->second);
+			}
+		}
+	}
 
 	/* dump the history list */
 	_history.clear ();
