diff --git a/.gitignore b/.gitignore
index 0f3b119423db74e21ab8914f97c254e51436f672..f140cb47ca629d575e58f819b212b4340d137f7b 100644
--- a/.gitignore
+++ b/.gitignore
@@ -68,8 +68,8 @@ src/corelib/lib
 src/network/lib
 src/xml/lib/
 
-# Files copied by syncIde
-# -----------------------
+# Binaries
+# --------
 bin/Aggregation.dll
 bin/CodeModel.dll
 bin/ExtensionSystem.dll
@@ -77,24 +77,4 @@ bin/QtConcurrent.dll
 bin/Utils.dll
 bin/qtcreator
 bin/qtcreator.exe
-shared/help/bookmarkdialog.ui
-shared/help/bookmarkmanager.cpp
-shared/help/bookmarkmanager.h
-shared/help/contentwindow.cpp
-shared/help/contentwindow.h
-shared/help/filternamedialog.cpp
-shared/help/filternamedialog.h
-shared/help/filternamedialog.ui
-shared/help/helpviewer.cpp
-shared/help/helpviewer.h
-shared/help/indexwindow.cpp
-shared/help/indexwindow.h
-shared/help/topicchooser.cpp
-shared/help/topicchooser.h
-shared/help/topicchooser.ui
-shared/proparser/abstractproitemvisitor.h
-shared/proparser/profileevaluator.cpp
-shared/proparser/profileevaluator.h
-shared/proparser/proitems.cpp
-shared/proparser/proitems.h
-shared/proparser/proparserutils.h
+tests/manual/cplusplus/cplusplus0
diff --git a/shared/cplusplus/Parser.cpp b/shared/cplusplus/Parser.cpp
index 46618dd112b8c653b33652ba41100a4109d31538..13fbaa0160b6185e3a9609085d10c13f708fa97c 100644
--- a/shared/cplusplus/Parser.cpp
+++ b/shared/cplusplus/Parser.cpp
@@ -1191,6 +1191,11 @@ bool Parser::parseClassSpecifier(SpecifierAST *&node)
     NameAST *name = 0;
     parseName(name);
 
+    bool parsed = false;
+
+    const bool previousInFunctionBody = _inFunctionBody;
+    _inFunctionBody = false;
+
     if (LA() == T_COLON || LA() == T_LBRACE) {
         BaseSpecifierAST *base_clause = 0;
         if (LA() == T_COLON) {
@@ -1233,9 +1238,12 @@ bool Parser::parseClassSpecifier(SpecifierAST *&node)
             }
         }
         node = ast;
-        return true;
+        parsed = true;
     }
-    return false;
+
+    _inFunctionBody = previousInFunctionBody;
+
+    return parsed;
 }
 
 bool Parser::parseAccessSpecifier(SpecifierAST *&node)
diff --git a/shared/cplusplus/Scope.cpp b/shared/cplusplus/Scope.cpp
index 2c1b986b2c9f48d5afc19a08f5bcb0fc7b90f629..47221da121f58bd39c596bdba6e6b7f69d0067cb 100644
--- a/shared/cplusplus/Scope.cpp
+++ b/shared/cplusplus/Scope.cpp
@@ -292,6 +292,7 @@ Use *Scope::useAt(unsigned index) const
 
 void Scope::addUse(unsigned sourceOffset, Name *name)
 {
+#ifdef CPLUSPLUS_WITH_USES
     if (++_useCount == _allocatedUses) {
         _allocatedUses += 4;
         _uses = reinterpret_cast<Use *>(realloc(_uses, _allocatedUses * sizeof(Use)));
@@ -303,6 +304,7 @@ void Scope::addUse(unsigned sourceOffset, Name *name)
     else
         lastVisibleSymbol = _symbols[_symbolCount];
     _uses[_useCount].init(sourceOffset, name, lastVisibleSymbol);
+#endif
 }
 
 CPLUSPLUS_END_NAMESPACE
diff --git a/shared/help/help.pri b/shared/help/help.pri
index 9503d085938b6ae619b5d2567fa3fe8a163ec88a..dff0ae7699b673175d3571ba8d4ffa952340805e 100644
--- a/shared/help/help.pri
+++ b/shared/help/help.pri
@@ -9,7 +9,8 @@ HEADERS += \
         $$PWD/helpviewer.h \
         $$PWD/contentwindow.h \
         $$PWD/bookmarkmanager.h \
-        $$PWD/../namespace_global.h
+        $$PWD/../namespace_global.h \
+        $$PWD/indexwindow.h
 
 SOURCES += \
         $$PWD/filternamedialog.cpp \
@@ -19,7 +20,7 @@ SOURCES += \
         $$PWD/contentwindow.cpp \
         $$PWD/bookmarkmanager.cpp
 
-FORMS 	+= \
+FORMS   += \
         $$PWD/filternamedialog.ui \
         $$PWD/topicchooser.ui \
         $$PWD/bookmarkdialog.ui
diff --git a/src/libs/cplusplus/CppDocument.cpp b/src/libs/cplusplus/CppDocument.cpp
index 782c14ff6d556ecac284d71a567d619d1e52d145..3a280416d9b881631dac42e8486f7a9834a1ec0d 100644
--- a/src/libs/cplusplus/CppDocument.cpp
+++ b/src/libs/cplusplus/CppDocument.cpp
@@ -153,6 +153,11 @@ void Document::appendMacro(const QByteArray &macroName, const QByteArray &text)
     _definedMacros += text;
 }
 
+void Document::addMacroUse(unsigned offset, unsigned length)
+{
+    _macroUses.append(Block(offset, offset + length));
+}
+
 TranslationUnit *Document::translationUnit() const
 {
     return _translationUnit;
diff --git a/src/libs/cplusplus/CppDocument.h b/src/libs/cplusplus/CppDocument.h
index 17762200fa03c99fdde3871c5c9398c07720f411..e952913a07b7d75e37648b7af0117e180845f4cb 100644
--- a/src/libs/cplusplus/CppDocument.h
+++ b/src/libs/cplusplus/CppDocument.h
@@ -68,6 +68,8 @@ public:
 
     void appendMacro(const QByteArray &macroName, const QByteArray &text);
 
+    void addMacroUse(unsigned offset, unsigned length);
+
     Control *control() const;
     TranslationUnit *translationUnit() const;
 
@@ -176,6 +178,9 @@ public:
     QList<Block> skippedBlocks() const
     { return _skippedBlocks; }
 
+    QList<Block> macroUses() const
+    { return _macroUses; }
+
 private:
     Symbol *findSymbolAt(unsigned line, unsigned column, Scope *scope) const;
 
@@ -189,6 +194,7 @@ private:
     QByteArray _definedMacros;
     QSet<QByteArray> _macroNames;
     QList<Block> _skippedBlocks;
+    QList<Block> _macroUses;
 };
 
 } // end of namespace CPlusPlus
diff --git a/src/libs/cplusplus/ResolveExpression.cpp b/src/libs/cplusplus/ResolveExpression.cpp
index 019cbfff1ff1656321b595a49c702992ced15950..cfcd06cacd7067b55000916460c59aa08dcb5c83 100644
--- a/src/libs/cplusplus/ResolveExpression.cpp
+++ b/src/libs/cplusplus/ResolveExpression.cpp
@@ -235,9 +235,9 @@ bool ResolveExpression::visit(ExpressionListAST *)
     return false;
 }
 
-bool ResolveExpression::visit(BinaryExpressionAST *)
+bool ResolveExpression::visit(BinaryExpressionAST *ast)
 {
-    // nothing to do.
+    accept(ast->left_expression);
     return false;
 }
 
diff --git a/src/libs/cplusplus/TypeOfExpression.cpp b/src/libs/cplusplus/TypeOfExpression.cpp
index 2672bfb105f1422b8d39f3da2941d0ee280d2dfa..7dd669365fc3ec8bf3be89b6cf5e7c8ca8210759 100644
--- a/src/libs/cplusplus/TypeOfExpression.cpp
+++ b/src/libs/cplusplus/TypeOfExpression.cpp
@@ -91,7 +91,8 @@ Document::Ptr TypeOfExpression::documentForExpression(const QString &expression)
 {
     // create the expression's AST.
     Document::Ptr doc = Document::create(QLatin1String("<completion>"));
-    doc->setSource(expression.toUtf8());
+    const QByteArray bytes = expression.toUtf8();
+    doc->setSource(bytes);
     doc->parse(Document::ParseExpression);
     return doc;
 }
diff --git a/src/libs/utils/filesearch.cpp b/src/libs/utils/filesearch.cpp
index 6286b780d30db94e67f85d7f1cafe87c2c2712d4..153b9531742b3f5f5345d57e8b7844e050f650da 100644
--- a/src/libs/utils/filesearch.cpp
+++ b/src/libs/utils/filesearch.cpp
@@ -165,7 +165,7 @@ void runFileSearchRegExp(QFutureInterface<FileSearchResult> &future,
     int numFilesSearched = 0;
     int numMatches = 0;
     if (flags & QTextDocument::FindWholeWords)
-        searchTerm = QString("\b%1\b").arg(searchTerm);
+        searchTerm = QString("\\b%1\\b").arg(searchTerm);
     Qt::CaseSensitivity caseSensitivity = (flags & QTextDocument::FindCaseSensitively) ? Qt::CaseSensitive : Qt::CaseInsensitive;
     QRegExp expression(searchTerm, caseSensitivity);
 
diff --git a/src/libs/utils/filewizarddialog.cpp b/src/libs/utils/filewizarddialog.cpp
index 8608fed73ec6a0ed0bba88bce98cca01dcb29d9b..8441cdb86380e7add0b1f572296e5bd79d723f70 100644
--- a/src/libs/utils/filewizarddialog.cpp
+++ b/src/libs/utils/filewizarddialog.cpp
@@ -44,6 +44,8 @@ FileWizardDialog::FileWizardDialog(QWidget *parent) :
     m_filePage(new FileWizardPage)
 {
     setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
+    setOption(QWizard::NoCancelButton, false);
+    setOption(QWizard::NoDefaultButton, false);
     setPixmap(QWizard::WatermarkPixmap, QPixmap(QLatin1String(":/qworkbench/images/qtwatermark.png")));
     addPage(m_filePage);
     connect(m_filePage, SIGNAL(activated()), button(QWizard::FinishButton), SLOT(animateClick()));
diff --git a/src/libs/utils/synchronousprocess.cpp b/src/libs/utils/synchronousprocess.cpp
index 078373aa20837842dc505edbf791703539c73a06..6a1b2efa8403d49a73c39712b054a1396717edff 100644
--- a/src/libs/utils/synchronousprocess.cpp
+++ b/src/libs/utils/synchronousprocess.cpp
@@ -125,6 +125,7 @@ struct SynchronousProcessPrivate {
     SynchronousProcessResponse m_result;
     int m_hangTimerCount;
     int m_maxHangTimerCount;
+    bool m_startFailure;
 
     ChannelBuffer m_stdOut;
     ChannelBuffer m_stdErr;
@@ -133,7 +134,8 @@ struct SynchronousProcessPrivate {
 SynchronousProcessPrivate::SynchronousProcessPrivate() :
     m_stdOutCodec(0),
     m_hangTimerCount(0),
-    m_maxHangTimerCount(defaultMaxHangTimerCount)
+    m_maxHangTimerCount(defaultMaxHangTimerCount),
+    m_startFailure(false)
 {
 }
 
@@ -143,6 +145,7 @@ void SynchronousProcessPrivate::clearForRun()
     m_stdOut.clearForRun();
     m_stdErr.clearForRun();
     m_result.clear();
+    m_startFailure = false;
 }
 
 // ----------- SynchronousProcess
@@ -221,22 +224,26 @@ SynchronousProcessResponse SynchronousProcess::run(const QString &binary,
         qDebug() << '>' << Q_FUNC_INFO << binary << args;
 
     m_d->clearForRun();
-    m_d->m_timer.start();
-
-    QApplication::setOverrideCursor(Qt::WaitCursor);
 
+    // On Windows, start failure is triggered immediately if the
+    // executable cannot be found in the path. Do not start the
+    // event loop in that case.
     m_d->m_process.start(binary, args, QIODevice::ReadOnly);
-    m_d->m_eventLoop.exec(QEventLoop::ExcludeUserInputEvents);
-    if (m_d->m_result.result == SynchronousProcessResponse::Finished || m_d->m_result.result == SynchronousProcessResponse::FinishedError) {
-        processStdOut(false);
-        processStdErr(false);
-    }
+    if (!m_d->m_startFailure) {
+        m_d->m_timer.start();
+        QApplication::setOverrideCursor(Qt::WaitCursor);
+        m_d->m_eventLoop.exec(QEventLoop::ExcludeUserInputEvents);
+        if (m_d->m_result.result == SynchronousProcessResponse::Finished || m_d->m_result.result == SynchronousProcessResponse::FinishedError) {
+            processStdOut(false);
+            processStdErr(false);
+        }
 
-    m_d->m_result.stdOut = convertStdOut(m_d->m_stdOut.data);
-    m_d->m_result.stdErr = convertStdErr(m_d->m_stdErr.data);
+        m_d->m_result.stdOut = convertStdOut(m_d->m_stdOut.data);
+        m_d->m_result.stdErr = convertStdErr(m_d->m_stdErr.data);
 
-    m_d->m_timer.stop();
-    QApplication::restoreOverrideCursor();
+        m_d->m_timer.stop();
+        QApplication::restoreOverrideCursor();
+    }
 
     if (debug)
         qDebug() << '<' << Q_FUNC_INFO << binary << m_d->m_result;
@@ -246,12 +253,14 @@ SynchronousProcessResponse SynchronousProcess::run(const QString &binary,
 void SynchronousProcess::slotTimeout()
 {
     if (++m_d->m_hangTimerCount > m_d->m_maxHangTimerCount) {
+        if (debug)
+            qDebug() << Q_FUNC_INFO << "HANG detected, killing";
         m_d->m_process.kill();
         m_d->m_result.result = SynchronousProcessResponse::Hang;
+    } else {
+        if (debug)
+            qDebug() << Q_FUNC_INFO << m_d->m_hangTimerCount;
     }
-
-    if (debug)
-        qDebug() << Q_FUNC_INFO << m_d->m_hangTimerCount;
 }
 
 void SynchronousProcess::finished(int exitCode, QProcess::ExitStatus e)
@@ -265,7 +274,9 @@ void SynchronousProcess::finished(int exitCode, QProcess::ExitStatus e)
         m_d->m_result.exitCode = exitCode;
         break;
     case QProcess::CrashExit:
-        m_d->m_result.result = SynchronousProcessResponse::TerminatedAbnormally;
+        // Was hang detected before and killed?
+        if (m_d->m_result.result != SynchronousProcessResponse::Hang)
+            m_d->m_result.result = SynchronousProcessResponse::TerminatedAbnormally;
         m_d->m_result.exitCode = -1;
         break;
     }
@@ -277,7 +288,10 @@ void SynchronousProcess::error(QProcess::ProcessError e)
     m_d->m_hangTimerCount = 0;
     if (debug)
         qDebug() << Q_FUNC_INFO << e;
-    m_d->m_result.result = SynchronousProcessResponse::StartFailed;
+    // Was hang detected before and killed?
+    if (m_d->m_result.result != SynchronousProcessResponse::Hang)
+        m_d->m_result.result = SynchronousProcessResponse::StartFailed;
+    m_d->m_startFailure = true;
     m_d->m_eventLoop.quit();
 }
 
diff --git a/src/plugins/cmakeprojectmanager/cmakeprojectconstants.h b/src/plugins/cmakeprojectmanager/cmakeprojectconstants.h
index 516e3e61754d8d31ea41eea7ee5985a3e3407cfb..4832f17f26383d9deab8e48d2f9820068e95fa0e 100644
--- a/src/plugins/cmakeprojectmanager/cmakeprojectconstants.h
+++ b/src/plugins/cmakeprojectmanager/cmakeprojectconstants.h
@@ -40,6 +40,7 @@ namespace Constants {
 const char * const PROJECTCONTEXT = "CMakeProject.ProjectContext";
 const char * const CMAKEMIMETYPE  = "text/x-cmake"; // TOOD check that this is correct
 const char * const CMAKESTEP      = "CMakeProjectManager.CMakeStep";
+const char * const MAKESTEP       = "CMakeProjectManager.MakeStep";
 
 
 } // namespace Constants
diff --git a/src/plugins/cmakeprojectmanager/cmakeprojectmanager.pro b/src/plugins/cmakeprojectmanager/cmakeprojectmanager.pro
index 3d427a93d8b4b2237610dcf529ccfad2b442daa9..afca26b265b2d355d643d0c9c3f4ad7d385372da 100644
--- a/src/plugins/cmakeprojectmanager/cmakeprojectmanager.pro
+++ b/src/plugins/cmakeprojectmanager/cmakeprojectmanager.pro
@@ -7,10 +7,12 @@ HEADERS = cmakeproject.h \
     cmakeprojectmanager.h \
     cmakeprojectconstants.h \
     cmakeprojectnodes.h \
-    cmakestep.h
+    cmakestep.h \
+    makestep.h
 SOURCES = cmakeproject.cpp \
     cmakeprojectplugin.cpp \
     cmakeprojectmanager.cpp \
     cmakeprojectnodes.cpp \
-    cmakestep.cpp
+    cmakestep.cpp \
+    makestep.cpp
 RESOURCES += cmakeproject.qrc
diff --git a/src/plugins/cmakeprojectmanager/cmakestep.cpp b/src/plugins/cmakeprojectmanager/cmakestep.cpp
index 821bf6b1beca5b1b356adfa8d12430eaa7626325..523741c92ba9e16d838f4747f3dbcf8e1096eed5 100644
--- a/src/plugins/cmakeprojectmanager/cmakestep.cpp
+++ b/src/plugins/cmakeprojectmanager/cmakestep.cpp
@@ -1,3 +1,36 @@
+/***************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact:  Qt Software Information (qt-info@nokia.com)
+**
+**
+** Non-Open Source Usage
+**
+** Licensees may use this file in accordance with the Qt Beta Version
+** License Agreement, Agreement version 2.2 provided with the Software or,
+** alternatively, in accordance with the terms contained in a written
+** agreement between you and Nokia.
+**
+** GNU General Public License Usage
+**
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the packaging
+** of this file.  Please review the following information to ensure GNU
+** General Public Licensing requirements will be met:
+**
+** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt GPL Exception
+** version 1.2, included in the file GPL_EXCEPTION.txt in this package.
+**
+***************************************************************************/
+
 #include "cmakestep.h"
 #include "cmakeprojectconstants.h"
 #include "cmakeproject.h"
@@ -6,7 +39,7 @@ using namespace CMakeProjectManager;
 using namespace CMakeProjectManager::Internal;
 
 CMakeStep::CMakeStep(CMakeProject *pro)
-    : BuildStep(pro), m_pro(pro)
+    : AbstractProcessStep(pro), m_pro(pro)
 {
 
 }
@@ -18,14 +51,17 @@ CMakeStep::~CMakeStep()
 
 bool CMakeStep::init(const QString &buildConfiguration)
 {
-    // TODO
-    return true;
+    setEnabled(buildConfiguration, true);
+    setWorkingDirectory(buildConfiguration, m_pro->buildDirectory(buildConfiguration));
+    setCommand(buildConfiguration, "cmake"); // TODO give full path here?
+    setArguments(buildConfiguration, QStringList()); // TODO
+    setEnvironment(buildConfiguration, m_pro->environment(buildConfiguration));
+    return AbstractProcessStep::init(buildConfiguration);
 }
 
 void CMakeStep::run(QFutureInterface<bool> &fi)
 {
-    // TODO
-    fi.reportResult(true);
+    AbstractProcessStep::run(fi);
 }
 
 QString CMakeStep::name()
diff --git a/src/plugins/cmakeprojectmanager/cmakestep.h b/src/plugins/cmakeprojectmanager/cmakestep.h
index dea4499efc4fc3c6b05abc9d6772f6d5554528b4..75cc0d6ba3804b8eef0a51b810121097a0ba174c 100644
--- a/src/plugins/cmakeprojectmanager/cmakestep.h
+++ b/src/plugins/cmakeprojectmanager/cmakestep.h
@@ -1,7 +1,41 @@
+/***************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact:  Qt Software Information (qt-info@nokia.com)
+**
+**
+** Non-Open Source Usage
+**
+** Licensees may use this file in accordance with the Qt Beta Version
+** License Agreement, Agreement version 2.2 provided with the Software or,
+** alternatively, in accordance with the terms contained in a written
+** agreement between you and Nokia.
+**
+** GNU General Public License Usage
+**
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the packaging
+** of this file.  Please review the following information to ensure GNU
+** General Public Licensing requirements will be met:
+**
+** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt GPL Exception
+** version 1.2, included in the file GPL_EXCEPTION.txt in this package.
+**
+***************************************************************************/
+
 #ifndef CMAKESTEP_H
 #define CMAKESTEP_H
 
 #include <projectexplorer/buildstep.h>
+#include <projectexplorer/abstractprocessstep.h>
 
 namespace CMakeProjectManager {
 namespace Internal {
@@ -10,7 +44,7 @@ class CMakeProject;
 
 class CMakeBuildStepConfigWidget;
 
-class CMakeStep : public ProjectExplorer::BuildStep
+class CMakeStep : public ProjectExplorer::AbstractProcessStep
 {
 public:
     CMakeStep(CMakeProject *pro);
diff --git a/src/plugins/cmakeprojectmanager/makestep.cpp b/src/plugins/cmakeprojectmanager/makestep.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..6bb5b59cdf81833ee87147501c118ae408083753
--- /dev/null
+++ b/src/plugins/cmakeprojectmanager/makestep.cpp
@@ -0,0 +1,127 @@
+/***************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact:  Qt Software Information (qt-info@nokia.com)
+**
+**
+** Non-Open Source Usage
+**
+** Licensees may use this file in accordance with the Qt Beta Version
+** License Agreement, Agreement version 2.2 provided with the Software or,
+** alternatively, in accordance with the terms contained in a written
+** agreement between you and Nokia.
+**
+** GNU General Public License Usage
+**
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the packaging
+** of this file.  Please review the following information to ensure GNU
+** General Public Licensing requirements will be met:
+**
+** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt GPL Exception
+** version 1.2, included in the file GPL_EXCEPTION.txt in this package.
+**
+***************************************************************************/
+
+#include "makestep.h"
+#include "cmakeprojectconstants.h"
+#include "cmakeproject.h"
+
+using namespace CMakeProjectManager;
+using namespace CMakeProjectManager::Internal;
+
+MakeStep::MakeStep(CMakeProject *pro)
+    : AbstractProcessStep(pro), m_pro(pro)
+{
+
+}
+
+MakeStep::~MakeStep()
+{
+
+}
+
+bool MakeStep::init(const QString &buildConfiguration)
+{
+    setEnabled(buildConfiguration, true);
+    setWorkingDirectory(buildConfiguration, m_pro->buildDirectory(buildConfiguration));
+    setCommand(buildConfiguration, "make"); // TODO give full path here?
+    setArguments(buildConfiguration, QStringList()); // TODO
+    setEnvironment(buildConfiguration, m_pro->environment(buildConfiguration));
+    return AbstractProcessStep::init(buildConfiguration);
+}
+
+void MakeStep::run(QFutureInterface<bool> &fi)
+{
+    AbstractProcessStep::run(fi);
+}
+
+QString MakeStep::name()
+{
+    return "Make";
+}
+
+QString MakeStep::displayName()
+{
+    return Constants::CMAKESTEP;
+}
+
+ProjectExplorer::BuildStepConfigWidget *MakeStep::createConfigWidget()
+{
+    return new MakeBuildStepConfigWidget();
+}
+
+bool MakeStep::immutable() const
+{
+    return true;
+}
+
+//
+// CMakeBuildStepConfigWidget
+//
+
+QString MakeBuildStepConfigWidget::displayName() const
+{
+    return "Make";
+}
+
+void MakeBuildStepConfigWidget::init(const QString &buildConfiguration)
+{
+    // TODO
+}
+
+//
+// MakeBuildStepFactory
+//
+
+bool MakeBuildStepFactory::canCreate(const QString &name) const
+{
+    return (Constants::MAKESTEP == name);
+}
+
+ProjectExplorer::BuildStep *MakeBuildStepFactory::create(ProjectExplorer::Project *project, const QString &name) const
+{
+    Q_ASSERT(name == Constants::MAKESTEP);
+    CMakeProject *pro = qobject_cast<CMakeProject *>(project);
+    Q_ASSERT(pro);
+    return new MakeStep(pro);
+}
+
+QStringList MakeBuildStepFactory::canCreateForProject(ProjectExplorer::Project *pro) const
+{
+    return QStringList();
+}
+
+QString MakeBuildStepFactory::displayNameForName(const QString &name) const
+{
+    return "Make";
+}
+
diff --git a/src/plugins/cmakeprojectmanager/makestep.h b/src/plugins/cmakeprojectmanager/makestep.h
new file mode 100644
index 0000000000000000000000000000000000000000..f0ef530b42f912b921e35c01f6d62c624c5d53ba
--- /dev/null
+++ b/src/plugins/cmakeprojectmanager/makestep.h
@@ -0,0 +1,79 @@
+/***************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact:  Qt Software Information (qt-info@nokia.com)
+**
+**
+** Non-Open Source Usage
+**
+** Licensees may use this file in accordance with the Qt Beta Version
+** License Agreement, Agreement version 2.2 provided with the Software or,
+** alternatively, in accordance with the terms contained in a written
+** agreement between you and Nokia.
+**
+** GNU General Public License Usage
+**
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the packaging
+** of this file.  Please review the following information to ensure GNU
+** General Public Licensing requirements will be met:
+**
+** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt GPL Exception
+** version 1.2, included in the file GPL_EXCEPTION.txt in this package.
+**
+***************************************************************************/
+
+#ifndef MAKESTEP_H
+#define MAKESTEP_H
+
+#include <projectexplorer/abstractprocessstep.h>
+
+namespace CMakeProjectManager {
+namespace Internal {
+
+class CMakeProject;
+
+class MakeStep : public ProjectExplorer::AbstractProcessStep
+{
+public:
+    MakeStep(CMakeProject *pro);
+    ~MakeStep();
+    virtual bool init(const QString &buildConfiguration);
+
+    virtual void run(QFutureInterface<bool> &fi);
+
+    virtual QString name();
+    virtual QString displayName();
+    virtual ProjectExplorer::BuildStepConfigWidget *createConfigWidget();
+    virtual bool immutable() const;
+private:
+    CMakeProject *m_pro;
+};
+
+class MakeBuildStepConfigWidget :public ProjectExplorer::BuildStepConfigWidget
+{
+public:
+    virtual QString displayName() const;
+    virtual void init(const QString &buildConfiguration);
+};
+
+class MakeBuildStepFactory : public ProjectExplorer::IBuildStepFactory
+{
+    virtual bool canCreate(const QString &name) const;
+    virtual ProjectExplorer::BuildStep *create(ProjectExplorer::Project *pro, const QString &name) const;
+    virtual QStringList canCreateForProject(ProjectExplorer::Project *pro) const;
+    virtual QString displayNameForName(const QString &name) const;
+};
+
+}
+}
+
+#endif // MAKESTEP_H
diff --git a/src/plugins/coreplugin/basefilewizard.cpp b/src/plugins/coreplugin/basefilewizard.cpp
index f72353743b8852ec1b30750bc3aeb9e807020446..58030ba20c9ad8e0c7aaef03c266ff694fbbc3d6 100644
--- a/src/plugins/coreplugin/basefilewizard.cpp
+++ b/src/plugins/coreplugin/basefilewizard.cpp
@@ -509,6 +509,8 @@ QPixmap BaseFileWizard::watermark()
 void BaseFileWizard::setupWizard(QWizard *w)
 {
     w->setPixmap(QWizard::WatermarkPixmap, watermark());
+    w->setOption(QWizard::NoCancelButton, false);
+    w->setOption(QWizard::NoDefaultButton, false);
 }
 
 bool BaseFileWizard::postGenerateFiles(const GeneratedFiles &l, QString *errorMessage)
diff --git a/src/plugins/coreplugin/coreconstants.h b/src/plugins/coreplugin/coreconstants.h
index ee1488d40dc0097a8d6ce2857775f406931cd2a5..c2a703a2d6f66bb1633be393637b5ec53071f287 100644
--- a/src/plugins/coreplugin/coreconstants.h
+++ b/src/plugins/coreplugin/coreconstants.h
@@ -94,6 +94,7 @@ const char * const C_WELCOME_MODE        = "Core.WelcomeMode";
 const char * const C_EDIT_MODE           = "Core.EditMode";
 const char * const C_EDITORMANAGER       = "Core.EditorManager";
 const char * const C_NAVIGATION_PANE     = "Core.NavigationPane";
+const char * const C_PROBLEM_PANE        = "Core.ProblemPane";
 
 //default editor kind
 const char * const K_DEFAULT_TEXT_EDITOR = "Plain Text Editor";
diff --git a/src/plugins/coreplugin/editormanager/editormanager.cpp b/src/plugins/coreplugin/editormanager/editormanager.cpp
index 0092513693b467b42690e2c86e5157e932c827fa..29798b25c010e9202f09cd2c27d38e6278ff9900 100644
--- a/src/plugins/coreplugin/editormanager/editormanager.cpp
+++ b/src/plugins/coreplugin/editormanager/editormanager.cpp
@@ -74,20 +74,6 @@ using namespace Core::Internal;
 
 enum { debugEditorManager=0 };
 
-QString EditorManager::defaultExternalEditor() const
-{
-#ifdef Q_OS_MAC
-    return m_d->m_core->resourcePath()
-            +QLatin1String("/runInTerminal.command vi %f %l %c %W %H %x %y");
-#elif defined(Q_OS_UNIX)
-    return QLatin1String("xterm -geom %Wx%H+%x+%y -e vi %f +%l +\"normal %c|\"");
-#elif defined (Q_OS_WIN)
-    return QLatin1String("notepad %f");
-#else
-    return QString();
-#endif
-}
-
 //===================EditorManager=====================
 
 EditorManagerPlaceHolder *EditorManagerPlaceHolder::m_current = 0;
@@ -388,6 +374,20 @@ QSize EditorManager::minimumSizeHint() const
     return QSize(400, 300);
 }
 
+QString EditorManager::defaultExternalEditor() const
+{
+#ifdef Q_OS_MAC
+    return m_d->m_core->resourcePath()
+            +QLatin1String("/runInTerminal.command vi %f %l %c %W %H %x %y");
+#elif defined(Q_OS_UNIX)
+    return QLatin1String("xterm -geom %Wx%H+%x+%y -e vi %f +%l +\"normal %c|\"");
+#elif defined (Q_OS_WIN)
+    return QLatin1String("notepad %f");
+#else
+    return QString();
+#endif
+}
+
 EditorSplitter *EditorManager::editorSplitter() const
 {
     return m_d->m_splitter;
@@ -1003,29 +1003,32 @@ bool EditorManager::saveFile(IEditor *editor)
     return success;
 }
 
-namespace {
-    enum ReadOnlyAction { RO_Cancel, RO_OpenSCC, RO_MakeWriteable, RO_SaveAs };
-}
-
-static ReadOnlyAction promptReadOnly(const QString &fileName, bool hasSCC, QWidget *parent)
+EditorManager::ReadOnlyAction
+    EditorManager::promptReadOnlyFile(const QString &fileName,
+                                      const IVersionControl *versionControl,
+                                      QWidget *parent,
+                                      bool displaySaveAsButton)
 {
     QMessageBox msgBox(QMessageBox::Question, QObject::tr("File is Read Only"),
                        QObject::tr("The file %1 is read only.").arg(fileName),
                        QMessageBox::Cancel, parent);
 
     QPushButton *sccButton = 0;
-    if (hasSCC)
-        sccButton = msgBox.addButton(QObject::tr("Open with SCC"), QMessageBox::AcceptRole);
+    if (versionControl && versionControl->supportsOperation(IVersionControl::OpenOperation))
+        sccButton = msgBox.addButton(QObject::tr("Open with VCS (%1)").arg(versionControl->name()), QMessageBox::AcceptRole);
+
     QPushButton *makeWritableButton =  msgBox.addButton(QObject::tr("Make writable"), QMessageBox::AcceptRole);
-    QPushButton *saveAsButton =  msgBox.addButton(QObject::tr("Save as ..."), QMessageBox::ActionRole);
-    if (hasSCC)
-        msgBox.setDefaultButton(sccButton);
-    else
-        msgBox.setDefaultButton(makeWritableButton);
+
+    QPushButton *saveAsButton = 0;
+    if (displaySaveAsButton)
+        msgBox.addButton(QObject::tr("Save as ..."), QMessageBox::ActionRole);
+
+    msgBox.setDefaultButton(sccButton ? sccButton : makeWritableButton);
     msgBox.exec();
+
     QAbstractButton *clickedButton = msgBox.clickedButton();
     if (clickedButton == sccButton)
-        return RO_OpenSCC;
+        return RO_OpenVCS;
     if (clickedButton == makeWritableButton)
         return RO_MakeWriteable;
     if (clickedButton == saveAsButton)
@@ -1042,8 +1045,8 @@ EditorManager::makeEditorWritable(IEditor *editor)
     IFile *file = editor->file();
     const QString &fileName = file->fileName();
 
-    switch (promptReadOnly(fileName, versionControl, m_d->m_core->mainWindow())) {
-    case RO_OpenSCC:
+    switch (promptReadOnlyFile(fileName, versionControl, m_d->m_core->mainWindow(), true)) {
+    case RO_OpenVCS:
         if (!versionControl->vcsOpen(fileName)) {
             QMessageBox::warning(m_d->m_core->mainWindow(), tr("Failed!"), tr("Could not open the file for edit with SCC."));
             return Failed;
diff --git a/src/plugins/coreplugin/editormanager/editormanager.h b/src/plugins/coreplugin/editormanager/editormanager.h
index b71791f36bfaae03145b5eda8dd2804f48cfa1b2..b9da2e055ff2478a83487564c9593792d7199903 100644
--- a/src/plugins/coreplugin/editormanager/editormanager.h
+++ b/src/plugins/coreplugin/editormanager/editormanager.h
@@ -55,6 +55,7 @@ class IEditorFactory;
 class MimeType;
 class IFile;
 class IMode;
+class IVersionControl;
 
 enum MakeWritableResult {
     OpenedWithVersionControl,
@@ -159,6 +160,16 @@ public:
     QString defaultExternalEditor() const;
     QString externalEditorHelpText() const;
 
+
+    // Helper to display a message dialog when encountering a read-only
+    // file, prompting the user about how to make it writeable.
+    enum ReadOnlyAction { RO_Cancel, RO_OpenVCS, RO_MakeWriteable, RO_SaveAs };
+
+    static ReadOnlyAction promptReadOnlyFile(const QString &fileName,
+                                             const IVersionControl *versionControl,
+                                             QWidget *parent,
+                                             bool displaySaveAsButton = false);
+
 signals:
     void currentEditorChanged(Core::IEditor *editor);
     void editorCreated(Core::IEditor *editor, const QString &fileName);
diff --git a/src/plugins/coreplugin/iversioncontrol.h b/src/plugins/coreplugin/iversioncontrol.h
index b90f9d79c659536d31be68d962c5c12794ab6282..0962c5537e8cf6b1594fdcd84b1b4ff449fc955f 100644
--- a/src/plugins/coreplugin/iversioncontrol.h
+++ b/src/plugins/coreplugin/iversioncontrol.h
@@ -45,51 +45,53 @@ class CORE_EXPORT IVersionControl : public QObject
 {
     Q_OBJECT
 public:
+    enum Operation { AddOperation, DeleteOperation, OpenOperation };
+
     IVersionControl(QObject *parent = 0) : QObject(parent) {}
     virtual ~IVersionControl() {}
 
-    // Returns wheter files in this directory should be managed with this
+    virtual QString name() const = 0;
+
+    // Enable the VCS, that is, make its menu actions visible.
+    virtual bool isEnabled() const = 0;
+    virtual void setEnabled(bool enabled) = 0;
+
+    // Returns whether files in this directory should be managed with this
     // version control.
     virtual bool managesDirectory(const QString &filename) const = 0;
 
-    // This function should return the topmost directory, for
-    // which this IVersionControl should be used.
-    // The VCSManager assumes that all files in the returned directory
-    // are managed by the same IVersionControl
+    // This function should return the topmost directory, for which this
+    // IVersionControl should be used. The VCSManager assumes that all files
+    // in the returned directory are managed by the same IVersionControl
     // Note that this is used as an optimization, so that the VCSManager
     // doesn't need to call managesDirectory(..) for each directory
-    // This function is called after finding out that the directory is managed by
-    // a specific version control
+    // This function is called after finding out that the directory is managed
+    // by a specific version control.
     virtual QString findTopLevelForDirectory(const QString &directory) const = 0;
 
-    // Called prior to save, if the file is read only.
-    // Should be implemented if the scc requires a operation before editing the file
-    // E.g. p4 edit
-    // Note: The EditorManager calls this for the editors
+    // Called to query whether a VCS supports the respective operations.
+    virtual bool supportsOperation(Operation operation) const = 0;
+
+    // Called prior to save, if the file is read only. Should be implemented
+    // if the scc requires a operation before editing the file, e.g. 'p4 edit'
+    // Note: The EditorManager calls this for the editors.
     virtual bool vcsOpen(const QString &fileName) = 0;
 
-    // Called after a file has been added to a project
-    // If the version control needs to know which files it needs to track
-    // you should reimplement this function
-    // E.g. p4 add, cvs add, svn add
-    // Note: This function should be called from IProject subclasses after files
-    // are added to the project
+    // Called after a file has been added to a project If the version control
+    // needs to know which files it needs to track you should reimplement this
+    // function, e.g. 'p4 add', 'cvs add', 'svn add'.
+    // Note: This function should be called from IProject subclasses after
+    // files are added to the project
     virtual bool vcsAdd(const QString &filename) = 0;
 
-    // Called after a file has been removed from the project (if the user wants)
-    // E.g. p4 delete, svn delete
-    // You probably want to call SccManager::showDeleteDialog, which asks the user to
-    // confirm the deletion
+    // Called after a file has been removed from the project (if the user
+    // wants), e.g. 'p4 delete', 'svn delete'.
+    // You probably want to call VcsManager::showDeleteDialog, which asks the
+    // user to confirm the deletion
     virtual bool vcsDelete(const QString &filename) = 0;
 
     // TODO: ADD A WAY TO DETECT WHETHER A FILE IS MANAGED, e.g
     // virtual bool sccManaged(const QStryng &filename) = 0;
-
-    // TODO
-    // we probably want to have a function supports( enum Operation ) or
-    // something which describes which "kind" of revision control system it is.
-    // That is to check wheter a given operation is needed.
-    // But well I don't know yet how all different version control systems work
 };
 
 } // namespace Core
diff --git a/src/plugins/coreplugin/mainwindow.cpp b/src/plugins/coreplugin/mainwindow.cpp
index 59222acc419685bae0994a0aca0e75fb4c632721..1d9050705496bc05501ed25a3a22cec105f034ce 100644
--- a/src/plugins/coreplugin/mainwindow.cpp
+++ b/src/plugins/coreplugin/mainwindow.cpp
@@ -127,6 +127,7 @@ MainWindow::MainWindow() :
     m_mimeDatabase(new MimeDatabase),
     m_navigationWidget(0),
     m_rightPaneWidget(0),
+    m_versionDialog(0),
     m_activeContext(0),
     m_pluginManager(0),
     m_outputPane(new OutputPane(m_globalContext)),
@@ -1085,8 +1086,20 @@ void MainWindow::openRecentFile()
 
 void MainWindow::aboutQtCreator()
 {
-    VersionDialog versionDialog(this);
-    versionDialog.exec();
+    if (!m_versionDialog) {
+        m_versionDialog = new VersionDialog(this);
+        connect(m_versionDialog, SIGNAL(finished(int)),
+                this, SLOT(destroyVersionDialog()));
+    }
+    m_versionDialog->show();
+}
+
+void MainWindow::destroyVersionDialog()
+{
+    if (m_versionDialog) {
+        m_versionDialog->deleteLater();
+        m_versionDialog = 0;
+    }
 }
 
 void MainWindow::aboutPlugins()
diff --git a/src/plugins/coreplugin/mainwindow.h b/src/plugins/coreplugin/mainwindow.h
index 180b932d710bffe7d0b1e71cd5d85ecd937fda41..a8edd089972489c1076ddf1359d078969ec6aa2e 100644
--- a/src/plugins/coreplugin/mainwindow.h
+++ b/src/plugins/coreplugin/mainwindow.h
@@ -83,6 +83,7 @@ class OutputPane;
 class ProgressManager;
 class ShortcutSettings;
 class ViewManager;
+class VersionDialog;
 
 class CORE_EXPORT  MainWindow : public QMainWindow
 {
@@ -160,6 +161,7 @@ private slots:
     void aboutPlugins();
     void updateFocusWidget(QWidget *old, QWidget *now);
     void toggleNavigation();
+    void destroyVersionDialog();
 
 private:
     void updateContextObject(IContext *context);
@@ -190,6 +192,7 @@ private:
     NavigationWidget *m_navigationWidget;
     RightPaneWidget *m_rightPaneWidget;
     Core::BaseView *m_outputView;
+    VersionDialog *m_versionDialog;
 
     IContext * m_activeContext;
 
diff --git a/src/plugins/coreplugin/vcsmanager.cpp b/src/plugins/coreplugin/vcsmanager.cpp
index a0e1cc19c0ad2663899efcf53a566deeeba574da..02475a0d0e66cfb5369327ec1c5f2827f43aa167 100644
--- a/src/plugins/coreplugin/vcsmanager.cpp
+++ b/src/plugins/coreplugin/vcsmanager.cpp
@@ -45,8 +45,18 @@
 #include <QtCore/QFileInfo>
 #include <QtGui/QMessageBox>
 
+enum { debug = 0 };
+
 namespace Core {
 
+typedef QList<IVersionControl *> VersionControlList;
+
+static inline VersionControlList allVersionControls()
+{
+    return ExtensionSystem::PluginManager::instance()->getObjects<IVersionControl>();
+}
+
+// ---- VCSManagerPrivate
 struct VCSManagerPrivate {
     QMap<QString, IVersionControl *> m_cachedMatches;
 };
@@ -61,31 +71,54 @@ VCSManager::~VCSManager()
     delete m_d;
 }
 
+void VCSManager::setVCSEnabled(const QString &directory)
+{
+    if (debug)
+        qDebug() << Q_FUNC_INFO << directory;
+    IVersionControl* managingVCS = findVersionControlForDirectory(directory);
+    const VersionControlList versionControls = allVersionControls();
+    foreach(IVersionControl *versionControl, versionControls) {
+        const bool newEnabled = versionControl == managingVCS;
+        if (newEnabled != versionControl->isEnabled())
+            versionControl->setEnabled(newEnabled);
+    }
+}
+
+void VCSManager::setAllVCSEnabled()
+{
+    if (debug)
+        qDebug() << Q_FUNC_INFO;
+    const VersionControlList versionControls = allVersionControls();
+    foreach(IVersionControl *versionControl, versionControls)
+        if (!versionControl->isEnabled())
+            versionControl->setEnabled(true);
+}
+
 IVersionControl* VCSManager::findVersionControlForDirectory(const QString &directory)
 {
-    // first look into the cache
-    int pos = 0;
-    { // First try the whole name
-        QMap<QString, IVersionControl *>::const_iterator it = m_d->m_cachedMatches.constFind(directory);
-        if (it != m_d->m_cachedMatches.constEnd()) {
+    // first look into the cache, check the whole name
+
+    {
+        const QMap<QString, IVersionControl *>::const_iterator it = m_d->m_cachedMatches.constFind(directory);
+        if (it != m_d->m_cachedMatches.constEnd())
             return it.value();
-        }
     }
 
+    int pos = 0;
+    const QChar slash = QLatin1Char('/');
     while(true) {
-        int index = directory.indexOf('/', pos);
+        int index = directory.indexOf(slash, pos);
         if (index == -1)
             break;
-        QString directoryPart = directory.left(index);
+        const QString directoryPart = directory.left(index);
         QMap<QString, IVersionControl *>::const_iterator it = m_d->m_cachedMatches.constFind(directoryPart);
-        if (it != m_d->m_cachedMatches.constEnd()) {
+        if (it != m_d->m_cachedMatches.constEnd())
             return it.value();
-        }
         pos = index+1;
     }
 
     // ah nothing so ask the IVersionControls directly
-    QList<IVersionControl *> versionControls = ExtensionSystem::PluginManager::instance()->getObjects<IVersionControl>();
+    const VersionControlList versionControls = allVersionControls();
     foreach(IVersionControl * versionControl, versionControls) {
         if (versionControl->managesDirectory(directory)) {
             m_d->m_cachedMatches.insert(versionControl->findTopLevelForDirectory(directory), versionControl);
@@ -95,20 +128,20 @@ IVersionControl* VCSManager::findVersionControlForDirectory(const QString &direc
     return 0;
 }
 
-void VCSManager::showDeleteDialog(const QString &fileName)
+bool VCSManager::showDeleteDialog(const QString &fileName)
 {
     IVersionControl *vc = findVersionControlForDirectory(QFileInfo(fileName).absolutePath());
-    if (!vc)
-        return;
+    if (!vc || !vc->supportsOperation(IVersionControl::DeleteOperation))
+        return true;
     const QString title = QCoreApplication::translate("VCSManager", "Version Control");
     const QString msg = QCoreApplication::translate("VCSManager",
-                                                    "Would you like to remove this file from the version control system?\n"
-                                                    "Note: This might remove the local file.");
+                                                    "Would you like to remove this file from the version control system (%1)?\n"
+                                                    "Note: This might remove the local file.").arg(vc->name());
     const QMessageBox::StandardButton button =
         QMessageBox::question(0, title, msg, QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes);
-    if (button == QMessageBox::Yes) {
-        vc->vcsDelete(fileName);
-    }
+    if (button != QMessageBox::Yes)
+        return true;
+    return vc->vcsDelete(fileName);
 }
 
 } // namespace Core
diff --git a/src/plugins/coreplugin/vcsmanager.h b/src/plugins/coreplugin/vcsmanager.h
index 92e4f35d1540a2a2282b1fb361ae35ea231a75ef..a3afca96d6adef219ad847fcc7427d8818b92814 100644
--- a/src/plugins/coreplugin/vcsmanager.h
+++ b/src/plugins/coreplugin/vcsmanager.h
@@ -45,12 +45,12 @@ class IVersionControl;
 
 // The VCSManager has only one notable function:
 // findVersionControlFor(), which returns the IVersionControl * for a given
-// filename. Note that the VCSManager assumes that if a IVersionControl * 
+// filename. Note that the VCSManager assumes that if a IVersionControl *
 // manages a directory, then it also manages all the files and all the
 // subdirectories.
 //
 // It works by asking all IVersionControl * if they manage the file, and ask
-// for the topmost directory it manages. This information is cached and 
+// for the topmost directory it manages. This information is cached and
 // VCSManager thus knows pretty fast which IVersionControl * is responsible.
 
 class CORE_EXPORT VCSManager
@@ -62,10 +62,16 @@ public:
 
     IVersionControl *findVersionControlForDirectory(const QString &directory);
 
-    // Shows a confirmation dialog,
-    // wheter the file should also be deleted from revision control
-    // Calls sccDelete on the file
-    void showDeleteDialog(const QString &fileName);
+    // Enable the VCS managing a certain directory only. This should
+    // be used by project manager classes.
+    void setVCSEnabled(const QString &directory);
+    // Enable all VCS.
+    void setAllVCSEnabled();
+
+    // Shows a confirmation dialog, whether the file should also be deleted
+    // from revision control Calls sccDelete on the file. Returns false
+    // if a failure occurs
+    bool showDeleteDialog(const QString &fileName);
 
 private:
     VCSManagerPrivate *m_d;
diff --git a/src/plugins/cppeditor/cppeditor.cpp b/src/plugins/cppeditor/cppeditor.cpp
index 254e9341de66b16c24f814dfadeecd1ec0a7170d..da52bb3d6016a367647e00aa59197607fa8d19fa 100644
--- a/src/plugins/cppeditor/cppeditor.cpp
+++ b/src/plugins/cppeditor/cppeditor.cpp
@@ -206,6 +206,7 @@ void CPPEditor::createToolBar(CPPEditorEditable *editable)
 
     connect(m_methodCombo, SIGNAL(activated(int)), this, SLOT(jumpToMethod(int)));
     connect(this, SIGNAL(cursorPositionChanged()), this, SLOT(updateMethodBoxIndex()));
+    connect(m_methodCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(updateMethodBoxToolTip()));
 
     connect(file(), SIGNAL(changed()), this, SLOT(updateFileName()));
 
@@ -355,10 +356,16 @@ void CPPEditor::updateMethodBoxIndex()
     if (lastIndex.isValid()) {
         bool blocked = m_methodCombo->blockSignals(true);
         m_methodCombo->setCurrentIndex(lastIndex.row());
+        updateMethodBoxToolTip();
         (void) m_methodCombo->blockSignals(blocked);
     }
 }
 
+void CPPEditor::updateMethodBoxToolTip()
+{
+    m_methodCombo->setToolTip(m_methodCombo->currentText());
+}
+
 static bool isCompatible(Name *name, Name *otherName)
 {
     if (NameId *nameId = name->asNameId()) {
diff --git a/src/plugins/cppeditor/cppeditor.h b/src/plugins/cppeditor/cppeditor.h
index e6c6d1aa8633cd807179308b2761685119a0a247..2420bcf4e5e441d67834d5d9d0a612dbbad09f06 100644
--- a/src/plugins/cppeditor/cppeditor.h
+++ b/src/plugins/cppeditor/cppeditor.h
@@ -115,7 +115,7 @@ private slots:
     void updateFileName();
     void jumpToMethod(int index);
     void updateMethodBoxIndex();
-
+    void updateMethodBoxToolTip();
     void onDocumentUpdated(CPlusPlus::Document::Ptr doc);
 
 private:
diff --git a/src/plugins/cpptools/cppclassesfilter.cpp b/src/plugins/cpptools/cppclassesfilter.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..3d8da9a7387a209638c415d55abe3ddeb5fd039e
--- /dev/null
+++ b/src/plugins/cpptools/cppclassesfilter.cpp
@@ -0,0 +1,49 @@
+/***************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact:  Qt Software Information (qt-info@nokia.com)
+**
+**
+** Non-Open Source Usage
+**
+** Licensees may use this file in accordance with the Qt Beta Version
+** License Agreement, Agreement version 2.2 provided with the Software or,
+** alternatively, in accordance with the terms contained in a written
+** agreement between you and Nokia.
+**
+** GNU General Public License Usage
+**
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the packaging
+** of this file.  Please review the following information to ensure GNU
+** General Public Licensing requirements will be met:
+**
+** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt GPL Exception
+** version 1.2, included in the file GPL_EXCEPTION.txt in this package.
+**
+***************************************************************************/
+
+#include "cppclassesfilter.h"
+
+using namespace CppTools::Internal;
+
+CppClassesFilter::CppClassesFilter(CppModelManager *manager, Core::EditorManager *editorManager)
+    : CppQuickOpenFilter(manager, editorManager)
+{
+    setShortcutString("c");
+    setIncludedByDefault(false);
+
+    search.setSymbolsToSearchFor(SearchSymbols::Classes);
+}
+
+CppClassesFilter::~CppClassesFilter()
+{
+}
diff --git a/src/plugins/cpptools/cppclassesfilter.h b/src/plugins/cpptools/cppclassesfilter.h
new file mode 100644
index 0000000000000000000000000000000000000000..ba936eab869fe76cf9b9a0b9ef1ac5f0f266965e
--- /dev/null
+++ b/src/plugins/cpptools/cppclassesfilter.h
@@ -0,0 +1,58 @@
+/***************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact:  Qt Software Information (qt-info@nokia.com)
+**
+**
+** Non-Open Source Usage
+**
+** Licensees may use this file in accordance with the Qt Beta Version
+** License Agreement, Agreement version 2.2 provided with the Software or,
+** alternatively, in accordance with the terms contained in a written
+** agreement between you and Nokia.
+**
+** GNU General Public License Usage
+**
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the packaging
+** of this file.  Please review the following information to ensure GNU
+** General Public Licensing requirements will be met:
+**
+** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt GPL Exception
+** version 1.2, included in the file GPL_EXCEPTION.txt in this package.
+**
+***************************************************************************/
+
+#ifndef CPPCLASSESFILTER_H
+#define CPPCLASSESFILTER_H
+
+#include <cppquickopenfilter.h>
+
+namespace CppTools {
+namespace Internal {
+
+class CppClassesFilter : public CppQuickOpenFilter
+{
+    Q_OBJECT
+
+public:
+    CppClassesFilter(CppModelManager *manager, Core::EditorManager *editorManager);
+    ~CppClassesFilter();
+
+    QString trName() const { return tr("Classes"); }
+    QString name() const { return QLatin1String("Classes"); }
+    Priority priority() const { return Medium; }
+};
+
+} // namespace Internal
+} // namespace CppTools
+
+#endif // CPPCLASSESFILTER_H
diff --git a/src/plugins/cpptools/cpphoverhandler.cpp b/src/plugins/cpptools/cpphoverhandler.cpp
index 37b63bda9c23f4adf11670e34062efaded814a18..16ed8a9215039009e6d47403939d02d996824f83 100644
--- a/src/plugins/cpptools/cpphoverhandler.cpp
+++ b/src/plugins/cpptools/cpphoverhandler.cpp
@@ -60,7 +60,7 @@
 using namespace CppTools::Internal;
 
 CppHoverHandler::CppHoverHandler(CppModelManager *manager, QObject *parent)
-    : QObject(parent), m_manager(manager)
+    : QObject(parent), m_manager(manager), m_helpEngineNeedsSetup(false)
 {
     QFileInfo fi(ExtensionSystem::PluginManager::instance()->getObject<Core::ICore>()->settings()->fileName());
     m_helpEngine = new QHelpEngineCore(fi.absolutePath()
@@ -68,6 +68,7 @@ CppHoverHandler::CppHoverHandler(CppModelManager *manager, QObject *parent)
     //m_helpEngine->setAutoSaveFilter(false);
     m_helpEngine->setupData();
     m_helpEngine->setCurrentFilter(tr("Unfiltered"));
+    m_helpEngineNeedsSetup = m_helpEngine->registeredDocumentations().count() == 0;
 }
 
 void CppHoverHandler::updateContextHelpId(TextEditor::ITextEditor *editor, int pos)
@@ -234,6 +235,12 @@ void CppHoverHandler::updateHelpIdAndTooltip(TextEditor::ITextEditor *editor, in
         }
     }
 
+    if (m_helpEngineNeedsSetup
+        && m_helpEngine->registeredDocumentations().count() > 0) {
+        m_helpEngine->setupData();
+        m_helpEngineNeedsSetup = false;
+    }
+
     if (!m_helpId.isEmpty() && !m_helpEngine->linksForIdentifier(m_helpId).isEmpty()) {
         m_toolTip = QString(QLatin1String("<table><tr><td valign=middle><nobr>%1</td>"
                                           "<td><img src=\":/cpptools/images/f1.svg\"></td></tr></table>")).arg(Qt::escape(m_toolTip));
diff --git a/src/plugins/cpptools/cpphoverhandler.h b/src/plugins/cpptools/cpphoverhandler.h
index 9aaa17cb0f88e1e47c04ebca1a96114f53f6917b..d1de5277b1241468b5dfdfbeff5d9ec14ea49927 100644
--- a/src/plugins/cpptools/cpphoverhandler.h
+++ b/src/plugins/cpptools/cpphoverhandler.h
@@ -68,6 +68,7 @@ private:
     QHelpEngineCore *m_helpEngine;
     QString m_helpId;
     QString m_toolTip;
+    bool m_helpEngineNeedsSetup;
 };
 
 } // namespace Internal
diff --git a/src/plugins/cpptools/cppmodelmanager.cpp b/src/plugins/cpptools/cppmodelmanager.cpp
index 1708e62de35b26c5aae7bf7c25d4f5129505278b..b3f9fb604c3c46e6866f9a03eb6065a63942c13a 100644
--- a/src/plugins/cpptools/cppmodelmanager.cpp
+++ b/src/plugins/cpptools/cppmodelmanager.cpp
@@ -129,9 +129,12 @@ public:
     void setProjectFiles(const QStringList &files)
     { m_projectFiles = files; }
 
-    void operator()(QString &fileName)
+    void run(QString &fileName)
     { sourceNeeded(fileName, IncludeGlobal); }
 
+    void operator()(QString &fileName)
+    { run(fileName); }
+
 protected:
     bool includeFile(const QString &absoluteFilePath, QByteArray *result)
     {
@@ -253,6 +256,25 @@ protected:
         m_currentDoc->appendMacro(macroName, macroText);
     }
 
+    virtual void startExpandingMacro(unsigned offset,
+                                     const rpp::Macro &,
+                                     const QByteArray &originalText)
+    {
+        if (! m_currentDoc)
+            return;
+
+        //qDebug() << "start expanding:" << macro.name << "text:" << originalText;
+        m_currentDoc->addMacroUse(offset, originalText.length());
+    }
+
+    virtual void stopExpandingMacro(unsigned, const rpp::Macro &)
+    {
+        if (! m_currentDoc)
+            return;
+
+        //qDebug() << "stop expanding:" << macro.name;
+    }
+
     void mergeEnvironment(Document::Ptr doc)
     {
         QSet<QString> processed;
@@ -390,6 +412,8 @@ CppModelManager::CppModelManager(QObject *parent) :
     CppModelManagerInterface(parent),
     m_core(ExtensionSystem::PluginManager::instance()->getObject<Core::ICore>())
 {
+    m_dirty = true;
+
     m_projectExplorer = ExtensionSystem::PluginManager::instance()
                         ->getObject<ProjectExplorer::ProjectExplorerPlugin>();
 
@@ -398,6 +422,9 @@ CppModelManager::CppModelManager(QObject *parent) :
     ProjectExplorer::SessionManager *session = m_projectExplorer->session();
     Q_ASSERT(session != 0);
 
+    connect(session, SIGNAL(projectAdded(ProjectExplorer::Project*)),
+            this, SLOT(onProjectAdded(ProjectExplorer::Project*)));
+
     connect(session, SIGNAL(aboutToRemoveProject(ProjectExplorer::Project *)),
             this, SLOT(onAboutToRemoveProject(ProjectExplorer::Project *)));
 
@@ -429,7 +456,7 @@ Document::Ptr CppModelManager::document(const QString &fileName)
 CppModelManager::DocumentTable CppModelManager::documents()
 { return m_documents; }
 
-QStringList CppModelManager::projectFiles() const
+QStringList CppModelManager::updateProjectFiles() const
 {
     QStringList files;
     QMapIterator<ProjectExplorer::Project *, ProjectInfo> it(m_projects);
@@ -441,7 +468,7 @@ QStringList CppModelManager::projectFiles() const
     return files;
 }
 
-QStringList CppModelManager::includePaths() const
+QStringList CppModelManager::updateIncludePaths() const
 {
     QStringList includePaths;
     QMapIterator<ProjectExplorer::Project *, ProjectInfo> it(m_projects);
@@ -453,7 +480,7 @@ QStringList CppModelManager::includePaths() const
     return includePaths;
 }
 
-QStringList CppModelManager::frameworkPaths() const
+QStringList CppModelManager::updateFrameworkPaths() const
 {
     QStringList frameworkPaths;
     QMapIterator<ProjectExplorer::Project *, ProjectInfo> it(m_projects);
@@ -465,7 +492,7 @@ QStringList CppModelManager::frameworkPaths() const
     return frameworkPaths;
 }
 
-QByteArray CppModelManager::definedMacros() const
+QByteArray CppModelManager::updateDefinedMacros() const
 {
     QByteArray macros;
     QMapIterator<ProjectExplorer::Project *, ProjectInfo> it(m_projects);
@@ -477,7 +504,7 @@ QByteArray CppModelManager::definedMacros() const
     return macros;
 }
 
-QMap<QString, QByteArray> CppModelManager::buildWorkingCopyList() const
+QMap<QString, QByteArray> CppModelManager::buildWorkingCopyList()
 {
     QMap<QString, QByteArray> workingCopy;
     QMapIterator<TextEditor::ITextEditor *, CppEditorSupport *> it(m_editorSupport);
@@ -505,11 +532,17 @@ CppModelManager::ProjectInfo *CppModelManager::projectInfo(ProjectExplorer::Proj
 
 QFuture<void> CppModelManager::refreshSourceFiles(const QStringList &sourceFiles)
 {
-    if (qgetenv("QTCREATOR_NO_CODE_INDEXER").isNull()) {
+    if (! sourceFiles.isEmpty() && qgetenv("QTCREATOR_NO_CODE_INDEXER").isNull()) {
         const QMap<QString, QByteArray> workingCopy = buildWorkingCopyList();
 
-        QFuture<void> result = QtConcurrent::run(&CppModelManager::parse, this,
-                                                 sourceFiles, workingCopy);
+        CppPreprocessor *preproc = new CppPreprocessor(this);
+        preproc->setProjectFiles(projectFiles());
+        preproc->setIncludePaths(includePaths());
+        preproc->setFrameworkPaths(frameworkPaths());
+        preproc->setWorkingCopy(workingCopy);
+
+        QFuture<void> result = QtConcurrent::run(&CppModelManager::parse,
+                                                 preproc, sourceFiles);
 
         if (sourceFiles.count() > 1) {
             m_core->progressManager()->addTask(result, tr("Indexing"),
@@ -595,6 +628,22 @@ void CppModelManager::onDocumentUpdated(Document::Ptr doc)
 
             QList<QTextEdit::ExtraSelection> selections;
 
+#ifdef QTCREATOR_WITH_MACRO_HIGHLIGHTING
+            // set up the format for the macros
+            QTextCharFormat macroFormat;
+            macroFormat.setUnderlineStyle(QTextCharFormat::SingleUnderline);
+
+            QTextCursor c = ed->textCursor();
+            foreach (const Document::Block block, doc->macroUses()) {
+                QTextEdit::ExtraSelection sel;
+                sel.cursor = c;
+                sel.cursor.setPosition(block.begin());
+                sel.cursor.setPosition(block.end(), QTextCursor::KeepAnchor);
+                sel.format = macroFormat;
+                selections.append(sel);
+            }
+#endif // QTCREATOR_WITH_MACRO_HIGHLIGHTING
+
             // set up the format for the errors
             QTextCharFormat errorFormat;
             errorFormat.setUnderlineStyle(QTextCharFormat::WaveUnderline);
@@ -640,36 +689,39 @@ void CppModelManager::onDocumentUpdated(Document::Ptr doc)
     }
 }
 
+void CppModelManager::onProjectAdded(ProjectExplorer::Project *)
+{
+    m_dirty = true;
+}
+
 void CppModelManager::onAboutToRemoveProject(ProjectExplorer::Project *project)
 {
+    m_dirty = true;
     m_projects.remove(project);
     GC();
 }
 
 void CppModelManager::onSessionUnloaded()
 {
-    if (m_core->progressManager())
+    if (m_core->progressManager()) {
         m_core->progressManager()->cancelTasks(CppTools::Constants::TASK_INDEX);
+        m_dirty = true;
+    }
 }
 
 void CppModelManager::parse(QFutureInterface<void> &future,
-                            CppModelManager *model,
-                            QStringList files,
-                            QMap<QString, QByteArray> workingCopy)
+                            CppPreprocessor *preproc,
+                            QStringList files)
 {
+    Q_ASSERT(! files.isEmpty());
+
     // Change the priority of the background parser thread to idle.
     QThread::currentThread()->setPriority(QThread::IdlePriority);
 
     future.setProgressRange(0, files.size());
 
-    CppPreprocessor preproc(model);
-    preproc.setWorkingCopy(workingCopy);
-    preproc.setProjectFiles(model->projectFiles());
-    preproc.setIncludePaths(model->includePaths());
-    preproc.setFrameworkPaths(model->frameworkPaths());
-
     QString conf = QLatin1String(pp_configuration_file);
-    (void) preproc(conf);
+    (void) preproc->run(conf);
 
     const int STEP = 10;
 
@@ -688,7 +740,7 @@ void CppModelManager::parse(QFutureInterface<void> &future,
 #endif
 
         QString fileName = files.at(i);
-        preproc(fileName);
+        preproc->run(fileName);
 
         if (! (i % STEP)) // Yields execution of the current thread.
             QThread::yieldCurrentThread();
@@ -698,8 +750,12 @@ void CppModelManager::parse(QFutureInterface<void> &future,
 #endif
     }
 
+    future.setProgressValue(files.size());
+
     // Restore the previous thread priority.
     QThread::currentThread()->setPriority(QThread::NormalPriority);
+
+    delete preproc;
 }
 
 void CppModelManager::GC()
@@ -707,7 +763,7 @@ void CppModelManager::GC()
     DocumentTable documents = m_documents;
 
     QSet<QString> processed;
-    QStringList todo = m_projectFiles;
+    QStringList todo = projectFiles();
 
     while (! todo.isEmpty()) {
         QString fn = todo.last();
diff --git a/src/plugins/cpptools/cppmodelmanager.h b/src/plugins/cpptools/cppmodelmanager.h
index 187187cc5d313586293cd3fdb0e7d5186dc30c01..a91a414e4803e2464a68a149b5f1eac9ae43068a 100644
--- a/src/plugins/cpptools/cppmodelmanager.h
+++ b/src/plugins/cpptools/cppmodelmanager.h
@@ -58,6 +58,7 @@ namespace CppTools {
 namespace Internal {
 
 class CppEditorSupport;
+class CppPreprocessor;
 class CppHoverHandler;
 
 class CppModelManager : public CppModelManagerInterface
@@ -97,18 +98,54 @@ private Q_SLOTS:
     void onDocumentUpdated(CPlusPlus::Document::Ptr doc);
     void onAboutToRemoveProject(ProjectExplorer::Project *project);
     void onSessionUnloaded();
+    void onProjectAdded(ProjectExplorer::Project *project);
 
 private:
-    QMap<QString, QByteArray> buildWorkingCopyList() const;
-    QStringList projectFiles() const;
-    QStringList includePaths() const;
-    QStringList frameworkPaths() const;
-    QByteArray definedMacros() const;
+    QMap<QString, QByteArray> buildWorkingCopyList();
+
+    QStringList projectFiles()
+    {
+        ensureUpdated();
+        return m_projectFiles;
+    }
+
+    QStringList includePaths()
+    {
+        ensureUpdated();
+        return m_includePaths;
+    }
+
+    QStringList frameworkPaths()
+    {
+        ensureUpdated();
+        return m_frameworkPaths;
+    }
+
+    QByteArray definedMacros()
+    {
+        ensureUpdated();
+        return m_definedMacros;
+    }
+
+    QStringList updateProjectFiles() const;
+    QStringList updateIncludePaths() const;
+    QStringList updateFrameworkPaths() const;
+    QByteArray updateDefinedMacros() const;
+
+    void ensureUpdated() {
+        if (! m_dirty)
+            return;
+
+        m_projectFiles = updateProjectFiles();
+        m_includePaths = updateIncludePaths();
+        m_frameworkPaths = updateFrameworkPaths();
+        m_definedMacros = updateDefinedMacros();
+        m_dirty = false;
+    }
 
     static void parse(QFutureInterface<void> &future,
-                      CppModelManager *model,
-                      QStringList files,
-                      QMap<QString, QByteArray> workingCopy);
+                      CppPreprocessor *preproc,
+                      QStringList files);
 
 private:
     Core::ICore *m_core;
@@ -116,8 +153,12 @@ private:
     CppHoverHandler *m_hoverHandler;
     DocumentTable m_documents;
 
-    // List of available source files
+    // cache
+    bool m_dirty;
     QStringList m_projectFiles;
+    QStringList m_includePaths;
+    QStringList m_frameworkPaths;
+    QByteArray m_definedMacros;
 
     // editor integration
     QMap<TextEditor::ITextEditor *, CppEditorSupport *> m_editorSupport;
diff --git a/src/plugins/cpptools/cppquickopenfilter.cpp b/src/plugins/cpptools/cppquickopenfilter.cpp
index 9470ec46039a57c77e3d1499b71c3e457f01c190..a1f1a9b3713e00c76a967d2922dad17875c48034 100644
--- a/src/plugins/cpptools/cppquickopenfilter.cpp
+++ b/src/plugins/cpptools/cppquickopenfilter.cpp
@@ -32,172 +32,13 @@
 ***************************************************************************/
 
 #include "cppquickopenfilter.h"
+#include "cppmodelmanager.h"
 
-#include <Literals.h>
-#include <Symbols.h>
-#include <SymbolVisitor.h>
-#include <Scope.h>
-#include <cplusplus/Overview.h>
-#include <cplusplus/Icons.h>
-
+#include <coreplugin/editormanager/editormanager.h>
 #include <coreplugin/editormanager/ieditor.h>
 #include <texteditor/itexteditor.h>
 #include <texteditor/basetexteditor.h>
 
-#include <QtCore/QMultiMap>
-
-#include <functional>
-
-using namespace CPlusPlus;
-
-namespace CppTools {
-namespace Internal {
-
-class SearchSymbols: public std::unary_function<Document::Ptr, QList<ModelItemInfo> >,
-                     protected SymbolVisitor
-{
-    Overview overview;
-    Icons icons;
-    QList<ModelItemInfo> items;
-
-public:
-    QList<ModelItemInfo> operator()(Document::Ptr doc)
-    { return operator()(doc, QString()); }
-
-    QList<ModelItemInfo> operator()(Document::Ptr doc, const QString &scope)
-    {
-        QString previousScope = switchScope(scope);
-        items.clear();
-        for (unsigned i = 0; i < doc->globalSymbolCount(); ++i) {
-            accept(doc->globalSymbolAt(i));
-        }
-        (void) switchScope(previousScope);
-        return items;
-    }
-
-protected:
-    using SymbolVisitor::visit;
-
-    void accept(Symbol *symbol)
-    { Symbol::visitSymbol(symbol, this); }
-
-    QString switchScope(const QString &scope)
-    {
-        QString previousScope = _scope;
-        _scope = scope;
-        return previousScope;
-    }
-
-    virtual bool visit(Enum *symbol)
-    {
-        QString name = symbolName(symbol);
-        QString previousScope = switchScope(name);
-        QIcon icon = icons.iconForSymbol(symbol);
-        Scope *members = symbol->members();
-        items.append(ModelItemInfo(name, QString(), ModelItemInfo::Enum,
-                                   QString::fromUtf8(symbol->fileName(), symbol->fileNameLength()),
-                                   symbol->line(),
-                                   icon));
-        for (unsigned i = 0; i < members->symbolCount(); ++i) {
-            accept(members->symbolAt(i));
-        }
-        (void) switchScope(previousScope);
-        return false;
-    }
-
-    virtual bool visit(Function *symbol)
-    {
-        QString name = symbolName(symbol);
-        QString type = overview.prettyType(symbol->type());
-        QIcon icon = icons.iconForSymbol(symbol);
-        items.append(ModelItemInfo(name, type, ModelItemInfo::Method,
-                                   QString::fromUtf8(symbol->fileName(), symbol->fileNameLength()),
-                                   symbol->line(),
-                                   icon));
-        return false;
-    }
-
-    virtual bool visit(Namespace *symbol)
-    {
-        QString name = symbolName(symbol);
-        QString previousScope = switchScope(name);
-        Scope *members = symbol->members();
-        for (unsigned i = 0; i < members->symbolCount(); ++i) {
-            accept(members->symbolAt(i));
-        }
-        (void) switchScope(previousScope);
-        return false;
-    }
-#if 0
-    // This visit method would make function declaration be included in QuickOpen
-    virtual bool visit(Declaration *symbol)
-    {
-        if (symbol->type()->isFunction()) {
-            QString name = symbolName(symbol);
-            QString type = overview.prettyType(symbol->type());
-            //QIcon icon = ...;
-            items.append(ModelItemInfo(name, type, ModelItemInfo::Method,
-                                       QString::fromUtf8(symbol->fileName(), symbol->line()),
-                                       symbol->line()));
-        }
-        return false;
-    }
-#endif
-    virtual bool visit(Class *symbol)
-    {
-        QString name = symbolName(symbol);
-        QString previousScope = switchScope(name);
-        QIcon icon = icons.iconForSymbol(symbol);
-        items.append(ModelItemInfo(name, QString(), ModelItemInfo::Class,
-                                   QString::fromUtf8(symbol->fileName(), symbol->fileNameLength()),
-                                   symbol->line(),
-                                   icon));
-        Scope *members = symbol->members();
-        for (unsigned i = 0; i < members->symbolCount(); ++i) {
-            accept(members->symbolAt(i));
-        }
-        (void) switchScope(previousScope);
-        return false;
-    }
-
-    QString symbolName(Symbol *symbol) const
-    {
-        QString name = _scope;
-        if (! name.isEmpty())
-            name += QLatin1String("::");
-        QString symbolName = overview.prettyName(symbol->name());
-        if (symbolName.isEmpty()) {
-            QString type;
-            if (symbol->isNamespace()) {
-                type = QLatin1String("namespace");
-            } else if (symbol->isEnum()) {
-                type = QLatin1String("enum");
-            } else if (Class *c = symbol->asClass())  {
-                if (c->isUnion()) {
-                    type = QLatin1String("union");
-                } else if (c->isStruct()) {
-                    type = QLatin1String("struct");
-                } else {
-                    type = QLatin1String("class");
-                }
-            } else {
-                type = QLatin1String("symbol");
-            }
-            symbolName = QLatin1String("<anonymous ");
-            symbolName += type;
-            symbolName += QLatin1String(">");
-        }
-        name += symbolName;
-        return name;
-    }
-
-private:
-    QString _scope;
-};
-
-} // namespace Internal
-} // namespace CppTools
-
 using namespace CppTools::Internal;
 
 CppQuickOpenFilter::CppQuickOpenFilter(CppModelManager *manager, Core::EditorManager *editorManager)
@@ -225,9 +66,8 @@ void CppQuickOpenFilter::onDocumentUpdated(CPlusPlus::Document::Ptr doc)
 
 void CppQuickOpenFilter::onAboutToRemoveFiles(const QStringList &files)
 {
-    foreach (QString file, files) {
+    foreach (const QString &file, files)
         m_searchList.remove(file);
-    }
 }
 
 void CppQuickOpenFilter::refresh(QFutureInterface<void> &future)
@@ -245,7 +85,6 @@ QList<QuickOpen::FilterEntry> CppQuickOpenFilter::matchesFor(const QString &orig
         return entries;
     bool hasWildcard = (entry.contains('*') || entry.contains('?'));
 
-    SearchSymbols search;
     QMutableMapIterator<QString, Info> it(m_searchList);
     while (it.hasNext()) {
         it.next();
@@ -276,6 +115,5 @@ QList<QuickOpen::FilterEntry> CppQuickOpenFilter::matchesFor(const QString &orig
 void CppQuickOpenFilter::accept(QuickOpen::FilterEntry selection) const
 {
     ModelItemInfo info = qvariant_cast<CppTools::Internal::ModelItemInfo>(selection.internalData);
-
     TextEditor::BaseTextEditor::openEditorAt(info.fileName, info.line);
 }
diff --git a/src/plugins/cpptools/cppquickopenfilter.h b/src/plugins/cpptools/cppquickopenfilter.h
index bf6696a02af24ed690d286177e6ed9746e206112..12eaacb3f980d194b7c1e69416dbd6d8ec2b3504 100644
--- a/src/plugins/cpptools/cppquickopenfilter.h
+++ b/src/plugins/cpptools/cppquickopenfilter.h
@@ -34,45 +34,18 @@
 #ifndef CPPQUICKOPENFILTER_H
 #define CPPQUICKOPENFILTER_H
 
-#include "cppmodelmanager.h"
-#include <cplusplus/CppDocument.h>
-#include <coreplugin/editormanager/editormanager.h>
+#include "searchsymbols.h"
+
 #include <quickopen/iquickopenfilter.h>
-#include <QtGui/QIcon>
-#include <QFile>
-#include <QMetaType>
+
+namespace Core {
+class EditorManager;
+}
 
 namespace CppTools {
 namespace Internal {
 
-struct ModelItemInfo
-{
-    enum ItemType { Enum, Class, Method };
-
-    ModelItemInfo()
-    { }
-
-    ModelItemInfo(const QString &symbolName,
-                  const QString &symbolType,
-                  ItemType type,
-                  const QString &fileName,
-                  int line,
-                  const QIcon &icon)
-        : symbolName(symbolName),
-          symbolType(symbolType),
-          type(type),
-          fileName(fileName),
-          line(line),
-          icon(icon)
-    { }
-
-    QString symbolName;
-    QString symbolType;
-    ItemType type;
-    QString fileName;
-    int line;
-    QIcon icon;
-};
+class CppModelManager;
 
 class CppQuickOpenFilter : public QuickOpen::IQuickOpenFilter
 {
@@ -82,12 +55,15 @@ public:
     ~CppQuickOpenFilter();
 
     QString trName() const { return tr("Classes and Methods"); }
-    QString name() const { return "Classes and Methods"; }
+    QString name() const { return QLatin1String("Classes and Methods"); }
     Priority priority() const { return Medium; }
     QList<QuickOpen::FilterEntry> matchesFor(const QString &entry);
     void accept(QuickOpen::FilterEntry selection) const;
     void refresh(QFutureInterface<void> &future);
 
+protected:
+    SearchSymbols search;
+
 private slots:
     void onDocumentUpdated(CPlusPlus::Document::Ptr doc);
     void onAboutToRemoveFiles(const QStringList &files);
@@ -114,6 +90,4 @@ private:
 } // namespace Internal
 } // namespace CppTools
 
-Q_DECLARE_METATYPE(CppTools::Internal::ModelItemInfo)
-
 #endif // CPPQUICKOPENFILTER_H
diff --git a/src/plugins/cpptools/cpptools.cpp b/src/plugins/cpptools/cpptools.cpp
index 423ddf3016d0d4a967dffd0d4a7e236163aa9793..957f0cae9b07ed7bf97842baaf316c2dd7bd53a2 100644
--- a/src/plugins/cpptools/cpptools.cpp
+++ b/src/plugins/cpptools/cpptools.cpp
@@ -32,6 +32,7 @@
 ***************************************************************************/
 
 #include "cpptools.h"
+#include "cppclassesfilter.h"
 #include "cppcodecompletion.h"
 #include "cpphoverhandler.h"
 #include "cppmodelmanager.h"
@@ -87,6 +88,7 @@ bool CppToolsPlugin::initialize(const QStringList & /*arguments*/, QString *)
     CppQuickOpenFilter *quickOpenFilter = new CppQuickOpenFilter(m_modelManager,
                                                                  m_core->editorManager());
     addAutoReleasedObject(quickOpenFilter);
+    addAutoReleasedObject(new CppClassesFilter(m_modelManager, m_core->editorManager()));
 
     // Menus
     Core::IActionContainer *mtools = am->actionContainer(Core::Constants::M_TOOLS);
diff --git a/src/plugins/cpptools/cpptools.pro b/src/plugins/cpptools/cpptools.pro
index 17b72496a92f3a8c398e8bc3972da1983a7b8230..8a096900ebf699ba9f0712eafb670660ebffb113 100644
--- a/src/plugins/cpptools/cpptools.pro
+++ b/src/plugins/cpptools/cpptools.pro
@@ -4,31 +4,27 @@ include(../../qworkbenchplugin.pri)
 include(../../plugins/quickopen/quickopen.pri)
 include(cpptools_dependencies.pri)
 
-#DEFINES += QT_NO_CAST_FROM_ASCII
+# DEFINES += QT_NO_CAST_FROM_ASCII
 DEFINES += QT_NO_CAST_TO_ASCII
-unix:QMAKE_CXXFLAGS_DEBUG+=-O3
-
+unix:QMAKE_CXXFLAGS_DEBUG += -O3
 INCLUDEPATH += .
-
 DEFINES += CPPTOOLS_LIBRARY
-
 CONFIG += help
 include(rpp/rpp.pri)|error("Can't find RPP")
-
-HEADERS += \
-    cpptools_global.h \
-    cppquickopenfilter.h
-
-SOURCES += \
-    cppquickopenfilter.cpp \
-    cpptoolseditorsupport.cpp
+HEADERS += cpptools_global.h \
+    cppquickopenfilter.h \
+    cppclassesfilter.h \
+    searchsymbols.h
+SOURCES += cppquickopenfilter.cpp \
+    cpptoolseditorsupport.cpp \
+    cppclassesfilter.cpp \
+    searchsymbols.cpp
 
 # Input
 SOURCES += cpptools.cpp \
     cppmodelmanager.cpp \
     cppcodecompletion.cpp \
     cpphoverhandler.cpp
-
 HEADERS += cpptools.h \
     cppmodelmanager.h \
     cppcodecompletion.h \
@@ -36,5 +32,4 @@ HEADERS += cpptools.h \
     cppmodelmanagerinterface.h \
     cpptoolseditorsupport.h \
     cpptoolsconstants.h
-
 RESOURCES += cpptools.qrc
diff --git a/src/plugins/cpptools/rpp/pp-client.h b/src/plugins/cpptools/rpp/pp-client.h
index 073fc44c3627ad3643e18eef4be96c2e565a8f40..974004a6ce50ec85aeb2df035d63c686df19b444 100644
--- a/src/plugins/cpptools/rpp/pp-client.h
+++ b/src/plugins/cpptools/rpp/pp-client.h
@@ -40,6 +40,8 @@
 
 namespace rpp {
 
+class Macro;
+
 class Client
 {
   Client(const Client &other);
@@ -61,6 +63,13 @@ public:
   virtual void macroAdded(const QByteArray &macroId, const QByteArray &text) = 0;
   virtual void sourceNeeded(QString &fileName, IncludeType mode) = 0; // ### FIX the signature.
 
+  virtual void startExpandingMacro(unsigned offset,
+                                   const Macro &macro,
+                                   const QByteArray &originalTextt) = 0;
+
+  virtual void stopExpandingMacro(unsigned offset,
+                                  const Macro &macro) = 0;
+
   virtual void startSkippingBlocks(unsigned offset) = 0;
   virtual void stopSkippingBlocks(unsigned offset) = 0;
 };
diff --git a/src/plugins/cpptools/rpp/pp-engine.cpp b/src/plugins/cpptools/rpp/pp-engine.cpp
index 3a3e9245b30229a330fe9f3ea894eb5ec9a66b29..66e8957f355e5dc28c25c755b4d86e83d49f5a04 100644
--- a/src/plugins/cpptools/rpp/pp-engine.cpp
+++ b/src/plugins/cpptools/rpp/pp-engine.cpp
@@ -575,7 +575,17 @@ void pp::operator()(const QByteArray &source, QByteArray *result)
 
                 const QByteArray spell = tokenSpell(*identifierToken);
                 if (env.isBuiltinMacro(spell)) {
+                    const Macro trivial;
+
+                    if (client)
+                        client->startExpandingMacro(identifierToken->offset,
+                                                    trivial, spell);
+
                     expand(spell.constBegin(), spell.constEnd(), result);
+
+                    if (client)
+                        client->stopExpandingMacro(_dot->offset, trivial);
+
                     continue;
                 }
 
@@ -585,18 +595,36 @@ void pp::operator()(const QByteArray &source, QByteArray *result)
                 } else {
                     if (! m->function_like) {
                         if (_dot->isNot(T_LPAREN)) {
+                            if (client)
+                                client->startExpandingMacro(identifierToken->offset,
+                                                            *m, spell);
+
                             m->hidden = true;
+
                             expand(m->definition.constBegin(),
                                    m->definition.constEnd(),
                                    result);
+
+                            if (client)
+                                client->stopExpandingMacro(_dot->offset, *m);
+
                             m->hidden = false;
                             continue;
                         } else {
                             QByteArray tmp;
                             m->hidden = true;
+
+                            if (client)
+                                client->startExpandingMacro(identifierToken->offset,
+                                                            *m, spell);
+
                             expand(m->definition.constBegin(),
                                    m->definition.constEnd(),
                                    &tmp);
+
+                            if (client)
+                                client->stopExpandingMacro(_dot->offset, *m);
+
                             m->hidden = false;
 
                             m = 0; // reset the active the macro
@@ -640,9 +668,20 @@ void pp::operator()(const QByteArray &source, QByteArray *result)
                         const char *beginOfText = startOfToken(*identifierToken);
                         const char *endOfText = endOfToken(*_dot);
                         ++_dot; // skip T_RPAREN
-                        //m->hidden = true;
+
+                        if (client) {
+                            const QByteArray text =
+                                    QByteArray::fromRawData(beginOfText,
+                                                            endOfText - beginOfText);
+
+                            client->startExpandingMacro(identifierToken->offset,
+                                                        *m, text);
+                        }
+
                         expand(beginOfText, endOfText, result);
-                        //m->hidden = false;
+
+                        if (client)
+                            client->stopExpandingMacro(_dot->offset, *m);
                     }
                 }
             }
diff --git a/src/plugins/cpptools/searchsymbols.cpp b/src/plugins/cpptools/searchsymbols.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..c0d29aae18a7fabde085f4a5e129abd1e4fb7539
--- /dev/null
+++ b/src/plugins/cpptools/searchsymbols.cpp
@@ -0,0 +1,178 @@
+/***************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact:  Qt Software Information (qt-info@nokia.com)
+**
+**
+** Non-Open Source Usage
+**
+** Licensees may use this file in accordance with the Qt Beta Version
+** License Agreement, Agreement version 2.2 provided with the Software or,
+** alternatively, in accordance with the terms contained in a written
+** agreement between you and Nokia.
+**
+** GNU General Public License Usage
+**
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the packaging
+** of this file.  Please review the following information to ensure GNU
+** General Public Licensing requirements will be met:
+**
+** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt GPL Exception
+** version 1.2, included in the file GPL_EXCEPTION.txt in this package.
+**
+***************************************************************************/
+
+#include "searchsymbols.h"
+
+#include <Literals.h>
+#include <Scope.h>
+
+using namespace CPlusPlus;
+using namespace CppTools::Internal;
+
+SearchSymbols::SearchSymbols():
+    symbolsToSearchFor(ClassesMethodsFunctionsAndEnums)
+{
+}
+
+void SearchSymbols::setSymbolsToSearchFor(SymbolType type)
+{
+    symbolsToSearchFor = type;
+}
+
+QList<ModelItemInfo> SearchSymbols::operator()(Document::Ptr doc, const QString &scope)
+{
+    QString previousScope = switchScope(scope);
+    items.clear();
+    for (unsigned i = 0; i < doc->globalSymbolCount(); ++i) {
+        accept(doc->globalSymbolAt(i));
+    }
+    (void) switchScope(previousScope);
+    return items;
+}
+
+QString SearchSymbols::switchScope(const QString &scope)
+{
+    QString previousScope = _scope;
+    _scope = scope;
+    return previousScope;
+}
+
+bool SearchSymbols::visit(Enum *symbol)
+{
+    if (symbolsToSearchFor != ClassesMethodsFunctionsAndEnums)
+        return false;
+
+    QString name = symbolName(symbol);
+    QString previousScope = switchScope(name);
+    QIcon icon = icons.iconForSymbol(symbol);
+    Scope *members = symbol->members();
+    items.append(ModelItemInfo(name, QString(), ModelItemInfo::Enum,
+                               QString::fromUtf8(symbol->fileName(), symbol->fileNameLength()),
+                               symbol->line(),
+                               icon));
+    for (unsigned i = 0; i < members->symbolCount(); ++i) {
+        accept(members->symbolAt(i));
+    }
+    (void) switchScope(previousScope);
+    return false;
+}
+
+bool SearchSymbols::visit(Function *symbol)
+{
+    if (symbolsToSearchFor != ClassesMethodsFunctionsAndEnums)
+        return false;
+
+    QString name = symbolName(symbol);
+    QString type = overview.prettyType(symbol->type());
+    QIcon icon = icons.iconForSymbol(symbol);
+    items.append(ModelItemInfo(name, type, ModelItemInfo::Method,
+                               QString::fromUtf8(symbol->fileName(), symbol->fileNameLength()),
+                               symbol->line(),
+                               icon));
+    return false;
+}
+
+bool SearchSymbols::visit(Namespace *symbol)
+{
+    QString name = symbolName(symbol);
+    QString previousScope = switchScope(name);
+    Scope *members = symbol->members();
+    for (unsigned i = 0; i < members->symbolCount(); ++i) {
+        accept(members->symbolAt(i));
+    }
+    (void) switchScope(previousScope);
+    return false;
+}
+
+#if 0
+bool SearchSymbols::visit(Declaration *symbol)
+{
+    if (symbol->type()->isFunction()) {
+        QString name = symbolName(symbol);
+        QString type = overview.prettyType(symbol->type());
+        //QIcon icon = ...;
+        items.append(ModelItemInfo(name, type, ModelItemInfo::Method,
+                                   QString::fromUtf8(symbol->fileName(), symbol->line()),
+                                   symbol->line()));
+    }
+    return false;
+}
+#endif
+
+bool SearchSymbols::visit(Class *symbol)
+{
+    QString name = symbolName(symbol);
+    QString previousScope = switchScope(name);
+    QIcon icon = icons.iconForSymbol(symbol);
+    items.append(ModelItemInfo(name, QString(), ModelItemInfo::Class,
+                               QString::fromUtf8(symbol->fileName(), symbol->fileNameLength()),
+                               symbol->line(),
+                               icon));
+    Scope *members = symbol->members();
+    for (unsigned i = 0; i < members->symbolCount(); ++i) {
+        accept(members->symbolAt(i));
+    }
+    (void) switchScope(previousScope);
+    return false;
+}
+
+QString SearchSymbols::symbolName(const Symbol *symbol) const
+{
+    QString name = _scope;
+    if (! name.isEmpty())
+        name += QLatin1String("::");
+    QString symbolName = overview.prettyName(symbol->name());
+    if (symbolName.isEmpty()) {
+        QString type;
+        if (symbol->isNamespace()) {
+            type = QLatin1String("namespace");
+        } else if (symbol->isEnum()) {
+            type = QLatin1String("enum");
+        } else if (const Class *c = symbol->asClass())  {
+            if (c->isUnion()) {
+                type = QLatin1String("union");
+            } else if (c->isStruct()) {
+                type = QLatin1String("struct");
+            } else {
+                type = QLatin1String("class");
+            }
+        } else {
+            type = QLatin1String("symbol");
+        }
+        symbolName = QLatin1String("<anonymous ");
+        symbolName += type;
+        symbolName += QLatin1String(">");
+    }
+    name += symbolName;
+    return name;
+}
diff --git a/src/plugins/cpptools/searchsymbols.h b/src/plugins/cpptools/searchsymbols.h
new file mode 100644
index 0000000000000000000000000000000000000000..d9b678e026fb6778ada898736a45ea3936e571e2
--- /dev/null
+++ b/src/plugins/cpptools/searchsymbols.h
@@ -0,0 +1,128 @@
+/***************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact:  Qt Software Information (qt-info@nokia.com)
+**
+**
+** Non-Open Source Usage
+**
+** Licensees may use this file in accordance with the Qt Beta Version
+** License Agreement, Agreement version 2.2 provided with the Software or,
+** alternatively, in accordance with the terms contained in a written
+** agreement between you and Nokia.
+**
+** GNU General Public License Usage
+**
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the packaging
+** of this file.  Please review the following information to ensure GNU
+** General Public Licensing requirements will be met:
+**
+** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt GPL Exception
+** version 1.2, included in the file GPL_EXCEPTION.txt in this package.
+**
+***************************************************************************/
+
+#ifndef SEARCHSYMBOLS_H
+#define SEARCHSYMBOLS_H
+
+#include <cplusplus/CppDocument.h>
+#include <cplusplus/Icons.h>
+#include <cplusplus/Overview.h>
+#include <Symbols.h>
+#include <SymbolVisitor.h>
+
+#include <QIcon>
+#include <QMetaType>
+#include <QString>
+
+namespace CppTools {
+namespace Internal {
+
+struct ModelItemInfo
+{
+    enum ItemType { Enum, Class, Method };
+
+    ModelItemInfo()
+    { }
+
+    ModelItemInfo(const QString &symbolName,
+                  const QString &symbolType,
+                  ItemType type,
+                  const QString &fileName,
+                  int line,
+                  const QIcon &icon)
+        : symbolName(symbolName),
+          symbolType(symbolType),
+          type(type),
+          fileName(fileName),
+          line(line),
+          icon(icon)
+    { }
+
+    QString symbolName;
+    QString symbolType;
+    ItemType type;
+    QString fileName;
+    int line;
+    QIcon icon;
+};
+
+class SearchSymbols: public std::unary_function<CPlusPlus::Document::Ptr, QList<ModelItemInfo> >,
+                     protected CPlusPlus::SymbolVisitor
+{
+public:
+    // TODO: Probably should use QFlags
+    enum SymbolType {
+        Classes,
+        ClassesMethodsFunctionsAndEnums
+    };
+
+    SearchSymbols();
+
+    void setSymbolsToSearchFor(SymbolType type);
+
+    QList<ModelItemInfo> operator()(CPlusPlus::Document::Ptr doc)
+    { return operator()(doc, QString()); }
+
+    QList<ModelItemInfo> operator()(CPlusPlus::Document::Ptr doc, const QString &scope);
+
+protected:
+    using SymbolVisitor::visit;
+
+    void accept(CPlusPlus::Symbol *symbol)
+    { CPlusPlus::Symbol::visitSymbol(symbol, this); }
+
+    QString switchScope(const QString &scope);
+    virtual bool visit(CPlusPlus::Enum *symbol);
+    virtual bool visit(CPlusPlus::Function *symbol);
+    virtual bool visit(CPlusPlus::Namespace *symbol);
+#if 0
+    // This visit method would make function declaration be included in QuickOpen
+    virtual bool visit(CPlusPlus::Declaration *symbol);
+#endif
+    virtual bool visit(CPlusPlus::Class *symbol);
+    QString symbolName(const CPlusPlus::Symbol *symbol) const;
+
+private:
+    QString _scope;
+    CPlusPlus::Overview overview;
+    CPlusPlus::Icons icons;
+    QList<ModelItemInfo> items;
+    SymbolType symbolsToSearchFor;
+};
+
+} // namespace Internal
+} // namespace CppTools
+
+Q_DECLARE_METATYPE(CppTools::Internal::ModelItemInfo)
+
+#endif // SEARCHSYMBOLS_H
diff --git a/src/plugins/debugger/breakhandler.cpp b/src/plugins/debugger/breakhandler.cpp
index 8199d4ab518ddc3a1884cb009c5d688b6096ba55..f4b528c50fa9816f896ab3941c062e5f44e0ac2e 100644
--- a/src/plugins/debugger/breakhandler.cpp
+++ b/src/plugins/debugger/breakhandler.cpp
@@ -231,6 +231,11 @@ BreakHandler::BreakHandler(QObject *parent)
 {
 }
 
+BreakHandler::~BreakHandler()
+{
+    clear();
+}
+
 int BreakHandler::columnCount(const QModelIndex &parent) const
 {
     return parent.isValid() ? 0 : 6;
diff --git a/src/plugins/debugger/breakhandler.h b/src/plugins/debugger/breakhandler.h
index 4581e3a4de97552328dfda23835a41124214ec54..95743f6df50d4727741ffa1f0b4f15d508eff287 100644
--- a/src/plugins/debugger/breakhandler.h
+++ b/src/plugins/debugger/breakhandler.h
@@ -113,6 +113,7 @@ class BreakHandler : public QAbstractItemModel
 
 public:
     explicit BreakHandler(QObject *parent = 0);
+    ~BreakHandler();
 
     void removeAllBreakpoints();
     void setAllPending();
diff --git a/src/plugins/debugger/debuggermanager.cpp b/src/plugins/debugger/debuggermanager.cpp
index f696d728467654a5df68124e060c28f030c97fcc..a94b1fb0931e3ac551f4fb815126b947ec998b80 100644
--- a/src/plugins/debugger/debuggermanager.cpp
+++ b/src/plugins/debugger/debuggermanager.cpp
@@ -317,10 +317,20 @@ void DebuggerManager::init()
 
     m_debugDumpersAction = new QAction(this);
     m_debugDumpersAction->setText(tr("Debug Custom Dumpers"));
+    m_debugDumpersAction->setToolTip(tr("This is an internal tool to "
+        "make debugging the Custom Data Dumper code easier. "
+        "Using this action is in general not needed unless you "
+        "want do debug Qt Creator itself."));
     m_debugDumpersAction->setCheckable(true);
 
     m_skipKnownFramesAction = new QAction(this);
     m_skipKnownFramesAction->setText(tr("Skip Known Frames When Stepping"));
+    m_skipKnownFramesAction->setToolTip(tr("After checking this option"
+        "'Step Into' combines in certain situations several steps, "
+        "leading to 'less noisy' debugging. So will, e.g., the atomic "
+        "reference counting code be skipped, and a single 'Step Into' "
+        "for a signal emission will end up directly in the slot connected "
+        "to it"));
     m_skipKnownFramesAction->setCheckable(true);
 
     m_useCustomDumpersAction = new QAction(this);
@@ -330,13 +340,6 @@ void DebuggerManager::init()
     m_useCustomDumpersAction->setCheckable(true);
     m_useCustomDumpersAction->setChecked(true);
 
-    m_useCustomDumpersAction = new QAction(this);
-    m_useCustomDumpersAction->setText(tr("Use Custom Display for Qt Objects"));
-    m_useCustomDumpersAction->setToolTip(tr("Checking this will make the debugger "
-        "try to use code to format certain data (QObject, QString, ...) nicely. "));
-    m_useCustomDumpersAction->setCheckable(true);
-    m_useCustomDumpersAction->setChecked(true);
-
     m_useFastStartAction = new QAction(this);
     m_useFastStartAction->setText(tr("Fast Debugger Start"));
     m_useFastStartAction->setToolTip(tr("Checking this will make the debugger "
@@ -622,7 +625,7 @@ void DebuggerManager::notifyInferiorPidChanged(int pid)
 
 void DebuggerManager::showApplicationOutput(const QString &prefix, const QString &str)
 {
-     applicationOutputAvailable(prefix, str);
+     emit applicationOutputAvailable(prefix, str);
 }
 
 void DebuggerManager::shutdown()
diff --git a/src/plugins/debugger/debuggerrunner.cpp b/src/plugins/debugger/debuggerrunner.cpp
index c161c9bad9881f49f5bbe555b27a0f3afe0c734d..90c8c4e9f7d6dc53acf6bfe7dfcbc415b596b0e1 100644
--- a/src/plugins/debugger/debuggerrunner.cpp
+++ b/src/plugins/debugger/debuggerrunner.cpp
@@ -44,6 +44,7 @@
 #include <QtCore/QDebug>
 #include <QtCore/QDir>
 #include <QtCore/QFileInfo>
+#include <QtGui/QTextDocument>
 
 using namespace Debugger::Internal;
 
@@ -140,8 +141,8 @@ void DebuggerRunControl::slotAddToOutputWindow(const QString &prefix, const QStr
 {  
     Q_UNUSED(prefix);
     foreach (const QString &l, line.split('\n'))
-        emit addToOutputWindow(this, prefix + l);
-    //emit addToOutputWindow(this, prefix + line);
+        emit addToOutputWindow(this, prefix + Qt::escape(l));
+    //emit addToOutputWindow(this, prefix + Qt::escape(line));
 }
 
 void DebuggerRunControl::stop()
diff --git a/src/plugins/debugger/gdbengine.cpp b/src/plugins/debugger/gdbengine.cpp
index df0eaa9f0b293d0379236ebc67172daf095aba40..80d0a046fc3179f334fa054f8ba1abcd59500cdd 100644
--- a/src/plugins/debugger/gdbengine.cpp
+++ b/src/plugins/debugger/gdbengine.cpp
@@ -110,7 +110,6 @@ enum GdbCommandType
     GdbFileExecAndSymbols,
     GdbQueryPwd,
     GdbQuerySources,
-    GdbQuerySources2,
     GdbAsyncOutput2,
     GdbExecRun,
     GdbExecRunToFunction,
@@ -126,7 +125,6 @@ enum GdbCommandType
     GdbInfoProc,
     GdbQueryDataDumper1,
     GdbQueryDataDumper2,
-    GdbInitializeSocket1,
 
     BreakCondition = 200,
     BreakEnablePending,
@@ -444,7 +442,7 @@ void GdbEngine::handleResponse()
             break;
         }
 
-        if (token == -1 && *from != '&' && *from != '~') {
+        if (token == -1 && *from != '&' && *from != '~' && *from != '*') {
             // FIXME: On Linux the application's std::out is merged in here.
             // High risk of falsely interpreting this as MI output.
             // We assume that we _always_ use tokens, so not finding a token
@@ -493,8 +491,10 @@ void GdbEngine::handleResponse()
                 m_inbuffer = QByteArray(from, to - from);
                 if (asyncClass == "stopped") {
                     handleAsyncOutput(record);
+                } else if (asyncClass == "running") {
+                    // Archer has 'thread-id="all"' here
                 } else {
-                    qDebug() << "INGNORED ASYNC OUTPUT " << record.toString();
+                    qDebug() << "IGNORED ASYNC OUTPUT " << record.toString();
                 }
                 break;
             }
@@ -633,18 +633,10 @@ void GdbEngine::readGdbStandardOutput()
 {
     // This is the function called whenever the Gdb process created
     // output. As a rule of thumb, stdout contains _real_ Gdb output
-    // as responses to our command (with exception of the data dumpers)
+    // as responses to our command
     // and "spontaneous" events like messages on loaded shared libraries.
-    // Otoh, stderr contains application output produced by qDebug etc.
-    // There is no organized way to pass application stdout output
-
-    // The result of custom data dumpers arrives over the socket _before_
-    // the corresponding Gdb "^done" message arrives here over stdout
-    // and is merged into the response via m_pendingCustomValueContents.
-
-    // Note that this code here runs syncronized to the arriving
-    // output. The completed response will be signalled by a queued
-    // connection to the handlers.
+    // OTOH, stderr contains application output produced by qDebug etc.
+    // There is no organized way to pass application stdout output.
 
     QByteArray out = m_gdbProc.readAllStandardOutput();
 
@@ -765,19 +757,12 @@ void GdbEngine::handleResultRecord(const GdbResultRecord &record)
     //qDebug() << "TOKEN: " << record.token
     //    << " ACCEPTABLE: " << m_oldestAcceptableToken;
     //qDebug() << "";
-    //qDebug() << qPrintable(currentTime()) << "Reading response:  "
-    //   << record.toString() << "\n";
     //qDebug() << "\nRESULT" << record.token << record.toString();
 
     int token = record.token;
     if (token == -1)
         return;
 
-    if (!m_cookieForToken.contains(token)) {
-        qDebug() << "NO SUCH TOKEN (ANYMORE): " << token;
-        return;
-    }
-
     GdbCookie cmd = m_cookieForToken.take(token);
 
     // FIXME: this falsely rejects results from the custom dumper recognition
@@ -788,12 +773,6 @@ void GdbEngine::handleResultRecord(const GdbResultRecord &record)
         return;
     }
 
-    // We get _two_ results for a '-exec-foo' command: First a
-    // 'running' notification, then a 'stopped' or similar.
-    // So put it back.
-    if (record.resultClass == GdbResultRunning)
-        m_cookieForToken[token] = cmd;
-
 #if 0
     qDebug() << "# handleOutput, "
         << "cmd type: " << cmd.type
@@ -858,18 +837,12 @@ void GdbEngine::handleResult(const GdbResultRecord & record, int type,
         case GdbQuerySources:
             handleQuerySources(record);
             break;
-        case GdbQuerySources2:
-            handleQuerySources2(record, cookie);
-            break;
         case GdbAsyncOutput2:
             handleAsyncOutput2(cookie.value<GdbMi>());
             break;
         case GdbInfoShared:
             handleInfoShared(record);
             break;
-        case GdbInitializeSocket1:
-            //qDebug() << " INIT SOCKET" << record.toString();
-            break;
         case GdbQueryDataDumper1:
             handleQueryDataDumper1(record);
             break;
@@ -1072,13 +1045,6 @@ void GdbEngine::handleInfoShared(const GdbResultRecord &record)
     }
 }
 
-void GdbEngine::handleQuerySources2(const GdbResultRecord &record,
-    const QVariant &cookie)
-{
-    if (record.resultClass == GdbResultDone)
-        handleAsyncOutput2(cookie.value<GdbMi>());
-}
-
 void GdbEngine::handleExecJumpToLine(const GdbResultRecord &record)
 {
     // FIXME: remove this special case as soon as 'jump'
@@ -3681,11 +3647,16 @@ void GdbEngine::handleStackListLocals(const GdbResultRecord &record)
     // stage 2/2
 
     // There could be shadowed variables
-    QHash<QString, int> seen;
     QList<GdbMi> locals = record.data.findChild("locals").children();
     locals += m_currentFunctionArgs;
 
+    setLocals(locals);
+}
+
+void GdbEngine::setLocals(const QList<GdbMi> &locals) 
+{ 
     //qDebug() << m_varToType;
+    QHash<QString, int> seen;
 
     foreach (const GdbMi &item, locals) {
         #ifdef Q_OS_MAC
diff --git a/src/plugins/debugger/gdbengine.h b/src/plugins/debugger/gdbengine.h
index 45eafcdb92c6172f62fa634f4fb450b79e87f29c..b3e13233526754ac0d0c41bec3992bd668f19913 100644
--- a/src/plugins/debugger/gdbengine.h
+++ b/src/plugins/debugger/gdbengine.h
@@ -206,8 +206,6 @@ private:
     void handleShowVersion(const GdbResultRecord &response);
     void handleQueryPwd(const GdbResultRecord &response);
     void handleQuerySources(const GdbResultRecord &response);
-    void handleQuerySources2(const GdbResultRecord &response,
-        const QVariant &);
 
     QByteArray m_inbuffer;
 
@@ -219,7 +217,6 @@ private:
     QByteArray m_pendingConsoleStreamOutput;
     QByteArray m_pendingTargetStreamOutput;
     QByteArray m_pendingLogStreamOutput;
-    //QByteArray m_pendingCustomValueContents;
     QString m_pwd;
 
     // contains the first token number for the current round
@@ -329,6 +326,7 @@ private:
     void handleVarListChildrenHelper(const GdbMi &child,
         const WatchData &parent);
     void setWatchDataType(WatchData &data, const GdbMi &mi);
+    void setLocals(const QList<GdbMi> &locals);
 
     QString m_editedData;
     int m_pendingRequests;
diff --git a/src/plugins/find/finddialog.ui b/src/plugins/find/finddialog.ui
index 7240551772071624b06dcf80b47e75b3af48b97e..479299316f6d6b68d2ed4259593a5a814f215464 100644
--- a/src/plugins/find/finddialog.ui
+++ b/src/plugins/find/finddialog.ui
@@ -1,7 +1,8 @@
-<ui version="4.0" >
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
  <class>Find::Internal::FindDialog</class>
- <widget class="QDialog" name="Find::Internal::FindDialog" >
-  <property name="geometry" >
+ <widget class="QDialog" name="Find::Internal::FindDialog">
+  <property name="geometry">
    <rect>
     <x>0</x>
     <y>0</y>
@@ -9,109 +10,109 @@
     <height>168</height>
    </rect>
   </property>
-  <property name="sizePolicy" >
-   <sizepolicy vsizetype="Minimum" hsizetype="Minimum" >
+  <property name="sizePolicy">
+   <sizepolicy hsizetype="Minimum" vsizetype="Minimum">
     <horstretch>0</horstretch>
     <verstretch>0</verstretch>
    </sizepolicy>
   </property>
-  <property name="windowTitle" >
+  <property name="windowTitle">
    <string>Search for...</string>
   </property>
-  <property name="sizeGripEnabled" >
+  <property name="sizeGripEnabled">
    <bool>false</bool>
   </property>
-  <layout class="QVBoxLayout" name="verticalLayout" >
+  <layout class="QVBoxLayout" name="verticalLayout">
    <item>
-    <layout class="QGridLayout" name="gridLayout" >
-     <item row="0" column="0" >
-      <widget class="QLabel" name="label" >
-       <property name="sizePolicy" >
-        <sizepolicy vsizetype="Preferred" hsizetype="Fixed" >
+    <layout class="QGridLayout" name="gridLayout">
+     <item row="0" column="0">
+      <widget class="QLabel" name="label">
+       <property name="sizePolicy">
+        <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
          <horstretch>0</horstretch>
          <verstretch>0</verstretch>
         </sizepolicy>
        </property>
-       <property name="minimumSize" >
+       <property name="minimumSize">
         <size>
          <width>80</width>
          <height>0</height>
         </size>
        </property>
-       <property name="text" >
+       <property name="text">
         <string>Sc&amp;ope:</string>
        </property>
-       <property name="alignment" >
+       <property name="alignment">
         <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
        </property>
-       <property name="buddy" >
+       <property name="buddy">
         <cstring>filterList</cstring>
        </property>
       </widget>
      </item>
-     <item row="0" column="1" >
-      <widget class="QComboBox" name="filterList" >
-       <property name="sizePolicy" >
-        <sizepolicy vsizetype="Fixed" hsizetype="Expanding" >
+     <item row="0" column="1">
+      <widget class="QComboBox" name="filterList">
+       <property name="sizePolicy">
+        <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
          <horstretch>0</horstretch>
          <verstretch>0</verstretch>
         </sizepolicy>
        </property>
       </widget>
      </item>
-     <item row="0" column="2" >
-      <widget class="QPushButton" name="searchButton" >
-       <property name="text" >
+     <item row="0" column="2">
+      <widget class="QPushButton" name="searchButton">
+       <property name="text">
         <string>&amp;Search</string>
        </property>
-       <property name="default" >
+       <property name="default">
         <bool>true</bool>
        </property>
       </widget>
      </item>
-     <item row="1" column="0" >
-      <widget class="QLabel" name="label_2" >
-       <property name="text" >
+     <item row="1" column="0">
+      <widget class="QLabel" name="label_2">
+       <property name="text">
         <string>Search &amp;for:</string>
        </property>
-       <property name="alignment" >
+       <property name="alignment">
         <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
        </property>
-       <property name="buddy" >
+       <property name="buddy">
         <cstring>searchTerm</cstring>
        </property>
       </widget>
      </item>
-     <item row="1" column="1" >
-      <widget class="QLineEdit" name="searchTerm" />
+     <item row="1" column="1">
+      <widget class="QLineEdit" name="searchTerm"/>
      </item>
-     <item row="1" column="2" >
-      <widget class="QPushButton" name="closeButton" >
-       <property name="text" >
-        <string>&amp;Close</string>
+     <item row="1" column="2">
+      <widget class="QPushButton" name="closeButton">
+       <property name="text">
+        <string>Close</string>
        </property>
       </widget>
      </item>
-     <item row="4" column="0" colspan="2" >
-      <widget class="QWidget" native="1" name="configWidget" >
-       <property name="sizePolicy" >
-        <sizepolicy vsizetype="Fixed" hsizetype="Preferred" >
+     <item row="4" column="0" colspan="2">
+      <widget class="QWidget" name="configWidget" native="true">
+       <property name="sizePolicy">
+        <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
          <horstretch>0</horstretch>
          <verstretch>10</verstretch>
         </sizepolicy>
        </property>
       </widget>
      </item>
-     <item row="2" column="1" >
-      <widget class="QCheckBox" name="matchCase" >
-       <property name="text" >
-        <string>Match &amp;case</string>
+     <item row="2" column="1">
+      <widget class="QCheckBox" name="matchCase">
+       <property name="text">
+        <string>&amp;Case sensitive</string>
        </property>
       </widget>
      </item>
-     <item row="3" column="1" >
-      <widget class="QCheckBox" name="wholeWords" >
-       <property name="text" >
+     <item row="3" column="1">
+      <widget class="QCheckBox" name="wholeWords">
+       <property name="text">
         <string>&amp;Whole words only</string>
        </property>
       </widget>
@@ -119,11 +120,11 @@
     </layout>
    </item>
    <item>
-    <spacer name="verticalSpacer_2" >
-     <property name="orientation" >
+    <spacer name="verticalSpacer_2">
+     <property name="orientation">
       <enum>Qt::Vertical</enum>
      </property>
-     <property name="sizeHint" stdset="0" >
+     <property name="sizeHint" stdset="0">
       <size>
        <width>0</width>
        <height>0</height>
diff --git a/src/plugins/git/commitdata.cpp b/src/plugins/git/commitdata.cpp
index 60e2173a660ab315b406c5c79313d256a934f107..7ea937233c7e115e901b56ff72d58809edcece29 100644
--- a/src/plugins/git/commitdata.cpp
+++ b/src/plugins/git/commitdata.cpp
@@ -80,16 +80,16 @@ void CommitData::clear()
     panelInfo.clear();
     panelData.clear();
 
-    commitFiles.clear();
-    notUpdatedFiles.clear();
+    stagedFiles.clear();
+    unstagedFiles.clear();
     untrackedFiles.clear();
 }
 
 QDebug operator<<(QDebug d, const CommitData &data)
 {
     d <<  data.panelInfo << data.panelData;
-    d.nospace() << "Commit: " << data.commitFiles << " Not updated: "
-        << data.notUpdatedFiles << " Untracked: " << data.untrackedFiles;
+    d.nospace() << "Commit: " << data.stagedFiles << " Not updated: "
+        << data.unstagedFiles << " Untracked: " << data.untrackedFiles;
     return d;
 }
 
diff --git a/src/plugins/git/commitdata.h b/src/plugins/git/commitdata.h
index 9cd5a83eb16c3e01fec0950c6ef3675354c440bb..b535168f6f357e56e7aa3877313ea9871febeee8 100644
--- a/src/plugins/git/commitdata.h
+++ b/src/plugins/git/commitdata.h
@@ -71,8 +71,8 @@ struct CommitData
     void clear();
     GitSubmitEditorPanelInfo panelInfo;
     GitSubmitEditorPanelData panelData;
-    QStringList commitFiles;
-    QStringList notUpdatedFiles;
+    QStringList stagedFiles;
+    QStringList unstagedFiles;
     QStringList untrackedFiles;
 };
 
diff --git a/src/plugins/git/git.pro b/src/plugins/git/git.pro
index 258639dcbe3416cce70579750af6d0b4dd600c12..3c4ca176cb5aa8bfce855a81e380b780ac0739c2 100644
--- a/src/plugins/git/git.pro
+++ b/src/plugins/git/git.pro
@@ -17,7 +17,9 @@ HEADERS += gitplugin.h \
     giteditor.h \
     annotationhighlighter.h \
     gitsubmiteditorwidget.h \
-    gitsubmiteditor.h
+    gitsubmiteditor.h \
+    gitversioncontrol.h \
+    gitsettings.h
 
 SOURCES += gitplugin.cpp \
     gitoutputwindow.cpp \
@@ -28,7 +30,9 @@ SOURCES += gitplugin.cpp \
     giteditor.cpp \
     annotationhighlighter.cpp \
     gitsubmiteditorwidget.cpp \
-    gitsubmiteditor.cpp
+    gitsubmiteditor.cpp \
+    gitversioncontrol.cpp \
+    gitsettings.cpp
 
 FORMS += changeselectiondialog.ui \
     settingspage.ui \
diff --git a/src/plugins/git/gitclient.cpp b/src/plugins/git/gitclient.cpp
index fb73d4fe5e2b41a2a750f4ab656d3966baab951c..a1668e60cebcf93343e54862c30a7f429cf933dd 100644
--- a/src/plugins/git/gitclient.cpp
+++ b/src/plugins/git/gitclient.cpp
@@ -35,6 +35,7 @@
 #include "gitplugin.h"
 #include "gitconstants.h"
 #include "commitdata.h"
+#include "gitsubmiteditor.h"
 
 #include <coreplugin/icore.h>
 #include <coreplugin/coreconstants.h>
@@ -49,8 +50,11 @@
 #include <QtCore/QRegExp>
 #include <QtCore/QTemporaryFile>
 #include <QtCore/QFuture>
+#include <QtCore/QTime>
 
-#include <QtGui/QErrorMessage>
+#include <QtGui/QMessageBox>
+#include <QtGui/QMainWindow> // for msg box parent
+#include <QtGui/QPushButton>
 
 using namespace Git;
 using namespace Git::Internal;
@@ -76,22 +80,37 @@ inline Core::IEditor* locateEditor(const Core::ICore *core, const char *property
     return 0;
 }
 
+static inline QString msgRepositoryNotFound(const QString &dir)
+{
+    return GitClient::tr("Unable to determine the repository for %1.").arg(dir);
+}
+
+static inline QString msgParseFilesFailed()
+{
+    return  GitClient::tr("Unable to parse the file output.");
+}
+
+// Format a command for the status window
+static QString formatCommand(const QString &binary, const QStringList &args)
+{
+    const QString timeStamp = QTime::currentTime().toString(QLatin1String("HH:mm"));
+    return GitClient::tr("%1 Executing: %2 %3\n").arg(timeStamp, binary, args.join(QString(QLatin1Char(' '))));
+}
+
+// ---------------- GitClient
 GitClient::GitClient(GitPlugin* plugin, Core::ICore *core) :
     m_msgWait(tr("Waiting for data...")),
     m_plugin(plugin),
     m_core(core)
 {
+    if (QSettings *s = m_core->settings())
+        m_settings.fromSettings(s);
 }
 
 GitClient::~GitClient()
 {
 }
 
-bool GitClient::vcsOpen(const QString &fileName)
-{
-    return m_plugin->vcsOpen(fileName);
-}
-
 QString GitClient::findRepositoryForFile(const QString &fileName)
 {
     const QString gitDirectory = QLatin1String(kGitDirectoryC);
@@ -176,7 +195,7 @@ void GitClient::diff(const QString &workingDirectory, const QStringList &fileNam
     const QString title = tr("Git Diff");
 
     VCSBase::VCSBaseEditor *editor = createVCSEditor(kind, title, workingDirectory, true, "originalFileName", workingDirectory);
-    executeGit(workingDirectory, arguments, m_plugin->m_outputWindow, editor);
+    executeGit(workingDirectory, arguments, m_plugin->outputWindow(), editor);
 
 }
 
@@ -194,27 +213,26 @@ void GitClient::diff(const QString &workingDirectory, const QString &fileName)
     const QString sourceFile = source(workingDirectory, fileName);
 
     VCSBase::VCSBaseEditor *editor = createVCSEditor(kind, title, sourceFile, true, "originalFileName", sourceFile);
-    executeGit(workingDirectory, arguments, m_plugin->m_outputWindow, editor);
+    executeGit(workingDirectory, arguments, m_plugin->outputWindow(), editor);
 }
 
 void GitClient::status(const QString &workingDirectory)
 {
     QStringList statusArgs(QLatin1String("status"));
     statusArgs << QLatin1String("-u");
-    executeGit(workingDirectory, statusArgs, m_plugin->m_outputWindow, 0,true);
+    executeGit(workingDirectory, statusArgs, m_plugin->outputWindow(), 0,true);
 }
 
 void GitClient::log(const QString &workingDirectory, const QString &fileName)
 {
     if (Git::Constants::debug)
         qDebug() << "log" << workingDirectory << fileName;
-    QStringList arguments;
-    int logCount = 10;
-    if (m_plugin->m_settingsPage && m_plugin->m_settingsPage->logCount() > 0)
-        logCount = m_plugin->m_settingsPage->logCount();
 
-    arguments << QLatin1String("log") << QLatin1String("-n")
-        << QString::number(logCount);
+    QStringList arguments(QLatin1String("log"));
+
+    if (m_settings.logCount > 0)
+         arguments << QLatin1String("-n") << QString::number(m_settings.logCount);
+
     if (!fileName.isEmpty())
         arguments << fileName;
 
@@ -222,7 +240,7 @@ void GitClient::log(const QString &workingDirectory, const QString &fileName)
     const QString kind = QLatin1String(Git::Constants::GIT_LOG_EDITOR_KIND);
     const QString sourceFile = source(workingDirectory, fileName);
     VCSBase::VCSBaseEditor *editor = createVCSEditor(kind, title, sourceFile, false, "logFileName", sourceFile);
-    executeGit(workingDirectory, arguments, m_plugin->m_outputWindow, editor);
+    executeGit(workingDirectory, arguments, m_plugin->outputWindow(), editor);
 }
 
 void GitClient::show(const QString &source, const QString &id)
@@ -238,7 +256,7 @@ void GitClient::show(const QString &source, const QString &id)
 
     const QFileInfo sourceFi(source);
     const QString workDir = sourceFi.isDir() ? sourceFi.absoluteFilePath() : sourceFi.absolutePath();
-    executeGit(workDir, arguments, m_plugin->m_outputWindow, editor);
+    executeGit(workDir, arguments, m_plugin->outputWindow(), editor);
 }
 
 void GitClient::blame(const QString &workingDirectory, const QString &fileName)
@@ -253,7 +271,7 @@ void GitClient::blame(const QString &workingDirectory, const QString &fileName)
     const QString sourceFile = source(workingDirectory, fileName);
 
     VCSBase::VCSBaseEditor *editor = createVCSEditor(kind, title, sourceFile, true, "blameFileName", sourceFile);
-    executeGit(workingDirectory, arguments, m_plugin->m_outputWindow, editor);
+    executeGit(workingDirectory, arguments, m_plugin->outputWindow(), editor);
 }
 
 void GitClient::checkout(const QString &workingDirectory, const QString &fileName)
@@ -267,7 +285,7 @@ void GitClient::checkout(const QString &workingDirectory, const QString &fileNam
     arguments << QLatin1String("checkout") << QLatin1String("HEAD") << QLatin1String("--")
             << fileName;
 
-    executeGit(workingDirectory, arguments, m_plugin->m_outputWindow, 0,true);
+    executeGit(workingDirectory, arguments, m_plugin->outputWindow(), 0,true);
 }
 
 void GitClient::hardReset(const QString &workingDirectory, const QString &commit)
@@ -277,7 +295,7 @@ void GitClient::hardReset(const QString &workingDirectory, const QString &commit
     if (!commit.isEmpty())
         arguments << commit;
 
-    executeGit(workingDirectory, arguments, m_plugin->m_outputWindow, 0,true);
+    executeGit(workingDirectory, arguments, m_plugin->outputWindow(), 0,true);
 }
 
 void GitClient::addFile(const QString &workingDirectory, const QString &fileName)
@@ -285,7 +303,7 @@ void GitClient::addFile(const QString &workingDirectory, const QString &fileName
     QStringList arguments;
     arguments << QLatin1String("add") << fileName;
 
-    executeGit(workingDirectory, arguments, m_plugin->m_outputWindow, 0,true);
+    executeGit(workingDirectory, arguments, m_plugin->outputWindow(), 0,true);
 }
 
 bool GitClient::synchronousAdd(const QString &workingDirectory, const QStringList &files)
@@ -300,14 +318,27 @@ bool GitClient::synchronousAdd(const QString &workingDirectory, const QStringLis
     if (!rc) {
         const QString errorMessage = tr("Unable to add %n file(s) to %1: %2", 0, files.size()).
                                      arg(workingDirectory, QString::fromLocal8Bit(errorText));
-        m_plugin->m_outputWindow->append(errorMessage);
-        m_plugin->m_outputWindow->popup(false);
+        m_plugin->outputWindow()->append(errorMessage);
+        m_plugin->outputWindow()->popup(false);
     }
     return rc;
 }
 
 bool GitClient::synchronousReset(const QString &workingDirectory,
                                  const QStringList &files)
+{
+    QString errorMessage;
+    const bool rc = synchronousReset(workingDirectory, files, &errorMessage);
+    if (!rc) {
+        m_plugin->outputWindow()->append(errorMessage);
+        m_plugin->outputWindow()->popup(false);
+    }
+    return rc;
+}
+
+bool GitClient::synchronousReset(const QString &workingDirectory,
+                                 const QStringList &files,
+                                 QString *errorMessage)
 {
     if (Git::Constants::debug)
         qDebug() << Q_FUNC_INFO << workingDirectory << files;
@@ -317,14 +348,30 @@ bool GitClient::synchronousReset(const QString &workingDirectory,
     arguments << QLatin1String("reset") << QLatin1String("HEAD") << QLatin1String("--") << files;
     const bool rc = synchronousGit(workingDirectory, arguments, &outputText, &errorText);
     const QString output = QString::fromLocal8Bit(outputText);
-    m_plugin->m_outputWindow->popup(false);
-    m_plugin->m_outputWindow->append(output);
+    m_plugin->outputWindow()->popup(false);
+    m_plugin->outputWindow()->append(output);
     // Note that git exits with 1 even if the operation is successful
     // Assume real failure if the output does not contain "foo.cpp modified"
     if (!rc && !output.contains(QLatin1String("modified"))) {
-        const QString errorMessage = tr("Unable to reset %n file(s) in %1: %2", 0, files.size()).
-                                     arg(workingDirectory, QString::fromLocal8Bit(errorText));
-        m_plugin->m_outputWindow->append(errorMessage);
+        *errorMessage = tr("Unable to reset %n file(s) in %1: %2", 0, files.size()).arg(workingDirectory, QString::fromLocal8Bit(errorText));
+        return false;
+    }
+    return true;
+}
+
+bool GitClient::synchronousCheckout(const QString &workingDirectory,
+                                    const QStringList &files,
+                                    QString *errorMessage)
+{
+    if (Git::Constants::debug)
+        qDebug() << Q_FUNC_INFO << workingDirectory << files;
+    QByteArray outputText;
+    QByteArray errorText;
+    QStringList arguments;
+    arguments << QLatin1String("checkout") << QLatin1String("--") << files;
+    const bool rc = synchronousGit(workingDirectory, arguments, &outputText, &errorText);
+    if (!rc) {
+        *errorMessage = tr("Unable to checkout %n file(s) in %1: %2", 0, files.size()).arg(workingDirectory, QString::fromLocal8Bit(errorText));
         return false;
     }
     return true;
@@ -336,13 +383,14 @@ void GitClient::executeGit(const QString &workingDirectory, const QStringList &a
 {
     if (Git::Constants::debug)
         qDebug() << "executeGit" << workingDirectory << arguments << editor;
-    outputWindow->clearContents();
+
+    m_plugin->outputWindow()->append(formatCommand(QLatin1String(kGitCommand), arguments));
 
     QProcess process;
     ProjectExplorer::Environment environment = ProjectExplorer::Environment::systemEnvironment();
 
-    if (m_plugin->m_settingsPage && !m_plugin->m_settingsPage->adoptEnvironment())
-        environment.set(QLatin1String("PATH"), m_plugin->m_settingsPage->path());
+    if (m_settings.adoptPath)
+        environment.set(QLatin1String("PATH"), m_settings.path);
 
     GitCommand* command = new GitCommand();
     if (outputToWindow) {
@@ -361,23 +409,28 @@ void GitClient::executeGit(const QString &workingDirectory, const QStringList &a
     command->execute(arguments, workingDirectory, environment);
 }
 
-bool GitClient::synchronousGit(const QString &workingDirectory
-                                , const QStringList &arguments
-                                , QByteArray* outputText
-                                , QByteArray* errorText)
+bool GitClient::synchronousGit(const QString &workingDirectory,
+                               const QStringList &arguments,
+                               QByteArray* outputText,
+                               QByteArray* errorText,
+                               bool logCommandToWindow)
 {
     if (Git::Constants::debug)
         qDebug() << "synchronousGit" << workingDirectory << arguments;
-    QProcess process;
+    const QString binary = QLatin1String(kGitCommand);
+
+    if (logCommandToWindow)
+        m_plugin->outputWindow()->append(formatCommand(binary, arguments));
 
+    QProcess process;
     process.setWorkingDirectory(workingDirectory);
 
     ProjectExplorer::Environment environment = ProjectExplorer::Environment::systemEnvironment();
-    if (m_plugin->m_settingsPage && !m_plugin->m_settingsPage->adoptEnvironment())
-        environment.set(QLatin1String("PATH"), m_plugin->m_settingsPage->path());
+    if (m_settings.adoptPath)
+        environment.set(QLatin1String("PATH"), m_settings.path);
     process.setEnvironment(environment.toStringList());
 
-    process.start(QLatin1String(kGitCommand), arguments);
+    process.start(binary, arguments);
     if (!process.waitForFinished()) {
         if (errorText)
             *errorText = "Error: Git timed out";
@@ -411,6 +464,34 @@ static inline QString trimFileSpecification(QString fileSpec)
     return fileSpec;
 }
 
+GitClient::StatusResult GitClient::gitStatus(const QString &workingDirectory,
+                                             bool untracked,
+                                             QString *output,
+                                             QString *errorMessage)
+{
+    // Run 'status'. Note that git returns exitcode 1 if there are no added files.
+    QByteArray outputText;
+    QByteArray errorText;
+    QStringList statusArgs(QLatin1String("status"));
+    if (untracked)
+        statusArgs << QLatin1String("-u");
+    const bool statusRc = synchronousGit(workingDirectory, statusArgs, &outputText, &errorText);
+    if (output)
+        *output = QString::fromLocal8Bit(outputText).remove(QLatin1Char('\r'));
+    // Is it something really fatal?
+    if (!statusRc && !outputText.contains(kBranchIndicatorC)) {
+        if (errorMessage) {
+            const QString error = QString::fromLocal8Bit(errorText).remove(QLatin1Char('\r'));
+            *errorMessage = tr("Unable to obtain the status: %1").arg(error);
+        }
+        return StatusFailed;
+    }
+    // Unchanged?
+    if (outputText.contains("nothing to commit"))
+        return StatusUnchanged;
+    return StatusChanged;
+}
+
 /* Parse a git status file list:
  * \code
     # Changes to be committed:
@@ -421,10 +502,11 @@ static inline QString trimFileSpecification(QString fileSpec)
     #<tab>modified:<blanks>git.pro
     \endcode
 */
-static bool parseFiles(const QStringList &lines, CommitData *d)
+static bool parseFiles(const QString &output, CommitData *d)
 {
     enum State { None, CommitFiles, NotUpdatedFiles, UntrackedFiles };
 
+    const QStringList lines = output.split(QLatin1Char('\n'));
     const QString branchIndicator = QLatin1String(kBranchIndicatorC);
     const QString commitIndicator = QLatin1String("# Changes to be committed:");
     const QString notUpdatedIndicator = QLatin1String("# Changed but not updated:");
@@ -457,10 +539,10 @@ static bool parseFiles(const QStringList &lines, CommitData *d)
                             const QString fileSpec = line.mid(2).trimmed();
                             switch (s) {
                             case CommitFiles:
-                                d->commitFiles.push_back(trimFileSpecification(fileSpec));
+                                d->stagedFiles.push_back(trimFileSpecification(fileSpec));
                             break;
                             case NotUpdatedFiles:
-                                d->notUpdatedFiles.push_back(trimFileSpecification(fileSpec));
+                                d->unstagedFiles.push_back(trimFileSpecification(fileSpec));
                                 break;
                             case UntrackedFiles:
                                 d->untrackedFiles.push_back(QLatin1String("untracked: ") + fileSpec);
@@ -474,7 +556,7 @@ static bool parseFiles(const QStringList &lines, CommitData *d)
             }
         }
     }
-    return !d->commitFiles.empty() || !d->notUpdatedFiles.empty() || !d->untrackedFiles.empty();
+    return !d->stagedFiles.empty() || !d->unstagedFiles.empty() || !d->untrackedFiles.empty();
 }
 
 bool GitClient::getCommitData(const QString &workingDirectory,
@@ -482,12 +564,15 @@ bool GitClient::getCommitData(const QString &workingDirectory,
                               CommitData *d,
                               QString *errorMessage)
 {
+    if (Git::Constants::debug)
+        qDebug() << Q_FUNC_INFO << workingDirectory;
+
     d->clear();
 
     // Find repo
     const QString repoDirectory = GitClient::findRepositoryForDirectory(workingDirectory);
     if (repoDirectory.isEmpty()) {
-        *errorMessage = tr("Unable to determine the repository for %1.").arg(workingDirectory);
+        *errorMessage = msgRepositoryNotFound(workingDirectory);
         return false;
     }
 
@@ -508,23 +593,15 @@ bool GitClient::getCommitData(const QString &workingDirectory,
     }
 
     // Run status. Note that it has exitcode 1 if there are no added files.
-    QByteArray outputText;
-    QByteArray errorText;
-    QStringList statusArgs(QLatin1String("status"));
-    if (untrackedFilesInCommit)
-        statusArgs << QLatin1String("-u");
-    const bool statusRc = synchronousGit(workingDirectory, statusArgs, &outputText, &errorText);
-    if (!statusRc) {
-        // Something fatal
-        if (!outputText.contains(kBranchIndicatorC)) {
-            *errorMessage = tr("Unable to obtain the project status: %1").arg(QString::fromLocal8Bit(errorText));
-            return false;
-        }
-        // All unchanged
-        if (outputText.contains("nothing to commit")) {
-            *errorMessage = tr("There are no modified files.");
-            return false;
-        }
+    QString output;
+    switch (gitStatus(repoDirectory, untrackedFilesInCommit, &output, errorMessage)) {
+    case  StatusChanged:
+        break;
+    case StatusUnchanged:
+        *errorMessage = msgNoChangedFiles();
+        return false;
+    case StatusFailed:
+        return false;
     }
 
     //    Output looks like:
@@ -545,9 +622,8 @@ bool GitClient::getCommitData(const QString &workingDirectory,
     //    #
     //    #       list of files...
 
-    const QStringList lines = QString::fromLocal8Bit(outputText).remove(QLatin1Char('\r')).split(QLatin1Char('\n'));
-    if (!parseFiles(lines, d)) {
-        *errorMessage = tr("Unable to parse the file output.");
+    if (!parseFiles(output, d)) {
+        *errorMessage = msgParseFilesFailed();
         return false;
     }
 
@@ -570,24 +646,24 @@ bool GitClient::getCommitData(const QString &workingDirectory,
 }
 
 // addAndCommit:
-bool GitClient::addAndCommit(const QString &workingDirectory,
+bool GitClient::addAndCommit(const QString &repositoryDirectory,
                              const GitSubmitEditorPanelData &data,
                              const QString &messageFile,
                              const QStringList &checkedFiles,
                              const QStringList &origCommitFiles)
 {
     if (Git::Constants::debug)
-        qDebug() << "GitClient::addAndCommit:" << workingDirectory << checkedFiles << origCommitFiles;
+        qDebug() << "GitClient::addAndCommit:" << repositoryDirectory << checkedFiles << origCommitFiles;
 
     // Do we need to reset any files that had been added before
     // (did the user uncheck any previously added files)
     const QSet<QString> resetFiles = origCommitFiles.toSet().subtract(checkedFiles.toSet());
     if (!resetFiles.empty())
-        if (!synchronousReset(workingDirectory, resetFiles.toList()))
+        if (!synchronousReset(repositoryDirectory, resetFiles.toList()))
             return false;
 
     // Re-add all to make sure we have the latest changes
-    if (!synchronousAdd(workingDirectory, checkedFiles))
+    if (!synchronousAdd(repositoryDirectory, checkedFiles))
         return false;
 
     // Do the final commit
@@ -598,24 +674,192 @@ bool GitClient::addAndCommit(const QString &workingDirectory,
 
     QByteArray outputText;
     QByteArray errorText;
-    const bool rc = synchronousGit(workingDirectory, args, &outputText, &errorText);
+    const bool rc = synchronousGit(repositoryDirectory, args, &outputText, &errorText);
     const QString message = rc ?
-        tr("Committed %n file(s).", 0, checkedFiles.size()) :
-        tr("Unable to commit %n file(s): %1", 0, checkedFiles.size()).arg(QString::fromLocal8Bit(errorText));
+        tr("Committed %n file(s).\n", 0, checkedFiles.size()) :
+        tr("Unable to commit %n file(s): %1\n", 0, checkedFiles.size()).arg(QString::fromLocal8Bit(errorText));
 
-    m_plugin->m_outputWindow->append(message);
-    m_plugin->m_outputWindow->popup(false);
+    m_plugin->outputWindow()->append(message);
+    m_plugin->outputWindow()->popup(false);
     return rc;
 }
 
+static inline bool askWithInformativeText(QWidget *parent,
+                                          const QString &title,
+                                          const QString &msg,
+                                          const QString &inf,
+                                          bool defaultValue)
+{
+    QMessageBox msgBox(QMessageBox::Question, title, msg, QMessageBox::Yes|QMessageBox::No, parent);
+    msgBox.setInformativeText(inf);
+    msgBox.setDefaultButton(defaultValue ? QMessageBox::Yes : QMessageBox::No);
+    return msgBox.exec() == QMessageBox::Yes;
+}
+
+/* Revert: This function can be called with a file list (to revert single
+ * files)  or a single directory (revert all). Qt Creator currently has only
+ * 'revert single' in its VCS menus, but the code is prepared to deal with
+ * reverting a directory pending a sophisticated selection dialog in the
+ * VCSBase plugin. */
+
+GitClient::RevertResult GitClient::revertI(QStringList files, bool *ptrToIsDirectory, QString *errorMessage)
+{
+    if (Git::Constants::debug)
+        qDebug() << Q_FUNC_INFO << files;
+
+    if (files.empty())
+        return RevertCanceled;
+
+    // Figure out the working directory
+    const QFileInfo firstFile(files.front());
+    const bool isDirectory = firstFile.isDir();
+    if (ptrToIsDirectory)
+        *ptrToIsDirectory = isDirectory;
+    const QString workingDirectory = isDirectory ? firstFile.absoluteFilePath() : firstFile.absolutePath();
+
+    const QString repoDirectory = GitClient::findRepositoryForDirectory(workingDirectory);
+    if (repoDirectory.isEmpty()) {
+        *errorMessage = msgRepositoryNotFound(workingDirectory);
+        return RevertFailed;
+    }
+
+    // Check for changes
+    QString output;
+    switch (gitStatus(repoDirectory, false, &output, errorMessage)) {
+    case StatusChanged:
+        break;
+    case StatusUnchanged:
+        return RevertUnchanged;
+    case StatusFailed:
+        return RevertFailed;
+    }
+    CommitData d;
+    if (!parseFiles(output, &d)) {
+        *errorMessage = msgParseFilesFailed();
+        return RevertFailed;
+    }
+
+    // If we are looking at files, make them relative to the repository
+    // directory to match them in the status output list.
+    if (!isDirectory) {
+        const QDir repoDir(repoDirectory);
+        const QStringList::iterator cend = files.end();
+        for (QStringList::iterator it = files.begin(); it != cend; ++it)
+            *it = repoDir.relativeFilePath(*it);
+    }
+
+    // From the status output, determine all modified [un]staged files.
+    const QString modifiedPattern = QLatin1String("modified: ");
+    const QStringList allStagedFiles = GitSubmitEditor::statusListToFileList(d.stagedFiles.filter(modifiedPattern));
+    const QStringList allUnstagedFiles = GitSubmitEditor::statusListToFileList(d.unstagedFiles.filter(modifiedPattern));
+    // Unless a directory was passed, filter all modified files for the
+    // argument file list.
+    QStringList stagedFiles = allStagedFiles;
+    QStringList unstagedFiles = allUnstagedFiles;
+    if (!isDirectory) {
+        const QSet<QString> filesSet = files.toSet();
+        stagedFiles = allStagedFiles.toSet().intersect(filesSet).toList();
+        unstagedFiles = allUnstagedFiles.toSet().intersect(filesSet).toList();
+    }
+    if (Git::Constants::debug)
+        qDebug() << Q_FUNC_INFO << d.stagedFiles << d.unstagedFiles << allStagedFiles << allUnstagedFiles << stagedFiles << unstagedFiles;
+
+    if (stagedFiles.empty() && unstagedFiles.empty())
+        return RevertUnchanged;
+
+    // Ask to revert (to do: Handle lists with a selection dialog)
+    const QMessageBox::StandardButton answer
+        = QMessageBox::question(m_core->mainWindow(),
+                                tr("Revert"),
+                                tr("The file has been changed. Do you want to revert it?"),
+                                QMessageBox::Yes|QMessageBox::No,
+                                QMessageBox::No);
+    if (answer == QMessageBox::No)
+        return RevertCanceled;
+
+    // Unstage the staged files
+    if (!stagedFiles.empty() && !synchronousReset(repoDirectory, stagedFiles, errorMessage))
+        return RevertFailed;
+    // Finally revert!
+    if (!synchronousCheckout(repoDirectory, stagedFiles + unstagedFiles, errorMessage))
+        return RevertFailed;
+    return RevertOk;
+}
+
+void GitClient::revert(const QStringList &files)
+{
+    bool isDirectory;
+    QString errorMessage;
+    switch (revertI(files, &isDirectory, &errorMessage)) {
+    case RevertOk:
+    case RevertCanceled:
+        break;
+    case RevertUnchanged: {
+        const QString msg = (isDirectory || files.size() > 1) ? msgNoChangedFiles() : tr("The file is not modified.");
+        m_plugin->outputWindow()->append(msg);
+        m_plugin->outputWindow()->popup();
+    }
+        break;
+    case RevertFailed:
+        m_plugin->outputWindow()->append(errorMessage);
+        m_plugin->outputWindow()->popup();
+        break;
+    }
+}
+
 void GitClient::pull(const QString &workingDirectory)
 {
-    executeGit(workingDirectory, QStringList(QLatin1String("pull")), m_plugin->m_outputWindow, 0,true);
+    executeGit(workingDirectory, QStringList(QLatin1String("pull")), m_plugin->outputWindow(), 0, true);
 }
 
 void GitClient::push(const QString &workingDirectory)
 {
-    executeGit(workingDirectory, QStringList(QLatin1String("push")), m_plugin->m_outputWindow, 0,true);
+    executeGit(workingDirectory, QStringList(QLatin1String("push")), m_plugin->outputWindow(), 0, true);
+}
+
+QString GitClient::msgNoChangedFiles()
+{
+    return tr("There are no modified files.");
+}
+
+void GitClient::stash(const QString &workingDirectory)
+{
+    // Check for changes and stash
+    QString errorMessage;
+    switch (gitStatus(workingDirectory, false, 0, &errorMessage)) {
+    case  StatusChanged:
+        executeGit(workingDirectory, QStringList(QLatin1String("stash")), m_plugin->outputWindow(), 0, true);
+        break;
+    case StatusUnchanged:
+        m_plugin->outputWindow()->append(msgNoChangedFiles());
+        m_plugin->outputWindow()->popup();
+        break;
+    case StatusFailed:
+        m_plugin->outputWindow()->append(errorMessage);
+        m_plugin->outputWindow()->popup();
+        break;
+    }
+}
+
+void GitClient::stashPop(const QString &workingDirectory)
+{
+    QStringList arguments(QLatin1String("stash"));
+    arguments << QLatin1String("pop");
+    executeGit(workingDirectory, arguments, m_plugin->outputWindow(), 0, true);
+}
+
+void GitClient::branchList(const QString &workingDirectory)
+{
+    QStringList arguments(QLatin1String("branch"));
+    arguments << QLatin1String("-r");
+    executeGit(workingDirectory, arguments, m_plugin->outputWindow(), 0, true);
+}
+
+void GitClient::stashList(const QString &workingDirectory)
+{
+    QStringList arguments(QLatin1String("stash"));
+    arguments << QLatin1String("list");
+    executeGit(workingDirectory, arguments, m_plugin->outputWindow(), 0, true);
 }
 
 QString GitClient::readConfig(const QString &workingDirectory, const QStringList &configVar)
@@ -624,8 +868,8 @@ QString GitClient::readConfig(const QString &workingDirectory, const QStringList
     arguments << QLatin1String("config") << configVar;
 
     QByteArray outputText;
-    if (synchronousGit(workingDirectory, arguments, &outputText))
-        return QString::fromLocal8Bit(outputText);
+    if (synchronousGit(workingDirectory, arguments, &outputText, 0, false))
+        return QString::fromLocal8Bit(outputText).remove(QLatin1Char('\r'));
     return QString();
 }
 
@@ -635,6 +879,21 @@ QString GitClient::readConfigValue(const QString &workingDirectory, const QStrin
     return readConfig(workingDirectory, QStringList(configVar)).remove(QLatin1Char('\n'));
 }
 
+GitSettings GitClient::settings() const
+{
+    return m_settings;
+}
+
+void GitClient::setSettings(const GitSettings &s)
+{
+    if (s != m_settings) {
+        m_settings = s;
+        if (QSettings *s = m_core->settings())
+            m_settings.toSettings(s);
+    }
+}
+
+// ------------------------ GitCommand
 GitCommand::GitCommand()
 {
 }
diff --git a/src/plugins/git/gitclient.h b/src/plugins/git/gitclient.h
index 1a7ebe8c983a8f83dd970e1019b02ca4c2e8286b..efc767e54095e98e8be96022f1bd5ed04cf4989f 100644
--- a/src/plugins/git/gitclient.h
+++ b/src/plugins/git/gitclient.h
@@ -34,6 +34,8 @@
 #ifndef GITCLIENT_H
 #define GITCLIENT_H
 
+#include "gitsettings.h"
+
 #include <coreplugin/iversioncontrol.h>
 #include <coreplugin/editormanager/ieditor.h>
 #include <projectexplorer/environment.h>
@@ -62,17 +64,14 @@ class GitCommand;
 struct CommitData;
 struct GitSubmitEditorPanelData;
 
-class GitClient : public Core::IVersionControl
+class GitClient : public QObject
 {
     Q_OBJECT
 
 public:
-    GitClient(GitPlugin *plugin, Core::ICore *core);
+    explicit GitClient(GitPlugin *plugin, Core::ICore *core);
     ~GitClient();
 
-    bool vcsOpen(const QString &fileName);
-    bool vcsAdd(const QString &) { return false; }
-    bool vcsDelete(const QString &) { return false; }
     bool managesDirectory(const QString &) const { return false; }
     QString findTopLevelForDirectory(const QString &) const { return QString(); }
 
@@ -91,9 +90,17 @@ public:
     void addFile(const QString &workingDirectory, const QString &fileName);
     bool synchronousAdd(const QString &workingDirectory, const QStringList &files);
     bool synchronousReset(const QString &workingDirectory, const QStringList &files);
+    bool synchronousReset(const QString &workingDirectory, const QStringList &files, QString *errorMessage);
+    bool synchronousCheckout(const QString &workingDirectory, const QStringList &files, QString *errorMessage);
     void pull(const QString &workingDirectory);
     void push(const QString &workingDirectory);
 
+    void stash(const QString &workingDirectory);
+    void stashPop(const QString &workingDirectory);
+    void revert(const QStringList &files);
+    void branchList(const QString &workingDirectory);
+    void stashList(const QString &workingDirectory);
+
     QString readConfig(const QString &workingDirectory, const QStringList &configVar);
 
     QString readConfigValue(const QString &workingDirectory, const QString &configVar);
@@ -109,6 +116,17 @@ public:
                       const QStringList &checkedFiles,
                       const QStringList &origCommitFiles);
 
+    enum StatusResult { StatusChanged, StatusUnchanged, StatusFailed };
+    StatusResult gitStatus(const QString &workingDirectory,
+                           bool untracked,
+                           QString *output = 0,
+                           QString *errorMessage = 0);
+
+    GitSettings  settings() const;
+    void setSettings(const GitSettings &s);
+
+    static QString msgNoChangedFiles();
+
 public slots:
     void show(const QString &source, const QString &id);
 
@@ -128,13 +146,18 @@ private:
                                            bool outputToWindow = false);
 
     bool synchronousGit(const QString &workingDirectory,
-                                           const QStringList &arguments,
-                                           QByteArray* outputText = 0,
-                                           QByteArray* errorText = 0);
+                        const QStringList &arguments,
+                        QByteArray* outputText = 0,
+                        QByteArray* errorText = 0,
+                        bool logCommandToWindow = true);
+
+    enum RevertResult { RevertOk, RevertUnchanged, RevertCanceled, RevertFailed };
+    RevertResult revertI(QStringList files, bool *isDirectory, QString *errorMessage);
 
     const QString m_msgWait;
     GitPlugin     *m_plugin;
     Core::ICore   *m_core;
+    GitSettings   m_settings;
 };
 
 class GitCommand : public QObject
diff --git a/src/plugins/git/gitoutputwindow.cpp b/src/plugins/git/gitoutputwindow.cpp
index a321449b1e22614c5367d0138e0502ede392a5f8..375be9095973414a65bf715b3c2c38e7a394ffd0 100644
--- a/src/plugins/git/gitoutputwindow.cpp
+++ b/src/plugins/git/gitoutputwindow.cpp
@@ -104,6 +104,7 @@ void GitOutputWindow::append(const QString &text)
     const QStringList lines = text.split(QLatin1Char('\n'));
     foreach (const QString &s, lines)
         m_outputListWidget->addItem(s);
+    m_outputListWidget->scrollToBottom();
     popup();
 }
 
diff --git a/src/plugins/git/gitplugin.cpp b/src/plugins/git/gitplugin.cpp
index 6209996edc141052ff75a4571df052fdb3d85144..ebce0f7c452dbf9624a7186d3aded21a0fe056d0 100644
--- a/src/plugins/git/gitplugin.cpp
+++ b/src/plugins/git/gitplugin.cpp
@@ -33,6 +33,7 @@
 
 #include "gitplugin.h"
 #include "gitclient.h"
+#include "gitversioncontrol.h"
 #include "giteditor.h"
 #include "gitconstants.h"
 #include "changeselectiondialog.h"
@@ -117,7 +118,9 @@ GitPlugin::GitPlugin() :
     m_undoFileAction(0),
     m_undoProjectAction(0),
     m_showAction(0),
-    m_addAction(0),
+    m_stageAction(0),
+    m_unstageAction(0),
+    m_revertAction(0),
     m_commitAction(0),
     m_pullAction(0),
     m_pushAction(0),
@@ -125,6 +128,10 @@ GitPlugin::GitPlugin() :
     m_diffSelectedFilesAction(0),
     m_undoAction(0),
     m_redoAction(0),
+    m_stashAction(0),
+    m_stashPopAction(0),
+    m_stashListAction(0),
+    m_branchListAction(0),
     m_projectExplorer(0),
     m_gitClient(0),
     m_outputWindow(0),
@@ -132,6 +139,7 @@ GitPlugin::GitPlugin() :
     m_settingsPage(0),
     m_coreListener(0),
     m_submitEditorFactory(0),
+    m_versionControl(0),
     m_changeTmpFile(0)
 {
     Q_ASSERT(m_instance == 0);
@@ -170,6 +178,12 @@ GitPlugin::~GitPlugin()
         m_submitEditorFactory = 0;
     }
 
+    if (m_versionControl) {
+        removeObject(m_versionControl);
+        delete m_versionControl;
+        m_versionControl = 0;
+    }
+
     cleanChangeTmpFile();
     delete m_gitClient;
     m_instance = 0;
@@ -198,6 +212,15 @@ static const VCSBase::VCSBaseSubmitEditorParameters submitParameters = {
     Git::Constants::DIFF_SELECTED
 };
 
+static inline Core::ICommand *createSeparator(Core::ActionManagerInterface *am,
+                                              const QList<int> &context,
+                                              const QString &id,
+                                              QObject *parent)
+{
+    QAction *a = new QAction(parent);
+    a->setSeparator(true);
+    return  am->registerAction(a, id, context);
+}
 
 bool GitPlugin::initialize(const QStringList &arguments, QString *error_message)
 {
@@ -235,6 +258,9 @@ bool GitPlugin::initialize(const QStringList &arguments, QString *error_message)
     m_submitEditorFactory = new GitSubmitEditorFactory(&submitParameters);
     addObject(m_submitEditorFactory);
 
+    m_versionControl = new GitVersionControl(m_gitClient);
+    addObject(m_versionControl);
+
     //register actions
     Core::ActionManagerInterface *actionManager = m_core->actionManager();
 
@@ -245,9 +271,12 @@ bool GitPlugin::initialize(const QStringList &arguments, QString *error_message)
         actionManager->createMenu(QLatin1String("Git"));
     gitContainer->menu()->setTitle(tr("&Git"));
     toolsContainer->addMenu(gitContainer);
+    if (QAction *ma = gitContainer->menu()->menuAction()) {
+        ma->setEnabled(m_versionControl->isEnabled());
+        connect(m_versionControl, SIGNAL(enabledChanged(bool)), ma, SLOT(setVisible(bool)));
+    }
 
     Core::ICommand *command;
-    QAction *tmpaction;
 
     m_diffAction = new QAction(tr("Diff current file"), this);
     command = actionManager->registerAction(m_diffAction, "Git.Diff", globalcontext);
@@ -284,18 +313,27 @@ bool GitPlugin::initialize(const QStringList &arguments, QString *error_message)
     connect(m_undoFileAction, SIGNAL(triggered()), this, SLOT(undoFileChanges()));
     gitContainer->addAction(command);
 
-    m_addAction = new QAction(tr("Add File"), this);
-    command = actionManager->registerAction(m_addAction, "Git.Add", globalcontext);
+    m_stageAction = new QAction(tr("Stage file for commit"), this);
+    command = actionManager->registerAction(m_stageAction, "Git.Stage", globalcontext);
     command->setDefaultKeySequence(QKeySequence(tr("Alt+G,Alt+A")));
     command->setAttribute(Core::ICommand::CA_UpdateText);
-    connect(m_addAction, SIGNAL(triggered()), this, SLOT(addFile()));
+    connect(m_stageAction, SIGNAL(triggered()), this, SLOT(stageFile()));
     gitContainer->addAction(command);
 
-    tmpaction = new QAction(this);
-    tmpaction->setSeparator(true);
-    command = actionManager->registerAction(tmpaction, QLatin1String("Git.Sep.Project"), globalcontext);
+    m_unstageAction = new QAction(tr("Unstage file from commit"), this);
+    command = actionManager->registerAction(m_unstageAction, "Git.Unstage", globalcontext);
+    command->setAttribute(Core::ICommand::CA_UpdateText);
+    connect(m_unstageAction, SIGNAL(triggered()), this, SLOT(unstageFile()));
     gitContainer->addAction(command);
 
+    m_revertAction = new QAction(tr("Revert..."), this);
+    command = actionManager->registerAction(m_revertAction, "Git.Revert", globalcontext);
+    command->setAttribute(Core::ICommand::CA_UpdateText);
+    connect(m_revertAction, SIGNAL(triggered()), this, SLOT(revertFile()));
+    gitContainer->addAction(command);
+
+    gitContainer->addAction(createSeparator(actionManager, globalcontext, QLatin1String("Git.Sep.Project"), this));
+
     m_diffProjectAction = new QAction(tr("Diff current project"), this);
     command = actionManager->registerAction(m_diffProjectAction, "Git.DiffProject", globalcontext);
     command->setDefaultKeySequence(QKeySequence("Alt+G,Alt+Shift+D"));
@@ -322,15 +360,26 @@ bool GitPlugin::initialize(const QStringList &arguments, QString *error_message)
     connect(m_undoProjectAction, SIGNAL(triggered()), this, SLOT(undoProjectChanges()));
     gitContainer->addAction(command);
 
-    tmpaction = new QAction(this);
-    tmpaction->setSeparator(true);
-    command = actionManager->registerAction(tmpaction, QLatin1String("Git.Sep.Global"), globalcontext);
+    gitContainer->addAction(createSeparator(actionManager, globalcontext, QLatin1String("Git.Sep.Global"), this));
+
+    m_stashAction = new QAction(tr("Stash"), this);
+    m_stashAction->setToolTip("Saves the current state of your work.");
+    command = actionManager->registerAction(m_stashAction, "Git.Stash", globalcontext);
+    command->setAttribute(Core::ICommand::CA_UpdateText);
+    connect(m_stashAction, SIGNAL(triggered()), this, SLOT(stash()));
     gitContainer->addAction(command);
 
-    m_showAction = new QAction(tr("Show commit..."), this);
-    command = actionManager->registerAction(m_showAction, "Git.ShowCommit", globalcontext);
+    m_pullAction = new QAction(tr("Pull"), this);
+    command = actionManager->registerAction(m_pullAction, "Git.Pull", globalcontext);
     command->setAttribute(Core::ICommand::CA_UpdateText);
-    connect(m_showAction, SIGNAL(triggered()), this, SLOT(showCommit()));
+    connect(m_pullAction, SIGNAL(triggered()), this, SLOT(pull()));
+    gitContainer->addAction(command);
+
+    m_stashPopAction = new QAction(tr("Stash pop"), this);
+    m_stashAction->setToolTip("Restores changes saved to the stash list using \"Stash\".");
+    command = actionManager->registerAction(m_stashPopAction, "Git.StashPop", globalcontext);
+    command->setAttribute(Core::ICommand::CA_UpdateText);
+    connect(m_stashPopAction, SIGNAL(triggered()), this, SLOT(stashPop()));
     gitContainer->addAction(command);
 
     m_commitAction = new QAction(tr("Commit..."), this);
@@ -340,24 +389,37 @@ bool GitPlugin::initialize(const QStringList &arguments, QString *error_message)
     connect(m_commitAction, SIGNAL(triggered()), this, SLOT(startCommit()));
     gitContainer->addAction(command);
 
-    m_pullAction = new QAction(tr("Pull"), this);
-    command = actionManager->registerAction(m_pullAction, "Git.Pull", globalcontext);
-    command->setAttribute(Core::ICommand::CA_UpdateText);
-    connect(m_pullAction, SIGNAL(triggered()), this, SLOT(pull()));
-    gitContainer->addAction(command);
-
     m_pushAction = new QAction(tr("Push"), this);
     command = actionManager->registerAction(m_pushAction, "Git.Push", globalcontext);
     command->setAttribute(Core::ICommand::CA_UpdateText);
     connect(m_pushAction, SIGNAL(triggered()), this, SLOT(push()));
     gitContainer->addAction(command);
 
+    gitContainer->addAction(createSeparator(actionManager, globalcontext, QLatin1String("Git.Sep.Branch"), this));
+
+    m_branchListAction = new QAction(tr("List branches"), this);
+    command = actionManager->registerAction(m_branchListAction, "Git.BranchList", globalcontext);
+    command->setAttribute(Core::ICommand::CA_UpdateText);
+    connect(m_branchListAction, SIGNAL(triggered()), this, SLOT(branchList()));
+    gitContainer->addAction(command);
+
+    m_stashListAction = new QAction(tr("List stashes"), this);
+    command = actionManager->registerAction(m_stashListAction, "Git.StashList", globalcontext);
+    command->setAttribute(Core::ICommand::CA_UpdateText);
+    connect(m_stashListAction, SIGNAL(triggered()), this, SLOT(stashList()));
+    gitContainer->addAction(command);
+
+    m_showAction = new QAction(tr("Show commit..."), this);
+    command = actionManager->registerAction(m_showAction, "Git.ShowCommit", globalcontext);
+    command->setAttribute(Core::ICommand::CA_UpdateText);
+    connect(m_showAction, SIGNAL(triggered()), this, SLOT(showCommit()));
+    gitContainer->addAction(command);
+
     // Submit editor
     QList<int> submitContext;
     submitContext.push_back(m_core->uniqueIDManager()->uniqueIdentifier(QLatin1String(Constants::C_GITSUBMITEDITOR)));
     m_submitCurrentAction = new QAction(VCSBase::VCSBaseSubmitEditor::submitIcon(), tr("Commit"), this);
     command = actionManager->registerAction(m_submitCurrentAction, Constants::SUBMIT_CURRENT, submitContext);
-    // TODO
     connect(m_submitCurrentAction, SIGNAL(triggered()), this, SLOT(submitCurrentLog()));
 
     m_diffSelectedFilesAction = new QAction(VCSBase::VCSBaseSubmitEditor::diffIcon(), tr("Diff Selected Files"), this);
@@ -383,12 +445,6 @@ void GitPlugin::extensionsInitialized()
     m_projectExplorer = ExtensionSystem::PluginManager::instance()->getObject<ProjectExplorer::ProjectExplorerPlugin>();
 }
 
-bool GitPlugin::vcsOpen(const QString &fileName)
-{
-    Q_UNUSED(fileName);
-    return false;
-}
-
 void GitPlugin::submitEditorDiff(const QStringList &files)
 {
     if (files.empty())
@@ -412,7 +468,7 @@ void GitPlugin::diffCurrentProject()
     m_gitClient->diff(workingDirectory, QString());
 }
 
-QFileInfo GitPlugin::currentFile()
+QFileInfo GitPlugin::currentFile() const
 {
     QString fileName = m_core->fileManager()->currentFile();
     QFileInfo fileInfo(fileName);
@@ -495,14 +551,28 @@ void GitPlugin::undoProjectChanges()
     m_gitClient->hardReset(workingDirectory, QString());
 }
 
-void GitPlugin::addFile()
+void GitPlugin::stageFile()
 {
-    QFileInfo fileInfo = currentFile();
-    QString fileName = fileInfo.fileName();
-    QString workingDirectory = fileInfo.absolutePath();
+    const QFileInfo fileInfo = currentFile();
+    const QString fileName = fileInfo.fileName();
+    const QString workingDirectory = fileInfo.absolutePath();
     m_gitClient->addFile(workingDirectory, fileName);
 }
 
+void GitPlugin::unstageFile()
+{
+    const QFileInfo fileInfo = currentFile();
+    const QString fileName = fileInfo.fileName();
+    const QString workingDirectory = fileInfo.absolutePath();
+    m_gitClient->synchronousReset(workingDirectory, QStringList(fileName));
+}
+
+void GitPlugin::revertFile()
+{
+    const QFileInfo fileInfo = currentFile();
+    m_gitClient->revert(QStringList(fileInfo.absoluteFilePath()));
+}
+
 void GitPlugin::startCommit()
 {
     if (m_changeTmpFile) {
@@ -528,7 +598,7 @@ void GitPlugin::startCommit()
     // Store repository for diff and the original list of
     // files to be able to unstage files the user unchecks
     m_submitRepository = data.panelInfo.repository;
-    m_submitOrigCommitFiles = GitSubmitEditor::statusListToFileList(data.commitFiles);
+    m_submitOrigCommitFiles = GitSubmitEditor::statusListToFileList(data.stagedFiles);
 
     if (Git::Constants::debug)
         qDebug() << Q_FUNC_INFO << data << commitTemplate;
@@ -560,7 +630,7 @@ Core::IEditor *GitPlugin::openSubmitEditor(const QString &fileName, const Commit
     Q_ASSERT(submitEditor);
     // The actions are for some reason enabled by the context switching
     // mechanism. Disable them correctly.
-    m_submitCurrentAction->setEnabled(!cd.commitFiles.empty());
+    m_submitCurrentAction->setEnabled(!cd.stagedFiles.empty());
     m_diffSelectedFilesAction->setEnabled(false);
     m_undoAction->setEnabled(false);
     m_redoAction->setEnabled(false);
@@ -627,26 +697,52 @@ bool GitPlugin::editorAboutToClose(Core::IEditor *iEditor)
 
 void GitPlugin::pull()
 {
-    QString workingDirectory = getWorkingDirectory();
-    if (workingDirectory.isEmpty())
-        return;
-    m_gitClient->pull(workingDirectory);
+    const QString workingDirectory = getWorkingDirectory();
+    if (!workingDirectory.isEmpty())
+        m_gitClient->pull(workingDirectory);
 }
 
 void GitPlugin::push()
 {
-    QString workingDirectory = getWorkingDirectory();
-    if (workingDirectory.isEmpty())
-        return;
-    m_gitClient->push(workingDirectory);
+    const QString workingDirectory = getWorkingDirectory();
+    if (!workingDirectory.isEmpty())
+        m_gitClient->push(workingDirectory);
+}
+
+void GitPlugin::stash()
+{
+    const QString workingDirectory = getWorkingDirectory();
+    if (!workingDirectory.isEmpty())
+        m_gitClient->stash(workingDirectory);
+}
+
+void GitPlugin::stashPop()
+{
+    const QString workingDirectory = getWorkingDirectory();
+    if (!workingDirectory.isEmpty())
+        m_gitClient->stashPop(workingDirectory);
+}
+
+void GitPlugin::branchList()
+{
+    const QString workingDirectory = getWorkingDirectory();
+    if (!workingDirectory.isEmpty())
+        m_gitClient->branchList(workingDirectory);
+}
+
+void GitPlugin::stashList()
+{
+    const QString workingDirectory = getWorkingDirectory();
+    if (!workingDirectory.isEmpty())
+        m_gitClient->stashList(workingDirectory);
 }
 
 void GitPlugin::updateActions()
 {
-    QFileInfo current = currentFile();
+    const QFileInfo current = currentFile();
     const QString fileName = current.fileName();
     const QString currentDirectory = getWorkingDirectory();
-    QString repository = m_gitClient->findRepositoryForFile(current.absoluteFilePath());
+    const QString repository = m_gitClient->findRepositoryForFile(current.absoluteFilePath());
     // First check for file commands and if the current file is inside
     // a Git-repository
     m_diffAction->setText(tr("Diff %1").arg(fileName));
@@ -654,7 +750,9 @@ void GitPlugin::updateActions()
     m_logAction->setText(tr("Log %1").arg(fileName));
     m_blameAction->setText(tr("Blame %1").arg(fileName));
     m_undoFileAction->setText(tr("Undo changes for %1").arg(fileName));
-    m_addAction->setText(tr("Add %1").arg(fileName));
+    m_stageAction->setText(tr("Stage %1 for commit").arg(fileName));
+    m_unstageAction->setText(tr("Unstage %1 from commit").arg(fileName));
+    m_revertAction->setText(tr("Revert %1...").arg(fileName));
     if (repository.isEmpty()) {
         // If the file is not in a repository, the corresponding project will
         // be neither and we can disable everything and return
@@ -663,7 +761,9 @@ void GitPlugin::updateActions()
         m_logAction->setEnabled(false);
         m_blameAction->setEnabled(false);
         m_undoFileAction->setEnabled(false);
-        m_addAction->setEnabled(false);
+        m_stageAction->setEnabled(false);
+        m_unstageAction->setEnabled(false);
+        m_revertAction->setEnabled(false);
         m_diffProjectAction->setEnabled(false);
         m_diffProjectAction->setText(tr("Diff Project"));
         m_statusProjectAction->setText(tr("Status Project"));
@@ -679,12 +779,14 @@ void GitPlugin::updateActions()
         m_logAction->setEnabled(true);
         m_blameAction->setEnabled(true);
         m_undoFileAction->setEnabled(true);
-        m_addAction->setEnabled(true);
+        m_stageAction->setEnabled(true);
+        m_unstageAction->setEnabled(true);
+        m_revertAction->setEnabled(true);
     }
 
     if (m_projectExplorer && m_projectExplorer->currentNode()
         && m_projectExplorer->currentNode()->projectNode()) {
-        QString name = QFileInfo(m_projectExplorer->currentNode()->projectNode()->path()).baseName();
+        const QString name = QFileInfo(m_projectExplorer->currentNode()->projectNode()->path()).baseName();
         m_diffProjectAction->setEnabled(true);
         m_diffProjectAction->setText(tr("Diff Project %1").arg(name));
         m_statusProjectAction->setEnabled(true);
@@ -720,4 +822,19 @@ void GitPlugin::showCommit()
     m_gitClient->show(m_changeSelectionDialog->m_ui.repositoryEdit->text(), change);
 }
 
+GitOutputWindow *GitPlugin::outputWindow() const
+{
+    return m_outputWindow;
+}
+
+GitSettings GitPlugin::settings() const
+{
+    return m_gitClient->settings();
+}
+
+void GitPlugin::setSettings(const GitSettings &s)
+{
+    m_gitClient->setSettings(s);
+}
+
 Q_EXPORT_PLUGIN(GitPlugin)
diff --git a/src/plugins/git/gitplugin.h b/src/plugins/git/gitplugin.h
index 51846c71d66650bb197b63ae58e0769b62d9289a..adff899e505564dc680a3a9dc4ac161bcae306a0 100644
--- a/src/plugins/git/gitplugin.h
+++ b/src/plugins/git/gitplugin.h
@@ -55,6 +55,7 @@ QT_END_NAMESPACE
 namespace Core {
     class IEditorFactory;
     class ICore;
+    class IVersionControl;
 }
 
 namespace Git {
@@ -65,6 +66,7 @@ namespace Internal {
     class ChangeSelectionDialog;
     class GitSubmitEditor;
     struct CommitData;
+    struct GitSettings;
 
 // Just a proxy for GitPlugin
 class CoreListener : public Core::ICoreListener
@@ -87,14 +89,17 @@ public:
                                 ~GitPlugin();
     static GitPlugin *instance();
 
-    bool                        vcsOpen(const QString &fileName);
-
     bool                        initialize(const QStringList &arguments
                                            , QString *error_message);
     void                        extensionsInitialized();
 
     QString                     getWorkingDirectory();
 
+    GitOutputWindow             *outputWindow() const;
+
+    GitSettings  settings() const;
+    void setSettings(const GitSettings &s);
+
 public slots:
     void                        updateActions();
     bool                        editorAboutToClose(Core::IEditor *editor);
@@ -111,16 +116,21 @@ private slots:
     void                        logProject();
     void                        undoFileChanges();
     void                        undoProjectChanges();
-    void                        addFile();
+    void                        stageFile();
+    void                        unstageFile();
+    void                        revertFile();
 
     void                        showCommit();
     void                        startCommit();
+    void                        stash();
+    void                        stashPop();
+    void                        branchList();
+    void                        stashList();
     void                        pull();
     void                        push();
 
 private:
-    friend class GitClient;
-    QFileInfo                   currentFile();
+    QFileInfo                   currentFile() const;
     Core::IEditor               *openSubmitEditor(const QString &fileName, const CommitData &cd);
     void                        cleanChangeTmpFile();
 
@@ -136,7 +146,9 @@ private:
     QAction                     *m_undoFileAction;
     QAction                     *m_undoProjectAction;
     QAction                     *m_showAction;
-    QAction                     *m_addAction;
+    QAction                     *m_stageAction;
+    QAction                     *m_unstageAction;
+    QAction                     *m_revertAction;
     QAction                     *m_commitAction;
     QAction                     *m_pullAction;
     QAction                     *m_pushAction;
@@ -145,6 +157,10 @@ private:
     QAction                     *m_diffSelectedFilesAction;
     QAction                     *m_undoAction;
     QAction                     *m_redoAction;
+    QAction                     *m_stashAction;
+    QAction                     *m_stashPopAction;
+    QAction                     *m_stashListAction;
+    QAction                     *m_branchListAction;
 
     ProjectExplorer::ProjectExplorerPlugin *m_projectExplorer;
     GitClient                   *m_gitClient;
@@ -154,6 +170,7 @@ private:
     QList<Core::IEditorFactory*> m_editorFactories;
     CoreListener                *m_coreListener;
     Core::IEditorFactory        *m_submitEditorFactory;
+    Core::IVersionControl       *m_versionControl;
     QString                     m_submitRepository;
     QStringList                 m_submitOrigCommitFiles;
     QTemporaryFile              *m_changeTmpFile;
diff --git a/src/plugins/git/gitsettings.cpp b/src/plugins/git/gitsettings.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..f4473e1fd92e222539cc2d82d99cff9168873454
--- /dev/null
+++ b/src/plugins/git/gitsettings.cpp
@@ -0,0 +1,79 @@
+/***************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact:  Qt Software Information (qt-info@nokia.com)
+**
+**
+** Non-Open Source Usage
+**
+** Licensees may use this file in accordance with the Qt Beta Version
+** License Agreement, Agreement version 2.2 provided with the Software or,
+** alternatively, in accordance with the terms contained in a written
+** agreement between you and Nokia.
+**
+** GNU General Public License Usage
+**
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the packaging
+** of this file.  Please review the following information to ensure GNU
+** General Public Licensing requirements will be met:
+**
+** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt GPL Exception
+** version 1.2, included in the file GPL_EXCEPTION.txt in this package.
+**
+***************************************************************************/
+
+#include "gitsettings.h"
+
+#include <QtCore/QSettings>
+#include <QtCore/QTextStream>
+
+static const char *groupC = "Git";
+static const char *sysEnvKeyC = "SysEnv";
+static const char *pathKeyC = "Path";
+static const char *logCountKeyC = "LogCount";
+
+enum { defaultLogCount =  10 };
+
+namespace Git {
+namespace Internal {
+
+GitSettings::GitSettings() :
+    adoptPath(false),
+    logCount(defaultLogCount)
+{
+}
+
+void GitSettings::fromSettings(QSettings *settings)
+{
+    settings->beginGroup(QLatin1String(groupC));
+    adoptPath = settings->value(QLatin1String(sysEnvKeyC), false).toBool();
+    path = settings->value(QLatin1String(pathKeyC), QString()).toString();
+    logCount = settings->value(QLatin1String(logCountKeyC), defaultLogCount).toInt();
+    settings->endGroup();
+}
+
+void GitSettings::toSettings(QSettings *settings) const
+{
+    settings->beginGroup(QLatin1String(groupC));
+    settings->setValue(QLatin1String(sysEnvKeyC), adoptPath);
+    settings->setValue(QLatin1String(pathKeyC), path);
+    settings->setValue(QLatin1String(logCountKeyC), logCount);
+    settings->endGroup();
+}
+
+bool GitSettings::equals(const GitSettings &s) const
+{
+    return adoptPath == s.adoptPath  && path == s.path && logCount == s.logCount;
+}
+
+}
+}
diff --git a/src/plugins/git/gitsettings.h b/src/plugins/git/gitsettings.h
new file mode 100644
index 0000000000000000000000000000000000000000..1b07f4437963f89496af0d75fae7b9439bf3a021
--- /dev/null
+++ b/src/plugins/git/gitsettings.h
@@ -0,0 +1,69 @@
+/***************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact:  Qt Software Information (qt-info@nokia.com)
+**
+**
+** Non-Open Source Usage
+**
+** Licensees may use this file in accordance with the Qt Beta Version
+** License Agreement, Agreement version 2.2 provided with the Software or,
+** alternatively, in accordance with the terms contained in a written
+** agreement between you and Nokia.
+**
+** GNU General Public License Usage
+**
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the packaging
+** of this file.  Please review the following information to ensure GNU
+** General Public Licensing requirements will be met:
+**
+** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt GPL Exception
+** version 1.2, included in the file GPL_EXCEPTION.txt in this package.
+**
+***************************************************************************/
+
+#ifndef GITSETTINGS_H
+#define GITSETTINGS_H
+
+#include <QtCore/QStringList>
+
+QT_BEGIN_NAMESPACE
+class QSettings;
+QT_END_NAMESPACE
+
+namespace Git {
+namespace Internal {
+
+// Todo: Add user name and password?
+struct GitSettings
+{
+    GitSettings();
+
+    void fromSettings(QSettings *);
+    void toSettings(QSettings *) const;
+
+    bool equals(const GitSettings &s) const;
+
+    bool adoptPath;
+    QString path;
+    int logCount;
+};
+
+inline bool operator==(const GitSettings &p1, const GitSettings &p2)
+    { return p1.equals(p2); }
+inline bool operator!=(const GitSettings &p1, const GitSettings &p2)
+    { return !p1.equals(p2); }
+
+} // namespace Internal
+} // namespace Git
+
+#endif // GITSETTINGS_H
diff --git a/src/plugins/git/gitsubmiteditor.cpp b/src/plugins/git/gitsubmiteditor.cpp
index 516dc6570b73c7b9e62d72e0fb0d01def65c0513..db854f3e3c6d406bd20f3ff2ca98cd6203645ca0 100644
--- a/src/plugins/git/gitsubmiteditor.cpp
+++ b/src/plugins/git/gitsubmiteditor.cpp
@@ -67,9 +67,9 @@ void GitSubmitEditor::setCommitData(const CommitData &d)
     submitEditorWidget()->setPanelData(d.panelData);
     submitEditorWidget()->setPanelInfo(d.panelInfo);
 
-    addFiles(d.commitFiles, true, true);
+    addFiles(d.stagedFiles, true, true);
     // Not Updated: Initially unchecked
-    addFiles(d.notUpdatedFiles, false, true);
+    addFiles(d.unstagedFiles, false, true);
     addFiles(d.untrackedFiles, false, true);
 }
 
diff --git a/src/plugins/git/gitversioncontrol.cpp b/src/plugins/git/gitversioncontrol.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..5f403ef2b57d22fdb4cbcae06ad4845bfe3b12e4
--- /dev/null
+++ b/src/plugins/git/gitversioncontrol.cpp
@@ -0,0 +1,104 @@
+/***************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact:  Qt Software Information (qt-info@nokia.com)
+**
+**
+** Non-Open Source Usage
+**
+** Licensees may use this file in accordance with the Qt Beta Version
+** License Agreement, Agreement version 2.2 provided with the Software or,
+** alternatively, in accordance with the terms contained in a written
+** agreement between you and Nokia.
+**
+** GNU General Public License Usage
+**
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the packaging
+** of this file.  Please review the following information to ensure GNU
+** General Public Licensing requirements will be met:
+**
+** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt GPL Exception
+** version 1.2, included in the file GPL_EXCEPTION.txt in this package.
+**
+***************************************************************************/
+
+#include "gitversioncontrol.h"
+#include "gitclient.h"
+
+namespace Git {
+namespace Internal {
+
+GitVersionControl::GitVersionControl(GitClient *client) :
+    m_enabled(true),
+    m_client(client)
+{
+}
+
+QString GitVersionControl::name() const
+{
+    return QLatin1String("git");
+}
+
+bool GitVersionControl::isEnabled() const
+{
+    return m_enabled;
+}
+
+void GitVersionControl::setEnabled(bool enabled)
+{
+    if (m_enabled != enabled) {
+        m_enabled = enabled;
+        emit enabledChanged(m_enabled);
+    }
+}
+
+bool GitVersionControl::supportsOperation(Operation operation) const
+{
+    bool rc = false;
+    switch (operation) {
+    case AddOperation:
+    case DeleteOperation:
+    case OpenOperation:
+        break;
+    }
+    return rc;
+}
+
+bool GitVersionControl::vcsOpen(const QString & /*fileName*/)
+{
+    return false;
+}
+
+bool GitVersionControl::vcsAdd(const QString & /*fileName*/)
+{
+    return false;
+}
+
+bool GitVersionControl::vcsDelete(const QString & /*fileName*/)
+{
+    // TODO: implement using 'git rm'.
+    return false;
+}
+
+bool GitVersionControl::managesDirectory(const QString &directory) const
+{
+    return !GitClient::findRepositoryForDirectory(directory).isEmpty();
+
+}
+
+QString GitVersionControl::findTopLevelForDirectory(const QString &directory) const
+{
+    return GitClient::findRepositoryForDirectory(directory);
+}
+
+} // Internal
+} // Git
diff --git a/src/plugins/help/indexwindow.h b/src/plugins/git/gitversioncontrol.h
similarity index 59%
rename from src/plugins/help/indexwindow.h
rename to src/plugins/git/gitversioncontrol.h
index 51ebb06653d197fa2fd1b74f5bcdf1bcc44031c8..e12e7736713c9a6b5ed100cef2b1fd705680d3c8 100644
--- a/src/plugins/help/indexwindow.h
+++ b/src/plugins/git/gitversioncontrol.h
@@ -31,52 +31,45 @@
 **
 ***************************************************************************/
 
-#ifndef INDEXWINDOW_H
-#define INDEXWINDOW_H
+#ifndef GITVERSIONCONTROL_H
+#define GITVERSIONCONTROL_H
 
-#include <QtCore/QUrl>
-#include <QtGui/QWidget>
-#include <QtGui/QLineEdit>
+#include <coreplugin/iversioncontrol.h>
 
-QT_BEGIN_NAMESPACE
+namespace Git {
+namespace Internal {
 
-class QHelpIndexWidget;
-class QHelpEngine;
+class GitClient;
 
-class IndexWindow : public QWidget
+// Just a proxy for GitPlugin
+class GitVersionControl : public Core::IVersionControl
 {
     Q_OBJECT
-
 public:
-    IndexWindow(QHelpEngine *helpEngine, QWidget *parent = 0);
-    ~IndexWindow();
+    explicit GitVersionControl(GitClient *plugin);
 
-    void setSearchLineEditText(const QString &text);
-    QString searchLineEditText() const
-    {
-        return m_searchLineEdit->text();
-    }
+    virtual QString name() const;
 
-signals:
-    void linkActivated(const QUrl &link);
-    void linksActivated(const QMap<QString, QUrl> &links,
-        const QString &keyword);
-    void escapePressed();
+    virtual bool isEnabled() const;
+    virtual void setEnabled(bool enabled);
 
-private slots:
-    void filterIndices(const QString &filter);
-    void enableSearchLineEdit();
-    void disableSearchLineEdit();
+    bool managesDirectory(const QString &directory) const;
+    virtual QString findTopLevelForDirectory(const QString &directory) const;
 
-private:
-    bool eventFilter(QObject *obj, QEvent *e);
-    void focusInEvent(QFocusEvent *e);
+    virtual bool supportsOperation(Operation operation) const;
+    virtual bool vcsOpen(const QString &fileName);
+    virtual bool vcsAdd(const QString &fileName);
+    virtual bool vcsDelete(const QString &filename);
 
-    QLineEdit *m_searchLineEdit;
-    QHelpIndexWidget *m_indexWidget;
-    QHelpEngine *m_helpEngine;
+signals:
+    void enabledChanged(bool);
+
+private:
+    bool m_enabled;
+    GitClient *m_client;
 };
 
-QT_END_NAMESPACE
+} // Internal
+} // Git
 
-#endif // INDEXWINDOW_H
+#endif // GITVERSIONCONTROL_H
diff --git a/src/plugins/git/settingspage.cpp b/src/plugins/git/settingspage.cpp
index 7b0c37284aa1793bd82b7ff74ca58c8715164e4f..e1b14cb9ccc627c31fff00065d560f8f7fa7e31e 100644
--- a/src/plugins/git/settingspage.cpp
+++ b/src/plugins/git/settingspage.cpp
@@ -32,35 +32,44 @@
 ***************************************************************************/
 
 #include "settingspage.h"
+#include "gitsettings.h"
+#include "gitplugin.h"
 
-#include <coreplugin/icore.h>
-#include <extensionsystem/pluginmanager.h>
-
-#include <QtCore/QSettings>
-#include <QtGui/QLineEdit>
-#include <QtGui/QFileDialog>
 #include <QtCore/QDebug>
 
 using namespace Git::Internal;
 
-static const char *groupC = "Git";
-static const char *sysEnvKeyC = "SysEnv";
-static const char *pathKeyC = "Path";
-static const char *logCountKeyC = "LogCount";
+SettingsPageWidget::SettingsPageWidget(QWidget *parent) :
+    QWidget(parent)
+{
+    m_ui.setupUi(this);
+    connect(m_ui.adoptButton, SIGNAL(clicked()), this, SLOT(setSystemPath()));
+}
 
-SettingsPage::SettingsPage()
+GitSettings SettingsPageWidget::settings() const
 {
-    Core::ICore *coreIFace = ExtensionSystem::PluginManager::instance()->getObject<Core::ICore>();
-    if (coreIFace)
-        m_settings = coreIFace->settings();
+    GitSettings rc;
+    rc.path = m_ui.pathLineEdit->text();
+    rc.adoptPath = m_ui.environmentGroupBox->isChecked() && !rc.path.isEmpty();
+    rc.logCount = m_ui.logCountSpinBox->value();
+    return rc;
+}
 
-    if (m_settings) {
-        m_settings->beginGroup(QLatin1String(groupC));
-        m_adopt = m_settings->value(QLatin1String(sysEnvKeyC), true).toBool();
-        m_path = m_settings->value(QLatin1String(pathKeyC), QString()).toString();
-        m_logCount = m_settings->value(QLatin1String(logCountKeyC), 10).toInt();
-        m_settings->endGroup();
-    }
+void SettingsPageWidget::setSettings(const GitSettings &s)
+{
+    m_ui.environmentGroupBox->setChecked(s.adoptPath);
+    m_ui.pathLineEdit->setText(s.path);
+    m_ui.logCountSpinBox->setValue(s.logCount);
+}
+
+void SettingsPageWidget::setSystemPath()
+{
+    m_ui.pathLineEdit->setText(QLatin1String(qgetenv("PATH")));
+}
+
+// -------- SettingsPage
+SettingsPage::SettingsPage()
+{
 }
 
 QString SettingsPage::name() const
@@ -68,7 +77,7 @@ QString SettingsPage::name() const
     return tr("General");
 }
 
-QString SettingsPage::category() const
+ QString SettingsPage::category() const
 {
     return QLatin1String("Git");
 }
@@ -80,37 +89,17 @@ QString SettingsPage::trCategory() const
 
 QWidget *SettingsPage::createPage(QWidget *parent)
 {
-    QWidget *w = new QWidget(parent);
-    m_ui.setupUi(w);
-    m_ui.adoptCheckBox->setChecked(m_adopt);
-    m_ui.pathLineEdit->setText(m_path);
-    m_ui.logLineEdit->setText(QString::number(m_logCount));
-
-    connect(m_ui.adoptButton, SIGNAL(clicked()), this, SLOT(setSystemPath()));
-    return w;
+    if (!m_widget)
+        m_widget = new SettingsPageWidget(parent);
+    m_widget->setSettings(GitPlugin::instance()->settings());
+    return m_widget;
 }
 
 void SettingsPage::finished(bool accepted)
 {
-    if (!accepted)
+    if (!accepted || !m_widget)
         return;
 
-    m_adopt = m_ui.adoptCheckBox->isChecked();
-    m_path = m_ui.pathLineEdit->text();
-    m_logCount = m_ui.logLineEdit->text().toInt();
-
-    if (!m_settings)
-        return;
-
-    m_settings->beginGroup(QLatin1String(groupC));
-    m_settings->setValue(QLatin1String(sysEnvKeyC), m_adopt);
-    m_settings->setValue(QLatin1String(pathKeyC), m_path);
-    m_settings->setValue(QLatin1String(logCountKeyC), m_logCount);
-    m_settings->endGroup();
+    GitPlugin::instance()->setSettings(m_widget->settings());
 }
 
-void SettingsPage::setSystemPath()
-{
-    m_path = qgetenv("PATH");
-    m_ui.pathLineEdit->setText(m_path);
-}
diff --git a/src/plugins/git/settingspage.h b/src/plugins/git/settingspage.h
index 95147cf6552e1a1ae50bf0e75218dd3bf678da51..c1f1403c4c909336fcba3b373fbb036e7c897aab 100644
--- a/src/plugins/git/settingspage.h
+++ b/src/plugins/git/settingspage.h
@@ -35,6 +35,7 @@
 #define SETTINGSPAGE_H
 
 #include <QtGui/QWidget>
+#include <QtCore/QPointer>
 
 #include <coreplugin/dialogs/ioptionspage.h>
 
@@ -47,6 +48,23 @@ QT_END_NAMESPACE
 namespace Git {
 namespace Internal {
 
+struct GitSettings;
+
+class SettingsPageWidget : public QWidget {
+    Q_OBJECT
+public:
+    explicit SettingsPageWidget(QWidget *parent = 0);
+
+    GitSettings settings() const;
+    void setSettings(const GitSettings &);
+
+private slots:
+    void setSystemPath();
+
+private:
+    Ui::SettingsPage m_ui;
+};
+
 class SettingsPage : public Core::IOptionsPage
 {
     Q_OBJECT
@@ -61,20 +79,8 @@ public:
     QWidget *createPage(QWidget *parent);
     void finished(bool accepted);
 
-    bool adoptEnvironment() const { return m_adopt; }
-    int logCount() const { return m_logCount; }
-    QString path() const { return m_path; }
-
-private slots:
-    void setSystemPath();
-
 private:
-    Ui_SettingsPage m_ui;
-    QSettings *m_settings;
-
-    bool m_adopt;
-    QString m_path;
-    int m_logCount;
+    QPointer<SettingsPageWidget> m_widget;
 };
 
 } // namespace Internal
diff --git a/src/plugins/git/settingspage.ui b/src/plugins/git/settingspage.ui
index 738413e676f87c3e0405d20baf4a58befa82f780..aa2337605b8bf95f21521e9e0fdb8fb790ace6d8 100644
--- a/src/plugins/git/settingspage.ui
+++ b/src/plugins/git/settingspage.ui
@@ -6,103 +6,113 @@
    <rect>
     <x>0</x>
     <y>0</y>
-    <width>345</width>
-    <height>177</height>
+    <width>436</width>
+    <height>186</height>
    </rect>
   </property>
   <property name="windowTitle">
    <string>Form</string>
   </property>
-  <layout class="QVBoxLayout" name="verticalLayout">
+  <layout class="QHBoxLayout" name="horizontalLayout">
    <item>
-    <widget class="QCheckBox" name="adoptCheckBox">
-     <property name="text">
-      <string>Use System Environment</string>
-     </property>
-    </widget>
-   </item>
-   <item>
-    <widget class="QGroupBox" name="groupBox">
-     <property name="enabled">
-      <bool>true</bool>
-     </property>
-     <property name="title">
-      <string>Environment variables</string>
-     </property>
-     <property name="checkable">
-      <bool>false</bool>
-     </property>
-     <layout class="QGridLayout" name="gridLayout">
-      <item row="0" column="0">
-       <widget class="QLabel" name="label">
-        <property name="text">
-         <string>PATH:</string>
-        </property>
-       </widget>
-      </item>
-      <item row="0" column="1">
-       <widget class="QLineEdit" name="pathLineEdit"/>
-      </item>
-      <item row="0" column="2">
-       <widget class="QPushButton" name="adoptButton">
-        <property name="text">
-         <string>Adopt</string>
-        </property>
-       </widget>
-      </item>
-      <item row="1" column="0">
-       <spacer name="horizontalSpacer">
-        <property name="orientation">
-         <enum>Qt::Horizontal</enum>
-        </property>
-        <property name="sizeHint" stdset="0">
-         <size>
-          <width>52</width>
-          <height>20</height>
-         </size>
-        </property>
-       </spacer>
-      </item>
-      <item row="1" column="1" colspan="2">
-       <widget class="QLabel" name="label_2">
-        <property name="text">
-         <string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
-&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
-p, li { white-space: pre-wrap; }
-&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;&quot;&gt;
-&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-size:8pt; font-weight:600;&quot;&gt;Note&lt;/span&gt;&lt;span style=&quot; font-size:8pt;&quot;&gt; that Git needs Perl in the environment as well&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
-        </property>
-       </widget>
-      </item>
-     </layout>
-    </widget>
-   </item>
-   <item>
-    <layout class="QHBoxLayout" name="horizontalLayout">
+    <layout class="QVBoxLayout" name="verticalLayout">
      <item>
-      <widget class="QLabel" name="label_3">
-       <property name="text">
-        <string>Commit display count:</string>
+      <widget class="QGroupBox" name="environmentGroupBox">
+       <property name="enabled">
+        <bool>true</bool>
        </property>
+       <property name="title">
+        <string>Environment variables</string>
+       </property>
+       <property name="checkable">
+        <bool>true</bool>
+       </property>
+       <layout class="QFormLayout" name="formLayout">
+        <item row="0" column="0">
+         <widget class="QLabel" name="pathlabel">
+          <property name="text">
+           <string>PATH:</string>
+          </property>
+         </widget>
+        </item>
+        <item row="0" column="1">
+         <layout class="QHBoxLayout" name="horizontalLayout_2">
+          <item>
+           <widget class="QLineEdit" name="pathLineEdit"/>
+          </item>
+          <item>
+           <widget class="QPushButton" name="adoptButton">
+            <property name="text">
+             <string>From system</string>
+            </property>
+           </widget>
+          </item>
+         </layout>
+        </item>
+        <item row="1" column="0">
+         <widget class="QLabel" name="noteLabel">
+          <property name="text">
+           <string>&lt;b&gt;Note:&lt;/b&gt;</string>
+          </property>
+         </widget>
+        </item>
+        <item row="1" column="1">
+         <widget class="QLabel" name="noteFieldlabel">
+          <property name="text">
+           <string>Git needs to find Perl in the environment as well.</string>
+          </property>
+         </widget>
+        </item>
+       </layout>
       </widget>
      </item>
      <item>
-      <widget class="QLineEdit" name="logLineEdit">
-       <property name="toolTip">
-        <string>Note that huge amount of commits might take some time.</string>
+      <layout class="QFormLayout" name="logFormLayout">
+       <property name="fieldGrowthPolicy">
+        <enum>QFormLayout::ExpandingFieldsGrow</enum>
        </property>
-      </widget>
+       <item row="0" column="1">
+        <widget class="QSpinBox" name="logCountSpinBox">
+         <property name="toolTip">
+          <string>Note that huge amount of commits might take some time.</string>
+         </property>
+         <property name="maximum">
+          <number>1000</number>
+         </property>
+        </widget>
+       </item>
+       <item row="0" column="0">
+        <widget class="QLabel" name="logCountLabel">
+         <property name="text">
+          <string>Log commit display count:</string>
+         </property>
+        </widget>
+       </item>
+      </layout>
+     </item>
+     <item>
+      <spacer name="verticalSpacer">
+       <property name="orientation">
+        <enum>Qt::Vertical</enum>
+       </property>
+       <property name="sizeHint" stdset="0">
+        <size>
+         <width>20</width>
+         <height>40</height>
+        </size>
+       </property>
+      </spacer>
      </item>
     </layout>
    </item>
    <item>
-    <spacer>
+    <spacer name="horizontalSpacer">
      <property name="orientation">
-      <enum>Qt::Vertical</enum>
+      <enum>Qt::Horizontal</enum>
      </property>
      <property name="sizeHint" stdset="0">
       <size>
-       <width>141</width>
+       <width>40</width>
        <height>20</height>
       </size>
      </property>
@@ -114,22 +124,5 @@ p, li { white-space: pre-wrap; }
   <tabstop>pathLineEdit</tabstop>
  </tabstops>
  <resources/>
- <connections>
-  <connection>
-   <sender>adoptCheckBox</sender>
-   <signal>toggled(bool)</signal>
-   <receiver>groupBox</receiver>
-   <slot>setDisabled(bool)</slot>
-   <hints>
-    <hint type="sourcelabel">
-     <x>144</x>
-     <y>33</y>
-    </hint>
-    <hint type="destinationlabel">
-     <x>139</x>
-     <y>65</y>
-    </hint>
-   </hints>
-  </connection>
- </connections>
+ <connections/>
 </ui>
diff --git a/src/plugins/help/help.pro b/src/plugins/help/help.pro
index 1148606cab73e847a7b8bb75ce359cae31a93c21..b2e9a1dbd613cec02e2b73ed04d1cd6c7e1eaa3d 100644
--- a/src/plugins/help/help.pro
+++ b/src/plugins/help/help.pro
@@ -16,8 +16,8 @@ HEADERS += helpplugin.h \
     searchwidget.h \
     helpfindsupport.h \
     help_global.h \
-    helpindexfilter.h \
-    indexwindow.h
+    helpindexfilter.h
+
 SOURCES += helpplugin.cpp \
     docsettingspage.cpp \
     filtersettingspage.cpp \
@@ -26,6 +26,7 @@ SOURCES += helpplugin.cpp \
     searchwidget.cpp \
     helpfindsupport.cpp \
     helpindexfilter.cpp
+
 FORMS += docsettingspage.ui \
     filtersettingspage.ui
 RESOURCES += help.qrc
diff --git a/src/plugins/perforce/perforceplugin.cpp b/src/plugins/perforce/perforceplugin.cpp
index 7f71282fbbf71df8d7ea6d6bcef2e50c41073ce2..dc28901b7050540b8dc028165ccf658308a0c493 100644
--- a/src/plugins/perforce/perforceplugin.cpp
+++ b/src/plugins/perforce/perforceplugin.cpp
@@ -235,6 +235,10 @@ bool PerforcePlugin::initialize(const QStringList & /*arguments*/, QString *erro
         am->createMenu(QLatin1String(PERFORCE_MENU));
     mperforce->menu()->setTitle(tr("&Perforce"));
     mtools->addMenu(mperforce);
+    if (QAction *ma = mperforce->menu()->menuAction()) {
+        ma->setEnabled(m_versionControl->isEnabled());
+        connect(m_versionControl, SIGNAL(enabledChanged(bool)), ma, SLOT(setVisible(bool)));
+    }
 
     QList<int> globalcontext;
     globalcontext << Core::Constants::C_GLOBAL_ID;
@@ -401,17 +405,17 @@ void PerforcePlugin::extensionsInitialized()
 
 void PerforcePlugin::openCurrentFile()
 {
-    runP4Cmd(QStringList() << QLatin1String("edit") << currentFileName(), QStringList(), true);
+    vcsOpen(currentFileName());
 }
 
 void PerforcePlugin::addCurrentFile()
 {
-    runP4Cmd(QStringList() << QLatin1String("add") << currentFileName(), QStringList(), true);
+    vcsAdd(currentFileName());
 }
 
 void PerforcePlugin::deleteCurrentFile()
 {
-    runP4Cmd(QStringList() << QLatin1String("delete") << currentFileName(), QStringList(), true);
+    vcsDelete(currentFileName());
 }
 
 void PerforcePlugin::revertCurrentFile()
@@ -422,7 +426,7 @@ void PerforcePlugin::revertCurrentFile()
     QTextCodec *codec = VCSBase::VCSBaseEditor::getCodec(m_coreInstance, fileName);
     QStringList args;
     args << QLatin1String("diff") << QLatin1String("-sa");
-    PerforceResponse result = runP4Cmd(args, QStringList(), false, true, codec);
+    PerforceResponse result = runP4Cmd(args, QStringList(), CommandToWindow|StdErrToWindow|ErrorToWindow, codec);
     if (result.error)
         return;
 
@@ -440,7 +444,7 @@ void PerforcePlugin::revertCurrentFile()
     foreach (Core::IFile *file, files) {
         fm->blockFileChange(file);
     }
-    PerforceResponse result2 = runP4Cmd(QStringList() << QLatin1String("revert") << fileName, QStringList(), true);
+    PerforceResponse result2 = runP4Cmd(QStringList() << QLatin1String("revert") << fileName, QStringList(), CommandToWindow|StdOutToWindow|StdErrToWindow|ErrorToWindow);
     Core::IFile::ReloadBehavior tempBehavior =
             Core::IFile::ReloadAll;
     foreach (Core::IFile *file, files) {
@@ -485,7 +489,7 @@ void PerforcePlugin::printOpenedFileList()
     Core::IEditor *e = m_coreInstance->editorManager()->currentEditor();
     if (e)
         e->widget()->setFocus();
-    PerforceResponse result = runP4Cmd(QStringList() << QLatin1String("opened"), QStringList(), true);
+    PerforceResponse result = runP4Cmd(QStringList() << QLatin1String("opened"), QStringList(), CommandToWindow|StdOutToWindow|StdErrToWindow|ErrorToWindow);
 }
 
 #ifdef USE_P4_API
@@ -518,7 +522,8 @@ void PerforcePlugin::submit()
         return;
     }
 
-    PerforceResponse result = runP4Cmd(QStringList()<< QLatin1String("change") << QLatin1String("-o"), QStringList(), false);
+    PerforceResponse result = runP4Cmd(QStringList()<< QLatin1String("change") << QLatin1String("-o"), QStringList(),
+                                       CommandToWindow|StdErrToWindow|ErrorToWindow);
     if (result.error) {
         delete m_changeTmpFile;
         m_changeTmpFile = 0;
@@ -546,7 +551,8 @@ void PerforcePlugin::submit()
     foreach (const QString &f, files)
         nativeFiles << QDir::toNativeSeparators(f);
 
-    PerforceResponse result2 = runP4Cmd(QStringList(QLatin1String("fstat")), nativeFiles, false);
+    PerforceResponse result2 = runP4Cmd(QStringList(QLatin1String("fstat")), nativeFiles,
+                                        CommandToWindow|StdErrToWindow|ErrorToWindow);
     if (result2.error) {
         delete m_changeTmpFile;
         m_changeTmpFile = 0;
@@ -593,8 +599,10 @@ void PerforcePlugin::printPendingChanges()
     PendingChangesDialog dia(pendingChangesData(), m_coreInstance->mainWindow());
     qApp->restoreOverrideCursor();
     if (dia.exec() == QDialog::Accepted) {
-        int i = dia.changeNumber();
-        PerforceResponse result = runP4Cmd(QStringList()<<"submit"<<"-c"<<QString::number(i), QStringList(), true);
+        const int i = dia.changeNumber();
+        QStringList args(QLatin1String("submit"));
+        args << QLatin1String("-c") << QString::number(i);
+        runP4Cmd(args, QStringList(), CommandToWindow|StdOutToWindow|StdErrToWindow|ErrorToWindow);
     }
 }
 
@@ -624,7 +632,8 @@ void PerforcePlugin::annotate(const QString &fileName)
     QTextCodec *codec = VCSBase::VCSBaseEditor::getCodec(m_coreInstance, fileName);
     QStringList args;
     args << QLatin1String("annotate") << QLatin1String("-cqi") << fileName;
-    const PerforceResponse result = runP4Cmd(args, QStringList(), false, true, codec);
+    const PerforceResponse result = runP4Cmd(args, QStringList(),
+                                             CommandToWindow|StdErrToWindow|ErrorToWindow, codec);
     if (!result.error) {
         const QFileInfo fi(fileName);
         showOutputInEditor(tr("p4 annotate %1").arg(fi.fileName()), result.stdOut, VCSBase::AnnotateOutput, codec);
@@ -650,7 +659,8 @@ void PerforcePlugin::filelog(const QString &fileName)
     QTextCodec *codec = VCSBase::VCSBaseEditor::getCodec(m_coreInstance, fileName);
     QStringList args;
     args << QLatin1String("filelog") << QLatin1String("-li") << fileName;
-    const PerforceResponse result = runP4Cmd(args, QStringList(), false, true, codec);
+    const PerforceResponse result = runP4Cmd(args, QStringList(),
+                                             CommandToWindow|StdErrToWindow|ErrorToWindow, codec);
     if (!result.error) {
         const QFileInfo fi(fileName);
         showOutputInEditor(tr("p4 filelog %1").arg(fi.fileName()), result.stdOut, VCSBase::LogOutput, codec);
@@ -714,18 +724,19 @@ bool PerforcePlugin::managesDirectory(const QString &directory) const
     QStringList args;
     args << QLatin1String("fstat") << QLatin1String("-m1") << p4Path;
 
-    const PerforceResponse result = runP4Cmd(args, QStringList(), false, false);
+    const PerforceResponse result = runP4Cmd(args, QStringList(), 0u);
     return result.stdOut.contains("depotFile") || result.stdErr.contains("... - no such file(s)");
 }
 
 QString PerforcePlugin::findTopLevelForDirectory(const QString & /* dir */) const
 {
     // First check with p4 client -o
-    PerforceResponse result = runP4Cmd(QStringList() << QLatin1String("client") << QLatin1String("-o"), QStringList(), false, false);
+    PerforceResponse result = runP4Cmd(QStringList() << QLatin1String("client") << QLatin1String("-o"), QStringList(), 0u);
     if (result.error)
         return QString::null;
 
     QRegExp regExp(QLatin1String("(\\n|\\r\\n|\\r)Root:\\s*(.*)(\\n|\\r\\n|\\r)"));
+    Q_ASSERT(regExp.isValid());
     regExp.setMinimal(true);
     if (regExp.indexIn(result.stdOut) != -1) {
         QString file = regExp.cap(2).trimmed();
@@ -737,20 +748,24 @@ QString PerforcePlugin::findTopLevelForDirectory(const QString & /* dir */) cons
 
 bool PerforcePlugin::vcsOpen(const QString &fileName)
 {
-    PerforceResponse result = runP4Cmd(QStringList() << QLatin1String("edit") << QDir::toNativeSeparators(fileName), QStringList(), true);
+    PerforceResponse result = runP4Cmd(QStringList() << QLatin1String("edit") << QDir::toNativeSeparators(fileName), QStringList(),
+                                       CommandToWindow|StdOutToWindow|StdErrToWindow|ErrorToWindow);
     return !result.error;
 }
 
 bool PerforcePlugin::vcsAdd(const QString &fileName)
 {
-    PerforceResponse result = runP4Cmd(QStringList() << QLatin1String("add") << fileName, QStringList(), true);
+    PerforceResponse result = runP4Cmd(QStringList() << QLatin1String("add") << fileName, QStringList(),
+                                       CommandToWindow|StdOutToWindow|StdErrToWindow|ErrorToWindow);
     return !result.error;
 }
 
 bool PerforcePlugin::vcsDelete(const QString &fileName)
 {
-    PerforceResponse result = runP4Cmd(QStringList() << QLatin1String("revert") << fileName, QStringList(), true);
-    PerforceResponse result2 = runP4Cmd(QStringList() << QLatin1String("delete") << fileName, QStringList(), true);
+    PerforceResponse result = runP4Cmd(QStringList() << QLatin1String("revert") << fileName, QStringList(),
+                                       CommandToWindow|StdOutToWindow|StdErrToWindow|ErrorToWindow);
+    PerforceResponse result2 = runP4Cmd(QStringList() << QLatin1String("delete") << fileName, QStringList(),
+                                        CommandToWindow|StdOutToWindow|StdErrToWindow|ErrorToWindow);
     // TODO need to carefully parse the actual messages from perforce
     // or do a fstat before to decide what to do
 
@@ -763,8 +778,7 @@ bool PerforcePlugin::vcsDelete(const QString &fileName)
 
 PerforceResponse PerforcePlugin::runP4Cmd(const QStringList &args,
                                           const QStringList &extraArgs,
-                                          bool showStdOutInOutputWindow,
-                                          bool showStdErrInOutputWindow,
+                                          unsigned logFlags,
                                           QTextCodec *outputCodec) const
 {
     if (Perforce::Constants::debug)
@@ -797,12 +811,14 @@ PerforceResponse PerforcePlugin::runP4Cmd(const QStringList &args,
     }
     actualArgs << args;
 
-    response.command = m_settings.p4Command;
-    response.command += blank;
-    response.command += actualArgs.join(QString(blank));
-    const QString timeStamp = QTime::currentTime().toString(QLatin1String("HH:mm"));
-    const QString outputText = tr("%1 Executing: %2\n").arg(timeStamp, response.command);
-    showOutput(outputText, false);
+    if (logFlags & CommandToWindow) {
+        QString command = m_settings.p4Command;
+        command += blank;
+        command += actualArgs.join(QString(blank));
+        const QString timeStamp = QTime::currentTime().toString(QLatin1String("HH:mm"));
+        const QString outputText = tr("%1 Executing: %2\n").arg(timeStamp, command);
+        showOutput(outputText, false);
+    }
 
     // Run, connect stderr to the output window
     Core::Utils::SynchronousProcess process;
@@ -811,13 +827,13 @@ PerforceResponse PerforcePlugin::runP4Cmd(const QStringList &args,
     process.setEnvironment(environment());
 
     // connect stderr to the output window if desired
-    if (showStdErrInOutputWindow) {
+    if (logFlags & StdErrToWindow) {
         process.setStdErrBufferedSignalsEnabled(true);
         connect(&process, SIGNAL(stdErrBuffered(QString,bool)), m_perforceOutputWindow, SLOT(append(QString,bool)));
     }
 
     // connect stdout to the output window if desired
-    if (showStdOutInOutputWindow) {
+    if (logFlags & StdOutToWindow) {
         process.setStdOutBufferedSignalsEnabled(true);
         connect(&process, SIGNAL(stdOutBuffered(QString,bool)), m_perforceOutputWindow, SLOT(append(QString,bool)));
     }
@@ -843,13 +859,15 @@ PerforceResponse PerforcePlugin::runP4Cmd(const QStringList &args,
         response.message = tr("Could not start perforce '%1'. Please check your settings in the preferences.").arg(m_settings.p4Command);
         break;
     case Core::Utils::SynchronousProcessResponse::Hang:
-        response.message = tr("Subversion did not respond within timeout limit (%1 ms).").arg(p4Timeout );
+        response.message = tr("Perforce did not respond within timeout limit (%1 ms).").arg(p4Timeout );
         break;
     }
-    if (response.error)
-        m_perforceOutputWindow->append(response.message, true);
-
-
+    if (response.error) {
+        if (Perforce::Constants::debug)
+            qDebug() << response.message;
+        if (logFlags & ErrorToWindow)
+            m_perforceOutputWindow->append(response.message, true);
+    }
     return response;
 }
 
@@ -919,7 +937,7 @@ void PerforcePlugin::p4Diff(const QStringList &files, QString diffname)
         }
     }
 
-    const PerforceResponse result = runP4Cmd(QStringList() << QLatin1String("diff") << QLatin1String("-du"), files, false, codec);
+    const PerforceResponse result = runP4Cmd(QStringList() << QLatin1String("diff") << QLatin1String("-du"), files, CommandToWindow|StdErrToWindow|ErrorToWindow, codec);
     if (result.error)
         return;
 
@@ -944,7 +962,7 @@ void PerforcePlugin::describe(const QString & source, const QString &n)
     QTextCodec *codec = source.isEmpty() ? static_cast<QTextCodec *>(0) : VCSBase::VCSBaseEditor::getCodec(m_coreInstance, source);
     QStringList args;
     args << QLatin1String("describe") << QLatin1String("-du") << n;
-    const PerforceResponse result = runP4Cmd(args, QStringList(), codec);
+    const PerforceResponse result = runP4Cmd(args, QStringList(), CommandToWindow|StdErrToWindow|ErrorToWindow, codec);
     if (!result.error)
         showOutputInEditor(tr("p4 describe %1").arg(n), result.stdOut, VCSBase::DiffOutput, codec);
 }
diff --git a/src/plugins/perforce/perforceplugin.h b/src/plugins/perforce/perforceplugin.h
index 4c088563324ae8999d279b5c8607b3300aeabec2..7a4e23077794ef89599d00b3818d537fb118c46a 100644
--- a/src/plugins/perforce/perforceplugin.h
+++ b/src/plugins/perforce/perforceplugin.h
@@ -86,7 +86,6 @@ private:
 struct PerforceResponse
 {
     bool error;
-    QString command;
     QString stdOut;
     QString stdErr;
     QString message;
@@ -161,12 +160,15 @@ private:
     Core::IEditor *showOutputInEditor(const QString& title, const QString output,
                                       int editorType,
                                       QTextCodec *codec = 0);
+
+    // Verbosity flags for runP4Cmd.
+    enum  RunLogFlags { CommandToWindow = 0x1, StdOutToWindow = 0x2, StdErrToWindow = 0x4, ErrorToWindow = 0x8 };
+
     // args are passed as command line arguments
     // extra args via a tempfile and the option -x "temp-filename"
     PerforceResponse runP4Cmd(const QStringList &args,
                               const QStringList &extraArgs = QStringList(),
-                              bool showStdOutInOutputWindow = false,
-                              bool showStdErrInOutputWindow = true,
+                              unsigned logFlags = CommandToWindow|StdErrToWindow|ErrorToWindow,
                               QTextCodec *outputCodec = 0) const;
 
     void openFiles(const QStringList &files);
diff --git a/src/plugins/perforce/perforceversioncontrol.cpp b/src/plugins/perforce/perforceversioncontrol.cpp
index a51930c1e6daf254994442a27bfd9e25d3007d1e..98379024bc04858b349778ae904133d3b5d62c23 100644
--- a/src/plugins/perforce/perforceversioncontrol.cpp
+++ b/src/plugins/perforce/perforceversioncontrol.cpp
@@ -38,10 +38,41 @@ namespace Perforce {
 namespace Internal {
 
 PerforceVersionControl::PerforceVersionControl(PerforcePlugin *plugin) :
+    m_enabled(true),
     m_plugin(plugin)
 {
 }
 
+QString PerforceVersionControl::name() const
+{
+    return QLatin1String("perforce");
+}
+
+bool PerforceVersionControl::isEnabled() const
+{
+     return m_enabled;
+}
+
+void PerforceVersionControl::setEnabled(bool enabled)
+{
+    if (m_enabled != enabled) {
+        m_enabled = enabled;
+        emit enabledChanged(m_enabled);
+    }
+}
+
+bool PerforceVersionControl::supportsOperation(Operation operation) const
+{
+    bool rc = true;
+    switch (operation) {
+    case AddOperation:
+    case DeleteOperation:
+    case OpenOperation:
+        break;
+    }
+    return rc;
+}
+
 bool PerforceVersionControl::vcsOpen(const QString &fileName)
 {
     return m_plugin->vcsOpen(fileName);
diff --git a/src/plugins/perforce/perforceversioncontrol.h b/src/plugins/perforce/perforceversioncontrol.h
index d87a7f15ae4ef86de7870d1662d062965d331b95..0e8a1ea6539d6aaaa1465bbca2be2d25ba96cc83 100644
--- a/src/plugins/perforce/perforceversioncontrol.h
+++ b/src/plugins/perforce/perforceversioncontrol.h
@@ -46,13 +46,25 @@ class PerforceVersionControl : public Core::IVersionControl
     Q_OBJECT
 public:
     explicit PerforceVersionControl(PerforcePlugin *plugin);
+
+    virtual QString name() const;
+
+    virtual bool isEnabled() const;
+    virtual void setEnabled(bool enabled);
+
     bool managesDirectory(const QString &directory) const;
     virtual QString findTopLevelForDirectory(const QString &directory) const;
+
+    virtual bool supportsOperation(Operation operation) const;
     virtual bool vcsOpen(const QString &fileName);
     virtual bool vcsAdd(const QString &fileName);
     virtual bool vcsDelete(const QString &filename);
 
+signals:
+    void enabledChanged(bool);
+
 private:
+    bool m_enabled;
     PerforcePlugin *m_plugin;
 };
 
diff --git a/src/plugins/projectexplorer/abstractprocessstep.cpp b/src/plugins/projectexplorer/abstractprocessstep.cpp
index 09bd73fe7676effdca5524515f2941679b29057a..06b40135c1262da635ecd62f21b5ec24364c7e5f 100644
--- a/src/plugins/projectexplorer/abstractprocessstep.cpp
+++ b/src/plugins/projectexplorer/abstractprocessstep.cpp
@@ -39,6 +39,7 @@
 #include <QtCore/QEventLoop>
 #include <QtCore/QDebug>
 #include <QtCore/QTimer>
+#include <QtGui/QTextDocument>
 
 using namespace ProjectExplorer;
 
@@ -165,7 +166,7 @@ void AbstractProcessStep::run(QFutureInterface<bool> & fi)
 
 void AbstractProcessStep::processStarted()
 {
-    emit addToOutputWindow(tr("<font color=\"#0000ff\">Starting: %1 %2</font>\n").arg(m_command, m_arguments.join(" ")));
+    emit addToOutputWindow(tr("<font color=\"#0000ff\">Starting: %1 %2</font>\n").arg(m_command, Qt::escape(m_arguments.join(" "))));
 }
 
 bool AbstractProcessStep::processFinished(int exitCode, QProcess::ExitStatus status)
@@ -196,7 +197,7 @@ void AbstractProcessStep::processReadyReadStdOutput()
 
 void AbstractProcessStep::stdOut(const QString &line)
 {
-    emit addToOutputWindow(line);
+    emit addToOutputWindow(Qt::escape(line));
 }
 
 void AbstractProcessStep::processReadyReadStdError()
@@ -211,7 +212,7 @@ void AbstractProcessStep::processReadyReadStdError()
 
 void AbstractProcessStep::stdError(const QString &line)
 {
-    emit addToOutputWindow(QLatin1String("<font color=\"#ff0000\">") + line + QLatin1String("</font>"));
+    emit addToOutputWindow(QLatin1String("<font color=\"#ff0000\">") + Qt::escape(line) + QLatin1String("</font>"));
 }
 
 void AbstractProcessStep::checkForCancel()
diff --git a/src/plugins/projectexplorer/allprojectsfind.cpp b/src/plugins/projectexplorer/allprojectsfind.cpp
index f892f5ff39900c8c98ee67b1660635346d194199..be7d9d96ee452ae48e8c82ac2ef386a8a986e859 100644
--- a/src/plugins/projectexplorer/allprojectsfind.cpp
+++ b/src/plugins/projectexplorer/allprojectsfind.cpp
@@ -108,12 +108,14 @@ QWidget *AllProjectsFind::createConfigWidget()
         gridLayout->setMargin(0);
         m_configWidget->setLayout(gridLayout);
         gridLayout->addWidget(createRegExpWidget(), 0, 1);
-        QLabel * const filePatternLabel = new QLabel(tr("File pattern:"));
+        QLabel * const filePatternLabel = new QLabel(tr("File &pattern:"));
         filePatternLabel->setMinimumWidth(80);
         filePatternLabel->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Preferred);
         filePatternLabel->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
+        QWidget *patternWidget = createPatternWidget();
+        filePatternLabel->setBuddy(patternWidget);
         gridLayout->addWidget(filePatternLabel, 1, 0, Qt::AlignRight);
-        gridLayout->addWidget(createPatternWidget(), 1, 1);
+        gridLayout->addWidget(patternWidget, 1, 1);
         m_configWidget->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
     }
     return m_configWidget;
diff --git a/src/plugins/projectexplorer/applicationrunconfiguration.cpp b/src/plugins/projectexplorer/applicationrunconfiguration.cpp
index ba459d563c1f7338e1f248d207898251d354ad09..30b9a7f7caab9ec98223e647ef13ccd392e9f71b 100644
--- a/src/plugins/projectexplorer/applicationrunconfiguration.cpp
+++ b/src/plugins/projectexplorer/applicationrunconfiguration.cpp
@@ -38,6 +38,7 @@
 #include <projectexplorer/projectexplorerconstants.h>
 
 #include <QtGui/QLabel>
+#include <QtGui/QTextDocument>
 #include <QDebug>
 
 using namespace ProjectExplorer;
@@ -160,7 +161,7 @@ void ApplicationRunControl::slotError(const QString & err)
 
 void ApplicationRunControl::slotAddToOutputWindow(const QString &line)
 {
-    emit addToOutputWindow(this, line);
+    emit addToOutputWindow(this, Qt::escape(line));
 }
 
 void ApplicationRunControl::processExited(int exitCode)
diff --git a/src/plugins/projectexplorer/currentprojectfind.cpp b/src/plugins/projectexplorer/currentprojectfind.cpp
index 58300f4ca83f7adcb6dcaa5359cc0930f74fe1e4..fb55df3e0fd7a6f1e9710e9cf0884b6ea288111c 100644
--- a/src/plugins/projectexplorer/currentprojectfind.cpp
+++ b/src/plugins/projectexplorer/currentprojectfind.cpp
@@ -104,12 +104,14 @@ QWidget *CurrentProjectFind::createConfigWidget()
         layout->setMargin(0);
         m_configWidget->setLayout(layout);
         layout->addWidget(createRegExpWidget(), 0, 1);
-        QLabel * const filePatternLabel = new QLabel(tr("File pattern:"));
+        QLabel * const filePatternLabel = new QLabel(tr("File &pattern:"));
         filePatternLabel->setMinimumWidth(80);
         filePatternLabel->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Preferred);
         filePatternLabel->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
+        QWidget *patternWidget = createPatternWidget();
+        filePatternLabel->setBuddy(patternWidget);
         layout->addWidget(filePatternLabel, 1, 0, Qt::AlignRight);
-        layout->addWidget(createPatternWidget(), 1, 1);
+        layout->addWidget(patternWidget, 1, 1);
         m_configWidget->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
     }
     return m_configWidget;
diff --git a/src/plugins/projectexplorer/projectexplorer.cpp b/src/plugins/projectexplorer/projectexplorer.cpp
index e04553763a36e1194fc9a2cffd5dc707afa6486e..b95d5c19463d46a20a554fa4381b49ef178bf661 100644
--- a/src/plugins/projectexplorer/projectexplorer.cpp
+++ b/src/plugins/projectexplorer/projectexplorer.cpp
@@ -76,6 +76,7 @@
 #include <coreplugin/welcomemode.h>
 #include <coreplugin/vcsmanager.h>
 #include <coreplugin/iversioncontrol.h>
+#include <coreplugin/vcsmanager.h>
 #include <utils/listutils.h>
 
 #include <QtCore/qplugin.h>
@@ -685,28 +686,19 @@ void ProjectExplorerPlugin::loadAction()
     updateActions();
 }
 
-bool ProjectExplorerPlugin::saveAction(Project *pro)
+void ProjectExplorerPlugin::unloadProject()
 {
     if (debug)
-        qDebug() << "ProjectExplorerPlugin::saveAction";
-
-    if (!pro)
-        pro = m_currentProject;
-    Q_ASSERT(pro);
-
-    Core::IFile *fi = pro->file();
+        qDebug() << "ProjectExplorerPlugin::unloadProject";
 
-    if (!fi) // TODO Why saving the session here????
-        fi = m_session->file();
+    Core::IFile *fi = m_currentProject->file();
 
     if (!fi || fi->fileName().isEmpty()) //nothing to save?
-        return false;
+        return;
 
     QList<Core::IFile*> filesToSave;
-
     filesToSave << fi;
-    if (pro)
-        filesToSave << pro->dependencies();
+    filesToSave << m_currentProject->dependencies();
 
     // check the number of modified files
     int readonlycount = 0;
@@ -721,20 +713,10 @@ bool ProjectExplorerPlugin::saveAction(Project *pro)
     else
         success = m_core->fileManager()->saveModifiedFilesSilently(filesToSave).isEmpty();
 
-    if (success)
-        addToRecentProjects(fi->fileName());
-    updateActions();
-    return success;
-}
-
-void ProjectExplorerPlugin::unloadProject()
-{
-    if (debug)
-        qDebug() << "ProjectExplorerPlugin::unloadProject";
-
-    if (!saveAction(m_currentProject))
+    if (!success)
         return;
 
+    addToRecentProjects(fi->fileName());
     m_session->removeProject(m_currentProject);
     updateActions();
 }
@@ -1172,6 +1154,13 @@ void ProjectExplorerPlugin::setCurrent(Project *project, QString filePath, Node
     if (projectChanged) {
         if (debug)
             qDebug() << "ProjectExplorer - currentProjectChanged(" << (project ? project->name() : "0") << ")";
+        // Enable the right VCS
+        if (const Core::IFile *projectFile = project ? project->file() : static_cast<const Core::IFile *>(0)) {
+            m_core->vcsManager()->setVCSEnabled(QFileInfo(projectFile->fileName()).absolutePath());
+        } else {
+            m_core->vcsManager()->setAllVCSEnabled();
+        }
+
         emit currentProjectChanged(project);
         updateActions();
     }
@@ -1584,27 +1573,28 @@ void ProjectExplorerPlugin::addExistingFiles()
             fileNames.removeOne(file);
     }
 
-    if (Core::IVersionControl *vcManager = m_core->vcsManager()->findVersionControlForDirectory(dir)) {
-        const QString files = fileNames.join("\n");
-        QMessageBox::StandardButton button =
+    if (Core::IVersionControl *vcManager = m_core->vcsManager()->findVersionControlForDirectory(dir))
+        if (vcManager->supportsOperation(Core::IVersionControl::AddOperation)) {
+            const QString files = fileNames.join(QString(QLatin1Char('\n')));
+            QMessageBox::StandardButton button =
                 QMessageBox::question(m_core->mainWindow(), tr("Add to Version Control"),
-                                      tr("Add files\n%1\nto version control?").arg(files),
+                                      tr("Add files\n%1\nto version control (%2)?").arg(files, vcManager->name()),
                                       QMessageBox::Yes | QMessageBox::No);
-        if (button == QMessageBox::Yes) {
-           QStringList notAddedToVc;
-            foreach (const QString file, fileNames) {
-                if (!vcManager->vcsAdd(file))
-                    notAddedToVc << file;
-            }
+            if (button == QMessageBox::Yes) {
+                QStringList notAddedToVc;
+                foreach (const QString &file, fileNames) {
+                    if (!vcManager->vcsAdd(file))
+                        notAddedToVc << file;
+                }
 
-            if (!notAddedToVc.isEmpty()) {
-                const QString message = tr("Could not add following files to version control\n");
-                const QString filesNotAdded = notAddedToVc.join("\n");
-                QMessageBox::warning(m_core->mainWindow(), tr("Add files to version control failed"),
-                                 message + filesNotAdded);
+                if (!notAddedToVc.isEmpty()) {
+                    const QString message = tr("Could not add following files to version control (%1)\n").arg(vcManager->name());
+                    const QString filesNotAdded = notAddedToVc.join(QString(QLatin1Char('\n')));
+                    QMessageBox::warning(m_core->mainWindow(), tr("Add files to version control failed"),
+                                         message + filesNotAdded);
+                }
             }
         }
-    }
 }
 
 void ProjectExplorerPlugin::openFile()
diff --git a/src/plugins/projectexplorer/projectexplorer.h b/src/plugins/projectexplorer/projectexplorer.h
index 039def13052347ccb61ab58c3f14cca361224902..6a7f4beb83119b92c5756cd744430a9c720b2b9c 100644
--- a/src/plugins/projectexplorer/projectexplorer.h
+++ b/src/plugins/projectexplorer/projectexplorer.h
@@ -139,7 +139,6 @@ private slots:
     void cancelBuild();
     void debugProject();
     void editDependencies();
-    bool saveAction(ProjectExplorer::Project *pro = 0);
     void loadAction();
     void unloadProject();
     void clearSession();
diff --git a/src/plugins/projectexplorer/projectfilewizardextension.cpp b/src/plugins/projectexplorer/projectfilewizardextension.cpp
index 2cd220ef58e3e9c1eb4cf7b39699871d92098718..7445d4799c7e7a304d421f6ce4545e2bf084eaaf 100644
--- a/src/plugins/projectexplorer/projectfilewizardextension.cpp
+++ b/src/plugins/projectexplorer/projectfilewizardextension.cpp
@@ -118,7 +118,11 @@ void ProjectFileWizardExtension::firstExtensionPageShown(const QList<Core::Gener
     m_context->versionControl = m_core->vcsManager()->findVersionControlForDirectory(directory);
 
     m_context->page->setFilesDisplay(fileNames);
-    m_context->page->setAddToVersionControlEnabled(m_context->versionControl != 0);
+
+    const bool canAddToVCS = m_context->versionControl && m_context->versionControl->supportsOperation(Core::IVersionControl::AddOperation);
+    if (m_context->versionControl)
+         m_context->page->setVCSDisplay(m_context->versionControl->name());
+    m_context->page->setAddToVersionControlEnabled(canAddToVCS);
 }
 
 static ProjectNode *currentProject()
diff --git a/src/plugins/projectexplorer/projectwizardpage.cpp b/src/plugins/projectexplorer/projectwizardpage.cpp
index 8a2873c336db953bbfc3e2eac0a00938683f5518..8912fbb9e948e02c1c505fd56b8ca699cb8f9aab 100644
--- a/src/plugins/projectexplorer/projectwizardpage.cpp
+++ b/src/plugins/projectexplorer/projectwizardpage.cpp
@@ -108,6 +108,11 @@ void ProjectWizardPage::changeEvent(QEvent *e)
     }
 }
 
+void ProjectWizardPage::setVCSDisplay(const QString &vcsName)
+{
+    m_ui->addToVersionControlLabel->setText(tr("Add to &VCS (%1)").arg(vcsName));
+}
+
 void ProjectWizardPage::setFilesDisplay(const QStringList &files)
 {
     QString fileMessage; {
diff --git a/src/plugins/projectexplorer/projectwizardpage.h b/src/plugins/projectexplorer/projectwizardpage.h
index 2031923d37c8a3c7adf4404c321f931f7e490463..bc86bb6fa7eccc52ca0af34bf910a78077a29f2a 100644
--- a/src/plugins/projectexplorer/projectwizardpage.h
+++ b/src/plugins/projectexplorer/projectwizardpage.h
@@ -69,6 +69,7 @@ public:
     bool addToVersionControl() const;
     void setAddToVersionControlEnabled(bool b);
 
+    void setVCSDisplay(const QString &vcsName);
     void setFilesDisplay(const QStringList &files);
 
 protected:
diff --git a/src/plugins/projectexplorer/session.cpp b/src/plugins/projectexplorer/session.cpp
index 61ca7df05a9a705c0cb84867e9810a44ba2d6ecf..876b8294a377c0ca72f49d88e2823ca8309acd2c 100644
--- a/src/plugins/projectexplorer/session.cpp
+++ b/src/plugins/projectexplorer/session.cpp
@@ -939,6 +939,7 @@ void SessionManager::removeProjects(QList<Project *> remove)
 
     // Delete projects
     foreach (Project *pro, remove) {
+        pro->saveSettings();
         m_file->m_projects.removeOne(pro);
 
         if (pro == m_file->m_startupProject)
diff --git a/src/plugins/projectexplorer/taskwindow.cpp b/src/plugins/projectexplorer/taskwindow.cpp
index b69d37541ee4d54865089981e68abb3ced71d249..309e8ab983693116aff611f19822792519565785 100644
--- a/src/plugins/projectexplorer/taskwindow.cpp
+++ b/src/plugins/projectexplorer/taskwindow.cpp
@@ -37,6 +37,7 @@
 #include <coreplugin/actionmanager/actionmanager.h>
 #include <coreplugin/editormanager/editormanager.h>
 #include <coreplugin/coreconstants.h>
+#include <coreplugin/uniqueidmanager.h>
 #include <texteditor/itexteditor.h>
 #include <texteditor/basetexteditor.h>
 #include <projectexplorerconstants.h>
@@ -47,6 +48,8 @@
 #include <QtGui/QListView>
 #include <QtGui/QPainter>
 #include <QtCore/QAbstractItemModel>
+#include <QtGui/QApplication>
+#include <QtGui/QClipboard>
 #include <QtGui/QFont>
 #include <QtGui/QFontMetrics>
 #include <QtGui/QTextLayout>
@@ -81,7 +84,7 @@ public:
     QModelIndex firstError() const;
     void setFileNotFound(const QModelIndex &index, bool b);
 
-    enum Roles { File = Qt::UserRole, Line, Description, FileNotFound };
+    enum Roles { File = Qt::UserRole, Line, Description, FileNotFound, Type };
 private:
     QList<TaskItem> m_items;
     int m_maxSizeOfFileName;
@@ -196,6 +199,8 @@ QVariant TaskModel::data(const QModelIndex &index, int role) const
         return m_items.at(index.row()).description;
     else if (role == TaskModel::FileNotFound)
         return m_items.at(index.row()).fileNotFound;
+    else if (role == TaskModel::Type)
+        return (int)m_items.at(index.row()).type;
     else if (role == Qt::DecorationRole) {
          if (m_items.at(index.row()).type == ProjectExplorer::BuildParserInterface::Error) {
            return QIcon(":/projectexplorer/images/compile_error.png");
@@ -257,6 +262,15 @@ TaskWindow::TaskWindow()
     TaskDelegate *tld = new TaskDelegate(this);
     m_listview->setItemDelegate(tld);
     m_listview->setWindowIcon(QIcon(":/qt4projectmanager/images/window.png"));
+    m_listview->setContextMenuPolicy(Qt::ActionsContextMenu);
+
+    m_taskWindowContext = new TaskWindowContext(m_listview);
+    m_coreIFace->addContextObject(m_taskWindowContext);
+
+    m_copyAction = new QAction(QIcon(Core::Constants::ICON_COPY), tr("&Copy"), this);
+    m_coreIFace->actionManager()->
+            registerAction(m_copyAction, Core::Constants::COPY, m_taskWindowContext->context());
+    m_listview->addAction(m_copyAction);
 
     connect(m_listview->selectionModel(), SIGNAL(currentChanged(const QModelIndex &, const QModelIndex &)),
             tld, SLOT(currentChanged(const QModelIndex &, const QModelIndex &)));
@@ -266,12 +280,15 @@ TaskWindow::TaskWindow()
     connect(m_listview, SIGNAL(clicked(const QModelIndex &)),
             this, SLOT(showTaskInFile(const QModelIndex &)));
 
+    connect(m_copyAction, SIGNAL(triggered()), SLOT(copy()));
+
     m_errorCount = 0;
     m_currentTask = -1;
 }
 
 TaskWindow::~TaskWindow()
 {
+    m_coreIFace->removeContextObject(m_taskWindowContext);
     delete m_listview;
     delete m_model;
 }
@@ -291,6 +308,7 @@ void TaskWindow::clearContents()
     m_errorCount = 0;
     m_currentTask = -1;
     m_model->clear();
+    m_copyAction->setEnabled(false);
     emit tasksChanged();
 }
 
@@ -305,6 +323,7 @@ void TaskWindow::addItem(ProjectExplorer::BuildParserInterface::PatternType type
     m_model->addTask(type, description, file, line);
     if (type == ProjectExplorer::BuildParserInterface::Error)
         ++m_errorCount;
+    m_copyAction->setEnabled(true);
     emit tasksChanged();
 }
 
@@ -327,6 +346,25 @@ void TaskWindow::showTaskInFile(const QModelIndex &index)
     m_listview->selectionModel()->select(index, QItemSelectionModel::ClearAndSelect);
 }
 
+void TaskWindow::copy()
+{
+    QModelIndex index = m_listview->selectionModel()->currentIndex();
+    QString file = index.data(TaskModel::File).toString();
+    QString line = index.data(TaskModel::Line).toString();
+    QString description = index.data(TaskModel::Description).toString();
+    QString type;
+    switch (index.data(TaskModel::Type).toInt()) {
+    case ProjectExplorer::BuildParserInterface::Error:
+        type = "error: ";
+        break;
+    case ProjectExplorer::BuildParserInterface::Warning:
+        type = "warning: ";
+        break;
+    }
+
+    QApplication::clipboard()->setText(file + ':' + line + ": " + type + description);
+}
+
 int TaskWindow::numberOfTasks() const
 {
     return m_model->rowCount(QModelIndex());
@@ -483,7 +521,7 @@ void TaskDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option,
             painter->fillRect(width, 2 + opt.rect.top(), gwidth, fm.height() + 1, lg);
         }
     } else {
-        // Descritption
+        // Description
         QString description = index.data(TaskModel::Description).toString();
         // Layout the description
         int leading = fm.leading();
@@ -536,3 +574,21 @@ void TaskDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option,
     painter->drawLine(0, opt.rect.bottom(), opt.rect.right(), opt.rect.bottom());
     painter->restore();
 }
+
+TaskWindowContext::TaskWindowContext(QWidget *widget)
+    : m_taskList(widget)
+{
+    Core::ICore *core = ExtensionSystem::PluginManager::instance()->getObject<Core::ICore>();
+    m_context << core->uniqueIDManager()->uniqueIdentifier(Core::Constants::C_PROBLEM_PANE);
+}
+
+QList<int> TaskWindowContext::context() const
+{
+    return m_context;
+}
+
+QWidget *TaskWindowContext::widget()
+{
+    return m_taskList;
+}
+
diff --git a/src/plugins/projectexplorer/taskwindow.h b/src/plugins/projectexplorer/taskwindow.h
index efd2752469e24ad2a0af89b4103382a4e23d9c92..702534115309eb1b95c137dd9c34025faa5f42af 100644
--- a/src/plugins/projectexplorer/taskwindow.h
+++ b/src/plugins/projectexplorer/taskwindow.h
@@ -37,6 +37,7 @@
 #include "buildparserinterface.h"
 
 #include <coreplugin/ioutputpane.h>
+#include <coreplugin/icontext.h>
 #include <coreplugin/icore.h>
 
 #include <QtGui/QTreeWidget>
@@ -49,6 +50,7 @@ namespace Internal {
 
 class TaskModel;
 class TaskView;
+class TaskWindowContext;
 
 class TaskWindow : public Core::IOutputPane
 {
@@ -82,6 +84,7 @@ signals:
 
 private slots:
     void showTaskInFile(const QModelIndex &index);
+    void copy();
 
 private:
     int sizeHintForColumn(int column) const;
@@ -92,6 +95,8 @@ private:
 
     TaskModel *m_model;
     TaskView *m_listview;
+    TaskWindowContext *m_taskWindowContext;
+    QAction *m_copyAction;
 };
 
 class TaskView : public QListView
@@ -122,6 +127,17 @@ private:
     void generateGradientPixmap(int width, int height, QColor color, bool selected) const;
 };
 
+class TaskWindowContext : public Core::IContext
+{
+public:
+    TaskWindowContext(QWidget *widget);
+    virtual QList<int> context() const;
+    virtual QWidget *widget();
+private:
+    QWidget *m_taskList;
+    QList<int> m_context;
+};
+
 } //namespace Internal
 } //namespace ProjectExplorer
 
diff --git a/src/plugins/qt4projectmanager/gccparser.cpp b/src/plugins/qt4projectmanager/gccparser.cpp
index de69904ac80d66807e82b6316a839d326b0356d7..a208fc63052dfb4accd20b768ead5ee18aa5cda3 100644
--- a/src/plugins/qt4projectmanager/gccparser.cpp
+++ b/src/plugins/qt4projectmanager/gccparser.cpp
@@ -40,13 +40,13 @@ using namespace Qt4ProjectManager;
 
 GccParser::GccParser()
 {
-    m_regExp.setPattern("^([^\\(\\)]+[^\\d]):(\\d+):(\\d+:)*(\\s(warning|error):)?(.+)$");
+    m_regExp.setPattern("^([^\\(\\)]+[^\\d]):(\\d+):(\\d+:)*(\\s(warning|error):)?\\s(.+)$");
     m_regExp.setMinimal(true);
 
     m_regExpIncluded.setPattern("^.*from\\s([^:]+):(\\d+)(,|:)$");
     m_regExpIncluded.setMinimal(true);
 
-    m_regExpLinker.setPattern("^(\\S+)\\(\\S+\\):(.+)$");
+    m_regExpLinker.setPattern("^(\\S+)\\(\\S+\\):\\s(.+)$");
     m_regExpLinker.setMinimal(true);
 
     //make[4]: Entering directory `/home/kkoehne/dev/ide-explorer/src/plugins/qtscripteditor'
diff --git a/src/plugins/qt4projectmanager/qmakestep.cpp b/src/plugins/qt4projectmanager/qmakestep.cpp
index 44654496dc84eb867020f20abe7dfdf4217261ad..44780a7dcc5584ce297475f637b1a619e41235dd 100644
--- a/src/plugins/qt4projectmanager/qmakestep.cpp
+++ b/src/plugins/qt4projectmanager/qmakestep.cpp
@@ -159,7 +159,6 @@ bool QMakeStep::init(const QString &name)
     setCommand(name, program);
     setArguments(name, args);
     setEnvironment(name, environment);
-    setWorkingDirectory(name, workingDirectory);
     return AbstractProcessStep::init(name);
 }
 
diff --git a/src/plugins/qt4projectmanager/qt4nodes.cpp b/src/plugins/qt4projectmanager/qt4nodes.cpp
index 672ce8b835b9077fd5ae28c743231979b39b1304..8c4010aac5ea9603646b662d3faed8e80ddba377 100644
--- a/src/plugins/qt4projectmanager/qt4nodes.cpp
+++ b/src/plugins/qt4projectmanager/qt4nodes.cpp
@@ -84,7 +84,7 @@ Qt4PriFileNode::Qt4PriFileNode(Qt4Project *project,
         : ProjectNode(filePath),
           m_core(project->qt4ProjectManager()->core()),
           m_project(project),
-          m_projectFilePath(filePath),
+          m_projectFilePath(QDir::fromNativeSeparators(filePath)),
           m_projectDir(QFileInfo(filePath).absolutePath()),
           m_includeFile(0),
           m_saveTimer(new QTimer(this)),
@@ -265,46 +265,18 @@ bool Qt4PriFileNode::changeIncludes(ProFile *includeFile, const QStringList &pro
     return false;
 }
 
-
-namespace {
-    enum ReadOnlyAction { RO_Cancel, RO_OpenSCC, RO_MakeWriteable };
-}
-
-static ReadOnlyAction promptReadOnly(const QString &fileName, bool hasSCC, QWidget *parent)
-{
-    QMessageBox msgBox(QMessageBox::Question, QObject::tr("File is Read Only"),
-                       QObject::tr("The file %1 is read only.").arg(fileName),
-                       QMessageBox::Cancel, parent);
-
-    QPushButton *sccButton = 0;
-    if (hasSCC)
-        sccButton = msgBox.addButton(QObject::tr("Open with SCC"), QMessageBox::AcceptRole);
-    QPushButton *makeWritableButton =  msgBox.addButton(QObject::tr("Make writable"), QMessageBox::AcceptRole);
-    if (hasSCC)
-        msgBox.setDefaultButton(sccButton);
-    else
-        msgBox.setDefaultButton(makeWritableButton);
-    msgBox.exec();
-    QAbstractButton *clickedButton = msgBox.clickedButton();
-    if (clickedButton == sccButton)
-        return RO_OpenSCC;
-    if (clickedButton == makeWritableButton)
-        return RO_MakeWriteable;
-    return  RO_Cancel;
-}
-
 bool Qt4PriFileNode::priFileWritable(const QString &path)
 {
     const QString dir = QFileInfo(path).dir().path();
     Core::IVersionControl *versionControl = m_core->vcsManager()->findVersionControlForDirectory(dir);
-    switch (promptReadOnly(path, versionControl != 0, m_core->mainWindow())) {
-    case RO_OpenSCC:
+    switch (Core::EditorManager::promptReadOnlyFile(path, versionControl, m_core->mainWindow(), false)) {
+    case Core::EditorManager::RO_OpenVCS:
         if (!versionControl->vcsOpen(path)) {
             QMessageBox::warning(m_core->mainWindow(), tr("Failed!"), tr("Could not open the file for edit with SCC."));
             return false;
         }
         break;
-    case RO_MakeWriteable: {
+    case Core::EditorManager::RO_MakeWriteable: {
         const bool permsOk = QFile::setPermissions(path, QFile::permissions(path) | QFile::WriteUser);
         if (!permsOk) {
             QMessageBox::warning(m_core->mainWindow(), tr("Failed!"),  tr("Could not set permissions to writable."));
@@ -312,10 +284,10 @@ bool Qt4PriFileNode::priFileWritable(const QString &path)
         }
         break;
     }
-    case RO_Cancel: {
+    case Core::EditorManager::RO_SaveAs:
+    case Core::EditorManager::RO_Cancel:
         return false;
     }
-    }
     return true;
 }
 
@@ -457,7 +429,8 @@ void Qt4PriFileNode::save()
     if (modifiedFileHandle)
         fileManager->blockFileChange(modifiedFileHandle);
     ProWriter pw;
-    bool ok = pw.write(m_includeFile, m_includeFile->fileName());
+    const bool ok = pw.write(m_includeFile, m_includeFile->fileName());
+    Q_UNUSED(ok)
     m_includeFile->setModified(false);
     m_project->qt4ProjectManager()->notifyChanged(m_includeFile->fileName());
     if (modifiedFileHandle)
diff --git a/src/plugins/qt4projectmanager/wizards/consoleappwizarddialog.cpp b/src/plugins/qt4projectmanager/wizards/consoleappwizarddialog.cpp
index 14965f50187675bf5c69cec9cc2ddc79032c16ff..1090673284f08a4d50278b104b826541e71c9208 100644
--- a/src/plugins/qt4projectmanager/wizards/consoleappwizarddialog.cpp
+++ b/src/plugins/qt4projectmanager/wizards/consoleappwizarddialog.cpp
@@ -35,6 +35,7 @@
 #include "consoleappwizard.h"
 #include "modulespage.h"
 
+#include <QtCore/QDebug>
 #include <utils/projectintropage.h>
 
 namespace Qt4ProjectManager {
@@ -51,13 +52,11 @@ ConsoleAppWizardDialog::ConsoleAppWizardDialog(const QString &templateName,
     setWindowIcon(icon);
     setWindowTitle(templateName);
     Core::BaseFileWizard::setupWizard(this);
-    setOptions(QWizard::IndependentPages | QWizard::HaveNextButtonOnLastPage);
 
     m_introPage->setDescription(tr("This wizard generates a Qt4 console application "
                           "project. The application derives from QCoreApplication and does not "
                           "present a GUI. You can press 'Finish' at any point in time."));
 
-    m_introPage->setFinalPage(true);
     addPage(m_introPage);
 
     m_modulesPage->setModuleSelected(QLatin1String("core"));
diff --git a/src/plugins/qt4projectmanager/wizards/guiappwizarddialog.cpp b/src/plugins/qt4projectmanager/wizards/guiappwizarddialog.cpp
index 7b1ba073d34e6203a1f2cb720d6dafac79c2faed..621a3b6ba92072de3d411f1713ac6515166102c6 100644
--- a/src/plugins/qt4projectmanager/wizards/guiappwizarddialog.cpp
+++ b/src/plugins/qt4projectmanager/wizards/guiappwizarddialog.cpp
@@ -63,7 +63,6 @@ GuiAppWizardDialog::GuiAppWizardDialog(const QString &templateName,
     setWindowIcon(icon);
     setWindowTitle(templateName);
     Core::BaseFileWizard::setupWizard(this);
-    setOptions(QWizard::IndependentPages);
 
     m_introPage->setDescription(tr("This wizard generates a Qt4 GUI application "
          "project. The application derives by default from QApplication "
diff --git a/src/plugins/subversion/subversioncontrol.cpp b/src/plugins/subversion/subversioncontrol.cpp
index ba2a2f2e8e92dcfa8b5af88c36b308418aa05f32..56ad229954743e3719088985e4eecc15be726919 100644
--- a/src/plugins/subversion/subversioncontrol.cpp
+++ b/src/plugins/subversion/subversioncontrol.cpp
@@ -38,10 +38,43 @@ using namespace Subversion;
 using namespace Subversion::Internal;
 
 SubversionControl::SubversionControl(SubversionPlugin *plugin) :
+    m_enabled(true),
     m_plugin(plugin)
 {
 }
 
+QString SubversionControl::name() const
+{
+    return QLatin1String("subversion");
+}
+
+bool SubversionControl::isEnabled() const
+{
+     return m_enabled;
+}
+
+void SubversionControl::setEnabled(bool enabled)
+{
+    if (m_enabled != enabled) {
+        m_enabled = enabled;
+        emit enabledChanged(m_enabled);
+    }
+}
+
+bool SubversionControl::supportsOperation(Operation operation) const
+{
+    bool rc = true;
+    switch (operation) {
+    case AddOperation:
+    case DeleteOperation:
+        break;
+    case OpenOperation:
+        rc = false;
+        break;
+    }
+    return rc;
+}
+
 bool SubversionControl::vcsOpen(const QString & /* fileName */)
 {
     // Open for edit: N/A
diff --git a/src/plugins/subversion/subversioncontrol.h b/src/plugins/subversion/subversioncontrol.h
index f293852a3a11e4917dd912d1d767ef324ef8afd4..c4a2f8aa79c69d5145438a9182fd6737821e1443 100644
--- a/src/plugins/subversion/subversioncontrol.h
+++ b/src/plugins/subversion/subversioncontrol.h
@@ -47,13 +47,24 @@ class SubversionControl : public Core::IVersionControl
     Q_OBJECT
 public:
     explicit SubversionControl(SubversionPlugin *plugin);
+    virtual QString name() const;
+
+    virtual bool isEnabled() const;
+    virtual void setEnabled(bool enabled);
+
     virtual bool managesDirectory(const QString &directory) const;
     virtual QString findTopLevelForDirectory(const QString &directory) const;
+
+    virtual bool supportsOperation(Operation operation) const;
     virtual bool vcsOpen(const QString &fileName);
     virtual bool vcsAdd(const QString &fileName);
     virtual bool vcsDelete(const QString &filename);
 
+signals:
+    void enabledChanged(bool);
+
 private:
+    bool m_enabled;
     SubversionPlugin *m_plugin;
 };
 
diff --git a/src/plugins/subversion/subversionplugin.cpp b/src/plugins/subversion/subversionplugin.cpp
index 6532a9d43357775f8de4e8ba199f447c60039979..a24bb7d3d06bbb0e652143e6a73cc134332f97a1 100644
--- a/src/plugins/subversion/subversionplugin.cpp
+++ b/src/plugins/subversion/subversionplugin.cpp
@@ -276,6 +276,10 @@ bool SubversionPlugin::initialize(const QStringList & /*arguments*/, QString *er
         ami->createMenu(QLatin1String(SUBVERSION_MENU));
     subversionMenu->menu()->setTitle(tr("&Subversion"));
     toolsContainer->addMenu(subversionMenu);
+    if (QAction *ma = subversionMenu->menu()->menuAction()) {
+        ma->setEnabled(m_versionControl->isEnabled());
+        connect(m_versionControl, SIGNAL(enabledChanged(bool)), ma, SLOT(setVisible(bool)));
+    }
 
     QList<int> globalcontext;
     globalcontext << m_coreInstance->uniqueIDManager()->uniqueIdentifier(C_GLOBAL);
diff --git a/src/plugins/texteditor/basefilefind.cpp b/src/plugins/texteditor/basefilefind.cpp
index 43606bf205a5cab80cde45f9f9a00f806404ba2d..4811e4e4c18454cc8b4eca3637e49e2092e352a8 100644
--- a/src/plugins/texteditor/basefilefind.cpp
+++ b/src/plugins/texteditor/basefilefind.cpp
@@ -146,7 +146,7 @@ QWidget *BaseFileFind::createPatternWidget()
 */
     QString filterToolTip = tr("List of comma separated wildcard filters");
 /*
-    QLabel *label = new QLabel(tr("File pattern:"));
+    QLabel *label = new QLabel(tr("File &pattern:"));
     label->setToolTip(filterToolTip);
 */
 /*
@@ -163,6 +163,7 @@ QWidget *BaseFileFind::createPatternWidget()
     m_filterCombo->setToolTip(filterToolTip);
     syncComboWithSettings(m_filterCombo, m_filterSetting);
 /*
+    label->setBuddy(m_filterCombo);
     hlayout->addWidget(m_filterCombo);
 */
     return m_filterCombo;
@@ -170,7 +171,7 @@ QWidget *BaseFileFind::createPatternWidget()
 
 QWidget *BaseFileFind::createRegExpWidget()
 {
-    m_useRegExpCheckBox = new QCheckBox(tr("Use Regular Expressions"));
+    m_useRegExpCheckBox = new QCheckBox(tr("Use Regular E&xpressions"));
     m_useRegExpCheckBox->setChecked(m_useRegExp);
     connect(m_useRegExpCheckBox, SIGNAL(toggled(bool)), this, SLOT(syncRegExpSetting(bool)));
     return m_useRegExpCheckBox;
diff --git a/src/plugins/texteditor/basetexteditor.cpp b/src/plugins/texteditor/basetexteditor.cpp
index 4dda8f7b952265305a7198a9d2ffd8dd1f1417ee..1e6a266e6da886b16eb0f7ec44c1fddd12c9cdcd 100644
--- a/src/plugins/texteditor/basetexteditor.cpp
+++ b/src/plugins/texteditor/basetexteditor.cpp
@@ -502,7 +502,8 @@ void BaseTextEditor::currentEditorChanged(Core::IEditor *editor)
     if (editor == d->m_editable) {
         if (d->m_document->hasDecodingError()) {
             Core::EditorManager::instance()->showEditorInfoBar(QLatin1String(Constants::SELECT_ENCODING),
-                tr("<b>Error:</b> Could not decode \"%1\" with \"%2\"-encoding. Editing not possible.").arg(displayName()).arg(QString::fromLatin1(d->m_document->codec()->name())),
+                tr("<b>Error:</b> Could not decode \"%1\" with \"%2\"-encoding. Editing not possible.")
+                    .arg(displayName()).arg(QString::fromLatin1(d->m_document->codec()->name())),
                 tr("Select Encoding"),
                 this, SLOT(selectEncoding()));
         }
diff --git a/src/plugins/texteditor/findinfiles.cpp b/src/plugins/texteditor/findinfiles.cpp
index 55ecd01e5ad380b7589dabd2c52b86ecbef77b2e..a67dbebe11065c0b7ad2c4e4e8fc5bbd633c8b6b 100644
--- a/src/plugins/texteditor/findinfiles.cpp
+++ b/src/plugins/texteditor/findinfiles.cpp
@@ -88,7 +88,8 @@ QWidget *FindInFiles::createConfigWidget()
         m_configWidget->setLayout(gridLayout);
         gridLayout->addWidget(createRegExpWidget(), 0, 1, 1, 2);
 
-        gridLayout->addWidget(new QLabel(tr("Directory:")), 1, 0, Qt::AlignRight);
+        QLabel *dirLabel = new QLabel(tr("&Directory:"));
+        gridLayout->addWidget(dirLabel, 1, 0, Qt::AlignRight);
         m_directory = new QComboBox;
         m_directory->setEditable(true);
         m_directory->setMaxCount(30);
@@ -98,17 +99,20 @@ QWidget *FindInFiles::createConfigWidget()
         m_directory->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
         m_directory->setModel(&m_directoryStrings);
         syncComboWithSettings(m_directory, m_directorySetting);
+        dirLabel->setBuddy(m_directory);
         gridLayout->addWidget(m_directory, 1, 1);
-        QPushButton *browseButton = new QPushButton(tr("Browse"));
+        QPushButton *browseButton = new QPushButton(tr("&Browse"));
         gridLayout->addWidget(browseButton, 1, 2);
         connect(browseButton, SIGNAL(clicked()), this, SLOT(openFileBrowser()));
 
-        QLabel * const filePatternLabel = new QLabel(tr("File pattern:"));
+        QLabel * const filePatternLabel = new QLabel(tr("File &pattern:"));
         filePatternLabel->setMinimumWidth(80);
         filePatternLabel->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Preferred);
         filePatternLabel->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
+        QWidget *patternWidget = createPatternWidget();
+        filePatternLabel->setBuddy(patternWidget);
         gridLayout->addWidget(filePatternLabel, 2, 0);
-        gridLayout->addWidget(createPatternWidget(), 2, 1, 1, 2);
+        gridLayout->addWidget(patternWidget, 2, 1, 1, 2);
         m_configWidget->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
     }
     return m_configWidget;