diff --git a/src/plugins/coreplugin/coreconstants.h b/src/plugins/coreplugin/coreconstants.h
index ecc1c2a4bc26dcba9e6def2a20d7c8a5e8ec80e3..13081d5ecc764eb311771a26acc443316d63a78e 100644
--- a/src/plugins/coreplugin/coreconstants.h
+++ b/src/plugins/coreplugin/coreconstants.h
@@ -246,6 +246,8 @@ const char * const SETTINGS_CATEGORY_CORE_ICON = ":/core/images/category_core.pn
 const char * const SETTINGS_TR_CATEGORY_CORE = QT_TRANSLATE_NOOP("Core", "Environment");
 const char * const SETTINGS_ID_ENVIRONMENT = "A.General";
 
+const char * const ALL_FILES_FILTER      = QT_TRANSLATE_NOOP("Core", "All Files (*)");
+
 const int TARGET_ICON_SIZE = 32;
 
 } // namespace Constants
diff --git a/src/plugins/coreplugin/dialogs/shortcutsettings.cpp b/src/plugins/coreplugin/dialogs/shortcutsettings.cpp
index 59b5b2e8fe97c9a8348e247dbfaf40d5c442d069..74abe1321e12452d3241ec37c44b16bfdcc8b6e0 100644
--- a/src/plugins/coreplugin/dialogs/shortcutsettings.cpp
+++ b/src/plugins/coreplugin/dialogs/shortcutsettings.cpp
@@ -264,8 +264,7 @@ void ShortcutSettings::exportAction()
     QString fileName = ICore::instance()->fileManager()->getSaveFileNameWithExtension(
         tr("Export Keyboard Mapping Scheme"),
         ICore::instance()->resourcePath() + "/schemes/",
-        tr("Keyboard Mapping Scheme (*.kms)"),
-        ".kms");
+        tr("Keyboard Mapping Scheme (*.kms)"));
     if (!fileName.isEmpty()) {
         CommandsFile cf(fileName);
         cf.exportCommands(m_scitems);
diff --git a/src/plugins/coreplugin/editormanager/editormanager.cpp b/src/plugins/coreplugin/editormanager/editormanager.cpp
index c0e56ac3a8b97d7b3c2295fbe427fd12b015c467..6b58cc7f8508aebec056907f9cbe65ddaa1665d1 100644
--- a/src/plugins/coreplugin/editormanager/editormanager.cpp
+++ b/src/plugins/coreplugin/editormanager/editormanager.cpp
@@ -77,6 +77,8 @@
 #include <QtGui/QSplitter>
 #include <QtGui/QStackedLayout>
 
+#include <algorithm>
+
 Q_DECLARE_METATYPE(Core::IEditor*)
 
 enum { debugEditorManager=0 };
@@ -208,9 +210,6 @@ struct EditorManagerPrivate {
     QMap<QString, QVariant> m_editorStates;
     Internal::OpenEditorsViewFactory *m_openEditorsFactory;
 
-    QString fileFilters;
-    QString selectedFilter;
-
     OpenEditorsModel *m_editorModel;
     QString m_externalEditor;
 
@@ -1152,33 +1151,28 @@ QString EditorManager::getOpenWithEditorId(const QString &fileName,
     return selectedId;
 }
 
-static QString formatFileFilters(const Core::ICore *core, QString *selectedFilter)
+static QString formatFileFilters(const Core::ICore *core, QString *selectedFilter = 0)
 {
-    QString rc;
+    if (selectedFilter)
+        selectedFilter->clear();
 
-    // Compile list of filter strings
+    // Compile list of filter strings, sort, and remove duplicates (different mime types might
+    // generate the same filter).
     QStringList filters = core->mimeDatabase()->filterStrings();
-    filters.sort();
-    selectedFilter->clear();
     if (filters.empty())
-        return rc;
+        return QString();
+    filters.sort();
+    filters.erase(std::unique(filters.begin(), filters.end()), filters.end());
 
-    const QString filterSeparator = QLatin1String(";;");
-    foreach (const QString &filterString, filters) {
-        if (!rc.isEmpty())
-            rc += filterSeparator;
-        rc += filterString;
-    }
+    static const QString allFilesFilter =
+        QCoreApplication::translate("Core", Constants::ALL_FILES_FILTER);
+    if (selectedFilter)
+        *selectedFilter = allFilesFilter;
 
-    // prepend all files filter
-    // prepending instead of appending to work around a bug in Qt/Mac
-    QString allFilesFilter = EditorManager::tr("All Files (*)");
-    if (!rc.isEmpty())
-        allFilesFilter += filterSeparator;
-    rc.prepend(allFilesFilter);
-    *selectedFilter = allFilesFilter;
+    // Prepend all files filter (instead of appending to work around a bug in Qt/Mac).
+    filters.prepend(allFilesFilter);
 
-    return rc;
+    return filters.join(QLatin1String(";;"));
 }
 
 IEditor *EditorManager::openEditor(const QString &fileName, const QString &editorId,
@@ -1244,10 +1238,10 @@ bool EditorManager::openExternalEditor(const QString &fileName, const QString &e
 
 QStringList EditorManager::getOpenFileNames() const
 {
-    if (m_d->fileFilters.isEmpty())
-        m_d->fileFilters = formatFileFilters(m_d->m_core, &m_d->selectedFilter);
-    return ICore::instance()->fileManager()->getOpenFileNames(m_d->fileFilters,
-                                                              QString(), &m_d->selectedFilter);
+    QString selectedFilter;
+    const QString &fileFilters = formatFileFilters(m_d->m_core, &selectedFilter);
+    return ICore::instance()->fileManager()->getOpenFileNames(fileFilters,
+                                                              QString(), &selectedFilter);
 }
 
 
@@ -1475,23 +1469,35 @@ bool EditorManager::saveFileAs(IEditor *editor)
     if (!editor)
         return false;
 
-    QString absoluteFilePath = m_d->m_core->fileManager()->getSaveAsFileName(editor->file());
+    IFile *file = editor->file();
+    const QString &filter = formatFileFilters(m_d->m_core);
+    QString selectedFilter =
+        m_d->m_core->mimeDatabase()->findByFile(QFileInfo(file->fileName())).filterString();
+    const QString &absoluteFilePath =
+        m_d->m_core->fileManager()->getSaveAsFileName(file, filter, &selectedFilter);
+
     if (absoluteFilePath.isEmpty())
         return false;
-    if (absoluteFilePath != editor->file()->fileName()) {
+    if (absoluteFilePath != file->fileName()) {
         const QList<IEditor *> existList = editorsForFileName(absoluteFilePath);
         if (!existList.isEmpty()) {
             closeEditors(existList, false);
         }
     }
 
-    m_d->m_core->fileManager()->blockFileChange(editor->file());
-    const bool success = editor->file()->save(absoluteFilePath);
-    m_d->m_core->fileManager()->unblockFileChange(editor->file());
-    editor->file()->checkPermissions();
+    m_d->m_core->fileManager()->blockFileChange(file);
+    const bool success = file->save(absoluteFilePath);
+    m_d->m_core->fileManager()->unblockFileChange(file);
+    file->checkPermissions();
+
+    // @todo: There is an issue to be treated here. The new file might be of a different mime
+    // type than the original and thus require a different editor. An alternative strategy
+    // would be to close the current editor and open a new appropriate one, but this is not
+    // a good way out either (also the undo stack would be lost). Perhaps the best is to
+    // re-think part of the editors design.
 
     if (success && !editor->isTemporary())
-        m_d->m_core->fileManager()->addToRecentFiles(editor->file()->fileName());
+        m_d->m_core->fileManager()->addToRecentFiles(file->fileName());
 
     updateActions();
     return success;
diff --git a/src/plugins/coreplugin/filemanager.cpp b/src/plugins/coreplugin/filemanager.cpp
index 1551adc04eecc8475435a774eee40742e6c3dcf8..bb5bf60825ff4568fb616d41458716d08afec40a 100644
--- a/src/plugins/coreplugin/filemanager.cpp
+++ b/src/plugins/coreplugin/filemanager.cpp
@@ -37,6 +37,7 @@
 #include "mimedatabase.h"
 #include "saveitemsdialog.h"
 #include "vcsmanager.h"
+#include "coreconstants.h"
 
 #include <utils/qtcassert.h>
 #include <utils/pathchooser.h>
@@ -689,22 +690,45 @@ QList<IFile *> FileManager::saveModifiedFiles(const QList<IFile *> &files,
     return notSaved;
 }
 
-QString FileManager::getSaveFileNameWithExtension(const QString &title, const QString &pathIn,
-    const QString &fileFilter, const QString &extension)
+QString FileManager::getSaveFileName(const QString &title, const QString &pathIn,
+                                     const QString &filter, QString *selectedFilter)
 {
+    const QString &path = pathIn.isEmpty() ? fileDialogInitialDirectory() : pathIn;
     QString fileName;
     bool repeat;
     do {
         repeat = false;
-        const QString path = pathIn.isEmpty() ? fileDialogInitialDirectory() : pathIn;
-        fileName = QFileDialog::getSaveFileName(d->m_mainWindow, title, path, fileFilter);
-        if (!fileName.isEmpty() && !extension.isEmpty() && !fileName.endsWith(extension)) {
-            fileName.append(extension);
+        fileName = QFileDialog::getSaveFileName(
+            d->m_mainWindow, title, path, filter, selectedFilter, QFileDialog::DontConfirmOverwrite);
+        if (!fileName.isEmpty()) {
+            // If the selected filter is All Files (*) we leave the name exactly as the user
+            // specified. Otherwise the suffix must be one available in the selected filter. If
+            // the name already ends with such suffix nothing needs to be done. But if not, the
+            // first one from the filter is appended.
+            if (selectedFilter && *selectedFilter != QCoreApplication::translate(
+                    "Core", Constants::ALL_FILES_FILTER)) {
+                // Mime database creates filter strings like this: Anything here (*.foo *.bar)
+                QRegExp regExp(".*\\s+\\((.*)\\)$");
+                const int index = regExp.lastIndexIn(*selectedFilter);
+                bool suffixOk = false;
+                if (index != -1) {
+                    const QStringList &suffixes = regExp.cap(1).remove('*').split(' ');
+                    foreach (const QString &suffix, suffixes)
+                        if (fileName.endsWith(suffix)) {
+                            suffixOk = true;
+                            break;
+                        }
+                    if (!suffixOk && !suffixes.isEmpty())
+                        fileName.append(suffixes.at(0));
+                }
+            }
             if (QFile::exists(fileName)) {
                 if (QMessageBox::warning(d->m_mainWindow, tr("Overwrite?"),
-                        tr("An item named '%1' already exists at this location. Do you want to overwrite it?").arg(fileName),
-                        QMessageBox::Yes | QMessageBox::No) == QMessageBox::No)
+                    tr("An item named '%1' already exists at this location. "
+                       "Do you want to overwrite it?").arg(fileName),
+                    QMessageBox::Yes | QMessageBox::No) == QMessageBox::No) {
                     repeat = true;
+                }
             }
         }
     } while (repeat);
@@ -713,12 +737,19 @@ QString FileManager::getSaveFileNameWithExtension(const QString &title, const QS
     return fileName;
 }
 
+QString FileManager::getSaveFileNameWithExtension(const QString &title, const QString &pathIn,
+                                                  const QString &filter)
+{
+    QString selected = filter;
+    return getSaveFileName(title, pathIn, filter, &selected);
+}
+
 /*!
     \fn QString FileManager::getSaveAsFileName(IFile *file)
 
     Asks the user for a new file name (Save File As) for /arg file.
 */
-QString FileManager::getSaveAsFileName(IFile *file)
+QString FileManager::getSaveAsFileName(IFile *file, const QString &filter, QString *selectedFilter)
 {
     if (!file)
         return QLatin1String("");
@@ -732,17 +763,20 @@ QString FileManager::getSaveAsFileName(IFile *file)
         if (!defaultPath.isEmpty())
             path = defaultPath;
     }
+
     QString filterString;
-    QString preferredSuffix;
-    if (const MimeType mt = Core::ICore::instance()->mimeDatabase()->findByFile(fi)) {
-        filterString = mt.filterString();
-        preferredSuffix = mt.preferredSuffix();
+    if (filter.isEmpty()) {
+        if (const MimeType &mt = Core::ICore::instance()->mimeDatabase()->findByFile(fi))
+            filterString = mt.filterString();
+        selectedFilter = &filterString;
+    } else {
+        filterString = filter;
     }
 
-    absoluteFilePath = getSaveFileNameWithExtension(tr("Save File As"),
+    absoluteFilePath = getSaveFileName(tr("Save File As"),
         path + QDir::separator() + fileName,
         filterString,
-        preferredSuffix);
+        selectedFilter);
     return absoluteFilePath;
 }
 
diff --git a/src/plugins/coreplugin/filemanager.h b/src/plugins/coreplugin/filemanager.h
index 9834bce17e58c13cbcf35df9ab6e5ce16a9fc905..0de993330843849ee26f85d29074418e53e58859 100644
--- a/src/plugins/coreplugin/filemanager.h
+++ b/src/plugins/coreplugin/filemanager.h
@@ -87,10 +87,12 @@ public:
     QStringList getOpenFileNames(const QString &filters,
                                  const QString path = QString(),
                                  QString *selectedFilter = 0);
-
-    QString getSaveFileNameWithExtension(const QString &title, const QString &path,
-                                    const QString &fileFilter, const QString &extension);
-    QString getSaveAsFileName(IFile *file);
+    QString getSaveFileName(const QString &title, const QString &pathIn,
+                            const QString &filter = QString(), QString *selectedFilter = 0);
+    QString getSaveFileNameWithExtension(const QString &title, const QString &pathIn,
+                                         const QString &filter);
+    QString getSaveAsFileName(IFile *file, const QString &filter = QString(),
+                              QString *selectedFilter = 0);
 
     QList<IFile *> saveModifiedFilesSilently(const QList<IFile *> &files);
     QList<IFile *> saveModifiedFiles(const QList<IFile *> &files,
diff --git a/src/plugins/cpptools/cppcurrentdocumentfilter.cpp b/src/plugins/cpptools/cppcurrentdocumentfilter.cpp
index 60107acf4f3bcd3b1ae5493dbb8e028e8a9a9188..838e0c1191db5c2323d3ab7f0d7d2a66efac51c1 100644
--- a/src/plugins/cpptools/cppcurrentdocumentfilter.cpp
+++ b/src/plugins/cpptools/cppcurrentdocumentfilter.cpp
@@ -58,7 +58,7 @@ CppCurrentDocumentFilter::CppCurrentDocumentFilter(CppModelManager *manager, Cor
             this,          SLOT(onEditorAboutToClose(Core::IEditor*)));
 }
 
-QList<Locator::FilterEntry> CppCurrentDocumentFilter::matchesFor(const QString & origEntry)
+QList<Locator::FilterEntry> CppCurrentDocumentFilter::matchesFor(QFutureInterface<Locator::FilterEntry> &future, const QString & origEntry)
 {
     QString entry = trimWildcards(origEntry);
     QList<Locator::FilterEntry> goodEntries;
@@ -82,6 +82,9 @@ QList<Locator::FilterEntry> CppCurrentDocumentFilter::matchesFor(const QString &
 
     foreach (const ModelItemInfo & info, m_itemsOfCurrentDoc)
     {
+        if (future.isCanceled())
+            break;
+
         if ((hasWildcard && regexp.exactMatch(info.symbolName))
             || (!hasWildcard && matcher.indexIn(info.symbolName) != -1))
         {
diff --git a/src/plugins/cpptools/cppcurrentdocumentfilter.h b/src/plugins/cpptools/cppcurrentdocumentfilter.h
index 0231124eb3a12f19ec9a8216674067562069de61..6f4bbbc5cd4eb5539d7bc740146fa96e54596d70 100644
--- a/src/plugins/cpptools/cppcurrentdocumentfilter.h
+++ b/src/plugins/cpptools/cppcurrentdocumentfilter.h
@@ -53,7 +53,7 @@ public:
     QString displayName() const { return tr("Methods in current Document"); }
     QString id() const { return QLatin1String("Methods in current Document"); }
     Priority priority() const { return Medium; }
-    QList<Locator::FilterEntry> matchesFor(const QString &entry);
+    QList<Locator::FilterEntry> matchesFor(QFutureInterface<Locator::FilterEntry> &future, const QString &entry);
     void accept(Locator::FilterEntry selection) const;
     void refresh(QFutureInterface<void> &future);
 
diff --git a/src/plugins/cpptools/cpplocatorfilter.cpp b/src/plugins/cpptools/cpplocatorfilter.cpp
index 2b10afdce60f1518f0f4bab24cc39b95526f44b1..62162025d252d809396f682ed307ae82aa9027a4 100644
--- a/src/plugins/cpptools/cpplocatorfilter.cpp
+++ b/src/plugins/cpptools/cpplocatorfilter.cpp
@@ -76,7 +76,7 @@ static bool compareLexigraphically(const Locator::FilterEntry &a,
     return a.displayName < b.displayName;
 }
 
-QList<Locator::FilterEntry> CppLocatorFilter::matchesFor(const QString &origEntry)
+QList<Locator::FilterEntry> CppLocatorFilter::matchesFor(QFutureInterface<Locator::FilterEntry> &future, const QString &origEntry)
 {
     QString entry = trimWildcards(origEntry);
     QList<Locator::FilterEntry> goodEntries;
@@ -90,6 +90,9 @@ QList<Locator::FilterEntry> CppLocatorFilter::matchesFor(const QString &origEntr
 
     QHashIterator<QString, QList<ModelItemInfo> > it(m_searchList);
     while (it.hasNext()) {
+        if (future.isCanceled())
+            break;
+
         it.next();
 
         const QList<ModelItemInfo> items = it.value();
diff --git a/src/plugins/cpptools/cpplocatorfilter.h b/src/plugins/cpptools/cpplocatorfilter.h
index 7b13adc6c7fa83b66cf4cd47b4b63910be89678e..c58a9100c1b47d41cd29311bf231f19e34891639 100644
--- a/src/plugins/cpptools/cpplocatorfilter.h
+++ b/src/plugins/cpptools/cpplocatorfilter.h
@@ -48,7 +48,7 @@ public:
     QString displayName() const { return tr("Classes and Methods"); }
     QString id() const { return QLatin1String("Classes and Methods"); }
     Priority priority() const { return Medium; }
-    QList<Locator::FilterEntry> matchesFor(const QString &entry);
+    QList<Locator::FilterEntry> matchesFor(QFutureInterface<Locator::FilterEntry> &future, const QString &entry);
     void accept(Locator::FilterEntry selection) const;
     void refresh(QFutureInterface<void> &future);
 
diff --git a/src/plugins/help/helpindexfilter.cpp b/src/plugins/help/helpindexfilter.cpp
index 10c4fc06f59b1f855054bffba1cf9ba9b83e9f0b..5bb20698ed1eee62b61a480a22308f860bba6551 100644
--- a/src/plugins/help/helpindexfilter.cpp
+++ b/src/plugins/help/helpindexfilter.cpp
@@ -70,7 +70,7 @@ ILocatorFilter::Priority HelpIndexFilter::priority() const
     return Medium;
 }
 
-QList<FilterEntry> HelpIndexFilter::matchesFor(const QString &entry)
+QList<FilterEntry> HelpIndexFilter::matchesFor(QFutureInterface<Locator::FilterEntry> &future, const QString &entry)
 {
     QStringList keywords;
     if (entry.length() < 2)
@@ -79,8 +79,11 @@ QList<FilterEntry> HelpIndexFilter::matchesFor(const QString &entry)
         keywords = Core::HelpManager::instance()->findKeywords(entry);
 
     QList<FilterEntry> entries;
-    foreach (const QString &keyword, keywords)
+    foreach (const QString &keyword, keywords) {
+        if (future.isCanceled())
+            break;
         entries.append(FilterEntry(this, keyword, QVariant(), m_icon));
+    }
 
     return entries;
 }
diff --git a/src/plugins/help/helpindexfilter.h b/src/plugins/help/helpindexfilter.h
index dde609b3f549e772a1c339280d37a7b365671b4a..0203890b90ba3e98d4d4e68dd79cf6f21d983379 100644
--- a/src/plugins/help/helpindexfilter.h
+++ b/src/plugins/help/helpindexfilter.h
@@ -49,7 +49,7 @@ public:
     QString displayName() const;
     QString id() const;
     Priority priority() const;
-    QList<Locator::FilterEntry> matchesFor(const QString &entry);
+    QList<Locator::FilterEntry> matchesFor(QFutureInterface<Locator::FilterEntry> &future, const QString &entry);
     void accept(Locator::FilterEntry selection) const;
     void refresh(QFutureInterface<void> &future);
 
diff --git a/src/plugins/help/remotehelpfilter.cpp b/src/plugins/help/remotehelpfilter.cpp
index 8fcbeae3eda29313be429c888274306892a9b307..05a7f462186b9d3554a1f6721c39efe513f22ef6 100644
--- a/src/plugins/help/remotehelpfilter.cpp
+++ b/src/plugins/help/remotehelpfilter.cpp
@@ -100,10 +100,13 @@ Locator::ILocatorFilter::Priority RemoteHelpFilter::priority() const
     return Medium;
 }
 
-QList<Locator::FilterEntry> RemoteHelpFilter::matchesFor(const QString &pattern)
+QList<Locator::FilterEntry> RemoteHelpFilter::matchesFor(QFutureInterface<Locator::FilterEntry> &future, const QString &pattern)
 {
     QList<Locator::FilterEntry> entries;
     foreach (const QString &url, m_remoteUrls) {
+        if (future.isCanceled())
+            break;
+
         entries.append(Locator::FilterEntry(this, url.arg(pattern), QVariant(),
             m_icon));
     }
diff --git a/src/plugins/help/remotehelpfilter.h b/src/plugins/help/remotehelpfilter.h
index e2d32fbb329fb2c2d34539c52a2d6d8791a73bdf..5c858de33cfc9af033f9296d35d64a3f48986fbf 100644
--- a/src/plugins/help/remotehelpfilter.h
+++ b/src/plugins/help/remotehelpfilter.h
@@ -50,7 +50,7 @@ public:
     QString displayName() const;
     QString id() const;
     Priority priority() const;
-    QList<Locator::FilterEntry> matchesFor(const QString &entry);
+    QList<Locator::FilterEntry> matchesFor(QFutureInterface<Locator::FilterEntry> &future, const QString &entry);
     void accept(Locator::FilterEntry selection) const;
     void refresh(QFutureInterface<void> &future);
     QByteArray saveState() const;
diff --git a/src/plugins/locator/basefilefilter.cpp b/src/plugins/locator/basefilefilter.cpp
index 4f35ec7d827ec93f26caecc12845e990170513e1..5ba5437cbc5007c20741de93fdf18901a5b3eb34 100644
--- a/src/plugins/locator/basefilefilter.cpp
+++ b/src/plugins/locator/basefilefilter.cpp
@@ -42,7 +42,7 @@ BaseFileFilter::BaseFileFilter()
 {
 }
 
-QList<FilterEntry> BaseFileFilter::matchesFor(const QString &origEntry)
+QList<FilterEntry> BaseFileFilter::matchesFor(QFutureInterface<Locator::FilterEntry> &future, const QString &origEntry)
 {
     updateFiles();
     QList<FilterEntry> matches;
@@ -70,6 +70,9 @@ QList<FilterEntry> BaseFileFilter::matchesFor(const QString &origEntry)
     QStringListIterator paths(searchListPaths);
     QStringListIterator names(searchListNames);
     while (paths.hasNext() && names.hasNext()) {
+        if (future.isCanceled())
+            break;
+
         QString path = paths.next();
         QString name = names.next();
         if ((hasWildcard && regexp.exactMatch(name))
diff --git a/src/plugins/locator/basefilefilter.h b/src/plugins/locator/basefilefilter.h
index ee942694463721230a2c56952e5abd29d0759ddc..707a61dc2617d997e0a029c27b0af959c6efa019 100644
--- a/src/plugins/locator/basefilefilter.h
+++ b/src/plugins/locator/basefilefilter.h
@@ -43,7 +43,7 @@ class LOCATOR_EXPORT BaseFileFilter : public Locator::ILocatorFilter
 
 public:
     BaseFileFilter();
-    QList<Locator::FilterEntry> matchesFor(const QString &entry);
+    QList<Locator::FilterEntry> matchesFor(QFutureInterface<Locator::FilterEntry> &future, const QString &entry);
     void accept(Locator::FilterEntry selection) const;
 
 protected:
diff --git a/src/plugins/locator/commandlocator.cpp b/src/plugins/locator/commandlocator.cpp
index fa3684f60d6f83798d0621155dcdf08073ffd274..cb1aa287c3bf2a6a491d1d8508c1a1a766b10945 100644
--- a/src/plugins/locator/commandlocator.cpp
+++ b/src/plugins/locator/commandlocator.cpp
@@ -84,7 +84,7 @@ ILocatorFilter::Priority CommandLocator::priority() const
     return Medium;
 }
 
-QList<Locator::FilterEntry> CommandLocator::matchesFor(const QString &entry)
+QList<Locator::FilterEntry> CommandLocator::matchesFor(QFutureInterface<Locator::FilterEntry> &future, const QString &entry)
 {
     QList<FilterEntry> filters;
     // Get active, enabled actions matching text, store in list.
@@ -92,6 +92,8 @@ QList<Locator::FilterEntry> CommandLocator::matchesFor(const QString &entry)
     const QChar ampersand = QLatin1Char('&');
     const int count = d->commands.size();
     for (int i = 0; i  < count; i++) {
+        if (future.isCanceled())
+            break;
         if (d->commands.at(i)->isActive()) {
             if (QAction *action = d->commands.at(i)->action())
                 if (action->isEnabled()) {
diff --git a/src/plugins/locator/commandlocator.h b/src/plugins/locator/commandlocator.h
index bc18667191ed63577d78f50b00eff92529c5de49..186bf9e916deb93561ce5e21887a60281f064c7c 100644
--- a/src/plugins/locator/commandlocator.h
+++ b/src/plugins/locator/commandlocator.h
@@ -64,7 +64,7 @@ public:
     virtual QString displayName() const;
     virtual QString id() const;
     virtual Priority priority() const;
-    virtual QList<FilterEntry> matchesFor(const QString &entry);
+    virtual QList<FilterEntry> matchesFor(QFutureInterface<Locator::FilterEntry> &future, const QString &entry);
     virtual void accept(FilterEntry selection) const;
     virtual void refresh(QFutureInterface<void> &future);
 
diff --git a/src/plugins/locator/filesystemfilter.cpp b/src/plugins/locator/filesystemfilter.cpp
index 6ef07bdbaec0cbc784b6fe685dd74ea340dc0425..fe24241dbe34ac489c9406b6c8a6010881b577d8 100644
--- a/src/plugins/locator/filesystemfilter.cpp
+++ b/src/plugins/locator/filesystemfilter.cpp
@@ -45,7 +45,7 @@ FileSystemFilter::FileSystemFilter(EditorManager *editorManager, LocatorWidget *
     setIncludedByDefault(false);
 }
 
-QList<FilterEntry> FileSystemFilter::matchesFor(const QString &entry)
+QList<FilterEntry> FileSystemFilter::matchesFor(QFutureInterface<Locator::FilterEntry> &future, const QString &entry)
 {
     QList<FilterEntry> value;
     QFileInfo entryInfo(entry);
@@ -75,6 +75,8 @@ QList<FilterEntry> FileSystemFilter::matchesFor(const QString &entry)
     QStringList files = dirInfo.entryList(fileFilter,
                                       QDir::Name|QDir::IgnoreCase|QDir::LocaleAware);
     foreach (const QString &dir, dirs) {
+        if (future.isCanceled())
+            break;
         if (dir != QLatin1String(".") && (name.isEmpty() || dir.startsWith(name, Qt::CaseInsensitive))) {
             FilterEntry filterEntry(this, dir, dirInfo.filePath(dir));
             filterEntry.resolveFileIcon = true;
@@ -82,6 +84,8 @@ QList<FilterEntry> FileSystemFilter::matchesFor(const QString &entry)
         }
     }
     foreach (const QString &file, files) {
+        if (future.isCanceled())
+            break;
         if (name.isEmpty() || file.startsWith(name, Qt::CaseInsensitive)) {
             const QString fullPath = dirInfo.filePath(file);
             FilterEntry filterEntry(this, file, fullPath);
diff --git a/src/plugins/locator/filesystemfilter.h b/src/plugins/locator/filesystemfilter.h
index 07ab3414a520c75e1d51bcbcc259acf58c93c2ce..21b740c6d691619702755a5cfeff0b5b311e6ba4 100644
--- a/src/plugins/locator/filesystemfilter.h
+++ b/src/plugins/locator/filesystemfilter.h
@@ -56,7 +56,7 @@ public:
     QString displayName() const { return tr("Files in file system"); }
     QString id() const { return "Files in file system"; }
     Locator::ILocatorFilter::Priority priority() const { return Locator::ILocatorFilter::Medium; }
-    QList<Locator::FilterEntry> matchesFor(const QString &entry);
+    QList<Locator::FilterEntry> matchesFor(QFutureInterface<Locator::FilterEntry> &future, const QString &entry);
     void accept(Locator::FilterEntry selection) const;
     QByteArray saveState() const;
     bool restoreState(const QByteArray &state);
diff --git a/src/plugins/locator/ilocatorfilter.h b/src/plugins/locator/ilocatorfilter.h
index f3207c208734ce6d347f98513a6e56f2452934ac..7f519d7fe1c14d8c3402034f93fd5d7ba884d733 100644
--- a/src/plugins/locator/ilocatorfilter.h
+++ b/src/plugins/locator/ilocatorfilter.h
@@ -100,7 +100,7 @@ public:
     QString shortcutString() const;
 
     /* List of matches for the given user entry. */
-    virtual QList<FilterEntry> matchesFor(const QString &entry) = 0;
+    virtual QList<FilterEntry> matchesFor(QFutureInterface<Locator::FilterEntry> &future, const QString &entry) = 0;
 
     /* User has selected the given entry that belongs to this filter. */
     virtual void accept(FilterEntry selection) const = 0;
diff --git a/src/plugins/locator/locatorfiltersfilter.cpp b/src/plugins/locator/locatorfiltersfilter.cpp
index f02e63d4f3741316b566e282860b2c273a3b2c39..a0fe20c46432bc5c5ee6d69cde90b7e6cd9acd52 100644
--- a/src/plugins/locator/locatorfiltersfilter.cpp
+++ b/src/plugins/locator/locatorfiltersfilter.cpp
@@ -63,11 +63,13 @@ ILocatorFilter::Priority LocatorFiltersFilter::priority() const
     return High;
 }
 
-QList<FilterEntry> LocatorFiltersFilter::matchesFor(const QString &entry)
+QList<FilterEntry> LocatorFiltersFilter::matchesFor(QFutureInterface<Locator::FilterEntry> &future, const QString &entry)
 {
     QList<FilterEntry> entries;
     if (entry.isEmpty()) {
         foreach (ILocatorFilter *filter, m_plugin->filters()) {
+            if (future.isCanceled())
+                break;
             if (!filter->shortcutString().isEmpty() && !filter->isHidden()) {
                 FilterEntry filterEntry(this,
                                   filter->shortcutString(),
diff --git a/src/plugins/locator/locatorfiltersfilter.h b/src/plugins/locator/locatorfiltersfilter.h
index ea7d5d75aa1bcd6928aec3953a6710be9e855819..2b7d22e12b2956efb1cd63eb589efbdc526ac327 100644
--- a/src/plugins/locator/locatorfiltersfilter.h
+++ b/src/plugins/locator/locatorfiltersfilter.h
@@ -56,7 +56,7 @@ public:
     QString displayName() const;
     QString id() const;
     Priority priority() const;
-    QList<FilterEntry> matchesFor(const QString &entry);
+    QList<FilterEntry> matchesFor(QFutureInterface<Locator::FilterEntry> &future, const QString &entry);
     void accept(FilterEntry selection) const;
     void refresh(QFutureInterface<void> &future);
     bool isConfigurable() const;
diff --git a/src/plugins/locator/locatorwidget.cpp b/src/plugins/locator/locatorwidget.cpp
index 0ee99048ea07d7ef59c0aba86b14fda438a6fa22..4ea486caddc8460eb610d07ed364815b3156ae11 100644
--- a/src/plugins/locator/locatorwidget.cpp
+++ b/src/plugins/locator/locatorwidget.cpp
@@ -428,7 +428,7 @@ QList<ILocatorFilter*> LocatorWidget::filtersFor(const QString &text, QString &s
     return activeFilters;
 }
 
-static void filter_helper(QFutureInterface<FilterEntry> &entries, QList<ILocatorFilter *> filters, QString searchText)
+static void filter_helper(QFutureInterface<Locator::FilterEntry> &entries, QList<ILocatorFilter *> filters, QString searchText)
 {
     QSet<FilterEntry> alreadyAdded;
     const bool checkDuplicates = (filters.size() > 1);
@@ -436,7 +436,7 @@ static void filter_helper(QFutureInterface<FilterEntry> &entries, QList<ILocator
         if (entries.isCanceled())
             break;
 
-        foreach (const FilterEntry &entry, filter->matchesFor(searchText)) {
+        foreach (const FilterEntry &entry, filter->matchesFor(entries, searchText)) {
             if (checkDuplicates && alreadyAdded.contains(entry))
                 continue;
             entries.reportResult(entry);
@@ -453,6 +453,7 @@ void LocatorWidget::updateCompletionList(const QString &text)
 
     // cancel the old future
     m_entriesWatcher->future().cancel();
+    m_entriesWatcher->future().waitForFinished();
 
     QFuture<FilterEntry> future = QtConcurrent::run(filter_helper, filters, searchText);
     m_entriesWatcher->setFuture(future);
diff --git a/src/plugins/locator/opendocumentsfilter.cpp b/src/plugins/locator/opendocumentsfilter.cpp
index 535d670e4703a053011e189d255aa7b725c9e098..0c06aff5a13fdd1e2b83baae0c6cca291f013c64 100644
--- a/src/plugins/locator/opendocumentsfilter.cpp
+++ b/src/plugins/locator/opendocumentsfilter.cpp
@@ -49,7 +49,7 @@ OpenDocumentsFilter::OpenDocumentsFilter(EditorManager *editorManager) :
     setIncludedByDefault(true);
 }
 
-QList<FilterEntry> OpenDocumentsFilter::matchesFor(const QString &entry)
+QList<FilterEntry> OpenDocumentsFilter::matchesFor(QFutureInterface<Locator::FilterEntry> &future, const QString &entry)
 {
     QList<FilterEntry> value;
     const QChar asterisk = QLatin1Char('*');
@@ -60,6 +60,8 @@ QList<FilterEntry> OpenDocumentsFilter::matchesFor(const QString &entry)
     if (!regexp.isValid())
         return value;
     foreach (const OpenEditorsModel::Entry &editorEntry, m_editors) {
+        if (future.isCanceled())
+            break;
         QString fileName = editorEntry.fileName();
         QString displayName = editorEntry.displayName();
         if (regexp.exactMatch(displayName)) {
diff --git a/src/plugins/locator/opendocumentsfilter.h b/src/plugins/locator/opendocumentsfilter.h
index 3b419b980be3ce3e206b75b769d41bdafdbe4a25..33fe15a0621accae5e1e2979d8e635810eb96a60 100644
--- a/src/plugins/locator/opendocumentsfilter.h
+++ b/src/plugins/locator/opendocumentsfilter.h
@@ -55,7 +55,7 @@ public:
     QString displayName() const { return tr("Open documents"); }
     QString id() const { return "Open documents"; }
     Locator::ILocatorFilter::Priority priority() const { return Locator::ILocatorFilter::Medium; }
-    QList<Locator::FilterEntry> matchesFor(const QString &entry);
+    QList<Locator::FilterEntry> matchesFor(QFutureInterface<Locator::FilterEntry> &future, const QString &entry);
     void accept(Locator::FilterEntry selection) const;
     void refresh(QFutureInterface<void> &future);
 
diff --git a/src/plugins/projectexplorer/customwizard/customwizard.cpp b/src/plugins/projectexplorer/customwizard/customwizard.cpp
index 7f4c5107b6169044a4e6b7d573f83837eba988a4..2943e55dfd3f7327b0677be4a31f20c0c0c40fab 100644
--- a/src/plugins/projectexplorer/customwizard/customwizard.cpp
+++ b/src/plugins/projectexplorer/customwizard/customwizard.cpp
@@ -182,6 +182,18 @@ template <class WizardPage>
     return 0;
 }
 
+// Determine where to run the generator script. The user may specify
+// an expression subject to field replacement, default is the target path.
+static inline QString scriptWorkingDirectory(const QSharedPointer<Internal::CustomWizardContext> &ctx,
+                                             const QSharedPointer<Internal::CustomWizardParameters> &p)
+{
+    if (p->filesGeneratorScriptWorkingDirectory.isEmpty())
+        return ctx->targetPath;
+    QString path = p->filesGeneratorScriptWorkingDirectory;
+    Internal::CustomWizardContext::replaceFields(ctx->replacements, &path);
+    return path;
+}
+
 Core::GeneratedFiles CustomWizard::generateFiles(const QWizard *dialog, QString *errorMessage) const
 {
     // Look for the Custom field page to find the path
@@ -215,17 +227,18 @@ bool CustomWizard::writeFiles(const Core::GeneratedFiles &files, QString *errorM
     // project wizard that is entirely created by a script,
     // the target project directory might not exist.
     const CustomWizardContextPtr ctx = context();
-    QDir targetPathDir(ctx->targetPath);
-    if (!targetPathDir.exists()) {
+    const QString scriptWorkingDir = scriptWorkingDirectory(ctx, d->m_parameters);
+    const QDir scriptWorkingDirDir(scriptWorkingDir);
+    if (!scriptWorkingDirDir.exists()) {
         if (CustomWizardPrivate::verbose)
-            qDebug("Creating directory %s", qPrintable(ctx->targetPath));
-        if (!targetPathDir.mkpath(ctx->targetPath)) {
-            *errorMessage = QString::fromLatin1("Unable to create the target directory '%1'").arg(ctx->targetPath);
+            qDebug("Creating directory %s", qPrintable(scriptWorkingDir));
+        if (!scriptWorkingDirDir.mkpath(scriptWorkingDir)) {
+            *errorMessage = QString::fromLatin1("Unable to create the target directory '%1'").arg(scriptWorkingDir);
             return false;
         }
     }
     // Run the custom script to actually generate the files.
-    if (!Internal::runCustomWizardGeneratorScript(ctx->targetPath,
+    if (!Internal::runCustomWizardGeneratorScript(scriptWorkingDir,
                                                   d->m_parameters->filesGeneratorScript,
                                                   d->m_parameters->filesGeneratorScriptArguments,
                                                   ctx->replacements, errorMessage))
@@ -254,10 +267,11 @@ Core::GeneratedFiles CustomWizard::generateWizardFiles(QString *errorMessage) co
 
     // If generator script is non-empty, do a dry run to get it's files.
     if (!d->m_parameters->filesGeneratorScript.isEmpty()) {
-        rc += Internal::dryRunCustomWizardGeneratorScript(ctx->targetPath,
+        rc += Internal::dryRunCustomWizardGeneratorScript(scriptWorkingDirectory(ctx, d->m_parameters),
                                                           d->m_parameters->filesGeneratorScript,
                                                           d->m_parameters->filesGeneratorScriptArguments,
-                                                          ctx->replacements, errorMessage);
+                                                          ctx->replacements,
+                                                          errorMessage);
         if (rc.isEmpty())
             return rc;
     }
@@ -276,6 +290,9 @@ CustomWizard::FieldReplacementMap CustomWizard::replacementMap(const QWizard *w)
         const QString value = w->field(field.name).toString();
         fieldReplacementMap.insert(field.name, value);
     }
+    // Insert paths for generator scripts.
+    fieldReplacementMap.insert(QLatin1String("Path"), QDir::toNativeSeparators(context()->path));
+    fieldReplacementMap.insert(QLatin1String("TargetPath"), QDir::toNativeSeparators(context()->targetPath));
     return fieldReplacementMap;
 }
 
diff --git a/src/plugins/projectexplorer/customwizard/customwizardparameters.cpp b/src/plugins/projectexplorer/customwizard/customwizardparameters.cpp
index 6efcd8d6ec2f21780d9c788727f646054e692bbb..6ccca0449895df5bcf8b07571c94b95abf2cafa4 100644
--- a/src/plugins/projectexplorer/customwizard/customwizardparameters.cpp
+++ b/src/plugins/projectexplorer/customwizard/customwizardparameters.cpp
@@ -72,6 +72,7 @@ static const char comboEntryTextElementC[] = "comboentrytext";
 
 static const char generatorScriptElementC[] = "generatorscript";
 static const char generatorScriptBinaryAttributeC[] = "binary";
+static const char generatorScriptWorkingDirectoryAttributeC[] = "workingdirectory";
 static const char generatorScriptArgumentElementC[] = "argument";
 static const char generatorScriptArgumentValueAttributeC[] = "value";
 static const char generatorScriptArgumentOmitEmptyAttributeC[] = "omit-empty";
@@ -557,6 +558,7 @@ CustomWizardParameters::ParseResult
                         *errorMessage = QString::fromLatin1("No binary specified for generator script.");
                         return ParseFailed;
                     }
+                    filesGeneratorScriptWorkingDirectory = attributeValue(reader, generatorScriptWorkingDirectoryAttributeC);
                     break;
                 case ParseWithinScriptArguments: {
                     GeneratorScriptArgument argument(attributeValue(reader, generatorScriptArgumentValueAttributeC));
@@ -623,6 +625,8 @@ QString CustomWizardParameters::toString() const
         str << "Script:";
         foreach(const QString &a, filesGeneratorScript)
             str << " '" << a << '\'';
+        if (!filesGeneratorScriptWorkingDirectory.isEmpty())
+            str << "\nrun in '" <<  filesGeneratorScriptWorkingDirectory << '\'';
         str << "\nArguments: ";
         foreach(const GeneratorScriptArgument &a, filesGeneratorScriptArguments) {
             str << " '" << a.value  << '\'';
diff --git a/src/plugins/projectexplorer/customwizard/customwizardparameters.h b/src/plugins/projectexplorer/customwizard/customwizardparameters.h
index 59ee8599cccd0d5bb762cca94ea2b76885978e3b..732098ff35ec3421291f2262d7d7c5d24ba4298c 100644
--- a/src/plugins/projectexplorer/customwizard/customwizardparameters.h
+++ b/src/plugins/projectexplorer/customwizard/customwizardparameters.h
@@ -104,6 +104,7 @@ public:
     QString klass;
     QList<CustomWizardFile> files;
     QStringList filesGeneratorScript; // Complete binary, such as 'cmd /c myscript.pl'.
+    QString filesGeneratorScriptWorkingDirectory;
     QList<GeneratorScriptArgument> filesGeneratorScriptArguments;
 
     QString fieldPageTitle;
diff --git a/src/plugins/projectexplorer/customwizard/customwizardscriptgenerator.cpp b/src/plugins/projectexplorer/customwizard/customwizardscriptgenerator.cpp
index 5b6c2bef19a92740b90408a3c97abf47d8ae50f4..72f91696429b32ef2fbf0f09ee06e0ca2c3811e5 100644
--- a/src/plugins/projectexplorer/customwizard/customwizardscriptgenerator.cpp
+++ b/src/plugins/projectexplorer/customwizard/customwizardscriptgenerator.cpp
@@ -178,7 +178,12 @@ Core::GeneratedFiles
                             attributes |= Core::GeneratedFile::OpenProjectAttribute;
                 } else {
                     // Token 0 is file name. Wizard wants native names.
-                    const QString fullPath = targetPath + QLatin1Char('/') + token;
+                    // Expand to full path if relative
+                    const QFileInfo fileInfo(token);
+                    const QString fullPath =
+                            fileInfo.isAbsolute() ?
+                            token :
+                            (targetPath + QLatin1Char('/') + token);
                     file.setPath(QDir::toNativeSeparators(fullPath));
                 }
             }
@@ -186,9 +191,12 @@ Core::GeneratedFiles
             files.push_back(file);
         }
     }
-    if (CustomWizard::verbose())
+    if (CustomWizard::verbose()) {
+        QDebug nospace = qDebug().nospace();
+        nospace << script << " generated:\n";
         foreach(const Core::GeneratedFile &f, files)
-            qDebug() << script << " generated: " << f.path() << f.attributes();
+            nospace << ' ' << f.path() << f.attributes() << '\n';
+    }
     return files;
 }
 
diff --git a/src/plugins/projectexplorer/userfileaccessor.cpp b/src/plugins/projectexplorer/userfileaccessor.cpp
index e9feb7e784d42277f8aba5e2ae20a197ed242536..948780e82b63b45c79d125565f7b90bce3e786aa 100644
--- a/src/plugins/projectexplorer/userfileaccessor.cpp
+++ b/src/plugins/projectexplorer/userfileaccessor.cpp
@@ -1034,7 +1034,7 @@ QVariantMap Version3Handler::update(Project *, const QVariantMap &map)
         // first iteration: search run configurations, get signing info, remove old signing keys
         QString customKeyPath;
         QString customSignaturePath;
-        int signingMode;
+        int signingMode = 0; // SelfSign
         QMapIterator<QString, QVariant> targetIt(originalTarget);
         while (targetIt.hasNext()) {
             targetIt.next();
diff --git a/src/plugins/qt4projectmanager/qt-s60/s60createpackagestep.cpp b/src/plugins/qt4projectmanager/qt-s60/s60createpackagestep.cpp
index 2921ee23e88e1582729124df2c6abd9ecccb1034..a5d7c9ec95df26dcf2ce3917dd35e4edb8fadf2a 100644
--- a/src/plugins/qt4projectmanager/qt-s60/s60createpackagestep.cpp
+++ b/src/plugins/qt4projectmanager/qt-s60/s60createpackagestep.cpp
@@ -140,7 +140,7 @@ QVariantMap S60CreatePackageStep::toMap() const
 
 bool S60CreatePackageStep::fromMap(const QVariantMap &map)
 {
-    m_signingMode = (SigningMode)map.value(QLatin1String(SIGNMODE_KEY)).toInt();
+    m_signingMode = static_cast<SigningMode>(map.value(QLatin1String(SIGNMODE_KEY), static_cast<int>(SignSelf)).toInt());
     m_customSignaturePath = map.value(QLatin1String(CERTIFICATE_KEY)).toString();
     setCustomKeyPath(map.value(QLatin1String(KEYFILE_KEY)).toString());
     m_createSmartInstaller = map.value(QLatin1String(SMART_INSTALLER_KEY), false).toBool();
diff --git a/src/plugins/texteditor/linenumberfilter.cpp b/src/plugins/texteditor/linenumberfilter.cpp
index 961c03c9e44793d64fe2b1db497fcf4c6678decd..6cbd99713a088a60bf7faf34a7c4bad2eaca34e5 100644
--- a/src/plugins/texteditor/linenumberfilter.cpp
+++ b/src/plugins/texteditor/linenumberfilter.cpp
@@ -48,7 +48,7 @@ LineNumberFilter::LineNumberFilter(QObject *parent)
     setIncludedByDefault(true);
 }
 
-QList<FilterEntry> LineNumberFilter::matchesFor(const QString &entry)
+QList<FilterEntry> LineNumberFilter::matchesFor(QFutureInterface<Locator::FilterEntry> &future, const QString &entry)
 {
     bool ok;
     QList<FilterEntry> value;
diff --git a/src/plugins/texteditor/linenumberfilter.h b/src/plugins/texteditor/linenumberfilter.h
index 8a21a220a17ce96ba8e6806dd2301e94e5e4897b..f4d61a66d5ab418ab861c6890ec8217fcac38844 100644
--- a/src/plugins/texteditor/linenumberfilter.h
+++ b/src/plugins/texteditor/linenumberfilter.h
@@ -52,7 +52,7 @@ public:
     QString displayName() const { return tr("Line in current document"); }
     QString id() const { return "Line in current document"; }
     Locator::ILocatorFilter::Priority priority() const { return Locator::ILocatorFilter::High; }
-    QList<Locator::FilterEntry> matchesFor(const QString &entry);
+    QList<Locator::FilterEntry> matchesFor(QFutureInterface<Locator::FilterEntry> &future, const QString &entry);
     void accept(Locator::FilterEntry selection) const;
     void refresh(QFutureInterface<void> &) {}