diff --git a/src/plugins/debugger/gdb/gdb.pri b/src/plugins/debugger/gdb/gdb.pri
index c10997f27ea3f65b41d39a1699f72eef76dd0ebc..a83f0a5a16a45781e1f8632259cac49e3124622c 100644
--- a/src/plugins/debugger/gdb/gdb.pri
+++ b/src/plugins/debugger/gdb/gdb.pri
@@ -6,14 +6,20 @@ HEADERS += \
     $$PWD/gdbengine.h \
     $$PWD/gdboptionspage.h \
     $$PWD/trkgdbadapter.h \
-    #$$PWD/gdboptionspage.h \
+    $$PWD/trkoptions.h \
+    $$PWD/trkoptionswidget.h \
+    $$PWD/trkoptionspage.h
 
 SOURCES += \
     $$PWD/gdbmi.cpp \
     $$PWD/gdbengine.cpp \
     $$PWD/gdboptionspage.cpp \
-    $$PWD/trkgdbadapter.cpp
+    $$PWD/trkgdbadapter.cpp \
+    $$PWD/trkoptions.cpp \
+    $$PWD/trkoptionswidget.cpp \
+    $$PWD/trkoptionspage.cpp
 
-FORMS +=  $$PWD/gdboptionspage.ui
+FORMS +=  $$PWD/gdboptionspage.ui \
+$$PWD/trkoptionswidget.ui
 
 RESOURCES += $$PWD/gdb.qrc
diff --git a/src/plugins/debugger/gdb/gdbengine.cpp b/src/plugins/debugger/gdb/gdbengine.cpp
index 07d5524505a222e9943553d9a668348556761b0d..faa860a1467347db717391317eaf7b445bb562bd 100644
--- a/src/plugins/debugger/gdb/gdbengine.cpp
+++ b/src/plugins/debugger/gdb/gdbengine.cpp
@@ -31,6 +31,8 @@
 
 #include "gdbengine.h"
 #include "gdboptionspage.h"
+#include "trkoptions.h"
+#include "trkoptionspage.h"
 #include "trkgdbadapter.h"
 
 #include "watchutils.h"
@@ -4313,9 +4315,11 @@ IDebuggerEngine *createGdbEngine(DebuggerManager *parent,
 IDebuggerEngine *createSymbianEngine(DebuggerManager *parent,
     QList<Core::IOptionsPage*> *opts)
 {
-    Q_UNUSED(opts);
-    //opts->push_back(new GdbOptionsPage);
-    TrkGdbAdapter *adapter = new TrkGdbAdapter;
+    QSharedPointer<TrkOptions> options(new TrkOptions);
+    options->fromSettings(Core::ICore::instance()->settings());
+
+    opts->push_back(new TrkOptionsPage(options));
+    TrkGdbAdapter *adapter = new TrkGdbAdapter(options);
     GdbEngine *engine = new GdbEngine(parent, adapter);
     QObject::connect(adapter, SIGNAL(output(QString)),
         parent, SLOT(showDebuggerOutput(QString)));
diff --git a/src/plugins/debugger/gdb/trkgdbadapter.cpp b/src/plugins/debugger/gdb/trkgdbadapter.cpp
index b892167d27513199da943ba2ce55cbadda50f483..59126ed60c9b1267f1f4ef7ddd5c14123c4574f9 100644
--- a/src/plugins/debugger/gdb/trkgdbadapter.cpp
+++ b/src/plugins/debugger/gdb/trkgdbadapter.cpp
@@ -28,6 +28,7 @@
 **************************************************************************/
 
 #include "trkgdbadapter.h"
+#include "trkoptions.h"
 #ifndef STANDALONE_RUNNER
 #include "gdbengine.h"
 #endif
@@ -36,6 +37,9 @@
 #  include <unistd.h>
 #endif
 
+#include <QtCore/QTimer>
+#include <QtCore/QDir>
+
 #define TrkCB(s) TrkCallback(this, &TrkGdbAdapter::s)
 
 
@@ -71,21 +75,21 @@ static QByteArray dumpRegister(int n, uint value)
 namespace Debugger {
 namespace Internal {
 
-TrkGdbAdapter::TrkGdbAdapter()
+TrkGdbAdapter::TrkGdbAdapter(const TrkOptionsPtr &options) :
+    m_options(options),
+    m_running(false),
+    m_gdbAckMode(true),
+    m_verbose(2),
+    m_bufferedMemoryRead(true),
+    m_waitCount(0)
 {
-    m_running = false;
-    m_gdbAckMode = true;
-    m_verbose = 2;
-    m_serialFrame = false;
-    m_bufferedMemoryRead = true;
-    m_rfcommDevice = "/dev/rfcomm0";
 
 #ifdef Q_OS_WIN
-    int userId = 0;
+    const DWORD portOffset = GetCurrentProcessId() % 100;
 #else
-    uid_t userId = getuid();
+    const uid_t portOffset = getuid();
 #endif
-    m_gdbServerName = QString("127.0.0.1:%1").arg(2222 + userId);
+    m_gdbServerName = QString::fromLatin1("127.0.0.1:%1").arg(2222 + portOffset);
     connect(&m_gdbProc, SIGNAL(readyReadStandardError()),
         this, SIGNAL(readyReadStandardError()));
     connect(&m_gdbProc, SIGNAL(readyReadStandardOutput()),
@@ -103,18 +107,18 @@ TrkGdbAdapter::TrkGdbAdapter()
         this, SLOT(handleRfcommReadyReadStandardError()));
     connect(&m_rfcommProc, SIGNAL(readyReadStandardOutput()),
         this, SLOT(handleRfcommReadyReadStandardOutput()));
-    connect(&m_gdbProc, SIGNAL(error(QProcess::ProcessError)),
+    connect(&m_rfcommProc, SIGNAL(error(QProcess::ProcessError)),
         this, SLOT(handleRfcommError(QProcess::ProcessError)));
-    connect(&m_gdbProc, SIGNAL(finished(int, QProcess::ExitStatus)),
+    connect(&m_rfcommProc, SIGNAL(finished(int, QProcess::ExitStatus)),
         this, SLOT(handleRfcommFinished(int, QProcess::ExitStatus)));
-    connect(&m_gdbProc, SIGNAL(started()),
+    connect(&m_rfcommProc, SIGNAL(started()),
         this, SLOT(handleRfcommStarted()));
-    connect(&m_gdbProc, SIGNAL(stateChanged(QProcess::ProcessState)),
+    connect(&m_rfcommProc, SIGNAL(stateChanged(QProcess::ProcessState)),
         this, SLOT(handleRfcommStateChanged(QProcess::ProcessState)));
 
     if (m_verbose > 1)
         m_trkDevice.setVerbose(true);
-    m_trkDevice.setSerialFrame(m_serialFrame);
+    m_trkDevice.setSerialFrame(m_options->mode != TrkOptions::BlueTooth);
 
     connect(&m_trkDevice, SIGNAL(logMessage(QString)),
         this, SLOT(trkLogMessage(QString)));
@@ -126,6 +130,25 @@ TrkGdbAdapter::~TrkGdbAdapter()
     logMessage("Shutting down.\n");
 }
 
+QString TrkGdbAdapter::overrideTrkDevice() const
+{
+    return m_overrideTrkDevice;
+}
+
+void TrkGdbAdapter::setOverrideTrkDevice(const QString &d)
+{
+    m_overrideTrkDevice = d;
+}
+
+QString TrkGdbAdapter::effectiveTrkDevice() const
+{
+    if (!m_overrideTrkDevice.isEmpty())
+        return m_overrideTrkDevice;
+    if (m_options->mode == TrkOptions::BlueTooth)
+        return m_options->blueToothDevice;
+    return m_options->serialPort;
+}
+
 void TrkGdbAdapter::trkLogMessage(const QString &msg)
 {
     logMessage("TRK " + msg);
@@ -196,9 +219,16 @@ QByteArray TrkGdbAdapter::trkStepRangeMessage(byte option)
 void TrkGdbAdapter::startInferior()
 {
     QString errorMessage;
-    if (!m_trkDevice.open(m_rfcommDevice, &errorMessage)) {
-        emit output("LOOPING");
-        QTimer::singleShot(1000, this, SLOT(startInferior()));
+    const QString device = effectiveTrkDevice();
+    if (!m_trkDevice.open(device, &errorMessage)) {
+        emit output(QString::fromLatin1("Waiting on %1 (%2)").arg(device, errorMessage));
+        // Do not loop forever
+        if (m_waitCount++ < (m_options->mode == TrkOptions::BlueTooth ? 60 : 5)) {
+            QTimer::singleShot(1000, this, SLOT(startInferior()));
+        } else {
+            emit output(QString::fromLatin1("Failed to connect to %1 after %2 attempts").arg(device).arg(m_waitCount));
+            emit finished(-44, QProcess::CrashExit);
+        }
         return;
     }
 
@@ -1283,14 +1313,21 @@ void TrkGdbAdapter::handleGdbStateChanged(QProcess::ProcessState newState)
 
 void TrkGdbAdapter::run()
 {
-    emit output("### Starting TrkGdbAdapter");
-    m_rfcommProc.start("rfcomm -r listen " + m_rfcommDevice + " 1");
-    m_rfcommProc.waitForStarted();
-    
-    if (m_rfcommProc.state() != QProcess::Running) {
-        emit finished(-44, QProcess::CrashExit);
-        return;
+    emit output(QLatin1String("### Starting TrkGdbAdapter"));
+    if (m_options->mode == TrkOptions::BlueTooth) {
+        const QString device = effectiveTrkDevice();
+        const QString blueToothListener = QLatin1String("rfcomm");
+        emit output(QString::fromLatin1("### Starting BlueTooth listener %1 on %2").arg(blueToothListener, device));
+        m_rfcommProc.start(blueToothListener + QLatin1String(" -r listen ") + m_options->blueToothDevice + QLatin1String(" 1"));
+        m_rfcommProc.waitForStarted();
+        if (m_rfcommProc.state() != QProcess::Running) {
+            const QString msg = QString::fromLocal8Bit(m_rfcommProc.readAllStandardError());
+            emit output(QString::fromLatin1("Failed to start BlueTooth listener %1 on %2: %3\n%4").arg(blueToothListener, device, m_rfcommProc.errorString(), msg));
+            emit finished(-44, QProcess::CrashExit);
+            return;
+        }
     }
+    m_waitCount = 0;
 
     connect(&m_trkDevice, SIGNAL(messageReceived(trk::TrkResult)),
         this, SLOT(handleTrkResult(trk::TrkResult)));
@@ -1300,6 +1337,29 @@ void TrkGdbAdapter::run()
     startInferior();
 }
 
+#ifdef Q_OS_WIN
+
+// Prepend environment of the Symbian Gdb by Cygwin '/bin'
+static void setGdbCygwinEnvironment(const QString &cygwin, QProcess *process)
+{
+    if (cygwin.isEmpty() || !QFileInfo(cygwin).isDir())
+        return;
+    const QString cygwinBinPath = QDir::toNativeSeparators(cygwin) + QLatin1String("\\bin");
+    QStringList env = process->environment();
+    if (env.isEmpty())
+        env = QProcess::systemEnvironment();
+    const QRegExp pathPattern(QLatin1String("^PATH=.*"));
+    const int index = env.indexOf(pathPattern);
+    if (index == -1)
+        return;
+    QString pathValue = env.at(index).mid(5);
+    if (pathValue.startsWith(cygwinBinPath))
+        return;
+    env[index] = QLatin1String("PATH=") + cygwinBinPath + QLatin1Char(';');
+    process->setEnvironment(env);
+}
+#endif
+
 void TrkGdbAdapter::startGdb()
 {
     if (!m_gdbServer.listen(QHostAddress(gdbServerIP()), gdbServerPort())) {
@@ -1316,11 +1376,15 @@ void TrkGdbAdapter::startGdb()
         this, SLOT(handleGdbConnection()));
 
     logMessage("STARTING GDB");
+    emit output(QString::fromLatin1("### Starting gdb %1").arg(m_options->gdb));
     QStringList gdbArgs;
-    gdbArgs.append("--nx"); // Do not read .gdbinit file
-    gdbArgs.append("-i");
-    gdbArgs.append("mi");
-    m_gdbProc.start(QDir::currentPath() + "/cs-gdb", gdbArgs);
+    gdbArgs.append(QLatin1String("--nx")); // Do not read .gdbinit file
+    gdbArgs.append(QLatin1String("-i"));
+    gdbArgs.append(QLatin1String("mi"));
+#ifdef Q_OS_WIN
+    setGdbCygwinEnvironment(m_options->cygwin, &m_gdbProc);
+#endif
+    m_gdbProc.start(m_options->gdb, gdbArgs);
 }
 
 void TrkGdbAdapter::sendGdbMessage(const QString &msg, GdbCallback callback,
@@ -1379,12 +1443,15 @@ void TrkGdbAdapter::start(const QString &program, const QStringList &args,
     QIODevice::OpenMode mode)
 {
     Q_UNUSED(mode);
+    Q_UNUSED(program);
+    Q_UNUSED(args);
     run();
 }
 
 void TrkGdbAdapter::kill()
 {
-    m_rfcommProc.kill();
+    if (m_options->mode == TrkOptions::BlueTooth && m_rfcommProc.state() == QProcess::Running)
+        m_rfcommProc.kill();
     m_gdbProc.kill();
 }
 
@@ -1402,7 +1469,7 @@ bool TrkGdbAdapter::waitForFinished(int msecs)
     m_rfcommProc.terminate();
     m_rfcommProc.waitForFinished();
     QProcess proc;
-    proc.start("rfcomm release " + m_rfcommDevice.toLatin1());
+    proc.start("rfcomm release " + m_options->blueToothDevice);
     proc.waitForFinished();
     return m_gdbProc.waitForFinished(msecs);
 }
diff --git a/src/plugins/debugger/gdb/trkgdbadapter.h b/src/plugins/debugger/gdb/trkgdbadapter.h
index 828e8bc9537a676d2ff8eb4eeb41c89e3eca05f3..db5b5413c7cd16924e8ca33a196dd227168d6a48 100644
--- a/src/plugins/debugger/gdb/trkgdbadapter.h
+++ b/src/plugins/debugger/gdb/trkgdbadapter.h
@@ -34,34 +34,22 @@
 #include "trkdevice.h"
 #include "abstractgdbadapter.h"
 
-#include <QtCore/QDebug>
-#include <QtCore/QDir>
-#include <QtCore/QFile>
 #include <QtCore/QHash>
 #include <QtCore/QPointer>
+#include <QtCore/QSharedPointer>
 #include <QtCore/QProcess>
 #include <QtCore/QQueue>
 #include <QtCore/QString>
 #include <QtCore/QStringList>
-#include <QtCore/QTextStream>
-#include <QtCore/QTimer>
-
-#include <QtGui/QAction>
-#include <QtGui/QApplication>
-#include <QtGui/QMainWindow>
-#include <QtGui/QKeyEvent>
-#include <QtGui/QTextBlock>
-#include <QtGui/QTextEdit>
-#include <QtGui/QToolBar>
 
 #include <QtNetwork/QTcpServer>
 #include <QtNetwork/QTcpSocket>
-#include <QtNetwork/QLocalServer>
-#include <QtNetwork/QLocalSocket>
 
 namespace Debugger {
 namespace Internal {
 
+struct TrkOptions;
+
 struct GdbResult
 {
     QByteArray data;
@@ -81,18 +69,22 @@ public:
     typedef trk::TrkResult TrkResult;
     typedef trk::Callback<const TrkResult &> TrkCallback;
     typedef trk::Callback<const GdbResult &> GdbCallback;
+    typedef QSharedPointer<TrkOptions> TrkOptionsPtr;
 
-    TrkGdbAdapter();
+    explicit TrkGdbAdapter(const TrkOptionsPtr &options);
     ~TrkGdbAdapter();
     void setGdbServerName(const QString &name);
     QString gdbServerName() const { return m_gdbServerName; }
     QString gdbServerIP() const;
     uint gdbServerPort() const;
     void setVerbose(int verbose) { m_verbose = verbose; }
-    void setSerialFrame(bool b) { m_serialFrame = b; }
     void setBufferedMemoryRead(bool b) { m_bufferedMemoryRead = b; }
     trk::Session &session() { return m_session; }
 
+    // Set a device (from the project) to override the settings.
+    QString overrideTrkDevice() const;
+    void setOverrideTrkDevice(const QString &);
+
 public slots:
     void startInferior();
     void run();
@@ -108,7 +100,9 @@ private slots:
 private:
     friend class RunnerGui;
 
-    QString m_rfcommDevice;  // /dev/rfcomm0
+    const TrkOptionsPtr m_options;
+    QString m_overrideTrkDevice;
+
     QString m_gdbServerName; // 127.0.0.1:(2222+uid)
 
     QProcess m_gdbProc;
@@ -237,13 +231,15 @@ public:
     Q_SLOT void handleRfcommStarted();
     Q_SLOT void handleRfcommStateChanged(QProcess::ProcessState newState);
 
+    QString effectiveTrkDevice() const;
+
     // Debuggee state
     Q_SLOT void executeCommand(const QString &msg);
     trk::Session m_session; // global-ish data (process id, target information)
     trk::Snapshot m_snapshot; // local-ish data (memory and registers)
     int m_verbose;
-    bool m_serialFrame;
     bool m_bufferedMemoryRead;
+    int m_waitCount;
 };
 
 } // namespace Internal
diff --git a/src/plugins/debugger/gdb/trkoptions.cpp b/src/plugins/debugger/gdb/trkoptions.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..4975d619852f25016ad210d859283389e34dcd0b
--- /dev/null
+++ b/src/plugins/debugger/gdb/trkoptions.cpp
@@ -0,0 +1,133 @@
+/**************************************************************************
+**
+** 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 "trkoptions.h"
+
+#include <QtCore/QSettings>
+#include <QtCore/QFileInfo>
+
+#ifdef Q_OS_WIN
+#    define SERIALPORT_ROOT "COM"
+enum { firstSerialPort = 1, lastSerialPort = 12 };
+enum { modeDefault = Debugger::Internal::TrkOptions::Serial };
+static const char *serialPortDefaultC = SERIALPORT_ROOT"1";
+static const char *gdbDefaultC = "symgdb";
+#else
+#    define SERIALPORT_ROOT "/dev/ttyS"
+enum { firstSerialPort = 0, lastSerialPort = 3 };
+enum { modeDefault = Debugger::Internal::TrkOptions::BlueTooth };
+static const char *serialPortDefaultC = SERIALPORT_ROOT"0";
+static const char *gdbDefaultC = "symgdb";
+#endif
+
+static const char *settingsGroupC = "S60Debugger";
+static const char *serialPortKeyC = "Port";
+static const char *modeKeyC = "Mode";
+static const char *blueToothDeviceKeyC = "BlueToothDevice";
+static const char *blueToothDeviceDefaultC = "/dev/rfcomm0";
+static const char *gdbKeyC = "gdb";
+static const char *cygwinKeyC = "Cygwin";
+
+static inline QString cygwinDefault()
+{
+#ifdef Q_OS_WIN
+    // Some smartness to check for Cygwin
+    static bool firstTime = true;
+    static QString rc = QLatin1String("C:/cygwin");
+    if (firstTime) {
+        if (!QFileInfo(rc).isDir())
+            rc.clear();
+        firstTime = false;
+    }
+    return rc;
+#else
+    return QString();
+#endif
+}
+
+namespace Debugger {
+namespace Internal {
+
+TrkOptions::TrkOptions() :
+        mode(modeDefault),
+        serialPort(QLatin1String(serialPortDefaultC)),
+        blueToothDevice(QLatin1String(blueToothDeviceDefaultC)),
+        gdb(QLatin1String(gdbDefaultC)),
+        cygwin(cygwinDefault())
+{
+}
+
+void TrkOptions::fromSettings(const QSettings *s)
+{
+    const QString keyRoot = QLatin1String(settingsGroupC) + QLatin1Char('/');
+    mode = s->value(keyRoot + QLatin1String(modeKeyC), modeDefault).toInt();
+    serialPort = s->value(keyRoot + QLatin1String(serialPortKeyC), QLatin1String(serialPortDefaultC)).toString();
+    gdb =  s->value(keyRoot + QLatin1String(gdbKeyC),QLatin1String(gdbDefaultC)).toString();
+    cygwin = s->value(keyRoot + QLatin1String(cygwinKeyC), cygwinDefault()).toString();
+    blueToothDevice = s->value(keyRoot + QLatin1String(blueToothDeviceKeyC), QLatin1String(blueToothDeviceDefaultC)).toString();
+}
+
+void TrkOptions::toSettings(QSettings *s) const
+{
+    s->beginGroup(QLatin1String(settingsGroupC));
+    s->setValue(QLatin1String(modeKeyC), mode);
+    s->setValue(QLatin1String(serialPortKeyC), serialPort);
+    s->setValue(QLatin1String(blueToothDeviceKeyC), blueToothDevice);
+    s->setValue(QLatin1String(gdbKeyC), gdb);
+    s->setValue(QLatin1String(cygwinKeyC), cygwin);
+    s->endGroup();
+}
+
+bool TrkOptions::equals(const  TrkOptions &o) const
+{
+    return mode == o.mode
+            && serialPort == o.serialPort
+            && blueToothDevice == o.blueToothDevice
+            && gdb == o.gdb
+            && cygwin == o.cygwin;
+}
+
+QStringList TrkOptions::serialPorts()
+{
+    QStringList rc;
+    const QString root = QLatin1String(SERIALPORT_ROOT);
+    for (int p = firstSerialPort; p != lastSerialPort; p++)
+        rc.push_back(root + QString::number(p));
+    return rc;
+}
+
+QStringList TrkOptions::blueToothDevices()
+{
+    QStringList rc;
+    rc.push_back(QLatin1String(blueToothDeviceDefaultC));
+    return rc;
+}
+
+} // namespace Internal
+} // namespace Debugger
diff --git a/src/plugins/debugger/gdb/trkoptions.h b/src/plugins/debugger/gdb/trkoptions.h
new file mode 100644
index 0000000000000000000000000000000000000000..cacf1a93cbea8d051d9b4966d8eda102450bbece
--- /dev/null
+++ b/src/plugins/debugger/gdb/trkoptions.h
@@ -0,0 +1,74 @@
+/**************************************************************************
+**
+** 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 TRKOPTIONS_H
+#define TRKOPTIONS_H
+
+#include <QtCore/QStringList>
+
+QT_BEGIN_NAMESPACE
+class QSettings;
+QT_END_NAMESPACE
+
+namespace Debugger {
+namespace Internal {
+
+/* Parameter to be used for debugging S60 via TRK.
+ * GDB is a Symbian-ARM Gdb. It is Cygwin-built on Windows; the cygwin
+ * location 'x/bin' will prepended to the execution path.
+ * Communication happens either via BlueTooth (Linux only) or
+ * serial ports. */
+
+struct TrkOptions
+{
+    enum Mode { Serial, BlueTooth };
+
+    TrkOptions();
+    void fromSettings(const QSettings *s);
+    void toSettings(QSettings *s) const;
+    bool equals(const  TrkOptions &o) const;
+
+    // Lists of choices for the devices
+    static QStringList serialPorts();
+    static QStringList blueToothDevices();
+
+    int mode;
+    QString serialPort;
+    QString blueToothDevice;
+    QString gdb;
+    QString cygwin; // ignored on Linux
+};
+
+inline bool operator==(const TrkOptions &o1, const TrkOptions &o2) { return o1.equals(o2); }
+inline bool operator!=(const TrkOptions &o1, const TrkOptions &o2) { return !o1.equals(o2); }
+
+} // namespace Internal
+} // namespace Debugger
+
+#endif // TRKOPTIONS_H
diff --git a/src/plugins/debugger/gdb/trkoptionspage.cpp b/src/plugins/debugger/gdb/trkoptionspage.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..2962e3c2ceb467e772764db2549bb1bb6afc4c96
--- /dev/null
+++ b/src/plugins/debugger/gdb/trkoptionspage.cpp
@@ -0,0 +1,98 @@
+/**************************************************************************
+**
+** 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 "trkoptionspage.h"
+#include "trkoptionswidget.h"
+#include "trkoptions.h"
+#include "debuggerconstants.h"
+
+#include <coreplugin/icore.h>
+
+#include <QtCore/QCoreApplication>
+#include <QtCore/QSettings>
+
+namespace Debugger {
+namespace Internal {
+
+const char * const TRK_SETTINGS_ID = QT_TRANSLATE_NOOP("Debugger::Internal::TrkOptionsPage", "S60 / Trk");
+
+TrkOptionsPage::TrkOptionsPage(const TrkOptionsPtr &options) :
+    m_options(options)
+{
+}
+
+TrkOptionsPage::~TrkOptionsPage()
+{
+}
+
+QString TrkOptionsPage::settingsId()
+{
+    return QLatin1String(TRK_SETTINGS_ID);
+}
+
+QString TrkOptionsPage::trName() const
+{
+    return tr(TRK_SETTINGS_ID);
+}
+
+QString TrkOptionsPage::category() const
+{
+    return QLatin1String(Debugger::Constants::DEBUGGER_SETTINGS_CATEGORY);
+}
+
+QString TrkOptionsPage::trCategory() const
+{
+    return QCoreApplication::translate("Debugger", Debugger::Constants::DEBUGGER_SETTINGS_CATEGORY);
+}
+
+QWidget *TrkOptionsPage::createPage(QWidget *parent)
+{
+    if (!m_widget)
+        m_widget = new TrkOptionsWidget(parent);
+    m_widget->setTrkOptions(*m_options);
+    return m_widget;
+}
+
+void TrkOptionsPage::apply()
+{
+    if (!m_widget)
+        return;
+    const TrkOptions newOptions = m_widget->trkOptions();
+    if (newOptions == *m_options)
+        return;
+    *m_options = newOptions;
+    m_options->toSettings(Core::ICore::instance()->settings());
+}
+
+void TrkOptionsPage::finish()
+{
+}
+
+} // namespace Internal
+} // namespace Designer
diff --git a/src/plugins/debugger/gdb/trkoptionspage.h b/src/plugins/debugger/gdb/trkoptionspage.h
new file mode 100644
index 0000000000000000000000000000000000000000..1d33ab954f5cd1f19c651488261e66f38f5b6b39
--- /dev/null
+++ b/src/plugins/debugger/gdb/trkoptionspage.h
@@ -0,0 +1,72 @@
+/**************************************************************************
+**
+** 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 TRKOPTIONSPAGE_H
+#define TRKOPTIONSPAGE_H
+
+#include <QtGui/QWidget>
+#include <QtCore/QSharedPointer>
+#include <QtCore/QPointer>
+
+#include <coreplugin/dialogs/ioptionspage.h>
+
+namespace Debugger {
+namespace Internal {
+
+class TrkOptionsWidget;
+struct TrkOptions;
+
+class TrkOptionsPage : public Core::IOptionsPage
+{
+    Q_OBJECT
+    Q_DISABLE_COPY(TrkOptionsPage)
+public:
+    typedef QSharedPointer<TrkOptions> TrkOptionsPtr;
+
+    TrkOptionsPage(const TrkOptionsPtr &options);
+    virtual ~TrkOptionsPage();
+
+    virtual QString id() const { return settingsId(); }
+    virtual QString trName() const;
+    virtual QString category() const;
+    virtual QString trCategory() const;
+
+    virtual QWidget *createPage(QWidget *parent);
+    virtual void apply();
+    virtual void finish();
+
+    static QString settingsId();
+private:
+    const TrkOptionsPtr m_options;
+    QPointer<TrkOptionsWidget> m_widget;
+};
+
+} // namespace Internal
+} // namespace Designer
+#endif // TRKOPTIONSPAGE_H
diff --git a/src/plugins/debugger/gdb/trkoptionswidget.cpp b/src/plugins/debugger/gdb/trkoptionswidget.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..34b5afb4f3c0b00ad2eefef59b896333125477c1
--- /dev/null
+++ b/src/plugins/debugger/gdb/trkoptionswidget.cpp
@@ -0,0 +1,98 @@
+/**************************************************************************
+**
+** 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 "trkoptionswidget.h"
+#include "trkoptions.h"
+#include "debuggerconstants.h"
+#include "ui_trkoptionswidget.h"
+
+namespace Debugger {
+namespace Internal {
+
+TrkOptionsWidget::TrkOptionsWidget(QWidget *parent) :
+    QWidget(parent),
+    ui(new Ui::TrkOptionsWidget)
+{
+    ui->setupUi(this);
+    ui->gdbChooser->setExpectedKind(Core::Utils::PathChooser::Command);
+    ui->cygwinChooser->setExpectedKind(Core::Utils::PathChooser::Directory);
+    ui->blueToothComboBox->addItems(TrkOptions::blueToothDevices());
+    ui->serialComboBox->addItems(TrkOptions::serialPorts());
+    connect(ui->commComboBox, SIGNAL(currentIndexChanged(int)), ui->commStackedWidget, SLOT(setCurrentIndex(int)));
+    // No bluetooth on Windows yet...
+#ifdef Q_OS_WIN
+    ui->commComboBox->setEnabled(false);
+#else
+    ui->cygwinChooser->setVisible(false);
+    ui->cygwinLabel->setVisible(false);
+#endif
+}
+
+TrkOptionsWidget::~TrkOptionsWidget()
+{
+    delete ui;
+}
+
+void TrkOptionsWidget::changeEvent(QEvent *e)
+{
+    QWidget::changeEvent(e);
+    switch (e->type()) {
+    case QEvent::LanguageChange:
+        ui->retranslateUi(this);
+        break;
+    default:
+        break;
+    }
+}
+
+void TrkOptionsWidget::setTrkOptions(const TrkOptions &o)
+{
+    ui->commComboBox->setCurrentIndex(o.mode);
+    ui->commStackedWidget->setCurrentIndex(o.mode);
+    const int serialPortIndex = qMax(0, ui->serialComboBox->findText(o.serialPort));
+    ui->serialComboBox->setCurrentIndex(serialPortIndex);
+    ui->gdbChooser->setPath(o.gdb);
+    ui->cygwinChooser->setPath(o.cygwin);
+    const int blueToothIndex = qMax(0, ui->blueToothComboBox->findText(o.blueToothDevice));
+    ui->blueToothComboBox->setCurrentIndex(blueToothIndex);
+}
+
+TrkOptions TrkOptionsWidget::trkOptions() const
+{
+    TrkOptions rc;
+    rc.mode = ui->commComboBox->currentIndex();
+    rc.gdb = ui->gdbChooser->path();
+    rc.cygwin = ui->cygwinChooser->path();
+    rc.blueToothDevice = ui->blueToothComboBox->currentText();
+    rc.serialPort = ui->serialComboBox->currentText();
+    return rc;
+}
+
+} // namespace Internal
+} // namespace Designer
diff --git a/src/plugins/debugger/gdb/trkoptionswidget.h b/src/plugins/debugger/gdb/trkoptionswidget.h
new file mode 100644
index 0000000000000000000000000000000000000000..25ca593dbb1f55e8241369b83ae046844c193e4a
--- /dev/null
+++ b/src/plugins/debugger/gdb/trkoptionswidget.h
@@ -0,0 +1,62 @@
+/**************************************************************************
+**
+** 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 TRKOPTIONSWIDGET_H
+#define TRKOPTIONSWIDGET_H
+
+#include <QtGui/QWidget>
+
+namespace Debugger {
+namespace Internal {
+
+struct TrkOptions;
+
+namespace Ui {
+    class TrkOptionsWidget;
+}
+
+class TrkOptionsWidget : public QWidget {
+    Q_OBJECT
+public:
+    TrkOptionsWidget(QWidget *parent = 0);
+    ~TrkOptionsWidget();
+
+    void setTrkOptions(const TrkOptions &);
+    TrkOptions trkOptions() const;
+
+protected:
+    void changeEvent(QEvent *e);
+
+private:
+    Ui::TrkOptionsWidget *ui;
+};
+
+} // namespace Internal
+} // namespace Designer
+#endif // TRKOPTIONSWIDGET_H
diff --git a/src/plugins/debugger/gdb/trkoptionswidget.ui b/src/plugins/debugger/gdb/trkoptionswidget.ui
new file mode 100644
index 0000000000000000000000000000000000000000..a1c699438d17e271576331ad489bb2d8c8b96d0e
--- /dev/null
+++ b/src/plugins/debugger/gdb/trkoptionswidget.ui
@@ -0,0 +1,149 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>Debugger::Internal::TrkOptionsWidget</class>
+ <widget class="QWidget" name="Debugger::Internal::TrkOptionsWidget">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>400</width>
+    <height>300</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>Form</string>
+  </property>
+  <layout class="QVBoxLayout" name="verticalLayout_2">
+   <item>
+    <widget class="QGroupBox" name="gdbGroupBox">
+     <property name="title">
+      <string>Gdb</string>
+     </property>
+     <layout class="QFormLayout" name="formLayout">
+      <item row="0" column="0">
+       <widget class="QLabel" name="gdbLabel">
+        <property name="text">
+         <string>Symbian ARM gdb location:</string>
+        </property>
+       </widget>
+      </item>
+      <item row="0" column="1">
+       <widget class="Core::Utils::PathChooser" name="gdbChooser" native="true"/>
+      </item>
+      <item row="1" column="0">
+       <widget class="QLabel" name="cygwinLabel">
+        <property name="text">
+         <string>Cygwin location:</string>
+        </property>
+       </widget>
+      </item>
+      <item row="1" column="1">
+       <widget class="Core::Utils::PathChooser" name="cygwinChooser" native="true"/>
+      </item>
+     </layout>
+    </widget>
+   </item>
+   <item>
+    <widget class="QGroupBox" name="commGroupBox">
+     <property name="title">
+      <string>Communication</string>
+     </property>
+     <layout class="QHBoxLayout" name="horizontalLayout">
+      <item>
+       <layout class="QVBoxLayout" name="verticalLayout">
+        <item>
+         <widget class="QComboBox" name="commComboBox">
+          <item>
+           <property name="text">
+            <string>Serial Port</string>
+           </property>
+          </item>
+          <item>
+           <property name="text">
+            <string>Bluetooth</string>
+           </property>
+          </item>
+         </widget>
+        </item>
+        <item>
+         <widget class="QStackedWidget" name="commStackedWidget">
+          <property name="currentIndex">
+           <number>1</number>
+          </property>
+          <widget class="QWidget" name="serialPage">
+           <layout class="QFormLayout" name="formLayout_2">
+            <item row="0" column="0">
+             <widget class="QLabel" name="serialLabel">
+              <property name="text">
+               <string>Port:</string>
+              </property>
+             </widget>
+            </item>
+            <item row="0" column="1">
+             <widget class="QComboBox" name="serialComboBox"/>
+            </item>
+           </layout>
+          </widget>
+          <widget class="QWidget" name="blueToothPage">
+           <layout class="QFormLayout" name="formLayout_3">
+            <property name="fieldGrowthPolicy">
+             <enum>QFormLayout::ExpandingFieldsGrow</enum>
+            </property>
+            <item row="0" column="1">
+             <widget class="QComboBox" name="blueToothComboBox"/>
+            </item>
+            <item row="0" column="0">
+             <widget class="QLabel" name="blueToothLabel">
+              <property name="text">
+               <string>Device:</string>
+              </property>
+             </widget>
+            </item>
+           </layout>
+          </widget>
+         </widget>
+        </item>
+       </layout>
+      </item>
+      <item>
+       <spacer name="commHorizontalSpacer">
+        <property name="orientation">
+         <enum>Qt::Horizontal</enum>
+        </property>
+        <property name="sizeHint" stdset="0">
+         <size>
+          <width>182</width>
+          <height>20</height>
+         </size>
+        </property>
+       </spacer>
+      </item>
+     </layout>
+    </widget>
+   </item>
+   <item>
+    <spacer name="verticalSpacer">
+     <property name="orientation">
+      <enum>Qt::Vertical</enum>
+     </property>
+     <property name="sizeHint" stdset="0">
+      <size>
+       <width>20</width>
+       <height>40</height>
+      </size>
+     </property>
+    </spacer>
+   </item>
+  </layout>
+ </widget>
+ <customwidgets>
+  <customwidget>
+   <class>Core::Utils::PathChooser</class>
+   <extends>QWidget</extends>
+   <header location="global">utils/pathchooser.h</header>
+   <container>1</container>
+  </customwidget>
+ </customwidgets>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/tests/manual/trk/runner.cpp b/tests/manual/trk/runner.cpp
index 77b0d6a02d7a6c8a05e353130ef5dcc57b55fac8..25ff2d46847e31343b0fb5ca8986ff0ad3557f51 100755
--- a/tests/manual/trk/runner.cpp
+++ b/tests/manual/trk/runner.cpp
@@ -28,6 +28,7 @@
 **************************************************************************/
 
 #include "trkgdbadapter.h"
+#include "trkoptions.h"
 
 #include <QtCore/QDebug>
 
@@ -38,6 +39,9 @@
 #include <QtGui/QTextBlock>
 #include <QtGui/QTextEdit>
 #include <QtGui/QToolBar>
+#include <QtCore/QSharedPointer>
+#include <QtCore/QTimer>
+#include <QtCore/QDir>
 
 ///////////////////////////////////////////////////////////////////////
 //
@@ -224,7 +228,9 @@ void RunnerGui::started()
 int main(int argc, char *argv[])
 {
     QApplication app(argc, argv);
-    TrkGdbAdapter adapter;
+    QSharedPointer<TrkOptions> options(new TrkOptions);
+    options->gdb = QDir::currentPath() + QLatin1String("/cs-gdb");
+    TrkGdbAdapter adapter(options);
     adapter.setVerbose(2);
     RunnerGui gui(&adapter);
     gui.show();
diff --git a/tests/manual/trk/runner.pro b/tests/manual/trk/runner.pro
index 6a409f6e6a772f2d26ae06e5d0d4b089dddce361..91a27d01c021c8de6d09d575927dbf08ff4ce57e 100644
--- a/tests/manual/trk/runner.pro
+++ b/tests/manual/trk/runner.pro
@@ -15,8 +15,10 @@ win32:CONFIG+=console
 
 HEADERS += \
     $$DEBUGGERHOME/abstractgdbadapter.h \
+    $$DEBUGGERHOME/trkoptions.h \
     $$DEBUGGERHOME/trkgdbadapter.h \
 
 SOURCES += \
     $$DEBUGGERHOME/trkgdbadapter.cpp \
+    $$DEBUGGERHOME/trkoptions.cpp \
     $$PWD/runner.cpp \