diff --git a/src/plugins/debugger/breakcondition.ui b/src/plugins/debugger/breakcondition.ui
index f5b5b0819d3c15ece4bc8aa8e04936d8a9f1475c..73aaa8ac39198547e132f8ef691adc4099af91d4 100644
--- a/src/plugins/debugger/breakcondition.ui
+++ b/src/plugins/debugger/breakcondition.ui
@@ -14,32 +14,65 @@
    <item>
     <layout class="QGridLayout" name="gridLayout">
      <item row="0" column="0">
+      <widget class="QLabel" name="labelFileName">
+       <property name="text">
+        <string>File name:</string>
+       </property>
+      </widget>
+     </item>
+     <item row="0" column="1">
+      <widget class="QLineEdit" name="lineEditFileName"/>
+     </item>
+     <item row="1" column="0">
+      <widget class="QLabel" name="labelLineNumber">
+       <property name="text">
+        <string>Line number:</string>
+       </property>
+      </widget>
+     </item>
+     <item row="1" column="1">
+      <widget class="QLineEdit" name="lineEditLineNumber"/>
+     </item>
+     <item row="2" column="0">
+      <widget class="QLabel" name="labelFunction">
+       <property name="text">
+        <string>Function:</string>
+       </property>
+      </widget>
+     </item>
+     <item row="2" column="1">
+      <widget class="QLineEdit" name="lineEditFunction"/>
+     </item>
+     <item row="3" column="0">
       <widget class="QLabel" name="labelCondition">
        <property name="text">
         <string>Condition:</string>
        </property>
       </widget>
      </item>
-     <item row="0" column="1">
+     <item row="3" column="1">
       <widget class="QLineEdit" name="lineEditCondition"/>
      </item>
-     <item row="1" column="0">
+     <item row="4" column="0">
       <widget class="QLabel" name="labelIgnoreCount">
        <property name="text">
         <string>Ignore count:</string>
        </property>
       </widget>
      </item>
-     <item row="1" column="1">
-      <widget class="QSpinBox" name="spinBoxIgnoreCount">
-       <property name="layoutDirection">
-        <enum>Qt::LeftToRight</enum>
-       </property>
-       <property name="maximum">
-        <number>999999999</number>
+     <item row="4" column="1">
+      <widget class="QLineEdit" name="lineEditIgnoreCount"/>
+     </item>
+     <item row="5" column="0">
+      <widget class="QLabel" name="labelThreadSpec">
+       <property name="text">
+        <string>Thread specification:</string>
        </property>
       </widget>
      </item>
+     <item row="5" column="1">
+      <widget class="QLineEdit" name="lineEditThreadSpec"/>
+     </item>
     </layout>
    </item>
    <item>
diff --git a/src/plugins/debugger/breakhandler.cpp b/src/plugins/debugger/breakhandler.cpp
index 6ed2830cd8cdb6b85bc67177e0c9caa724bb2c30..c41eb00c86a2824d7defa848ad294e5acac0aec5 100644
--- a/src/plugins/debugger/breakhandler.cpp
+++ b/src/plugins/debugger/breakhandler.cpp
@@ -247,6 +247,8 @@ QString BreakpointData::toToolTip() const
         << "</td><td>" << condition << "</td><td>" << bpCondition << "</td></tr>"
         << "<tr><td>" << BreakHandler::tr("Ignore Count:")
         << "</td><td>" << ignoreCount << "</td><td>" << bpIgnoreCount << "</td></tr>"
+        << "<tr><td>" << BreakHandler::tr("Thread Specification:")
+        << "</td><td>" << threadSpec << "</td><td>" << bpThreadSpec << "</td></tr>"
         << "</table></body></html>";
     return rc;
 }
@@ -268,7 +270,9 @@ QString BreakpointData::toString() const
         << BreakHandler::tr("Condition:")
         << condition << " -- " << bpCondition << '\n'
         << BreakHandler::tr("Ignore Count:")
-        << ignoreCount << " -- " << bpIgnoreCount << '\n';
+        << ignoreCount << " -- " << bpIgnoreCount << '\n'
+        << BreakHandler::tr("Thread Specification:")
+        << threadSpec << " -- " << bpThreadSpec << '\n';
     return rc;
 }
 
@@ -320,7 +324,7 @@ BreakHandler::~BreakHandler()
 
 int BreakHandler::columnCount(const QModelIndex &parent) const
 {
-    return parent.isValid() ? 0 : 7;
+    return parent.isValid() ? 0 : 8;
 }
 
 int BreakHandler::rowCount(const QModelIndex &parent) const
@@ -418,6 +422,8 @@ void BreakHandler::saveBreakpoints()
             map.insert(QLatin1String("condition"), data->condition);
         if (!data->ignoreCount.isEmpty())
             map.insert(QLatin1String("ignorecount"), data->ignoreCount);
+        if (!data->threadSpec.isEmpty())
+            map.insert(QLatin1String("threadspec"), data->threadSpec);
         if (!data->enabled)
             map.insert(QLatin1String("disabled"), QLatin1String("1"));
         if (data->useFullPath)
@@ -447,6 +453,9 @@ void BreakHandler::loadBreakpoints()
         v = map.value(QLatin1String("ignorecount"));
         if (v.isValid())
             data->ignoreCount = v.toString().toLatin1();
+        v = map.value(QLatin1String("threadspec"));
+        if (v.isValid())
+            data->threadSpec = v.toString().toLatin1();
         v = map.value(QLatin1String("funcname"));
         if (v.isValid())
             data->funcName = v.toString();
@@ -476,6 +485,7 @@ void BreakHandler::resetBreakpoints()
         data->bpCorrectedLineNumber.clear();
         data->bpCondition.clear();
         data->bpIgnoreCount.clear();
+        data->bpThreadSpec.clear();
         data->bpAddress.clear();
         // Keep marker data if it was primary.
         if (data->markerFileName() != data->fileName)
@@ -502,7 +512,7 @@ QVariant BreakHandler::headerData(int section,
     if (orientation == Qt::Horizontal && role == Qt::DisplayRole) {
         static QString headers[] = {
             tr("Number"),  tr("Function"), tr("File"), tr("Line"),
-            tr("Condition"), tr("Ignore"), tr("Address")
+            tr("Condition"), tr("Ignore"), tr("Threads"), tr("Address")
         };
         return headers[section];
     }
@@ -538,6 +548,8 @@ QVariant BreakHandler::data(const QModelIndex &mi, int role) const
                 const QString str = data->pending ? data->funcName : data->bpFuncName;
                 return str.isEmpty() ? empty : str;
             }
+            if (role == Qt::UserRole + 1)
+                return data->funcName;
             break;
         case 2:
             if (role == Qt::DisplayRole) {
@@ -553,6 +565,8 @@ QVariant BreakHandler::data(const QModelIndex &mi, int role) const
             }
             if (role == Qt::UserRole)
                 return data->useFullPath;
+            if (role == Qt::UserRole + 1)
+                return data->fileName;
             break;
         case 3:
             if (role == Qt::DisplayRole) {
@@ -562,19 +576,36 @@ QVariant BreakHandler::data(const QModelIndex &mi, int role) const
                 const QString str = data->pending ? data->lineNumber : data->bpLineNumber;
                 return str.isEmpty() ? empty : str;
             }
+            if (role == Qt::UserRole + 1)
+                return data->lineNumber;
             break;
         case 4:
             if (role == Qt::DisplayRole)
                 return data->pending ? data->condition : data->bpCondition;
             if (role == Qt::ToolTipRole)
                 return tr("Breakpoint will only be hit if this condition is met.");
+            if (role == Qt::UserRole + 1)
+                return data->condition;
             break;
         case 5:
             if (role == Qt::DisplayRole)
                 return data->pending ? data->ignoreCount : data->bpIgnoreCount;
             if (role == Qt::ToolTipRole)
                 return tr("Breakpoint will only be hit after being ignored so many times.");
+            if (role == Qt::UserRole + 1)
+                return data->ignoreCount;
         case 6:
+            if (role == Qt::DisplayRole) {
+                if (data->pending)
+                    return !data->threadSpec.isEmpty() ? data->threadSpec : tr("(all)");
+                else
+                    return !data->bpThreadSpec.isEmpty() ? data->bpThreadSpec : tr("(all)");
+            }
+            if (role == Qt::ToolTipRole)
+                return tr("Breakpoint will only be hit in the specified thread(s).");
+            if (role == Qt::UserRole + 1)
+                return data->threadSpec;
+        case 7:
             if (role == Qt::DisplayRole)
                 return data->bpAddress;
             break;
@@ -597,38 +628,73 @@ Qt::ItemFlags BreakHandler::flags(const QModelIndex &mi) const
 
 bool BreakHandler::setData(const QModelIndex &mi, const QVariant &value, int role)
 {
-    if (role != Qt::EditRole)
-        return false;
-
     BreakpointData *data = at(mi.row());
+
+    if (role == Qt::UserRole + 1) {
+        if (data->enabled != value.toBool()) {
+            toggleBreakpointEnabled(data);
+            layoutChanged();
+        }
+        return true;
+    }
+
+    if (role == Qt::UserRole + 2) {
+        if (data->useFullPath != value.toBool()) {
+            data->useFullPath = value.toBool();
+            layoutChanged();
+        }
+        return true;
+    }
+
+    //if (role != Qt::EditRole)
+    //    return false;
+
     switch (mi.column()) {
-        case 0: {
-            if (data->enabled != value.toBool()) {
-                toggleBreakpointEnabled(data);
-                dataChanged(mi, mi);
+        case 1: {
+            QString val = value.toString();
+            if (data->funcName != val) {
+                data->funcName = val;
+                layoutChanged();
             }
             return true;
         }
         case 2: {
-            if (data->useFullPath != value.toBool()) {
-                data->useFullPath = value.toBool();
-                dataChanged(mi, mi);
+            QString val = value.toString();
+            if (data->fileName != val) {
+                data->fileName = val;
+                layoutChanged();
+            }
+            return true;
+        }
+        case 3: {
+            QByteArray val = value.toString().toLatin1();
+            if (data->lineNumber != val) {
+                data->lineNumber = val;
+                layoutChanged();
             }
             return true;
         }
         case 4: {
-            QString val = value.toString();
+            QByteArray val = value.toString().toLatin1();
             if (val != data->condition) {
-                data->condition = val.toLatin1();
-                dataChanged(mi, mi);
+                data->condition = val;
+                layoutChanged();
             }
             return true;
         }
         case 5: {
-            QString val = value.toString();
+            QByteArray val = value.toString().toLatin1();
             if (val != data->ignoreCount) {
-                data->ignoreCount = val.toLatin1();
-                dataChanged(mi, mi);
+                data->ignoreCount = val;
+                layoutChanged();
+            }
+            return true;
+        }
+        case 6: {
+            QByteArray val = value.toString().toLatin1();
+            if (val != data->threadSpec) {
+                data->threadSpec = val;
+                layoutChanged();
             }
             return true;
         }
diff --git a/src/plugins/debugger/breakhandler.h b/src/plugins/debugger/breakhandler.h
index c0aaadc8cb6727e82f604e8ce929433cc9b01b04..ad2c640a30f7b7441d12a111f56d2fcc11baf77c 100644
--- a/src/plugins/debugger/breakhandler.h
+++ b/src/plugins/debugger/breakhandler.h
@@ -80,6 +80,7 @@ public:
     QByteArray condition;    // Condition associated with breakpoint.
     QByteArray ignoreCount;  // Ignore count associated with breakpoint.
     QByteArray lineNumber;   // Line in source file.
+    QByteArray threadSpec;   // Thread specification.
     QString funcName;        // Name of containing function.
     bool useFullPath;        // Should we use the full path when setting the bp?
 
@@ -91,6 +92,7 @@ public:
     QString bpFullName;      // Full file name acknowledged by the debugger engine.
     QByteArray bpLineNumber; // Line number acknowledged by the debugger engine.
     QByteArray bpCorrectedLineNumber; // Acknowledged by the debugger engine.
+    QByteArray bpThreadSpec; // Thread spec acknowledged by the debugger engine.
     QString bpFuncName;      // Function name acknowledged by the debugger engine.
     QByteArray bpAddress;    // Address acknowledged by the debugger engine.
     bool bpMultiple;         // Happens in constructors/gdb.
diff --git a/src/plugins/debugger/breakwindow.cpp b/src/plugins/debugger/breakwindow.cpp
index 34ddcd551d59e81bf6d405c494721d03a8fd0879..99826798c01ad7f1c809acd057bd0bccb62fa00c 100644
--- a/src/plugins/debugger/breakwindow.cpp
+++ b/src/plugins/debugger/breakwindow.cpp
@@ -103,7 +103,7 @@ BreakWindow::BreakWindow(Debugger::DebuggerManager *manager)
 
 void BreakWindow::showAddressColumn(bool on)
 {
-    setColumnHidden(6, !on);
+    setColumnHidden(7, !on);
 }
 
 static QModelIndexList normalizeIndexes(const QModelIndexList &list)
@@ -133,6 +133,13 @@ void BreakWindow::resizeEvent(QResizeEvent *ev)
     QTreeView::resizeEvent(ev);
 }
 
+void BreakWindow::mouseDoubleClickEvent(QMouseEvent *ev)
+{
+    QModelIndex indexUnderMouse = indexAt(ev->pos());
+    if (indexUnderMouse.isValid())
+        editBreakpoint(QModelIndexList() << indexUnderMouse);
+}
+
 void BreakWindow::contextMenuEvent(QContextMenuEvent *ev)
 {
     QMenu menu;
@@ -185,9 +192,9 @@ void BreakWindow::contextMenuEvent(QContextMenuEvent *ev)
     alwaysAdjustAction->setCheckable(true);
     alwaysAdjustAction->setChecked(m_alwaysResizeColumnsToContents);
 
-    QAction *editConditionAction =
-        new QAction(tr("Edit Condition..."), &menu);
-    editConditionAction->setEnabled(si.size() > 0);
+    QAction *editBreakpointAction =
+        new QAction(tr("Edit Breakpoint..."), &menu);
+    editBreakpointAction->setEnabled(si.size() > 0);
 
     QAction *synchronizeAction =
         new QAction(tr("Synchronize Breakpoints"), &menu);
@@ -223,7 +230,7 @@ void BreakWindow::contextMenuEvent(QContextMenuEvent *ev)
         new QAction(tr("Set Breakpoint at \"catch\""), this);
 
     menu.addAction(deleteAction);
-    menu.addAction(editConditionAction);
+    menu.addAction(editBreakpointAction);
     menu.addAction(toggleEnabledAction);
     menu.addAction(pathAction);
     menu.addSeparator();
@@ -261,8 +268,8 @@ void BreakWindow::contextMenuEvent(QContextMenuEvent *ev)
         resizeColumnsToContents();
     else if (act == alwaysAdjustAction)
         setAlwaysResizeColumnsToContents(!m_alwaysResizeColumnsToContents);
-    else if (act == editConditionAction)
-        editConditions(si);
+    else if (act == editBreakpointAction)
+        editBreakpoint(si);
     else if (act == synchronizeAction)
         emit breakpointSynchronizationRequested();
     else if (act == toggleEnabledAction)
@@ -284,7 +291,7 @@ void BreakWindow::contextMenuEvent(QContextMenuEvent *ev)
 void BreakWindow::setBreakpointsEnabled(const QModelIndexList &list, bool enabled)
 {
     foreach (const QModelIndex &idx, list)
-        model()->setData(idx, enabled);
+        model()->setData(idx, enabled, Qt::UserRole + 1);
     emit breakpointSynchronizationRequested();
 }
 
@@ -292,7 +299,7 @@ void BreakWindow::setBreakpointsFullPath(const QModelIndexList &list, bool fullp
 {
     foreach (const QModelIndex &idx, list) {
         QModelIndex idx2 = idx.sibling(idx.row(), 2);
-        model()->setData(idx2, fullpath);
+        model()->setData(idx2, fullpath, Qt::UserRole + 2);
     }
     emit breakpointSynchronizationRequested();
 }
@@ -320,7 +327,7 @@ void BreakWindow::deleteBreakpoints(QList<int> list)
         setCurrentIndex(model()->index(row, 0));
 }
 
-void BreakWindow::editConditions(const QModelIndexList &list)
+void BreakWindow::editBreakpoint(const QModelIndexList &list)
 {
     QDialog dlg(this);
     Ui::BreakCondition ui;
@@ -330,15 +337,36 @@ void BreakWindow::editConditions(const QModelIndexList &list)
     QModelIndex idx = list.front();
     int row = idx.row();
     dlg.setWindowTitle(tr("Conditions on Breakpoint %1").arg(row));
-    ui.lineEditCondition->setText(model()->data(idx.sibling(row, 4)).toString());
-    ui.spinBoxIgnoreCount->setValue(model()->data(idx.sibling(row, 5)).toInt());
+    int role = Qt::UserRole + 1;
+    ui.lineEditFunction->hide();
+    ui.labelFunction->hide();
+    ui.lineEditFileName->hide();
+    ui.labelFileName->hide();
+    ui.lineEditLineNumber->hide();
+    ui.labelLineNumber->hide();
+    //ui.lineEditFunction->setText(
+    //    model()->data(idx.sibling(row, 1), role).toString());
+    //ui.lineEditFileName->setText(
+    //    model()->data(idx.sibling(row, 2), role).toString());
+    //ui.lineEditLineNumber->setText(
+    //    model()->data(idx.sibling(row, 3), role).toString());
+    ui.lineEditCondition->setText(
+        model()->data(idx.sibling(row, 4), role).toString());
+    ui.lineEditIgnoreCount->setText(
+        model()->data(idx.sibling(row, 5), role).toString());
+    ui.lineEditThreadSpec->setText(
+        model()->data(idx.sibling(row, 6), role).toString());
 
     if (dlg.exec() == QDialog::Rejected)
         return;
 
     foreach (const QModelIndex &idx, list) {
+        //model()->setData(idx.sibling(idx.row(), 1), ui.lineEditFunction->text());
+        //model()->setData(idx.sibling(idx.row(), 2), ui.lineEditFileName->text());
+        //model()->setData(idx.sibling(idx.row(), 3), ui.lineEditLineNumber->text());
         model()->setData(idx.sibling(idx.row(), 4), ui.lineEditCondition->text());
-        model()->setData(idx.sibling(idx.row(), 5), ui.spinBoxIgnoreCount->value());
+        model()->setData(idx.sibling(idx.row(), 5), ui.lineEditIgnoreCount->text());
+        model()->setData(idx.sibling(idx.row(), 6), ui.lineEditThreadSpec->text());
     }
     emit breakpointSynchronizationRequested();
 }
diff --git a/src/plugins/debugger/breakwindow.h b/src/plugins/debugger/breakwindow.h
index 3429d7a64858e5ef9731e280baf88036a3990207..be25319d2bbe8d66e617ef08b6cba43772566865 100644
--- a/src/plugins/debugger/breakwindow.h
+++ b/src/plugins/debugger/breakwindow.h
@@ -1,4 +1,5 @@
 /**************************************************************************
+QT_END_NAMESPACE
 **
 ** This file is part of Qt Creator
 **
@@ -65,11 +66,12 @@ protected:
     void resizeEvent(QResizeEvent *ev);
     void contextMenuEvent(QContextMenuEvent *ev);
     void keyPressEvent(QKeyEvent *ev);
+    void mouseDoubleClickEvent(QMouseEvent *ev);
 
 private:
     void deleteBreakpoints(const QModelIndexList &list);
     void deleteBreakpoints(QList<int> rows);
-    void editConditions(const QModelIndexList &list);
+    void editBreakpoint(const QModelIndexList &list);
     void setBreakpointsEnabled(const QModelIndexList &list, bool enabled);
     void setBreakpointsFullPath(const QModelIndexList &list, bool fullpath);
 
diff --git a/src/plugins/debugger/cdb/cdbbreakpoint.cpp b/src/plugins/debugger/cdb/cdbbreakpoint.cpp
index 79e7012aeb60106bdc53608afef948ee0bac7a31..cdd57b5544bc5097a112f475c77213be9e3418bc 100644
--- a/src/plugins/debugger/cdb/cdbbreakpoint.cpp
+++ b/src/plugins/debugger/cdb/cdbbreakpoint.cpp
@@ -102,6 +102,7 @@ bool synchronizeBreakPoints(CIDebugControl* debugControl,
                 // Take over rest as is
                 nbd->bpCondition = nbd->condition;
                 nbd->bpIgnoreCount = nbd->ignoreCount;
+                nbd->bpThreadSpec = nbd->threadSpec;
                 nbd->bpFileName = nbd->fileName;
                 nbd->bpLineNumber = nbd->lineNumber;
                 nbd->bpFuncName = nbd->funcName;
diff --git a/src/plugins/debugger/gdb/gdbengine.cpp b/src/plugins/debugger/gdb/gdbengine.cpp
index 166e5de6c7b6132faad6e63bdb67830648065a00..16199e52ebb4e5feff47b61c82ff1b01860f5a75 100644
--- a/src/plugins/debugger/gdb/gdbengine.cpp
+++ b/src/plugins/debugger/gdb/gdbengine.cpp
@@ -443,7 +443,7 @@ void GdbEngine::handleResponse(const QByteArray &buff)
                 int progress = m_progress->progressValue();
                 m_progress->setProgressValue(qMin(70, progress + 1));
                 QByteArray id = result.findChild("id").data();
-                showStatusMessage(tr("Thread group %1 created.").arg(_(id)), 1000);
+                showStatusMessage(tr("Thread group %1 created").arg(_(id)), 1000);
                 int pid = id.toInt();
                 if (pid != inferiorPid())
                     handleInferiorPidChanged(pid);
@@ -789,7 +789,7 @@ void GdbEngine::postCommandHelper(const GdbCommand &cmd)
             } else if (state() == InferiorRunningRequested_Kill) {
                 debugMessage(_("RUNNING REQUESTED; POSTPONING INTERRUPT (KILL PENDING)"));
             } else if (state() == InferiorRunning) {
-                showStatusMessage(tr("Stopping temporarily."), 1000);
+                showStatusMessage(tr("Stopping temporarily"), 1000);
                 interruptInferiorTemporarily();
             } else {
                 qDebug() << "ATTEMPTING TO QUEUE COMMAND IN INAPPROPRIATE STATE" << state();
@@ -802,7 +802,7 @@ void GdbEngine::postCommandHelper(const GdbCommand &cmd)
 
 void GdbEngine::flushQueuedCommands()
 {
-    showStatusMessage(tr("Processing queued commands."), 1000);
+    showStatusMessage(tr("Processing queued commands"), 1000);
     while (!m_commandsToRunOnTemporaryBreak.isEmpty()) {
         GdbCommand cmd = m_commandsToRunOnTemporaryBreak.takeFirst();
         debugMessage(_("RUNNING QUEUED COMMAND " + cmd.command + ' '
@@ -908,7 +908,7 @@ void GdbEngine::handleResultRecord(GdbResponse *response)
                 debugMessage(_("APPLYING WORKAROUND #1"));
                 showMessageBox(QMessageBox::Critical,
                     tr("Executable failed"), QString::fromLocal8Bit(msg));
-                showStatusMessage(tr("Process failed to start."));
+                showStatusMessage(tr("Process failed to start"));
                 shutdown();
             } else if (msg == "\"finish\" not meaningful in the outermost frame.") {
                 // Handle a case known to appear on gdb 6.4 symbianelf when
@@ -1091,7 +1091,7 @@ void GdbEngine::handleExecJumpToLine(const GdbResponse &response)
     // ~"242\t x *= 2;"
     //109^done"
     setState(InferiorStopped);
-    showStatusMessage(tr("Jumped. Stopped."));
+    showStatusMessage(tr("Jumped. Stopped"));
     QByteArray output = response.data.findChild("logstreamoutput").data();
     if (output.isEmpty())
         return;
@@ -1117,7 +1117,7 @@ void GdbEngine::handleExecJumpToLine(const GdbResponse &response)
 //    // file="main.cpp",fullname="/tmp/g/main.cpp",line="37"}
 //    QTC_ASSERT(state() == InferiorStopping, qDebug() << state())
 //    setState(InferiorStopped);
-//    showStatusMessage(tr("Function reached. Stopped."));
+//    showStatusMessage(tr("Function reached. Stopped"));
 //    GdbMi frame = response.data.findChild("frame");
 //    StackFrame f = parseStackFrame(frame, 0);
 //    gotoLocation(f, true);
@@ -1389,7 +1389,7 @@ void GdbEngine::handleStop1(const GdbMi &data)
     if (reason == "breakpoint-hit") {
         QByteArray bpNumber = data.findChild("bkptno").data();
         QByteArray threadId = data.findChild("thread-id").data();
-        showStatusMessage(tr("Stopped at breakpoint %1 in thread %2.")
+        showStatusMessage(tr("Stopped at breakpoint %1 in thread %2")
             .arg(_(bpNumber), _(threadId)));
     } else {
         QString reasontr = tr("Stopped: \"%1\"").arg(_(reason));
@@ -2115,6 +2115,8 @@ void GdbEngine::breakpointDataFromOutput(BreakpointData *data, const GdbMi &bkpt
             if (ba.startsWith('<') && ba.endsWith('>'))
                 ba = ba.mid(1, ba.size() - 2);
             data->bpFuncName = _(ba);
+        } else if (child.hasName("thread")) {
+            data->bpThreadSpec = child.data();
         }
     }
     // This field is not present.  Contents needs to be parsed from
@@ -2145,9 +2147,8 @@ QString GdbEngine::breakLocation(const QString &file) const
     return where;
 }
 
-QByteArray GdbEngine::breakpointLocation(int index)
+QByteArray GdbEngine::breakpointLocation(const BreakpointData *data)
 {
-    const BreakpointData *data = manager()->breakHandler()->at(index);
     if (!data->funcName.isEmpty())
         return data->funcName.toLatin1();
     // In this case, data->funcName is something like '*0xdeadbeef'
@@ -2162,21 +2163,28 @@ QByteArray GdbEngine::breakpointLocation(int index)
 
 void GdbEngine::sendInsertBreakpoint(int index)
 {
+    const BreakpointData *data = manager()->breakHandler()->at(index);
     // Set up fallback in case of pending breakpoints which aren't handled
     // by the MI interface.
     QByteArray cmd;
-    if (m_isMacGdb)
+    if (m_isMacGdb) {
         cmd = "-break-insert -l -1 -f ";
-    else if (m_gdbAdapter->isTrkAdapter())
+    } else if (m_gdbAdapter->isTrkAdapter()) {
         cmd = "-break-insert -h -f ";
-    else if (m_gdbVersion >= 60800)
+    } else if (m_gdbVersion >= 70000) {
+        cmd = "-break-insert ";
+        if (!data->threadSpec.isEmpty())
+            cmd += "-p " + data->threadSpec;
+        cmd += " -f ";
+    } else if (m_gdbVersion >= 60800) {
         // Probably some earlier version would work as well.
         cmd = "-break-insert -f ";
-    else
+    } else {
         cmd = "-break-insert ";
+    }
     //if (!data->condition.isEmpty())
     //    cmd += "-c " + data->condition + ' ';
-    cmd += breakpointLocation(index);
+    cmd += breakpointLocation(data);
     postCommand(cmd, NeedsStop | RebuildBreakpointModel,
         CB(handleBreakInsert1), index);
 }
@@ -2184,17 +2192,16 @@ void GdbEngine::sendInsertBreakpoint(int index)
 void GdbEngine::handleBreakInsert1(const GdbResponse &response)
 {
     int index = response.cookie.toInt();
-    BreakHandler *handler = manager()->breakHandler();
+    BreakpointData *data = manager()->breakHandler()->at(index);
     if (response.resultClass == GdbResultDone) {
         // Interesting only on Mac?
-        BreakpointData *data = handler->at(index);
         GdbMi bkpt = response.data.findChild("bkpt");
         breakpointDataFromOutput(data, bkpt);
     } else {
         // Some versions of gdb like "GNU gdb (GDB) SUSE (6.8.91.20090930-2.4)"
         // know how to do pending breakpoints using CLI but not MI. So try 
         // again with MI.
-        QByteArray cmd = "break " + breakpointLocation(index);
+        QByteArray cmd = "break " + breakpointLocation(data);
         postCommand(cmd, NeedsStop | RebuildBreakpointModel,
             CB(handleBreakInsert2), index);
     }
@@ -2524,7 +2531,8 @@ void GdbEngine::attemptBreakpointSynchronization()
             else // Because gdb won't do both changes at a time anyway.
             if (data->ignoreCount != data->bpIgnoreCount) {
                 // Update ignorecount if needed.
-                postCommand("ignore " + data->bpNumber + ' ' + data->ignoreCount,
+                QByteArray ic = QByteArray::number(data->ignoreCount.toInt());
+                postCommand("ignore " + data->bpNumber + ' ' + ic,
                     NeedsStop | RebuildBreakpointModel,
                     CB(handleBreakIgnore), data->bpNumber.toInt());
                 continue;
@@ -2536,6 +2544,17 @@ void GdbEngine::attemptBreakpointSynchronization()
                 data->bpEnabled = false;
                 continue;
             }
+            if (data->threadSpec != data->bpThreadSpec && !data->bpThreadSpec.isEmpty()) {
+                // The only way to change this seems to be to re-set the bp completely.
+                //qDebug() << "FIXME: THREAD: " << data->threadSpec << data->bpThreadSpec;
+                //data->bpThreadSpec = data->threadSpec;
+                if (!data->bpNumber.isEmpty()) {
+                    postCommand("-break-delete " + data->bpNumber,
+                        NeedsStop | RebuildBreakpointModel);
+                    sendInsertBreakpoint(index);
+                }
+                continue;
+            }
             if (data->bpAddress.startsWith("0x")
                     && data->bpCorrectedLineNumber.isEmpty()) {
                 // Prevent endless loop.
@@ -3958,7 +3977,7 @@ bool GdbEngine::startGdb(const QStringList &args, const QString &gdb, const QStr
     }
     if (!foundPython) {
         debugMessage(_("UNSUPPORTED GDB %1 DOES NOT HAVE PYTHON.").arg(m_gdb));
-        showStatusMessage(_("Gdb at %1 does not have python.").arg(m_gdb));
+        showStatusMessage(_("Gdb at %1 does not have python").arg(m_gdb));
     }
 #endif
 
diff --git a/src/plugins/debugger/gdb/gdbengine.h b/src/plugins/debugger/gdb/gdbengine.h
index 2093e54346ff13fd6f1169d76370ca25d47bb276..b5950703f39fc93a2864b1454cb1d1f779dab8c4 100644
--- a/src/plugins/debugger/gdb/gdbengine.h
+++ b/src/plugins/debugger/gdb/gdbengine.h
@@ -348,7 +348,7 @@ private: ////////// View & Data Stuff //////////
     void handleInfoLine(const GdbResponse &response);
     void extractDataFromInfoBreak(const QString &output, BreakpointData *data);
     void breakpointDataFromOutput(BreakpointData *data, const GdbMi &bkpt);
-    QByteArray breakpointLocation(int index);
+    QByteArray breakpointLocation(const BreakpointData *data);
     void sendInsertBreakpoint(int index);
     QString breakLocation(const QString &file) const;
     void reloadBreakListInternal();
diff --git a/src/plugins/debugger/gdb/pythongdbengine.cpp b/src/plugins/debugger/gdb/pythongdbengine.cpp
index 3edf26905ac4ef280b50aafecee4efa69da03528..ebe0dff8f8337552d707891e13aef5cb810636a5 100644
--- a/src/plugins/debugger/gdb/pythongdbengine.cpp
+++ b/src/plugins/debugger/gdb/pythongdbengine.cpp
@@ -114,8 +114,8 @@ void GdbEngine::handleStackFramePython(const GdbResponse &response)
         //qDebug() << "SECOND CHUNK: " << out;
         int pos = out.indexOf("data=");
         if (pos != 0) {
-            qDebug() << "DISCARDING JUNK AT BEGIN OF RESPONSE: "
-                << out.left(pos);
+            debugMessage(_("DISCARDING JUNK AT BEGIN OF RESPONSE: "
+                + out.left(pos)));
             out = out.mid(pos);
         }
         GdbMi all;
diff --git a/tests/manual/gdbdebugger/simple/app.cpp b/tests/manual/gdbdebugger/simple/app.cpp
index 1705327ffa59084ad55266868dbcfd7a6d594ec9..8d700848c7f8f2e8bb988ce3df670768c405b399 100644
--- a/tests/manual/gdbdebugger/simple/app.cpp
+++ b/tests/manual/gdbdebugger/simple/app.cpp
@@ -1218,10 +1218,13 @@ public:
 
     void run()
     {
+        int j = 2;
+        ++j;
         for (int i = 0; i != 100000; ++i) {
             //sleep(1);
             std::cerr << m_id;
         }
+        std::cerr << j;
     }
 
 private:
@@ -1655,7 +1658,7 @@ int main(int argc, char *argv[])
     #endif
     testQStringList();
     testStruct();
-    //testThreads();
+    testQThread();
     testQVariant1();
     testQVariant2();
     testQVariant3();