diff --git a/src/plugins/cmakeprojectmanager/cmakeproject.cpp b/src/plugins/cmakeprojectmanager/cmakeproject.cpp
index b7fa77ee74693c036cddea39d87ae96d436a5979..2845b74ed00fc6b51569b242b61ca267a8415a12 100644
--- a/src/plugins/cmakeprojectmanager/cmakeproject.cpp
+++ b/src/plugins/cmakeprojectmanager/cmakeproject.cpp
@@ -376,13 +376,18 @@ void CMakeProject::gatherFileNodes(ProjectExplorer::FolderNode *parent, QList<Pr
         list.append(file);
 }
 
+bool sortNodesByPath(Node *a, Node *b)
+{
+    return a->path() < b->path();
+}
+
 void CMakeProject::buildTree(CMakeProjectNode *rootNode, QList<ProjectExplorer::FileNode *> newList)
 {
     // Gather old list
     QList<ProjectExplorer::FileNode *> oldList;
     gatherFileNodes(rootNode, oldList);
-    qSort(oldList.begin(), oldList.end(), ProjectExplorer::ProjectNode::sortNodesByPath);
-    qSort(newList.begin(), newList.end(), ProjectExplorer::ProjectNode::sortNodesByPath);
+    qSort(oldList.begin(), oldList.end(), sortNodesByPath);
+    qSort(newList.begin(), newList.end(), sortNodesByPath);
 
     // generate added and deleted list
     QList<ProjectExplorer::FileNode *>::const_iterator oldIt  = oldList.constBegin();
diff --git a/src/plugins/projectexplorer/projectexplorer.cpp b/src/plugins/projectexplorer/projectexplorer.cpp
index a4f4553b05f09977bc9c96e08b7192f455331bdd..92f46f15e1b3c0f3c6962cdd42c5a980274045fa 100644
--- a/src/plugins/projectexplorer/projectexplorer.cpp
+++ b/src/plugins/projectexplorer/projectexplorer.cpp
@@ -2567,12 +2567,11 @@ QString pathOrDirectoryFor(Node *node, bool dir)
     QString path = node->path();
     QString location;
     FolderNode *folder = qobject_cast<FolderNode *>(node);
-    const int hashPos = path.indexOf(QLatin1Char('#'));
-    if (hashPos >= 0 && folder) {
+    if (node->nodeType() == ProjectExplorer::VirtualFolderNodeType && folder) {
         // Virtual Folder case
         // If there are files directly below or no subfolders, take the folder path
         if (!folder->fileNodes().isEmpty() || folder->subFolderNodes().isEmpty()) {
-            location = path.left(hashPos);
+            location = path;
         } else {
             // Otherwise we figure out a commonPath from the subfolders
             QStringList list;
diff --git a/src/plugins/projectexplorer/projectmodels.cpp b/src/plugins/projectexplorer/projectmodels.cpp
index 9eeb72aecad35d2bdfc9837a0112141ee036a87a..aaf65d113afbe926a4113797b379dfedc37eeeaa 100644
--- a/src/plugins/projectexplorer/projectmodels.cpp
+++ b/src/plugins/projectexplorer/projectmodels.cpp
@@ -101,6 +101,29 @@ bool sortNodes(Node *n1, Node *n2)
     if (n2Type == ProjectNodeType)
         return false;
 
+    if (n1Type == VirtualFolderNodeType) {
+        if (n2Type == VirtualFolderNodeType) {
+            VirtualFolderNode *folder1 = static_cast<VirtualFolderNode *>(n1);
+            VirtualFolderNode *folder2 = static_cast<VirtualFolderNode *>(n2);
+
+            if (folder1->priority() > folder2->priority())
+                return true;
+            if (folder1->priority() < folder2->priority())
+                return false;
+            int result = caseFriendlyCompare(folder1->path(), folder2->path());
+            if (result != 0)
+                return result < 0;
+            else
+                return folder1 < folder2;
+        } else {
+            return true; // virtual folder is before folder
+        }
+    }
+
+    if (n2Type == VirtualFolderNodeType)
+        return false;
+
+
     if (n1Type == FolderNodeType) {
         if (n2Type == FolderNodeType) {
             FolderNode *folder1 = static_cast<FolderNode*>(n1);
@@ -240,14 +263,11 @@ QVariant FlatModel::data(const QModelIndex &index, int role) const
         switch (role) {
         case Qt::DisplayRole:
         case Qt::EditRole: {
-            if (folderNode)
-                result = folderNode->displayName();
-            else
-                result = QFileInfo(node->path()).fileName(); //TODO cache that?
+            result = node->displayName();
             break;
         }
         case Qt::ToolTipRole: {
-            result = QDir::toNativeSeparators(node->path());
+            result = node->tooltip();
             break;
         }
         case Qt::DecorationRole: {
diff --git a/src/plugins/projectexplorer/projectnodes.cpp b/src/plugins/projectexplorer/projectnodes.cpp
index 2d971dc6746bce9f84fc1f4d7ab86d766729f600..6620b43967379b4b93f6985187f17c351e4de093 100644
--- a/src/plugins/projectexplorer/projectnodes.cpp
+++ b/src/plugins/projectexplorer/projectnodes.cpp
@@ -102,6 +102,16 @@ QString Node::path() const
     return m_path;
 }
 
+QString Node::displayName() const
+{
+    return QFileInfo(path()).fileName();
+}
+
+QString Node::tooltip() const
+{
+    return QDir::toNativeSeparators(path());
+}
+
 void Node::setNodeType(NodeType type)
 {
     m_nodeType = type;
@@ -154,8 +164,8 @@ bool FileNode::isGenerated() const
 
   \sa ProjectExplorer::FileNode, ProjectExplorer::ProjectNode
 */
-FolderNode::FolderNode(const QString &folderPath)  :
-    Node(FolderNodeType, folderPath),
+FolderNode::FolderNode(const QString &folderPath, NodeType nodeType)  :
+    Node(nodeType, folderPath),
     m_displayName(QDir::toNativeSeparators(folderPath))
 {
 }
@@ -215,6 +225,31 @@ void FolderNode::setIcon(const QIcon &icon)
     m_icon = icon;
 }
 
+/*!
+  \class ProjectExplorer::VirtualFolderNode
+
+  In-memory presentation of a virtual folder.
+  Note that the node itself + all children (files and folders) are "managed" by the owning project.
+  A virtual folder does not correspond to a actual folder on the file system. See for example the
+  sources, headers and forms folder the qt4projectmanager creates
+  VirtualFolderNodes are always sorted before FolderNodes and are sorted according to their priority.
+
+  \sa ProjectExplorer::FileNode, ProjectExplorer::ProjectNode
+*/
+VirtualFolderNode::VirtualFolderNode(const QString &folderPath, int priority)
+    : FolderNode(folderPath, VirtualFolderNodeType), m_priority(priority)
+{
+}
+
+VirtualFolderNode::~VirtualFolderNode()
+{
+}
+
+int VirtualFolderNode::priority() const
+{
+    return m_priority;
+}
+
 /*!
   \class ProjectExplorer::ProjectNode
 
@@ -344,10 +379,8 @@ void ProjectNode::addProjectNodes(const QList<ProjectNode*> &subProjects)
             m_subFolderNodes.append(project);
             m_subProjectNodes.append(project);
         }
-        qSort(m_subFolderNodes.begin(), m_subFolderNodes.end(),
-              sortNodesByPath);
-        qSort(m_subProjectNodes.begin(), m_subProjectNodes.end(),
-              sortNodesByPath);
+        qSort(m_subFolderNodes.begin(), m_subFolderNodes.end());
+        qSort(m_subProjectNodes.begin(), m_subProjectNodes.end());
 
         foreach (NodesWatcher *watcher, m_watchers)
             emit watcher->foldersAdded();
@@ -366,7 +399,7 @@ void ProjectNode::removeProjectNodes(const QList<ProjectNode*> &subProjects)
         QList<FolderNode*> toRemove;
         foreach (ProjectNode *projectNode, subProjects)
             toRemove << projectNode;
-        qSort(toRemove.begin(), toRemove.end(), sortNodesByPath);
+        qSort(toRemove.begin(), toRemove.end());
 
         foreach (NodesWatcher *watcher, m_watchers)
             emit watcher->foldersAboutToBeRemoved(this, toRemove);
@@ -375,12 +408,12 @@ void ProjectNode::removeProjectNodes(const QList<ProjectNode*> &subProjects)
         QList<FolderNode*>::iterator folderIter = m_subFolderNodes.begin();
         QList<ProjectNode*>::iterator projectIter = m_subProjectNodes.begin();
         for (; toRemoveIter != toRemove.constEnd(); ++toRemoveIter) {
-            while ((*projectIter)->path() != (*toRemoveIter)->path()) {
+            while (*projectIter != *toRemoveIter) {
                 ++projectIter;
                 QTC_ASSERT(projectIter != m_subProjectNodes.end(),
                     qDebug("Project to remove is not part of specified folder!"));
             }
-            while ((*folderIter)->path() != (*toRemoveIter)->path()) {
+            while (*folderIter != *toRemoveIter) {
                 ++folderIter;
                 QTC_ASSERT(folderIter != m_subFolderNodes.end(),
                     qDebug("Project to remove is not part of specified folder!"));
@@ -416,22 +449,17 @@ void ProjectNode::addFolderNodes(const QList<FolderNode*> &subFolders, FolderNod
             folder->setProjectNode(this);
 
             // Find the correct place to insert
-            if (parentFolder->m_subFolderNodes.count() == 0 || sortNodesByPath(parentFolder->m_subFolderNodes.last(), folder)) {
+            if (parentFolder->m_subFolderNodes.count() == 0
+                    || parentFolder->m_subFolderNodes.last() < folder) {
                 // empty list or greater then last node
                 parentFolder->m_subFolderNodes.append(folder);
             } else {
                 // Binary Search for insertion point
-                int l = 0;
-                int r = parentFolder->m_subFolderNodes.count();
-                while (l != r) {
-                    int i = (l + r) / 2;
-                    if (sortNodesByPath(folder, parentFolder->m_subFolderNodes.at(i))) {
-                        r = i;
-                    } else {
-                        l = i + 1;
-                    }
-                }
-                parentFolder->m_subFolderNodes.insert(l, folder);
+                QList<FolderNode*>::iterator it
+                        = qLowerBound(parentFolder->m_subFolderNodes.begin(),
+                                      parentFolder->m_subFolderNodes.end(),
+                                      folder);
+                parentFolder->m_subFolderNodes.insert(it, folder);
             }
 
             // project nodes have to be added via addProjectNodes
@@ -459,7 +487,7 @@ void ProjectNode::removeFolderNodes(const QList<FolderNode*> &subFolders,
         const bool emitSignals = (parentFolder->projectNode() == this);
 
         QList<FolderNode*> toRemove = subFolders;
-        qSort(toRemove.begin(), toRemove.end(), sortNodesByPath);
+        qSort(toRemove.begin(), toRemove.end());
 
         if (emitSignals)
             foreach (NodesWatcher *watcher, m_watchers)
@@ -470,7 +498,7 @@ void ProjectNode::removeFolderNodes(const QList<FolderNode*> &subFolders,
         for (; toRemoveIter != toRemove.constEnd(); ++toRemoveIter) {
             QTC_ASSERT((*toRemoveIter)->nodeType() != ProjectNodeType,
                 qDebug("project nodes have to be removed via removeProjectNodes"));
-            while ((*folderIter)->path() != (*toRemoveIter)->path()) {
+            while (*folderIter != *toRemoveIter) {
                 ++folderIter;
                 QTC_ASSERT(folderIter != parentFolder->m_subFolderNodes.end(),
                     qDebug("Folder to remove is not part of specified folder!"));
@@ -509,22 +537,16 @@ void ProjectNode::addFileNodes(const QList<FileNode*> &files, FolderNode *folder
             file->setParentFolderNode(folder);
             file->setProjectNode(this);
             // Now find the correct place to insert file
-            if (folder->m_fileNodes.count() == 0 || sortNodesByPath(folder->m_fileNodes.last(), file)) {
+            if (folder->m_fileNodes.count() == 0
+                    || folder->m_fileNodes.last() < file) {
                 // empty list or greater then last node
                 folder->m_fileNodes.append(file);
             } else {
-                // Binary Search for insertion point
-                int l = 0;
-                int r = folder->m_fileNodes.count();
-                while (l != r) {
-                    int i = (l + r) / 2;
-                    if (sortNodesByPath(file, folder->m_fileNodes.at(i))) {
-                        r = i;
-                    } else {
-                        l = i + 1;
-                    }
-                }
-                folder->m_fileNodes.insert(l, file);
+                QList<FileNode *>::iterator it
+                        = qLowerBound(folder->m_fileNodes.begin(),
+                                      folder->m_fileNodes.end(),
+                                      file);
+                folder->m_fileNodes.insert(it, file);
             }
         }
 
@@ -549,7 +571,7 @@ void ProjectNode::removeFileNodes(const QList<FileNode*> &files, FolderNode *fol
         const bool emitSignals = (folder->projectNode() == this);
 
         QList<FileNode*> toRemove = files;
-        qSort(toRemove.begin(), toRemove.end(), sortNodesByPath);
+        qSort(toRemove.begin(), toRemove.end());
 
         if (emitSignals)
             foreach (NodesWatcher *watcher, m_watchers)
@@ -558,7 +580,7 @@ void ProjectNode::removeFileNodes(const QList<FileNode*> &files, FolderNode *fol
         QList<FileNode*>::const_iterator toRemoveIter = toRemove.constBegin();
         QList<FileNode*>::iterator filesIter = folder->m_fileNodes.begin();
         for (; toRemoveIter != toRemove.constEnd(); ++toRemoveIter) {
-            while ((*filesIter)->path() != (*toRemoveIter)->path()) {
+            while (*filesIter != *toRemoveIter) {
                 ++filesIter;
                 QTC_ASSERT(filesIter != folder->m_fileNodes.end(),
                     qDebug("File to remove is not part of specified folder!"));
@@ -579,12 +601,6 @@ void ProjectNode::watcherDestroyed(QObject *watcher)
     unregisterWatcher(static_cast<NodesWatcher*>(watcher));
 }
 
-/*!
-  \brief Sort pointers to FileNodes
-*/
-bool ProjectNode::sortNodesByPath(Node *n1, Node *n2) {
-    return n1->path() < n2->path();
-}
 
 /*!
   \class ProjectExplorer::SessionNode
@@ -663,6 +679,9 @@ void SessionNode::addProjectNodes(const QList<ProjectNode*> &projectNodes)
             m_projectNodes.append(project);
         }
 
+        qSort(m_subFolderNodes);
+        qSort(m_projectNodes);
+
         foreach (NodesWatcher *watcher, m_watchers)
             emit watcher->foldersAdded();
    }
@@ -675,6 +694,8 @@ void SessionNode::removeProjectNodes(const QList<ProjectNode*> &projectNodes)
         foreach (ProjectNode *projectNode, projectNodes)
             toRemove << projectNode;
 
+        qSort(toRemove);
+
         foreach (NodesWatcher *watcher, m_watchers)
             emit watcher->foldersAboutToBeRemoved(this, toRemove);
 
@@ -682,12 +703,12 @@ void SessionNode::removeProjectNodes(const QList<ProjectNode*> &projectNodes)
         QList<FolderNode*>::iterator folderIter = m_subFolderNodes.begin();
         QList<ProjectNode*>::iterator projectIter = m_projectNodes.begin();
         for (; toRemoveIter != toRemove.constEnd(); ++toRemoveIter) {
-            while ((*projectIter)->path() != (*toRemoveIter)->path()) {
+            while (*projectIter != *toRemoveIter) {
                 ++projectIter;
                 QTC_ASSERT(projectIter != m_projectNodes.end(),
                     qDebug("Project to remove is not part of specified folder!"));
             }
-            while ((*folderIter)->path() != (*toRemoveIter)->path()) {
+            while (*folderIter != *toRemoveIter) {
                 ++folderIter;
                 QTC_ASSERT(folderIter != m_subFolderNodes.end(),
                     qDebug("Project to remove is not part of specified folder!"));
diff --git a/src/plugins/projectexplorer/projectnodes.h b/src/plugins/projectexplorer/projectnodes.h
index 24440c668e59f927b0758e0750bdbcb40d98b39f..c654d2da16ae2768b71267805ee97e4aec3b76ae 100644
--- a/src/plugins/projectexplorer/projectnodes.h
+++ b/src/plugins/projectexplorer/projectnodes.h
@@ -54,6 +54,7 @@ class RunConfiguration;
 enum NodeType {
     FileNodeType = 1,
     FolderNodeType,
+    VirtualFolderNodeType,
     ProjectNodeType,
     SessionNodeType
 };
@@ -87,6 +88,8 @@ public:
     ProjectNode *projectNode() const;     // managing project
     FolderNode *parentFolderNode() const; // parent folder or project
     QString path() const;                 // file system path
+    virtual QString displayName() const;
+    virtual QString tooltip() const;
 
 protected:
     Node(NodeType nodeType, const QString &path);
@@ -122,7 +125,7 @@ private:
 class PROJECTEXPLORER_EXPORT FolderNode : public Node {
     Q_OBJECT
 public:
-    explicit FolderNode(const QString &folderPath);
+    explicit FolderNode(const QString &folderPath, NodeType nodeType = FolderNodeType);
     virtual ~FolderNode();
 
     QString displayName() const;
@@ -147,6 +150,18 @@ private:
     mutable QIcon m_icon;
 };
 
+class PROJECTEXPLORER_EXPORT VirtualFolderNode : public FolderNode
+{
+    Q_OBJECT
+public:
+    explicit VirtualFolderNode(const QString &folderPath, int priority);
+    virtual ~VirtualFolderNode();
+
+    int priority() const;
+private:
+    int m_priority;
+};
+
 // Documentation inside.
 class PROJECTEXPLORER_EXPORT ProjectNode : public FolderNode
 {
@@ -213,8 +228,6 @@ public:
 
     void accept(NodesVisitor *visitor);
 
-    static bool sortNodesByPath(Node *n1, Node *n2);
-
 protected:
     // this is just the in-memory representation, a subclass
     // will add the persistent stuff
diff --git a/src/plugins/qt4projectmanager/qt4nodes.cpp b/src/plugins/qt4projectmanager/qt4nodes.cpp
index 0aa2b5695251ea7e5becd267bfc366b06e769121..0d69951516d7a312392ac222677abd64088977d0 100644
--- a/src/plugins/qt4projectmanager/qt4nodes.cpp
+++ b/src/plugins/qt4projectmanager/qt4nodes.cpp
@@ -107,6 +107,11 @@ static const FileTypeDataStorage fileTypeDataStorage[] = {
       ":/qt4projectmanager/images/unknown.png" }
 };
 
+bool sortNodesByPath(ProjectExplorer::Node *a, ProjectExplorer::Node *b)
+{
+    return a->path() < b->path();
+}
+
 class Qt4NodeStaticData {
 public:
     class FileTypeData {
@@ -278,20 +283,25 @@ void Qt4PriFileNode::scheduleUpdate()
 namespace Internal {
 struct InternalNode
 {
-    QMap<QString, InternalNode*> subnodes;
+    QList<InternalNode *> virtualfolders;
+    QMap<QString, InternalNode *> subnodes;
     QStringList files;
     ProjectExplorer::FileType type;
     QString displayName;
+    QString typeName;
+    int priority;
     QString fullPath;
     QIcon icon;
 
     InternalNode()
     {
         type = ProjectExplorer::UnknownFileType;
+        priority = 0;
     }
 
     ~InternalNode()
     {
+        qDeleteAll(virtualfolders);
         qDeleteAll(subnodes);
     }
 
@@ -381,62 +391,102 @@ struct InternalNode
         subnodes = newSubnodes;
     }
 
+    FolderNode *createFolderNode(InternalNode *node)
+    {
+        FolderNode *newNode = 0;
+        if (node->typeName.isEmpty())
+            newNode = new FolderNode(node->fullPath);
+        else
+            newNode = new ProVirtualFolderNode(node->fullPath, node->priority, node->typeName);
+
+        newNode->setDisplayName(node->displayName);
+        if (!node->icon.isNull())
+            newNode->setIcon(node->icon);
+        return newNode;
+    }
+
     // Makes the projectNode's subtree below the given folder match this internal node's subtree
     void updateSubFolders(Qt4ProjectManager::Qt4PriFileNode *projectNode, ProjectExplorer::FolderNode *folder)
     {
         updateFiles(projectNode, folder, type);
 
-        // update folders
-        QList<FolderNode *> existingFolderNodes;
-        foreach (FolderNode *node, folder->subFolderNodes()) {
+        // updateFolders
+        QMultiMap<QString, FolderNode *> existingFolderNodes;
+        foreach (FolderNode *node, folder->subFolderNodes())
             if (node->nodeType() != ProjectNodeType)
-                existingFolderNodes << node;
-        }
-
-        qSort(existingFolderNodes.begin(), existingFolderNodes.end(), ProjectNode::sortNodesByPath);
+                existingFolderNodes.insert(node->path(), node);
 
         QList<FolderNode *> foldersToRemove;
         QList<FolderNode *> foldersToAdd;
         typedef QPair<InternalNode *, FolderNode *> NodePair;
         QList<NodePair> nodesToUpdate;
 
-        // Both lists should be already sorted...
-        QList<FolderNode*>::const_iterator existingNodeIter = existingFolderNodes.constBegin();
-        QMap<QString, InternalNode*>::const_iterator newNodeIter = subnodes.constBegin();;
-        while (existingNodeIter != existingFolderNodes.constEnd()
-               && newNodeIter != subnodes.constEnd()) {
-            if ((*existingNodeIter)->path() < newNodeIter.value()->fullPath) {
-                foldersToRemove << *existingNodeIter;
-                ++existingNodeIter;
-            } else if ((*existingNodeIter)->path() > newNodeIter.value()->fullPath) {
-                FolderNode *newNode = new FolderNode(newNodeIter.value()->fullPath);
-                newNode->setDisplayName(newNodeIter.value()->displayName);
-                if (!newNodeIter.value()->icon.isNull())
-                    newNode->setIcon(newNodeIter.value()->icon);
-                foldersToAdd << newNode;
-                nodesToUpdate << NodePair(newNodeIter.value(), newNode);
-                ++newNodeIter;
-            } else { // *existingNodeIter->path() == *newPathIter
-                nodesToUpdate << NodePair(newNodeIter.value(), *existingNodeIter);
-                ++existingNodeIter;
-                ++newNodeIter;
+        // Check virtual
+        {
+            QList<InternalNode *>::const_iterator it = virtualfolders.constBegin();
+            QList<InternalNode *>::const_iterator end = virtualfolders.constEnd();
+            for ( ; it != end; ++it) {
+                bool found = false;
+                QString path = (*it)->fullPath;
+                QMultiMap<QString, FolderNode *>::const_iterator oldit
+                        = existingFolderNodes.constFind(path);
+                while (oldit != existingFolderNodes.end() && oldit.key() == path) {
+                    if (oldit.value()->nodeType() == ProjectExplorer::VirtualFolderNodeType) {
+                        ProjectExplorer::VirtualFolderNode *vfn
+                                = qobject_cast<ProjectExplorer::VirtualFolderNode *>(oldit.value());
+                        if (vfn->priority() == (*it)->priority) {
+                            found = true;
+                            break;
+                        }
+                    }
+                    ++oldit;
+                }
+                if (found) {
+                    nodesToUpdate << NodePair(*it, *oldit);
+                } else {
+                    FolderNode *newNode = createFolderNode(*it);
+                    foldersToAdd << newNode;
+                    nodesToUpdate << NodePair(*it, newNode);
+                }
             }
         }
-
-        while (existingNodeIter != existingFolderNodes.constEnd()) {
-            foldersToRemove << *existingNodeIter;
-            ++existingNodeIter;
-        }
-        while (newNodeIter != subnodes.constEnd()) {
-            FolderNode *newNode = new FolderNode(newNodeIter.value()->fullPath);
-            newNode->setDisplayName(newNodeIter.value()->displayName);
-            if (!newNodeIter.value()->icon.isNull())
-                newNode->setIcon(newNodeIter.value()->icon);
-            foldersToAdd << newNode;
-            nodesToUpdate << NodePair(newNodeIter.value(), newNode);
-            ++newNodeIter;
+        // Check subnodes
+        {
+            QMap<QString, InternalNode *>::const_iterator it = subnodes.constBegin();
+            QMap<QString, InternalNode *>::const_iterator end = subnodes.constEnd();
+
+            for ( ; it != end; ++it) {
+                bool found = false;
+                QString path = it.value()->fullPath;
+                QMultiMap<QString, FolderNode *>::const_iterator oldit
+                        = existingFolderNodes.constFind(path);
+                while (oldit != existingFolderNodes.end() && oldit.key() == path) {
+                    if (oldit.value()->nodeType() == ProjectExplorer::FolderNodeType) {
+                        found = true;
+                        break;
+                    }
+                    ++oldit;
+                }
+                if (found) {
+                    nodesToUpdate << NodePair(it.value(), *oldit);
+                } else {
+                    FolderNode *newNode = createFolderNode(it.value());
+                    foldersToAdd << newNode;
+                    nodesToUpdate << NodePair(it.value(), newNode);
+                }
+            }
         }
 
+        QSet<FolderNode *> toKeep;
+        foreach (const NodePair &np, nodesToUpdate)
+            toKeep << np.second;
+
+        QMultiMap<QString, FolderNode *>::const_iterator jit = existingFolderNodes.constBegin();
+        QMultiMap<QString, FolderNode *>::const_iterator jend = existingFolderNodes.constEnd();
+        for ( ; jit != jend; ++jit)
+            if (!toKeep.contains(jit.value()))
+                foldersToRemove << jit.value();
+
         if (!foldersToRemove.isEmpty())
             projectNode->removeFolderNodes(foldersToRemove, folder);
         if (!foldersToAdd.isEmpty())
@@ -459,7 +509,7 @@ struct InternalNode
         QList<FileNode*> filesToAdd;
 
         qSort(files);
-        qSort(existingFileNodes.begin(), existingFileNodes.end(), ProjectNode::sortNodesByPath);
+        qSort(existingFileNodes.begin(), existingFileNodes.end(), sortNodesByPath);
 
         QList<FileNode*>::const_iterator existingNodeIter = existingFileNodes.constBegin();
         QList<QString>::const_iterator newPathIter = files.constBegin();
@@ -647,10 +697,11 @@ void Qt4PriFileNode::update(ProFile *includeFileExact, QtSupport::ProFileReader
             InternalNode *subfolder = new InternalNode;
             subfolder->type = type;
             subfolder->icon = fileTypes.at(i).icon;
-            subfolder->fullPath = m_projectDir + QLatin1String("/#")
-                                  + QString::number(i) + fileTypes.at(i).typeName;
+            subfolder->fullPath = m_projectDir;
+            subfolder->typeName = fileTypes.at(i).typeName;
+            subfolder->priority = -i;
             subfolder->displayName = fileTypes.at(i).typeName;
-            contents.subnodes.insert(subfolder->fullPath, subfolder);
+            contents.virtualfolders.append(subfolder);
             // create the hierarchy with subdirectories
             subfolder->create(m_projectDir, newFilePaths, type);
         }
@@ -731,10 +782,11 @@ void Qt4PriFileNode::folderChanged(const QString &folder)
             InternalNode *subfolder = new InternalNode;
             subfolder->type = type;
             subfolder->icon = fileTypes.at(i).icon;
-            subfolder->fullPath = m_projectDir + QLatin1String("/#")
-                                  + QString::number(i) + fileTypes.at(i).typeName;
+            subfolder->fullPath = m_projectDir;
+            subfolder->typeName = fileTypes.at(i).typeName;
+            subfolder->priority = -i;
             subfolder->displayName = fileTypes.at(i).typeName;
-            contents.subnodes.insert(subfolder->fullPath, subfolder);
+            contents.virtualfolders.append(subfolder);
             // create the hierarchy with subdirectories
             subfolder->create(m_projectDir, m_files[type], type);
         }
@@ -833,7 +885,7 @@ QList<ProjectNode::ProjectAction> Qt4PriFileNode::supportedActions(Node *node) c
         }
 
         bool addExistingFiles = true;
-        if (node->path().contains(QLatin1Char('#'))) {
+        if (node->nodeType() == ProjectExplorer::VirtualFolderNodeType) {
             // A virtual folder, we do what the projectexplorer does
             FolderNode *folder = qobject_cast<FolderNode *>(node);
             if (folder) {
@@ -1648,6 +1700,11 @@ void Qt4ProFileNode::applyAsyncEvaluate()
     m_project->decrementPendingEvaluateFutures();
 }
 
+bool sortByNodes(Node *a, Node *b)
+{
+    return a->path() < b->path();
+}
+
 void Qt4ProFileNode::applyEvaluate(EvalResult evalResult, bool async)
 {
     if (!m_readerExact)
@@ -1996,7 +2053,7 @@ QStringList Qt4ProFileNode::updateUiFiles()
     QStringList toUpdate;
 
     qSort(newFilePaths);
-    qSort(existingFileNodes.begin(), existingFileNodes.end(), ProjectNode::sortNodesByPath);
+    qSort(existingFileNodes.begin(), existingFileNodes.end(), sortNodesByPath);
 
     QList<ProjectExplorer::FileNode*>::const_iterator existingNodeIter = existingFileNodes.constBegin();
     QList<QString>::const_iterator newPathIter = newFilePaths.constBegin();
diff --git a/src/plugins/qt4projectmanager/qt4nodes.h b/src/plugins/qt4projectmanager/qt4nodes.h
index dcef5dbd821f170c6594e0dcce8467e7ed631266..5426d6de7de5ce33aa777b1614f06910aada8504 100644
--- a/src/plugins/qt4projectmanager/qt4nodes.h
+++ b/src/plugins/qt4projectmanager/qt4nodes.h
@@ -264,6 +264,29 @@ private:
     friend class Qt4PriFileNode;
 };
 
+class ProVirtualFolderNode : public ProjectExplorer::VirtualFolderNode
+{
+public:
+    explicit ProVirtualFolderNode(const QString &folderPath, int priority, const QString &typeName)
+        : VirtualFolderNode(folderPath, priority), m_typeName(typeName)
+    {
+
+    }
+
+    QString displayName() const
+    {
+        return m_typeName;
+    }
+
+    QString tooltip() const
+    {
+        return QString();
+    }
+
+private:
+    QString m_typeName;
+};
+
 } // namespace Internal
 
 struct QT4PROJECTMANAGER_EXPORT TargetInformation