diff --git a/src/plugins/bazaar/bazaarplugin.cpp b/src/plugins/bazaar/bazaarplugin.cpp
index d61b0d2a55aae30d44f9517046ac01850ea667b8..1e369b18f5be020812992de7e9d9e76819412b47 100644
--- a/src/plugins/bazaar/bazaarplugin.cpp
+++ b/src/plugins/bazaar/bazaarplugin.cpp
@@ -163,7 +163,6 @@ bool BazaarPlugin::initialize(const QStringList &arguments, QString *errorMessag
     addAutoReleasedObject(m_optionsPage);
     m_bazaarSettings.readSettings(m_core->settings());
 
-    connect(m_optionsPage, SIGNAL(settingsChanged()), m_client, SLOT(handleSettingsChanged()));
     connect(m_client, SIGNAL(changed(QVariant)), versionControl(), SLOT(changed(QVariant)));
 
     static const char *describeSlot = SLOT(view(QString,QString));
diff --git a/src/plugins/mercurial/mercurialclient.cpp b/src/plugins/mercurial/mercurialclient.cpp
index 73bb5737c42203d5015706f1950ed9f3e075c0dc..6986af378cc5410ba8b4a201f5d911499b32215f 100644
--- a/src/plugins/mercurial/mercurialclient.cpp
+++ b/src/plugins/mercurial/mercurialclient.cpp
@@ -33,11 +33,11 @@
 #include "mercurialclient.h"
 #include "constants.h"
 
+#include <vcsbase/command.h>
 #include <vcsbase/vcsbaseoutputwindow.h>
 #include <vcsbase/vcsbaseplugin.h>
 #include <vcsbase/vcsbaseeditor.h>
 #include <vcsbase/vcsbaseeditorparameterwidget.h>
-#include <vcsbase/vcsjobrunner.h>
 #include <utils/synchronousprocess.h>
 #include <utils/fileutils.h>
 #include <utils/qtcassert.h>
@@ -277,12 +277,10 @@ void MercurialClient::incoming(const QString &repositoryRoot, const QString &rep
 
     VCSBase::VCSBaseEditorWidget *editor = createVCSEditor(kind, title, repositoryRoot,
                                                      true, "incoming", id);
-
-    QSharedPointer<VCSBase::VCSJob> job(new VCSBase::VCSJob(repositoryRoot, args, editor));
-    // Suppress SSH prompting.
+    VCSBase::Command *cmd = createCommand(repository, editor);
     if (!repository.isEmpty() && VCSBase::VCSBasePlugin::isSshPromptConfigured())
-        job->setUnixTerminalDisabled(true);
-    enqueueJob(job);
+        cmd->setUnixTerminalDisabled(true);
+    enqueueJob(cmd, args);
 }
 
 void MercurialClient::outgoing(const QString &repositoryRoot)
@@ -297,10 +295,9 @@ void MercurialClient::outgoing(const QString &repositoryRoot)
     VCSBase::VCSBaseEditorWidget *editor = createVCSEditor(kind, title, repositoryRoot, true,
                                                      "outgoing", repositoryRoot);
 
-    QSharedPointer<VCSBase::VCSJob> job(new VCSBase::VCSJob(repositoryRoot, args, editor));
-    // Suppress SSH prompting
-    job->setUnixTerminalDisabled(VCSBase::VCSBasePlugin::isSshPromptConfigured());
-    enqueueJob(job);
+    VCSBase::Command *cmd = createCommand(repositoryRoot, editor);
+    cmd->setUnixTerminalDisabled(VCSBase::VCSBasePlugin::isSshPromptConfigured());
+    enqueueJob(cmd, args);
 }
 
 void MercurialClient::annotate(const QString &workingDir, const QString &file,
diff --git a/src/plugins/mercurial/mercurialplugin.cpp b/src/plugins/mercurial/mercurialplugin.cpp
index 90e7271cd6cbc295b27a5c649027022e8fbb2eef..8c70e93b68494ee9c065ed4bdfcac456db29c98b 100644
--- a/src/plugins/mercurial/mercurialplugin.cpp
+++ b/src/plugins/mercurial/mercurialplugin.cpp
@@ -166,8 +166,6 @@ bool MercurialPlugin::initialize(const QStringList & /* arguments */, QString *
     addAutoReleasedObject(optionsPage);
     mercurialSettings.readSettings(core->settings());
 
-    connect(optionsPage, SIGNAL(settingsChanged()), m_client, SLOT(handleSettingsChanged()));
-
     connect(m_client, SIGNAL(changed(QVariant)), versionControl(), SLOT(changed(QVariant)));
 
     static const char *describeSlot = SLOT(view(QString,QString));
diff --git a/src/plugins/vcsbase/command.cpp b/src/plugins/vcsbase/command.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..917a49aadd47780dbb71c217b3d8d94922e9d85c
--- /dev/null
+++ b/src/plugins/vcsbase/command.cpp
@@ -0,0 +1,340 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2010 Brian McGillion & Hugues Delorme
+**
+** Contact: Nokia Corporation (info@qt.nokia.com)
+**
+**
+** GNU Lesser General Public License Usage
+**
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this file.
+** Please review the following information to ensure the GNU Lesser General
+** Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** Other Usage
+**
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at info@qt.nokia.com.
+**
+**************************************************************************/
+
+#include "command.h"
+#include "vcsbaseconstants.h"
+
+#include <coreplugin/icore.h>
+#include <coreplugin/progressmanager/progressmanager.h>
+#include <extensionsystem/pluginmanager.h>
+#include <utils/synchronousprocess.h>
+
+#include <QtCore/QDebug>
+#include <QtCore/QProcess>
+#include <QtCore/QFuture>
+#include <QtCore/QtConcurrentRun>
+#include <QtCore/QFileInfo>
+#include <QtCore/QCoreApplication>
+
+Q_DECLARE_METATYPE(QVariant)
+
+namespace VCSBase {
+
+static QString msgTermination(int exitCode, const QString &binaryPath, const QStringList &args)
+{
+    QString cmd = QFileInfo(binaryPath).baseName();
+    if (!args.empty()) {
+        cmd += QLatin1Char(' ');
+        cmd += args.front();
+    }
+    return exitCode ?
+                QCoreApplication::translate("VcsCommand", "\n'%1' failed (exit code %2).\n").arg(cmd).arg(exitCode) :
+                QCoreApplication::translate("VcsCommand", "\n'%1' completed (exit code %2).\n").arg(cmd).arg(exitCode);
+}
+
+class CommandPrivate
+{
+public:
+    struct Job {
+        explicit Job(const QStringList &a, int t);
+
+        QStringList arguments;
+        int timeout;
+    };
+
+    CommandPrivate(const QString &binary,
+                   const QString &workingDirectory,
+                   const QProcessEnvironment &environment);
+
+    const QString m_binaryPath;
+    const QString m_workingDirectory;
+    const QProcessEnvironment m_environment;
+    QVariant m_cookie;
+    bool m_unixTerminalDisabled;
+    int m_defaultTimeout;
+
+    QList<Job> m_jobs;
+    Command::TerminationReportMode m_reportTerminationMode;
+
+    bool m_lastExecSuccess;
+    int m_lastExecExitCode;
+};
+
+CommandPrivate::CommandPrivate(const QString &binary,
+                               const QString &workingDirectory,
+                               const QProcessEnvironment &environment) :
+    m_binaryPath(binary),
+    m_workingDirectory(workingDirectory),
+    m_environment(environment),
+    m_unixTerminalDisabled(false),
+    m_defaultTimeout(10),
+    m_reportTerminationMode(Command::NoReport),
+    m_lastExecSuccess(false),
+    m_lastExecExitCode(-1)
+{
+}
+
+CommandPrivate::Job::Job(const QStringList &a, int t) :
+    arguments(a),
+    timeout(t)
+{
+    // Finished cookie is emitted via queued slot, needs metatype
+    static const int qvMetaId = qRegisterMetaType<QVariant>();
+    Q_UNUSED(qvMetaId)
+}
+
+Command::Command(const QString &binary,
+                 const QString &workingDirectory,
+                 const QProcessEnvironment &environment) :
+    d(new CommandPrivate(binary, workingDirectory, environment))
+{
+}
+
+Command::~Command()
+{
+    delete d;
+}
+
+const QString &Command::binaryPath() const
+{
+    return d->m_binaryPath;
+}
+
+const QString &Command::workingDirectory() const
+{
+    return d->m_workingDirectory;
+}
+
+const QProcessEnvironment &Command::processEnvironment() const
+{
+    return d->m_environment;
+}
+
+Command::TerminationReportMode Command::reportTerminationMode() const
+{
+    return d->m_reportTerminationMode;
+}
+
+void Command::setTerminationReportMode(TerminationReportMode m)
+{
+    d->m_reportTerminationMode = m;
+}
+
+int Command::defaultTimeout() const
+{
+    return d->m_defaultTimeout;
+}
+
+void Command::setDefaultTimeout(int timeout)
+{
+    d->m_defaultTimeout = timeout;
+}
+
+bool Command::unixTerminalDisabled() const
+{
+    return d->m_unixTerminalDisabled;
+}
+
+void Command::setUnixTerminalDisabled(bool e)
+{
+    d->m_unixTerminalDisabled = e;
+}
+
+void Command::addJob(const QStringList &arguments)
+{
+    addJob(arguments, defaultTimeout());
+}
+
+void Command::addJob(const QStringList &arguments, int timeout)
+{
+    d->m_jobs.push_back(CommandPrivate::Job(arguments, timeout));
+}
+
+void Command::execute()
+{
+    if (Constants::Internal::debug)
+        qDebug() << "Command::execute" << d->m_workingDirectory << d->m_jobs.size();
+
+    d->m_lastExecSuccess = false;
+    d->m_lastExecExitCode = -1;
+
+    if (d->m_jobs.empty())
+        return;
+
+    // For some reason QtConcurrent::run() only works on this
+    QFuture<void> task = QtConcurrent::run(this, &Command::run);
+    QString binary = QFileInfo(d->m_binaryPath).baseName();
+    if (!binary.isEmpty())
+        binary = binary.replace(0, 1, binary[0].toUpper()); // Upper the first letter
+    const QString taskName = binary + QLatin1Char(' ') + d->m_jobs.front().arguments.at(0);
+
+    Core::ICore::instance()->progressManager()->addTask(task, taskName, binary + QLatin1String(".action"));
+}
+
+bool Command::lastExecutionSuccess() const
+{
+    return d->m_lastExecSuccess;
+}
+
+int Command::lastExecutionExitCode() const
+{
+    return d->m_lastExecExitCode;
+}
+
+QString Command::msgTimeout(int seconds)
+{
+    return tr("Error: VCS timed out after %1s.").arg(seconds);
+}
+
+void Command::run()
+{
+    if (Constants::Internal::debug)
+        qDebug() << "Command::run" << workingDirectory() << d->m_jobs.size()
+                 << "terminal_disabled" << unixTerminalDisabled();
+
+    // Check that the binary path is not empty
+    if (binaryPath().trimmed().isEmpty()) {
+        emit errorText(tr("Unable to start process, binary is empty"));
+        return;
+    }
+
+    const unsigned processFlags = unixTerminalDisabled() ?
+                unsigned(Utils::SynchronousProcess::UnixTerminalDisabled) :
+                unsigned(0);
+    const QSharedPointer<QProcess> process = Utils::SynchronousProcess::createProcess(processFlags);
+    if (!workingDirectory().isEmpty())
+        process->setWorkingDirectory(workingDirectory());
+
+    process->setProcessEnvironment(processEnvironment());
+
+    QByteArray stdOut;
+    QByteArray stdErr;
+    QString error;
+
+    const int count = d->m_jobs.size();
+    int exitCode = -1;
+    bool ok = true;
+    for (int j = 0; j < count; j++) {
+        if (Constants::Internal::debug)
+            qDebug() << "Command::run" << j << '/' << count << d->m_jobs.at(j).arguments;
+
+        process->start(binaryPath(), d->m_jobs.at(j).arguments);
+        if (!process->waitForStarted()) {
+            ok = false;
+            error += QString::fromLatin1("Error: \"%1\" could not be started: %2")
+                    .arg(binaryPath(), process->errorString());
+            break;
+        }
+
+        process->closeWriteChannel();
+        const int timeOutSeconds = d->m_jobs.at(j).timeout;
+        if (!Utils::SynchronousProcess::readDataFromProcess(*process, timeOutSeconds * 1000,
+                                                            &stdOut, &stdErr, false)) {
+            Utils::SynchronousProcess::stopProcess(*process);
+            ok = false;
+            error += msgTimeout(timeOutSeconds);
+            break;
+        }
+
+        error += QString::fromLocal8Bit(stdErr);
+        exitCode = process->exitCode();
+        switch (reportTerminationMode()) {
+        case NoReport:
+            break;
+        case ReportStdout:
+            stdOut += msgTermination(exitCode, binaryPath(), d->m_jobs.at(j).arguments).toUtf8();
+            break;
+        case ReportStderr:
+            error += msgTermination(exitCode, binaryPath(), d->m_jobs.at(j).arguments);
+            break;
+        }
+    }
+
+    // Special hack: Always produce output for diff
+    if (ok && stdOut.isEmpty() && d->m_jobs.front().arguments.at(0) == QLatin1String("diff")) {
+        stdOut += "No difference to HEAD";
+    } else {
+        // @TODO: Remove, see below
+        if (ok && d->m_jobs.front().arguments.at(0) == QLatin1String("status"))
+            removeColorCodes(&stdOut);
+    }
+
+    d->m_lastExecSuccess = ok;
+    d->m_lastExecExitCode = exitCode;
+
+    if (ok && !stdOut.isEmpty())
+        emit outputData(stdOut);
+
+    if (!error.isEmpty())
+        emit errorText(error);
+
+    emit finished(ok, exitCode, cookie());
+    if (ok)
+        emit success(cookie());
+    // As it is used asynchronously, we need to delete ourselves
+    this->deleteLater();
+}
+
+// Clean output from carriage return and ANSI color codes.
+// @TODO: Remove once all relevant commands support "--no-color",
+//("status" is  missing it as of git 1.6.2)
+
+void Command::removeColorCodes(QByteArray *data)
+{
+    // Remove ansi color codes that look like "ESC[<stuff>m"
+    const QByteArray ansiColorEscape("\033[");
+    int escapePos = 0;
+    while (true) {
+        const int nextEscapePos = data->indexOf(ansiColorEscape, escapePos);
+        if (nextEscapePos == -1)
+            break;
+        const int endEscapePos = data->indexOf('m', nextEscapePos + ansiColorEscape.size());
+        if (endEscapePos != -1) {
+            data->remove(nextEscapePos, endEscapePos - nextEscapePos + 1);
+            escapePos = nextEscapePos;
+        } else {
+            escapePos = nextEscapePos + ansiColorEscape.size();
+        }
+    }
+}
+
+const QVariant &Command::cookie() const
+{
+    return d->m_cookie;
+}
+
+void Command::setCookie(const QVariant &cookie)
+{
+    d->m_cookie = cookie;
+}
+
+} // namespace VCSBase
diff --git a/src/plugins/vcsbase/command.h b/src/plugins/vcsbase/command.h
new file mode 100644
index 0000000000000000000000000000000000000000..04d0b053a08a34bfff527bdc885deca8d6b6deb5
--- /dev/null
+++ b/src/plugins/vcsbase/command.h
@@ -0,0 +1,105 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2010 Brian McGillion & Hugues Delorme
+**
+** Contact: Nokia Corporation (info@qt.nokia.com)
+**
+**
+** GNU Lesser General Public License Usage
+**
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this file.
+** Please review the following information to ensure the GNU Lesser General
+** Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** Other Usage
+**
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at info@qt.nokia.com.
+**
+**************************************************************************/
+
+#ifndef VCSBASE_COMMAND_H
+#define VCSBASE_COMMAND_H
+
+#include "vcsbase_global.h"
+
+#include <QtCore/QObject>
+#include <QtCore/QStringList>
+#include <QtCore/QVariant>
+#include <QtCore/QProcessEnvironment>
+
+namespace VCSBase {
+
+class VCSBASE_EXPORT Command : public QObject
+{
+    Q_OBJECT
+
+public:
+    // Where to report command termination with exit code if desired
+    enum TerminationReportMode { NoReport,
+                                 ReportStdout,  // This assumes UTF8
+                                 ReportStderr };
+
+    Command(const QString &binary,
+            const QString &workingDirectory,
+            const QProcessEnvironment &environment);
+    ~Command();
+
+    void addJob(const QStringList &arguments);
+    void addJob(const QStringList &arguments, int timeout);
+    void execute();
+    bool lastExecutionSuccess() const;
+    int lastExecutionExitCode() const;
+
+    // Clean output from carriage return and ANSI color codes
+    // Workaround until all relevant commands support "--no-color"
+    static void removeColorCodes(QByteArray *data);
+
+    const QString &binaryPath() const;
+    const QString &workingDirectory() const;
+    const QProcessEnvironment &processEnvironment() const;
+
+    // Report command termination with exit code
+    TerminationReportMode reportTerminationMode() const;
+    void setTerminationReportMode(TerminationReportMode m);
+
+    int defaultTimeout() const;
+    void setDefaultTimeout(int timeout);
+
+    // Disable Terminal on UNIX (see VCS SSH handling)
+    bool unixTerminalDisabled() const;
+    void setUnixTerminalDisabled(bool);
+
+    static QString msgTimeout(int seconds);
+
+    const QVariant &cookie() const;
+    void setCookie(const QVariant &cookie);
+
+private:
+    void run();
+
+signals:
+    void outputData(const QByteArray &);
+    void errorText(const QString &);
+    void finished(bool ok, int exitCode, const QVariant &cookie);
+    void success(const QVariant &cookie);
+
+private:
+    class CommandPrivate *d;
+};
+
+} //namespace VCSBase
+
+#endif // VCSBASE_COMMAND_H
diff --git a/src/plugins/vcsbase/vcsbase.pro b/src/plugins/vcsbase/vcsbase.pro
index 6a4cc9e37ca0da0f08a24215274b273d52b81f84..f9cd7b796313bb63df70803c68417fde9a282d8f 100644
--- a/src/plugins/vcsbase/vcsbase.pro
+++ b/src/plugins/vcsbase/vcsbase.pro
@@ -29,7 +29,7 @@ HEADERS += vcsbase_global.h \
     vcsbaseoutputwindow.h \
     cleandialog.h \
     vcsbaseoptionspage.h \
-    vcsjobrunner.h \
+    command.h \
     vcsbaseclient.h \
     vcsbaseclientsettings.h \
     vcsbaseeditorparameterwidget.h
@@ -58,7 +58,7 @@ SOURCES += vcsplugin.cpp \
     vcsbaseoutputwindow.cpp \
     cleandialog.cpp \
     vcsbaseoptionspage.cpp \
-    vcsjobrunner.cpp \
+    command.cpp \
     vcsbaseclient.cpp \
     vcsbaseclientsettings.cpp \
     vcsbaseeditorparameterwidget.cpp
diff --git a/src/plugins/vcsbase/vcsbaseclient.cpp b/src/plugins/vcsbase/vcsbaseclient.cpp
index d936d3ceed1284bcbacde6e90639911154af33a9..e522ce37b9feb86e108b646a53f8a88c11a3dd3e 100644
--- a/src/plugins/vcsbase/vcsbaseclient.cpp
+++ b/src/plugins/vcsbase/vcsbaseclient.cpp
@@ -30,8 +30,9 @@
 **
 **************************************************************************/
 
+#include "command.h"
 #include "vcsbaseclient.h"
-#include "vcsjobrunner.h"
+#include "vcsbaseconstants.h"
 #include "vcsbaseclientsettings.h"
 #include "vcsbaseeditorparameterwidget.h"
 
@@ -49,6 +50,7 @@
 #include <QtCore/QSharedPointer>
 #include <QtCore/QDir>
 #include <QtCore/QProcess>
+#include <QtCore/QSignalMapper>
 #include <QtCore/QTextCodec>
 #include <QtCore/QtDebug>
 #include <QtCore/QFileInfo>
@@ -75,6 +77,15 @@ inline Core::IEditor *locateEditor(const Core::ICore *core, const char *property
     return 0;
 }
 
+namespace {
+
+VCSBase::VCSBaseOutputWindow *vcsOutputWindow()
+{
+    return VCSBase::VCSBaseOutputWindow::instance();
+}
+
+}
+
 namespace VCSBase {
 
 class VCSBaseClientPrivate
@@ -86,18 +97,22 @@ public:
     void annotateRevision(QString source, QString change, int lineNumber);
     void saveSettings();
 
-    void updateJobRunnerSettings();
+    void bindCommandToEditor(Command *cmd, VCSBaseEditorWidget *editor);
+    void commandFinishedGotoLine(QObject *editorObject);
 
-    VCSJobRunner *m_jobManager;
     Core::ICore *m_core;
     VCSBaseClientSettings *m_clientSettings;
+    QSignalMapper *m_cmdFinishedMapper;
 
 private:
     VCSBaseClient *m_client;
 };
 
 VCSBaseClientPrivate::VCSBaseClientPrivate(VCSBaseClient *client, VCSBaseClientSettings *settings) :
-    m_jobManager(0), m_core(Core::ICore::instance()), m_clientSettings(settings), m_client(client)
+    m_core(Core::ICore::instance()),
+    m_clientSettings(settings),
+    m_cmdFinishedMapper(new QSignalMapper(client)),
+    m_client(client)
 {
 }
 
@@ -132,11 +147,23 @@ void VCSBaseClientPrivate::saveSettings()
     m_clientSettings->writeSettings(m_core->settings());
 }
 
-void VCSBaseClientPrivate::updateJobRunnerSettings()
+void VCSBaseClientPrivate::bindCommandToEditor(Command *cmd, VCSBaseEditorWidget *editor)
+{
+    QObject::connect(cmd, SIGNAL(finished(bool,int,QVariant)), m_cmdFinishedMapper, SLOT(map()));
+    m_cmdFinishedMapper->setMapping(cmd, editor);
+}
+
+void VCSBaseClientPrivate::commandFinishedGotoLine(QObject *editorObject)
 {
-    if (m_jobManager && m_clientSettings) {
-        m_jobManager->setBinary(m_clientSettings->stringValue(VCSBaseClientSettings::binaryPathKey));
-        m_jobManager->setTimeoutMs(m_clientSettings->intValue(VCSBaseClientSettings::timeoutKey) * 1000);
+    VCSBase::VCSBaseEditorWidget *editor = qobject_cast<VCSBase::VCSBaseEditorWidget *>(editorObject);
+    Command *cmd = qobject_cast<Command *>(m_cmdFinishedMapper->mapping(editor));
+    if (editor && cmd) {
+        if (cmd->lastExecutionSuccess() && cmd->cookie().type() == QVariant::Int) {
+            const int line = cmd->cookie().toInt();
+            if (line >= 0)
+                editor->gotoLine(line);
+        }
+        m_cmdFinishedMapper->removeMappings(cmd);
     }
 }
 
@@ -154,12 +181,11 @@ VCSBaseClient::VCSBaseClient(VCSBaseClientSettings *settings) :
 {
     qRegisterMetaType<QVariant>();
     connect(d->m_core, SIGNAL(saveSettingsRequested()), this, SLOT(saveSettings()));
+    connect(d->m_cmdFinishedMapper, SIGNAL(mapped(QObject*)), this, SLOT(commandFinishedGotoLine(QObject*)));
 }
 
 VCSBaseClient::~VCSBaseClient()
 {
-    delete d->m_jobManager;
-    d->m_jobManager = 0;
     delete d;
 }
 
@@ -173,7 +199,7 @@ bool VCSBaseClient::synchronousCreateRepository(const QString &workingDirectory,
         return false;
     QString output = QString::fromLocal8Bit(outputData);
     output.remove(QLatin1Char('\r'));
-    VCSBase::VCSBaseOutputWindow::instance()->append(output);
+    ::vcsOutputWindow()->append(output);
 
     resetCachedVcsInfo(workingDirectory);
 
@@ -262,17 +288,17 @@ bool VCSBaseClient::vcsFullySynchronousExec(const QString &workingDir,
     QProcess vcsProcess;
     if (!workingDir.isEmpty())
         vcsProcess.setWorkingDirectory(workingDir);
-    VCSJobRunner::setProcessEnvironment(&vcsProcess);
+    vcsProcess.setProcessEnvironment(processEnvironment());
 
     const QString binary = settings()->stringValue(VCSBaseClientSettings::binaryPathKey);
 
-    VCSBase::VCSBaseOutputWindow *outputWindow = VCSBase::VCSBaseOutputWindow::instance();
-    outputWindow->appendCommand(workingDir, binary, args);
+    ::vcsOutputWindow()->appendCommand(workingDir, binary, args);
 
     vcsProcess.start(binary, args);
 
     if (!vcsProcess.waitForStarted()) {
-        outputWindow->appendError(VCSJobRunner::msgStartFailed(binary, vcsProcess.errorString()));
+        ::vcsOutputWindow()->appendError(tr("Unable to start process '%1': %2")
+                                         .arg(QDir::toNativeSeparators(binary), vcsProcess.errorString()));
         return false;
     }
 
@@ -283,20 +309,21 @@ bool VCSBaseClient::vcsFullySynchronousExec(const QString &workingDir,
     if (!Utils::SynchronousProcess::readDataFromProcess(vcsProcess, timeoutSec * 1000,
                                                         output, &stdErr, true)) {
         Utils::SynchronousProcess::stopProcess(vcsProcess);
-        outputWindow->appendError(VCSJobRunner::msgTimeout(binary, timeoutSec));
+        ::vcsOutputWindow()->appendError(tr("Timed out after %1s waiting for the process %2 to finish.")
+                                         .arg(timeoutSec).arg(binary));
         return false;
     }
     if (!stdErr.isEmpty())
-        outputWindow->append(QString::fromLocal8Bit(stdErr));
+        ::vcsOutputWindow()->append(QString::fromLocal8Bit(stdErr));
 
     return vcsProcess.exitStatus() == QProcess::NormalExit && vcsProcess.exitCode() == 0;
 }
 
 Utils::SynchronousProcessResponse VCSBaseClient::vcsSynchronousExec(
-    const QString &workingDirectory,
-    const QStringList &args,
-    unsigned flags,
-    QTextCodec *outputCodec)
+        const QString &workingDirectory,
+        const QStringList &args,
+        unsigned flags,
+        QTextCodec *outputCodec)
 {
     const QString binary = settings()->stringValue(VCSBaseClientSettings::binaryPathKey);
     const int timeoutSec = settings()->intValue(VCSBaseClientSettings::timeoutKey);
@@ -321,8 +348,9 @@ void VCSBaseClient::annotate(const QString &workingDir, const QString &file,
     VCSBase::VCSBaseEditorWidget *editor = createVCSEditor(kind, title, source, true,
                                                            vcsCmdString.toLatin1().constData(), id);
 
-    QSharedPointer<VCSJob> job(new VCSJob(workingDir, args, editor));
-    enqueueJob(job);
+    Command *cmd = createCommand(workingDir, editor);
+    cmd->setCookie(lineNumber);
+    enqueueJob(cmd, args);
 }
 
 void VCSBaseClient::diff(const QString &workingDir, const QStringList &files,
@@ -348,8 +376,7 @@ void VCSBaseClient::diff(const QString &workingDir, const QStringList &files,
     QStringList args;
     const QStringList paramArgs = paramWidget != 0 ? paramWidget->arguments() : QStringList();
     args << vcsCmdString << extraOptions << paramArgs << files;
-    QSharedPointer<VCSJob> job(new VCSJob(workingDir, args, editor));
-    enqueueJob(job);
+    enqueueJob(createCommand(workingDir, editor), args);
 }
 
 void VCSBaseClient::log(const QString &workingDir, const QStringList &files,
@@ -373,8 +400,7 @@ void VCSBaseClient::log(const QString &workingDir, const QStringList &files,
     QStringList args;
     const QStringList paramArgs = paramWidget != 0 ? paramWidget->arguments() : QStringList();
     args << vcsCmdString << extraOptions << paramArgs << files;
-    QSharedPointer<VCSJob> job(new VCSJob(workingDir, args, editor));
-    enqueueJob(job);
+    enqueueJob(createCommand(workingDir, editor), args);
 }
 
 void VCSBaseClient::revertFile(const QString &workingDir,
@@ -385,11 +411,10 @@ void VCSBaseClient::revertFile(const QString &workingDir,
     QStringList args(vcsCommandString(RevertCommand));
     args << revisionSpec(revision) << extraOptions << file;
     // Indicate repository change or file list
-    QSharedPointer<VCSJob> job(new VCSJob(workingDir, args));
-    job->setCookie(QStringList(workingDir + QLatin1Char('/') + file));
-    connect(job.data(), SIGNAL(succeeded(QVariant)),
-            this, SIGNAL(changed(QVariant)), Qt::QueuedConnection);
-    enqueueJob(job);
+    Command *cmd = createCommand(workingDir);
+    cmd->setCookie(QStringList(workingDir + QLatin1Char('/') + file));
+    connect(cmd, SIGNAL(success(QVariant)), this, SIGNAL(changed(QVariant)), Qt::QueuedConnection);
+    enqueueJob(cmd, args);
 }
 
 void VCSBaseClient::revertAll(const QString &workingDir, const QString &revision,
@@ -398,10 +423,10 @@ void VCSBaseClient::revertAll(const QString &workingDir, const QString &revision
     QStringList args(vcsCommandString(RevertCommand));
     args << revisionSpec(revision) << extraOptions;
     // Indicate repository change or file list
-    QSharedPointer<VCSJob> job(new VCSJob(workingDir, args));
-    connect(job.data(), SIGNAL(succeeded(QVariant)),
-            this, SIGNAL(changed(QVariant)), Qt::QueuedConnection);
-    enqueueJob(job);
+    Command *cmd = createCommand(workingDir);
+    cmd->setCookie(QStringList(workingDir));
+    connect(cmd, SIGNAL(success(QVariant)), this, SIGNAL(changed(QVariant)), Qt::QueuedConnection);
+    enqueueJob(createCommand(workingDir), args);
 }
 
 void VCSBaseClient::status(const QString &workingDir, const QString &file,
@@ -409,21 +434,20 @@ void VCSBaseClient::status(const QString &workingDir, const QString &file,
 {
     QStringList args(vcsCommandString(StatusCommand));
     args << extraOptions << file;
-    VCSBase::VCSBaseOutputWindow *outwin = VCSBase::VCSBaseOutputWindow::instance();
-    outwin->setRepository(workingDir);
-    QSharedPointer<VCSJob> job(new VCSJob(workingDir, args));
-    connect(job.data(), SIGNAL(succeeded(QVariant)),
-            outwin, SLOT(clearRepository()), Qt::QueuedConnection);
-    enqueueJob(job);
+    ::vcsOutputWindow()->setRepository(workingDir);
+    Command *cmd = createCommand(workingDir, 0, VcsWindowOutputBind);
+    connect(cmd, SIGNAL(finished(bool,int,QVariant)), ::vcsOutputWindow(), SLOT(clearRepository()),
+            Qt::QueuedConnection);
+    enqueueJob(cmd, args);
 }
 
 void VCSBaseClient::emitParsedStatus(const QString &repository, const QStringList &extraOptions)
 {
     QStringList args(vcsCommandString(StatusCommand));
     args << extraOptions;
-    QSharedPointer<VCSJob> job(new VCSJob(repository, args, VCSJob::RawDataEmitMode));
-    connect(job.data(), SIGNAL(rawData(QByteArray)), this, SLOT(statusParser(QByteArray)));
-    enqueueJob(job);
+    Command *cmd = createCommand(repository);
+    connect(cmd, SIGNAL(outputData(QByteArray)), this, SLOT(statusParser(QByteArray)));
+    enqueueJob(cmd, args);
 }
 
 QString VCSBaseClient::vcsCommandString(VCSCommand cmd) const
@@ -453,8 +477,7 @@ void VCSBaseClient::import(const QString &repositoryRoot, const QStringList &fil
 {
     QStringList args(vcsCommandString(ImportCommand));
     args << extraOptions << files;
-    QSharedPointer<VCSJob> job(new VCSJob(repositoryRoot, args));
-    enqueueJob(job);
+    enqueueJob(createCommand(repositoryRoot), args);
 }
 
 void VCSBaseClient::view(const QString &source, const QString &id,
@@ -470,8 +493,7 @@ void VCSBaseClient::view(const QString &source, const QString &id,
 
     const QFileInfo fi(source);
     const QString workingDirPath = fi.isFile() ? fi.absolutePath() : source;
-    QSharedPointer<VCSJob> job(new VCSJob(workingDirPath, args, editor));
-    enqueueJob(job);
+    enqueueJob(createCommand(workingDirPath, editor), args);
 }
 
 void VCSBaseClient::update(const QString &repositoryRoot, const QString &revision,
@@ -479,12 +501,11 @@ void VCSBaseClient::update(const QString &repositoryRoot, const QString &revisio
 {
     QStringList args(vcsCommandString(UpdateCommand));
     args << revisionSpec(revision) << extraOptions;
-    QSharedPointer<VCSJob> job(new VCSJob(repositoryRoot, args));
-    job->setCookie(repositoryRoot);
-    // Suppress SSH prompting
-    job->setUnixTerminalDisabled(VCSBase::VCSBasePlugin::isSshPromptConfigured());
-    connect(job.data(), SIGNAL(succeeded(QVariant)), this, SIGNAL(changed(QVariant)), Qt::QueuedConnection);
-    enqueueJob(job);
+    Command *cmd = createCommand(repositoryRoot);
+    cmd->setCookie(repositoryRoot);
+    cmd->setUnixTerminalDisabled(VCSBase::VCSBasePlugin::isSshPromptConfigured());
+    connect(cmd, SIGNAL(success(QVariant)), this, SIGNAL(changed(QVariant)), Qt::QueuedConnection);
+    enqueueJob(cmd, args);
 }
 
 void VCSBaseClient::commit(const QString &repositoryRoot,
@@ -503,8 +524,7 @@ void VCSBaseClient::commit(const QString &repositoryRoot,
     Q_UNUSED(commitMessageFile);
     QStringList args(vcsCommandString(CommitCommand));
     args << extraOptions << files;
-    QSharedPointer<VCSJob> job(new VCSJob(repositoryRoot, args));
-    enqueueJob(job);
+    enqueueJob(createCommand(repositoryRoot), args);
 }
 
 VCSBaseClientSettings *VCSBaseClient::settings() const
@@ -512,14 +532,6 @@ VCSBaseClientSettings *VCSBaseClient::settings() const
     return d->m_clientSettings;
 }
 
-void VCSBaseClient::handleSettingsChanged()
-{
-    if (d->m_jobManager) {
-        d->updateJobRunnerSettings();
-        d->m_jobManager->restart();
-    }
-}
-
 VCSBaseEditorParameterWidget *VCSBaseClient::createDiffEditor(const QString &workingDir,
                                                               const QStringList &files,
                                                               const QStringList &extraOptions)
@@ -578,20 +590,58 @@ VCSBase::VCSBaseEditorWidget *VCSBaseClient::createVCSEditor(const QString &kind
     return baseEditor;
 }
 
-void VCSBaseClient::resetCachedVcsInfo(const QString &workingDir)
+QProcessEnvironment VCSBaseClient::processEnvironment() const
 {
-    Core::VcsManager *vcsManager = d->m_core->vcsManager();
-    vcsManager->resetVersionControlForDirectory(workingDir);
+    QProcessEnvironment environment = QProcessEnvironment::systemEnvironment();
+    VCSBase::VCSBasePlugin::setProcessEnvironment(&environment, false);
+    return environment;
 }
 
-void VCSBaseClient::enqueueJob(const QSharedPointer<VCSJob> &job)
+Command *VCSBaseClient::createCommand(const QString &workingDirectory,
+                                      VCSBase::VCSBaseEditorWidget *editor,
+                                      JobOutputBindMode mode)
 {
-    if (!d->m_jobManager) {
-        d->m_jobManager = new VCSJobRunner();
-        d->updateJobRunnerSettings();
-        d->m_jobManager->start();
+    if (Constants::Internal::debug)
+        qDebug() << Q_FUNC_INFO << workingDirectory << editor;
+
+    Command *cmd = new Command(d->m_clientSettings->stringValue(VCSBaseClientSettings::binaryPathKey),
+                               workingDirectory, processEnvironment());
+    cmd->setDefaultTimeout(d->m_clientSettings->intValue(VCSBaseClientSettings::timeoutKey));
+    if (editor)
+        d->bindCommandToEditor(cmd, editor);
+    if (mode == VcsWindowOutputBind) {
+        if (editor) { // assume that the commands output is the important thing
+            connect(cmd, SIGNAL(outputData(QByteArray)),
+                    ::vcsOutputWindow(), SLOT(appendDataSilently(QByteArray)));
+        }
+        else {
+            connect(cmd, SIGNAL(outputData(QByteArray)),
+                    ::vcsOutputWindow(), SLOT(appendData(QByteArray)));
+        }
+    }
+    else if (editor) {
+        connect(cmd, SIGNAL(outputData(QByteArray)),
+                editor, SLOT(setPlainTextData(QByteArray)));
     }
-    d->m_jobManager->enqueueJob(job);
+
+    if (::vcsOutputWindow())
+        connect(cmd, SIGNAL(errorText(QString)),
+                ::vcsOutputWindow(), SLOT(appendError(QString)));
+    return cmd;
+}
+
+void VCSBaseClient::enqueueJob(Command *cmd, const QStringList &args)
+{
+    const QString binary = QFileInfo(d->m_clientSettings->stringValue(VCSBaseClientSettings::binaryPathKey)).baseName();
+    ::vcsOutputWindow()->appendCommand(cmd->workingDirectory(), binary, args);
+    cmd->addJob(args);
+    cmd->execute();
+}
+
+void VCSBaseClient::resetCachedVcsInfo(const QString &workingDir)
+{
+    Core::VcsManager *vcsManager = d->m_core->vcsManager();
+    vcsManager->resetVersionControlForDirectory(workingDir);
 }
 
 } // namespace VCSBase
diff --git a/src/plugins/vcsbase/vcsbaseclient.h b/src/plugins/vcsbase/vcsbaseclient.h
index c6cffb79643cdbafa9b927b3edaa54479c948397..eb0e82a52a9eb686d0b923f8ec13e4512de89c69 100644
--- a/src/plugins/vcsbase/vcsbaseclient.h
+++ b/src/plugins/vcsbase/vcsbaseclient.h
@@ -38,6 +38,8 @@
 #include <QtCore/QObject>
 #include <QtCore/QStringList>
 #include <QtCore/QSharedPointer>
+#include <QtCore/QVariant>
+#include <QtCore/QProcessEnvironment>
 
 QT_BEGIN_NAMESPACE
 class QFileInfo;
@@ -49,6 +51,7 @@ struct SynchronousProcessResponse;
 
 namespace VCSBase {
 
+class Command;
 class VCSBaseEditorWidget;
 class VCSBaseClientSettings;
 class VCSJob;
@@ -126,7 +129,6 @@ signals:
 public slots:
     virtual void view(const QString &source, const QString &id,
                       const QStringList &extraOptions = QStringList());
-    void handleSettingsChanged();
 
 protected:
     enum VCSCommand
@@ -160,7 +162,6 @@ protected:
     virtual StatusItem parseStatusLine(const QString &line) const = 0;
 
     QString vcsEditorTitle(const QString &vcsCmd, const QString &sourceId) const;
-    void enqueueJob(const QSharedPointer<VCSJob> &);
     // Fully synchronous VCS execution (QProcess-based)
     bool vcsFullySynchronousExec(const QString &workingDir,
                                  const QStringList &args,
@@ -176,6 +177,17 @@ protected:
                                                   const char *registerDynamicProperty,
                                                   const QString &dynamicPropertyValue) const;
 
+    virtual QProcessEnvironment processEnvironment() const;
+
+    enum JobOutputBindMode {
+        NoOutputBind,
+        VcsWindowOutputBind
+    };
+    Command *createCommand(const QString &workingDirectory,
+                           VCSBase::VCSBaseEditorWidget *editor = 0,
+                           JobOutputBindMode mode = NoOutputBind);
+    void enqueueJob(Command *cmd, const QStringList &args);
+
     void resetCachedVcsInfo(const QString &workingDir);
 
 private:
@@ -185,6 +197,7 @@ private:
     Q_PRIVATE_SLOT(d, void statusParser(QByteArray))
     Q_PRIVATE_SLOT(d, void annotateRevision(QString, QString, int))
     Q_PRIVATE_SLOT(d, void saveSettings())
+    Q_PRIVATE_SLOT(d, void commandFinishedGotoLine(QObject *))
 };
 
 } //namespace VCSBase
diff --git a/src/plugins/vcsbase/vcsjobrunner.cpp b/src/plugins/vcsbase/vcsjobrunner.cpp
deleted file mode 100644
index c09dd8fceb8bf52df5e2b4528ad9772f5ffd2c27..0000000000000000000000000000000000000000
--- a/src/plugins/vcsbase/vcsjobrunner.cpp
+++ /dev/null
@@ -1,392 +0,0 @@
-/**************************************************************************
-**
-** This file is part of Qt Creator
-**
-** Copyright (c) 2010 Brian McGillion & Hugues Delorme
-**
-** Contact: Nokia Corporation (info@qt.nokia.com)
-**
-**
-** GNU Lesser General Public License Usage
-**
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this file.
-** Please review the following information to ensure the GNU Lesser General
-** Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** Other Usage
-**
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-** If you have questions regarding the use of this file, please contact
-** Nokia at info@qt.nokia.com.
-**
-**************************************************************************/
-
-#include "vcsjobrunner.h"
-#include "vcsbaseconstants.h"
-#include "vcsbaseoutputwindow.h"
-#include "vcsbaseeditor.h"
-#include "vcsbaseplugin.h"
-
-#include <utils/synchronousprocess.h>
-
-#include <QtCore/QMutexLocker>
-#include <QtCore/QProcess>
-#include <QtCore/QProcessEnvironment>
-#include <QtCore/QString>
-#include <QtCore/QDebug>
-#include <QtCore/QDir>
-#include <QtCore/QQueue>
-#include <QtCore/QMutex>
-#include <QtCore/QWaitCondition>
-#include <QtCore/QSharedPointer>
-
-namespace {
-
-//Helper class to automatically disconnect a signal from all its receivers.
-//The disconnect occurs on destruction of the helper object.
-class DisconnectSignalHelper
-{
-public:
-    DisconnectSignalHelper(QObject *sender, const char *signal) :
-        m_sender(sender), m_signal(signal)
-    {
-    }
-
-    ~DisconnectSignalHelper()
-    {
-        QObject::disconnect(m_sender, m_signal, 0, 0);
-    }
-
-private:
-    QObject *m_sender;
-    const char *m_signal;
-};
-
-} // Anonymous namespace
-
-/*!
-    \class  VCSBase::VCSJob
-
-    \brief Version control system background command execution job.
-
-    Takes arguments, etc. as parameters and emits signals on output/termination.
-
-    \sa VCSBase::VCSJobRunner, VCSBase::VCSBaseClient
-*/
-
-namespace VCSBase {
-
-VCSJob::VCSJob(const QString &workingDir,
-               const QStringList &args,
-               DataEmitMode emitMode) :
-    m_workingDir(workingDir),
-    m_arguments(args),
-    m_emitRaw(emitMode == RawDataEmitMode),
-    m_cookie(),
-    m_editor(0),
-    m_unixTerminalDisabled(false)
-{
-}
-
-VCSJob::VCSJob(const QString &workingDir,
-               const QStringList &args,
-               VCSBase::VCSBaseEditorWidget *editor) :
-    m_workingDir(workingDir),
-    m_arguments(args),
-    m_emitRaw(false),
-    m_cookie(),
-    m_editor(editor),
-    m_unixTerminalDisabled(false)
-{
-}
-
-
-VCSJob::DataEmitMode VCSJob::dataEmitMode() const
-{
-    if (m_emitRaw)
-        return RawDataEmitMode;
-    else if (displayEditor() != 0)
-        return EditorDataEmitMode;
-    else
-        return NoDataEmitMode;
-}
-
-VCSBase::VCSBaseEditorWidget *VCSJob::displayEditor() const
-{
-    return m_editor;
-}
-
-QStringList VCSJob::arguments() const
-{
-    return m_arguments;
-}
-
-QString VCSJob::workingDirectory() const
-{
-    return m_workingDir;
-}
-
-const QVariant &VCSJob::cookie() const
-{
-    return m_cookie;
-}
-
-bool VCSJob::unixTerminalDisabled() const
-{
-    return m_unixTerminalDisabled;
-}
-
-void VCSJob::setDisplayEditor(VCSBase::VCSBaseEditorWidget *editor)
-{
-    m_editor = editor;
-    m_emitRaw = false;
-}
-
-void VCSJob::setCookie(const QVariant &cookie)
-{
-    m_cookie = cookie;
-}
-
-void VCSJob::setUnixTerminalDisabled(bool v)
-{
-    m_unixTerminalDisabled = v;
-}
-
-/*!
-    \class  VCSBase::VCSJobRunner
-
-    \brief Job queue for version control system background command execution.
-
-    A job queue running in a separate thread, executing commands
-    and emitting status/log  signals.
-
-    \sa VCSBase::VCSJob, VCSBase::VCSBaseClient
-*/
-
-class VCSJobRunnerPrivate
-{
-public:
-    VCSJobRunnerPrivate();
-
-    QQueue<QSharedPointer<VCSJob> > m_jobs;
-    QMutex m_mutex;
-    QWaitCondition m_waiter;
-    bool m_keepRunning;
-    QString m_binary;
-    int m_timeoutMs;
-};
-
-VCSJobRunnerPrivate::VCSJobRunnerPrivate() :
-    m_keepRunning(true), m_timeoutMs(30000)
-{
-}
-
-VCSJobRunner::VCSJobRunner() : d(new VCSJobRunnerPrivate)
-{
-    VCSBase::VCSBaseOutputWindow *ow = VCSBase::VCSBaseOutputWindow::instance();
-    connect(this, SIGNAL(error(QString)),
-            ow, SLOT(appendError(QString)), Qt::QueuedConnection);
-    connect(this, SIGNAL(commandStarted(QString)),
-            ow, SLOT(appendCommand(QString)), Qt::QueuedConnection);
-}
-
-VCSJobRunner::~VCSJobRunner()
-{
-    stop();
-    delete d;
-}
-
-void VCSJobRunner::stop()
-{
-    {
-        QMutexLocker mutexLocker(&d->m_mutex); Q_UNUSED(mutexLocker);
-        d->m_keepRunning = false;
-        //Create a dummy task to break the cycle
-        QSharedPointer<VCSJob> job(0);
-        d->m_jobs.enqueue(job);
-        d->m_waiter.wakeAll();
-    }
-
-    wait();
-}
-
-void VCSJobRunner::restart()
-{
-    stop();
-    d->m_mutex.lock();
-    d->m_keepRunning = true;
-    d->m_mutex.unlock();
-    start();
-}
-
-void VCSJobRunner::enqueueJob(const QSharedPointer<VCSJob> &job)
-{
-    QMutexLocker mutexLocker(&d->m_mutex); Q_UNUSED(mutexLocker);
-    d->m_jobs.enqueue(job);
-    d->m_waiter.wakeAll();
-}
-
-void VCSJobRunner::run()
-{
-    forever {
-        d->m_mutex.lock();
-        while (d->m_jobs.count() == 0)
-            d->m_waiter.wait(&d->m_mutex);
-
-        if (!d->m_keepRunning) {
-            d->m_jobs.clear();
-            d->m_mutex.unlock();
-            return;
-        }
-
-        QSharedPointer<VCSJob> job = d->m_jobs.dequeue();
-        d->m_mutex.unlock();
-
-        task(job);
-    }
-}
-
-QString VCSJobRunner::msgStartFailed(const QString &binary, const QString &why)
-{
-    return tr("Unable to start process '%1': %2").
-            arg(QDir::toNativeSeparators(binary), why);
-}
-
-QString VCSJobRunner::msgTimeout(const QString &binary, int timeoutSeconds)
-{
-    return tr("Timed out after %1s waiting for the process %2 to finish.").arg(timeoutSeconds).arg(binary);
-}
-
-// Set environment for a VCS process to run in locale "C". Note that there appears
-// to be a bug in some VCSs (like hg) that causes special characters to be garbled
-// when running in a different language, which seems to be independent from the encoding.
-void VCSJobRunner::setProcessEnvironment(QProcess *p)
-{
-    if (p == 0)
-        return;
-    QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
-    VCSBase::VCSBasePlugin::setProcessEnvironment(&env, false);
-    p->setProcessEnvironment(env);
-}
-
-const QString &VCSJobRunner::binary() const
-{
-    return d->m_binary;
-}
-
-void VCSJobRunner::setBinary(const QString &bin)
-{
-    d->m_binary = bin;
-}
-
-int VCSJobRunner::timeoutMs() const
-{
-    return d->m_timeoutMs;
-}
-
-void VCSJobRunner::setTimeoutMs(int msec)
-{
-    d->m_timeoutMs = msec;
-}
-
-void VCSJobRunner::task(const QSharedPointer<VCSJob> &job)
-{
-    VCSJob *taskData = job.data();
-
-    VCSBase::VCSBaseOutputWindow *outputWindow = VCSBase::VCSBaseOutputWindow::instance();
-
-    switch (taskData->dataEmitMode()) {
-    case VCSJob::NoDataEmitMode :
-        //Just output the data to the "Version control" output window
-        connect(this, SIGNAL(output(QByteArray)), outputWindow, SLOT(appendData(QByteArray)),
-                Qt::QueuedConnection);
-        break;
-    case VCSJob::RawDataEmitMode :
-        //Call the job's signal so the Initator of the job can process the data
-        //Because the QSharedPointer that holds the VCSJob will go out of scope and hence be deleted
-        //we have to block and wait until the signal is delivered
-        connect(this, SIGNAL(output(QByteArray)), taskData, SIGNAL(rawData(QByteArray)),
-                Qt::BlockingQueuedConnection);
-        break;
-    case VCSJob::EditorDataEmitMode :
-        //An editor has been created to display the data so send it there
-        connect(this, SIGNAL(output(QByteArray)),
-                taskData->displayEditor(), SLOT(setPlainTextData(QByteArray)),
-                Qt::QueuedConnection);
-        break;
-    }
-
-    //the signal connection is to last only for the duration of a job/task.  next time a new
-    //output signal connection must be made
-    DisconnectSignalHelper autoDisconnectOutputSig(this, SIGNAL(output(QByteArray)));
-    Q_UNUSED(autoDisconnectOutputSig);
-
-    // Check that the binary path is not empty
-    if (binary().trimmed().isEmpty()) {
-        emit error(tr("Unable to start process, binary is empty"));
-        return;
-    }
-
-    const QStringList args = taskData->arguments();
-    emit commandStarted(VCSBase::VCSBaseOutputWindow::msgExecutionLogEntry(taskData->workingDirectory(), binary(), args));
-    //infom the user of what we are going to try and perform
-
-    if (Constants::Internal::debug)
-        qDebug() << Q_FUNC_INFO << "Repository root is "
-                 << taskData->workingDirectory() << " terminal_disabled"
-                 << taskData->unixTerminalDisabled();
-
-    const unsigned processFlags = taskData->unixTerminalDisabled() ?
-                unsigned(Utils::SynchronousProcess::UnixTerminalDisabled) :
-                unsigned(0);
-
-    QSharedPointer<QProcess> vcsProcess = Utils::SynchronousProcess::createProcess(processFlags);
-    vcsProcess->setWorkingDirectory(taskData->workingDirectory());
-    VCSJobRunner::setProcessEnvironment(vcsProcess.data());
-
-    vcsProcess->start(binary(), args);
-
-    if (!vcsProcess->waitForStarted()) {
-        emit error(msgStartFailed(binary(), vcsProcess->errorString()));
-        return;
-    }
-
-    vcsProcess->closeWriteChannel();
-
-    QByteArray stdOutput;
-    QByteArray stdErr;
-
-    if (!Utils::SynchronousProcess::readDataFromProcess(*vcsProcess, timeoutMs(), &stdOutput, &stdErr, false)) {
-        Utils::SynchronousProcess::stopProcess(*vcsProcess);
-        emit error(msgTimeout(binary(), timeoutMs() / 1000));
-        return;
-    }
-
-    if (vcsProcess->exitStatus() == QProcess::NormalExit) {
-        /*
-          * sometimes success means output is actually on error channel (stderr)
-          * e.g. "hg revert" outputs "no changes needed to 'file'" on stderr if file has not changed
-          * from revision specified
-          */
-        if (stdOutput.isEmpty())
-            stdOutput = stdErr;
-        emit output(stdOutput); // This will clear the diff "Working..." text.
-        if (vcsProcess->exitCode() == 0)
-            emit taskData->succeeded(taskData->cookie());
-        else
-            emit error(QString::fromLocal8Bit(stdErr));
-    }
-
-    vcsProcess->close();
-}
-
-} // namespace VCSBase
diff --git a/src/plugins/vcsbase/vcsjobrunner.h b/src/plugins/vcsbase/vcsjobrunner.h
deleted file mode 100644
index ece94fa7dd055747cbced7fa650061b6f6e91477..0000000000000000000000000000000000000000
--- a/src/plugins/vcsbase/vcsjobrunner.h
+++ /dev/null
@@ -1,134 +0,0 @@
-/**************************************************************************
-**
-** This file is part of Qt Creator
-**
-** Copyright (c) 2010 Brian McGillion & Hugues Delorme
-**
-** Contact: Nokia Corporation (info@qt.nokia.com)
-**
-**
-** GNU Lesser General Public License Usage
-**
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this file.
-** Please review the following information to ensure the GNU Lesser General
-** Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** Other Usage
-**
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-** If you have questions regarding the use of this file, please contact
-** Nokia at info@qt.nokia.com.
-**
-**************************************************************************/
-
-#ifndef VCSJOBRUNNER_H
-#define VCSJOBRUNNER_H
-
-#include "vcsbase_global.h"
-
-#include <QtCore/QThread>
-#include <QtCore/QStringList>
-#include <QtCore/QString>
-#include <QtCore/QPointer>
-#include <QtCore/QSharedPointer>
-#include <QtCore/QVariant>
-
-QT_BEGIN_NAMESPACE
-class QProcess;
-QT_END_NAMESPACE
-
-namespace VCSBase {
-class VCSBaseEditorWidget;
-class VCSJobRunnerPrivate;
-
-class VCSBASE_EXPORT VCSJob : public QObject
-{
-    Q_OBJECT
-
-public:
-    enum DataEmitMode {
-        NoDataEmitMode,
-        RawDataEmitMode,
-        EditorDataEmitMode
-    };
-
-    VCSJob(const QString &workingDir, const QStringList &args,
-           DataEmitMode emitMode = NoDataEmitMode);
-    VCSJob(const QString &workingDir, const QStringList &args,
-           VCSBase::VCSBaseEditorWidget *editor);
-
-    DataEmitMode dataEmitMode() const;
-    VCSBase::VCSBaseEditorWidget *displayEditor() const;
-    QStringList arguments() const;
-    QString workingDirectory() const;
-    const QVariant &cookie() const;
-    bool unixTerminalDisabled() const;
-
-    void setDisplayEditor(VCSBase::VCSBaseEditorWidget *editor);
-    void setCookie(const QVariant &cookie);
-    // Disable terminal to suppress SSH prompting
-    void setUnixTerminalDisabled(bool v);
-
-signals:
-    void succeeded(const QVariant &cookie); // Use a queued connection
-    void rawData(const QByteArray &data);
-
-private:
-    friend class VCSJobRunner;
-    const QString m_workingDir;
-    const QStringList m_arguments;
-    bool m_emitRaw;
-    QVariant m_cookie;
-    QPointer<VCSBase::VCSBaseEditorWidget> m_editor; // User might close it
-    bool m_unixTerminalDisabled;
-};
-
-class VCSBASE_EXPORT VCSJobRunner : public QThread
-{
-    Q_OBJECT
-
-public:
-    VCSJobRunner();
-    ~VCSJobRunner();
-    void enqueueJob(const QSharedPointer<VCSJob> &job);
-    void restart();
-
-    static QString msgStartFailed(const QString &binary, const QString &why);
-    static QString msgTimeout(const QString &binary, int timeoutSeconds);
-
-    // Set environment for a VCS process to run in locale "C"
-    static void setProcessEnvironment(QProcess *p);
-
-    const QString &binary() const;
-    void setBinary(const QString &bin);
-
-    int timeoutMs() const;
-    void setTimeoutMs(int msec);
-
-protected:
-    void run();
-
-signals:
-    void commandStarted(const QString &notice);
-    void error(const QString &error);
-    void output(const QByteArray &output);
-
-private:
-    void task(const QSharedPointer<VCSJob> &job);
-    void stop();
-
-    VCSJobRunnerPrivate *d;
-};
-
-} //namespace VCSBase
-
-#endif // VCSJOBRUNNER_H