diff --git a/src/plugins/qt4projectmanager/qt-s60/qt-s60.pri b/src/plugins/qt4projectmanager/qt-s60/qt-s60.pri
index d66632169280af1f5e5c4bdda56e21e1b719c2d3..8a445fa8de578c6b335aa91a6b92807cff03d119 100644
--- a/src/plugins/qt4projectmanager/qt-s60/qt-s60.pri
+++ b/src/plugins/qt4projectmanager/qt-s60/qt-s60.pri
@@ -8,6 +8,7 @@
         $$PWD/gccetoolchain.cpp \
         $$PWD/s60emulatorrunconfiguration.cpp \
         $$PWD/s60devicerunconfiguration.cpp \
+        $$PWD/s60devicerunconfigurationwidget.cpp \
         $$PWD/serialdevicelister.cpp \
         $$PWD/rvcttoolchain.cpp
     HEADERS += $$PWD/s60devices.h \
@@ -17,6 +18,7 @@
         $$PWD/gccetoolchain.h \
         $$PWD/s60emulatorrunconfiguration.h \
         $$PWD/s60devicerunconfiguration.h \
+        $$PWD/s60devicerunconfigurationwidget.h \
         $$PWD/serialdevicelister.h \
         $$PWD/rvcttoolchain.h
     FORMS += $$PWD/s60devicespreferencepane.ui
diff --git a/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfiguration.cpp b/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfiguration.cpp
index 43606da69f9b0950e0ff3abd7fd008941c03287c..dc3fa07748ce875a82bb59d133496d2ccb978160 100644
--- a/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfiguration.cpp
+++ b/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfiguration.cpp
@@ -28,13 +28,12 @@
 **************************************************************************/
 
 #include "s60devicerunconfiguration.h"
-
+#include "s60devicerunconfigurationwidget.h"
 #include "qt4project.h"
 #include "qtversionmanager.h"
 #include "profilereader.h"
 #include "s60manager.h"
 #include "s60devices.h"
-#include "serialdevicelister.h"
 
 #include <coreplugin/icore.h>
 #include <coreplugin/messagemanager.h>
@@ -48,11 +47,6 @@
 
 #include <debugger/debuggermanager.h>
 
-#include <QtGui/QRadioButton>
-#include <QtGui/QLabel>
-#include <QtGui/QLineEdit>
-#include <QtGui/QComboBox>
-
 using namespace ProjectExplorer;
 using namespace Qt4ProjectManager::Internal;
 
@@ -313,139 +307,6 @@ void S60DeviceRunConfiguration::invalidateCachedTargetInformation()
     emit targetInformationChanged();
 }
 
-// ======== S60DeviceRunConfigurationWidget
-
-S60DeviceRunConfigurationWidget::S60DeviceRunConfigurationWidget(
-        S60DeviceRunConfiguration *runConfiguration,
-        QWidget *parent)
-    : QWidget(parent),
-    m_runConfiguration(runConfiguration)
-{
-    QVBoxLayout *mainBoxLayout = new QVBoxLayout();
-    mainBoxLayout->setMargin(0);
-    setLayout(mainBoxLayout);
-    QFormLayout *formLayout = new QFormLayout();
-    formLayout->setMargin(0);
-    mainBoxLayout->addLayout(formLayout);
-
-    QLabel *nameLabel = new QLabel(tr("Name:"));
-    m_nameLineEdit = new QLineEdit(m_runConfiguration->name());
-    nameLabel->setBuddy(m_nameLineEdit);
-    formLayout->addRow(nameLabel, m_nameLineEdit);
-
-    m_sisxFileLabel = new QLabel(m_runConfiguration->basePackageFilePath() + ".sisx");
-    formLayout->addRow(tr("Install File:"), m_sisxFileLabel);
-
-    m_serialPorts = new QComboBox;
-    updateSerialDevices();
-    connect(S60Manager::instance()->serialDeviceLister(), SIGNAL(updated()),
-            this, SLOT(updateSerialDevices()));
-    connect(m_serialPorts, SIGNAL(activated(int)), this, SLOT(setSerialPort(int)));
-    formLayout->addRow(tr("Device on Serial Port:"), m_serialPorts);
-
-    QWidget *signatureWidget = new QWidget();
-    QVBoxLayout *layout = new QVBoxLayout();
-    signatureWidget->setLayout(layout);
-    mainBoxLayout->addWidget(signatureWidget);
-    QRadioButton *selfSign = new QRadioButton(tr("Self-signed certificate"));
-    QHBoxLayout *customHBox = new QHBoxLayout();
-    customHBox->setMargin(0);
-    QVBoxLayout *radioLayout = new QVBoxLayout();
-    QRadioButton *customSignature = new QRadioButton();
-    radioLayout->addWidget(customSignature);
-    radioLayout->addStretch(10);
-    customHBox->addLayout(radioLayout);
-    QFormLayout *customLayout = new QFormLayout();
-    customLayout->setMargin(0);
-    customLayout->setLabelAlignment(Qt::AlignRight);
-    Utils::PathChooser *signaturePath = new Utils::PathChooser();
-    signaturePath->setExpectedKind(Utils::PathChooser::File);
-    signaturePath->setPromptDialogTitle(tr("Choose certificate file (.cer)"));
-    customLayout->addRow(new QLabel(tr("Custom certificate:")), signaturePath);
-    Utils::PathChooser *keyPath = new Utils::PathChooser();
-    keyPath->setExpectedKind(Utils::PathChooser::File);
-    keyPath->setPromptDialogTitle(tr("Choose key file (.key / .pem)"));
-    customLayout->addRow(new QLabel(tr("Key file:")), keyPath);
-    customHBox->addLayout(customLayout);
-    customHBox->addStretch(10);
-    layout->addWidget(selfSign);
-    layout->addLayout(customHBox);
-    layout->addStretch(10);
-
-    switch (m_runConfiguration->signingMode()) {
-    case S60DeviceRunConfiguration::SignSelf:
-        selfSign->setChecked(true);
-        break;
-    case S60DeviceRunConfiguration::SignCustom:
-        customSignature->setChecked(true);
-        break;
-    }
-
-    signaturePath->setPath(m_runConfiguration->customSignaturePath());
-    keyPath->setPath(m_runConfiguration->customKeyPath());
-
-    connect(m_nameLineEdit, SIGNAL(textEdited(QString)),
-        this, SLOT(nameEdited(QString)));
-    connect(m_runConfiguration, SIGNAL(targetInformationChanged()),
-            this, SLOT(updateTargetInformation()));
-    connect(selfSign, SIGNAL(toggled(bool)), this, SLOT(selfSignToggled(bool)));
-    connect(customSignature, SIGNAL(toggled(bool)), this, SLOT(customSignatureToggled(bool)));
-    connect(signaturePath, SIGNAL(changed(QString)), this, SLOT(signaturePathChanged(QString)));
-    connect(keyPath, SIGNAL(changed(QString)), this, SLOT(keyPathChanged(QString)));
-}
-
-void S60DeviceRunConfigurationWidget::updateSerialDevices()
-{
-    m_serialPorts->clear();
-    QString runConfigurationPortName = m_runConfiguration->serialPortName();
-    QList<SerialDeviceLister::SerialDevice> serialDevices = S60Manager::instance()->serialDeviceLister()->serialDevices();
-    for (int i = 0; i < serialDevices.size(); ++i) {
-        const SerialDeviceLister::SerialDevice &device = serialDevices.at(i);
-        m_serialPorts->addItem(device.friendlyName, device.portName);
-        if (device.portName == runConfigurationPortName)
-            m_serialPorts->setCurrentIndex(i);
-    }
-    QString selectedPortName = m_serialPorts->itemData(m_serialPorts->currentIndex()).toString();
-    if (m_serialPorts->count() > 0 && runConfigurationPortName != selectedPortName)
-        m_runConfiguration->setSerialPortName(selectedPortName);
-}
-
-void S60DeviceRunConfigurationWidget::nameEdited(const QString &text)
-{
-    m_runConfiguration->setName(text);
-}
-
-void S60DeviceRunConfigurationWidget::updateTargetInformation()
-{
-    m_sisxFileLabel->setText(m_runConfiguration->basePackageFilePath() + ".sisx");
-}
-
-void S60DeviceRunConfigurationWidget::setSerialPort(int index)
-{
-    m_runConfiguration->setSerialPortName(m_serialPorts->itemData(index).toString());
-}
-
-void S60DeviceRunConfigurationWidget::selfSignToggled(bool toggle)
-{
-    if (toggle)
-        m_runConfiguration->setSigningMode(S60DeviceRunConfiguration::SignSelf);
-}
-
-void S60DeviceRunConfigurationWidget::customSignatureToggled(bool toggle)
-{
-    if (toggle)
-        m_runConfiguration->setSigningMode(S60DeviceRunConfiguration::SignCustom);
-}
-
-void S60DeviceRunConfigurationWidget::signaturePathChanged(const QString &path)
-{
-    m_runConfiguration->setCustomSignaturePath(path);
-}
-
-void S60DeviceRunConfigurationWidget::keyPathChanged(const QString &path)
-{
-    m_runConfiguration->setCustomKeyPath(path);
-}
 
 // ======== S60DeviceRunConfigurationFactory
 
diff --git a/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfiguration.h b/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfiguration.h
index 775804cb201781bac4ac2a142e7c63571792d62c..41b48a9e248a4875eb3215d8eaa219b8072eada2 100644
--- a/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfiguration.h
+++ b/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfiguration.h
@@ -35,16 +35,8 @@
 #include <projectexplorer/runconfiguration.h>
 #include <projectexplorer/toolchain.h>
 
-#include <QtGui/QWidget>
-
 #include <QtCore/QProcess>
 
-QT_BEGIN_NAMESPACE
-class QLabel;
-class QLineEdit;
-class QComboBox;
-QT_END_NAMESPACE
-
 namespace Debugger {
     class DebuggerStartParameters;
 }
@@ -111,30 +103,6 @@ private:
     QString m_customKeyPath;
 };
 
-class S60DeviceRunConfigurationWidget : public QWidget
-{
-    Q_OBJECT
-public:
-    explicit S60DeviceRunConfigurationWidget(S60DeviceRunConfiguration *runConfiguration,
-                                      QWidget *parent = 0);
-
-private slots:
-    void nameEdited(const QString &text);
-    void updateTargetInformation();
-    void updateSerialDevices();
-    void setSerialPort(int index);
-    void selfSignToggled(bool toggle);
-    void customSignatureToggled(bool toggle);
-    void signaturePathChanged(const QString &path);
-    void keyPathChanged(const QString &path);
-
-private:
-    S60DeviceRunConfiguration *m_runConfiguration;
-    QComboBox *m_serialPorts;
-    QLineEdit *m_nameLineEdit;
-    QLabel *m_sisxFileLabel;
-};
-
 class S60DeviceRunConfigurationFactory : public ProjectExplorer::IRunConfigurationFactory
 {
     Q_OBJECT
diff --git a/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfigurationwidget.cpp b/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfigurationwidget.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..40faa686c407efb96b319fc9e74b137a452cf8c8
--- /dev/null
+++ b/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfigurationwidget.cpp
@@ -0,0 +1,318 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** GNU Lesser General Public License Usage
+**
+** Alternatively, 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://qt.nokia.com/contact.
+**
+**************************************************************************/
+
+#include "s60devicerunconfigurationwidget.h"
+#include "s60devicerunconfiguration.h"
+#include "s60manager.h"
+#include "launcher.h"
+#include "serialdevicelister.h"
+
+#include <utils/detailswidget.h>
+#include <utils/qtcassert.h>
+#include <utils/pathchooser.h>
+
+#include <QtCore/QTimer>
+#include <QtGui/QRadioButton>
+#include <QtGui/QLabel>
+#include <QtGui/QLineEdit>
+#include <QtGui/QComboBox>
+#include <QtGui/QVBoxLayout>
+#include <QtGui/QHBoxLayout>
+#include <QtGui/QFormLayout>
+#include <QtGui/QToolButton>
+#include <QtGui/QStyle>
+#include <QtGui/QApplication>
+#include <QtGui/QSpacerItem>
+
+namespace Qt4ProjectManager {
+namespace Internal {
+
+S60DeviceRunConfigurationWidget::S60DeviceRunConfigurationWidget(
+            S60DeviceRunConfiguration *runConfiguration,
+            QWidget *parent)
+    : QWidget(parent),
+    m_runConfiguration(runConfiguration),
+    m_detailsWidget(new Utils::DetailsWidget),
+    m_serialPortsCombo(new QComboBox),
+    m_nameLineEdit(new QLineEdit(m_runConfiguration->name())),
+    m_sisxFileLabel(new QLabel(m_runConfiguration->basePackageFilePath() + QLatin1String(".sisx"))),
+    m_deviceInfoButton(new QToolButton),
+    m_deviceInfoDescriptionLabel(new QLabel(tr("Device:"))),
+    m_deviceInfoLabel(new QLabel),
+    m_infoTimeOutTimer(0)
+{
+    QVBoxLayout *mainBoxLayout = new QVBoxLayout();
+    mainBoxLayout->setMargin(0);
+    setLayout(mainBoxLayout);
+    mainBoxLayout->addWidget(m_detailsWidget);
+    QWidget *detailsContainer = new QWidget;
+    m_detailsWidget->setWidget(detailsContainer);
+
+    QVBoxLayout *detailsBoxLayout = new QVBoxLayout();
+    detailsBoxLayout->setMargin(0);
+    detailsContainer->setLayout(detailsBoxLayout);
+
+    QFormLayout *formLayout = new QFormLayout();
+    formLayout->setMargin(0);
+    detailsBoxLayout->addLayout(formLayout);
+    // Name control
+    QLabel *nameLabel = new QLabel(tr("Name:"));
+    nameLabel->setBuddy(m_nameLineEdit);
+    formLayout->addRow(nameLabel, m_nameLineEdit);
+    formLayout->addRow(tr("Install File:"), m_sisxFileLabel);
+
+    updateSerialDevices();    
+    connect(S60Manager::instance()->serialDeviceLister(), SIGNAL(updated()),
+            this, SLOT(updateSerialDevices()));
+    // Serial devices control
+    connect(m_serialPortsCombo, SIGNAL(activated(int)), this, SLOT(setSerialPort(int)));
+    QHBoxLayout *serialPortHBoxLayout = new QHBoxLayout;
+    serialPortHBoxLayout->addSpacerItem(new QSpacerItem(0, 0, QSizePolicy::MinimumExpanding, QSizePolicy::Ignored));
+    serialPortHBoxLayout->addWidget(m_serialPortsCombo);
+
+    formLayout->addRow(tr("Device on Serial Port:"), serialPortHBoxLayout);
+
+    // Device Info with button. Widgets are enabled in above call to updateSerialDevices()
+    QHBoxLayout *infoHBoxLayout = new QHBoxLayout;
+    m_deviceInfoLabel->setWordWrap(true);
+    infoHBoxLayout->addWidget(m_deviceInfoLabel);
+    infoHBoxLayout->addSpacerItem(new QSpacerItem(0, 0, QSizePolicy::MinimumExpanding, QSizePolicy::Ignored));
+    infoHBoxLayout->addWidget(m_deviceInfoButton);
+    m_deviceInfoButton->setIcon(qApp->style()->standardIcon(QStyle::SP_MessageBoxInformation));
+    m_deviceInfoButton->setToolTip(tr("Queries the device for information"));
+    connect(m_deviceInfoButton, SIGNAL(clicked()), this, SLOT(updateDeviceInfo()));
+    formLayout->addRow(m_deviceInfoDescriptionLabel, infoHBoxLayout);
+
+    // Signature/certificate stuff.
+    QWidget *signatureWidget = new QWidget();
+    QVBoxLayout *layout = new QVBoxLayout();
+    signatureWidget->setLayout(layout);
+    detailsBoxLayout->addWidget(signatureWidget);
+    QRadioButton *selfSign = new QRadioButton(tr("Self-signed certificate"));
+    QHBoxLayout *customHBox = new QHBoxLayout();
+    customHBox->setMargin(0);
+    QVBoxLayout *radioLayout = new QVBoxLayout();
+    QRadioButton *customSignature = new QRadioButton();
+    radioLayout->addWidget(customSignature);
+    radioLayout->addStretch(10);
+    customHBox->addLayout(radioLayout);
+    QFormLayout *customLayout = new QFormLayout();
+    customLayout->setMargin(0);
+    customLayout->setLabelAlignment(Qt::AlignRight);
+    Utils::PathChooser *signaturePath = new Utils::PathChooser();
+    signaturePath->setExpectedKind(Utils::PathChooser::File);
+    signaturePath->setPromptDialogTitle(tr("Choose certificate file (.cer)"));
+    customLayout->addRow(new QLabel(tr("Custom certificate:")), signaturePath);
+    Utils::PathChooser *keyPath = new Utils::PathChooser();
+    keyPath->setExpectedKind(Utils::PathChooser::File);
+    keyPath->setPromptDialogTitle(tr("Choose key file (.key / .pem)"));
+    customLayout->addRow(new QLabel(tr("Key file:")), keyPath);
+    customHBox->addLayout(customLayout);
+    customHBox->addStretch(10);
+    layout->addWidget(selfSign);
+    layout->addLayout(customHBox);
+    layout->addStretch(10);
+
+    switch (m_runConfiguration->signingMode()) {
+    case S60DeviceRunConfiguration::SignSelf:
+        selfSign->setChecked(true);
+        break;
+    case S60DeviceRunConfiguration::SignCustom:
+        customSignature->setChecked(true);
+        break;
+    }
+
+    signaturePath->setPath(m_runConfiguration->customSignaturePath());
+    keyPath->setPath(m_runConfiguration->customKeyPath());
+
+    connect(m_nameLineEdit, SIGNAL(textEdited(QString)),
+            this, SLOT(nameEdited(QString)));
+    connect(m_runConfiguration, SIGNAL(targetInformationChanged()),
+            this, SLOT(updateTargetInformation()));
+    connect(selfSign, SIGNAL(toggled(bool)), this, SLOT(selfSignToggled(bool)));
+    connect(customSignature, SIGNAL(toggled(bool)), this, SLOT(customSignatureToggled(bool)));
+    connect(signaturePath, SIGNAL(changed(QString)), this, SLOT(signaturePathChanged(QString)));
+    connect(keyPath, SIGNAL(changed(QString)), this, SLOT(keyPathChanged(QString)));
+    updateSummary();
+}
+
+void S60DeviceRunConfigurationWidget::updateSerialDevices()
+{
+    m_serialPortsCombo->clear();
+    clearDeviceInfo();
+    const QString previousRunConfigurationPortName = m_runConfiguration->serialPortName();
+    const QList<SerialDeviceLister::SerialDevice> serialDevices = S60Manager::instance()->serialDeviceLister()->serialDevices();
+    int newIndex = -1;
+    for (int i = 0; i < serialDevices.size(); ++i) {
+        const SerialDeviceLister::SerialDevice &device = serialDevices.at(i);
+        m_serialPortsCombo->addItem(device.friendlyName, device.portName);
+        if (device.portName == previousRunConfigurationPortName)
+            newIndex = i;
+    }
+    // Set new index: prefer to keep old or set to 0, if available.
+    if (newIndex == -1 && !serialDevices.empty())
+        newIndex = 0;
+    m_serialPortsCombo->setCurrentIndex(newIndex);
+    if (newIndex == -1) {
+        m_deviceInfoButton->setEnabled(false);
+        m_runConfiguration->setSerialPortName(QString());
+    } else {
+        m_deviceInfoButton->setEnabled(true);
+        const QString newPortName = portName(newIndex);
+        if (newPortName != previousRunConfigurationPortName)
+            m_runConfiguration->setSerialPortName(newPortName);
+    }
+}
+
+QString S60DeviceRunConfigurationWidget::portName(int index) const
+{
+    return index >= 0 ? m_serialPortsCombo->itemData(index).toString() : QString();
+}
+
+QString S60DeviceRunConfigurationWidget::currentPortName() const
+{
+    return portName(m_serialPortsCombo->currentIndex());
+}
+
+void S60DeviceRunConfigurationWidget::nameEdited(const QString &text)
+{
+    m_runConfiguration->setName(text);
+}
+
+void S60DeviceRunConfigurationWidget::updateTargetInformation()
+{
+    m_sisxFileLabel->setText(m_runConfiguration->basePackageFilePath() + QLatin1String(".sisx"));
+}
+
+void S60DeviceRunConfigurationWidget::setSerialPort(int index)
+{
+    m_runConfiguration->setSerialPortName(portName(index));
+    m_deviceInfoButton->setEnabled(index >= 0);
+    clearDeviceInfo();
+    updateSummary();
+}
+
+void S60DeviceRunConfigurationWidget::selfSignToggled(bool toggle)
+{
+    if (toggle)
+        m_runConfiguration->setSigningMode(S60DeviceRunConfiguration::SignSelf);
+    updateSummary();
+}
+
+void S60DeviceRunConfigurationWidget::customSignatureToggled(bool toggle)
+{
+    if (toggle)
+        m_runConfiguration->setSigningMode(S60DeviceRunConfiguration::SignCustom);
+    updateSummary();
+}
+
+void S60DeviceRunConfigurationWidget::signaturePathChanged(const QString &path)
+{
+    m_runConfiguration->setCustomSignaturePath(path);
+    updateSummary();
+}
+
+void S60DeviceRunConfigurationWidget::keyPathChanged(const QString &path)
+{
+    m_runConfiguration->setCustomKeyPath(path);
+    updateSummary();
+}
+
+void S60DeviceRunConfigurationWidget::updateSummary()
+{
+    //: Summary text of S60 device run configuration
+    const QString device = m_serialPortsCombo->currentIndex() != -1 ?
+                           m_serialPortsCombo->currentText() :
+                           tr("<No Device>");
+    const QString signature = m_runConfiguration->signingMode() == S60DeviceRunConfiguration::SignCustom ?
+                              tr("(custom certificate)") :
+                              tr("(self-signed certificate)");
+    m_detailsWidget->setSummaryText(tr("Summary: Run on '%1' %2").arg(device, signature));
+}
+
+void S60DeviceRunConfigurationWidget::clearDeviceInfo()
+{
+    // Restore text & color
+    m_deviceInfoLabel->clear();
+    m_deviceInfoLabel->setStyleSheet(QString());
+}
+
+void S60DeviceRunConfigurationWidget::setDeviceInfoLabel(const QString &message, bool isError)
+{
+    m_deviceInfoLabel->setStyleSheet(isError ?
+                                     QString(QLatin1String("background-color: red;")) :
+                                     QString());
+    m_deviceInfoLabel->setText(message);
+}
+
+void S60DeviceRunConfigurationWidget::updateDeviceInfo()
+{
+    QString message;
+    setDeviceInfoLabel(tr("Connecting..."));
+    const bool ok = getDeviceInfo(&message);
+    setDeviceInfoLabel(message, !ok);
+}
+
+bool S60DeviceRunConfigurationWidget::getDeviceInfo(QString *message)
+{
+    // Do a launcher run with the ping protocol. Instantiate launcher on heap
+    // as not to introduce delays when destructing a device with timeout
+    trk::Launcher *launcher = new trk::Launcher(trk::Launcher::ActionPingOnly, this);
+    launcher->setTrkServerName(currentPortName());
+    if (!launcher->startServer(message)) {
+        launcher->deleteLater();
+        return false;
+    }
+    // Set up event loop in the foreground with a timer to quit in case of  timeout.
+    QEventLoop eventLoop;
+    if (!m_infoTimeOutTimer) {
+        m_infoTimeOutTimer = new QTimer(this);
+        m_infoTimeOutTimer->setInterval(3000);
+        m_infoTimeOutTimer->setSingleShot(true);
+    }
+    connect(m_infoTimeOutTimer, SIGNAL(timeout()), &eventLoop, SLOT(quit()));
+    connect(launcher, SIGNAL(finished()), &eventLoop, SLOT(quit()));
+    // Go!
+    QApplication::setOverrideCursor(Qt::BusyCursor);
+    m_infoTimeOutTimer->start();
+    eventLoop.exec(QEventLoop::ExcludeUserInputEvents);
+    m_infoTimeOutTimer->disconnect();
+    QApplication::restoreOverrideCursor();
+    // Anything received?
+    *message = launcher->deviceDescription();
+    launcher->deleteLater();
+    if (message->isEmpty()) {
+        *message = tr("A timeout occurred while querying the device. Check whether Trk is running");
+        return false;
+    }
+    return true;
+}
+
+} // namespace Internal
+} // namespace Qt4ProjectManager
diff --git a/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfigurationwidget.h b/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfigurationwidget.h
new file mode 100644
index 0000000000000000000000000000000000000000..65c5d192443d6ebfbb1e4ce39e6f8295c34cb4bb
--- /dev/null
+++ b/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfigurationwidget.h
@@ -0,0 +1,95 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** GNU Lesser General Public License Usage
+**
+** Alternatively, 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://qt.nokia.com/contact.
+**
+**************************************************************************/
+
+#ifndef S60DEVICERUNCONFIGURATIONWIDGET_H
+#define S60DEVICERUNCONFIGURATIONWIDGET_H
+
+#include <QtGui/QWidget>
+
+QT_BEGIN_NAMESPACE
+class QLabel;
+class QTimer;
+class QLineEdit;
+class QComboBox;
+class QToolButton;
+QT_END_NAMESPACE
+
+namespace Utils {
+    class DetailsWidget;
+}
+
+namespace Qt4ProjectManager {
+namespace Internal {
+
+class S60DeviceRunConfiguration;
+
+/* Configuration widget for S60 devices on serial ports that are
+ * provided by the SerialDeviceLister class. Has an info/test
+ * button connecting to the device and showing info. */
+class S60DeviceRunConfigurationWidget : public QWidget
+{
+    Q_OBJECT
+public:
+    explicit S60DeviceRunConfigurationWidget(S60DeviceRunConfiguration *runConfiguration,
+                                      QWidget *parent = 0);
+
+private slots:
+    void nameEdited(const QString &text);
+    void updateTargetInformation();
+    void updateSerialDevices();
+    void setSerialPort(int index);
+    void selfSignToggled(bool toggle);
+    void customSignatureToggled(bool toggle);
+    void signaturePathChanged(const QString &path);
+    void keyPathChanged(const QString &path);
+    void updateSummary();
+    void updateDeviceInfo();
+    void clearDeviceInfo();
+
+private:
+    inline QString currentPortName() const;
+    inline QString portName(int index) const;
+    bool getDeviceInfo(QString *message);
+    void setDeviceInfoLabel(const QString &message, bool isError = false);
+
+    S60DeviceRunConfiguration *m_runConfiguration;
+    Utils::DetailsWidget *m_detailsWidget;
+    QComboBox *m_serialPortsCombo;
+    QLineEdit *m_nameLineEdit;
+    QLabel *m_sisxFileLabel;
+    QToolButton *m_deviceInfoButton;
+    QLabel *m_deviceInfoDescriptionLabel;
+    QLabel *m_deviceInfoLabel;
+    QTimer *m_infoTimeOutTimer;
+};
+
+} // namespace Internal
+} // namespace Qt4ProjectManager
+
+#endif // S60DEVICERUNCONFIGURATIONWIDGET_H
diff --git a/src/plugins/qt4projectmanager/qt-s60/s60emulatorrunconfiguration.cpp b/src/plugins/qt4projectmanager/qt-s60/s60emulatorrunconfiguration.cpp
index aeabbebc24b2464f464147be24917544e837b869..b1c65fa0e926273cce012300e9c7f20dce4580ea 100644
--- a/src/plugins/qt4projectmanager/qt-s60/s60emulatorrunconfiguration.cpp
+++ b/src/plugins/qt4projectmanager/qt-s60/s60emulatorrunconfiguration.cpp
@@ -38,10 +38,14 @@
 #include <coreplugin/icore.h>
 #include <coreplugin/messagemanager.h>
 #include <utils/qtcassert.h>
+#include <utils/detailswidget.h>
 #include <projectexplorer/projectexplorerconstants.h>
 #include <projectexplorer/project.h>
 #include <projectexplorer/persistentsettings.h>
 
+#include <QtGui/QLabel>
+#include <QtGui/QLineEdit>
+
 using namespace ProjectExplorer;
 using namespace Qt4ProjectManager::Internal;
 
@@ -175,24 +179,34 @@ void S60EmulatorRunConfiguration::invalidateCachedTargetInformation()
 S60EmulatorRunConfigurationWidget::S60EmulatorRunConfigurationWidget(S60EmulatorRunConfiguration *runConfiguration,
                                                                      QWidget *parent)
     : QWidget(parent),
-    m_runConfiguration(runConfiguration)
+    m_runConfiguration(runConfiguration),
+    m_detailsWidget(new Utils::DetailsWidget),
+    m_nameLineEdit(new QLineEdit(m_runConfiguration->name())),
+    m_executableLabel(new QLabel(m_runConfiguration->executable()))
 {
-    QFormLayout *toplayout = new QFormLayout();
-    toplayout->setMargin(0);
-    setLayout(toplayout);
+    QVBoxLayout *mainBoxLayout = new QVBoxLayout();
+    mainBoxLayout->setMargin(0);
+    setLayout(mainBoxLayout);
+    mainBoxLayout->addWidget(m_detailsWidget);
+    QWidget *detailsContainer = new QWidget;
+    m_detailsWidget->setWidget(detailsContainer);
+
+    QFormLayout *detailsFormLayout = new QFormLayout();
+    detailsFormLayout->setMargin(0);
+    detailsContainer->setLayout(detailsFormLayout);
 
     QLabel *nameLabel = new QLabel(tr("Name:"));
-    m_nameLineEdit = new QLineEdit(m_runConfiguration->name());
+
     nameLabel->setBuddy(m_nameLineEdit);
-    toplayout->addRow(nameLabel, m_nameLineEdit);
+    detailsFormLayout->addRow(nameLabel, m_nameLineEdit);
 
-    m_executableLabel = new QLabel(m_runConfiguration->executable());
-    toplayout->addRow(tr("Executable:"), m_executableLabel);
+    detailsFormLayout->addRow(tr("Executable:"), m_executableLabel);
 
     connect(m_nameLineEdit, SIGNAL(textEdited(QString)),
         this, SLOT(nameEdited(QString)));
     connect(m_runConfiguration, SIGNAL(targetInformationChanged()),
             this, SLOT(updateTargetInformation()));
+    updateSummary();
 }
 
 void S60EmulatorRunConfigurationWidget::nameEdited(const QString &text)
@@ -205,6 +219,11 @@ void S60EmulatorRunConfigurationWidget::updateTargetInformation()
     m_executableLabel->setText(m_runConfiguration->executable());
 }
 
+void S60EmulatorRunConfigurationWidget::updateSummary()
+{
+    m_detailsWidget->setSummaryText(tr("Summary: Run %1 in emulator").arg(m_runConfiguration->executable()));
+}
+
 // ======== S60EmulatorRunConfigurationFactory
 
 S60EmulatorRunConfigurationFactory::S60EmulatorRunConfigurationFactory(QObject *parent)
diff --git a/src/plugins/qt4projectmanager/qt-s60/s60emulatorrunconfiguration.h b/src/plugins/qt4projectmanager/qt-s60/s60emulatorrunconfiguration.h
index 1682478d95a234789994d7574b9eb56a9db35be9..8ba0aeded4d6a9a5ee533cfa9f74a0ff514c17a2 100644
--- a/src/plugins/qt4projectmanager/qt-s60/s60emulatorrunconfiguration.h
+++ b/src/plugins/qt4projectmanager/qt-s60/s60emulatorrunconfiguration.h
@@ -34,8 +34,15 @@
 #include <projectexplorer/applicationlauncher.h>
 
 #include <QtGui/QWidget>
-#include <QtGui/QLabel>
-#include <QtGui/QLineEdit>
+
+QT_BEGIN_NAMESPACE
+class QLabel;
+class QLineEdit;
+QT_END_NAMESPACE
+
+namespace Utils {
+    class DetailsWidget;
+}
 
 namespace Qt4ProjectManager {
 namespace Internal {
@@ -79,9 +86,11 @@ public:
 private slots:
     void nameEdited(const QString &text);
     void updateTargetInformation();
+    void updateSummary();
 
 private:
     S60EmulatorRunConfiguration *m_runConfiguration;
+    Utils::DetailsWidget *m_detailsWidget;
     QLineEdit *m_nameLineEdit;
     QLabel *m_executableLabel;
 };
diff --git a/src/shared/trk/launcher.cpp b/src/shared/trk/launcher.cpp
index 08af4a215359f409423ac4bcde93d3b9bc744b16..cff53c02a1831e1492895b4138b1de53e3852056 100644
--- a/src/shared/trk/launcher.cpp
+++ b/src/shared/trk/launcher.cpp
@@ -73,7 +73,8 @@ LauncherPrivate::LauncherPrivate() :
 {
 }
 
-Launcher::Launcher(Actions startupActions) :
+Launcher::Launcher(Actions startupActions, QObject *parent) :
+    QObject(parent),
     d(new LauncherPrivate)
 {
     d->m_startupActions = startupActions;
@@ -318,6 +319,11 @@ void Launcher::handleResult(const TrkResult &result)
     }
 }
 
+QString Launcher::deviceDescription(unsigned verbose) const
+{
+    return d->m_session.deviceDescription(verbose);
+}
+
 void Launcher::handleTrkVersion(const TrkResult &result)
 {
     if (result.errorCode() || result.data.size() < 5) {
@@ -325,19 +331,13 @@ void Launcher::handleTrkVersion(const TrkResult &result)
             emit finished();
         return;
     }
-    const int trkMajor = result.data.at(1);
-    const int trkMinor = result.data.at(2);
-    const int protocolMajor = result.data.at(3);
-    const int protocolMinor = result.data.at(4);
+    d->m_session.trkAppVersion.trkMajor = result.data.at(1);
+    d->m_session.trkAppVersion.trkMinor = result.data.at(2);
+    d->m_session.trkAppVersion.protocolMajor = result.data.at(3);
+    d->m_session.trkAppVersion.protocolMinor = result.data.at(4);
     // Ping mode: Log & Terminate
     if (d->m_startupActions == ActionPingOnly) {
-        QString msg;
-        QTextStream(&msg) << "CPU: " << d->m_session.cpuMajor << '.' << d->m_session.cpuMinor << ' '
-                << (d->m_session.bigEndian ? "big endian" : "little endian")
-                << " type size: " << d->m_session.defaultTypeSize
-                << " float size: " << d->m_session.fpTypeSize
-                << " Trk: v" << trkMajor << '.' << trkMinor << " Protocol: " << protocolMajor << '.' << protocolMinor;
-        qWarning("%s", qPrintable(msg));
+        qWarning("%s", qPrintable(deviceDescription()));
         emit finished();
     }
 }
diff --git a/src/shared/trk/launcher.h b/src/shared/trk/launcher.h
index a216b79fcb33cbc89179ba8890e13726fbb50fcf..93f5d52923e6baeed1ba53090ede3f058329bbe5 100644
--- a/src/shared/trk/launcher.h
+++ b/src/shared/trk/launcher.h
@@ -55,7 +55,8 @@ public:
         ActionCopyInstallRun = ActionCopy | ActionInstall | ActionRun
     };
 
-    Launcher(trk::Launcher::Actions startupActions = trk::Launcher::ActionPingOnly);
+    explicit Launcher(trk::Launcher::Actions startupActions = trk::Launcher::ActionPingOnly,
+                      QObject *parent = 0);
     ~Launcher();
     void addStartupActions(trk::Launcher::Actions startupActions);
     void setTrkServerName(const QString &name);
@@ -67,6 +68,9 @@ public:
     void setSerialFrame(bool b);
     bool serialFrame() const;
 
+    // becomes valid after successful execution of ActionPingOnly
+    QString deviceDescription(unsigned verbose = 0u) const;
+
 signals:
     void copyingStarted();
     void canNotConnect(const QString &errorMessage);
diff --git a/src/shared/trk/trkdevice.cpp b/src/shared/trk/trkdevice.cpp
index a303ba1c2d35c998c7ffc00476421b86b5bc5090..ef7bc8b34f8a239bb35d1408c844f832aeb38881 100644
--- a/src/shared/trk/trkdevice.cpp
+++ b/src/shared/trk/trkdevice.cpp
@@ -436,15 +436,52 @@ void WriterThread::terminate()
 }
 
 #ifdef Q_OS_WIN
-static inline bool overlappedSyncWrite(HANDLE file, const char *data,
+
+static inline QString msgTerminated(int size)
+{
+    return QString::fromLatin1("Terminated with %1 bytes pending.").arg(size);
+}
+
+// Interruptible synchronous write function.
+static inline bool overlappedSyncWrite(HANDLE file,
+                                       const bool &terminateFlag,
+                                       const char *data,
                                        DWORD size, DWORD *charsWritten,
-                                       OVERLAPPED *overlapped)
+                                       OVERLAPPED *overlapped,
+                                       QString *errorMessage)
 {
     if (WriteFile(file, data, size, charsWritten, overlapped))
         return true;
-    if (GetLastError() != ERROR_IO_PENDING)
+    const DWORD writeError = GetLastError();
+    if (writeError != ERROR_IO_PENDING) {
+        *errorMessage = QString::fromLatin1("WriteFile failed: %1").arg(winErrorMessage(writeError));
+        return false;
+    }
+    // Wait for written or thread terminated
+    const DWORD timeoutMS = 200;
+    const unsigned maxAttempts = 20;
+    DWORD wr = WaitForSingleObject(overlapped->hEvent, timeoutMS);
+    for (unsigned n = 0; wr == WAIT_TIMEOUT && n < maxAttempts && !terminateFlag;
+         wr = WaitForSingleObject(overlapped->hEvent, timeoutMS), n++);
+    if (terminateFlag) {
+        *errorMessage = msgTerminated(size);
+        return false;
+    }
+    switch (wr) {
+    case WAIT_OBJECT_0:
+        break;
+    case WAIT_TIMEOUT:
+        *errorMessage = QString::fromLatin1("Write timed out.");
+        return false;
+    default:
+        *errorMessage = QString::fromLatin1("Error while waiting for WriteFile results: %1").arg(winErrorMessage(GetLastError()));
+        return false;
+    }
+    if (!GetOverlappedResult(file, overlapped, charsWritten, TRUE)) {
+        *errorMessage = QString::fromLatin1("Error writing %1 bytes: %2").arg(size).arg(winErrorMessage(GetLastError()));
         return false;
-    return GetOverlappedResult(file, overlapped, charsWritten, TRUE);
+    }
+    return true;
 }
 #endif
 
@@ -453,8 +490,7 @@ bool WriterThread::write(const QByteArray &data, QString *errorMessage)
     QMutexLocker locker(&m_context->mutex);
 #ifdef Q_OS_WIN
     DWORD charsWritten;
-    if (!overlappedSyncWrite(m_context->device, data.data(), data.size(), &charsWritten, &m_context->writeOverlapped)) {
-        *errorMessage = QString::fromLatin1("Error writing data: %1").arg(winErrorMessage(GetLastError()));
+    if (!overlappedSyncWrite(m_context->device, m_terminate, data.data(), data.size(), &charsWritten, &m_context->writeOverlapped, errorMessage)) {
         return false;
     }
     FlushFileBuffers(m_context->device);
@@ -473,8 +509,10 @@ bool WriterThread::trkWriteRawMessage(const TrkMessage &msg)
     const QByteArray ba = frameMessage(msg.code, msg.token, msg.data, m_context->serialFrame);
     QString errorMessage;
     const bool rc = write(ba, &errorMessage);
-    if (!rc)
+    if (!rc) {
+        qWarning("%s\n", qPrintable(errorMessage));
         emit error(errorMessage);
+    }
     return rc;
 }
 
diff --git a/src/shared/trk/trkutils.cpp b/src/shared/trk/trkutils.cpp
index 463415e7c21c3da5443fdd4c25b51147d1cd7c20..93df3937994f5fcc32513c57775dfebddeaed8dd 100644
--- a/src/shared/trk/trkutils.cpp
+++ b/src/shared/trk/trkutils.cpp
@@ -36,6 +36,75 @@
 
 namespace trk {
 
+TrkAppVersion::TrkAppVersion()
+{
+    reset();
+}
+
+void TrkAppVersion::reset()
+{
+    trkMajor = trkMinor= protocolMajor = protocolMinor = 0;
+}
+
+Session::Session()
+{
+    reset();
+}
+
+void Session::reset()
+{
+    cpuMajor = 0;
+    cpuMinor = 0;
+    bigEndian = 0;
+    defaultTypeSize = 0;
+    fpTypeSize = 0;
+    extended1TypeSize = 0;
+    extended2TypeSize = 0;
+    pid = 0;
+    tid = 0;
+    codeseg = 0;
+    dataseg = 0;
+
+    currentThread = 0;
+    libraries.clear();
+    trkAppVersion.reset();
+}
+
+inline void formatCpu(QTextStream &str,int major, int minor)
+{
+    str << "CPU: v" << major << '.' << minor;
+    switch (major) {
+    case 0x04:
+        str << " ARM";
+        break;
+    }
+    switch (minor) {
+    case 0x00:
+        str << " 920T";
+        break;
+    }
+ }
+
+QString Session::deviceDescription(unsigned verbose) const
+{
+    QString msg;
+    if (cpuMajor) {
+        QTextStream str(&msg);
+        formatCpu(str, cpuMajor, cpuMinor);
+        str << ", "  << (bigEndian ? "big endian" : "little endian");
+        if (verbose) {
+            if (defaultTypeSize)
+                str << ", type size: " << defaultTypeSize;
+            if (fpTypeSize)
+                str << ", float size: " << fpTypeSize;
+        }
+        str << ", Trk: v" << trkAppVersion.trkMajor << '.' << trkAppVersion.trkMinor
+            << " Protocol: v" << trkAppVersion.protocolMajor << '.' << trkAppVersion.protocolMinor;
+    }
+    return msg;
+}
+
+
 // FIXME: Use the QByteArray based version below?
 QString stringFromByte(byte c)
 {
diff --git a/src/shared/trk/trkutils.h b/src/shared/trk/trkutils.h
index e8388356c533f47cf7766b28ee72374478643137..441a2ba2c2d729b7cba03c3ce245c2a6261e634f 100644
--- a/src/shared/trk/trkutils.h
+++ b/src/shared/trk/trkutils.h
@@ -102,26 +102,21 @@ struct Library
     uint dataseg;
 };
 
+struct TrkAppVersion {
+    TrkAppVersion();
+    void reset();    
+
+    int trkMajor;
+    int trkMinor;
+    int protocolMajor;
+    int protocolMinor;
+};
+
 struct Session
 {
-    Session() { reset(); }
-
-    void reset() {
-        cpuMajor = 0;
-        cpuMinor = 0;
-        bigEndian = 0;
-        defaultTypeSize = 0;
-        fpTypeSize = 0;
-        extended1TypeSize = 0;
-        extended2TypeSize = 0;
-        pid = 0;
-        tid = 0;
-        codeseg = 0;
-        dataseg = 0;
-
-        currentThread = 0;
-        libraries.clear();
-    }
+    Session();
+    void reset();
+    QString deviceDescription(unsigned verbose) const;
 
     // Trk feedback
     byte cpuMajor;
@@ -131,6 +126,7 @@ struct Session
     byte fpTypeSize;
     byte extended1TypeSize;
     byte extended2TypeSize;
+    TrkAppVersion trkAppVersion;
     uint pid;
     uint tid;
     uint codeseg;