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/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/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/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 1593847ef858a8d992ce95d4d83868a677d7a3c0..29798b25c010e9202f09cd2c27d38e6278ff9900 100644
--- a/src/plugins/coreplugin/editormanager/editormanager.cpp
+++ b/src/plugins/coreplugin/editormanager/editormanager.cpp
@@ -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/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/cpptools/cppmodelmanager.cpp b/src/plugins/cpptools/cppmodelmanager.cpp
index 1708e62de35b26c5aae7bf7c25d4f5129505278b..ccaff0bcfe5cf2e40a43a815004953f11c9a3607 100644
--- a/src/plugins/cpptools/cppmodelmanager.cpp
+++ b/src/plugins/cpptools/cppmodelmanager.cpp
@@ -253,6 +253,25 @@ protected:
         m_currentDoc->appendMacro(macroName, macroText);
     }
 
+    virtual void startExpandingMacro(unsigned offset,
+                                     const rpp::Macro &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 offset, const rpp::Macro &macro)
+    {
+        if (! m_currentDoc)
+            return;
+
+        //qDebug() << "stop expanding:" << macro.name;
+    }
+
     void mergeEnvironment(Document::Ptr doc)
     {
         QSet<QString> processed;
@@ -505,7 +524,7 @@ 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,
@@ -595,6 +614,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);
@@ -657,6 +692,8 @@ void CppModelManager::parse(QFutureInterface<void> &future,
                             QStringList files,
                             QMap<QString, QByteArray> workingCopy)
 {
+    Q_ASSERT(! files.isEmpty());
+
     // Change the priority of the background parser thread to idle.
     QThread::currentThread()->setPriority(QThread::IdlePriority);
 
@@ -698,6 +735,8 @@ void CppModelManager::parse(QFutureInterface<void> &future,
 #endif
     }
 
+    future.setProgressValue(files.size());
+
     // Restore the previous thread priority.
     QThread::currentThread()->setPriority(QThread::NormalPriority);
 }
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/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..42551168fe20e1e72e0e934797bfd9c7b0c16ffe 100644
--- a/src/plugins/debugger/debuggermanager.cpp
+++ b/src/plugins/debugger/debuggermanager.cpp
@@ -622,7 +622,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/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..7d87ce27827838b4971155378b8b4281695a5151 100644
--- a/src/plugins/git/gitclient.cpp
+++ b/src/plugins/git/gitclient.cpp
@@ -49,6 +49,7 @@
 #include <QtCore/QRegExp>
 #include <QtCore/QTemporaryFile>
 #include <QtCore/QFuture>
+#include <QtCore/QTime>
 
 #include <QtGui/QErrorMessage>
 
@@ -76,22 +77,25 @@ inline Core::IEditor* locateEditor(const Core::ICore *core, const char *property
     return 0;
 }
 
+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(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 +180,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 +198,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 +225,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 +241,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 +256,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 +270,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 +280,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 +288,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,8 +303,8 @@ 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;
 }
@@ -317,14 +320,14 @@ 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);
+        m_plugin->outputWindow()->append(errorMessage);
         return false;
     }
     return true;
@@ -336,13 +339,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) {
@@ -368,16 +372,19 @@ bool GitClient::synchronousGit(const QString &workingDirectory
 {
     if (Git::Constants::debug)
         qDebug() << "synchronousGit" << workingDirectory << arguments;
-    QProcess process;
+    const QString binary = QLatin1String(kGitCommand);
 
+    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 +418,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:
@@ -482,6 +517,9 @@ bool GitClient::getCommitData(const QString &workingDirectory,
                               CommitData *d,
                               QString *errorMessage)
 {
+    if (Git::Constants::debug)
+        qDebug() << Q_FUNC_INFO << workingDirectory;
+
     d->clear();
 
     // Find repo
@@ -508,23 +546,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 = tr("There are no modified files.");
+        return false;
+    case StatusFailed:
+        return false;
     }
 
     //    Output looks like:
@@ -545,7 +575,7 @@ bool GitClient::getCommitData(const QString &workingDirectory,
     //    #
     //    #       list of files...
 
-    const QStringList lines = QString::fromLocal8Bit(outputText).remove(QLatin1Char('\r')).split(QLatin1Char('\n'));
+    const QStringList lines = output.split(QLatin1Char('\n'));
     if (!parseFiles(lines, d)) {
         *errorMessage = tr("Unable to parse the file output.");
         return false;
@@ -570,24 +600,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 +628,64 @@ 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;
 }
 
 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);
+}
+
+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(tr("There are no modified files."));
+        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)
@@ -635,6 +705,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..5be276a7877f6d1f1fc82149d74fe0f812b74017 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(); }
 
@@ -94,6 +93,11 @@ public:
     void pull(const QString &workingDirectory);
     void push(const QString &workingDirectory);
 
+    void stash(const QString &workingDirectory);
+    void stashPop(const QString &workingDirectory);
+    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,10 +113,19 @@ public:
                       const QStringList &checkedFiles,
                       const QStringList &origCommitFiles);
 
+    GitSettings  settings() const;
+    void setSettings(const GitSettings &s);
+
 public slots:
     void show(const QString &source, const QString &id);
 
 private:
+    enum StatusResult { StatusChanged, StatusUnchanged, StatusFailed };
+    StatusResult gitStatus(const QString &workingDirectory,
+                           bool untracked,
+                           QString *output = 0,
+                           QString *errorMessage = 0);
+
     VCSBase::VCSBaseEditor *createVCSEditor(const QString &kind,
                                                  QString title,
                                                  const QString &source,
@@ -135,6 +148,7 @@ private:
     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..ef57b9bb12a830b97c6870e2aadb7889a47ff04b 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"
@@ -125,6 +126,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 +137,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 +176,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 +210,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 +256,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 +269,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);
@@ -291,10 +318,7 @@ bool GitPlugin::initialize(const QStringList &arguments, QString *error_message)
     connect(m_addAction, SIGNAL(triggered()), this, SLOT(addFile()));
     gitContainer->addAction(command);
 
-    tmpaction = new QAction(this);
-    tmpaction->setSeparator(true);
-    command = actionManager->registerAction(tmpaction, QLatin1String("Git.Sep.Project"), globalcontext);
-    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);
@@ -322,15 +346,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 +375,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 +431,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 +454,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);
@@ -627,26 +669,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));
@@ -684,7 +752,7 @@ void GitPlugin::updateActions()
 
     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 +788,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..3da8ff26cec6c1ad194613864a02f330a7edf7a2 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);
@@ -115,12 +120,15 @@ private slots:
 
     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();
 
@@ -145,6 +153,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 +166,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/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/perforce/perforceplugin.cpp b/src/plugins/perforce/perforceplugin.cpp
index 7f71282fbbf71df8d7ea6d6bcef2e50c41073ce2..2de31700a867462dba9d8a17017cf8d81e990096 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;
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 1a9c24b994d3e11fa49d01769068d000309d8e81..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>
@@ -1153,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();
     }
@@ -1565,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/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/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/qt4nodes.cpp b/src/plugins/qt4projectmanager/qt4nodes.cpp
index e67172eb7fb362220584ee4d4153b2757229d8c0..8c4010aac5ea9603646b662d3faed8e80ddba377 100644
--- a/src/plugins/qt4projectmanager/qt4nodes.cpp
+++ b/src/plugins/qt4projectmanager/qt4nodes.cpp
@@ -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/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/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;