diff --git a/src/plugins/debugger/gdb/coregdbadapter.cpp b/src/plugins/debugger/gdb/coregdbadapter.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..820d158d10579916cf9a54ca76c5520cb03860a7
--- /dev/null
+++ b/src/plugins/debugger/gdb/coregdbadapter.cpp
@@ -0,0 +1,195 @@
+/**************************************************************************
+**
+** 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 "coregdbadapter.h"
+
+#include "debuggeractions.h"
+#include "gdbengine.h"
+#include "procinterrupt.h"
+
+#include <utils/qtcassert.h>
+#include <coreplugin/icore.h>
+
+#include <QtCore/QFileInfo>
+#include <QtGui/QMessageBox>
+
+namespace Debugger {
+namespace Internal {
+
+#define STRINGIFY_INTERNAL(x) #x
+#define STRINGIFY(x) STRINGIFY_INTERNAL(x)
+#define CB(callback) \
+    static_cast<GdbEngine::AdapterCallback>(&CoreGdbAdapter::callback), \
+    STRINGIFY(callback)
+
+///////////////////////////////////////////////////////////////////////
+//
+// CoreGdbAdapter
+//
+///////////////////////////////////////////////////////////////////////
+
+CoreGdbAdapter::CoreGdbAdapter(GdbEngine *engine, QObject *parent)
+    : AbstractGdbAdapter(engine, parent)
+{
+    QTC_ASSERT(state() == AdapterNotRunning, qDebug() << state());
+    connect(&m_gdbProc, SIGNAL(error(QProcess::ProcessError)),
+        this, SIGNAL(error(QProcess::ProcessError)));
+    connect(&m_gdbProc, SIGNAL(readyReadStandardOutput()),
+        this, SIGNAL(readyReadStandardOutput()));
+    connect(&m_gdbProc, SIGNAL(readyReadStandardError()),
+        this, SIGNAL(readyReadStandardError()));
+    connect(&m_gdbProc, SIGNAL(started()),
+        this, SLOT(handleGdbStarted()));
+    connect(&m_gdbProc, SIGNAL(finished(int, QProcess::ExitStatus)),
+        this, SLOT(handleGdbFinished(int, QProcess::ExitStatus)));
+}
+
+void CoreGdbAdapter::startAdapter()
+{
+    QTC_ASSERT(state() == AdapterNotRunning, qDebug() << state());
+    setState(AdapterStarting);
+    debugMessage(_("TRYING TO START ADAPTER"));
+
+    QStringList gdbArgs;
+    gdbArgs.prepend(_("mi"));
+    gdbArgs.prepend(_("-i"));
+
+    if (!m_engine->m_outputCollector.listen()) {
+        emit adapterStartFailed(tr("Cannot set up communication with child process: %1")
+                .arg(m_engine->m_outputCollector.errorString()));
+        return;
+    }
+    gdbArgs.prepend(_("--tty=") + m_engine->m_outputCollector.serverName());
+
+    if (!startParameters().workingDir.isEmpty())
+        setWorkingDirectory(startParameters().workingDir);
+    if (!startParameters().environment.isEmpty())
+        setEnvironment(startParameters().environment);
+
+    QString location = theDebuggerStringSetting(GdbLocation);
+    m_gdbProc.start(location, gdbArgs);
+}
+
+void CoreGdbAdapter::handleGdbStarted()
+{
+    QTC_ASSERT(state() == AdapterStarting, qDebug() << state());
+    setState(AdapterStarted);
+    emit adapterStarted();
+}
+
+void CoreGdbAdapter::prepareInferior()
+{
+    QTC_ASSERT(state() == AdapterStarted, qDebug() << state());
+    setState(InferiorPreparing);
+    if (!startParameters().processArgs.isEmpty())
+        m_engine->postCommand(_("-exec-arguments ")
+            + startParameters().processArgs.join(_(" ")));
+    QFileInfo fi(m_engine->startParameters().executable);
+    m_engine->postCommand(_("-file-exec-and-symbols \"%1\"").arg(fi.absoluteFilePath()),
+        CB(handleFileExecAndSymbols));
+}
+
+void CoreGdbAdapter::handleFileExecAndSymbols(const GdbResultRecord &response, const QVariant &)
+{
+    QTC_ASSERT(state() == InferiorPreparing, qDebug() << state());
+    if (response.resultClass == GdbResultDone) {
+        //m_breakHandler->clearBreakMarkers();
+        setState(InferiorPrepared);
+        emit inferiorPrepared();
+    } else if (response.resultClass == GdbResultError) {
+        QString msg = tr("Starting executable failed:\n") +
+            __(response.data.findChild("msg").data());
+        setState(InferiorPreparationFailed);
+        emit inferiorPreparationFailed(msg);
+    }
+}
+
+void CoreGdbAdapter::startInferior()
+{
+    QTC_ASSERT(state() == InferiorPrepared, qDebug() << state());
+    setState(InferiorStarting);
+    QFileInfo fi(startParameters().executable);
+    QString fileName = _c('"') + fi.absoluteFilePath() + _c('"');
+    QFileInfo fi2(startParameters().coreFile);
+    // quoting core name below fails in gdb 6.8-debian
+    QString coreName = fi2.absoluteFilePath();
+    m_engine->postCommand(_("target core ") + coreName, CB(handleTargetCore));
+}
+
+void CoreGdbAdapter::handleTargetCore(const GdbResultRecord &response, const QVariant &)
+{
+    QTC_ASSERT(state() == InferiorStarting, qDebug() << state());
+    if (response.resultClass == GdbResultDone) {
+        setState(InferiorStarted);
+        emit inferiorStarted();
+        m_engine->handleTargetCore();
+    } else {
+        QTC_ASSERT(response.resultClass == GdbResultError, /**/);
+        const QByteArray &msg = response.data.findChild("msg").data();
+        setState(InferiorStartFailed);
+        emit inferiorStartFailed(msg);
+    }
+}
+
+void CoreGdbAdapter::interruptInferior()
+{
+    // A core should never 'run'
+    QTC_ASSERT(false, /**/);
+}
+
+void CoreGdbAdapter::shutdown()
+{
+    if (state() == InferiorStarted || state() == InferiorShutDown) {
+        setState(AdapterShuttingDown);
+        m_engine->postCommand(_("-gdb-exit"), CB(handleExit));
+        return;
+    }
+    QTC_ASSERT(state() == AdapterNotRunning, qDebug() << state());
+}
+
+void CoreGdbAdapter::handleExit(const GdbResultRecord &response, const QVariant &)
+{
+    if (response.resultClass == GdbResultDone) {
+        // don't set state here, this will be handled in handleGdbFinished()
+    } else if (response.resultClass == GdbResultError) {
+        QString msg = tr("Gdb process could not be stopped:\n") +
+            __(response.data.findChild("msg").data());
+        emit adapterShutdownFailed(msg);
+    }
+}
+
+void CoreGdbAdapter::handleGdbFinished(int, QProcess::ExitStatus)
+{
+    debugMessage(_("GDB PROESS FINISHED"));
+    setState(AdapterNotRunning);
+    emit adapterShutDown();
+}
+
+} // namespace Internal
+} // namespace Debugger
diff --git a/src/plugins/debugger/gdb/coregdbadapter.h b/src/plugins/debugger/gdb/coregdbadapter.h
new file mode 100644
index 0000000000000000000000000000000000000000..152c9bebf5701d5cee7a55338159556dd4d70202
--- /dev/null
+++ b/src/plugins/debugger/gdb/coregdbadapter.h
@@ -0,0 +1,83 @@
+/**************************************************************************
+**
+** 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 DEBUGGER_COREGDBADAPTER_H
+#define DEBUGGER_COREGDBADAPTER_H
+
+#include "abstractgdbadapter.h"
+#include "gdbengine.h"
+
+#include <QtCore/QDebug>
+#include <QtCore/QProcess>
+
+namespace Debugger {
+namespace Internal {
+
+///////////////////////////////////////////////////////////////////////
+//
+// CoreGdbAdapter
+//
+///////////////////////////////////////////////////////////////////////
+
+class CoreGdbAdapter : public AbstractGdbAdapter
+{
+    Q_OBJECT
+
+public:
+    CoreGdbAdapter(GdbEngine *engine, QObject *parent = 0);
+
+private:
+    QByteArray readAllStandardError() { return m_gdbProc.readAllStandardError(); }
+    QByteArray readAllStandardOutput() { return m_gdbProc.readAllStandardOutput(); }
+    qint64 write(const char *data) { return m_gdbProc.write(data); }
+    void setWorkingDirectory(const QString &dir) { m_gdbProc.setWorkingDirectory(dir); }
+    void setEnvironment(const QStringList &env) { m_gdbProc.setEnvironment(env); }
+    bool isTrkAdapter() const { return false; }
+
+    void startAdapter();
+    void prepareInferior();
+    void startInferior();
+    void interruptInferior();
+    void shutdown();
+
+    void handleFileExecAndSymbols(const GdbResultRecord &, const QVariant &);
+    void handleTargetCore(const GdbResultRecord &response, const QVariant &);
+    void handleExit(const GdbResultRecord &, const QVariant &);
+
+    void debugMessage(const QString &msg) { m_engine->debugMessage(msg); }
+    Q_SLOT void handleGdbFinished(int, QProcess::ExitStatus);
+    Q_SLOT void handleGdbStarted();
+
+    QProcess m_gdbProc;
+};
+
+} // namespace Internal
+} // namespace Debugger
+
+#endif // DEBUGGER_COREDBADAPTER_H
diff --git a/src/plugins/debugger/gdb/gdb.pri b/src/plugins/debugger/gdb/gdb.pri
index 77a3a42d885684d088bdd28fc4dbcc1a21fb7858..08a45315a94338d3062d35a9c5207ea24905819c 100644
--- a/src/plugins/debugger/gdb/gdb.pri
+++ b/src/plugins/debugger/gdb/gdb.pri
@@ -7,6 +7,7 @@ HEADERS += \
     $$PWD/gdbengine.h \
     $$PWD/gdboptionspage.h \
     $$PWD/remotegdbadapter.h \
+    $$PWD/coregdbadapter.h \
     $$PWD/trkgdbadapter.h \
     $$PWD/trkoptions.h \
     $$PWD/trkoptionswidget.h \
@@ -18,6 +19,7 @@ SOURCES += \
     $$PWD/gdboptionspage.cpp \
     $$PWD/plaingdbadapter.cpp \
     $$PWD/remotegdbadapter.cpp \
+    $$PWD/coregdbadapter.cpp \
     $$PWD/trkoptions.cpp \
     $$PWD/trkoptionswidget.cpp \
     $$PWD/trkoptionspage.cpp \
diff --git a/src/plugins/debugger/gdb/gdbengine.cpp b/src/plugins/debugger/gdb/gdbengine.cpp
index 2a835302fd77f01c36b673592add026cdd744b90..de6556e693a2a31b6cd67332a3ecba82b13ceaa1 100644
--- a/src/plugins/debugger/gdb/gdbengine.cpp
+++ b/src/plugins/debugger/gdb/gdbengine.cpp
@@ -33,9 +33,11 @@
 #include "gdboptionspage.h"
 #include "trkoptions.h"
 #include "trkoptionspage.h"
+
 #include "plaingdbadapter.h"
 #include "trkgdbadapter.h"
 #include "remotegdbadapter.h"
+#include "coregdbadapter.h"
 
 #include "watchutils.h"
 #include "debuggeractions.h"
@@ -178,7 +180,8 @@ GdbEngine::GdbEngine(DebuggerManager *parent) :
     options->fromSettings(Core::ICore::instance()->settings());
     m_plainAdapter = new PlainGdbAdapter(this);
     m_trkAdapter = new TrkGdbAdapter(this, options);
-    m_remoteAdapter = 0; // FIXME
+    m_remoteAdapter = new RemoteGdbAdapter(this);
+    m_coreAdapter = new CoreGdbAdapter(this);
 
     // Output
     connect(&m_outputCollector, SIGNAL(byteDelivery(QByteArray)),
@@ -228,6 +231,7 @@ GdbEngine::~GdbEngine()
     delete m_plainAdapter;
     delete m_trkAdapter;
     delete m_remoteAdapter;
+    delete m_coreAdapter;
 }
 
 void GdbEngine::connectAdapter()
@@ -900,7 +904,7 @@ void GdbEngine::executeDebuggerCommand(const QString &command)
     m_gdbAdapter->write(command.toLatin1() + "\r\n");
 }
 
-void GdbEngine::handleTargetCore(const GdbResultRecord &, const QVariant &)
+void GdbEngine::handleTargetCore()
 {
     qq->notifyInferiorStopped();
     showStatusMessage(tr("Core file loaded."));
@@ -1229,7 +1233,7 @@ void GdbEngine::handleAsyncOutput(const GdbMi &data)
 #if 1
     // FIXME: remove this special case as soon as there's a real
     // reason given when the temporary breakpoint is hit.
-    // reight now we get:
+    // right now we get:
     // 14*stopped,thread-id="1",frame={addr="0x0000000000403ce4",
     // func="foo",args=[{name="str",value="@0x7fff0f450460"}],
     // file="main.cpp",fullname="/tmp/g/main.cpp",line="37"}
@@ -1559,6 +1563,10 @@ void GdbEngine::startDebugger(const DebuggerStartParametersPtr &sp)
 
     if (sp->executable.endsWith(_(".sym")))
         m_gdbAdapter = m_trkAdapter;
+    else if (sp->startMode == AttachCore)
+        m_gdbAdapter = m_coreAdapter;
+    else if (sp->startMode == StartRemote)
+        m_gdbAdapter = m_remoteAdapter;
     else 
         m_gdbAdapter = m_plainAdapter;
 
@@ -4215,15 +4223,6 @@ void GdbEngine::handleInferiorPrepared()
         postCommand(_("attach %1").arg(m_startParameters->attachPID), CB(handleAttach));
         // Task 254674 does not want to remove them
         //qq->breakHandler()->removeAllBreakpoints();
-    } else if (startMode() == AttachCore) {
-        QFileInfo fi(m_startParameters->executable);
-        QString fileName = _c('"') + fi.absoluteFilePath() + _c('"');
-        QFileInfo fi2(m_startParameters->coreFile);
-        // quoting core name below fails in gdb 6.8-debian
-        QString coreName = fi2.absoluteFilePath();
-        postCommand(_("-file-exec-and-symbols ") + fileName, CB(handleFileExecAndSymbols));
-        postCommand(_("target core ") + coreName, CB(handleTargetCore));
-        qq->breakHandler()->removeAllBreakpoints();
     } else if (startMode() == StartRemote) {
         postCommand(_("set architecture %1").arg(m_startParameters->remoteArchitecture));
         qq->breakHandler()->setAllPending();
diff --git a/src/plugins/debugger/gdb/gdbengine.h b/src/plugins/debugger/gdb/gdbengine.h
index a71cede808c03acca75bcf678ffc27ae6816e580..eb97e06c6a5bfe74386060210a44cdce1b8aa3a2 100644
--- a/src/plugins/debugger/gdb/gdbengine.h
+++ b/src/plugins/debugger/gdb/gdbengine.h
@@ -68,6 +68,7 @@ class BreakpointData;
 class PlainGdbAdapter;
 class TrkGdbAdapter;
 class RemoteGdbAdapter;
+class CoreGdbAdapter;
 
 enum DebuggingHelperState
 {
@@ -94,6 +95,7 @@ private:
     friend class PlainGdbAdapter;
     friend class TrkGdbAdapter;
     friend class RemoteGdbAdapter;
+    friend class CoreGdbAdapter;
 
     //
     // IDebuggerEngine implementation
@@ -267,12 +269,12 @@ private:
     void handleShowVersion(const GdbResultRecord &response, const QVariant &);
     void handleQueryPwd(const GdbResultRecord &response, const QVariant &);
     void handleQuerySources(const GdbResultRecord &response, const QVariant &);
-    void handleTargetCore(const GdbResultRecord &, const QVariant &);
     void handleExit(const GdbResultRecord &, const QVariant &);
     void handleDetach(const GdbResultRecord &, const QVariant &);
     //void handleSetTargetAsync(const GdbResultRecord &, const QVariant &);
     //void handleTargetRemote(const GdbResultRecord &, const QVariant &);
     void handleWatchPoint(const GdbResultRecord &, const QVariant &);
+    void handleTargetCore();
     bool showToolTip();
 
     // Convenience
@@ -293,8 +295,6 @@ private:
 
     QByteArray m_inbuffer;
 
-    AbstractGdbAdapter *m_gdbAdapter;
-
     QHash<int, GdbCommand> m_cookieForToken;
     QHash<int, QByteArray> m_customOutputForToken;
 
@@ -442,10 +442,12 @@ private:
     DebuggerStartParametersPtr m_startParameters;
     // make sure to re-initialize new members in initializeVariables();
 
-    // only one of those is active at a given time
-    PlainGdbAdapter *m_plainAdapter;
-    TrkGdbAdapter *m_trkAdapter;
-    RemoteGdbAdapter *m_remoteAdapter;
+    // only one of those is active at a given time, available in m_gdbAdapter
+    AbstractGdbAdapter *m_gdbAdapter;  // pointer to one listed below
+    PlainGdbAdapter *m_plainAdapter;   // owned
+    TrkGdbAdapter *m_trkAdapter;       // owned
+    RemoteGdbAdapter *m_remoteAdapter; // owned
+    CoreGdbAdapter *m_coreAdapter;     // owned
     
 public:
     void showMessageBox(int icon, const QString &title, const QString &text);
diff --git a/src/plugins/debugger/gdb/remotegdbadapter.cpp b/src/plugins/debugger/gdb/remotegdbadapter.cpp
index 85aaaa318223e24aeb1f7ff7164f8c77ebebe5c1..0a4a9f92b619d95a36763f5a2d23dbce9e6b8ade 100644
--- a/src/plugins/debugger/gdb/remotegdbadapter.cpp
+++ b/src/plugins/debugger/gdb/remotegdbadapter.cpp
@@ -77,12 +77,11 @@ RemoteGdbAdapter::RemoteGdbAdapter(GdbEngine *engine, QObject *parent)
         this, SLOT(readUploadStandardError()));
 }
 
-void RemoteGdbAdapter::startAdapter(const DebuggerStartParametersPtr &sp)
+void RemoteGdbAdapter::startAdapter()
 {
     QTC_ASSERT(state() == AdapterNotRunning, qDebug() << state());
     setState(AdapterStarting);
     debugMessage(_("TRYING TO START ADAPTER"));
-    m_startParameters = sp;
 
     QStringList gdbArgs;
     gdbArgs.prepend(_("mi"));
@@ -95,25 +94,25 @@ void RemoteGdbAdapter::startAdapter(const DebuggerStartParametersPtr &sp)
     }
     gdbArgs.prepend(_("--tty=") + m_engine->m_outputCollector.serverName());
 
-    if (!m_startParameters->workingDir.isEmpty())
-        setWorkingDirectory(m_startParameters->workingDir);
-    if (!m_startParameters->environment.isEmpty())
-        setEnvironment(m_startParameters->environment);
+    if (!startParameters().workingDir.isEmpty())
+        setWorkingDirectory(startParameters().workingDir);
+    if (!startParameters().environment.isEmpty())
+        setEnvironment(startParameters().environment);
 
     QString location = theDebuggerStringSetting(GdbLocation);
 
 /*  
     // FIXME: make asynchroneouis
     // Start the remote server
-    if (m_startParameters->serverStartScript.isEmpty()) {
+    if (startParameters().serverStartScript.isEmpty()) {
         showStatusMessage(_("No server start script given. "
             "Assuming server runs already."));
     } else {
-        if (!m_startParameters->workingDir.isEmpty())
-            m_uploadProc.setWorkingDirectory(m_startParameters->workingDir);
-        if (!m_startParameters->environment.isEmpty())
-            m_uploadProc.setEnvironment(m_startParameters->environment);
-        m_uploadProc.start(_("/bin/sh ") + m_startParameters->serverStartScript);
+        if (!startParameters().workingDir.isEmpty())
+            m_uploadProc.setWorkingDirectory(startParameters().workingDir);
+        if (!startParameters().environment.isEmpty())
+            m_uploadProc.setEnvironment(startParameters().environment);
+        m_uploadProc.start(_("/bin/sh ") + startParameters().serverStartScript);
         m_uploadProc.waitForStarted();
     }
 */
@@ -182,9 +181,9 @@ void RemoteGdbAdapter::prepareInferior()
 {
     QTC_ASSERT(state() == AdapterStarted, qDebug() << state());
     setState(InferiorPreparing);
-    if (!m_startParameters->processArgs.isEmpty())
+    if (!startParameters().processArgs.isEmpty())
         m_engine->postCommand(_("-exec-arguments ")
-            + m_startParameters->processArgs.join(_(" ")));
+            + startParameters().processArgs.join(_(" ")));
     QFileInfo fi(m_engine->startParameters().executable);
     m_engine->postCommand(_("-file-exec-and-symbols \"%1\"").arg(fi.absoluteFilePath()),
         CB(handleFileExecAndSymbols));
diff --git a/src/plugins/debugger/gdb/remotegdbadapter.h b/src/plugins/debugger/gdb/remotegdbadapter.h
index 054d782fef8798e1d2572da273a4ee5fd9ec3166..cd15b87e5996648f1579ca2b07d54173eb93498e 100644
--- a/src/plugins/debugger/gdb/remotegdbadapter.h
+++ b/src/plugins/debugger/gdb/remotegdbadapter.h
@@ -52,6 +52,7 @@ class RemoteGdbAdapter : public AbstractGdbAdapter
 public:
     RemoteGdbAdapter(GdbEngine *engine, QObject *parent = 0);
 
+private:
     QByteArray readAllStandardError() { return m_gdbProc.readAllStandardError(); }
     QByteArray readAllStandardOutput() { return m_gdbProc.readAllStandardOutput(); }
     qint64 write(const char *data) { return m_gdbProc.write(data); }
@@ -59,17 +60,16 @@ public:
     void setEnvironment(const QStringList &env) { m_gdbProc.setEnvironment(env); }
     bool isTrkAdapter() const { return false; }
 
-    void startAdapter(const DebuggerStartParametersPtr &sp);
+    void startAdapter();
     void prepareInferior();
     void startInferior();
     void interruptInferior();
     void shutdown();
 
-    void readUploadStandardOutput();
-    void readUploadStandardError();
-    void uploadProcError(QProcess::ProcessError error);
+    Q_SLOT void readUploadStandardOutput();
+    Q_SLOT void readUploadStandardError();
+    Q_SLOT void uploadProcError(QProcess::ProcessError error);
 
-private:
     void handleFileExecAndSymbols(const GdbResultRecord &, const QVariant &);
     void handleKill(const GdbResultRecord &, const QVariant &);
     void handleExit(const GdbResultRecord &, const QVariant &);
@@ -80,7 +80,6 @@ private:
     Q_SLOT void handleGdbStarted();
 
     QProcess m_gdbProc;
-    DebuggerStartParametersPtr m_startParameters;
     QProcess m_uploadProc;
 };
 
diff --git a/src/plugins/texteditor/basetexteditor.cpp b/src/plugins/texteditor/basetexteditor.cpp
index fb34d45174cb591e6b370c2d5ca5f38aa5509b89..b5e47fa6be3fce2d1899c32da971c3b3e3d07a7b 100644
--- a/src/plugins/texteditor/basetexteditor.cpp
+++ b/src/plugins/texteditor/basetexteditor.cpp
@@ -589,6 +589,9 @@ Core::IFile *BaseTextEditor::file()
 
 void BaseTextEditor::editorContentsChange(int position, int charsRemoved, int charsAdded)
 {
+    if (d->m_animator)
+        d->m_animator->finish();
+
     d->m_contentsChanged = true;
 
     // Keep the line numbers and the block information for the text marks updated
@@ -2689,7 +2692,8 @@ void BaseTextEditor::slotCursorPositionChanged()
 
     if (d->m_parenthesesMatchingEnabled) {
         // Delay update when no matching is displayed yet, to avoid flicker
-        if (extraSelections(ParenthesesMatchingSelection).isEmpty()) {
+        if (extraSelections(ParenthesesMatchingSelection).isEmpty()
+            && d->m_animator == 0) {
             d->m_parenthesesMatchingTimer->start(50);
         } else {
              // use 0-timer, not direct call, to give the syntax highlighter a chance
@@ -3747,11 +3751,13 @@ void BaseTextEditor::setFindScope(const QTextCursor &scope)
     }
 }
 
-void BaseTextEditor::_q_animateUpdate(int position, QRectF rect)
+void BaseTextEditor::_q_animateUpdate(int position, QPointF lastPos, QRectF rect)
 {
     QTextCursor cursor(textCursor());
     cursor.setPosition(position);
     viewport()->update(QRectF(cursorRect(cursor).topLeft() + rect.topLeft(), rect.size()).toAlignedRect());
+    if (!lastPos.isNull())
+        viewport()->update(QRectF(lastPos + rect.topLeft(), rect.size()).toAlignedRect());
 }
 
 
@@ -3778,6 +3784,7 @@ void BaseTextEditorAnimator::setData(QFont f, QPalette pal, const QString &text)
 
 void BaseTextEditorAnimator::draw(QPainter *p, const QPointF &pos)
 {
+    m_lastDrawPos = pos;
     p->setPen(m_palette.text().color());
     QFont f = m_font;
     f.setPointSizeF(f.pointSizeF() * (1.0 + m_value/2));
@@ -3809,11 +3816,12 @@ void BaseTextEditorAnimator::step(qreal v)
     QRectF before = rect();
     m_value = v;
     QRectF after = rect();
-    emit updateRequest(m_position, before.united(after));
+    emit updateRequest(m_position, m_lastDrawPos, before.united(after));
 }
 
 void BaseTextEditorAnimator::finish()
 {
+    m_timeline->stop();
     step(0);
     deleteLater();
 }
@@ -3912,8 +3920,8 @@ void BaseTextEditor::_q_matchParentheses()
         pal.setBrush(QPalette::Text, d->m_matchFormat.foreground());
         pal.setBrush(QPalette::Base, d->m_rangeFormat.background());
         d->m_animator->setData(font(), pal, characterAt(d->m_animator->position()));
-        connect(d->m_animator, SIGNAL(updateRequest(int,QRectF)),
-                this, SLOT(_q_animateUpdate(int,QRectF)));
+        connect(d->m_animator, SIGNAL(updateRequest(int,QPointF,QRectF)),
+                this, SLOT(_q_animateUpdate(int,QPointF,QRectF)));
     }
 
     setExtraSelections(ParenthesesMatchingSelection, extraSelections);
diff --git a/src/plugins/texteditor/basetexteditor.h b/src/plugins/texteditor/basetexteditor.h
index 2015a10fcb5fa2887464e5fcf23281a2ffaa82c8..ad2b022b0a31b12b3848131dff84458eb85af82b 100644
--- a/src/plugins/texteditor/basetexteditor.h
+++ b/src/plugins/texteditor/basetexteditor.h
@@ -242,22 +242,23 @@ class TEXTEDITOR_EXPORT BaseTextEditorAnimator : public QObject
 public:
     BaseTextEditorAnimator(QObject *parent);
 
-    void setPosition(int position) { m_position = position; }
-    int position() const { return m_position; }
+    inline void setPosition(int position) { m_position = position; }
+    inline int position() const { return m_position; }
 
     void setData(QFont f, QPalette pal, const QString &text);
 
     void draw(QPainter *p, const QPointF &pos);
     QRectF rect() const;
 
-    qreal value() const { return m_value; }
+    inline qreal value() const { return m_value; }
+    inline QPointF lastDrawPos() const { return m_lastDrawPos; }
 
     void finish();
 
     bool isRunning() const;
 
 signals:
-    void updateRequest(int position, QRectF rect);
+    void updateRequest(int position, QPointF lastPos, QRectF rect);
 
 
 private slots:
@@ -267,6 +268,7 @@ private:
     QTimeLine *m_timeline;
     qreal m_value;
     int m_position;
+    QPointF m_lastDrawPos;
     QFont m_font;
     QPalette m_palette;
     QString m_text;
@@ -599,7 +601,7 @@ private slots:
     void _q_matchParentheses();
     void _q_highlightBlocks();
     void slotSelectionChanged();
-    void _q_animateUpdate(int position, QRectF rect);
+    void _q_animateUpdate(int position, QPointF lastPos, QRectF rect);
 };
 
 
diff --git a/src/shared/trk/trkdevice.cpp b/src/shared/trk/trkdevice.cpp
index c17a4532f19299868f4717246a792db601e64e4b..773e1ea3c48cf43e5612022688b408cd44f18ecb 100644
--- a/src/shared/trk/trkdevice.cpp
+++ b/src/shared/trk/trkdevice.cpp
@@ -39,6 +39,7 @@
 #include <QtCore/QMutex>
 #include <QtCore/QWaitCondition>
 #include <QtCore/QSharedPointer>
+#include <QtCore/QMetaType>
 
 #ifdef Q_OS_WIN
 #  include <windows.h>
@@ -132,18 +133,30 @@ TrkMessage::TrkMessage(byte c, byte t, TrkCallback cb) :
 {
 }
 
+} // namespace trk
+
+Q_DECLARE_METATYPE(trk::TrkMessage)
+
+namespace trk {
 
 ///////////////////////////////////////////////////////////////////////
 //
-// TrkWriteQueue
+// TrkWriteQueue: Mixin class that manages a write queue of Trk messages.
+// pendingMessage()/notifyWriteResult() should be called from a worked/timer
+// that writes the messages. The class does not take precautions for multithreading
+// with exception of the handling of the  TRK_WRITE_QUEUE_NOOP_CODE
+// synchronization message. The invocation of the callback is then
+// done by the thread owning the TrkWriteQueue, while pendingMessage() is called
+// from another thread. This happens via a Qt::BlockingQueuedConnection.
 //
 ///////////////////////////////////////////////////////////////////////
 
-/* Mixin class that manages a write queue of Trk messages. */
-class TrkWriteQueue
-{
+class TrkWriteQueue : public QObject
+{    
+    Q_OBJECT
+    Q_DISABLE_COPY(TrkWriteQueue)
 public:
-    TrkWriteQueue();
+    explicit TrkWriteQueue(bool multithreaded = true);
 
     // Enqueue messages.
     void queueTrkMessage(byte code, TrkCallback callback,
@@ -160,6 +173,12 @@ public:
     // after taking the pendingMessage off.
     void notifyWriteResult(bool ok);
 
+signals:
+    void internalNoopMessageDequeued(const trk::TrkMessage&);
+
+private slots:
+    void invokeNoopMessage(trk::TrkMessage);
+
 private:
     typedef QMap<byte, TrkMessage> TokenMessageMap;
 
@@ -171,10 +190,15 @@ private:
     bool m_trkWriteBusy;
 };
 
-TrkWriteQueue::TrkWriteQueue() :
+TrkWriteQueue::TrkWriteQueue(bool multithreaded) :
     m_trkWriteToken(0),
     m_trkWriteBusy(false)
 {
+    static const int trkMessageMetaId = qRegisterMetaType<trk::TrkMessage>();
+    Q_UNUSED(trkMessageMetaId)
+    connect(this, SIGNAL(internalNoopMessageDequeued(trk::TrkMessage)),
+            this, SLOT(invokeNoopMessage(trk::TrkMessage)),
+            multithreaded ? Qt::BlockingQueuedConnection : Qt::AutoConnection);
 }
 
 byte TrkWriteQueue::nextTrkWriteToken()
@@ -201,17 +225,11 @@ bool TrkWriteQueue::pendingMessage(TrkMessage *message)
     // Invoked from timer, try to flush out message queue
     if (m_trkWriteBusy || m_trkWriteQueue.isEmpty())
         return false;
-    // Handle the noop message, just invoke CB
+    // Handle the noop message, just invoke CB in slot (ower thread)
     if (m_trkWriteQueue.front().code == TRK_WRITE_QUEUE_NOOP_CODE) {
         TrkMessage noopMessage = m_trkWriteQueue.dequeue();
-        if (noopMessage.callback) {
-            TrkResult result;
-            result.code = noopMessage.code;
-            result.token = noopMessage.token;
-            result.data = noopMessage.data;
-            result.cookie = noopMessage.cookie;
-            noopMessage.callback(result);
-        }
+        if (noopMessage.callback)
+            emit internalNoopMessageDequeued(noopMessage);
     }
     // Check again for real messages
     if (m_trkWriteQueue.isEmpty())
@@ -221,6 +239,16 @@ bool TrkWriteQueue::pendingMessage(TrkMessage *message)
     return true;
 }
 
+void TrkWriteQueue::invokeNoopMessage(trk::TrkMessage noopMessage)
+{
+    TrkResult result;
+    result.code = noopMessage.code;
+    result.token = noopMessage.token;
+    result.data = noopMessage.data;
+    result.cookie = noopMessage.cookie;
+    noopMessage.callback(result);
+}
+
 void TrkWriteQueue::notifyWriteResult(bool ok)
 {
     // On success, dequeue message and await result
@@ -271,6 +299,7 @@ struct DeviceContext {
     QFile file;
 #endif
     bool serialFrame;
+    QMutex mutex;
 };
 
 DeviceContext::DeviceContext() :
@@ -358,6 +387,7 @@ void WriterThread::terminate()
 
 bool WriterThread::write(const QByteArray &data, QString *errorMessage)
 {
+    QMutexLocker(&m_context->mutex);
 #ifdef Q_OS_WIN
     DWORD charsWritten;
     if (!WriteFile(m_context->device, data.data(), data.size(), &charsWritten, NULL)) {
@@ -588,12 +618,14 @@ void TrkDevice::tryTrkRead()
     char buffer[BUFFERSIZE];
     DWORD charsRead;
     DWORD totalCharsRead = 0;
-
-    while (TryReadFile(d->deviceContext->device, buffer, BUFFERSIZE, &charsRead, NULL)) {
-        totalCharsRead += charsRead;
-        d->trkReadBuffer.append(buffer, charsRead);
-        if (isValidTrkResult(d->trkReadBuffer, d->deviceContext->serialFrame))
-            break;
+    {
+        QMutexLocker(&d->deviceContext->mutex);
+        while (TryReadFile(d->deviceContext->device, buffer, BUFFERSIZE, &charsRead, NULL)) {
+            totalCharsRead += charsRead;
+            d->trkReadBuffer.append(buffer, charsRead);
+            if (isValidTrkResult(d->trkReadBuffer, d->deviceContext->serialFrame))
+                break;
+        }
     }
     if (d->verbose > 1 && totalCharsRead)
         emitLogMessage("Read" + d->trkReadBuffer.toHex());
@@ -606,10 +638,14 @@ void TrkDevice::tryTrkRead()
         return;
     }
 #else
-    const int size = bytesAvailable(d->deviceContext->file.handle());
-    if (!size)
-        return;
-    const QByteArray data = d->deviceContext->file.read(size);
+    QByteArray data;
+    {
+        QMutexLocker(&d->deviceContext->mutex);
+        const int size = bytesAvailable(d->deviceContext->file.handle());
+        if (!size)
+            return;
+        data = d->deviceContext->file.read(size);
+    }
     if (d->verbose > 1)
         emitLogMessage("trk: <- " + stringFromArray(data));
     d->trkReadBuffer.append(data);