diff --git a/language/codegen/applychangeswidget.cpp b/language/codegen/applychangeswidget.cpp
index 3b6f740..03835d7 100644
--- a/language/codegen/applychangeswidget.cpp
+++ b/language/codegen/applychangeswidget.cpp
@@ -105,6 +105,11 @@ ApplyChangesWidget::~ApplyChangesWidget()
     delete d;
 }
 
+bool ApplyChangesWidget::hasDocuments() const
+{
+    return d->m_editParts.size() > 0;
+}
+
 KTextEditor::Document* ApplyChangesWidget::document() const
 {
     return qobject_cast<KTextEditor::Document*>(d->m_editParts[d->m_index]);
@@ -159,7 +164,7 @@ void ApplyChangesWidgetPrivate::addItem(QStandardItemModel* mit, KTextEditor::Do
         edition.takeFirst();
     QStandardItem* it= new QStandardItem(edition.join("\n"));
     QStandardItem* action= new QStandardItem(type);
-    
+
     it->setData(qVariantFromValue(range));
     it->setEditable(false);
     action->setEditable(false);
diff --git a/language/codegen/applychangeswidget.h b/language/codegen/applychangeswidget.h
index 08aa59c..7f063fa 100644
--- a/language/codegen/applychangeswidget.h
+++ b/language/codegen/applychangeswidget.h
@@ -41,6 +41,8 @@ class KDEVPLATFORMLANGUAGE_EXPORT ApplyChangesWidget : public KDialog
         
         void setInformation(const QString& info);
 
+        bool hasDocuments() const;
+
         KTextEditor::Document* document() const;
         
         ///@param modified may be an artifial code representation (@ref KDevelop::InsertArtificialCodeRepresentation)
diff --git a/plugins/genericprojectmanager/genericmanager.cpp b/plugins/genericprojectmanager/genericmanager.cpp
index 0b94d40..f90bcb4 100644
--- a/plugins/genericprojectmanager/genericmanager.cpp
+++ b/plugins/genericprojectmanager/genericmanager.cpp
@@ -435,29 +435,24 @@ bool GenericProjectManager::rename(KDevelop::ProjectBaseItem* item, const KUrl&
     return false;
 }
 
-bool GenericProjectManager::removeFolder( KDevelop::ProjectFolderItem * folder )
+bool GenericProjectManager::removeFilesAndFolders(QList<KDevelop::ProjectBaseItem*> items)
 {
-    kDebug() << "removing folder" << folder->url();
-    KDevelop::ProjectFolderItem* parent = getParentFolder(folder);
-    stopWatcher(parent);
-    const bool success = KDevelop::removeUrl(parent->project(), folder->url(), true);
-    if ( success ) {
-        folder->parent()->removeRow( folder->row() );
-    }
-    continueWatcher(parent);
-    return success;
-}
+    bool success = true;
+    foreach(KDevelop::ProjectBaseItem* item, items)
+    {
+        Q_ASSERT(item->folder() || item->file());
 
-bool GenericProjectManager::removeFile( KDevelop::ProjectFileItem * file )
-{
-    kDebug() << "removing file" << file->url();
-    KDevelop::ProjectFolderItem* parent = getParentFolder(file);
-    stopWatcher(parent);
-    const bool success = KDevelop::removeUrl(file->project(), file->url(), false);
-    if ( success ) {
-        file->parent()->removeRow( file->row() );
+        KDevelop::ProjectFolderItem* parent = getParentFolder(item);
+        stopWatcher(parent);
+
+        success &= KDevelop::removeUrl(parent->project(), item->url(), true);
+        if ( success )
+            item->parent()->removeRow( item->row() );
+
+        continueWatcher(parent);
+        if ( !success )
+            break;
     }
-    continueWatcher(parent);
     return success;
 }
 
diff --git a/plugins/genericprojectmanager/genericmanager.h b/plugins/genericprojectmanager/genericmanager.h
index 5014a9a..c6ccb58 100644
--- a/plugins/genericprojectmanager/genericmanager.h
+++ b/plugins/genericprojectmanager/genericmanager.h
@@ -68,8 +68,7 @@ public:
 
     virtual KDevelop::ProjectFolderItem* addFolder( const KUrl& folder, KDevelop::ProjectFolderItem *parent );
     virtual KDevelop::ProjectFileItem* addFile( const KUrl& file, KDevelop::ProjectFolderItem *parent );
-    virtual bool removeFolder( KDevelop::ProjectFolderItem *folder );
-    virtual bool removeFile( KDevelop::ProjectFileItem *file );
+    virtual bool removeFilesAndFolders( QList<KDevelop::ProjectBaseItem*> items);
     virtual bool renameFolder( KDevelop::ProjectFolderItem *folder, const KUrl& url );
     virtual bool renameFile( KDevelop::ProjectFileItem *file, const KUrl& url );
 
diff --git a/plugins/genericprojectmanager/test/reloadtest.cpp b/plugins/genericprojectmanager/test/reloadtest.cpp
index 094db44..f4098fb 100644
--- a/plugins/genericprojectmanager/test/reloadtest.cpp
+++ b/plugins/genericprojectmanager/test/reloadtest.cpp
@@ -112,7 +112,7 @@ void ProjectLoadTest::addRemoveFiles()
 
     QCOMPARE(project->filesForUrl(path+"/blub"+QString::number(50)).count(), 1);
     KDevelop::ProjectFileItem* file = project->filesForUrl(path+"/blub"+QString::number(50)).first();
-    project->projectFileManager()->removeFile(file); //message box has to be accepted manually :(
+    project->projectFileManager()->removeFilesAndFolders(QList<KDevelop::ProjectBaseItem*>() << file ); //message box has to be accepted manually :(
     for (int i=51; i<100; ++i) {
         QFile f2(path+"/blub"+QString::number(i));
         f2.remove();
diff --git a/plugins/projectmanagerview/projectmanagerviewplugin.cpp b/plugins/projectmanagerview/projectmanagerviewplugin.cpp
index 00f068b..4544d1c 100644
--- a/plugins/projectmanagerview/projectmanagerviewplugin.cpp
+++ b/plugins/projectmanagerview/projectmanagerviewplugin.cpp
@@ -459,26 +459,63 @@ void ProjectManagerViewPlugin::createFolderFromContextMenu( )
     }
 }
 
+bool projectItemUrlLessThan(KDevelop::ProjectBaseItem* item1, KDevelop::ProjectBaseItem* item2)
+{
+    return item1->url().path() < item2->url().path();
+}
 void ProjectManagerViewPlugin::removeFromContextMenu()
 {
-    foreach( KDevelop::ProjectBaseItem* item, d->ctxProjectItemList )
+    //copy the list of selected items and sort it to guarantee parents will come before children
+    QMap< IProjectFileManager*, QList<KDevelop::ProjectBaseItem*> > filteredItems;
+    filteredItems[0] += d->ctxProjectItemList;
+    qSort(filteredItems[0].begin(), filteredItems[0].end(), projectItemUrlLessThan);
+
+    KUrl lastFolder;
+    QStringList itemPaths;
+    //Clean up the list, organize by manager
+    /*FIXME: No targets, no target subfiles, and no project folders should ever get here
+     * fix the contextmenu to make sure of it
+     * this should just make sure no children of folders that will be deleted are listed
+     */
+    foreach( KDevelop::ProjectBaseItem* item, filteredItems[0] )
     {
-        if ( item->folder() || item->file() ) {
+        if (item->url() == item->project()->folder())
+            continue;
 
-            QWidget* window(QApplication::activeWindow());
-            int q=KMessageBox::questionYesNo(window,
-                item->folder() ? i18n("Do you really want to remove the directory <i>%1</i>?", item->folder()->url().pathOrUrl())
-                        : i18n("Do you really to remove the file <i>%1</i>?", item->file()->url().pathOrUrl()));
-            if(q==KMessageBox::Yes)
-            {
-                if ( item->folder() ) {
-                    item->project()->projectFileManager()->removeFolder(item->folder());
-                } else {
-                    item->project()->projectFileManager()->removeFile(item->file());
-                }
+        if (item->folder() || item->file())
+        {
+            if (lastFolder.isParentOf(item->url())) {
+                continue;
+            } else if (item->folder()) {
+                lastFolder = item->url();
+            } else if (item->file()) {
+                if (item->parent()->target())
+                    continue;
             }
+
+            filteredItems[item->project()->projectFileManager()] << item;
+            itemPaths << item->url().path();
         }
     }
+
+    if (!itemPaths.size())
+        return;
+
+    if (KMessageBox::questionYesNoList(
+            QApplication::activeWindow(),
+            i18n("Do you really want to delete these items?"),
+            itemPaths, i18n("Delete Files"), KStandardGuiItem::del()
+        ) == KMessageBox::No) {
+        return;
+    }
+
+    //Go though projectmanagers, have them remove the files and folders that they own
+    QMap< IProjectFileManager*, QList<KDevelop::ProjectBaseItem*> >::iterator it;
+    for (it = filteredItems.begin(); it != filteredItems.end(); ++it)
+    {
+        if (it.key())
+            it.key()->removeFilesAndFolders(it.value());
+    }
 }
 
 void ProjectManagerViewPlugin::renameItemFromContextMenu()
diff --git a/project/interfaces/ibuildsystemmanager.h b/project/interfaces/ibuildsystemmanager.h
index 0a84b92..29f77fd 100644
--- a/project/interfaces/ibuildsystemmanager.h
+++ b/project/interfaces/ibuildsystemmanager.h
@@ -29,8 +29,9 @@ namespace KDevelop
 {
 
 class IProjectBuilder;
-typedef QList<ProjectFileItem*> FileItemList;
 class ProjectTargetItem;
+typedef QList<ProjectFileItem*> FileItemList;
+typedef QPair<ProjectTargetItem*, ProjectFileItem*> TargetFilePair;
 /**
  * Manage the file and build system of the project.
  * @author Matt Rogers <mattr@kde.org>, Hamish Rodda <rodda@kde.org>
@@ -101,13 +102,12 @@ public:
     virtual bool addFileToTarget(ProjectFileItem *file, ProjectTargetItem *parent) = 0;
 
     /**
-     * Remove a file from a target
+     * Remove files from targets
      *
-     * Removes the file specified by @p file from the folder @p parent and
-     * modifies the underlying build system if needed. The file is not removed
-     * from the folder it is in
+     * Removes the files from the targets they are paired with (@p targetFiles)
+     * Files are not removed from the folders or the filesystem.
      */
-    virtual bool removeFileFromTarget(ProjectFileItem *file, ProjectTargetItem *parent) = 0;
+    virtual bool removeFilesFromTargets(QList<TargetFilePair> targetFiles) = 0;
 
     /**
      * Get the toplevel build directory for the project
diff --git a/project/interfaces/iprojectfilemanager.h b/project/interfaces/iprojectfilemanager.h
index e9419e1..6815d48 100644
--- a/project/interfaces/iprojectfilemanager.h
+++ b/project/interfaces/iprojectfilemanager.h
@@ -113,21 +113,12 @@ public:
     virtual ProjectFileItem* addFile(const KUrl& folder, ProjectFolderItem *parent) = 0;
 
     /**
-     * Remove a folder from the project and remove it from disk.
+     * Remove files or folders from the project and delete them from disk
      *
-     * Removes the folder specified by @p folder from folder @p parent and
+     * Removes the files or folders specified by @p items and
      * modifies the underlying build system if needed.
      */
-    virtual bool removeFolder(ProjectFolderItem *folder) = 0;
-
-    /**
-     * Remove a file from the project and remove it from disk.
-     *
-     * Removes the file specified by @p file and
-     * modifies the underlying build system if needed. If the file being
-     * removed is also part of a target, it should be removed from the target as well
-     */
-    virtual bool removeFile(ProjectFileItem *file) = 0;
+    virtual bool removeFilesAndFolders( QList<ProjectBaseItem*> items) = 0;
 
     /**
      * Rename a file in the project
diff --git a/shell/kross/xmltokross/dummybsm.h b/shell/kross/xmltokross/dummybsm.h
index cbf427c..585c161 100644
--- a/shell/kross/xmltokross/dummybsm.h
+++ b/shell/kross/xmltokross/dummybsm.h
@@ -48,10 +48,9 @@ class DummyBSM : public KDevelop::IPlugin, public KDevelop::IBuildSystemManager
         KDevelop::ProjectFileItem* addFile( const KUrl&, KDevelop::ProjectFolderItem* ) { return 0; }
 
         bool addFileToTarget( KDevelop::ProjectFileItem*, KDevelop::ProjectTargetItem* ) { return false; }
-        bool removeFolder( KDevelop::ProjectFolderItem* ) { return false; }
         bool removeTarget( KDevelop::ProjectTargetItem* ) { return false; }
-        bool removeFile( KDevelop::ProjectFileItem* ) { return false; }
-        bool removeFileFromTarget( KDevelop::ProjectFileItem*, KDevelop::ProjectTargetItem* ) { return false; }
+        bool removeFilesAndFolders(QList< KDevelop::ProjectBaseItem* > ) { return false; }
+        bool removeFilesFromTargets( QList<KDevelop::TargetFilePair> ) { return false; }
         bool renameFile(KDevelop::ProjectFileItem*, const KUrl&) { return false; }
         bool renameFolder(KDevelop::ProjectFolderItem*, const KUrl&) { return false; }
         QHash<QString,QString> environment(KDevelop::ProjectBaseItem *) const { return QHash<QString, QString>(); }
