diff --git a/src/plugins/android/androiddevice.cpp b/src/plugins/android/androiddevice.cpp
index 83ee64d9401ff1a67cc5f885013244e983f0b0c0..42e698e04427aab72a0f0110e964a8a7611293a6 100644
--- a/src/plugins/android/androiddevice.cpp
+++ b/src/plugins/android/androiddevice.cpp
@@ -90,22 +90,5 @@ IDevice::Ptr AndroidDevice::clone() const
     return IDevice::Ptr(new AndroidDevice(*this));
 }
 
-QString AndroidDevice::listProcessesCommandLine() const
-{
-    return QString();
-}
-
-QString AndroidDevice::killProcessCommandLine(const DeviceProcess &process) const
-{
-    Q_UNUSED(process);
-    return QString();
-}
-
-QList<DeviceProcess> AndroidDevice::buildProcessList(const QString &listProcessesReply) const
-{
-    Q_UNUSED(listProcessesReply);
-    return QList<DeviceProcess>();
-}
-
 } // namespace Internal
 } // namespace Android
diff --git a/src/plugins/android/androiddevice.h b/src/plugins/android/androiddevice.h
index f38f82cc1393b303008d7ee96eedda324c25217b..e4b8e28ce38f83bbc5dd3ae046b1046d2d7dd0d9 100644
--- a/src/plugins/android/androiddevice.h
+++ b/src/plugins/android/androiddevice.h
@@ -51,10 +51,6 @@ public:
 
     ProjectExplorer::IDevice::Ptr clone() const;
 
-    QString listProcessesCommandLine() const;
-    QString killProcessCommandLine(const ProjectExplorer::DeviceProcess &process) const;
-    QList<ProjectExplorer::DeviceProcess> buildProcessList(const QString &listProcessesReply) const;
-
 protected:
     friend class AndroidDeviceFactory;
     friend class Android::AndroidPlugin;
diff --git a/src/plugins/projectexplorer/devicesupport/desktopdevice.cpp b/src/plugins/projectexplorer/devicesupport/desktopdevice.cpp
index 31b11975fd71a220147743beed30e4f6f6b1da0e..15c6fee7ea1371fa35310935e7126678da79b1eb 100644
--- a/src/plugins/projectexplorer/devicesupport/desktopdevice.cpp
+++ b/src/plugins/projectexplorer/devicesupport/desktopdevice.cpp
@@ -85,21 +85,4 @@ IDevice::Ptr DesktopDevice::clone() const
     return Ptr(new DesktopDevice(*this));
 }
 
-QString DesktopDevice::listProcessesCommandLine() const
-{
-    return QString();
-}
-
-QString DesktopDevice::killProcessCommandLine(const DeviceProcess &process) const
-{
-    Q_UNUSED(process);
-    return QString();
-}
-
-QList<DeviceProcess> DesktopDevice::buildProcessList(const QString &listProcessesReply) const
-{
-    Q_UNUSED(listProcessesReply);
-    return QList<DeviceProcess>();
-}
-
 } // namespace ProjectExplorer
diff --git a/src/plugins/projectexplorer/devicesupport/desktopdevice.h b/src/plugins/projectexplorer/devicesupport/desktopdevice.h
index bd852ab45cea8885bc9926e59b74f60f4f44b8c7..4fb3857ca8cb85d5b657d3429c03b14a97c48df5 100644
--- a/src/plugins/projectexplorer/devicesupport/desktopdevice.h
+++ b/src/plugins/projectexplorer/devicesupport/desktopdevice.h
@@ -54,10 +54,6 @@ public:
 
     IDevice::Ptr clone() const;
 
-    QString listProcessesCommandLine() const;
-    QString killProcessCommandLine(const DeviceProcess &process) const;
-    QList<DeviceProcess> buildProcessList(const QString &listProcessesReply) const;
-
 protected:
     DesktopDevice();
     DesktopDevice(const DesktopDevice &other);
diff --git a/src/plugins/projectexplorer/devicesupport/deviceprocesslist.cpp b/src/plugins/projectexplorer/devicesupport/deviceprocesslist.cpp
index 7553c5c29f8c7a59b4bcf7060a1ea93211838620..be2be74cfdb892c2130745fa4cd626aab601709f 100644
--- a/src/plugins/projectexplorer/devicesupport/deviceprocesslist.cpp
+++ b/src/plugins/projectexplorer/devicesupport/deviceprocesslist.cpp
@@ -71,6 +71,7 @@ DeviceProcessList::~DeviceProcessList()
 void DeviceProcessList::update()
 {
     QTC_ASSERT(d->state == Inactive, return);
+    QTC_ASSERT(d->device && d->device->processSupport(), return);
 
     if (!d->remoteProcesses.isEmpty()) {
         beginRemoveRows(QModelIndex(), 0, d->remoteProcesses.count() - 1);
@@ -78,7 +79,7 @@ void DeviceProcessList::update()
         endRemoveRows();
     }
     d->state = Listing;
-    startProcess(d->device->listProcessesCommandLine());
+    startProcess(d->device->processSupport()->listProcessesCommandLine());
 }
 
 void DeviceProcessList::killProcess(int row)
@@ -87,7 +88,8 @@ void DeviceProcessList::killProcess(int row)
     QTC_ASSERT(d->state == Inactive, return);
 
     d->state = Killing;
-    startProcess(d->device->killProcessCommandLine(d->remoteProcesses.at(row)));
+    const int pid = d->remoteProcesses.at(row).pid;
+    startProcess(d->device->processSupport()->killProcessByPidCommandLine(pid));
 }
 
 DeviceProcess DeviceProcessList::at(int row) const
@@ -160,8 +162,10 @@ void DeviceProcessList::handleRemoteProcessFinished(int exitStatus)
         if (d->process.processExitCode() == 0) {
             if (d->state == Listing) {
                 const QByteArray remoteStdout = d->process.readAllStandardOutput();
-                QList<DeviceProcess> processes = d->device->buildProcessList(QString::fromUtf8(remoteStdout.data(),
-                    remoteStdout.count()));
+                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;
diff --git a/src/plugins/projectexplorer/devicesupport/deviceusedportsgatherer.cpp b/src/plugins/projectexplorer/devicesupport/deviceusedportsgatherer.cpp
index 8d57f9e22cff62e98c8964ba15dc41ffd95fee53..a97e1d95fc7fa115e2a5389e38d21e44de67b7f3 100644
--- a/src/plugins/projectexplorer/devicesupport/deviceusedportsgatherer.cpp
+++ b/src/plugins/projectexplorer/devicesupport/deviceusedportsgatherer.cpp
@@ -46,11 +46,10 @@ class DeviceUsedPortsGathererPrivate
  public:
     SshConnection *connection;
     SshRemoteProcess::Ptr process;
-    PortList portsToCheck;
     QList<int> usedPorts;
     QByteArray remoteStdout;
     QByteArray remoteStderr;
-    QString command;
+    IDevice::ConstPtr device;
 };
 
 } // namespace Internal
@@ -70,7 +69,9 @@ DeviceUsedPortsGatherer::~DeviceUsedPortsGatherer()
 void DeviceUsedPortsGatherer::start(const IDevice::ConstPtr &device)
 {
     QTC_ASSERT(!d->connection, return);
-    d->portsToCheck = device->freePorts();
+    QTC_ASSERT(device && device->portsGatheringMethod(), return);
+
+    d->device = device;
     d->connection = SshConnectionManager::instance().acquireConnection(device->sshParameters());
     connect(d->connection, SIGNAL(error(QSsh::SshError)), SLOT(handleConnectionError()));
     if (d->connection->state() == SshConnection::Connected) {
@@ -84,22 +85,10 @@ void DeviceUsedPortsGatherer::start(const IDevice::ConstPtr &device)
 
 void DeviceUsedPortsGatherer::handleConnectionEstablished()
 {
-    QString command = d->command;
-    if (command.isEmpty()) {
-        QString procFilePath;
-        int addressLength;
-        if (d->connection->connectionInfo().localAddress.protocol() == QAbstractSocket::IPv4Protocol) {
-            procFilePath = QLatin1String("/proc/net/tcp");
-            addressLength = 8;
-        } else {
-            procFilePath = QLatin1String("/proc/net/tcp6");
-            addressLength = 32;
-        }
-        command = QString::fromLatin1("sed "
-            "'s/.*: [[:xdigit:]]\\{%1\\}:\\([[:xdigit:]]\\{4\\}\\).*/\\1/g' %2")
-            .arg(addressLength).arg(procFilePath);
-    }
-    d->process = d->connection->createRemoteProcess(command.toUtf8());
+    const QAbstractSocket::NetworkLayerProtocol protocol
+            = d->connection->connectionInfo().localAddress.protocol();
+    const QByteArray commandLine = d->device->portsGatheringMethod()->commandLine(protocol);
+    d->process = d->connection->createRemoteProcess(commandLine);
 
     connect(d->process.data(), SIGNAL(closed(int)), SLOT(handleProcessClosed(int)));
     connect(d->process.data(), SIGNAL(readyReadStandardOutput()), SLOT(handleRemoteStdOut()));
@@ -138,27 +127,13 @@ QList<int> DeviceUsedPortsGatherer::usedPorts() const
     return d->usedPorts;
 }
 
-void DeviceUsedPortsGatherer::setCommand(const QString &command)
-{
-    d->command = command;
-}
-
 void DeviceUsedPortsGatherer::setupUsedPorts()
 {
-    QList<QByteArray> portStrings = d->remoteStdout.split('\n');
-    portStrings.removeFirst();
-    foreach (const QByteArray &portString, portStrings) {
-        if (portString.isEmpty())
-            continue;
-        bool ok;
-        const int port = portString.toInt(&ok, 16);
-        if (ok) {
-            if (d->portsToCheck.contains(port) && !d->usedPorts.contains(port))
-                d->usedPorts << port;
-        } else {
-            qWarning("%s: Unexpected string '%s' is not a port.",
-                Q_FUNC_INFO, portString.data());
-        }
+    d->usedPorts.clear();
+    const QList<int> usedPorts = d->device->portsGatheringMethod()->usedPorts(d->remoteStdout);
+    foreach (const int port, usedPorts) {
+        if (d->device->freePorts().contains(port))
+            d->usedPorts << port;
     }
     emit portListReady();
 }
diff --git a/src/plugins/projectexplorer/devicesupport/deviceusedportsgatherer.h b/src/plugins/projectexplorer/devicesupport/deviceusedportsgatherer.h
index f68dd6fa4d60c5d2c4e4be0370efef63c2088142..0ab94597cdde2ed6db832ab4ac7b7880fb7268e1 100644
--- a/src/plugins/projectexplorer/devicesupport/deviceusedportsgatherer.h
+++ b/src/plugins/projectexplorer/devicesupport/deviceusedportsgatherer.h
@@ -50,8 +50,6 @@ public:
     int getNextFreePort(Utils::PortList *freePorts) const; // returns -1 if no more are left
     QList<int> usedPorts() const;
 
-    void setCommand(const QString &command); // Will use default command if not set
-
 signals:
     void error(const QString &errMsg);
     void portListReady();
diff --git a/src/plugins/projectexplorer/devicesupport/idevice.cpp b/src/plugins/projectexplorer/devicesupport/idevice.cpp
index 13675b3dd08d1577ba13fb1d1fdf80c92b33ddda..5a9430b1d3f5509355f0fb90b51d9296faf3f038 100644
--- a/src/plugins/projectexplorer/devicesupport/idevice.cpp
+++ b/src/plugins/projectexplorer/devicesupport/idevice.cpp
@@ -190,6 +190,9 @@ public:
 };
 } // namespace Internal
 
+PortsGatheringMethod::~PortsGatheringMethod() { }
+DeviceProcessSupport::~DeviceProcessSupport() { }
+
 IDevice::IDevice() : d(new Internal::IDevicePrivate)
 { }
 
@@ -246,6 +249,16 @@ Core::Id IDevice::id() const
     return d->id;
 }
 
+DeviceProcessSupport::Ptr IDevice::processSupport() const
+{
+    return DeviceProcessSupport::Ptr();
+}
+
+PortsGatheringMethod::Ptr IDevice::portsGatheringMethod() const
+{
+    return PortsGatheringMethod::Ptr();
+}
+
 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 f69480fb70a3b64cd2106b1b916654b76c659ebe..c20ae330b22bf356df76b73ab8d28ae2984a5898 100644
--- a/src/plugins/projectexplorer/devicesupport/idevice.h
+++ b/src/plugins/projectexplorer/devicesupport/idevice.h
@@ -34,6 +34,7 @@
 
 #include <coreplugin/id.h>
 
+#include <QAbstractSocket>
 #include <QList>
 #include <QSharedPointer>
 #include <QVariantMap>
@@ -62,6 +63,29 @@ public:
     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;
+};
+
+class PROJECTEXPLORER_EXPORT PortsGatheringMethod
+{
+public:
+    typedef QSharedPointer<const PortsGatheringMethod> Ptr;
+
+    virtual ~PortsGatheringMethod();
+    virtual QByteArray commandLine(QAbstractSocket::NetworkLayerProtocol protocol) const = 0;
+    virtual QList<int> usedPorts(const QByteArray &commandOutput) const = 0;
+};
+
+
 // See cpp file for documentation.
 class PROJECTEXPLORER_EXPORT IDevice
 {
@@ -99,9 +123,8 @@ public:
     virtual QString displayNameForActionId(Core::Id actionId) const = 0;
     virtual void executeAction(Core::Id actionId, QWidget *parent = 0) const = 0;
 
-    virtual QString listProcessesCommandLine() const = 0;
-    virtual QString killProcessCommandLine(const DeviceProcess &process) const = 0;
-    virtual QList<DeviceProcess> buildProcessList(const QString &listProcessesReply) const = 0;
+    virtual DeviceProcessSupport::Ptr processSupport() const;
+    virtual PortsGatheringMethod::Ptr portsGatheringMethod() const;
 
     enum DeviceState { DeviceReadyToUse, DeviceConnected, DeviceDisconnected, DeviceStateUnknown };
     DeviceState deviceState() const;
diff --git a/src/plugins/projectexplorer/projectexplorer.pri b/src/plugins/projectexplorer/projectexplorer.pri
index 8b464277e4e10981ce40d5357001e7d3aae907f1..b1df3996e2d9df0172f993134a2ab7ccf0c065f3 100644
--- a/src/plugins/projectexplorer/projectexplorer.pri
+++ b/src/plugins/projectexplorer/projectexplorer.pri
@@ -1,2 +1,3 @@
 include(projectexplorer_dependencies.pri)
 LIBS *= -l$$qtLibraryName(ProjectExplorer)
+QT *= network
diff --git a/src/plugins/projectexplorer/projectexplorer.qbs b/src/plugins/projectexplorer/projectexplorer.qbs
index 10234f3ab56e1ad4939698bfa476609101082ccd..d36076c1b506f2aa015081fcce8b6d1c860f5ce3 100644
--- a/src/plugins/projectexplorer/projectexplorer.qbs
+++ b/src/plugins/projectexplorer/projectexplorer.qbs
@@ -328,5 +328,10 @@ QtcPlugin {
            "abstractmsvctoolchain.h"
         ]
     }
-}
 
+    ProductModule {
+        Depends { name: "cpp" }
+        Depends { name: "Qt"; submodules: ["network"] }
+        cpp.includePaths: [".."]
+    }
+}
diff --git a/src/plugins/qmlprofiler/remotelinuxqmlprofilerrunner.cpp b/src/plugins/qmlprofiler/remotelinuxqmlprofilerrunner.cpp
index 115f406c75f99e33b19e09b37e0a7e9772cf3e89..9071604230ca1e739c3deef172633a797e9470b2 100644
--- a/src/plugins/qmlprofiler/remotelinuxqmlprofilerrunner.cpp
+++ b/src/plugins/qmlprofiler/remotelinuxqmlprofilerrunner.cpp
@@ -35,7 +35,6 @@
 #include <projectexplorer/projectexplorerconstants.h>
 #include <projectexplorer/target.h>
 #include <remotelinux/remotelinuxrunconfiguration.h>
-#include <remotelinux/remotelinuxutils.h>
 #include <utils/portlist.h>
 #include <utils/qtcassert.h>
 
@@ -81,7 +80,8 @@ void RemoteLinuxQmlProfilerRunner::stop()
     if (m_port == 0)
         m_portsGatherer->stop();
     else
-        m_runner->stop(RemoteLinuxUtils::killApplicationCommandLine(m_remoteExecutable).toUtf8());
+        m_runner->stop(m_device->processSupport()
+                ->killProcessByNameCommandLine(m_remoteExecutable).toUtf8());
     m_port = 0;
 }
 
diff --git a/src/plugins/qnx/qnxconstants.h b/src/plugins/qnx/qnxconstants.h
index 26c68cd835238d9d6c272105453d6c31f2140df1..ab5a2f4b4d9d47b26c85a9d44c5565ec8356dce4 100644
--- a/src/plugins/qnx/qnxconstants.h
+++ b/src/plugins/qnx/qnxconstants.h
@@ -77,14 +77,6 @@ const char QNX_QNX_OS_TYPE[] = "QnxOsType";
 
 const char QNX_DEBUG_TOKEN_KEY[] = "debugToken";
 
-const char QNX_PORT_GATHERER_COMMAND[] = "netstat -na "
-                                         "| sed 's/[a-z]\\+\\s\\+[0-9]\\+\\s\\+[0-9]\\+\\s\\+\\(\\*\\|[0-9\\.]\\+\\)\\.\\([0-9]\\+\\).*/\\2/g' "
-                                         "| while read line; do "
-                                             "if [[ $line != udp* ]] && [[ $line != Active* ]]; then "
-                                                 "printf '%x\n' $line; "
-                                             "fi; "
-                                         "done";
-
 const char QNX_BAR_DESCRIPTOR_WIZARD_ID[]          = "Q.QnxBlackBerryBarDescriptor";
 const char QNX_BLACKBERRY_QTQUICK_APP_WIZARD_ID[]  = "Q.QnxBlackBerryQQApp";
 const char QNX_BLACKBERRY_QTQUICK2_APP_WIZARD_ID[] = "Q.QnxBlackBerryQQ2App";
diff --git a/src/plugins/qnx/qnxdebugsupport.cpp b/src/plugins/qnx/qnxdebugsupport.cpp
index 766a06c9bf0d5283e1e98e9d47e9e09e9ecb1872..03a84db5d92d2c4e5a01dd6f0f5677321e85db9a 100644
--- a/src/plugins/qnx/qnxdebugsupport.cpp
+++ b/src/plugins/qnx/qnxdebugsupport.cpp
@@ -34,7 +34,6 @@
 #include "qnxdebugsupport.h"
 #include "qnxconstants.h"
 #include "qnxrunconfiguration.h"
-#include "qnxutils.h"
 
 #include <debugger/debuggerengine.h>
 #include <projectexplorer/devicesupport/deviceapplicationrunner.h>
@@ -62,7 +61,6 @@ QnxDebugSupport::QnxDebugSupport(QnxRunConfiguration *runConfig, Debugger::Debug
 {
     m_runner = new DeviceApplicationRunner(this);
     m_portsGatherer = new DeviceUsedPortsGatherer(this);
-    m_portsGatherer->setCommand(QLatin1String(Constants::QNX_PORT_GATHERER_COMMAND));
 
     connect(m_portsGatherer, SIGNAL(error(QString)), SLOT(handleError(QString)));
     connect(m_portsGatherer, SIGNAL(portListReady()), SLOT(handlePortListReady()));
@@ -135,7 +133,7 @@ void QnxDebugSupport::handleDebuggingFinished()
 void QnxDebugSupport::setFinished()
 {
     m_state = Inactive;
-    m_runner->stop(QnxUtils::applicationKillCommand(m_executable).toUtf8());
+    m_runner->stop(m_device->processSupport()->killProcessByNameCommandLine(m_executable).toUtf8());
 }
 
 void QnxDebugSupport::handleProgressReport(const QString &progressOutput)
diff --git a/src/plugins/qnx/qnxdeviceconfiguration.cpp b/src/plugins/qnx/qnxdeviceconfiguration.cpp
index 1eb6c136d6716da7f2149c0c47fc1a1f5465ddc9..2c22a072372e11e95d7988ac1e3591ada02ac398 100644
--- a/src/plugins/qnx/qnxdeviceconfiguration.cpp
+++ b/src/plugins/qnx/qnxdeviceconfiguration.cpp
@@ -36,6 +36,57 @@
 using namespace Qnx;
 using namespace Qnx::Internal;
 
+class QnxDeviceProcessSupport : public RemoteLinux::LinuxDeviceProcessSupport
+{
+    QString killProcessByNameCommandLine(const QString &filePath) const
+    {
+        QString executable = filePath;
+        return QString::fromLatin1("for PID in $(ps -f -o pid,comm | grep %1 | awk '/%1/ {print $1}'); "
+            "do "
+                "kill $PID; sleep 1; kill -9 $PID; "
+            "done").arg(executable.replace(QLatin1String("/"), QLatin1String("\\/")));
+    }
+};
+
+
+class QnxPortsGatheringMethod : public ProjectExplorer::PortsGatheringMethod
+{
+    // TODO: The command is probably needlessly complicated because the parsing method
+    // used to be fixed. These two can now be matched to each other.
+    QByteArray commandLine(QAbstractSocket::NetworkLayerProtocol protocol) const
+    {
+        Q_UNUSED(protocol);
+        return "netstat -na "
+                "| sed 's/[a-z]\\+\\s\\+[0-9]\\+\\s\\+[0-9]\\+\\s\\+\\(\\*\\|[0-9\\.]\\+\\)\\.\\([0-9]\\+\\).*/\\2/g' "
+                "| while read line; do "
+                    "if [[ $line != udp* ]] && [[ $line != Active* ]]; then "
+                        "printf '%x\n' $line; "
+                    "fi; "
+                "done";
+    }
+
+    QList<int> usedPorts(const QByteArray &output) const
+    {
+        QList<int> ports;
+        QList<QByteArray> portStrings = output.split('\n');
+        portStrings.removeFirst();
+        foreach (const QByteArray &portString, portStrings) {
+            if (portString.isEmpty())
+                continue;
+            bool ok;
+            const int port = portString.toInt(&ok, 16);
+            if (ok) {
+                if (!ports.contains(port))
+                    ports << port;
+            } else {
+                qWarning("%s: Unexpected string '%s' is not a port.",
+                         Q_FUNC_INFO, portString.data());
+            }
+        }
+        return ports;
+    }
+};
+
 QnxDeviceConfiguration::QnxDeviceConfiguration()
     : RemoteLinux::LinuxDevice()
 {
@@ -72,3 +123,12 @@ ProjectExplorer::IDevice::Ptr QnxDeviceConfiguration::clone() const
     return Ptr(new QnxDeviceConfiguration(*this));
 }
 
+ProjectExplorer::DeviceProcessSupport::Ptr QnxDeviceConfiguration::processSupport() const
+{
+    return ProjectExplorer::DeviceProcessSupport::Ptr(new QnxDeviceProcessSupport);
+}
+
+ProjectExplorer::PortsGatheringMethod::Ptr QnxDeviceConfiguration::portsGatheringMethod() const
+{
+    return ProjectExplorer::PortsGatheringMethod::Ptr(new QnxPortsGatheringMethod);
+}
diff --git a/src/plugins/qnx/qnxdeviceconfiguration.h b/src/plugins/qnx/qnxdeviceconfiguration.h
index 0a68f9a9c9e059e988cf887f089d9c06749540a9..fe5bc58b8b9b25668bd06672afc5b7139957cea1 100644
--- a/src/plugins/qnx/qnxdeviceconfiguration.h
+++ b/src/plugins/qnx/qnxdeviceconfiguration.h
@@ -52,6 +52,9 @@ public:
                       Origin origin = ManuallyAdded, Core::Id id = Core::Id());
     ProjectExplorer::IDevice::Ptr clone() const;
 
+    ProjectExplorer::DeviceProcessSupport::Ptr processSupport() const;
+    ProjectExplorer::PortsGatheringMethod::Ptr portsGatheringMethod() const;
+
     QString displayType() const;
 
 protected:
diff --git a/src/plugins/qnx/qnxdeviceconfigurationwizard.cpp b/src/plugins/qnx/qnxdeviceconfigurationwizard.cpp
index 5fba97eba0b5323407aa0a5fcf84a2bb701652e5..a113cb5e07e1a7f7afedcf2fbf63d1bf8f4a57da 100644
--- a/src/plugins/qnx/qnxdeviceconfigurationwizard.cpp
+++ b/src/plugins/qnx/qnxdeviceconfigurationwizard.cpp
@@ -81,8 +81,6 @@ IDevice::Ptr QnxDeviceConfigurationWizard::device()
     device->setFreePorts(Utils::PortList::fromString(QLatin1String("10000-10100")));
 
     RemoteLinux::GenericLinuxDeviceTester *devTester = new RemoteLinux::GenericLinuxDeviceTester(this);
-    devTester->usedPortsGatherer()->setCommand(QLatin1String(Constants::QNX_PORT_GATHERER_COMMAND));
-
     RemoteLinux::LinuxDeviceTestDialog dlg(device, devTester, this);
     dlg.exec();
 
diff --git a/src/plugins/qnx/qnxruncontrol.cpp b/src/plugins/qnx/qnxruncontrol.cpp
index f3cb262c56e80f7b3572009c607b415081468163..81940942ba74c0a3325b450288ddce2baeb46f35 100644
--- a/src/plugins/qnx/qnxruncontrol.cpp
+++ b/src/plugins/qnx/qnxruncontrol.cpp
@@ -33,7 +33,6 @@
 
 #include "qnxruncontrol.h"
 #include "qnxrunconfiguration.h"
-#include "qnxutils.h"
 
 #include <projectexplorer/runconfiguration.h>
 #include <remotelinux/remotelinuxrunconfiguration.h>
@@ -45,9 +44,4 @@ using namespace RemoteLinux;
 QnxRunControl::QnxRunControl(ProjectExplorer::RunConfiguration *runConfig)
         : RemoteLinuxRunControl(runConfig)
 {
-    const RemoteLinuxRunConfiguration * const rc
-            = qobject_cast<RemoteLinuxRunConfiguration *>(runConfig);
-    QString executable = rc->remoteExecutableFilePath();
-    executable.replace(QLatin1String("/"), QLatin1String("\\/"));
-    overrideStopCommandLine(QnxUtils::applicationKillCommand(executable).toUtf8());
 }
diff --git a/src/plugins/qnx/qnxutils.cpp b/src/plugins/qnx/qnxutils.cpp
index d96b50649a08d298cceeff047bab7c23bd13b974..4ef95137c97f9a244050f2832571fc6bb7cdea87 100644
--- a/src/plugins/qnx/qnxutils.cpp
+++ b/src/plugins/qnx/qnxutils.cpp
@@ -75,11 +75,3 @@ QStringList QnxUtils::searchPaths(QnxAbstractQtVersion *qtVersion)
 
     return searchPaths;
 }
-
-QString QnxUtils::applicationKillCommand(const QString &applicationFilePath)
-{
-    return QString::fromLatin1("for PID in $(ps -f -o pid,comm | grep %1 | awk '/%1/ {print $1}'); "
-            "do "
-            "kill $PID; sleep 1; kill -9 $PID; "
-            "done").arg(applicationFilePath);
-}
diff --git a/src/plugins/qnx/qnxutils.h b/src/plugins/qnx/qnxutils.h
index 82d63de84131308b515bb4273f507cfa5963495b..1195f87c5797abf511fd7095ec69afc10fded7bc 100644
--- a/src/plugins/qnx/qnxutils.h
+++ b/src/plugins/qnx/qnxutils.h
@@ -49,7 +49,6 @@ public:
     static QString addQuotes(const QString &string);
     static Qnx::QnxArchitecture cpudirToArch(const QString &cpuDir);
     static QStringList searchPaths(QnxAbstractQtVersion *qtVersion);
-    static QString applicationKillCommand(const QString &applicationFilePath);
 };
 
 } // namespace Internal
diff --git a/src/plugins/qt4projectmanager/qt-s60/symbianidevice.cpp b/src/plugins/qt4projectmanager/qt-s60/symbianidevice.cpp
index d0f0c662e1d2b7cbf39d746067a9e7dd959d5faf..b084ecdac61993dbdf17f86b3df9741e72dc4a3b 100644
--- a/src/plugins/qt4projectmanager/qt-s60/symbianidevice.cpp
+++ b/src/plugins/qt4projectmanager/qt-s60/symbianidevice.cpp
@@ -249,21 +249,4 @@ void SymbianIDevice::updateState()
     }
 }
 
-QString SymbianIDevice::listProcessesCommandLine() const
-{
-    return QString();
-}
-
-QString SymbianIDevice::killProcessCommandLine(const DeviceProcess &process) const
-{
-    Q_UNUSED(process);
-    return QString();
-}
-
-QList<DeviceProcess> SymbianIDevice::buildProcessList(const QString &listProcessesReply) const
-{
-    Q_UNUSED(listProcessesReply);
-    return QList<DeviceProcess>();
-}
-
 } // namespace qt4projectmanager
diff --git a/src/plugins/qt4projectmanager/qt-s60/symbianidevice.h b/src/plugins/qt4projectmanager/qt-s60/symbianidevice.h
index aaba2fe407fb22f2ef907036ed1c0bebcc0b2b8b..2a8ba273cf96ef6f2ba2d3086dadb3b040445b95 100644
--- a/src/plugins/qt4projectmanager/qt-s60/symbianidevice.h
+++ b/src/plugins/qt4projectmanager/qt-s60/symbianidevice.h
@@ -78,10 +78,6 @@ public:
     QString displayNameForActionId(Core::Id actionId) const;
     void executeAction(Core::Id actionId, QWidget*parent) const;
 
-    QString listProcessesCommandLine() const;
-    QString killProcessCommandLine(const ProjectExplorer::DeviceProcess &process) const;
-    QList<ProjectExplorer::DeviceProcess> buildProcessList(const QString &listProcessesReply) const;
-
 protected:
     SymbianIDevice(const SymbianIDevice &other);
     SymbianIDevice &operator=(const SymbianIDevice &); // no impl.
diff --git a/src/plugins/remotelinux/linuxdevice.cpp b/src/plugins/remotelinux/linuxdevice.cpp
index 4a3b1d968f7594d1755360d37837dc2467e3149a..864e76d03380c612a9017bdfa82a7c402b8174a5 100644
--- a/src/plugins/remotelinux/linuxdevice.cpp
+++ b/src/plugins/remotelinux/linuxdevice.cpp
@@ -54,6 +54,119 @@ static QString visualizeNull(QString s)
     return s.replace(QLatin1Char('\0'), QLatin1String("<null>"));
 }
 
+QString LinuxDeviceProcessSupport::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;"
+                "cat $dir/cmdline;echo;" // cmdline does not end in newline
+                "cat $dir/stat;"
+                "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)
+                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);
+    }
+
+    qSort(processes);
+    return processes;
+}
+
+QString LinuxDeviceProcessSupport::killProcessByPidCommandLine(int pid) const
+{
+    return QLatin1String("kill -9 ") + QString::number(pid);
+}
+
+QString LinuxDeviceProcessSupport::killProcessByNameCommandLine(const QString &filePath) const
+{
+    return QString::fromLatin1("cd /proc; for pid in `ls -d [0123456789]*`; "
+            "do "
+                "if [ \"`readlink /proc/$pid/exe`\" = \"%1\" ]; then "
+                "    kill $pid; sleep 1; kill -9 $pid; "
+                "fi; "
+            "done").arg(filePath);
+}
+
+
+class LinuxPortsGatheringMethod : public ProjectExplorer::PortsGatheringMethod
+{
+    QByteArray commandLine(QAbstractSocket::NetworkLayerProtocol protocol) const
+    {
+        QString procFilePath;
+        int addressLength;
+        if (protocol == QAbstractSocket::IPv4Protocol) {
+            procFilePath = QLatin1String("/proc/net/tcp");
+            addressLength = 8;
+        } else {
+            procFilePath = QLatin1String("/proc/net/tcp6");
+            addressLength = 32;
+        }
+        return QString::fromLatin1("sed "
+                "'s/.*: [[:xdigit:]]\\{%1\\}:\\([[:xdigit:]]\\{4\\}\\).*/\\1/g' %2")
+                .arg(addressLength).arg(procFilePath).toUtf8();
+    }
+
+    QList<int> usedPorts(const QByteArray &output) const
+    {
+        QList<int> ports;
+        QList<QByteArray> portStrings = output.split('\n');
+        portStrings.removeFirst();
+        foreach (const QByteArray &portString, portStrings) {
+            if (portString.isEmpty())
+                continue;
+            bool ok;
+            const int port = portString.toInt(&ok, 16);
+            if (ok) {
+                if (!ports.contains(port))
+                    ports << port;
+            } else {
+                qWarning("%s: Unexpected string '%s' is not a port.",
+                         Q_FUNC_INFO, portString.data());
+            }
+        }
+        return ports;
+    }
+};
+
+
 LinuxDevice::Ptr LinuxDevice::create(const QString &name,
        Core::Id type, MachineType machineType, Origin origin, Core::Id id)
 {
@@ -128,65 +241,14 @@ ProjectExplorer::IDevice::Ptr LinuxDevice::clone() const
     return Ptr(new LinuxDevice(*this));
 }
 
-QString LinuxDevice::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;"
-            "cat $dir/cmdline;echo;" // cmdline does not end in newline
-            "cat $dir/stat;"
-            "readlink $dir/exe;"
-            "printf '%1''%2';"
-        "done").arg(Delimiter0).arg(Delimiter1);
-}
-
-QString LinuxDevice::killProcessCommandLine(const DeviceProcess &process) const
+DeviceProcessSupport::Ptr LinuxDevice::processSupport() const
 {
-    return QLatin1String("kill -9 ") + QString::number(process.pid);
+    return DeviceProcessSupport::Ptr(new LinuxDeviceProcessSupport);
 }
 
-QList<DeviceProcess> LinuxDevice::buildProcessList(const QString &listProcessesReply) const
+PortsGatheringMethod::Ptr LinuxDevice::portsGatheringMethod() 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)
-                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);
-    }
-
-    qSort(processes);
-    return processes;
+    return LinuxPortsGatheringMethod::Ptr(new LinuxPortsGatheringMethod);
 }
 
 } // namespace RemoteLinux
diff --git a/src/plugins/remotelinux/linuxdevice.h b/src/plugins/remotelinux/linuxdevice.h
index 3d4a5f73294e024e5ae863f38a915e6d0c2c573d..60a05c85b813697018a2b3b04a09bd181f933dfa 100644
--- a/src/plugins/remotelinux/linuxdevice.h
+++ b/src/plugins/remotelinux/linuxdevice.h
@@ -43,6 +43,15 @@ namespace Utils { class PortList; }
 namespace RemoteLinux {
 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;
+};
+
 class REMOTELINUX_EXPORT LinuxDevice : public ProjectExplorer::IDevice
 {
     Q_DECLARE_TR_FUNCTIONS(RemoteLinux::Internal::LinuxDevice)
@@ -62,9 +71,8 @@ public:
     void executeAction(Core::Id actionId, QWidget *parent) const;
     ProjectExplorer::IDevice::Ptr clone() const;
 
-    QString listProcessesCommandLine() const;
-    QString killProcessCommandLine(const ProjectExplorer::DeviceProcess &process) const;
-    QList<ProjectExplorer::DeviceProcess> buildProcessList(const QString &listProcessesReply) const;
+    ProjectExplorer::DeviceProcessSupport::Ptr processSupport() const;
+    ProjectExplorer::PortsGatheringMethod::Ptr portsGatheringMethod() const;
 
 protected:
     LinuxDevice() {}
diff --git a/src/plugins/remotelinux/remotelinuxdebugsupport.cpp b/src/plugins/remotelinux/remotelinuxdebugsupport.cpp
index a0f57b283dff33c2c8b8f5dc58a5084d60bae8ca..baa5be50af1edb0485be27329a94f571422bb45c 100644
--- a/src/plugins/remotelinux/remotelinuxdebugsupport.cpp
+++ b/src/plugins/remotelinux/remotelinuxdebugsupport.cpp
@@ -30,7 +30,6 @@
 #include "remotelinuxdebugsupport.h"
 
 #include "remotelinuxrunconfiguration.h"
-#include "remotelinuxutils.h"
 
 #include <debugger/debuggerengine.h>
 #include <debugger/debuggerstartparameters.h>
@@ -306,8 +305,11 @@ void LinuxDeviceDebugSupport::setFinished()
         return;
     d->portsGatherer.disconnect(this);
     d->appRunner.disconnect(this);
-    if (d->state == StartingRunner)
-        d->appRunner.stop(RemoteLinuxUtils::killApplicationCommandLine(d->remoteFilePath).toUtf8());
+    if (d->state == StartingRunner) {
+        const QString stopCommand
+                = d->device->processSupport()->killProcessByNameCommandLine(d->remoteFilePath);
+        d->appRunner.stop(stopCommand.toUtf8());
+    }
     d->state = Inactive;
 }
 
diff --git a/src/plugins/remotelinux/remotelinuxrunconfigurationfactory.cpp b/src/plugins/remotelinux/remotelinuxrunconfigurationfactory.cpp
index 9cdaf53ab0958f9027144e66c8c15b5f2311f9ff..e4e938cf367d095e0c01398d9a72580d5b477a8a 100644
--- a/src/plugins/remotelinux/remotelinuxrunconfigurationfactory.cpp
+++ b/src/plugins/remotelinux/remotelinuxrunconfigurationfactory.cpp
@@ -32,7 +32,6 @@
 #include "remotelinux_constants.h"
 #include "remotelinuxdeployconfigurationfactory.h"
 #include "remotelinuxrunconfiguration.h"
-#include "remotelinuxutils.h"
 
 #include <projectexplorer/profileinformation.h>
 #include <projectexplorer/target.h>
diff --git a/src/plugins/remotelinux/remotelinuxrunconfigurationwidget.cpp b/src/plugins/remotelinux/remotelinuxrunconfigurationwidget.cpp
index c31910d3addf02b75e19b4b8812d5466ef2b66d6..8cc6c45283c9dad0c2df0a4c2c1f15bd77da74a2 100644
--- a/src/plugins/remotelinux/remotelinuxrunconfigurationwidget.cpp
+++ b/src/plugins/remotelinux/remotelinuxrunconfigurationwidget.cpp
@@ -31,7 +31,6 @@
 
 #include "remotelinuxrunconfiguration.h"
 #include "remotelinuxenvironmentreader.h"
-#include "remotelinuxutils.h"
 
 #include <coreplugin/coreconstants.h>
 #include <coreplugin/icore.h>
diff --git a/src/plugins/remotelinux/remotelinuxruncontrol.cpp b/src/plugins/remotelinux/remotelinuxruncontrol.cpp
index 3492cf3a731124f56141496117548e27ef04c3e4..554816cf5855185a8259b11f62e84b4a2bc325a9 100644
--- a/src/plugins/remotelinux/remotelinuxruncontrol.cpp
+++ b/src/plugins/remotelinux/remotelinuxruncontrol.cpp
@@ -30,7 +30,6 @@
 #include "remotelinuxruncontrol.h"
 
 #include "remotelinuxrunconfiguration.h"
-#include "remotelinuxutils.h"
 
 #include <projectexplorer/devicesupport/deviceapplicationrunner.h>
 #include <projectexplorer/profileinformation.h>
@@ -54,7 +53,6 @@ public:
     QString remoteExecutable;
     QString arguments;
     QString prefix;
-    QByteArray stopCommand;
 };
 
 RemoteLinuxRunControl::RemoteLinuxRunControl(RunConfiguration *rc)
@@ -66,7 +64,6 @@ RemoteLinuxRunControl::RemoteLinuxRunControl(RunConfiguration *rc)
     d->remoteExecutable = lrc->remoteExecutableFilePath();
     d->arguments = lrc->arguments();
     d->prefix = lrc->commandPrefix();
-    d->stopCommand = RemoteLinuxUtils::killApplicationCommandLine(d->remoteExecutable).toUtf8();
 }
 
 RemoteLinuxRunControl::~RemoteLinuxRunControl()
@@ -92,7 +89,9 @@ void RemoteLinuxRunControl::start()
 
 RunControl::StopResult RemoteLinuxRunControl::stop()
 {
-    d->runner.stop(d->stopCommand);
+    const QString stopCommandLine
+            = d->device->processSupport()->killProcessByNameCommandLine(d->remoteExecutable);
+    d->runner.stop(stopCommandLine.toUtf8());
     return AsynchronousStop;
 }
 
@@ -141,11 +140,6 @@ void RemoteLinuxRunControl::setApplicationRunnerPostRunAction(DeviceApplicationH
     d->runner.setPostRunAction(action);
 }
 
-void RemoteLinuxRunControl::overrideStopCommandLine(const QByteArray &commandLine)
-{
-    d->stopCommand = commandLine;
-}
-
 void RemoteLinuxRunControl::setFinished()
 {
     d->runner.disconnect(this);
diff --git a/src/plugins/remotelinux/remotelinuxruncontrol.h b/src/plugins/remotelinux/remotelinuxruncontrol.h
index 86f690d66a507763c4f8cc8a5fc97ee6f4140ebd..207644ca5bafa3436f7ed8e305265ea1cdc9eaa9 100644
--- a/src/plugins/remotelinux/remotelinuxruncontrol.h
+++ b/src/plugins/remotelinux/remotelinuxruncontrol.h
@@ -52,7 +52,6 @@ public:
 
     void setApplicationRunnerPreRunAction(ProjectExplorer::DeviceApplicationHelperAction *action);
     void setApplicationRunnerPostRunAction(ProjectExplorer::DeviceApplicationHelperAction *action);
-    void overrideStopCommandLine(const QByteArray &commandLine);
 
 private slots:
     void handleErrorMessage(const QString &error);
diff --git a/src/plugins/remotelinux/remotelinuxutils.cpp b/src/plugins/remotelinux/remotelinuxutils.cpp
index 907d04e570edc7cd689670e258d978927ef2452b..2eb4518a6c1fbda9279b544bdbada35b208eaf22 100644
--- a/src/plugins/remotelinux/remotelinuxutils.cpp
+++ b/src/plugins/remotelinux/remotelinuxutils.cpp
@@ -29,20 +29,6 @@
 **************************************************************************/
 #include "remotelinuxutils.h"
 
-#include "linuxdevice.h"
-
-#include <QCoreApplication>
-
 namespace RemoteLinux {
 
-QString RemoteLinuxUtils::killApplicationCommandLine(const QString &applicationFilePath)
-{
-    return QString::fromLatin1("cd /proc; for pid in `ls -d [0123456789]*`; "
-        "do "
-            "if [ \"`readlink /proc/$pid/exe`\" = \"%1\" ]; then "
-            "    kill $pid; sleep 1; kill -9 $pid; "
-            "fi; "
-        "done").arg(applicationFilePath);
-}
-
 } // namespace RemoteLinux
diff --git a/src/plugins/remotelinux/remotelinuxutils.h b/src/plugins/remotelinux/remotelinuxutils.h
index b8bbf3b75883408939b33c407a7c540cae1c8225..24d9c37488c2658191b5a525361f5f3d74c0a16b 100644
--- a/src/plugins/remotelinux/remotelinuxutils.h
+++ b/src/plugins/remotelinux/remotelinuxutils.h
@@ -32,15 +32,11 @@
 
 #include "remotelinux_export.h"
 
-#include <QSharedPointer>
-
 namespace RemoteLinux {
-class LinuxDevice;
 
 class REMOTELINUX_EXPORT RemoteLinuxUtils
 {
 public:
-    static QString killApplicationCommandLine(const QString &applicationFilePath);
 };
 
 } // namespace RemoteLinux