diff --git a/src/libs/utils/consoleprocess_unix.cpp b/src/libs/utils/consoleprocess_unix.cpp
index 610082377852150b6adad7a1bd7f3d6c3b103d07..2e20ac0c37aca3c6f36eb27a8ef25993e4e48129 100644
--- a/src/libs/utils/consoleprocess_unix.cpp
+++ b/src/libs/utils/consoleprocess_unix.cpp
@@ -73,7 +73,12 @@ bool ConsoleProcess::start(const QString &program, const QStringList &args)
     }
 
     QStringList xtermArgs;
-    xtermArgs << "-e" << (QCoreApplication::applicationDirPath() + "/qtcreator_process_stub")
+    xtermArgs << "-e"
+#ifdef Q_OS_MAC
+              << (QCoreApplication::applicationDirPath() + "/../Resources/qtcreator_process_stub")
+#else
+              << (QCoreApplication::applicationDirPath() + "/qtcreator_process_stub")
+#endif
               << (m_debug ? "debug" : "exec")
               << m_stubServer.fullServerName()
               << tr("Press <RETURN> to close this window...")
diff --git a/src/libs/utils/process_stub.pro b/src/libs/utils/process_stub.pro
index accf024ed0fc7371243fc46ce77e7ece290c29e6..a7f48846a4fdf4b3294c17409f45238621aafefd 100644
--- a/src/libs/utils/process_stub.pro
+++ b/src/libs/utils/process_stub.pro
@@ -1,6 +1,13 @@
+IDE_BUILD_TREE=../../../
+include(../../qworkbench.pri)
+
 TEMPLATE        = app
 TARGET          = qtcreator_process_stub
-DESTDIR         = ../../../bin
+macx {
+    DESTDIR         = $$IDE_BUILD_TREE/bin/$${IDE_APP_TARGET}.app/Contents/Resources
+} else {
+    DESTDIR         = ../../../bin
+}
 
 CONFIG          += warn_on console use_c_linker
 CONFIG          -= qt app_bundle
diff --git a/src/libs/utils/process_stub_win.c b/src/libs/utils/process_stub_win.c
index a4998b7e6cfbb619d3c5b83bb5a9b41f1f8dab4a..3d99a6853957de81341d000d2cf9912748d30405 100644
--- a/src/libs/utils/process_stub_win.c
+++ b/src/libs/utils/process_stub_win.c
@@ -174,7 +174,7 @@ int main()
        the Windows kernel runs amok when we attempt this.
        So instead we start a debugged process, eat all the initial
        debug events, suspend the process and detach from it. If gdb
-       tries to attach *now*, everthing goes smoothly. Yay. */
+       tries to attach *now*, everything goes smoothly. Yay. */
     if (creationFlags & DEBUG_ONLY_THIS_PROCESS) {
         do {
             if (!WaitForDebugEvent (&dbev, INFINITE))
diff --git a/src/plugins/designer/formeditorplugin.cpp b/src/plugins/designer/formeditorplugin.cpp
index e132047df3850a91171252380e41dbeb324253b6..3052c1735855fcd76bc38302eab57c74d2b56546 100644
--- a/src/plugins/designer/formeditorplugin.cpp
+++ b/src/plugins/designer/formeditorplugin.cpp
@@ -38,9 +38,6 @@
 #endif
 
 #include "designerconstants.h"
-#if QT_VERSION < 0x040500
-#    include "settings.h"
-#endif
 
 #include <coreplugin/icore.h>
 #include <coreplugin/mimedatabase.h>
diff --git a/src/plugins/designer/formeditorw.cpp b/src/plugins/designer/formeditorw.cpp
index b3f6ffc70e6d92d55e89493f54e3c8eebc25264b..103d635168af40e56b00478d5b5a280733b8062c 100644
--- a/src/plugins/designer/formeditorw.cpp
+++ b/src/plugins/designer/formeditorw.cpp
@@ -173,7 +173,10 @@ FormEditorW::FormEditorW() :
     m_core(Core::ICore::instance()),
     m_initStage(RegisterPlugins),
     m_actionGroupEditMode(0),
-    m_actionPrint(0)
+    m_actionPrint(0),
+    m_actionPreview(0),
+    m_actionGroupPreviewInStyle(0),
+    m_actionAboutPlugins(0)
 {
     if (Designer::Constants::Internal::debug)
         qDebug() << Q_FUNC_INFO;
@@ -250,10 +253,14 @@ void FormEditorW::fullInit()
         }
     }
 
+    if (m_actionAboutPlugins)
+        m_actionAboutPlugins->setEnabled(true);
+
     if (Designer::Constants::Internal::debug) {
         qDebug() << Q_FUNC_INFO << initTime->elapsed() << "ms";
         delete initTime;
     }
+
     m_initStage = FullyInitialized;
 }
 
@@ -439,6 +446,15 @@ void FormEditorW::setupActions()
     QAction *actionFormSettings = m_fwm->actionShowFormWindowSettingsDialog();
     addToolAction(actionFormSettings, am, globalcontext, QLatin1String("FormEditor.FormSettings"), mformtools);
 
+#if QT_VERSION > 0x040500
+    createSeparator(this, am, globalcontext, mformtools, QLatin1String("FormEditor.Menu.Tools.Separator4"));
+    m_actionAboutPlugins = new QAction(tr("About Qt Designer plugins...."), this);
+    addToolAction(m_actionAboutPlugins,  am,  globalcontext,
+                   QLatin1String("FormEditor.AboutPlugins"), mformtools);
+    connect(m_actionAboutPlugins,  SIGNAL(triggered()), m_fwm, SLOT(aboutPlugins()));
+    m_actionAboutPlugins->setEnabled(false);
+#endif
+
     // FWM
     connect(m_fwm, SIGNAL(activeFormWindowChanged(QDesignerFormWindowInterface *)), this, SLOT(activeFormWindowChanged(QDesignerFormWindowInterface *)));
 }
diff --git a/src/plugins/designer/formeditorw.h b/src/plugins/designer/formeditorw.h
index bdddf3ae373a671e0c594aa8c00323d662659fd7..d4a94794eef601e24d6e14b50a47f698193db3e2 100644
--- a/src/plugins/designer/formeditorw.h
+++ b/src/plugins/designer/formeditorw.h
@@ -157,6 +157,7 @@ private:
     QAction *m_actionPrint;
     QAction *m_actionPreview;
     QActionGroup *m_actionGroupPreviewInStyle;
+    QAction *m_actionAboutPlugins;
 
     QList<int> m_context;
 
diff --git a/src/plugins/projectexplorer/projectexplorer.cpp b/src/plugins/projectexplorer/projectexplorer.cpp
index a0f4016d33ff557cfdbc20038361a417b7dc2b65..33e81f2e86432f6345e22a7adbc7e4b110967890 100644
--- a/src/plugins/projectexplorer/projectexplorer.cpp
+++ b/src/plugins/projectexplorer/projectexplorer.cpp
@@ -1121,7 +1121,7 @@ void ProjectExplorerPlugin::setCurrent(Project *project, QString filePath, Node
     if (node)
         filePath = node->path();
     else
-        node = m_session->nodeForFile(filePath);
+        node = m_session->nodeForFile(filePath, project);
 
     Core::ICore *core = Core::ICore::instance();
 
diff --git a/src/plugins/projectexplorer/projectwindow.cpp b/src/plugins/projectexplorer/projectwindow.cpp
index 0f0850c17cb2f1dabde424335298ca7a0a8f9ffc..c3c769056fe7b8e9ce3979efd0fe5b05483162ce 100644
--- a/src/plugins/projectexplorer/projectwindow.cpp
+++ b/src/plugins/projectexplorer/projectwindow.cpp
@@ -65,10 +65,9 @@ ProjectWindow::ProjectWindow(QWidget *parent) : QWidget(parent)
     m_projectExplorer = ProjectExplorerPlugin::instance();
     m_session = m_projectExplorer->session();
 
-    connect(m_session, SIGNAL(sessionLoaded()), this, SLOT(restoreStatus()));
-    connect(m_session, SIGNAL(aboutToSaveSession()), this, SLOT(saveStatus()));
-
     m_treeWidget = new QTreeWidget(this);
+    m_treeWidget->setSelectionMode(QAbstractItemView::SingleSelection);
+    m_treeWidget->setSelectionBehavior(QAbstractItemView::SelectRows);
     m_treeWidget->setFrameStyle(QFrame::NoFrame);
     m_treeWidget->setRootIsDecorated(false);
     m_treeWidget->header()->setResizeMode(QHeaderView::ResizeToContents);
@@ -79,7 +78,7 @@ ProjectWindow::ProjectWindow(QWidget *parent) : QWidget(parent)
         );
 
     connect(m_treeWidget, SIGNAL(itemChanged(QTreeWidgetItem*, int)),
-            this, SLOT(handleItem(QTreeWidgetItem*, int)), Qt::QueuedConnection);
+            this, SLOT(handleItem(QTreeWidgetItem*, int)));
     connect(m_treeWidget, SIGNAL(currentItemChanged(QTreeWidgetItem*, QTreeWidgetItem *)),
             this, SLOT(handleCurrentItemChanged(QTreeWidgetItem*)));
 
@@ -116,10 +115,14 @@ ProjectWindow::ProjectWindow(QWidget *parent) : QWidget(parent)
     topLayout->setSpacing(0);
     topLayout->addWidget(splitter);
 
-    connect(m_session, SIGNAL(sessionLoaded()), this, SLOT(updateTreeWidget()));
-    connect(m_session, SIGNAL(startupProjectChanged(ProjectExplorer::Project*)), this, SLOT(updateTreeWidget()));
-    connect(m_session, SIGNAL(projectAdded(ProjectExplorer::Project*)), this, SLOT(updateTreeWidget()));
-    connect(m_session, SIGNAL(projectRemoved(ProjectExplorer::Project*)), this, SLOT(updateTreeWidget()));
+    connect(m_session, SIGNAL(sessionLoaded()), this, SLOT(restoreStatus()));
+    connect(m_session, SIGNAL(aboutToSaveSession()), this, SLOT(saveStatus()));
+
+    connect(m_session, SIGNAL(startupProjectChanged(ProjectExplorer::Project*)), this, SLOT(updateTreeWidgetStatupProjectChanged(ProjectExplorer::Project*)));
+    connect(m_session, SIGNAL(projectAdded(ProjectExplorer::Project*)), this, SLOT(updateTreeWidgetProjectAdded(ProjectExplorer::Project*)));
+    connect(m_session, SIGNAL(projectRemoved(ProjectExplorer::Project*)), this, SLOT(updateTreeWidgetProjectRemoved(ProjectExplorer::Project*)));
+    connect(m_session, SIGNAL(aboutToRemoveProject(ProjectExplorer::Project*)), this, SLOT(updateTreeWidgetAboutToRemoveProject(ProjectExplorer::Project*)));
+
 }
 
 ProjectWindow::~ProjectWindow()
@@ -128,12 +131,21 @@ ProjectWindow::~ProjectWindow()
 
 void ProjectWindow::restoreStatus()
 {
+    m_panelsTabWidget->setFocus();
+
+    if (!m_treeWidget->currentItem() && m_treeWidget->topLevelItemCount()) {
+        m_treeWidget->setCurrentItem(m_treeWidget->topLevelItem(0), 0, QItemSelectionModel::SelectCurrent | QItemSelectionModel::Rows);
+    }
+
     const QVariant lastPanel = m_session->value(QLatin1String("ProjectWindow/Panel"));
     if (lastPanel.isValid()) {
         const int index = lastPanel.toInt();
         if (index < m_panelsTabWidget->count())
             m_panelsTabWidget->setCurrentIndex(index);
     }
+
+    if ((m_panelsTabWidget->currentIndex() == -1) && m_panelsTabWidget->count())
+        m_panelsTabWidget->setCurrentIndex(0);
 }
 
 void ProjectWindow::saveStatus()
@@ -172,52 +184,69 @@ void ProjectWindow::showProperties(ProjectExplorer::Project *project, const QMod
     }
 }
 
-void ProjectWindow::updateTreeWidget()
+void ProjectWindow::updateTreeWidgetStatupProjectChanged(ProjectExplorer::Project *startupProject)
 {
-    // This setFocus prevents a crash, which I (daniel) spend the better part of a day tracking down.
-    // To explain: Consider the case that a widget on either the build or run settings has Focus
-    // Us clearing the m_treewidget will emit a currentItemChanged(0) signal
-    // Which is connected to showProperties
-    // showProperties will now remove the widget that has focus from m_panelsTabWidget, so the treewidget
-    // gets focus, which will in focusIn select the first entry (due to QTreeWidget::clear() implementation,
-    // there are still items in the model) which emits another currentItemChanged() signal
-    // That one runs fully thorough and deletes all widgets, even that one that we are currently removing
-    // from m_panelsTabWidget.
-    // To prevent that, we simply prevent the focus switching....
-    QWidget *focusWidget = qApp->focusWidget();
-    while (focusWidget) {
-        if (focusWidget == this) {
-            m_treeWidget->setFocus();
-            break;
+    int count = m_treeWidget->topLevelItemCount();
+    for (int i = 0; i < count; ++i) {
+        QTreeWidgetItem *item = m_treeWidget->topLevelItem(i);
+        if (Project *project = findProject(item->text(2))) {
+            bool checked = (startupProject == project);
+            if (item->checkState(1) != (checked ? Qt::Checked : Qt::Unchecked))
+                item->setCheckState(1, checked ? Qt::Checked : Qt::Unchecked);
+        } else {
+            item->setCheckState(1, Qt::Unchecked);
         }
-        focusWidget = focusWidget->parentWidget();
     }
-    m_treeWidget->clear();
+}
 
-    foreach(Project *project, m_session->projects()) {
-        const QFileInfo fileInfo(project->file()->fileName());
+void ProjectWindow::updateTreeWidgetProjectAdded(ProjectExplorer::Project *projectAdded)
+{
+    int position = m_session->projects().indexOf(projectAdded);
+    const QFileInfo fileInfo(projectAdded->file()->fileName());
 
-        QTreeWidgetItem *item = new QTreeWidgetItem();
-        item->setText(0, fileInfo.baseName());
-        item->setIcon(0, Core::FileIconProvider::instance()->icon(fileInfo));
-        item->setText(2, fileInfo.filePath());
+    QTreeWidgetItem *item = new QTreeWidgetItem();
+    item->setText(0, fileInfo.baseName());
+    item->setIcon(0, Core::FileIconProvider::instance()->icon(fileInfo));
+    item->setText(2, fileInfo.filePath());
 
-        if (project->isApplication()) {
-            bool checked = (m_session->startupProject() == project);
-            item->setCheckState(1, checked ? Qt::Checked : Qt::Unchecked);
-        }
+    if (projectAdded->isApplication()) {
+        bool checked = (m_session->startupProject() == projectAdded);
+        item->setCheckState(1, checked ? Qt::Checked : Qt::Unchecked);
+    }
 
-        m_treeWidget->addTopLevelItem(item);
+    m_treeWidget->insertTopLevelItem(position, item);
+}
 
+void ProjectWindow::updateTreeWidgetAboutToRemoveProject(ProjectExplorer::Project *projectRemoved) {
+    int count = m_treeWidget->topLevelItemCount();
+    for (int i = 0; i < count; ++i) {
+        QTreeWidgetItem *item = m_treeWidget->topLevelItem(i);
+        if (item->text(2) == QFileInfo(projectRemoved->file()->fileName()).filePath()) {
+            if (m_treeWidget->currentItem() == item) {
+                    m_treeWidget->setCurrentItem(0);
+            }
+        }
     }
 }
 
+void ProjectWindow::updateTreeWidgetProjectRemoved(ProjectExplorer::Project *projectRemoved)
+{    
+    int count = m_treeWidget->topLevelItemCount();
+    for (int i = 0; i < count; ++i) {
+        QTreeWidgetItem *item = m_treeWidget->topLevelItem(i);
+        if (item->text(2) == QFileInfo(projectRemoved->file()->fileName()).filePath()) {
+            QTreeWidgetItem *it = m_treeWidget->takeTopLevelItem(i);
+            delete it;
+            break;
+        }
+    }
+}
 
 Project *ProjectWindow::findProject(const QString &path) const
 {
     QList<Project*> projects = m_session->projects();
     foreach (Project* project, projects)
-        if (project->file()->fileName() == path)
+        if (QFileInfo(project->file()->fileName()).filePath() == path)
             return project;
     return 0;
 }
@@ -232,22 +261,26 @@ void ProjectWindow::handleCurrentItemChanged(QTreeWidgetItem *current)
             showProperties(project, QModelIndex());
             return;
         }
+    } else {
+        showProperties(0, QModelIndex());
     }
 }
 
 
 void ProjectWindow::handleItem(QTreeWidgetItem *item, int column)
 {
+
     if (!item || column != 1) // startup project
         return;
 
     const QString path = item->text(2);
     Project *project = findProject(path);
-
     if (project && project->isApplication()) {
-        if (!(item->checkState(1) == Qt::Checked)) {
-            item->setCheckState(1, Qt::Checked); // uncheck not supported
-        } else {
+        if (!(item->checkState(1) == Qt::Checked)) { // is now unchecked
+            if (m_session->startupProject() == project) {
+                item->setCheckState(1, Qt::Checked); // uncheck not supported
+            }
+        } else { // is now checked
             m_session->setStartupProject(project);
         }
     }
diff --git a/src/plugins/projectexplorer/projectwindow.h b/src/plugins/projectexplorer/projectwindow.h
index 199be12cc945e96386637003e541a503c1bc1dac..18d19f749c9f5295da5bc984eaa8722a879a8d8b 100644
--- a/src/plugins/projectexplorer/projectwindow.h
+++ b/src/plugins/projectexplorer/projectwindow.h
@@ -62,6 +62,12 @@ private slots:
     void saveStatus();
 
     void updateTreeWidget();
+
+    void updateTreeWidgetStatupProjectChanged(ProjectExplorer::Project *startupProject);
+    void updateTreeWidgetProjectAdded(ProjectExplorer::Project *addedProject);
+    void updateTreeWidgetProjectRemoved(ProjectExplorer::Project *removedProject);
+    void updateTreeWidgetAboutToRemoveProject(ProjectExplorer::Project *removedProject);
+
     void handleItem(QTreeWidgetItem *item, int column);
     void handleCurrentItemChanged(QTreeWidgetItem *);
 
diff --git a/src/plugins/projectexplorer/session.cpp b/src/plugins/projectexplorer/session.cpp
index ce88d23c2618157f9ad2878a094f1f4e8b5a3787..cf0d79f8e01fee9f7f1425ce4b786bbe5a8de195 100644
--- a/src/plugins/projectexplorer/session.cpp
+++ b/src/plugins/projectexplorer/session.cpp
@@ -826,10 +826,12 @@ Project *SessionManager::projectForNode(Node *node) const
     return project;
 }
 
-Node *SessionManager::nodeForFile(const QString &fileName) const
+Node *SessionManager::nodeForFile(const QString &fileName, Project *project) const
 {
     Node *node = 0;
-    if (Project *project = projectForFile(fileName)) {
+    if (!project)
+        project = projectForFile(fileName);
+    if (project) {
         FindNodesForFileVisitor findNodes(fileName);
         project->rootProjectNode()->accept(&findNodes);
 
diff --git a/src/plugins/projectexplorer/session.h b/src/plugins/projectexplorer/session.h
index 15fd235977bdc249539cdbb3a27ff1acf64cec90..b2131595219b9f2d4064f04f702b339936d648cd 100644
--- a/src/plugins/projectexplorer/session.h
+++ b/src/plugins/projectexplorer/session.h
@@ -144,7 +144,7 @@ public:
     SessionNode *sessionNode() const;
 
     Project *projectForNode(ProjectExplorer::Node *node) const;
-    Node *nodeForFile(const QString &fileName) const;
+    Node *nodeForFile(const QString &fileName, Project *project = 0) const;
     Project *projectForFile(const QString &fileName) const;
 
 
diff --git a/src/plugins/qt4projectmanager/qt4runconfiguration.cpp b/src/plugins/qt4projectmanager/qt4runconfiguration.cpp
index 483ea16ff35e3986f6d03f312c63c4a0b2ed1544..8d784f5f4905ea31fa1269b4b43a97a2f11b4708 100644
--- a/src/plugins/qt4projectmanager/qt4runconfiguration.cpp
+++ b/src/plugins/qt4projectmanager/qt4runconfiguration.cpp
@@ -299,7 +299,7 @@ void Qt4RunConfiguration::updateCachedValues()
     }
 
 #if defined (Q_OS_MAC)
-    if (!reader->values("-CONFIG").contains("app_bundle")) {
+    if (reader->values("CONFIG").contains("app_bundle")) {
         destDir += QLatin1Char('/')
                    + "${QMAKE_TARGET}"
                    + QLatin1String(".app/Contents/MacOS");
diff --git a/src/shared/proparser/profileevaluator.cpp b/src/shared/proparser/profileevaluator.cpp
index b1498cee99523ccdc8867420067a01b84e67ec5a..522438d7ce6aeb36570846c5a9b72d49b5b7a9f6 100644
--- a/src/shared/proparser/profileevaluator.cpp
+++ b/src/shared/proparser/profileevaluator.cpp
@@ -781,18 +781,9 @@ bool ProFileEvaluator::Private::visitProValue(ProValue *value)
         case ProVariable::RemoveOperator:       // -=
             if (!m_cumulative) {
                 if (!m_skipLevel) {
-                    // the insertUnique is a hack for the moment to fix the
-                    // CONFIG -= app_bundle problem on Mac (add it to a variable -CONFIG as was done before)
-                    if (removeEach(&m_tempValuemap, varName, v) == 0)
-                        insertUnique(&m_tempValuemap, QString("-%1").arg(varName), v);
-                    if (removeEach(&m_tempFilevaluemap[currentProFile()], varName, v) == 0)
-                        insertUnique(&m_tempFilevaluemap[currentProFile()], QString("-%1").arg(varName), v);
+                    removeEach(&m_tempValuemap, varName, v);
+                    removeEach(&m_tempFilevaluemap[currentProFile()], varName, v);
                 }
-            } else if (!m_skipLevel) {
-                // the insertUnique is a hack for the moment to fix the
-                // CONFIG -= app_bundle problem on Mac (add it to a variable -CONFIG as was done before)
-                insertUnique(&m_tempValuemap, QString("-%1").arg(varName), v);
-                insertUnique(&m_tempFilevaluemap[currentProFile()], QString("-%1").arg(varName), v);
             } else {
                 // We are stingy with our values, too.
             }
@@ -987,11 +978,9 @@ QString ProFileEvaluator::Private::currentDirectory() const
 
 QStringList ProFileEvaluator::Private::expandVariableReferences(const QString &str)
 {
-    bool fOK;
-    bool *ok = &fOK;
     QStringList ret;
-    if (ok)
-        *ok = true;
+//    if (ok)
+//        *ok = true;
     if (str.isEmpty())
         return ret;
 
@@ -1007,7 +996,10 @@ QStringList ProFileEvaluator::Private::expandVariableReferences(const QString &s
     const ushort DOT = '.';
     const ushort SPACE = ' ';
     const ushort TAB = '\t';
+    const ushort SINGLEQUOTE = '\'';
+    const ushort DOUBLEQUOTE = '"';
 
+    ushort unicode, quote = 0;
     const QChar *str_data = str.data();
     const int str_len = str.length();
 
@@ -1017,126 +1009,105 @@ QStringList ProFileEvaluator::Private::expandVariableReferences(const QString &s
     int replaced = 0;
     QString current;
     for (int i = 0; i < str_len; ++i) {
-        ushort c = str_data[i].unicode();
+        unicode = str_data[i].unicode();
         const int start_var = i;
-        if (c == BACKSLASH) {
-            bool escape = false;
-            const char *symbols = "[]{}()$\\";
-            for (const char *s = symbols; *s; ++s) {
-                if (str_data[i+1] == (ushort)*s) {
-                    i++;
-                    escape = true;
-                    if (!(replaced++))
-                        current = str.left(start_var);
-                    current.append(str.at(i));
-                    break;
-                }
-            }
-            if (!escape && replaced)
-                current.append(QChar(c));
-            continue;
-        }
-        if (c == SPACE || c == TAB) {
-            c = 0;
-            if (!current.isEmpty()) {
-                unquote(&current);
-                ret.append(current);
-                current.clear();
-            }
-        } else if (c == DOLLAR && str_len > i+2) {
-            c = str_data[++i].unicode();
-            if (c == DOLLAR) {
+        if (unicode == DOLLAR && str_len > i+2) {
+            unicode = str_data[++i].unicode();
+            if (unicode == DOLLAR) {
                 term = 0;
                 var.clear();
                 args.clear();
                 enum { VAR, ENVIRON, FUNCTION, PROPERTY } var_type = VAR;
-                c = str_data[++i].unicode();
-                if (c == LSQUARE) {
-                    c = str_data[++i].unicode();
+                unicode = str_data[++i].unicode();
+                if (unicode == LSQUARE) {
+                    unicode = str_data[++i].unicode();
                     term = RSQUARE;
                     var_type = PROPERTY;
-                } else if (c == LCURLY) {
-                    c = str_data[++i].unicode();
+                } else if (unicode == LCURLY) {
+                    unicode = str_data[++i].unicode();
                     var_type = VAR;
                     term = RCURLY;
-                } else if (c == LPAREN) {
-                    c = str_data[++i].unicode();
+                } else if (unicode == LPAREN) {
+                    unicode = str_data[++i].unicode();
                     var_type = ENVIRON;
                     term = RPAREN;
                 }
-                while (1) {
-                    if (!(c & (0xFF<<8)) &&
-                       c != DOT && c != UNDERSCORE &&
-                       (c < 'a' || c > 'z') && (c < 'A' || c > 'Z') && (c < '0' || c > '9'))
+                forever {
+                    if (!(unicode & (0xFF<<8)) &&
+                       unicode != DOT && unicode != UNDERSCORE &&
+                       //unicode != SINGLEQUOTE && unicode != DOUBLEQUOTE &&
+                       (unicode < 'a' || unicode > 'z') && (unicode < 'A' || unicode > 'Z') &&
+                       (unicode < '0' || unicode > '9'))
                         break;
-                    var.append(QChar(c));
+                    var.append(QChar(unicode));
                     if (++i == str_len)
                         break;
-                    c = str_data[i].unicode();
+                    unicode = str_data[i].unicode();
+                    // at this point, i points to either the 'term' or 'next' character (which is in unicode)
                 }
-                if (var_type == VAR && c == LPAREN) {
+                if (var_type == VAR && unicode == LPAREN) {
                     var_type = FUNCTION;
                     int depth = 0;
-                    while (1) {
+                    forever {
                         if (++i == str_len)
                             break;
-                        c = str_data[i].unicode();
-                        if (c == LPAREN) {
+                        unicode = str_data[i].unicode();
+                        if (unicode == LPAREN) {
                             depth++;
-                        } else if (c == RPAREN) {
+                        } else if (unicode == RPAREN) {
                             if (!depth)
                                 break;
                             --depth;
                         }
-                        args.append(QChar(c));
+                        args.append(QChar(unicode));
                     }
-                    if (i < str_len-1)
-                        c = str_data[++i].unicode();
+                    if (++i < str_len)
+                        unicode = str_data[i].unicode();
                     else
-                        c = 0;
+                        unicode = 0;
+                    // at this point i is pointing to the 'next' character (which is in unicode)
+                    // this might actually be a term character since you can do $${func()}
                 }
                 if (term) {
-                    if (c != term) {
+                    if (unicode != term) {
                         q->logMessage(format("Missing %1 terminator [found %2]")
-                            .arg(QChar(term)).arg(QChar(c)));
-                        if (ok)
-                            *ok = false;
+                            .arg(QChar(term))
+                            .arg(unicode ? QString(unicode) : QString::fromLatin1(("end-of-line"))));
+//                        if (ok)
+//                            *ok = false;
                         return QStringList();
                     }
-                    c = 0;
-                } else if (i > str_len-1) {
-                    c = 0;
+                } else {
+                    // move the 'cursor' back to the last char of the thing we were looking at
+                    --i;
                 }
+                // since i never points to the 'next' character, there is no reason for this to be set
+                unicode = 0;
 
                 QStringList replacement;
                 if (var_type == ENVIRON) {
-                    replacement << QString::fromLocal8Bit(qgetenv(var.toLocal8Bit().constData()));
+                    replacement = split_value_list(QString::fromLocal8Bit(qgetenv(var.toLatin1().constData())));
                 } else if (var_type == PROPERTY) {
                     replacement << propertyValue(var);
-                    //if (prop)
-                    //    replacement = QStringList(prop->value(var));
                 } else if (var_type == FUNCTION) {
                     replacement << evaluateExpandFunction(var, args);
                 } else if (var_type == VAR) {
-                    replacement += values(var);
+                    replacement = values(var);
                 }
                 if (!(replaced++) && start_var)
                     current = str.left(start_var);
                 if (!replacement.isEmpty()) {
-                    /* If a list is beteen two strings make sure it expands in such a way
-                     * that the string to the left is prepended to the first string and
-                     * the string to the right is appended to the last string, example:
-                     *  LIST = a b c
-                     *  V3 = x/$$LIST/f.cpp
-                     *  message($$member(V3,0))     # Outputs "x/a"
-                     *  message($$member(V3,1))     # Outputs "b"
-                     *  message($$member(V3,2))     # Outputs "c/f.cpp"
-                     */
-                    current.append(replacement.at(0));
-                    for (int i = 1; i < replacement.count(); ++i) {
-                        unquote(&current);
-                        ret.append(current);
-                        current = replacement.at(i);
+                    if (quote) {
+                        current += replacement.join(QString(Option::field_sep));
+                    } else {
+                        current += replacement.takeFirst();
+                        if (!replacement.isEmpty()) {
+                            if (!current.isEmpty())
+                                ret.append(current);
+                            current = replacement.takeLast();
+                            if (!replacement.isEmpty())
+                                ret += replacement;
+                        }
                     }
                 }
             } else {
@@ -1144,17 +1115,43 @@ QStringList ProFileEvaluator::Private::expandVariableReferences(const QString &s
                     current.append(QLatin1Char('$'));
             }
         }
-        if (replaced && c != 0)
-            current.append(QChar(c));
+        if (quote && unicode == quote) {
+            unicode = 0;
+            quote = 0;
+        } else if (unicode == BACKSLASH) {
+            bool escape = false;
+            const char *symbols = "[]{}()$\\'\"";
+            for (const char *s = symbols; *s; ++s) {
+                if (str_data[i+1].unicode() == (ushort)*s) {
+                    i++;
+                    escape = true;
+                    if (!(replaced++))
+                        current = str.left(start_var);
+                    current.append(str.at(i));
+                    break;
+                }
+            }
+            if (escape || !replaced)
+                unicode =0;
+        } else if (!quote && (unicode == SINGLEQUOTE || unicode == DOUBLEQUOTE)) {
+            quote = unicode;
+            unicode = 0;
+            if (!(replaced++) && i)
+                current = str.left(i);
+        } else if (!quote && (unicode == SPACE || unicode == TAB)) {
+            unicode = 0;
+            if (!current.isEmpty()) {
+                ret.append(current);
+                current.clear();
+            }
+        }
+        if (replaced && unicode)
+            current.append(QChar(unicode));
     }
-    if (!replaced) {
-        current = str;
-        unquote(&current);
+    if (!replaced)
+        ret = QStringList(str);
+    else if (!current.isEmpty())
         ret.append(current);
-    } else if (!current.isEmpty()) {
-        unquote(&current);
-        ret.append(current);
-    }
     return ret;
 }
 
@@ -1456,11 +1453,8 @@ QStringList ProFileEvaluator::Private::evaluateExpandFunction(const QString &fun
                         ret += val;
             }
             break;
-#if 0 // Disabled, as it is relatively useless, too slow and dangerous.
         case E_SYSTEM:
-            if (!m_skipLevel) { // FIXME: should exec only if the result is being used
-                                // (i.e., if this is nested into an assignment) - these
-                                // are less likely to have side effects
+            if (!m_skipLevel) {
                 if (args.count() < 1 || args.count() > 2) {
                     q->logMessage(format("system(execute) requires one or two arguments."));
                 } else {
@@ -1485,7 +1479,6 @@ QStringList ProFileEvaluator::Private::evaluateExpandFunction(const QString &fun
                 }
             }
             break;
-#endif
         case E_UNIQUE:
             if(args.count() != 1) {
                 q->logMessage(format("unique(var) requires one argument."));
@@ -1860,7 +1853,7 @@ bool ProFileEvaluator::Private::evaluateConditionalFunction(const QString &funct
                 dirstr = file.left(slsh+1);
                 file = file.right(file.length() - slsh - 1);
             }
-            if (file.contains('*') || file.contains('?'))
+            if (file.contains(QLatin1Char('*')) || file.contains(QLatin1Char('?')))
                 cond = QDir(dirstr).entryList(QStringList(file)).count();
 
             break;
@@ -2317,17 +2310,10 @@ void evaluateProFile(const ProFileEvaluator &visitor, QHash<QByteArray, QStringL
         + visitor.values(QLatin1String("FORMS3"));
     sourceFiles << forms;
 
-#if QT_VERSION >= 0x040500
     sourceFiles.sort();
     sourceFiles.removeDuplicates();
     tsFileNames.sort();
     tsFileNames.removeDuplicates();
-#else
-    sourceFiles = sourceFiles.toSet().toList();
-    sourceFiles.sort();
-    tsFileNames = tsFileNames.toSet().toList();
-    tsFileNames.sort();
-#endif
 
     varMap->insert("SOURCES", sourceFiles);
     varMap->insert("CODECFORTR", QStringList() << codecForTr);
diff --git a/src/shared/proparser/proparserutils.h b/src/shared/proparser/proparserutils.h
index 5032d325f64bf655c08676131563c766aa73d0d3..05754860386505fe243f2c783157d47797c58628 100644
--- a/src/shared/proparser/proparserutils.h
+++ b/src/shared/proparser/proparserutils.h
@@ -116,17 +116,6 @@ QString Option::dirlist_sep;
 QString Option::dir_sep;
 QChar Option::field_sep;
 
-static void unquote(QString *string)
-{
-    PRE(string);
-    if ( (string->startsWith(QLatin1Char('\"')) && string->endsWith(QLatin1Char('\"')))
-        || (string->startsWith(QLatin1Char('\'')) && string->endsWith(QLatin1Char('\''))) )
-    {
-        string->remove(0,1);
-        string->remove(string->length() - 1,1);
-    }
-}
-
 static void insertUnique(QHash<QString, QStringList> *map,
     const QString &key, const QStringList &value)
 {
@@ -136,14 +125,12 @@ static void insertUnique(QHash<QString, QStringList> *map,
             sl.append(str);
 }
 
-static int removeEach(QHash<QString, QStringList> *map,
+static void removeEach(QHash<QString, QStringList> *map,
     const QString &key, const QStringList &value)
 {
-    int count = 0;
     QStringList &sl = (*map)[key];
     foreach (const QString &str, value)
-        count += sl.removeAll(str);
-    return count;
+        sl.removeAll(str);
 }
 
 /*
@@ -223,7 +210,8 @@ static QStringList split_arg_list(QString params)
             quote = 0;
         } else if (!quote && (unicode == SINGLEQUOTE || unicode == DOUBLEQUOTE)) {
             quote = unicode;
-        } else if (!parens && !quote && unicode == COMMA) {
+        }
+        if (!parens && !quote && unicode == COMMA) {
             QString mid = params.mid(last, x - last).trimmed();
             args << mid;
             last = x+1;
@@ -232,8 +220,6 @@ static QStringList split_arg_list(QString params)
                 ++last;
         }
     }
-    for (int i = 0; i < args.count(); i++)
-        unquote(&args[i]);
     return args;
 }
 
@@ -241,34 +227,35 @@ static QStringList split_value_list(const QString &vals, bool do_semicolon=false
 {
     QString build;
     QStringList ret;
-    QStack<QChar> quote;
+    QStack<char> quote;
 
-    const QChar LPAREN = QLatin1Char('(');
-    const QChar RPAREN = QLatin1Char(')');
-    const QChar SINGLEQUOTE = QLatin1Char('\'');
-    const QChar DOUBLEQUOTE = QLatin1Char('"');
-    const QChar BACKSLASH = QLatin1Char('\\');
-    const QChar SEMICOLON = QLatin1Char(';');
+    const ushort LPAREN = '(';
+    const ushort RPAREN = ')';
+    const ushort SINGLEQUOTE = '\'';
+    const ushort DOUBLEQUOTE = '"';
+    const ushort BACKSLASH = '\\';
+    const ushort SEMICOLON = ';';
 
+    ushort unicode;
     const QChar *vals_data = vals.data();
     const int vals_len = vals.length();
     for (int x = 0, parens = 0; x < vals_len; x++) {
-        QChar c = vals_data[x];
-        if (x != vals_len-1 && c == BACKSLASH &&
-           vals_data[x+1].unicode() == '\'' || vals_data[x+1] == DOUBLEQUOTE) {
-            build += vals_data[x++]; // get that 'escape'
-        } else if (!quote.isEmpty() && c == quote.top()) {
+        unicode = vals_data[x].unicode();
+        if (x != (int)vals_len-1 && unicode == BACKSLASH &&
+            (vals_data[x+1].unicode() == SINGLEQUOTE || vals_data[x+1].unicode() == DOUBLEQUOTE)) {
+            build += vals_data[x++]; //get that 'escape'
+        } else if (!quote.isEmpty() && unicode == quote.top()) {
             quote.pop();
-        } else if (c == SINGLEQUOTE || c == DOUBLEQUOTE) {
-            quote.push(c);
-        } else if (c == RPAREN) {
+        } else if (unicode == SINGLEQUOTE || unicode == DOUBLEQUOTE) {
+            quote.push(unicode);
+        } else if (unicode == RPAREN) {
             --parens;
-        } else if (c == LPAREN) {
+        } else if (unicode == LPAREN) {
             ++parens;
         }
 
-        if (!parens && quote.isEmpty() && ((do_semicolon && c == SEMICOLON) ||
-                                          vals_data[x] == Option::field_sep)) {
+        if (!parens && quote.isEmpty() && ((do_semicolon && unicode == SEMICOLON) ||
+                                           vals_data[x] == Option::field_sep)) {
             ret << build;
             build.clear();
         } else {