diff --git a/src/plugins/debugger/gdb/startgdbserverdialog.cpp b/src/plugins/debugger/gdb/startgdbserverdialog.cpp
index f6a6b0d4a2d0d0262530d8bbaf32a489764bd170..a35ed5d2ac2e45e12efa086ea116cc92c014ffd3 100644
--- a/src/plugins/debugger/gdb/startgdbserverdialog.cpp
+++ b/src/plugins/debugger/gdb/startgdbserverdialog.cpp
@@ -210,7 +210,7 @@ void StartGdbServerDialog::attachToDevice()
     if (!device)
         return;
     delete d->processList;
-    d->processList = new DeviceProcessList(device);
+    d->processList = device->createProcessListModel();
     d->proxyModel.setSourceModel(d->processList);
     connect(d->processList, SIGNAL(error(QString)),
         SLOT(handleRemoteError(QString)));
diff --git a/src/plugins/madde/maddedevice.cpp b/src/plugins/madde/maddedevice.cpp
index 3df7e4b201600f9bebdd2d515ce03106f488a2cb..c88ee1a5fe1ce09b14b5d0fcd52da2854283319c 100644
--- a/src/plugins/madde/maddedevice.cpp
+++ b/src/plugins/madde/maddedevice.cpp
@@ -111,12 +111,12 @@ void MaddeDevice::executeAction(Core::Id actionId, QWidget *parent) const
     if (actionId == Core::Id(MaddeDeviceTestActionId))
         d = new LinuxDeviceTestDialog(device, new MaddeDeviceTester, parent);
     else if (actionId == Core::Id(MaddeRemoteProcessesActionId))
-        d = new DeviceProcessesDialog(new DeviceProcessList(device), parent);
+        d = new DeviceProcessesDialog(createProcessListModel(parent));
     else if (actionId == Core::Id(Constants::GenericDeployKeyToDeviceActionId))
         d = PublicKeyDeploymentDialog::createDialog(device, parent);
-    // FIXME: Leak?
     if (d)
         d->exec();
+    delete d;
 }
 
 QString MaddeDevice::maddeDisplayType(Core::Id type)
diff --git a/src/plugins/projectexplorer/devicesupport/deviceprocesslist.cpp b/src/plugins/projectexplorer/devicesupport/deviceprocesslist.cpp
index be2be74cfdb892c2130745fa4cd626aab601709f..cf196610b6a396b34296acf53212e6d2fe3572df 100644
--- a/src/plugins/projectexplorer/devicesupport/deviceprocesslist.cpp
+++ b/src/plugins/projectexplorer/devicesupport/deviceprocesslist.cpp
@@ -30,9 +30,6 @@
 #include "deviceprocesslist.h"
 
 #include <utils/qtcassert.h>
-#include <ssh/sshremoteprocessrunner.h>
-
-using namespace QSsh;
 
 namespace ProjectExplorer {
 namespace Internal {
@@ -48,9 +45,7 @@ public:
     { }
 
     const IDevice::ConstPtr device;
-    SshRemoteProcessRunner process;
     QList<DeviceProcess> remoteProcesses;
-    QString errorMsg;
     State state;
 };
 
@@ -71,7 +66,7 @@ DeviceProcessList::~DeviceProcessList()
 void DeviceProcessList::update()
 {
     QTC_ASSERT(d->state == Inactive, return);
-    QTC_ASSERT(d->device && d->device->processSupport(), return);
+    QTC_ASSERT(device(), return);
 
     if (!d->remoteProcesses.isEmpty()) {
         beginRemoveRows(QModelIndex(), 0, d->remoteProcesses.count() - 1);
@@ -79,27 +74,51 @@ void DeviceProcessList::update()
         endRemoveRows();
     }
     d->state = Listing;
-    startProcess(d->device->processSupport()->listProcessesCommandLine());
+    doUpdate();
+}
+
+void DeviceProcessList::doUpdate()
+{
+    reportProcessListUpdated(QList<DeviceProcess>());
+}
+
+void DeviceProcessList::reportProcessListUpdated(const QList<DeviceProcess> &processes)
+{
+    QTC_ASSERT(d->state == Listing, return);
+    setFinished();
+    if (!processes.isEmpty()) {
+        beginInsertRows(QModelIndex(), 0, processes.count() - 1);
+        d->remoteProcesses = processes;
+        endInsertRows();
+    }
+    emit processListUpdated();
 }
 
 void DeviceProcessList::killProcess(int row)
 {
     QTC_ASSERT(row >= 0 && row < d->remoteProcesses.count(), return);
     QTC_ASSERT(d->state == Inactive, return);
+    QTC_ASSERT(device(), return);
 
     d->state = Killing;
-    const int pid = d->remoteProcesses.at(row).pid;
-    startProcess(d->device->processSupport()->killProcessByPidCommandLine(pid));
+    doKillProcess(d->remoteProcesses.at(row));
 }
 
-DeviceProcess DeviceProcessList::at(int row) const
+void DeviceProcessList::doKillProcess(const DeviceProcess &)
 {
-    return d->remoteProcesses.at(row);
+    QTC_ASSERT(false, qDebug("Process list should be empty"); return);
 }
 
-IDevice::ConstPtr DeviceProcessList::device() const
+void DeviceProcessList::reportProcessKilled()
 {
-    return d->device;
+    QTC_ASSERT(d->state == Killing, return);
+    setFinished();
+    emit processKilled();
+}
+
+DeviceProcess DeviceProcessList::at(int row) const
+{
+    return d->remoteProcesses.at(row);
 }
 
 int DeviceProcessList::rowCount(const QModelIndex &parent) const
@@ -134,80 +153,21 @@ QVariant DeviceProcessList::data(const QModelIndex &index, int role) const
     return QVariant();
 }
 
-void DeviceProcessList::handleConnectionError()
-{
-    QTC_ASSERT(d->state != Inactive, return);
-
-    emit error(tr("Connection failure: %1").arg(d->process.lastConnectionErrorString()));
-    beginResetModel();
-    d->remoteProcesses.clear();
-    endResetModel();
-    setFinished();
-}
-
-void DeviceProcessList::handleRemoteProcessFinished(int exitStatus)
+void DeviceProcessList::setFinished()
 {
-    QTC_ASSERT(d->state != Inactive, return);
-
-    switch (exitStatus) {
-    case SshRemoteProcess::FailedToStart:
-        d->errorMsg = tr("Error: Remote process failed to start: %1")
-            .arg(d->process.processErrorString());
-        break;
-    case SshRemoteProcess::CrashExit:
-        d->errorMsg = tr("Error: Remote process crashed: %1")
-            .arg(d->process.processErrorString());
-        break;
-    case SshRemoteProcess::NormalExit:
-        if (d->process.processExitCode() == 0) {
-            if (d->state == Listing) {
-                const QByteArray remoteStdout = d->process.readAllStandardOutput();
-                const QString stdoutString
-                        = QString::fromUtf8(remoteStdout.data(), remoteStdout.count());
-                QList<DeviceProcess> processes
-                        = d->device->processSupport()->buildProcessList(stdoutString);
-                if (!processes.isEmpty()) {
-                    beginInsertRows(QModelIndex(), 0, processes.count()-1);
-                    d->remoteProcesses = processes;
-                    endInsertRows();
-                }
-            }
-        } else {
-            d->errorMsg = tr("Remote process failed.");
-        }
-        break;
-    default:
-        Q_ASSERT_X(false, Q_FUNC_INFO, "Invalid exit status");
-    }
-
-    if (d->state == Listing)
-        emit processListUpdated();
-
-    if (!d->errorMsg.isEmpty()) {
-        const QByteArray remoteStderr = d->process.readAllStandardError();
-        if (!remoteStderr.isEmpty())
-            d->errorMsg += tr("\nRemote stderr was: %1").arg(QString::fromUtf8(remoteStderr));
-        emit error(d->errorMsg);
-    } else if (d->state == Killing) {
-        emit processKilled();
-    }
-
-    setFinished();
+    d->state = Inactive;
 }
 
-void DeviceProcessList::startProcess(const QString &cmdLine)
+IDevice::ConstPtr DeviceProcessList::device() const
 {
-    connect(&d->process, SIGNAL(connectionError()), SLOT(handleConnectionError()));
-    connect(&d->process, SIGNAL(processClosed(int)),
-        SLOT(handleRemoteProcessFinished(int)));
-    d->errorMsg.clear();
-    d->process.run(cmdLine.toUtf8(), d->device->sshParameters());
+    return d->device;
 }
 
-void DeviceProcessList::setFinished()
+void DeviceProcessList::reportError(const QString &message)
 {
-    disconnect(&d->process, 0, this, 0);
-    d->state = Inactive;
+    QTC_ASSERT(d->state != Inactive, return);
+    setFinished();
+    emit error(message);
 }
 
 
diff --git a/src/plugins/projectexplorer/devicesupport/deviceprocesslist.h b/src/plugins/projectexplorer/devicesupport/deviceprocesslist.h
index 5bfb8f2bd138e7c826b6c07d8a92aca4f6acb402..fcbf8bacc2324031d51005515f2a1d1367c8e85e 100644
--- a/src/plugins/projectexplorer/devicesupport/deviceprocesslist.h
+++ b/src/plugins/projectexplorer/devicesupport/deviceprocesslist.h
@@ -40,6 +40,17 @@ namespace ProjectExplorer {
 
 namespace Internal { class DeviceProcessListPrivate; }
 
+class PROJECTEXPLORER_EXPORT DeviceProcess
+{
+public:
+    DeviceProcess() : pid(0) {}
+    bool operator<(const DeviceProcess &other) const;
+
+    int pid;
+    QString cmdLine;
+    QString exe;
+};
+
 class PROJECTEXPLORER_EXPORT DeviceProcessList : public QAbstractTableModel
 {
     Q_OBJECT
@@ -51,16 +62,18 @@ public:
     void update();
     void killProcess(int row);
     DeviceProcess at(int row) const;
-    IDevice::ConstPtr device() const;
 
 signals:
     void processListUpdated();
     void error(const QString &errorMsg);
     void processKilled();
 
-private slots:
-    void handleConnectionError();
-    void handleRemoteProcessFinished(int exitStatus);
+protected:
+    void reportError(const QString &message);
+    void reportProcessKilled();
+    void reportProcessListUpdated(const QList<DeviceProcess> &processes);
+
+    IDevice::ConstPtr device() const;
 
 private:
     int rowCount(const QModelIndex &parent = QModelIndex()) const;
@@ -69,7 +82,10 @@ private:
         int role = Qt::DisplayRole) const;
     QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
 
-    void startProcess(const QString &cmdLine);
+    // No-op implementations for devices without process listing abilities.
+    virtual void doUpdate();
+    virtual void doKillProcess(const DeviceProcess &process);
+
     void setFinished();
 
     Internal::DeviceProcessListPrivate * const d;
diff --git a/src/plugins/projectexplorer/devicesupport/idevice.cpp b/src/plugins/projectexplorer/devicesupport/idevice.cpp
index 5a9430b1d3f5509355f0fb90b51d9296faf3f038..724cac12f1797d4ca45d8c672fa63caed52bd1c9 100644
--- a/src/plugins/projectexplorer/devicesupport/idevice.cpp
+++ b/src/plugins/projectexplorer/devicesupport/idevice.cpp
@@ -30,6 +30,7 @@
 #include "idevice.h"
 
 #include "devicemanager.h"
+#include "deviceprocesslist.h"
 
 #include <coreplugin/id.h>
 #include <ssh/sshconnection.h>
@@ -259,6 +260,11 @@ PortsGatheringMethod::Ptr IDevice::portsGatheringMethod() const
     return PortsGatheringMethod::Ptr();
 }
 
+DeviceProcessList *IDevice::createProcessListModel(QObject *parent) const
+{
+    return new DeviceProcessList(sharedFromThis(), parent);
+}
+
 IDevice::DeviceState IDevice::deviceState() const
 {
     return d->deviceState;
diff --git a/src/plugins/projectexplorer/devicesupport/idevice.h b/src/plugins/projectexplorer/devicesupport/idevice.h
index c20ae330b22bf356df76b73ab8d28ae2984a5898..b7e91b65356e19f214b28703c5757791b600c846 100644
--- a/src/plugins/projectexplorer/devicesupport/idevice.h
+++ b/src/plugins/projectexplorer/devicesupport/idevice.h
@@ -40,6 +40,7 @@
 #include <QVariantMap>
 
 QT_BEGIN_NAMESPACE
+class QObject;
 class QWidget;
 QT_END_NAMESPACE
 
@@ -47,30 +48,18 @@ namespace QSsh { class SshConnectionParameters; }
 namespace Utils { class PortList; }
 
 namespace ProjectExplorer {
+class DeviceProcessList;
 
 namespace Internal { class IDevicePrivate; }
 
 class IDeviceWidget;
 
-class PROJECTEXPLORER_EXPORT DeviceProcess
-{
-public:
-    DeviceProcess() : pid(0) {}
-    bool operator<(const DeviceProcess &other) const;
-
-    int pid;
-    QString cmdLine;
-    QString exe;
-};
-
 class PROJECTEXPLORER_EXPORT DeviceProcessSupport
 {
 public:
     typedef QSharedPointer<const DeviceProcessSupport> Ptr;
 
     virtual ~DeviceProcessSupport();
-    virtual QString listProcessesCommandLine() const = 0;
-    virtual QList<DeviceProcess> buildProcessList(const QString &listProcessesReply) const = 0;
     virtual QString killProcessByPidCommandLine(int pid) const = 0;
     virtual QString killProcessByNameCommandLine(const QString &filePath) const = 0;
 };
@@ -125,6 +114,7 @@ public:
 
     virtual DeviceProcessSupport::Ptr processSupport() const;
     virtual PortsGatheringMethod::Ptr portsGatheringMethod() const;
+    virtual DeviceProcessList *createProcessListModel(QObject *parent = 0) const;
 
     enum DeviceState { DeviceReadyToUse, DeviceConnected, DeviceDisconnected, DeviceStateUnknown };
     DeviceState deviceState() const;
diff --git a/src/plugins/projectexplorer/devicesupport/sshdeviceprocesslist.cpp b/src/plugins/projectexplorer/devicesupport/sshdeviceprocesslist.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..98656e941dee25596a367c6bf7f19e59c8b7bdb4
--- /dev/null
+++ b/src/plugins/projectexplorer/devicesupport/sshdeviceprocesslist.cpp
@@ -0,0 +1,144 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: http://www.qt-project.org/
+**
+** 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.
+**
+**
+**************************************************************************/
+#include "sshdeviceprocesslist.h"
+
+#include <ssh/sshremoteprocessrunner.h>
+#include <utils/qtcassert.h>
+
+using namespace QSsh;
+
+namespace ProjectExplorer {
+
+class SshDeviceProcessList::SshDeviceProcessListPrivate
+{
+public:
+    SshRemoteProcessRunner process;
+};
+
+SshDeviceProcessList::SshDeviceProcessList(const IDevice::ConstPtr &device, QObject *parent) :
+        DeviceProcessList(device, parent), d(new SshDeviceProcessListPrivate)
+{
+}
+
+SshDeviceProcessList::~SshDeviceProcessList()
+{
+    delete d;
+}
+
+void SshDeviceProcessList::doUpdate()
+{
+    QTC_ASSERT(device()->processSupport(), return);
+    connect(&d->process, SIGNAL(connectionError()), SLOT(handleConnectionError()));
+    connect(&d->process, SIGNAL(processClosed(int)), SLOT(handleListProcessFinished(int)));
+    d->process.run(listProcessesCommandLine().toUtf8(), device()->sshParameters());
+}
+
+void SshDeviceProcessList::doKillProcess(const DeviceProcess &process)
+{
+    QTC_ASSERT(device()->processSupport(), return);
+    connect(&d->process, SIGNAL(connectionError()), SLOT(handleConnectionError()));
+    connect(&d->process, SIGNAL(processClosed(int)), SLOT(handleKillProcessFinished(int)));
+    d->process.run(device()->processSupport()->killProcessByPidCommandLine(process.pid).toUtf8(),
+                   device()->sshParameters());
+}
+
+void SshDeviceProcessList::handleConnectionError()
+{
+    setFinished();
+    reportError(tr("Connection failure: %1").arg(d->process.lastConnectionErrorString()));
+}
+
+void SshDeviceProcessList::handleListProcessFinished(int exitStatus)
+{
+    setFinished();
+    switch (exitStatus) {
+    case SshRemoteProcess::FailedToStart:
+        handleProcessError(tr("Error: Process listing command failed to start: %1")
+                .arg(d->process.processErrorString()));
+        break;
+    case SshRemoteProcess::CrashExit:
+        handleProcessError(tr("Error: Process listing command crashed: %1")
+                .arg(d->process.processErrorString()));
+        break;
+    case SshRemoteProcess::NormalExit:
+        if (d->process.processExitCode() == 0) {
+            const QByteArray remoteStdout = d->process.readAllStandardOutput();
+            const QString stdoutString
+                    = QString::fromUtf8(remoteStdout.data(), remoteStdout.count());
+            reportProcessListUpdated(buildProcessList(stdoutString));
+        } else {
+            handleProcessError(tr("Process listing command failed with exit code %1.")
+                    .arg(d->process.processExitCode()));
+        }
+        break;
+    default:
+        Q_ASSERT_X(false, Q_FUNC_INFO, "Invalid exit status");
+    }
+}
+
+void SshDeviceProcessList::handleKillProcessFinished(int exitStatus)
+{
+    setFinished();
+    switch (exitStatus) {
+    case SshRemoteProcess::FailedToStart:
+        handleProcessError(tr("Error: Kill process failed to start: %1")
+                .arg(d->process.processErrorString()));
+        break;
+    case SshRemoteProcess::CrashExit:
+        handleProcessError(tr("Error: Kill process crashed: %1")
+                .arg(d->process.processErrorString()));
+        break;
+    case SshRemoteProcess::NormalExit: {
+        const int exitCode = d->process.processExitCode();
+        if (exitCode == 0)
+            reportProcessKilled();
+        else
+            handleProcessError(tr("Kill process failed with exit code %1.").arg(exitCode));
+        break;
+    }
+    default:
+        Q_ASSERT_X(false, Q_FUNC_INFO, "Invalid exit status");
+    }
+}
+
+void SshDeviceProcessList::handleProcessError(const QString &errorMessage)
+{
+    QString fullMessage = errorMessage;
+    const QByteArray remoteStderr = d->process.readAllStandardError();
+    if (!remoteStderr.isEmpty())
+        fullMessage += tr("\nRemote stderr was: %1").arg(QString::fromUtf8(remoteStderr));
+    reportError(fullMessage);
+}
+
+void SshDeviceProcessList::setFinished()
+{
+    d->process.disconnect(this);
+}
+
+} // namespace ProjectExplorer
diff --git a/src/plugins/projectexplorer/devicesupport/sshdeviceprocesslist.h b/src/plugins/projectexplorer/devicesupport/sshdeviceprocesslist.h
new file mode 100644
index 0000000000000000000000000000000000000000..32331557f5751240531d9a5fd72b13d4c6fe6e0c
--- /dev/null
+++ b/src/plugins/projectexplorer/devicesupport/sshdeviceprocesslist.h
@@ -0,0 +1,64 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: http://www.qt-project.org/
+**
+** 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.
+**
+**
+**************************************************************************/
+#ifndef SSHDEVICEPROCESSLIST_H
+#define SSHDEVICEPROCESSLIST_H
+
+#include "deviceprocesslist.h"
+
+namespace ProjectExplorer {
+
+class PROJECTEXPLORER_EXPORT SshDeviceProcessList : public DeviceProcessList
+{
+    Q_OBJECT
+public:
+    explicit SshDeviceProcessList(const IDevice::ConstPtr &device, QObject *parent = 0);
+    ~SshDeviceProcessList();
+
+private slots:
+    void handleConnectionError();
+    void handleListProcessFinished(int exitStatus);
+    void handleKillProcessFinished(int exitStatus);
+
+private:
+    virtual QString listProcessesCommandLine() const = 0;
+    virtual QList<DeviceProcess> buildProcessList(const QString &listProcessesReply) const = 0;
+
+    void doUpdate();
+    void doKillProcess(const DeviceProcess &process);
+
+    void handleProcessError(const QString &errorMessage);
+    void setFinished();
+
+    class SshDeviceProcessListPrivate;
+    SshDeviceProcessListPrivate * const d;
+};
+
+} // namespace ProjectExplorer
+
+#endif // SSHDEVICEPROCESSLIST_H
diff --git a/src/plugins/projectexplorer/projectexplorer.pro b/src/plugins/projectexplorer/projectexplorer.pro
index d27b13f22c4725ca5995e1da1b1b6e93a76b90d2..c733c3cb570d87e980ff918c5e686a26ca97f5be 100644
--- a/src/plugins/projectexplorer/projectexplorer.pro
+++ b/src/plugins/projectexplorer/projectexplorer.pro
@@ -126,7 +126,8 @@ HEADERS += projectexplorer.h \
     devicesupport/devicesettingswidget.h \
     devicesupport/devicesettingspage.h \
     devicesupport/deviceusedportsgatherer.h \
-    devicesupport/deviceapplicationrunner.h
+    devicesupport/deviceapplicationrunner.h \
+    devicesupport/sshdeviceprocesslist.h
 
 SOURCES += projectexplorer.cpp \
     abi.cpp \
@@ -229,7 +230,8 @@ SOURCES += projectexplorer.cpp \
     devicesupport/devicesettingswidget.cpp \
     devicesupport/devicesettingspage.cpp \
     devicesupport/deviceusedportsgatherer.cpp \
-    devicesupport/deviceapplicationrunner.cpp
+    devicesupport/deviceapplicationrunner.cpp \
+    devicesupport/sshdeviceprocesslist.cpp
 
 FORMS += processstep.ui \
     editorsettingspropertiespage.ui \
diff --git a/src/plugins/projectexplorer/projectexplorer.qbs b/src/plugins/projectexplorer/projectexplorer.qbs
index d36076c1b506f2aa015081fcce8b6d1c860f5ce3..64fbeb8c2c313cb10cba3993ef0582c3429f6cd7 100644
--- a/src/plugins/projectexplorer/projectexplorer.qbs
+++ b/src/plugins/projectexplorer/projectexplorer.qbs
@@ -298,6 +298,8 @@ QtcPlugin {
         "devicesupport/devicefactoryselectiondialog.ui",
         "devicesupport/deviceprocesslist.cpp",
         "devicesupport/deviceprocesslist.h",
+        "devicesupport/sshdeviceprocesslist.cpp",
+        "devicesupport/sshdeviceprocesslist.h",
         "devicesupport/deviceprocessesdialog.cpp",
         "devicesupport/deviceprocessesdialog.h",
         "devicesupport/deviceprocessesdialog.ui",
diff --git a/src/plugins/remotelinux/linuxdevice.cpp b/src/plugins/remotelinux/linuxdevice.cpp
index 864e76d03380c612a9017bdfa82a7c402b8174a5..7715e9f3fdea5ceafc5376652fc275c8f86812b8 100644
--- a/src/plugins/remotelinux/linuxdevice.cpp
+++ b/src/plugins/remotelinux/linuxdevice.cpp
@@ -36,7 +36,7 @@
 #include "remotelinux_constants.h"
 
 #include <coreplugin/id.h>
-#include <projectexplorer/devicesupport/deviceprocesslist.h>
+#include <projectexplorer/devicesupport/sshdeviceprocesslist.h>
 #include <projectexplorer/devicesupport/deviceprocessesdialog.h>
 #include <ssh/sshconnection.h>
 #include <utils/portlist.h>
@@ -54,9 +54,18 @@ static QString visualizeNull(QString s)
     return s.replace(QLatin1Char('\0'), QLatin1String("<null>"));
 }
 
-QString LinuxDeviceProcessSupport::listProcessesCommandLine() const
+class LinuxDeviceProcessList : public SshDeviceProcessList
 {
-    return QString::fromLatin1(
+public:
+    LinuxDeviceProcessList(const IDevice::ConstPtr &device, QObject *parent)
+            : SshDeviceProcessList(device, parent)
+    {
+    }
+
+private:
+    QString listProcessesCommandLine() const
+    {
+        return QString::fromLatin1(
             "for dir in `ls -d /proc/[0123456789]*`; do "
                 "test -d $dir || continue;" // Decrease the likelihood of a race condition.
                 "echo $dir;"
@@ -65,50 +74,52 @@ QString LinuxDeviceProcessSupport::listProcessesCommandLine() const
                 "readlink $dir/exe;"
                 "printf '%1''%2';"
             "done").arg(Delimiter0).arg(Delimiter1);
-}
+    }
 
-QList<DeviceProcess> LinuxDeviceProcessSupport::buildProcessList(const QString &listProcessesReply) const
-{
-    QList<DeviceProcess> processes;
-    const QStringList lines = listProcessesReply.split(QString::fromLatin1(Delimiter0)
-            + QString::fromLatin1(Delimiter1), QString::SkipEmptyParts);
-    foreach (const QString &line, lines) {
-        const QStringList elements = line.split(QLatin1Char('\n'));
-        if (elements.count() < 4) {
-            qDebug("%s: Expected four list elements, got %d. Line was '%s'.", Q_FUNC_INFO,
-                   elements.count(), qPrintable(visualizeNull(line)));
-            continue;
-        }
-        bool ok;
-        const int pid = elements.first().mid(6).toInt(&ok);
-        if (!ok) {
-            qDebug("%s: Expected number in %s. Line was '%s'.", Q_FUNC_INFO,
-                   qPrintable(elements.first()), qPrintable(visualizeNull(line)));
-            continue;
-        }
-        QString command = elements.at(1);
-        command.replace(QLatin1Char('\0'), QLatin1Char(' '));
-        if (command.isEmpty()) {
-            const QString &statString = elements.at(2);
-            const int openParenPos = statString.indexOf(QLatin1Char('('));
-            const int closedParenPos = statString.indexOf(QLatin1Char(')'), openParenPos);
-            if (openParenPos == -1 || closedParenPos == -1)
+    QList<DeviceProcess> buildProcessList(const QString &listProcessesReply) const
+    {
+        QList<DeviceProcess> processes;
+        const QStringList lines = listProcessesReply.split(QString::fromLatin1(Delimiter0)
+                + QString::fromLatin1(Delimiter1), QString::SkipEmptyParts);
+        foreach (const QString &line, lines) {
+            const QStringList elements = line.split(QLatin1Char('\n'));
+            if (elements.count() < 4) {
+                qDebug("%s: Expected four list elements, got %d. Line was '%s'.", Q_FUNC_INFO,
+                       elements.count(), qPrintable(visualizeNull(line)));
                 continue;
-            command = QLatin1Char('[')
-                    + statString.mid(openParenPos + 1, closedParenPos - openParenPos - 1)
-                    + QLatin1Char(']');
+            }
+            bool ok;
+            const int pid = elements.first().mid(6).toInt(&ok);
+            if (!ok) {
+                qDebug("%s: Expected number in %s. Line was '%s'.", Q_FUNC_INFO,
+                       qPrintable(elements.first()), qPrintable(visualizeNull(line)));
+                continue;
+            }
+            QString command = elements.at(1);
+            command.replace(QLatin1Char('\0'), QLatin1Char(' '));
+            if (command.isEmpty()) {
+                const QString &statString = elements.at(2);
+                const int openParenPos = statString.indexOf(QLatin1Char('('));
+                const int closedParenPos = statString.indexOf(QLatin1Char(')'), openParenPos);
+                if (openParenPos == -1 || closedParenPos == -1)
+                    continue;
+                command = QLatin1Char('[')
+                        + statString.mid(openParenPos + 1, closedParenPos - openParenPos - 1)
+                        + QLatin1Char(']');
+            }
+
+            DeviceProcess process;
+            process.pid = pid;
+            process.cmdLine = command;
+            process.exe = elements.at(3);
+            processes.append(process);
         }
 
-        DeviceProcess process;
-        process.pid = pid;
-        process.cmdLine = command;
-        process.exe = elements.at(3);
-        processes.append(process);
+        qSort(processes);
+        return processes;
     }
+};
 
-    qSort(processes);
-    return processes;
-}
 
 QString LinuxDeviceProcessSupport::killProcessByPidCommandLine(int pid) const
 {
@@ -212,11 +223,12 @@ void LinuxDevice::executeAction(Core::Id actionId, QWidget *parent) const
     if (actionId == Core::Id(Constants::GenericTestDeviceActionId))
         d = new LinuxDeviceTestDialog(device, new GenericLinuxDeviceTester, parent);
     else if (actionId == Core::Id(Constants::GenericRemoteProcessesActionId))
-        d = new DeviceProcessesDialog(new DeviceProcessList(device, parent));
+        d = new DeviceProcessesDialog(createProcessListModel(parent));
     else if (actionId == Core::Id(Constants::GenericDeployKeyToDeviceActionId))
         d = PublicKeyDeploymentDialog::createDialog(device, parent);
     if (d)
         d->exec();
+    delete d;
 }
 
 LinuxDevice::LinuxDevice(const QString &name, Core::Id type, MachineType machineType,
@@ -251,4 +263,9 @@ PortsGatheringMethod::Ptr LinuxDevice::portsGatheringMethod() const
     return LinuxPortsGatheringMethod::Ptr(new LinuxPortsGatheringMethod);
 }
 
+DeviceProcessList *LinuxDevice::createProcessListModel(QObject *parent) const
+{
+    return new LinuxDeviceProcessList(sharedFromThis(), parent);
+}
+
 } // namespace RemoteLinux
diff --git a/src/plugins/remotelinux/linuxdevice.h b/src/plugins/remotelinux/linuxdevice.h
index 60a05c85b813697018a2b3b04a09bd181f933dfa..498a79f1ea2a11c43a125667c1acce19e04bfe45 100644
--- a/src/plugins/remotelinux/linuxdevice.h
+++ b/src/plugins/remotelinux/linuxdevice.h
@@ -46,8 +46,6 @@ namespace Internal { class LinuxDevicePrivate; }
 class REMOTELINUX_EXPORT LinuxDeviceProcessSupport : public ProjectExplorer::DeviceProcessSupport
 {
 public:
-    QString listProcessesCommandLine() const;
-    QList<ProjectExplorer::DeviceProcess> buildProcessList(const QString &listProcessesReply) const;
     QString killProcessByPidCommandLine(int pid) const;
     QString killProcessByNameCommandLine(const QString &filePath) const;
 };
@@ -73,6 +71,7 @@ public:
 
     ProjectExplorer::DeviceProcessSupport::Ptr processSupport() const;
     ProjectExplorer::PortsGatheringMethod::Ptr portsGatheringMethod() const;
+    ProjectExplorer::DeviceProcessList *createProcessListModel(QObject *parent) const;
 
 protected:
     LinuxDevice() {}