diff --git a/src/plugins/debugger/breakhandler.cpp b/src/plugins/debugger/breakhandler.cpp
index 4e89fbf40bd30faec7be086529202c088f2959e3..6e91f1c3966e421f105a6b7c191ea9c794e38e17 100644
--- a/src/plugins/debugger/breakhandler.cpp
+++ b/src/plugins/debugger/breakhandler.cpp
@@ -57,14 +57,11 @@ BreakHandler::BreakHandler()
     m_emptyIcon(_(":/debugger/images/breakpoint_pending_16.png")),
     //m_emptyIcon(_(":/debugger/images/debugger_empty_14.png")),
     m_watchpointIcon(_(":/debugger/images/watchpoint.png")),
-    m_lastFound(0),
-    m_lastFoundQueried(false)
+    m_syncTimerId(-1)
 {}
 
 BreakHandler::~BreakHandler()
-{
-    clear();
-}
+{}
 
 int BreakHandler::columnCount(const QModelIndex &parent) const
 {
@@ -73,74 +70,149 @@ int BreakHandler::columnCount(const QModelIndex &parent) const
 
 int BreakHandler::rowCount(const QModelIndex &parent) const
 {
-    return parent.isValid() ? 0 : size();
+    return parent.isValid() ? 0 : m_bp.size();
 }
 
+// FIXME: Only used by cdb. Move there?
 bool BreakHandler::hasPendingBreakpoints() const
 {
-    for (int i = size() - 1; i >= 0; i--)
-        if (at(i)->pending)
+    ConstIterator it = m_bp.constBegin(), et = m_bp.constEnd();
+    for ( ; it != et; ++it)
+        if (it.value()->isPending())
             return true;
     return false;
 }
 
-BreakpointData *BreakHandler::at(int index) const
+static inline bool fileNameMatch(const QString &f1, const QString &f2)
 {
-    QTC_ASSERT(index < size(), return 0);
-    return m_bp.at(index);
+#ifdef Q_OS_WIN
+    return f1.compare(f2, Qt::CaseInsensitive) == 0;
+#else
+    return f1 == f2;
+#endif
 }
 
-void BreakHandler::removeAt(int index)
+static bool isSimilarTo(const BreakpointData *data, const BreakpointResponse &needle)
 {
-    BreakpointData *data = at(index);
-    QTC_ASSERT(data, return);
-    m_bp.removeAt(index);
-    delete m_markers.take(data->id);
-    delete data;
-}
+    // Clear hit.
+    // Clear miss.
+    if (needle.bpType != UnknownType && data->type() != UnknownType
+            && data->type() != needle.bpType)
+        return false;
 
-void BreakHandler::clear()
-{
-    m_enabled.clear();
-    m_disabled.clear();
-    m_removed.clear();
+    // Clear hit.
+    if (data->address() && data->address() == needle.bpAddress)
+        return true;
+
+    // At least at a position we were looking for.
+    // FIXME: breaks multiple breakpoints at the same location
+    if (!data->fileName().isEmpty()
+            && fileNameMatch(data->fileName(), needle.bpFileName)
+            && data->lineNumber() == needle.bpLineNumber)
+        return true;
+
+    // At least at a position we were looking for.
+    // FIXME: breaks multiple breakpoints at the same location
+    if (!data->fileName().isEmpty()
+            && fileNameMatch(data->fileName(), needle.bpFileName)
+            && data->lineNumber() == needle.bpLineNumber)
+        return true;
+
+    return false;
 }
 
-BreakpointData *BreakHandler::findSimilarBreakpoint(const BreakpointData *needle) const
+BreakpointId BreakHandler::findSimilarBreakpoint(const BreakpointResponse &needle) const
 {
     // Search a breakpoint we might refer to.
-    for (int index = 0; index != size(); ++index) {
-        BreakpointData *data = m_bp[index];
-        if (data->isSimilarTo(needle))
-            return data;
+    ConstIterator it = m_bp.constBegin(), et = m_bp.constEnd();
+    for ( ; it != et; ++it) {
+        const BreakpointId id = it.key();
+        const BreakpointData *data = it.value();
+        QTC_ASSERT(data, continue);
+        const BreakpointResponse *response = m_responses.value(id);
+        QTC_ASSERT(response, continue);
+
+        qDebug() << "COMPARING " << data->toString() << " WITH " << needle.toString();
+        if (response->bpNumber && response->bpNumber == needle.bpNumber)
+            return id;
+
+        if (isSimilarTo(data, needle))
+            return id;
     }
-    return 0;
+    return BreakpointId(-1);
 }
 
-BreakpointData *BreakHandler::findBreakpointByNumber(int bpNumber) const
+BreakpointId BreakHandler::findBreakpointByNumber(int bpNumber) const
 {
-    if (!size())
-        return 0;
-    QString numStr = QString::number(bpNumber);
-    for (int index = 0; index != size(); ++index)
-        if (at(index)->bpNumber == numStr)
-            return at(index);
-    return 0;
+    Responses::ConstIterator it = m_responses.constBegin();
+    Responses::ConstIterator et = m_responses.constEnd();
+    for ( ; it != et; ++it)
+        if (it.value()->bpNumber == bpNumber)
+            return it.key();
+    return BreakpointId(-1);
 }
 
-int BreakHandler::findWatchPointIndexByAddress(quint64 address) const
+BreakpointId BreakHandler::findBreakpointByFunction(const QString &functionName) const
 {
-    for (int index = size() - 1; index >= 0; --index) {
-        BreakpointData *bd = at(index);
-        if (bd->isWatchpoint() && bd->address == address)
-            return index;
+    ConstIterator it = m_bp.constBegin(), et = m_bp.constEnd();
+    for ( ; it != et; ++it)
+        if (it.value()->functionName() == functionName)
+            return it.key();
+    return BreakpointId(-1);
+}
+
+BreakpointId BreakHandler::findBreakpointByAddress(quint64 address) const
+{
+    ConstIterator it = m_bp.constBegin(), et = m_bp.constEnd();
+    for ( ; it != et; ++it)
+        if (it.value()->address() == address)
+            return it.key();
+    return BreakpointId(-1);
+}
+
+BreakpointId BreakHandler::findBreakpointByFileAndLine(const QString &fileName,
+    int lineNumber, bool useMarkerPosition)
+{
+    ConstIterator it = m_bp.constBegin(), et = m_bp.constEnd();
+    for ( ; it != et; ++it)
+        if (it.value()->isLocatedAt(fileName, lineNumber, useMarkerPosition))
+            return it.key();
+    return BreakpointId(-1);
+}
+
+BreakpointData *BreakHandler::breakpointById(BreakpointId id) const
+{
+    return m_bp.value(id, 0);
+}
+
+BreakpointId BreakHandler::findWatchpointByAddress(quint64 address) const
+{
+    ConstIterator it = m_bp.constBegin(), et = m_bp.constEnd();
+    for ( ; it != et; ++it)
+        if (it.value()->isWatchpoint() && it.value()->address() == address)
+            return it.key();
+    return BreakpointId(-1);
+}
+
+
+void BreakHandler::setWatchpointByAddress(quint64 address)
+{
+    const int id = findWatchpointByAddress(address);
+    if (id == -1) {
+        BreakpointData *data = new BreakpointData;
+        data->setType(Watchpoint);
+        data->setAddress(address);
+        appendBreakpoint(data);
+        scheduleSynchronization();
+    } else {
+        qDebug() << "WATCHPOINT EXISTS";
+     //   removeBreakpoint(index);
     }
-    return -1;
 }
 
-bool BreakHandler::watchPointAt(quint64 address) const
+bool BreakHandler::hasWatchpointAt(quint64 address) const
 {
-    return findWatchPointIndexByAddress(address) != -1;
+    return findWatchpointByAddress(address) != BreakpointId(-1);
 }
 
 void BreakHandler::saveBreakpoints()
@@ -148,31 +220,32 @@ void BreakHandler::saveBreakpoints()
     //qDebug() << "SAVING BREAKPOINTS...";
     QTC_ASSERT(debuggerCore(), return);
     QList<QVariant> list;
-    for (int index = 0; index != size(); ++index) {
-        const BreakpointData *data = at(index);
+    ConstIterator it = m_bp.constBegin(), et = m_bp.constEnd();
+    for ( ; it != et; ++it) {
+        const BreakpointData *data = it.value();
         QMap<QString, QVariant> map;
         // Do not persist Watchpoints.
         //if (data->isWatchpoint())
         //    continue;
-        if (data->type != BreakpointByFileAndLine)
-            map.insert(_("type"), data->type);
-        if (!data->fileName.isEmpty())
-            map.insert(_("filename"), data->fileName);
-        if (data->lineNumber)
-            map.insert(_("linenumber"), QVariant(data->lineNumber));
-        if (!data->funcName.isEmpty())
-            map.insert(_("funcname"), data->funcName);
-        if (data->address)
-            map.insert(_("address"), data->address);
-        if (!data->condition.isEmpty())
-            map.insert(_("condition"), data->condition);
-        if (data->ignoreCount)
-            map.insert(_("ignorecount"), QVariant(data->ignoreCount));
-        if (!data->threadSpec.isEmpty())
-            map.insert(_("threadspec"), data->threadSpec);
-        if (!data->enabled)
+        if (data->type() != BreakpointByFileAndLine)
+            map.insert(_("type"), data->type());
+        if (!data->fileName().isEmpty())
+            map.insert(_("filename"), data->fileName());
+        if (data->lineNumber())
+            map.insert(_("linenumber"), data->lineNumber());
+        if (!data->functionName().isEmpty())
+            map.insert(_("funcname"), data->functionName());
+        if (data->address())
+            map.insert(_("address"), data->address());
+        if (!data->condition().isEmpty())
+            map.insert(_("condition"), data->condition());
+        if (data->ignoreCount())
+            map.insert(_("ignorecount"), data->ignoreCount());
+        if (!data->threadSpec().isEmpty())
+            map.insert(_("threadspec"), data->threadSpec());
+        if (!data->isEnabled())
             map.insert(_("disabled"), _("1"));
-        if (data->useFullPath)
+        if (data->useFullPath())
             map.insert(_("usefullpath"), _("1"));
         list.append(map);
     }
@@ -186,75 +259,76 @@ void BreakHandler::loadBreakpoints()
     //qDebug() << "LOADING BREAKPOINTS...";
     QVariant value = debuggerCore()->sessionValue("Breakpoints");
     QList<QVariant> list = value.toList();
-    clear();
+    //clear();
     foreach (const QVariant &var, list) {
         const QMap<QString, QVariant> map = var.toMap();
         BreakpointData *data = new BreakpointData;
         QVariant v = map.value(_("filename"));
         if (v.isValid())
-            data->fileName = v.toString();
+            data->setFileName(v.toString());
         v = map.value(_("linenumber"));
         if (v.isValid())
-            data->lineNumber = v.toString().toInt();
+            data->setLineNumber(v.toString().toInt());
         v = map.value(_("condition"));
         if (v.isValid())
-            data->condition = v.toString().toLatin1();
+            data->setCondition(v.toString().toLatin1());
         v = map.value(_("address"));
         if (v.isValid())
-            data->address = v.toString().toULongLong();
+            data->setAddress(v.toString().toULongLong());
         v = map.value(_("ignorecount"));
         if (v.isValid())
-            data->ignoreCount = v.toString().toInt();
+            data->setIgnoreCount(v.toString().toInt());
         v = map.value(_("threadspec"));
         if (v.isValid())
-            data->threadSpec = v.toString().toLatin1();
+            data->setThreadSpec(v.toString().toLatin1());
         v = map.value(_("funcname"));
         if (v.isValid())
-            data->funcName = v.toString();
+            data->setFunctionName(v.toString());
         v = map.value(_("disabled"));
         if (v.isValid())
-            data->enabled = !v.toInt();
+            data->setEnabled(!v.toInt());
         v = map.value(_("usefullpath"));
         if (v.isValid())
-            data->useFullPath = bool(v.toInt());
+            data->setUseFullPath(bool(v.toInt()));
         v = map.value(_("type"));
         if (v.isValid())
-            data->type = BreakpointType(v.toInt());
-        data->setMarkerFileName(data->fileName);
-        data->setMarkerLineNumber(data->lineNumber);
-        append(data);
+            data->setType(BreakpointType(v.toInt()));
+        data->setMarkerFileName(data->fileName());
+        data->setMarkerLineNumber(data->lineNumber());
+        appendBreakpoint(data);
     }
     //qDebug() << "LOADED BREAKPOINTS" << this << list.size();
 }
 
 void BreakHandler::updateMarkers()
 {
-    for (int index = 0; index != size(); ++index)
-        updateMarker(at(index));
-    emit layoutChanged();
+    ConstIterator it = m_bp.constBegin(), et = m_bp.constEnd();
+    for ( ; it != et; ++it)
+        updateMarker(it.key());
 }
 
-void BreakHandler::updateMarker(BreakpointData * bp)
+void BreakHandler::updateMarker(BreakpointId id)
 {
-    BreakpointMarker *marker = m_markers.value(bp->id);
+    BreakpointData *data = m_bp.value(id);
+    QTC_ASSERT(data, return);
 
-    if (marker && (bp->m_markerFileName != marker->fileName()
-                || bp->m_markerLineNumber != marker->lineNumber())) {
-        removeMarker(bp);
+    BreakpointMarker *marker = m_markers.value(id);
+
+    if (marker && (data->m_markerFileName != marker->fileName()
+                || data->m_markerLineNumber != marker->lineNumber())) {
+        removeMarker(id);
         marker = 0;
     }
 
-    if (!marker && !bp->m_markerFileName.isEmpty() && bp->m_markerLineNumber > 0) {
-        marker = new BreakpointMarker(this, bp, bp->m_markerFileName, bp->m_markerLineNumber);
-        m_markers.insert(bp->id, marker);
+    if (!marker && !data->m_markerFileName.isEmpty() && data->m_markerLineNumber > 0) {
+        marker = new BreakpointMarker(id, data->m_markerFileName, data->m_markerLineNumber);
+        m_markers.insert(id, marker);
     }
-
-    if (marker)
-        marker->setPending(bp->pending);
 }
-void BreakHandler::removeMarker(BreakpointData * bp)
+
+void BreakHandler::removeMarker(BreakpointId id)
 {
-    delete m_markers.take(bp->id);
+    delete m_markers.take(id);
 }
 
 QVariant BreakHandler::headerData(int section,
@@ -270,45 +344,57 @@ QVariant BreakHandler::headerData(int section,
     return QVariant();
 }
 
+BreakpointId BreakHandler::findBreakpointByIndex(const QModelIndex &index) const
+{
+    int r = index.row();
+    ConstIterator it = m_bp.constBegin(), et = m_bp.constEnd();
+    for (int i = 0; it != et; ++it, ++i)
+        if (i == r)
+            return it.key();
+    return BreakpointId(-1);
+}
+
 QVariant BreakHandler::data(const QModelIndex &mi, int role) const
 {
     static const QString empty = QString(QLatin1Char('-'));
 
     QTC_ASSERT(mi.isValid(), return QVariant());
-    if (mi.row() >= size())
-        return QVariant();
-
-    BreakpointData *data = at(mi.row());
+    BreakpointId id = findBreakpointByIndex(mi);
+    BreakpointData *data = m_bp.value(id);
+    QTC_ASSERT(data, return QVariant());
+    BreakpointResponse *response = m_responses.value(id, 0);
+    QTC_ASSERT(response, return QVariant());
 
     switch (mi.column()) {
         case 0:
             if (role == Qt::DisplayRole) {
-                const QString str = data->bpNumber;
-                return str.isEmpty() ? empty : str;
+                return QString("%1 - %2").arg(id).arg(response->bpNumber);
             }
             if (role == Qt::DecorationRole) {
                 if (data->isWatchpoint())
                     return m_watchpointIcon;
-                if (!data->enabled)
+                if (!data->isEnabled())
                     return m_disabledBreakpointIcon;
-                return data->pending ? m_pendingBreakPointIcon : m_breakpointIcon;
+                return data->isPending() ? m_pendingBreakPointIcon : m_breakpointIcon;
             }
             break;
         case 1:
             if (role == Qt::DisplayRole) {
-                const QString str = data->pending ? data->funcName : data->bpFuncName;
+                const QString str = data->isPending()
+                    ? data->functionName() : response->bpFuncName;
                 return str.isEmpty() ? empty : str;
             }
             break;
         case 2:
             if (role == Qt::DisplayRole) {
-                QString str = data->pending ? data->fileName : data->bpFileName;
+                QString str = data->isPending()
+                    ? data->fileName() : response->bpFileName;
                 str = QFileInfo(str).fileName();
                 // FIXME: better?
                 //if (data->bpMultiple && str.isEmpty() && !data->markerFileName.isEmpty())
                 //    str = data->markerFileName;
                 str = str.isEmpty() ? empty : str;
-                if (data->useFullPath)
+                if (data->useFullPath())
                     str = QDir::toNativeSeparators(QLatin1String("/.../") + str);
                 return str;
             }
@@ -318,277 +404,426 @@ QVariant BreakHandler::data(const QModelIndex &mi, int role) const
                 // FIXME: better?
                 //if (data->bpMultiple && str.isEmpty() && !data->markerFileName.isEmpty())
                 //    str = data->markerLineNumber;
-                const int nr = data->pending ? data->lineNumber : data->bpLineNumber;
+                const int nr = data->isPending()
+                    ? data->lineNumber() : response->bpLineNumber;
                 return nr ? QString::number(nr) : empty;
             }
             if (role == Qt::UserRole + 1)
-                return data->lineNumber;
+                return data->lineNumber();
             break;
         case 4:
             if (role == Qt::DisplayRole)
-                return data->pending ? data->condition : data->bpCondition;
+                return data->isPending() ? data->condition() : response->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;
+                return data->condition();
             break;
         case 5:
             if (role == Qt::DisplayRole) {
-                const int ignoreCount = data->pending ? data->ignoreCount : data->bpIgnoreCount;
+                const int ignoreCount =
+                    data->isPending() ? data->ignoreCount() : response->bpIgnoreCount;
                 return ignoreCount ? QVariant(ignoreCount) : QVariant(QString());
             }
             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;
+                return data->ignoreCount();
             break;
         case 6:
             if (role == Qt::DisplayRole) {
-                if (data->pending)
-                    return !data->threadSpec.isEmpty() ? data->threadSpec : tr("(all)");
+                if (data->isPending())
+                    return !data->threadSpec().isEmpty() ? data->threadSpec() : tr("(all)");
                 else
-                    return !data->bpThreadSpec.isEmpty() ? data->bpThreadSpec : tr("(all)");
+                    return !response->bpThreadSpec.isEmpty() ? response->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;
+                return data->threadSpec();
             break;
         case 7:
             if (role == Qt::DisplayRole) {
                 QString displayValue;
-                const quint64 effectiveAddress
-                    = data->isWatchpoint() ? data->address : data->bpAddress;
-                if (effectiveAddress)
-                    displayValue += QString::fromAscii("0x%1").arg(effectiveAddress, 0, 16);
-                if (!data->bpState.isEmpty()) {
+                const quint64 address =
+                    data->isWatchpoint() ? data->address() : response->bpAddress;
+                if (address)
+                    displayValue += QString::fromAscii("0x%1").arg(address, 0, 16);
+                if (!response->bpState.isEmpty()) {
                     if (!displayValue.isEmpty())
                         displayValue += QLatin1Char(' ');
-                    displayValue += QString::fromAscii(data->bpState);
+                    displayValue += QString::fromAscii(response->bpState);
                 }
                 return displayValue;
             }
             break;
     }
     if (role == Qt::ToolTipRole)
-        return theDebuggerBoolSetting(UseToolTipsInBreakpointsView)
+        return debuggerCore()->boolSetting(UseToolTipsInBreakpointsView)
                 ? data->toToolTip() : QVariant();
+
     return QVariant();
 }
 
-Qt::ItemFlags BreakHandler::flags(const QModelIndex &index) const
-{
-//    switch (index.column()) {
-//        //case 0:
-//        //    return Qt::ItemIsUserCheckable | Qt::ItemIsEnabled;
-//        default:
-            return QAbstractTableModel::flags(index);
-//    }
+#define GETTER(type, getter) \
+type BreakHandler::getter(BreakpointId id) const \
+{ \
+    BreakpointData *data = m_bp.value(id); \
+    QTC_ASSERT(data, return type()); \
+    return data->getter(); \
 }
 
-void BreakHandler::reinsertBreakpoint(BreakpointData *data)
-{
-    // FIXME: Use some more direct method?
-    appendBreakpoint(data->clone());
-    removeBreakpoint(data);
-    synchronizeBreakpoints();
-    emit layoutChanged();
+#define SETTER(type, setter) \
+void BreakHandler::setter(BreakpointId id, const type &value) \
+{ \
+    BreakpointData *data = m_bp.value(id); \
+    QTC_ASSERT(data, return); \
+    if (data->setter(value)) \
+        scheduleSynchronization(); \
 }
 
-void BreakHandler::append(BreakpointData *data)
-{
-    m_bp.append(data);
-}
+#define PROPERTY(type, getter, setter) \
+    GETTER(type, getter) \
+    SETTER(type, setter)
 
-Breakpoints BreakHandler::takeRemovedBreakpoints()
-{
-    foreach(BreakpointData *bp, m_removed) {
-        removeMarker(bp);
-    }
-    Breakpoints result = m_removed;
-    m_removed.clear();
-    return result;
-}
 
-Breakpoints BreakHandler::takeEnabledBreakpoints()
+PROPERTY(bool, useFullPath, setUseFullPath)
+PROPERTY(QString, markerFileName, setMarkerFileName)
+PROPERTY(QString, fileName, setFileName)
+PROPERTY(QString, functionName, setFunctionName)
+PROPERTY(int, markerLineNumber, setMarkerLineNumber)
+PROPERTY(bool, isEnabled, setEnabled)
+PROPERTY(BreakpointType, type, setType)
+PROPERTY(BreakpointState, state, setState)
+PROPERTY(QByteArray, threadSpec, setThreadSpec)
+PROPERTY(QByteArray, condition, setCondition)
+PROPERTY(int, lineNumber, setLineNumber)
+PROPERTY(quint64, address, setAddress)
+
+DebuggerEngine *BreakHandler::engine(BreakpointId id) const
 {
-    Breakpoints result = m_enabled;
-    m_enabled.clear();
-    return result;
+    BreakpointData *data = m_bp.value(id);
+    QTC_ASSERT(data, return 0);
+    return data->engine();
 }
 
-Breakpoints BreakHandler::takeDisabledBreakpoints()
+void BreakHandler::setEngine(BreakpointId id, DebuggerEngine *value)
 {
-    Breakpoints result = m_disabled;
-    m_disabled.clear();
-    return result;
+    BreakpointData *data = m_bp.value(id);
+    QTC_ASSERT(data, return);
+    QTC_ASSERT(data->state() == BreakpointNew, /**/);
+    QTC_ASSERT(!data->engine(), return);
+    data->setEngine(value);
+    data->setState(BreakpointInsertRequested);
+    updateMarker(id);
+    scheduleSynchronization();
 }
 
-void BreakHandler::removeBreakpointHelper(int index)
+void BreakHandler::ackCondition(BreakpointId id)
 {
-    BreakpointData *data = at(index);
+    BreakpointData *data = m_bp.value(id);
+    BreakpointResponse *response = m_responses[id];
     QTC_ASSERT(data, return);
-    m_bp.removeAt(index);
-    removeMarker(data);
-    m_removed.append(data);
+    QTC_ASSERT(response, return);
+    response->bpCondition = data->condition();
+    updateMarker(id);
 }
 
-void BreakHandler::removeBreakpoint(int index)
+void BreakHandler::ackIgnoreCount(BreakpointId id)
 {
-    if (index < 0 || index >= size())
-        return;
-    removeBreakpointHelper(index);
-    emit layoutChanged();
+    BreakpointData *data = m_bp.value(id);
+    BreakpointResponse *response = m_responses[id];
+    QTC_ASSERT(data, return);
+    QTC_ASSERT(response, return);
+    response->bpIgnoreCount = data->ignoreCount();
+    updateMarker(id);
 }
 
-void BreakHandler::removeBreakpoint(BreakpointData *data)
+Qt::ItemFlags BreakHandler::flags(const QModelIndex &index) const
 {
-    removeBreakpointHelper(indexOf(data));
-    emit layoutChanged();
+//    switch (index.column()) {
+//        //case 0:
+//        //    return Qt::ItemIsUserCheckable | Qt::ItemIsEnabled;
+//        default:
+            return QAbstractTableModel::flags(index);
+//    }
 }
 
-void BreakHandler::toggleBreakpointEnabled(BreakpointData *data)
+void BreakHandler::removeBreakpoint(BreakpointId id)
 {
-    QTC_ASSERT(data, return);
-    data->enabled = !data->enabled;
-    if (data->enabled) {
-        m_enabled.append(data);
-        m_disabled.removeAll(data);
+    BreakpointData *data = m_bp.value(id);
+    if (data->state() == BreakpointInserted) {
+        qDebug() << "MARK AS CHANGED: " << id;
+        data->m_state = BreakpointRemoveRequested;
+        QTC_ASSERT(data->engine(), return);
+        debuggerCore()->synchronizeBreakpoints();
+    } else if (data->state() == BreakpointNew) {
+        data->m_state = BreakpointDead;
+        cleanupBreakpoint(id);
     } else {
-        m_enabled.removeAll(data);
-        m_disabled.append(data);
+        qDebug() << "CANNOT REMOVE IN STATE " << data->state();
     }
-    removeMarker(data); // Force icon update.
-    updateMarker(data);
-    emit layoutChanged();
-    synchronizeBreakpoints();
-}
-
-void BreakHandler::toggleBreakpointEnabled(const QString &fileName, int lineNumber)
-{
-    BreakpointData *data = findBreakpoint(fileName, lineNumber);
-    toggleBreakpointEnabled(data);
 }
 
 void BreakHandler::appendBreakpoint(BreakpointData *data)
 {
-    append(data);
-    emit layoutChanged();
-    saveBreakpoints();  // FIXME: remove?
-    updateMarkers();
-}
-
-void BreakHandler::removeAllBreakpoints()
-{
-    for (int index = size(); --index >= 0;)
-        removeBreakpointHelper(index);
-    emit layoutChanged();
-    updateMarkers();
-}
+    // Ok to be not thread-safe. The order does not matter and only the gui
+    // produces authoritative ids.
+    static quint64 currentId = 0;
 
-BreakpointData *BreakHandler::findBreakpoint(quint64 address) const
-{
-    foreach (BreakpointData *data, m_bp)
-        if (data->address == address)
-            return data;
-    return 0;
-}
-
-BreakpointData *BreakHandler::findBreakpoint(const QString &fileName,
-    int lineNumber, bool useMarkerPosition)
-{
-    foreach (BreakpointData *data, m_bp)
-        if (data->isLocatedAt(fileName, lineNumber, useMarkerPosition))
-            return data;
-    return 0;
+    BreakpointId id(++currentId);
+    m_bp.insert(id, data);
+    m_responses.insert(id, new BreakpointResponse);
+    scheduleSynchronization();
 }
 
 void BreakHandler::toggleBreakpoint(const QString &fileName, int lineNumber,
                                     quint64 address /* = 0 */)
 {
-    BreakpointData *data = 0;
+    BreakpointId id(-1);
 
     if (address) {
-        data = findBreakpoint(address);
+        id = findBreakpointByAddress(address);
     } else {
-        data = findBreakpoint(fileName, lineNumber, true);
-        if (!data)
-            data = findBreakpoint(fileName, lineNumber, false);
+        id = findBreakpointByFileAndLine(fileName, lineNumber, true);
+        if (id == BreakpointId(-1))
+            id = findBreakpointByFileAndLine(fileName, lineNumber, false);
     }
 
-    if (data) {
-        removeBreakpoint(data);
+    if (id != BreakpointId(-1)) {
+        removeBreakpoint(id);
     } else {
-        data = new BreakpointData;
+        BreakpointData *data = new BreakpointData;
         if (address) {
-            data->address = address;
+            data->setAddress(address);
         } else {
-            data->fileName = fileName;
-            data->lineNumber = lineNumber;
+            data->setFileName(fileName);
+            data->setLineNumber(lineNumber);
         }
-        data->pending = true;
         data->setMarkerFileName(fileName);
         data->setMarkerLineNumber(lineNumber);
         appendBreakpoint(data);
     }
-    synchronizeBreakpoints();
+    debuggerCore()->synchronizeBreakpoints();
 }
 
 void BreakHandler::saveSessionData()
 {
-    // FIXME QTC_ASSERT(m_engine->isSessionEngine(), return);
     saveBreakpoints();
 }
 
 void BreakHandler::loadSessionData()
 {
-    // FIXME QTC_ASSERT(m_engine->isSessionEngine(), return);
-    foreach (BreakpointData *bp, m_bp) {
-        delete m_markers.take(bp->id);
-    }
+    qDeleteAll(m_responses);
+    m_responses.clear();
     qDeleteAll(m_bp);
     m_bp.clear();
+    qDeleteAll(m_markers);
+    m_markers.clear();
     loadBreakpoints();
-    updateMarkers();
 }
 
 void BreakHandler::breakByFunction(const QString &functionName)
 {
     // One breakpoint per function is enough for now. This does not handle
     // combinations of multiple conditions and ignore counts, though.
-    for (int index = size(); --index >= 0;) {
-        const BreakpointData *data = at(index);
+    ConstIterator it = m_bp.constBegin(), et = m_bp.constEnd();
+    for ( ; it != et; ++it) {
+        const BreakpointData *data = it.value();
         QTC_ASSERT(data, break);
-        if (data->funcName == functionName && data->condition.isEmpty()
-                && data->ignoreCount == 0)
+        if (data->functionName() == functionName
+                && data->condition().isEmpty()
+                && data->ignoreCount() == 0)
             return;
     }
     BreakpointData *data = new BreakpointData;
-    data->funcName = functionName;
-    append(data);
-    //saveBreakpoints();
+    data->setType(BreakpointByFunction);
+    data->setFunctionName(functionName);
+    appendBreakpoint(data);
+}
+
+QIcon BreakHandler::icon(BreakpointId id) const
+{
+    //if (!m_handler->isActive())
+    //    return m_handler->emptyIcon();
+    const BreakpointData *data = m_bp.value(id);
+    QTC_ASSERT(data, return pendingBreakPointIcon());
+    //if (!isActive())
+    //    return emptyIcon();
+    switch (data->state()) {
+    case BreakpointInserted:
+        return breakpointIcon();
+    default:
+        return pendingBreakPointIcon();
+    }
+}
+
+void BreakHandler::scheduleSynchronization()
+{
+    if (m_syncTimerId == -1)
+        m_syncTimerId = startTimer(10);
+}
+
+void BreakHandler::timerEvent(QTimerEvent *event)
+{
+    QTC_ASSERT(event->timerId() == m_syncTimerId, return);
+    killTimer(m_syncTimerId);
+    m_syncTimerId = -1;
+    //qDebug() << "BREAKPOINT SYNCRONIZATION STARTED";
+    debuggerCore()->synchronizeBreakpoints();
     updateMarkers();
+    emit layoutChanged();
+    saveBreakpoints();  // FIXME: remove?
+}
+
+void BreakHandler::gotoLocation(BreakpointId id) const
+{
+    BreakpointData *data = m_bp.value(id);
+    QTC_ASSERT(data, return);
+    debuggerCore()->gotoLocation(
+        data->fileName(), data->lineNumber(), false);
+}
+
+void BreakHandler::updateLineNumberFromMarker(BreakpointId id, int lineNumber)
+{
+    BreakpointData *data = m_bp.value(id);
+    QTC_ASSERT(data, return);
+    //if (data->markerLineNumber == lineNumber)
+    //    return;
+    if (data->markerLineNumber() != lineNumber) {
+        data->setMarkerLineNumber(lineNumber);
+        // FIXME: Should we tell gdb about the change?
+        // Ignore it for now, as we would require re-compilation
+        // and debugger re-start anyway.
+        //if (0 && data->bpLineNumber) {
+        //    if (!data->bpNumber.trimmed().isEmpty()) {
+        //        data->pending = true;
+        //    }
+        //}
+    }
+    // Ignore updates to the "real" line number while the debugger is
+    // running, as this can be triggered by moving the breakpoint to
+    // the next line that generated code.
+    // FIXME: Do we need yet another data member?
+    BreakpointResponse *response = m_responses[id];
+    QTC_ASSERT(response, return);
+    if (response->bpNumber == 0) {
+        data->setLineNumber(lineNumber);
+        updateMarker(id);
+    }
+}
+
+BreakpointIds BreakHandler::allBreakpointIds() const
+{
+    BreakpointIds ids;
+    ConstIterator it = m_bp.constBegin(), et = m_bp.constEnd();
+    for ( ; it != et; ++it)
+        ids.append(it.key());
+    return ids;
+}
+
+BreakpointIds BreakHandler::unclaimedBreakpointIds() const
+{
+    return engineBreakpointIds(0);
+}
+
+BreakpointIds BreakHandler::engineBreakpointIds(DebuggerEngine *engine) const
+{
+    BreakpointIds ids;
+    ConstIterator it = m_bp.constBegin(), et = m_bp.constEnd();
+    for ( ; it != et; ++it)
+        if (it.value()->engine() == engine)
+            ids.append(it.key());
+    return ids;
+}
+
+void BreakHandler::notifyBreakpointInsertOk(BreakpointId id)
+{
+    QTC_ASSERT(breakHandler()->state(id)== BreakpointInsertProceeding, /**/);
+    breakHandler()->setState(id, BreakpointInserted);
 }
 
-bool BreakHandler::isActive() const
+void BreakHandler::notifyBreakpointInsertFailed(BreakpointId id)
 {
-    return true; // FIXME m_engine->isActive();
+    QTC_ASSERT(breakHandler()->state(id)== BreakpointInsertProceeding, /**/);
+    breakHandler()->setState(id, BreakpointDead);
 }
 
-int BreakHandler::size() const
+void BreakHandler::notifyBreakpointRemoveOk(BreakpointId id)
 {
-    return m_bp.size();
+    QTC_ASSERT(state(id) == BreakpointRemoveProceeding, /**/);
+    setState(id, BreakpointDead);
+    cleanupBreakpoint(id);
 }
 
-int BreakHandler::indexOf(BreakpointData *data)
+void BreakHandler::notifyBreakpointRemoveFailed(BreakpointId id)
 {
-    return m_bp.indexOf(data);
+    QTC_ASSERT(state(id) == BreakpointRemoveProceeding, /**/);
+    setState(id, BreakpointDead);
+    cleanupBreakpoint(id);
 }
 
-void BreakHandler::synchronizeBreakpoints()
+void BreakHandler::notifyBreakpointChangeOk(BreakpointId id)
+{
+    QTC_ASSERT(state(id) == BreakpointChangeProceeding, /**/);
+    setState(id, BreakpointInserted);
+}
+
+void BreakHandler::notifyBreakpointChangeFailed(BreakpointId id)
+{
+    QTC_ASSERT(state(id) == BreakpointChangeProceeding, /**/);
+    setState(id, BreakpointDead);
+}
+
+void BreakHandler::notifyBreakpointReleased(BreakpointId id)
+{
+    //QTC_ASSERT(state(id) == BreakpointChangeProceeding, /**/);
+    setState(id, BreakpointNew);
+    m_bp.value(id)->setEngine(0);
+    delete m_markers.take(id);
+    *m_responses[id] = BreakpointResponse();
+    updateMarker(id);
+}
+
+void BreakHandler::cleanupBreakpoint(BreakpointId id)
+{
+    QTC_ASSERT(state(id) == BreakpointDead, /**/);
+    delete m_markers.take(id);
+    delete m_bp.take(id);
+    delete m_responses.take(id);
+}
+
+BreakpointResponse BreakHandler::response(BreakpointId id) const
+{
+    BreakpointResponse *response = m_responses[id];
+    return response ? *response : BreakpointResponse();
+}
+
+void BreakHandler::setResponse(BreakpointId id, const BreakpointResponse &data)
+{
+    delete m_responses.take(id);
+    m_responses[id] = new BreakpointResponse(data);
+    updateMarker(id);
+}
+#if 0
+void BreakHandler::notifyBreakpointAdjusted(BreakpointId id)
 {
-    emit breakpointSynchronizationRequested();
+    QTC_ASSERT(state(id)== BreakpointChangeProceeding, /**/);
+    bp->bpNumber      = rbp.bpNumber;
+    bp->bpCondition   = rbp.bpCondition;
+    bp->bpIgnoreCount = rbp.bpIgnoreCount;
+    bp->bpFileName    = rbp.bpFileName;
+    bp->bpFullName    = rbp.bpFullName;
+    bp->bpLineNumber  = rbp.bpLineNumber;
+    bp->bpCorrectedLineNumber = rbp.bpCorrectedLineNumber;
+    bp->bpThreadSpec  = rbp.bpThreadSpec;
+    bp->bpFuncName    = rbp.bpFuncName;
+    bp->bpAddress     = rbp.bpAddress;
+    bp->bpMultiple    = rbp.bpMultiple;
+    bp->bpEnabled     = rbp.bpEnabled;
+    setState(id, BreakpointOk);
 }
+#endif
 
 } // namespace Internal
 } // namespace Debugger
diff --git a/src/plugins/debugger/breakhandler.h b/src/plugins/debugger/breakhandler.h
index 0099c7c1d3eec6a34a89f14dd398286925b7da12..877b19a541f07e12fcbd6ea76035a1ad5405fc9a 100644
--- a/src/plugins/debugger/breakhandler.h
+++ b/src/plugins/debugger/breakhandler.h
@@ -37,18 +37,15 @@
 
 #include <QtGui/QIcon>
 
-namespace Debugger {
-
-class DebuggerEngine;
-
-namespace Internal {
-
 //////////////////////////////////////////////////////////////////
 //
 // BreakHandler
 //
 //////////////////////////////////////////////////////////////////
 
+namespace Debugger {
+namespace Internal {
+
 class BreakHandler : public QAbstractTableModel
 {
     Q_OBJECT
@@ -57,31 +54,28 @@ public:
     BreakHandler();
     ~BreakHandler();
 
-    void removeAllBreakpoints();
     void loadSessionData();
     void saveSessionData();
 
     QAbstractItemModel *model() { return this; }
 
-    BreakpointData *at(int index) const;
-    int size() const;
+    BreakpointIds allBreakpointIds() const;
+    BreakpointIds engineBreakpointIds(DebuggerEngine *engine) const;
+    BreakpointIds unclaimedBreakpointIds() const;
+    BreakpointData *breakpointById(BreakpointId id) const;
+    int size() const { return m_bp.size(); }
     bool hasPendingBreakpoints() const;
-    void removeAt(int index); // This also deletes the marker.
-    void clear(); // This also deletes all the marker.
-    int indexOf(BreakpointData *data);
+
     // Find a breakpoint matching approximately the data in needle.
-    BreakpointData *findSimilarBreakpoint(const BreakpointData *needle) const;
-    BreakpointData *findBreakpointByNumber(int bpNumber) const;
-    int findWatchPointIndexByAddress(quint64 address) const;
-    bool watchPointAt(quint64 address) const;
+    BreakpointId findSimilarBreakpoint(const BreakpointResponse &needle) const;
+    BreakpointId findBreakpointByNumber(int bpNumber) const;
+    BreakpointId findWatchpointByAddress(quint64 address) const;
+    BreakpointId findBreakpointByFunction(const QString &functionName) const;
+    BreakpointId findBreakpointByIndex(const QModelIndex &index) const;
+    void setWatchpointByAddress(quint64 address);
+    bool hasWatchpointAt(quint64 address) const;
     void updateMarkers();
-    void updateMarker(BreakpointData *);
-    void removeMarker(BreakpointData *);
-    bool isActive() const;
-
-    Breakpoints takeRemovedBreakpoints(); // Owned.
-    Breakpoints takeEnabledBreakpoints(); // Not owned.
-    Breakpoints takeDisabledBreakpoints(); // Not owned.
+    void removeMarker(BreakpointId id);
 
     QIcon breakpointIcon() const { return m_breakpointIcon; }
     QIcon disabledBreakpointIcon() const { return m_disabledBreakpointIcon; }
@@ -89,21 +83,60 @@ public:
     QIcon emptyIcon() const { return m_emptyIcon; }
 
     void toggleBreakpoint(const QString &fileName, int lineNumber, quint64 address = 0);
-    void toggleBreakpointEnabled(const QString &fileName, int lineNumber);
-    BreakpointData *findBreakpoint(const QString &fileName, int lineNumber,
-        bool useMarkerPosition = true);
-    BreakpointData *findBreakpoint(quint64 address) const;
+    BreakpointId findBreakpointByFileAndLine(const QString &fileName,
+        int lineNumber, bool useMarkerPosition = true);
+    BreakpointId findBreakpointByAddress(quint64 address) const;
 
-    void appendBreakpoint(BreakpointData *data);
-    void reinsertBreakpoint(BreakpointData *data);
-    void toggleBreakpointEnabled(BreakpointData *data);
     void breakByFunction(const QString &functionName);
-    void removeBreakpoint(int index);
-    void removeBreakpoint(BreakpointData *data);
-    void synchronizeBreakpoints();
-
-signals:
-    void breakpointSynchronizationRequested();
+    void removeBreakpoint(BreakpointId id);
+    QIcon icon(BreakpointId id) const;
+
+    void gotoLocation(BreakpointId id) const;
+
+    // Getter retrieves property value.
+    // Setter sets property value and triggers update if changed.
+    #define PROPERTY(type, getter, setter) \
+        type getter(BreakpointId id) const; \
+        void setter(BreakpointId id, const type &value);
+
+    PROPERTY(bool, useFullPath, setUseFullPath)
+    PROPERTY(QString, markerFileName, setMarkerFileName)
+    PROPERTY(int, markerLineNumber, setMarkerLineNumber)
+    PROPERTY(QByteArray, condition, setCondition)
+    PROPERTY(int, ignoreCount, setIgnoreCount)
+    PROPERTY(QByteArray, threadSpec, setThreadSpec)
+    PROPERTY(BreakpointState, state, setState)
+    PROPERTY(QString, fileName, setFileName)
+    PROPERTY(QString, functionName, setFunctionName)
+    PROPERTY(BreakpointType, type, setType);
+    PROPERTY(quint64, address, setAddress);
+    PROPERTY(int, lineNumber, setLineNumber);
+    #undef PROPERTY
+    bool isEnabled(BreakpointId id) const;
+    void setEnabled(BreakpointId id, const bool &on);
+    void updateEnabled(BreakpointId id, const bool &on);
+    void updateLineNumberFromMarker(BreakpointId id, int lineNumber);
+
+    DebuggerEngine *engine(BreakpointId id) const;
+    void setEngine(BreakpointId id, DebuggerEngine *engine);
+    BreakpointResponse response(BreakpointId id) const;
+    void setResponse(BreakpointId id, const BreakpointResponse &data);
+
+    // Incorporate debugger feedback. No synchronization request needed.
+    // Return true if something changed.
+    void ackCondition(BreakpointId id);
+    void ackIgnoreCount(BreakpointId id);
+
+    void notifyBreakpointInsertOk(BreakpointId id);
+    void notifyBreakpointInsertFailed(BreakpointId id);
+    void notifyBreakpointChangeOk(BreakpointId id);
+    void notifyBreakpointChangeFailed(BreakpointId id);
+    void notifyBreakpointRemoveOk(BreakpointId id);
+    void notifyBreakpointRemoveFailed(BreakpointId id);
+    void notifyBreakpointReleased(BreakpointId id);
+
+    // This takes ownership.
+    void appendBreakpoint(BreakpointData *data);
 
 private:
     friend class BreakpointMarker;
@@ -118,8 +151,8 @@ private:
     void markerUpdated(BreakpointMarker *marker, int lineNumber);
     void loadBreakpoints();
     void saveBreakpoints();
-    void removeBreakpointHelper(int index);
-    void append(BreakpointData *data);
+    void updateMarker(BreakpointId id);
+    void cleanupBreakpoint(BreakpointId id);
 
     const QIcon m_breakpointIcon;
     const QIcon m_disabledBreakpointIcon;
@@ -127,17 +160,17 @@ private:
     const QIcon m_emptyIcon;
     const QIcon m_watchpointIcon;
 
-    Breakpoints m_inserted; // Lately inserted breakpoints.
-    Breakpoints m_removed; // Lately removed breakpoints.
-    Breakpoints m_enabled; // Lately enabled breakpoints.
-    Breakpoints m_disabled; // Lately disabled breakpoints.
-
-    // Hack for BreakWindow::findSimilarBreakpoint
-    mutable BreakpointData *m_lastFound;
-    mutable bool m_lastFoundQueried;
-
+    typedef QMap<BreakpointId, BreakpointData *> Breakpoints;
+    typedef QMap<BreakpointId, BreakpointMarker *> Markers;
+    typedef QMap<BreakpointId, BreakpointResponse *> Responses;
+    typedef Breakpoints::ConstIterator ConstIterator;
     Breakpoints m_bp;
-    QHash<quint64, BreakpointMarker *> m_markers;
+    Markers m_markers;
+    Responses m_responses;
+
+    void scheduleSynchronization();
+    void timerEvent(QTimerEvent *event);
+    int m_syncTimerId;
 };
 
 } // namespace Internal
diff --git a/src/plugins/debugger/breakpoint.cpp b/src/plugins/debugger/breakpoint.cpp
index 269e37d7c0ad21d9885dd49e2633ae7e80f2924e..8ee94e6604d6b81d7f34cdf4c308c445924f72a1 100644
--- a/src/plugins/debugger/breakpoint.cpp
+++ b/src/plugins/debugger/breakpoint.cpp
@@ -50,88 +50,86 @@ namespace Internal {
 const char *BreakpointData::throwFunction = "throw";
 const char *BreakpointData::catchFunction = "catch";
 
-static quint64 nextBPId() {
-    /* ok to be not thread-safe
-       the order does not matter and only the gui
-       produces authoritative ids. well, for now...
-    */
-    static quint64 i=1;
-    return ++i;
-}
-
-BreakpointData::BreakpointData() :
-    id(nextBPId()), uiDirty(false), enabled(true),
-    pending(true), type(BreakpointByFileAndLine),
-    ignoreCount(0), lineNumber(0), address(0),
-    useFullPath(false),
-    bpIgnoreCount(0), bpLineNumber(0),
-    bpCorrectedLineNumber(0), bpAddress(0),
-    bpMultiple(false), bpEnabled(true),
-    m_markerLineNumber(0)
-{
-}
-
-BreakpointData *BreakpointData::clone() const
+static quint64 nextBPId()
 {
-    BreakpointData *data = new BreakpointData();
-    data->enabled = enabled;
-    data->type = type;
-    data->fileName = fileName;
-    data->condition = condition;
-    data->ignoreCount = ignoreCount;
-    data->lineNumber = lineNumber;
-    data->address = address;
-    data->threadSpec = threadSpec;
-    data->funcName = funcName;
-    data->useFullPath = useFullPath;
-    if (data->type == BreakpointByFunction) {
-        // FIXME: Would removing it be better then leaving this 
-        // "history" around?
-        data->m_markerFileName = m_markerFileName;
-        data->m_markerLineNumber = m_markerLineNumber;
-    } else {
-        data->m_markerFileName = fileName;
-        data->m_markerLineNumber = lineNumber;
-    }
-    return data;
+    // Ok to be not thread-safe. The order does not matter and only the gui
+    // produces authoritative ids.
+    static quint64 i = 0;
+    return ++i;
 }
 
-BreakpointData::~BreakpointData()
+BreakpointData::BreakpointData()
 {
+    m_state = BreakpointNew;
+    m_engine = 0;
+    m_enabled = true;
+    m_type = BreakpointByFileAndLine;
+    m_ignoreCount = 0;
+    m_lineNumber = 0;
+    m_address = 0;
+    m_useFullPath = false;
+    m_markerLineNumber = 0;
 }
 
-void BreakpointData::clear()
+BreakpointResponse::BreakpointResponse()
 {
-    uiDirty = false;
-    pending = true;
-    bpNumber.clear();
-    bpCondition.clear();
+    bpNumber = 0;
     bpIgnoreCount = 0;
-    bpFileName.clear();
-    bpFullName.clear();
     bpLineNumber = 0;
-    bpCorrectedLineNumber = 0;
-    bpThreadSpec.clear();
-    bpFuncName.clear();
+    //bpCorrectedLineNumber = 0;
     bpAddress = 0;
     bpMultiple = false;
     bpEnabled = true;
-    bpState.clear();
-    m_markerFileName = fileName;
-    m_markerLineNumber = lineNumber;
 }
 
-void BreakpointData::setMarkerFileName(const QString &fileName)
-{
-    m_markerFileName = fileName;
-}
+#define SETIT(var, value) return (var != value) && (var = value, true)
 
-void BreakpointData::setMarkerLineNumber(int lineNumber)
-{
-    m_markerLineNumber = lineNumber;
-}
+bool BreakpointData::setUseFullPath(bool on)
+{ SETIT(m_useFullPath, on); }
+
+bool BreakpointData::setMarkerFileName(const QString &file)
+{ SETIT(m_markerFileName, file); }
+
+bool BreakpointData::setMarkerLineNumber(int line)
+{ SETIT(m_markerLineNumber, line); }
+
+bool BreakpointData::setFileName(const QString &file)
+{ SETIT(m_fileName, file); }
+
+bool BreakpointData::setEnabled(bool on)
+{ SETIT(m_enabled, on); }
+
+bool BreakpointData::setIgnoreCount(bool count)
+{ SETIT(m_ignoreCount, count); }
+
+bool BreakpointData::setFunctionName(const QString &name)
+{ SETIT(m_functionName, name); }
+
+bool BreakpointData::setLineNumber(int line)
+{ SETIT(m_lineNumber, line); }
+
+bool BreakpointData::setAddress(quint64 address)
+{ SETIT(m_address, address); }
 
-static inline void formatAddress(QTextStream &str, quint64 address)
+bool BreakpointData::setThreadSpec(const QByteArray &spec)
+{ SETIT(m_threadSpec, spec); }
+
+bool BreakpointData::setType(BreakpointType type)
+{ SETIT(m_type, type); }
+
+bool BreakpointData::setCondition(const QByteArray &cond)
+{ SETIT(m_condition, cond); }
+
+bool BreakpointData::setState(BreakpointState state)
+{ SETIT(m_state, state); }
+
+bool BreakpointData::setEngine(DebuggerEngine *engine)
+{ SETIT(m_engine, engine); }
+
+#undef SETIT
+
+
+static void formatAddress(QTextStream &str, quint64 address)
 {
     if (address) {
         str << "0x";
@@ -143,8 +141,8 @@ static inline void formatAddress(QTextStream &str, quint64 address)
 
 QString BreakpointData::toToolTip() const
 {
-    QString t = tr("Unknown Breakpoint Type");
-    switch (type) {
+    QString t;
+    switch (m_type) {
         case BreakpointByFileAndLine:
             t = tr("Breakpoint by File and Line");
             break;
@@ -157,64 +155,72 @@ QString BreakpointData::toToolTip() const
         case Watchpoint:
             t = tr("Watchpoint");
             break;
+        case UnknownType:
+            t = tr("Unknown Breakpoint Type");
     }
 
     QString rc;
     QTextStream str(&rc);
     str << "<html><body><table>"
+        //<< "<tr><td>" << tr("Id:")
+        //<< "</td><td>" << m_id << "</td></tr>"
+        << "<tr><td>" << tr("State:")
+        << "</td><td>" << m_state << "</td></tr>"
+        << "<tr><td>" << tr("Engine:")
+        << "</td><td>" << m_engine << "</td></tr>"
         << "<tr><td>" << tr("Marker File:")
         << "</td><td>" << QDir::toNativeSeparators(m_markerFileName) << "</td></tr>"
         << "<tr><td>" << tr("Marker Line:")
         << "</td><td>" << m_markerLineNumber << "</td></tr>"
-        << "<tr><td>" << tr("Breakpoint Number:")
-        << "</td><td>" << bpNumber << "</td></tr>"
+        //<< "<tr><td>" << tr("Breakpoint Number:")
+        //<< "</td><td>" << bpNumber << "</td></tr>"
         << "<tr><td>" << tr("Breakpoint Type:")
         << "</td><td>" << t << "</td></tr>"
         << "<tr><td>" << tr("State:")
-        << "</td><td>" << bpState << "</td></tr>"
+        //<< "</td><td>" << bpState << "</td></tr>"
         << "</table><br><hr><table>"
         << "<tr><th>" << tr("Property")
         << "</th><th>" << tr("Requested")
         << "</th><th>" << tr("Obtained") << "</th></tr>"
         << "<tr><td>" << tr("Internal Number:")
-        << "</td><td>&mdash;</td><td>" << bpNumber << "</td></tr>"
+        //<< "</td><td>&mdash;</td><td>" << bpNumber << "</td></tr>"
         << "<tr><td>" << tr("File Name:")
-        << "</td><td>" << QDir::toNativeSeparators(fileName)
-        << "</td><td>" << QDir::toNativeSeparators(bpFileName) << "</td></tr>"
+        << "</td><td>" << QDir::toNativeSeparators(m_fileName)
+        //<< "</td><td>" << QDir::toNativeSeparators(bpFileName) << "</td></tr>"
         << "<tr><td>" << tr("Function Name:")
-        << "</td><td>" << funcName << "</td><td>" << bpFuncName << "</td></tr>"
+        << "</td><td>" << m_functionName // << "</td><td>" << bpFuncName << "</td></tr>"
         << "<tr><td>" << tr("Line Number:") << "</td><td>";
-    if (lineNumber)
-        str << lineNumber;
-    str << "</td><td>";
-    if (bpLineNumber)
-        str << bpLineNumber;
+    if (m_lineNumber)
+        str << m_lineNumber;
+    //str << "</td><td>";
+    //if (bpLineNumber)
+    //    str << bpLineNumber;
     str << "</td></tr>"
         << "<tr><td>" << tr("Breakpoint Address:")
         << "</td><td>";
-    formatAddress(str, address);
+    formatAddress(str, m_address);
     str << "</td><td>";
-    formatAddress(str, bpAddress);
-    str <<  "</td></tr>"
-        << "<tr><td>" << tr("Corrected Line Number:")
-        << "</td><td>-</td><td>";
-    if (bpCorrectedLineNumber > 0) {
-        str << bpCorrectedLineNumber;
-    } else {
-        str << '-';
-    }
+    //formatAddress(str, bpAddress);
+    //str <<  "</td></tr>"
+    //    << "<tr><td>" << tr("Corrected Line Number:")
+    //    << "</td><td>-</td><td>";
+    //if (bpCorrectedLineNumber > 0) {
+    //    str << bpCorrectedLineNumber;
+   // } else {
+   //     str << '-';
+   // }
     str << "</td></tr>"
         << "<tr><td>" << tr("Condition:")
-        << "</td><td>" << condition << "</td><td>" << bpCondition << "</td></tr>"
+    //    << "</td><td>" << m_condition << "</td><td>" << bpCondition << "</td></tr>"
         << "<tr><td>" << tr("Ignore Count:") << "</td><td>";
-    if (ignoreCount)
-        str << ignoreCount;
+    if (m_ignoreCount)
+        str << m_ignoreCount;
     str << "</td><td>";
-    if (bpIgnoreCount)
-        str << bpIgnoreCount;
+    //if (bpIgnoreCount)
+    //    str << bpIgnoreCount;
     str << "</td></tr>"
         << "<tr><td>" << tr("Thread Specification:")
-        << "</td><td>" << threadSpec << "</td><td>" << bpThreadSpec << "</td></tr>"
+     //   << "</td><td>" << m_threadSpec << "</td><td>" << bpThreadSpec << "</td></tr>"
         << "</table></body></html>";
     return rc;
 }
@@ -229,66 +235,52 @@ static inline bool fileNameMatch(const QString &f1, const QString &f2)
 #endif
 }
 
-bool BreakpointData::isLocatedAt(const QString &fileName_, int lineNumber_, 
+bool BreakpointData::isLocatedAt(const QString &fileName, int lineNumber, 
     bool useMarkerPosition) const
 {
-    int line = useMarkerPosition ? m_markerLineNumber : lineNumber;
-    return lineNumber_ == line && fileNameMatch(fileName_, m_markerFileName);
+    int line = useMarkerPosition ? m_markerLineNumber : m_lineNumber;
+    return lineNumber == line && fileNameMatch(fileName, m_markerFileName);
 }
 
-bool BreakpointData::isSimilarTo(const BreakpointData *needle) const
-{
-    //qDebug() << "COMPARING " << toString() << " WITH " << needle->toString();
-
-    if (id == needle->id && id != 0)
-        return true;
-
-    // Clear hit.
-    if (bpNumber == needle->bpNumber
-            && !bpNumber.isEmpty()
-            && bpNumber.toInt() != 0)
-        return true;
-
-    // Clear miss.
-    if (type != needle->type)
-        return false;
-
-    // We have numbers, but they are different.
-    if (!bpNumber.isEmpty() && !needle->bpNumber.isEmpty()
-            && !bpNumber.startsWith(needle->bpNumber)
-            && !needle->bpNumber.startsWith(bpNumber))
-        return false;
-
-    if (address && needle->address && address == needle->address)
-        return true;
-
-    // At least at a position we were looking for.
-    // FIXME: breaks multiple breakpoints at the same location
-    if (!fileName.isEmpty()
-            && fileNameMatch(fileName, needle->fileName)
-            && lineNumber == needle->lineNumber)
-        return true;
-
-    // At least at a position we were looking for.
-    // FIXME: breaks multiple breakpoints at the same location
-    if (!fileName.isEmpty()
-            && fileNameMatch(fileName, needle->bpFileName)
-            && lineNumber == needle->bpLineNumber)
-        return true;
-
-    return false;
-}
-
-bool BreakpointData::conditionsMatch() const
+bool BreakpointData::conditionsMatch(const QString &other) const
 {
     // Some versions of gdb "beautify" the passed condition.
-    QString s1 = condition;
+    QString s1 = m_condition;
     s1.remove(QChar(' '));
-    QString s2 = bpCondition;
+    QString s2 = other;
     s2.remove(QChar(' '));
     return s1 == s2;
 }
 
+QString BreakpointData::toString() const
+{
+    QString result;
+    QTextStream ts(&result);
+    ts << fileName();
+    ts << condition();
+    ts << ignoreCount();
+    ts << lineNumber();
+    ts << address();
+    ts << functionName();
+    ts << useFullPath();
+    return result;
+}
+
+QString BreakpointResponse::toString() const
+{
+    QString result;
+    QTextStream ts(&result);
+    ts << bpNumber;
+    ts << bpCondition;
+    ts << bpIgnoreCount;
+    ts << bpFileName;
+    ts << bpFullName;
+    ts << bpLineNumber;
+    ts << bpThreadSpec;
+    ts << bpFuncName;
+    ts << bpAddress;
+    return result;
+}
+
 } // namespace Internal
 } // namespace Debugger
-
diff --git a/src/plugins/debugger/breakpoint.h b/src/plugins/debugger/breakpoint.h
index e155457ffd2ba18fee3f67f57f38d7dfd9f84e21..c013df2ef0239f8136ad5d62ace978a0232aed76 100644
--- a/src/plugins/debugger/breakpoint.h
+++ b/src/plugins/debugger/breakpoint.h
@@ -36,6 +36,11 @@
 #include <QtCore/QCoreApplication>
 
 namespace Debugger {
+
+class DebuggerEngine;
+
+typedef quint64 BreakpointId; // FIXME: make Internal.
+
 namespace Internal {
 
 class BreakpointMarker;
@@ -49,6 +54,7 @@ class BreakHandler;
 
 enum BreakpointType
 {
+    UnknownType,
     BreakpointByFileAndLine,
     BreakpointByFunction,
     BreakpointByAddress,
@@ -58,36 +64,21 @@ enum BreakpointType
 enum BreakpointState
 {
     BreakpointNew,
-    BreakpointInsertionRequested,  // Inferior was told about bp, not ack'ed.
+    BreakpointInsertRequested,  // Inferior was told about bp, not ack'ed.
+    BreakpointInsertProceeding,
     BreakpointChangeRequested,
-    BreakpointOk,
-    BreakpointRemovalRequested,
-    BreakpointRemoved,
+    BreakpointChangeProceeding,
+    BreakpointPending,
+    BreakpointInserted,
+    BreakpointRemoveRequested,
+    BreakpointRemoveProceeding,
     BreakpointDead,
 };
 
 class BreakpointData
 {
-public:
-    BreakpointData();
-    ~BreakpointData();
-
-    QString toToolTip() const;
-    void clear(); // Delete all generated data.
-
-    bool isLocatedAt(const QString &fileName, int lineNumber,
-        bool useMarkerPosition) const;
-    bool isSimilarTo(const BreakpointData *needle) const;
-    bool conditionsMatch() const;
-
-    // This copies only the static data.
-    BreakpointData *clone() const;
-
-    // Generic name for function to break on 'throw'
-    static const char *throwFunction;
-    static const char *catchFunction;
-
 private:
+
     // Intentionally unimplemented.
     // Making it copyable is tricky because of the markers.
     BreakpointData(const BreakpointData &);
@@ -96,64 +87,106 @@ private:
     friend class BreakHandler;
 
 public:
-    quint64 id;
-    BreakpointState state;
-    bool uiDirty;            // ui has changed stuff
+    BreakpointData();
 
-    bool enabled;            // Should we talk to the debugger engine?
-    bool pending;            // Does the debugger engine know about us already?
-    BreakpointType type;     // Type of breakpoint.
+    bool isPending() const { return m_state == BreakpointPending
+        || m_state == BreakpointNew; }
+    BreakpointType type() const { return m_type; }
+    quint64 address() const { return m_address; }
+    bool useFullPath() const { return m_useFullPath; }
+    QString toToolTip() const;
+    QString toString() const;
 
-    // This "user requested information" will get stored in the session.
-    QString fileName;        // Short name of source file.
-    QByteArray condition;    // Condition associated with breakpoint.
-    int ignoreCount;         // Ignore count associated with breakpoint.
-    int lineNumber;          // Line in source file.
-    quint64 address;         // Address for watchpoints.
-    QByteArray threadSpec;   // Thread specification.
-    // Name of containing function, special values:
-    // BreakpointData::throwFunction, BreakpointData::catchFunction
-    QString funcName;
-    bool useFullPath;        // Should we use the full path when setting the bp?
-
-    // This is what gdb produced in response.
-    QByteArray bpNumber;     // Breakpoint number assigned by the debugger engine.
-    QByteArray bpCondition;  // Condition acknowledged by the debugger engine.
-    int bpIgnoreCount;       // Ignore count acknowledged by the debugger engine.
-    QString bpFileName;      // File name acknowledged by the debugger engine.
-    QString bpFullName;      // Full file name acknowledged by the debugger engine.
-    int bpLineNumber; // Line number acknowledged by the debugger engine.
-    int bpCorrectedLineNumber; // Acknowledged by the debugger engine.
-    QByteArray bpThreadSpec; // Thread spec acknowledged by the debugger engine.
-    QString bpFuncName;      // Function name acknowledged by the debugger engine.
-    quint64 bpAddress;       // Address acknowledged by the debugger engine.
-    bool bpMultiple;         // Happens in constructors/gdb.
-    bool bpEnabled;          // Enable/disable command sent.
-    QByteArray bpState;      // gdb: <PENDING>, <MULTIPLE>
-
-    void setMarkerFileName(const QString &fileName);
+    bool isLocatedAt(const QString &fileName, int lineNumber,
+        bool useMarkerPosition) const;
+    bool conditionsMatch(const QString &other) const;
+    BreakpointState state() const { return m_state; }
+    QString functionName() const { return m_functionName; }
     QString markerFileName() const { return m_markerFileName; }
-
-    void setMarkerLineNumber(int lineNumber);
+    QString fileName() const { return m_fileName; }
     int markerLineNumber() const { return m_markerLineNumber; }
+    int lineNumber() const { return m_lineNumber; }
+    int ignoreCount() const { return m_ignoreCount; }
+    bool isEnabled() const { return m_enabled; }
+    QByteArray threadSpec() const { return m_threadSpec; }
+    QByteArray condition() const { return m_condition; }
+    DebuggerEngine *engine() const { return m_engine; }
+
+    bool isWatchpoint() const { return m_type == Watchpoint; }
+    bool isBreakpoint() const { return m_type != Watchpoint; } // Enough for now.
+    // Generic name for function to break on 'throw'
+    static const char *throwFunction;
+    static const char *catchFunction;
 
-    bool isWatchpoint() const { return type == Watchpoint; }
-    bool isBreakpoint() const { return type != Watchpoint; } // Enough for now.
-
-    Q_DECLARE_TR_FUNCTIONS(BreakHandler)
+//private:
+     // All setters return true on change.
+    bool setUseFullPath(bool on);
+    bool setMarkerFileName(const QString &file);
+    bool setMarkerLineNumber(int line);
+    bool setFileName(const QString &file);
+    bool setEnabled(bool on);
+    bool setIgnoreCount(bool count);
+    bool setFunctionName(const QString &name);
+    bool setLineNumber(int line);
+    bool setAddress(quint64 address);
+    bool setThreadSpec(const QByteArray &spec);
+    bool setType(BreakpointType type);
+    bool setCondition(const QByteArray &cond);
+    bool setState(BreakpointState state);
+    bool setEngine(DebuggerEngine *engine);
 
-    // TODO: move those to breakhandler
 private:
-    // Taken from either user input or gdb responses.
+    DebuggerEngine *m_engine;
+    BreakpointType m_type;     // Type of breakpoint.
+    BreakpointState m_state;   // Current state of breakpoint.
+    bool m_enabled;            // Should we talk to the debugger engine?
+    bool m_pending;            // Does the debugger engine know about us already?
+    bool m_useFullPath;        // Should we use the full path when setting the bp?
+    // This "user requested information" will get stored in the session.
+    QString m_fileName;        // Short name of source file.
+    QByteArray m_condition;    // Condition associated with breakpoint.
+    int m_ignoreCount;         // Ignore count associated with breakpoint.
+    int m_lineNumber;          // Line in source file.
+    quint64 m_address;         // Address for watchpoints.
+    QByteArray m_threadSpec;   // Thread specification.
+    // Name of containing function, special values:
+    // BreakpointData::throwFunction, BreakpointData::catchFunction
+    QString m_functionName;
     QString m_markerFileName; // Used to locate the marker.
     int m_markerLineNumber;
+
+public:
+    Q_DECLARE_TR_FUNCTIONS(BreakHandler)
+};
+
+// This is what debuggers produced in response to the attempt to
+// insert a breakpoint. The data might differ from the requested bits.
+class BreakpointResponse
+{
+public:
+    BreakpointResponse();
+    QString toString() const;
+
+public:
+    int bpNumber;             // Breakpoint number assigned by the debugger engine.
+    BreakpointType bpType;    // Breakpoint type used by debugger engine.
+    QByteArray bpCondition;   // Condition acknowledged by the debugger engine.
+    int bpIgnoreCount;        // Ignore count acknowledged by the debugger engine.
+    QString bpFileName;       // File name acknowledged by the debugger engine.
+    QString bpFullName;       // Full file name acknowledged by the debugger engine.
+    int bpLineNumber;         // Line number acknowledged by the debugger engine.
+    //int bpCorrectedLineNumber; // Acknowledged by the debugger engine.
+    QByteArray bpThreadSpec;  // Thread spec acknowledged by the debugger engine.
+    QString bpFuncName;       // Function name acknowledged by the debugger engine.
+    quint64 bpAddress;        // Address acknowledged by the debugger engine.
+    bool bpMultiple;          // Happens in constructors/gdb.
+    bool bpEnabled;           // Enable/disable command sent.
+    QByteArray bpState;       // gdb: <PENDING>, <MULTIPLE>
 };
 
-typedef QList<BreakpointData *> Breakpoints;
+typedef QList<BreakpointId> BreakpointIds;
 
 } // namespace Internal
 } // namespace Debugger
 
-Q_DECLARE_METATYPE(Debugger::Internal::BreakpointData *);
-
 #endif // DEBUGGER_BREAKPOINT_H
diff --git a/src/plugins/debugger/breakpointmarker.cpp b/src/plugins/debugger/breakpointmarker.cpp
index f0ffa4d67e41769dd4e2ad00ce9849629132f264..c77751b478a17e9cdf342e92328d41f9f43e9a69 100644
--- a/src/plugins/debugger/breakpointmarker.cpp
+++ b/src/plugins/debugger/breakpointmarker.cpp
@@ -29,17 +29,14 @@
 
 #include "breakpointmarker.h"
 #include "breakhandler.h"
-
-#include "stackframe.h"
+#include "debuggercore.h"
 
 #include <texteditor/basetextmark.h>
 #include <utils/qtcassert.h>
 
 #include <QtCore/QByteArray>
 #include <QtCore/QDebug>
-#include <QtCore/QTextStream>
-#include <QtCore/QFileInfo>
-#include <QtCore/QDir>
+
 
 //////////////////////////////////////////////////////////////////
 //
@@ -51,12 +48,9 @@
 namespace Debugger {
 namespace Internal {
 
-BreakpointMarker::BreakpointMarker(BreakHandler *handler, BreakpointData *data, 
+BreakpointMarker::BreakpointMarker(BreakpointId id,
         const QString &fileName, int lineNumber)
-    : BaseTextMark(fileName, lineNumber)
-    , m_handler(handler)
-    , m_data(data)
-    , m_pending(true)
+  : BaseTextMark(fileName, lineNumber), m_id(id)
 {
     //qDebug() << "CREATE MARKER " << fileName << lineNumber;
 }
@@ -64,24 +58,11 @@ BreakpointMarker::BreakpointMarker(BreakHandler *handler, BreakpointData *data,
 BreakpointMarker::~BreakpointMarker()
 {
     //qDebug() << "REMOVE MARKER ";
-    m_data = 0;
 }
 
 QIcon BreakpointMarker::icon() const
 {
-    if (!m_data->enabled)
-        return m_handler->disabledBreakpointIcon();
-    if (!m_handler->isActive())
-        return m_handler->emptyIcon();
-    return m_pending ? m_handler->pendingBreakPointIcon() : m_handler->breakpointIcon();
-}
-
-void BreakpointMarker::setPending(bool pending)
-{
-    if (pending == m_pending)
-        return;
-    m_pending = pending;
-    updateMarker();
+    return breakHandler()->icon(m_id);
 }
 
 void BreakpointMarker::updateBlock(const QTextBlock &)
@@ -91,38 +72,12 @@ void BreakpointMarker::updateBlock(const QTextBlock &)
 
 void BreakpointMarker::removedFromEditor()
 {
-    if (!m_data)
-        return;
-    m_handler->removeBreakpoint(m_data);
-    //handler->saveBreakpoints();
-    m_handler->updateMarkers();
+    breakHandler()->removeBreakpoint(m_id);
 }
 
 void BreakpointMarker::updateLineNumber(int lineNumber)
 {
-    if (!m_data)
-        return;
-    //if (m_data->markerLineNumber == lineNumber)
-    //    return;
-    if (m_data->markerLineNumber() != lineNumber) {
-        m_data->setMarkerLineNumber(lineNumber);
-        // FIXME: Should we tell gdb about the change?
-        // Ignore it for now, as we would require re-compilation
-        // and debugger re-start anyway.
-        if (0 && m_data->bpLineNumber) {
-            if (!m_data->bpNumber.trimmed().isEmpty()) {
-                m_data->pending = true;
-            }
-        }
-    }
-    // Ignore updates to the "real" line number while the debugger is
-    // running, as this can be triggered by moving the breakpoint to
-    // the next line that generated code.
-    // FIXME: Do we need yet another data member?
-    if (m_data->bpNumber.trimmed().isEmpty()) {
-        m_data->lineNumber = lineNumber;
-        m_handler->updateMarkers();
-    }
+    breakHandler()->updateLineNumberFromMarker(m_id, lineNumber);
 }
 
 } // namespace Internal
diff --git a/src/plugins/debugger/breakpointmarker.h b/src/plugins/debugger/breakpointmarker.h
index f643a96d46df5d3d5f7f17e70f8c846b68bc5163..2e8bd325aaa7c3b7e7cac12a199b44547d79ae43 100644
--- a/src/plugins/debugger/breakpointmarker.h
+++ b/src/plugins/debugger/breakpointmarker.h
@@ -45,18 +45,14 @@ class BreakpointMarker : public TextEditor::BaseTextMark
 {
     Q_OBJECT
 public:
-    BreakpointMarker(BreakHandler *handler, BreakpointData *data,
-            const QString &fileName, int lineNumber);
+    BreakpointMarker(BreakpointId id, const QString &fileName, int lineNumber);
     ~BreakpointMarker();
     QIcon icon() const;
-    void setPending(bool pending);
     void updateBlock(const QTextBlock &);
     void removedFromEditor();
     void updateLineNumber(int lineNumber);
 private:
-    BreakHandler *m_handler;
-    BreakpointData *m_data;
-    bool m_pending;
+    BreakpointId m_id;
     friend class BreakHandler;
 };
 
diff --git a/src/plugins/debugger/breakwindow.cpp b/src/plugins/debugger/breakwindow.cpp
index ba3ecddddeba81d866e903c659562e96cfe1c3e3..6b328eba7311f15ba18e30f962ba46c94e25f6f8 100644
--- a/src/plugins/debugger/breakwindow.cpp
+++ b/src/plugins/debugger/breakwindow.cpp
@@ -55,32 +55,6 @@
 namespace Debugger {
 namespace Internal {
 
-static BreakHandler *breakHandler()
-{
-    return debuggerCore()->breakHandler();
-}
-
-static BreakpointData *breakpointAt(int index)
-{
-    BreakHandler *handler = breakHandler();
-    QTC_ASSERT(handler, return 0);
-    return handler->at(index);
-}
-
-static void synchronizeBreakpoints()
-{
-    BreakHandler *handler = breakHandler();
-    QTC_ASSERT(handler, return);
-    handler->synchronizeBreakpoints();
-}
-
-static void appendBreakpoint(BreakpointData *data)
-{
-    BreakHandler *handler = breakHandler();
-    QTC_ASSERT(handler, return);
-    handler->appendBreakpoint(data);
-}
-
 
 ///////////////////////////////////////////////////////////////////////
 //
@@ -114,19 +88,20 @@ BreakpointDialog::BreakpointDialog(QWidget *parent) : QDialog(parent)
 
 bool BreakpointDialog::showDialog(BreakpointData *data)
 {
-    pathChooserFileName->setPath(data->fileName);
-    lineEditLineNumber->setText(QString::number(data->lineNumber));
-    lineEditFunction->setText(data->funcName);
-    lineEditCondition->setText(QString::fromUtf8(data->condition));
-    lineEditIgnoreCount->setText(QString::number(data->ignoreCount));
-    checkBoxUseFullPath->setChecked(data->useFullPath);
-    lineEditThreadSpec->setText(QString::fromUtf8(data->threadSpec));
-    if (data->address)
-        lineEditAddress->setText(QString::fromAscii("0x%1").arg(data->address, 0, 16));
+    pathChooserFileName->setPath(data->fileName());
+    lineEditLineNumber->setText(QString::number(data->lineNumber()));
+    lineEditFunction->setText(data->functionName());
+    lineEditCondition->setText(QString::fromUtf8(data->condition()));
+    lineEditIgnoreCount->setText(QString::number(data->ignoreCount()));
+    checkBoxUseFullPath->setChecked(data->useFullPath());
+    lineEditThreadSpec->setText(QString::fromUtf8(data->threadSpec()));
+    const quint64 address = data->address();
+    if (address)
+        lineEditAddress->setText(QString::fromAscii("0x%1").arg(address, 0, 16));
     int initialType = 0;
-    if (!data->funcName.isEmpty())
-        initialType = data->funcName == QLatin1String("main") ? 2 : 1;
-    if (data->address)
+    if (!data->functionName().isEmpty())
+        initialType = data->functionName() == QLatin1String("main") ? 2 : 1;
+    if (address)
         initialType = 3;
     typeChanged(initialType);
 
@@ -137,26 +112,22 @@ bool BreakpointDialog::showDialog(BreakpointData *data)
     const int newLineNumber = lineEditLineNumber->text().toInt();
     const bool newUseFullPath  = checkBoxUseFullPath->isChecked();
     const quint64 newAddress = lineEditAddress->text().toULongLong(0, 0);
-    const QString newFunc = lineEditFunction->text();
+    const QString newFunction = lineEditFunction->text();
     const QString newFileName = pathChooserFileName->path();
     const QByteArray newCondition = lineEditCondition->text().toUtf8();
     const int newIgnoreCount = lineEditIgnoreCount->text().toInt();
     const QByteArray newThreadSpec = lineEditThreadSpec->text().toUtf8();
-    if (newLineNumber == data->lineNumber && newUseFullPath == data->useFullPath
-        && newAddress == data->address && newFunc == data->funcName
-        && newFileName == data->fileName && newCondition == data->condition
-        && newIgnoreCount == data->ignoreCount && newThreadSpec == data->threadSpec)
-        return false; // Unchanged -> Cancel.
-
-    data->address = newAddress;
-    data->funcName = newFunc;
-    data->useFullPath = newUseFullPath;
-    data->fileName = newFileName;
-    data->lineNumber = newLineNumber;
-    data->condition = newCondition;
-    data->ignoreCount = newIgnoreCount;
-    data->threadSpec = newThreadSpec;
-    return true;
+   
+    bool result = false; 
+    result |= data->setAddress(newAddress);
+    result |= data->setFunctionName(newFunction);
+    result |= data->setUseFullPath(newUseFullPath);
+    result |= data->setFileName(newFileName);
+    result |= data->setLineNumber(newLineNumber);
+    result |= data->setCondition(newCondition);
+    result |= data->setIgnoreCount(newIgnoreCount);
+    result |= data->setThreadSpec(newThreadSpec);
+    return result;
 }
 
 void BreakpointDialog::typeChanged(int index)
@@ -189,7 +160,7 @@ BreakWindow::BreakWindow(QWidget *parent)
 {
     m_alwaysResizeColumnsToContents = false;
 
-    QAction *act = theDebuggerAction(UseAlternatingRowColors);
+    QAction *act = debuggerCore()->action(UseAlternatingRowColors);
     setFrameStyle(QFrame::NoFrame);
     setAttribute(Qt::WA_MacShowFocusRect, false);
     setWindowTitle(tr("Breakpoints"));
@@ -200,11 +171,11 @@ BreakWindow::BreakWindow(QWidget *parent)
     setSelectionMode(QAbstractItemView::ExtendedSelection);
 
     connect(this, SIGNAL(activated(QModelIndex)),
-        this, SLOT(rowActivated(QModelIndex)));
+        SLOT(rowActivated(QModelIndex)));
     connect(act, SIGNAL(toggled(bool)),
-        this, SLOT(setAlternatingRowColorsHelper(bool)));
-    connect(theDebuggerAction(UseAddressInBreakpointsView), SIGNAL(toggled(bool)),
-        this, SLOT(showAddressColumn(bool)));
+        SLOT(setAlternatingRowColorsHelper(bool)));
+    connect(debuggerCore()->action(UseAddressInBreakpointsView), SIGNAL(toggled(bool)),
+        SLOT(showAddressColumn(bool)));
 }
 
 BreakWindow::~BreakWindow()
@@ -264,6 +235,7 @@ void BreakWindow::contextMenuEvent(QContextMenuEvent *ev)
 
     const int rowCount = model()->rowCount();
     const unsigned engineCapabilities = BreakOnThrowAndCatchCapability;
+    BreakHandler *handler = breakHandler();
     // FIXME BP:    model()->data(QModelIndex(), EngineCapabilitiesRole).toUInt();
 
     QAction *deleteAction = new QAction(tr("Delete Breakpoint"), &menu);
@@ -274,14 +246,14 @@ void BreakWindow::contextMenuEvent(QContextMenuEvent *ev)
 
     // Delete by file: Find indices of breakpoints of the same file.
     QAction *deleteByFileAction = 0;
-    QList<int> breakPointsOfFile;
+    QList<QModelIndex> breakPointsOfFile;
     if (indexUnderMouse.isValid()) {
         const QModelIndex index = indexUnderMouse.sibling(indexUnderMouse.row(), 2);
         const QString file = model()->data(index).toString();
         if (!file.isEmpty()) {
             for (int i = 0; i < rowCount; i++)
                 if (model()->data(model()->index(i, 2)).toString() == file)
-                    breakPointsOfFile.push_back(i);
+                    breakPointsOfFile.push_back(model()->index(i, 2));
             if (breakPointsOfFile.size() > 1) {
                 deleteByFileAction =
                     new QAction(tr("Delete Breakpoints of \"%1\"").arg(file), &menu);
@@ -321,8 +293,9 @@ void BreakWindow::contextMenuEvent(QContextMenuEvent *ev)
 
     QModelIndex idx0 = (si.size() ? si.front() : QModelIndex());
     QModelIndex idx2 = idx0.sibling(idx0.row(), 2);
-    BreakpointData *data = breakpointAt(idx0.row());
-    bool enabled = si.isEmpty() || (data && data->enabled);
+    const BreakpointId id = handler->findBreakpointByIndex(idx0);
+
+    bool enabled = si.isEmpty() || handler->isEnabled(id);
 
     const QString str5 = si.size() > 1
         ? enabled
@@ -348,7 +321,7 @@ void BreakWindow::contextMenuEvent(QContextMenuEvent *ev)
     menu.addAction(toggleEnabledAction);
     menu.addSeparator();
     menu.addAction(deleteAllAction);
-    menu.addAction(deleteByFileAction);
+    //menu.addAction(deleteByFileAction);
     menu.addSeparator();
     menu.addAction(synchronizeAction);
     if (engineCapabilities & BreakOnThrowAndCatchCapability) {
@@ -357,21 +330,21 @@ void BreakWindow::contextMenuEvent(QContextMenuEvent *ev)
         menu.addAction(breakAtCatchAction);
     }
     menu.addSeparator();
-    menu.addAction(theDebuggerAction(UseToolTipsInBreakpointsView));
-    menu.addAction(theDebuggerAction(UseAddressInBreakpointsView));
+    menu.addAction(debuggerCore()->action(UseToolTipsInBreakpointsView));
+    menu.addAction(debuggerCore()->action(UseAddressInBreakpointsView));
     menu.addAction(adjustColumnAction);
     menu.addAction(alwaysAdjustAction);
     menu.addSeparator();
-    menu.addAction(theDebuggerAction(SettingsDialog));
+    menu.addAction(debuggerCore()->action(SettingsDialog));
 
     QAction *act = menu.exec(ev->globalPos());
 
     if (act == deleteAction) {
         deleteBreakpoints(si);
     } else if (act == deleteAllAction) {
-        QList<int> allRows;
+        QList<QModelIndex> allRows;
         for (int i = 0; i < rowCount; i++)
-            allRows.push_back(i);
+            allRows.push_back(model()->index(i, 0));
         deleteBreakpoints(allRows);
     }  else if (act == deleteByFileAction)
         deleteBreakpoints(breakPointsOfFile);
@@ -384,81 +357,62 @@ void BreakWindow::contextMenuEvent(QContextMenuEvent *ev)
     else if (act == associateBreakpointAction)
         associateBreakpoint(si, threadId);
     else if (act == synchronizeAction)
-        synchronizeBreakpoints();
+        ; //synchronizeBreakpoints();
     else if (act == toggleEnabledAction)
         setBreakpointsEnabled(si, !enabled);
     else if (act == addBreakpointAction)
         addBreakpoint();
     else if (act == breakAtThrowAction) {
+        // FIXME: Use the proper breakpoint type instead.
         BreakpointData *data = new BreakpointData;
-        data->funcName = BreakpointData::throwFunction;
-        appendBreakpoint(data);
+        data->setFunctionName(BreakpointData::throwFunction);
+        handler->appendBreakpoint(data);
     } else if (act == breakAtCatchAction) {
+        // FIXME: Use the proper breakpoint type instead.
         BreakpointData *data = new BreakpointData;
-        data->funcName = BreakpointData::catchFunction;
-        appendBreakpoint(data);
+        data->setFunctionName(BreakpointData::catchFunction);
+        handler->appendBreakpoint(data);
     }
 }
 
 void BreakWindow::setBreakpointsEnabled(const QModelIndexList &list, bool enabled)
 {
-    foreach (const QModelIndex &index, list) {
-        BreakpointData *data = breakpointAt(index.row());
-        QTC_ASSERT(data, continue);
-        data->enabled = enabled;
-    }
-    synchronizeBreakpoints();
+    BreakHandler *handler = breakHandler();
+    foreach (const QModelIndex &index, list)
+        handler->setEnabled(handler->findBreakpointByIndex(index), enabled);
 }
 
 void BreakWindow::setBreakpointsFullPath(const QModelIndexList &list, bool fullpath)
 {
-    foreach (const QModelIndex &index, list) {
-        BreakpointData *data = breakpointAt(index.row());
-        QTC_ASSERT(data, continue);
-        data->useFullPath = fullpath;
-    }
-    synchronizeBreakpoints();
+    BreakHandler *handler = breakHandler();
+    foreach (const QModelIndex &index, list)
+       handler->setUseFullPath(handler->findBreakpointByIndex(index), fullpath);
 }
 
-void BreakWindow::deleteBreakpoints(const QModelIndexList &indexes)
+void BreakWindow::deleteBreakpoints(const QModelIndexList &list)
 {
-    QTC_ASSERT(!indexes.isEmpty(), return);
-    QList<int> list;
-    foreach (const QModelIndex &index, indexes)
-        list.append(index.row());
-    deleteBreakpoints(list);
+    BreakHandler *handler = breakHandler();
+    foreach (const QModelIndex &index, list)
+       handler->removeBreakpoint(handler->findBreakpointByIndex(index));
 }
 
-void BreakWindow::deleteBreakpoints(QList<int> list)
+static bool editBreakpointInternal(BreakpointData *data, QWidget *parent)
 {
-    if (list.empty())
-        return;
-    BreakHandler *handler = breakHandler();
-    const int firstRow = list.front();
-    qSort(list.begin(), list.end());
-    for (int i = list.size(); --i >= 0; ) {
-        BreakpointData *data = breakpointAt(i);
-        QTC_ASSERT(data, continue);
-        handler->removeBreakpoint(data);
-    }
-
-    const int row = qMin(firstRow, model()->rowCount() - 1);
-    if (row >= 0)
-        setCurrentIndex(model()->index(row, 0));
-    synchronizeBreakpoints();
+    BreakpointDialog dialog(parent);
+    return dialog.showDialog(data);
 }
 
-bool BreakWindow::editBreakpoint(BreakpointData *data, QWidget *parent)
+bool BreakWindow::editBreakpoint(BreakpointId id, QWidget *parent)
 {
     BreakpointDialog dialog(parent);
-    return dialog.showDialog(data);
+    return dialog.showDialog(breakHandler()->breakpointById(id));
 }
 
 void BreakWindow::addBreakpoint()
 {
     BreakpointData *data = new BreakpointData();
-    if (editBreakpoint(data, this))
-        appendBreakpoint(data);
+    if (editBreakpointInternal(data, this))
+        breakHandler()->appendBreakpoint(data);
     else
         delete data;
 }
@@ -467,11 +421,11 @@ void BreakWindow::editBreakpoints(const QModelIndexList &list)
 {
     QTC_ASSERT(!list.isEmpty(), return);
 
+    BreakHandler *handler = breakHandler();
+    const BreakpointId id = handler->findBreakpointByIndex(list.at(0));
+
     if (list.size() == 1) {
-        BreakpointData *data = breakpointAt(0); 
-        QTC_ASSERT(data, return);
-        if (editBreakpoint(data, this))
-            breakHandler()->reinsertBreakpoint(data);
+        editBreakpoint(id, this);
         return;
     }
 
@@ -483,13 +437,9 @@ void BreakWindow::editBreakpoints(const QModelIndexList &list)
     ui.lineEditIgnoreCount->setValidator(
         new QIntValidator(0, 2147483647, ui.lineEditIgnoreCount));
 
-    const QModelIndex idx = list.front();
-    BreakpointData *data = breakpointAt(idx.row()); 
-    QTC_ASSERT(data, return);
-
-    const QString oldCondition = QString::fromLatin1(data->condition);
-    const QString oldIgnoreCount = QString::number(data->ignoreCount);
-    const QString oldThreadSpec = QString::fromLatin1(data->threadSpec);
+    const QString oldCondition = QString::fromLatin1(handler->condition(id));
+    const QString oldIgnoreCount = QString::number(handler->ignoreCount(id));
+    const QString oldThreadSpec = QString::fromLatin1(handler->threadSpec(id));
 
     ui.lineEditCondition->setText(oldCondition);
     ui.lineEditIgnoreCount->setText(oldIgnoreCount);
@@ -508,27 +458,19 @@ void BreakWindow::editBreakpoints(const QModelIndexList &list)
         return;
 
     foreach (const QModelIndex &idx, list) {
-        BreakpointData *data = breakpointAt(idx.row()); 
-        QTC_ASSERT(data, continue);
-        data->condition = newCondition.toLatin1();
-        data->ignoreCount = newIgnoreCount.toInt();
-        data->threadSpec = newThreadSpec.toLatin1();
-        data->uiDirty = true;
+        BreakpointId id = handler->findBreakpointByIndex(idx);
+        handler->setCondition(id, newCondition.toLatin1());
+        handler->setIgnoreCount(id, newIgnoreCount.toInt());
+        handler->setThreadSpec(id, newThreadSpec.toLatin1());
     }
-    synchronizeBreakpoints();
 }
 
 void BreakWindow::associateBreakpoint(const QModelIndexList &list, int threadId)
 {
-    QByteArray condition;
-    if (threadId != -1)
-        condition = QByteArray::number(threadId);
-    foreach (const QModelIndex &index, list) {
-        BreakpointData *data = breakpointAt(index.row()); 
-        QTC_ASSERT(data, continue);
-        data->condition = condition;
-    }
-    synchronizeBreakpoints();
+    BreakHandler *handler = breakHandler();
+    QByteArray spec = QByteArray::number(threadId);
+    foreach (const QModelIndex &index, list)
+        handler->setThreadSpec(handler->findBreakpointByIndex(index), spec);
 }
 
 void BreakWindow::resizeColumnsToContents()
@@ -548,10 +490,7 @@ void BreakWindow::setAlwaysResizeColumnsToContents(bool on)
 
 void BreakWindow::rowActivated(const QModelIndex &index)
 {
-    BreakpointData *data = breakpointAt(index.row());
-    QTC_ASSERT(data, return);
-    debuggerCore()->gotoLocation(data->markerFileName(),
-        data->markerLineNumber(), false);
+    breakHandler()->gotoLocation(breakHandler()->findBreakpointByIndex(index));
 }
 
 } // namespace Internal
diff --git a/src/plugins/debugger/breakwindow.h b/src/plugins/debugger/breakwindow.h
index bfa3b06fd7cdfa49a8f33e09621171eb1dd8e5e9..e843e8ade66e77f512364379fb9649417a2a14d5 100644
--- a/src/plugins/debugger/breakwindow.h
+++ b/src/plugins/debugger/breakwindow.h
@@ -30,13 +30,13 @@
 #ifndef DEBUGGER_BREAKWINDOW_H
 #define DEBUGGER_BREAKWINDOW_H
 
+#include "breakhandler.h"
+
 #include <QtGui/QTreeView>
 
 namespace Debugger {
 namespace Internal {
 
-class BreakpointData;
-
 class BreakWindow : public QTreeView
 {
     Q_OBJECT
@@ -45,7 +45,7 @@ public:
     explicit BreakWindow(QWidget *parent = 0);
     ~BreakWindow();
 
-    static bool editBreakpoint(BreakpointData *data, QWidget *parent = 0);
+    static bool editBreakpoint(BreakpointId id, QWidget *parent = 0);
 
 private slots:
     void resizeColumnsToContents();
@@ -62,7 +62,6 @@ private:
     void mouseDoubleClickEvent(QMouseEvent *ev);
 
     void deleteBreakpoints(const QModelIndexList &list);
-    void deleteBreakpoints(QList<int> rows);
     void addBreakpoint();
     void editBreakpoints(const QModelIndexList &list);
     void associateBreakpoint(const QModelIndexList &list, int thread);
diff --git a/src/plugins/debugger/cdb/cdbengine.cpp b/src/plugins/debugger/cdb/cdbengine.cpp
index a25143062878648dfca5391ed456e7fefbf35db4..e70b0b2a6ba76149bf2edd30684a08a27455a43d 100644
--- a/src/plugins/debugger/cdb/cdbengine.cpp
+++ b/src/plugins/debugger/cdb/cdbengine.cpp
@@ -183,7 +183,7 @@ DebuggerEngine *CdbEngine::create(const DebuggerStartParameters &sp,
 
 void  CdbEnginePrivate::updateCodeLevel()
 {
-    const CdbCore::CoreEngine::CodeLevel cl = theDebuggerBoolSetting(OperateByInstruction) ?
+    const CdbCore::CoreEngine::CodeLevel cl = debuggerCore()->boolSetting(OperateByInstruction) ?
                                               CdbCore::CoreEngine::CodeLevelAssembly : CdbCore::CoreEngine::CodeLevelSource;
     setCodeLevel(cl);
 }
@@ -1174,7 +1174,7 @@ void CdbEngine::activateFrame(int frameIndex)
         if (showAssembler) { // Assembly code: Clean out model and force instruction mode.
             watchHandler()->beginCycle();
             watchHandler()->endCycle();
-            QAction *assemblerAction = theDebuggerAction(OperateByInstruction);
+            QAction *assemblerAction = debuggerCore()->action(OperateByInstruction);
             if (!assemblerAction->isChecked())
                 assemblerAction->trigger();
             success = true;
diff --git a/src/plugins/debugger/cdb/cdbstackframecontext.cpp b/src/plugins/debugger/cdb/cdbstackframecontext.cpp
index 963aba5623fa775dca3d13fdeee20d66321c3c77..c55eddf4ff0ded2c90cb4878b684cdd8a721ab1a 100644
--- a/src/plugins/debugger/cdb/cdbstackframecontext.cpp
+++ b/src/plugins/debugger/cdb/cdbstackframecontext.cpp
@@ -294,7 +294,7 @@ WatchHandleDumperInserter &WatchHandleDumperInserter::operator=(WatchData &wd)
 // -----------CdbStackFrameContext
 CdbStackFrameContext::CdbStackFrameContext(const QSharedPointer<CdbDumperHelper> &dumper,
                                            CdbSymbolGroupContext *symbolContext) :
-        m_useDumpers(dumper->isEnabled() && theDebuggerBoolSetting(UseDebuggingHelpers)),
+        m_useDumpers(dumper->isEnabled() && debuggerCore()->boolSetting(UseDebuggingHelpers)),
         m_dumper(dumper),
         m_symbolContext(symbolContext)
 {
diff --git a/src/plugins/debugger/cdb/cdbstacktracecontext.cpp b/src/plugins/debugger/cdb/cdbstacktracecontext.cpp
index fb826f8897423d10b6c04244cf21de1f3410d63f..bb130141cbfd25019337c098fb39d4644746fb09 100644
--- a/src/plugins/debugger/cdb/cdbstacktracecontext.cpp
+++ b/src/plugins/debugger/cdb/cdbstacktracecontext.cpp
@@ -73,7 +73,7 @@ CdbStackTraceContext::createSymbolGroup(const CdbCore::ComInterfaces & /* cif */
     // Exclude uninitialized variables if desired
     QStringList uninitializedVariables;
     const CdbCore::StackFrame &frame = stackFrameAt(index);
-    if (theDebuggerAction(UseCodeModel)->isChecked())
+    if (debuggerCore()->action(UseCodeModel)->isChecked())
         getUninitializedVariables(debuggerCore()->cppCodeModelSnapshot(),
             frame.function, frame.fileName, frame.line, &uninitializedVariables);
     if (debug)
diff --git a/src/plugins/debugger/cdb/cdbsymbolgroupcontext.cpp b/src/plugins/debugger/cdb/cdbsymbolgroupcontext.cpp
index 9cd8f6903cf4aacb25b77cfb8d88c77d92117f38..0d6923555ed5beef91d43dec52e22dd6450dd4be 100644
--- a/src/plugins/debugger/cdb/cdbsymbolgroupcontext.cpp
+++ b/src/plugins/debugger/cdb/cdbsymbolgroupcontext.cpp
@@ -319,7 +319,7 @@ CdbSymbolGroupContext::CdbSymbolGroupContext(const QString &prefix,
     CdbCore::SymbolGroupContext(prefix, symbolGroup,
                                 dumper->comInterfaces()->debugDataSpaces,
                                 uninitializedVariables),
-    m_useDumpers(dumper->isEnabled() && theDebuggerBoolSetting(UseDebuggingHelpers)),
+    m_useDumpers(dumper->isEnabled() && debuggerCore()->boolSetting(UseDebuggingHelpers)),
     m_dumper(dumper)
 {
     setShadowedNameFormat(WatchData::shadowedNameFormat());
diff --git a/src/plugins/debugger/consolewindow.cpp b/src/plugins/debugger/consolewindow.cpp
index bb904ea58d797aa39c523ce35cfd71071ffb679c..eecb3aa7696c4f97f26d11f9da3c50058cc9e519 100644
--- a/src/plugins/debugger/consolewindow.cpp
+++ b/src/plugins/debugger/consolewindow.cpp
@@ -31,7 +31,7 @@
 #include "logwindow.h"
 
 #include "debuggeractions.h"
-#include "debuggerconstants.h"
+#include "debuggercore.h"
 
 #include <QtCore/QDebug>
 
@@ -188,15 +188,15 @@ public:
 
     void contextMenuEvent(QContextMenuEvent *ev)
     {
-        theDebuggerAction(ExecuteCommand)->setData(textCursor().block().text());
+        debuggerCore()->action(ExecuteCommand)->setData(textCursor().block().text());
         QMenu *menu = createStandardContextMenu();
         menu->addAction(m_clearContentsAction);
         menu->addAction(m_saveContentsAction); // X11 clipboard is unreliable for long texts
-        menu->addAction(theDebuggerAction(ExecuteCommand));
-        menu->addAction(theDebuggerAction(LogTimeStamps));
-        menu->addAction(theDebuggerAction(VerboseLog));
+        menu->addAction(debuggerCore()->action(ExecuteCommand));
+        menu->addAction(debuggerCore()->action(LogTimeStamps));
+        menu->addAction(debuggerCore()->action(VerboseLog));
         menu->addSeparator();
-        menu->addAction(theDebuggerAction(SettingsDialog));
+        menu->addAction(debuggerCore()->action(SettingsDialog));
         menu->exec(ev->globalPos());
         delete menu;
     }
@@ -213,7 +213,7 @@ public:
                     if (c.unicode() >= 32 && c.unicode() < 128)
                         cleanCmd.append(c);
                 if (!cleanCmd.isEmpty()) {
-                    theDebuggerAction(ExecuteCommand)->trigger(cleanCmd);
+                    debuggerCore()->action(ExecuteCommand)->trigger(cleanCmd);
                     m_history.append(cleanCmd);
                 }
             }
diff --git a/src/plugins/debugger/debuggeractions.cpp b/src/plugins/debugger/debuggeractions.cpp
index 741ff24389c8f6b5e6a454f9d4e3cbdec63f2490..e0bf9870546990b80f20864aa33801d28c324b0e 100644
--- a/src/plugins/debugger/debuggeractions.cpp
+++ b/src/plugins/debugger/debuggeractions.cpp
@@ -52,8 +52,6 @@
 using namespace Utils;
 
 static const char debugModeSettingsGroupC[] = "DebugMode";
-static const char gdbBinariesSettingsGroupC[] = "GdbBinaries";
-static const char debugModeGdbBinaryKeyC[] = "GdbBinary";
 
 namespace Debugger {
 namespace Internal {
@@ -64,217 +62,59 @@ namespace Internal {
 //
 //////////////////////////////////////////////////////////////////////////
 
-DebuggerSettings::DebuggerSettings(QObject *parent)
-    : QObject(parent), m_gdbBinariesChanged(false)
-{}
-
-DebuggerSettings::~DebuggerSettings()
-{
-    qDeleteAll(m_items);
-}
-
-DebuggerSettings::GdbBinaryToolChainMap DebuggerSettings::gdbBinaryToolChainMap() const
-{
-    return m_gdbBinaryToolChainMap;
-}
-
-void DebuggerSettings::setGdbBinaryToolChainMap(const GdbBinaryToolChainMap &map)
-{
-    m_gdbBinaryToolChainMap = map;
-    m_gdbBinariesChanged = true;
-}
-
-void DebuggerSettings::insertItem(int code, SavedAction *item)
-{
-    QTC_ASSERT(!m_items.contains(code),
-        qDebug() << code << item->toString(); return);
-    QTC_ASSERT(item->settingsKey().isEmpty() || item->defaultValue().isValid(),
-        qDebug() << "NO DEFAULT VALUE FOR " << item->settingsKey());
-    m_items[code] = item;
-}
-
-void DebuggerSettings::readSettings(const QSettings *settings)
-{
-     foreach (SavedAction *item, m_items)
-         item->readSettings(settings);
-    readGdbBinarySettings(settings);
-}
-
-void DebuggerSettings::writeSettings(QSettings *settings) const
-{
-    foreach (SavedAction *item, m_items)
-        item->writeSettings(settings);
-    if (m_gdbBinariesChanged)
-        writeGdbBinarySettings(settings);
-}
-
-void DebuggerSettings::readGdbBinarySettings(const QSettings *settings)
-{
-    // Convert gdb binaries from flat settings list (see writeSettings)
-    // into map ("binary1=gdb,1,2", "binary2=symbian_gdb,3,4").
-    m_gdbBinaryToolChainMap.clear();
-    const QChar separator = QLatin1Char(',');
-    const QString keyRoot = QLatin1String(gdbBinariesSettingsGroupC) + QLatin1Char('/') +
-                            QLatin1String(debugModeGdbBinaryKeyC);
-    for (int i = 1; ; i++) {
-        const QString value = settings->value(keyRoot + QString::number(i)).toString();
-        if (value.isEmpty())
-            break;
-        // Split apart comma-separated binary and its numerical toolchains.
-        QStringList tokens = value.split(separator);
-        if (tokens.size() < 2)
-            break;
-        const QString binary = tokens.front();
-        // Skip non-existent absolute binaries allowing for upgrades by the installer.
-        // Force a rewrite of the settings file.
-        const QFileInfo binaryInfo(binary);
-        if (binaryInfo.isAbsolute() && !binaryInfo.isExecutable()) {
-            m_gdbBinariesChanged = true;
-            const QString msg = QString::fromLatin1("Warning: The gdb binary '%1' does not exist, skipping.\n").arg(binary);
-            qWarning("%s", qPrintable(msg));
-            continue;
-        }
-        // Create entries for all toolchains.
-        tokens.pop_front();
-        foreach(const QString &t, tokens) {
-            // Paranoia: Check if the there is already a binary configured for the toolchain.
-            const int toolChain = t.toInt();
-            const QString predefinedGdb = m_gdbBinaryToolChainMap.key(toolChain);
-            if (predefinedGdb.isEmpty()) {
-                m_gdbBinaryToolChainMap.insert(binary, toolChain);
-            } else {
-                const QString toolChainName = ProjectExplorer::ToolChain::toolChainName(static_cast<ProjectExplorer::ToolChainType>(toolChain));
-                const QString msg =
-                        QString::fromLatin1("An inconsistency has been encountered in the Ini-file '%1':\n"
-                                            "Skipping gdb binary '%2' for toolchain '%3' as '%4' is already configured for it.").
-                        arg(settings->fileName(), binary, toolChainName, predefinedGdb);
-                qWarning("%s", qPrintable(msg));
-            }
-        }
-    }
-    // Linux defaults
-#ifdef Q_OS_UNIX
-    if (m_gdbBinaryToolChainMap.isEmpty()) {
-        const QString gdb = QLatin1String("gdb");
-        m_gdbBinaryToolChainMap.insert(gdb, ProjectExplorer::ToolChain_GCC);
-        m_gdbBinaryToolChainMap.insert(gdb, ProjectExplorer::ToolChain_LINUX_ICC);
-        m_gdbBinaryToolChainMap.insert(gdb, ProjectExplorer::ToolChain_OTHER);
-        m_gdbBinaryToolChainMap.insert(gdb, ProjectExplorer::ToolChain_UNKNOWN);
-    }
-#endif
-}
-
-void DebuggerSettings::writeGdbBinarySettings(QSettings *settings) const
+DebuggerSettings::DebuggerSettings(QSettings *settings)
 {
-    // Convert gdb binaries map into a flat settings list of
-    // ("binary1=gdb,1,2", "binary2=symbian_gdb,3,4"). It needs to be ASCII for installers
-    QString lastBinary;
-    QStringList settingsList;
-    const QChar separator = QLatin1Char(',');
-    const GdbBinaryToolChainMap::const_iterator cend = m_gdbBinaryToolChainMap.constEnd();
-    for (GdbBinaryToolChainMap::const_iterator it = m_gdbBinaryToolChainMap.constBegin(); it != cend; ++it) {
-        if (it.key() != lastBinary) {
-            lastBinary = it.key(); // Start new entry with first toolchain
-            settingsList.push_back(lastBinary);
-        }
-        settingsList.back().append(separator); // Append toolchain to last binary
-        settingsList.back().append(QString::number(it.value()));
-    }
-    // Terminate settings list by an empty element such that consecutive keys resulting
-    // from ini-file merging are suppressed while reading.
-    settingsList.push_back(QString());
-    // Write out list
-    settings->beginGroup(QLatin1String(gdbBinariesSettingsGroupC));
-    settings->remove(QString()); // remove all keys in group.
-    const int count = settingsList.size();
-    const QString keyRoot = QLatin1String(debugModeGdbBinaryKeyC);
-    for (int i = 0; i < count; i++)
-        settings->setValue(keyRoot + QString::number(i + 1), settingsList.at(i));
-    settings->endGroup();
-}
-
-SavedAction *DebuggerSettings::item(int code) const
-{
-    QTC_ASSERT(m_items.value(code, 0), qDebug() << "CODE: " << code; return 0);
-    return m_items.value(code, 0);
-}
-
-QString DebuggerSettings::dump() const
-{
-    QString out;
-    QTextStream ts(&out);
-    ts << "Debugger settings: ";
-    foreach (SavedAction *item, m_items) {
-        QString key = item->settingsKey();
-        if (!key.isEmpty()) {
-            const QString current = item->value().toString();
-            const QString default_ = item->defaultValue().toString();
-            ts << '\n' << key << ": " << current 
-               << "  (default: " << default_ << ")";
-            if (current != default_)
-                ts <<  "  ***";
-        }
-    }
-    return out;
-}
-
-DebuggerSettings *DebuggerSettings::instance()
-{
-    static DebuggerSettings *instance = 0;
-    if (instance)
-        return instance;
-
+    m_settings = settings;
     const QString debugModeGroup = QLatin1String(debugModeSettingsGroupC);
-    instance = new DebuggerSettings;
 
     SavedAction *item = 0;
 
-    item = new SavedAction(instance);
-    instance->insertItem(SettingsDialog, item);
+    item = new SavedAction(this);
+    insertItem(SettingsDialog, item);
     item->setText(tr("Debugger Properties..."));
 
     //
     // View
     //
-    item = new SavedAction(instance);
+    item = new SavedAction(this);
     item->setText(tr("Adjust Column Widths to Contents"));
-    instance->insertItem(AdjustColumnWidths, item);
+    insertItem(AdjustColumnWidths, item);
 
-    item = new SavedAction(instance);
+    item = new SavedAction(this);
     item->setText(tr("Always Adjust Column Widths to Contents"));
     item->setCheckable(true);
-    instance->insertItem(AlwaysAdjustColumnWidths, item);
+    insertItem(AlwaysAdjustColumnWidths, item);
 
-    item = new SavedAction(instance);
+    item = new SavedAction(this);
     item->setText(tr("Use Alternating Row Colors"));
     item->setSettingsKey(debugModeGroup, QLatin1String("UseAlternatingRowColours"));
     item->setCheckable(true);
     item->setDefaultValue(false);
-    instance->insertItem(UseAlternatingRowColors, item);
+    insertItem(UseAlternatingRowColors, item);
 
-    item = new SavedAction(instance);
+    item = new SavedAction(this);
     item->setText(tr("Show a Message Box When Receiving a Signal"));
     item->setSettingsKey(debugModeGroup, QLatin1String("UseMessageBoxForSignals"));
     item->setCheckable(true);
     item->setDefaultValue(true);
     item->setValue(true);
-    instance->insertItem(UseMessageBoxForSignals, item);
+    insertItem(UseMessageBoxForSignals, item);
 
-    item = new SavedAction(instance);
+    item = new SavedAction(this);
     item->setText(tr("Log Time Stamps"));
     item->setSettingsKey(debugModeGroup, QLatin1String("LogTimeStamps"));
     item->setCheckable(true);
     item->setDefaultValue(false);
-    instance->insertItem(LogTimeStamps, item);
+    insertItem(LogTimeStamps, item);
 
-    item = new SavedAction(instance);
+    item = new SavedAction(this);
     item->setText(tr("Verbose Log"));
     item->setSettingsKey(debugModeGroup, QLatin1String("VerboseLog"));
     item->setCheckable(true);
     item->setDefaultValue(false);
-    instance->insertItem(VerboseLog, item);
+    insertItem(VerboseLog, item);
 
-    item = new SavedAction(instance);
+    item = new SavedAction(this);
     item->setText(tr("Operate by Instruction"));
     item->setCheckable(true);
     item->setDefaultValue(false);
@@ -284,9 +124,9 @@ DebuggerSettings *DebuggerSettings::instance()
         "instructions and the source location view also shows the "
         "disassembled instructions."));
     item->setIconVisibleInMenu(false);
-    instance->insertItem(OperateByInstruction, item);
+    insertItem(OperateByInstruction, item);
 
-    item = new SavedAction(instance);
+    item = new SavedAction(this);
     item->setText(tr("Dereference Pointers Automatically"));
     item->setCheckable(true);
     item->setDefaultValue(true);
@@ -295,69 +135,69 @@ DebuggerSettings *DebuggerSettings::instance()
         "automatically dereference pointers. This saves a level in the "
         "tree view, but also loses data for the now-missing intermediate "
         "level."));
-    instance->insertItem(AutoDerefPointers, item);
+    insertItem(AutoDerefPointers, item);
 
     //
     // Locals & Watchers
     //
-    item = new SavedAction(instance);
+    item = new SavedAction(this);
     item->setSettingsKey(debugModeGroup, QLatin1String("ShowStandardNamespace"));
     item->setText(tr("Show \"std::\" Namespace in Types"));
     item->setCheckable(true);
     item->setDefaultValue(true);
     item->setValue(true);
-    instance->insertItem(ShowStdNamespace, item);
+    insertItem(ShowStdNamespace, item);
 
-    item = new SavedAction(instance);
+    item = new SavedAction(this);
     item->setSettingsKey(debugModeGroup, QLatin1String("ShowQtNamespace"));
     item->setText(tr("Show Qt's Namespace in Types"));
     item->setCheckable(true);
     item->setDefaultValue(true);
     item->setValue(true);
-    instance->insertItem(ShowQtNamespace, item);
+    insertItem(ShowQtNamespace, item);
 
-    item = new SavedAction(instance);
+    item = new SavedAction(this);
     item->setSettingsKey(debugModeGroup, QLatin1String("SortStructMembers"));
     item->setText(tr("Sort Members of Classes and Structs Alphabetically"));
     item->setCheckable(true);
     item->setDefaultValue(true);
     item->setValue(true);
-    instance->insertItem(SortStructMembers, item);
+    insertItem(SortStructMembers, item);
 
     //
     // DebuggingHelper
     //
-    item = new SavedAction(instance);
+    item = new SavedAction(this);
     item->setSettingsKey(debugModeGroup, QLatin1String("UseDebuggingHelper"));
     item->setText(tr("Use Debugging Helpers"));
     item->setCheckable(true);
     item->setDefaultValue(true);
     item->setValue(true);
-    instance->insertItem(UseDebuggingHelpers, item);
+    insertItem(UseDebuggingHelpers, item);
 
-    item = new SavedAction(instance);
+    item = new SavedAction(this);
     item->setSettingsKey(debugModeGroup, QLatin1String("UseCustomDebuggingHelperLocation"));
     item->setCheckable(true);
     item->setDefaultValue(false);
     item->setValue(false);
-    instance->insertItem(UseCustomDebuggingHelperLocation, item);
+    insertItem(UseCustomDebuggingHelperLocation, item);
 
-    item = new SavedAction(instance);
+    item = new SavedAction(this);
     item->setSettingsKey(debugModeGroup, QLatin1String("CustomDebuggingHelperLocation"));
     item->setCheckable(true);
     item->setDefaultValue(QString());
     item->setValue(QString());
-    instance->insertItem(CustomDebuggingHelperLocation, item);
+    insertItem(CustomDebuggingHelperLocation, item);
 
-    item = new SavedAction(instance);
+    item = new SavedAction(this);
     item->setSettingsKey(debugModeGroup, QLatin1String("DebugDebuggingHelpers"));
     item->setText(tr("Debug Debugging Helpers"));
     item->setCheckable(true);
     item->setDefaultValue(false);
     item->setValue(false);
-    instance->insertItem(DebugDebuggingHelpers, item);
+    insertItem(DebugDebuggingHelpers, item);
 
-    item = new SavedAction(instance);
+    item = new SavedAction(this);
     item->setSettingsKey(debugModeGroup, QLatin1String("UseCodeModel"));
     item->setText(tr("Use Code Model"));
     item->setToolTip(tr("Selecting this causes the C++ Code Model being asked "
@@ -366,17 +206,17 @@ DebuggerSettings *DebuggerSettings::instance()
     item->setCheckable(true);
     item->setDefaultValue(true);
     item->setValue(true);
-    instance->insertItem(UseCodeModel, item);
+    insertItem(UseCodeModel, item);
 
 
     //
     // Breakpoints
     //
-    item = new SavedAction(instance);
+    item = new SavedAction(this);
     item->setText(tr("Synchronize Breakpoints"));
-    instance->insertItem(SynchronizeBreakpoints, item);
+    insertItem(SynchronizeBreakpoints, item);
 
-    item = new SavedAction(instance);
+    item = new SavedAction(this);
     item->setText(tr("Adjust Breakpoint Locations"));
     item->setToolTip(tr("Not all source code lines generate "
       "executable code. Putting a breakpoint on such a line acts as "
@@ -388,58 +228,58 @@ DebuggerSettings *DebuggerSettings::instance()
     item->setDefaultValue(true);
     item->setValue(true);
     item->setSettingsKey(debugModeGroup, QLatin1String("AdjustBreakpointLocations"));
-    instance->insertItem(AdjustBreakpointLocations, item);
+    insertItem(AdjustBreakpointLocations, item);
 
-    item = new SavedAction(instance);
+    item = new SavedAction(this);
     item->setText(tr("Break on \"throw\""));
     item->setCheckable(true);
     item->setDefaultValue(false);
     item->setValue(false);
     item->setSettingsKey(debugModeGroup, QLatin1String("BreakOnThrow"));
-    instance->insertItem(BreakOnThrow, item);
+    insertItem(BreakOnThrow, item);
 
-    item = new SavedAction(instance);
+    item = new SavedAction(this);
     item->setText(tr("Break on \"catch\""));
     item->setCheckable(true);
     item->setDefaultValue(false);
     item->setValue(false);
     item->setSettingsKey(debugModeGroup, QLatin1String("BreakOnCatch"));
-    instance->insertItem(BreakOnCatch, item);
+    insertItem(BreakOnCatch, item);
 
     //
     // Settings
     //
 
-    item = new SavedAction(instance);
+    item = new SavedAction(this);
     item->setSettingsKey(debugModeGroup, QLatin1String("Environment"));
     item->setDefaultValue(QString());
-    instance->insertItem(GdbEnvironment, item);
+    insertItem(GdbEnvironment, item);
 
-    item = new SavedAction(instance);
+    item = new SavedAction(this);
     item->setSettingsKey(debugModeGroup, QLatin1String("ScriptFile"));
     item->setDefaultValue(QString());
-    instance->insertItem(GdbScriptFile, item);
+    insertItem(GdbScriptFile, item);
 
-    item = new SavedAction(instance);
+    item = new SavedAction(this);
     item->setSettingsKey(debugModeGroup, QLatin1String("CloseBuffersOnExit"));
     item->setCheckable(true);
     item->setDefaultValue(false);
-    instance->insertItem(CloseBuffersOnExit, item);
+    insertItem(CloseBuffersOnExit, item);
 
-    item = new SavedAction(instance);
+    item = new SavedAction(this);
     item->setSettingsKey(debugModeGroup, QLatin1String("SwitchModeOnExit"));
     item->setCheckable(true);
     item->setDefaultValue(false);
-    instance->insertItem(SwitchModeOnExit, item);
+    insertItem(SwitchModeOnExit, item);
 
-    item = new SavedAction(instance);
+    item = new SavedAction(this);
     item->setSettingsKey(debugModeGroup, QLatin1String("AutoQuit"));
     item->setText(tr("Automatically Quit Debugger"));
     item->setCheckable(true);
     item->setDefaultValue(false);
-    instance->insertItem(AutoQuit, item);
+    insertItem(AutoQuit, item);
 
-    item = new SavedAction(instance);
+    item = new SavedAction(this);
     item->setSettingsKey(debugModeGroup, QLatin1String("UseToolTips"));
     item->setText(tr("Use tooltips in main editor when debugging"));
     item->setToolTip(tr("Checking this will enable tooltips for variable "
@@ -448,52 +288,52 @@ DebuggerSettings *DebuggerSettings::instance()
         "information, it is switched off by default."));
     item->setCheckable(true);
     item->setDefaultValue(false);
-    instance->insertItem(UseToolTipsInMainEditor, item);
+    insertItem(UseToolTipsInMainEditor, item);
 
-    item = new SavedAction(instance);
+    item = new SavedAction(this);
     item->setSettingsKey(debugModeGroup, QLatin1String("UseToolTipsInLocalsView"));
     item->setText(tr("Use Tooltips in Locals View When Debugging"));
     item->setToolTip(tr("Checking this will enable tooltips in the locals "
         "view during debugging."));
     item->setCheckable(true);
     item->setDefaultValue(false);
-    instance->insertItem(UseToolTipsInLocalsView, item);
+    insertItem(UseToolTipsInLocalsView, item);
 
-    item = new SavedAction(instance);
+    item = new SavedAction(this);
     item->setSettingsKey(debugModeGroup, QLatin1String("UseToolTipsInBreakpointsView"));
     item->setText(tr("Use Tooltips in Breakpoints View When Debugging"));
     item->setToolTip(tr("Checking this will enable tooltips in the breakpoints "
         "view during debugging."));
     item->setCheckable(true);
     item->setDefaultValue(false);
-    instance->insertItem(UseToolTipsInBreakpointsView, item);
+    insertItem(UseToolTipsInBreakpointsView, item);
 
-    item = new SavedAction(instance);
+    item = new SavedAction(this);
     item->setSettingsKey(debugModeGroup, QLatin1String("UseAddressInBreakpointsView"));
     item->setText(tr("Show Address Data in Breakpoints View When Debugging"));
     item->setToolTip(tr("Checking this will show a column with address "
         "information in the breakpoint view during debugging."));
     item->setCheckable(true);
     item->setDefaultValue(false);
-    instance->insertItem(UseAddressInBreakpointsView, item);
+    insertItem(UseAddressInBreakpointsView, item);
 
-    item = new SavedAction(instance);
+    item = new SavedAction(this);
     item->setSettingsKey(debugModeGroup, QLatin1String("UseAddressInStackView"));
     item->setText(tr("Show Address Data in Stack View When Debugging"));
     item->setToolTip(tr("Checking this will show a column with address "
         "information in the stack view during debugging."));
     item->setCheckable(true);
     item->setDefaultValue(false);
-    instance->insertItem(UseAddressInStackView, item);
-    item = new SavedAction(instance);
+    insertItem(UseAddressInStackView, item);
+    item = new SavedAction(this);
 
     item->setSettingsKey(debugModeGroup, QLatin1String("ListSourceFiles"));
     item->setText(tr("List Source Files"));
     item->setCheckable(true);
     item->setDefaultValue(false);
-    instance->insertItem(ListSourceFiles, item);
+    insertItem(ListSourceFiles, item);
 
-    item = new SavedAction(instance);
+    item = new SavedAction(this);
     item->setSettingsKey(debugModeGroup, QLatin1String("SkipKnownFrames"));
     item->setText(tr("Skip Known Frames"));
     item->setToolTip(tr("Selecting this results in well-known but usually "
@@ -501,89 +341,117 @@ DebuggerSettings *DebuggerSettings::instance()
       "signal emission being skipped while single-stepping."));
     item->setCheckable(true);
     item->setDefaultValue(false);
-    instance->insertItem(SkipKnownFrames, item);
+    insertItem(SkipKnownFrames, item);
 
-    item = new SavedAction(instance);
+    item = new SavedAction(this);
     item->setSettingsKey(debugModeGroup, QLatin1String("EnableReverseDebugging"));
     item->setText(tr("Enable Reverse Debugging"));
     item->setCheckable(true);
     item->setDefaultValue(false);
-    instance->insertItem(EnableReverseDebugging, item);
+    insertItem(EnableReverseDebugging, item);
 
 #ifdef Q_OS_WIN
-    item = new RegisterPostMortemAction(instance);
+    item = new RegisterPostMortemAction(this);
     item->setSettingsKey(debugModeGroup, QLatin1String("RegisterForPostMortem"));
     item->setText(tr("Register For Post-Mortem Debugging"));
     item->setCheckable(true);
     item->setDefaultValue(false);
-    instance->insertItem(RegisterForPostMortem, item);
+    insertItem(RegisterForPostMortem, item);
 #endif
 
-    item = new SavedAction(instance);
+    item = new SavedAction(this);
     item->setSettingsKey(debugModeGroup, QLatin1String("AllPluginBreakpoints"));
     item->setDefaultValue(true);
-    instance->insertItem(AllPluginBreakpoints, item);
+    insertItem(AllPluginBreakpoints, item);
 
-    item = new SavedAction(instance);
+    item = new SavedAction(this);
     item->setSettingsKey(debugModeGroup, QLatin1String("SelectedPluginBreakpoints"));
     item->setDefaultValue(false);
-    instance->insertItem(SelectedPluginBreakpoints, item);
+    insertItem(SelectedPluginBreakpoints, item);
 
-    item = new SavedAction(instance);
+    item = new SavedAction(this);
     item->setSettingsKey(debugModeGroup, QLatin1String("NoPluginBreakpoints"));
     item->setDefaultValue(false);
-    instance->insertItem(NoPluginBreakpoints, item);
+    insertItem(NoPluginBreakpoints, item);
 
-    item = new SavedAction(instance);
+    item = new SavedAction(this);
     item->setSettingsKey(debugModeGroup, QLatin1String("SelectedPluginBreakpointsPattern"));
     item->setDefaultValue(QLatin1String(".*"));
-    instance->insertItem(SelectedPluginBreakpointsPattern, item);
+    insertItem(SelectedPluginBreakpointsPattern, item);
 
-    item = new SavedAction(instance);
+    item = new SavedAction(this);
     item->setSettingsKey(debugModeGroup, QLatin1String("MaximalStackDepth"));
     item->setDefaultValue(20);
-    instance->insertItem(MaximalStackDepth, item);
+    insertItem(MaximalStackDepth, item);
 
-    item = new SavedAction(instance);
+    item = new SavedAction(this);
     item->setText(tr("Reload Full Stack"));
-    instance->insertItem(ExpandStack, item);
+    insertItem(ExpandStack, item);
 
-    item = new SavedAction(instance);
+    item = new SavedAction(this);
     item->setText(tr("Create Full Backtrace"));
-    instance->insertItem(CreateFullBacktrace, item);
+    insertItem(CreateFullBacktrace, item);
 
-    item = new SavedAction(instance);
+    item = new SavedAction(this);
     item->setText(tr("Execute Line"));
-    instance->insertItem(ExecuteCommand, item);
+    insertItem(ExecuteCommand, item);
 
-    item = new SavedAction(instance);
+    item = new SavedAction(this);
     item->setSettingsKey(debugModeGroup, QLatin1String("WatchdogTimeout"));
     item->setDefaultValue(20);
-    instance->insertItem(GdbWatchdogTimeout, item);
+    insertItem(GdbWatchdogTimeout, item);
+}
 
-    return instance;
+
+DebuggerSettings::~DebuggerSettings()
+{
+    qDeleteAll(m_items);
 }
 
+void DebuggerSettings::insertItem(int code, SavedAction *item)
+{
+    QTC_ASSERT(!m_items.contains(code),
+        qDebug() << code << item->toString(); return);
+    QTC_ASSERT(item->settingsKey().isEmpty() || item->defaultValue().isValid(),
+        qDebug() << "NO DEFAULT VALUE FOR " << item->settingsKey());
+    m_items[code] = item;
+}
 
-//////////////////////////////////////////////////////////////////////////
-//
-// DebuggerActions
-//
-//////////////////////////////////////////////////////////////////////////
+void DebuggerSettings::readSettings()
+{
+    foreach (SavedAction *item, m_items)
+        item->readSettings(m_settings);
+}
 
-SavedAction *theDebuggerAction(int code)
+void DebuggerSettings::writeSettings() const
 {
-    return DebuggerSettings::instance()->item(code);
+    foreach (SavedAction *item, m_items)
+        item->writeSettings(m_settings);
 }
 
-bool theDebuggerBoolSetting(int code)
+SavedAction *DebuggerSettings::item(int code) const
 {
-    return DebuggerSettings::instance()->item(code)->value().toBool();
+    QTC_ASSERT(m_items.value(code, 0), qDebug() << "CODE: " << code; return 0);
+    return m_items.value(code, 0);
 }
 
-QString theDebuggerStringSetting(int code)
+QString DebuggerSettings::dump() const
 {
-    return DebuggerSettings::instance()->item(code)->value().toString();
+    QString out;
+    QTextStream ts(&out);
+    ts << "Debugger settings: ";
+    foreach (SavedAction *item, m_items) {
+        QString key = item->settingsKey();
+        if (!key.isEmpty()) {
+            const QString current = item->value().toString();
+            const QString default_ = item->defaultValue().toString();
+            ts << '\n' << key << ": " << current 
+               << "  (default: " << default_ << ")";
+            if (current != default_)
+                ts <<  "  ***";
+        }
+    }
+    return out;
 }
 
 } // namespace Internal
diff --git a/src/plugins/debugger/debuggeractions.h b/src/plugins/debugger/debuggeractions.h
index 1b8a99fb50b7bb8e9ef3324368f5558ad0e1daeb..22ea568845d4d5d083364c0ed39759cec88bb5ec 100644
--- a/src/plugins/debugger/debuggeractions.h
+++ b/src/plugins/debugger/debuggeractions.h
@@ -34,8 +34,6 @@
 #include <QtCore/QMap>
 
 QT_BEGIN_NAMESPACE
-class QAction;
-class QActionGroup;
 class QSettings;
 QT_END_NAMESPACE
 
@@ -48,34 +46,22 @@ namespace Internal {
 
 class DebuggerSettings : public QObject
 {
-    Q_OBJECT
+    Q_OBJECT // For tr().
 public:
-    typedef QMultiMap<QString, int> GdbBinaryToolChainMap;
-
-    explicit DebuggerSettings(QObject *parent = 0);
+    explicit DebuggerSettings(QSettings *setting);
     ~DebuggerSettings();
 
-    GdbBinaryToolChainMap gdbBinaryToolChainMap() const;
-    void setGdbBinaryToolChainMap(const GdbBinaryToolChainMap &map);
-
     void insertItem(int code, Utils::SavedAction *item);
     Utils::SavedAction *item(int code) const;
 
     QString dump() const;
 
-    static DebuggerSettings *instance();
-
-public slots:
-    void readSettings(const QSettings *settings);
-    void writeSettings(QSettings *settings) const;
+    void readSettings();
+    void writeSettings() const;
 
 private:
-    void readGdbBinarySettings(const QSettings *settings);
-    void writeGdbBinarySettings(QSettings *settings) const;
-
     QHash<int, Utils::SavedAction *> m_items;
-    GdbBinaryToolChainMap m_gdbBinaryToolChainMap;
-    bool m_gdbBinariesChanged;
+    QSettings *m_settings;
 };
 
 ///////////////////////////////////////////////////////////
@@ -147,13 +133,6 @@ enum DebuggerActionCode
     BreakOnCatch
 };
 
-// singleton access
-Utils::SavedAction *theDebuggerAction(int code);
-
-// convenience
-bool theDebuggerBoolSetting(int code);
-QString theDebuggerStringSetting(int code);
-
 } // namespace Internal
 } // namespace Debugger
 
diff --git a/src/plugins/debugger/debuggeragents.cpp b/src/plugins/debugger/debuggeragents.cpp
index bd5161afa614f105ca0e57ee47e5ed0d91d04a80..6a9be5d98ba155a2edc77d5167904d77ef575b70 100644
--- a/src/plugins/debugger/debuggeragents.cpp
+++ b/src/plugins/debugger/debuggeragents.cpp
@@ -134,7 +134,7 @@ void MemoryViewAgent::createBinEditor(quint64 addr)
         QMetaObject::invokeMethod(editor->widget(), "setLazyData",
             Q_ARG(quint64, addr), Q_ARG(int, DataRange), Q_ARG(int, BinBlockSize));
     } else {
-        DebuggerEngine::showMessageBox(QMessageBox::Warning,
+        showMessageBox(QMessageBox::Warning,
             tr("No memory viewer available"),
             tr("The memory contents cannot be shown as no viewer plugin "
                "for binary data has been loaded."));
diff --git a/src/plugins/debugger/debuggercore.h b/src/plugins/debugger/debuggercore.h
index a8acfe0f0dd0cc2ee332bae5bfdf455d894c13cb..3b8bc2eeb951e4baff19e6de24e26d1caeb4b0a0 100644
--- a/src/plugins/debugger/debuggercore.h
+++ b/src/plugins/debugger/debuggercore.h
@@ -34,6 +34,7 @@
 #include "debuggerconstants.h"
 
 #include <QtCore/QObject>
+#include <QtCore/QMultiMap>
 
 QT_BEGIN_NAMESPACE
 class QIcon;
@@ -45,6 +46,10 @@ namespace CPlusPlus {
 class Snapshot;
 }
 
+namespace Utils {
+class SavedAction;
+}
+
 namespace Debugger {
 
 class DebuggerEngine;
@@ -78,8 +83,8 @@ public:
     virtual bool isRegisterViewVisible() const = 0;
     virtual bool hasSnapshots() const = 0;
     virtual void openTextEditor(const QString &titlePattern, const QString &contents) = 0;
-    virtual Internal::BreakHandler *breakHandler() const = 0;
-    virtual Internal::SnapshotHandler *snapshotHandler() const = 0;
+    virtual BreakHandler *breakHandler() const = 0;
+    virtual SnapshotHandler *snapshotHandler() const = 0;
     virtual DebuggerEngine *currentEngine() const = 0;
     virtual bool isActiveDebugLanguage(int language) const = 0;
 
@@ -103,16 +108,22 @@ public:
     virtual void runControlFinished(DebuggerRunControl *runControl) = 0;
     virtual void displayDebugger(DebuggerEngine *engine, bool updateEngine) = 0;
     virtual DebuggerLanguages activeLanguages() const = 0;
-
-    virtual QMessageBox *showMessageBox(int icon, const QString &title,
-        const QString &text, int buttons = 0) = 0;
+    virtual void synchronizeBreakpoints() = 0;
 
     virtual bool initialize(const QStringList &arguments, QString *errorMessage) = 0;
     virtual QWidget *mainWindow() const = 0;
+    virtual QString gdbBinaryForToolChain(int toolChain) const = 0;
+
+    virtual Utils::SavedAction *action(int code) const = 0;
+    virtual bool boolSetting(int code) const = 0;
+    virtual QString stringSetting(int code) const = 0;
 };
 
 // This is the only way to access the global object.
 DebuggerCore *debuggerCore();
+inline BreakHandler *breakHandler() { return debuggerCore()->breakHandler(); }
+QMessageBox *showMessageBox(int icon, const QString &title,
+    const QString &text, int buttons = 0);
 
 } // namespace Internal
 } // namespace Debugger
diff --git a/src/plugins/debugger/debuggerengine.cpp b/src/plugins/debugger/debuggerengine.cpp
index bb614ab1b962d5cc06c327135c63c47ee897218f..f706146117be363e53ac0c71547f2833ee5ac71d 100644
--- a/src/plugins/debugger/debuggerengine.cpp
+++ b/src/plugins/debugger/debuggerengine.cpp
@@ -271,7 +271,6 @@ public:
     DisassemblerViewAgent m_disassemblerViewAgent;
     QFutureInterface<void> m_progress;
 
-    QHash<quint64, Internal::BreakpointData *> m_breakpoints;
     bool m_isSlaveEngine;
 };
 
@@ -485,7 +484,7 @@ void DebuggerEngine::startDebugger(DebuggerRunControl *runControl)
         breakByFunctionMain();
 
     const unsigned engineCapabilities = debuggerCapabilities();
-    theDebuggerAction(OperateByInstruction)
+    debuggerCore()->action(OperateByInstruction)
         ->setEnabled(engineCapabilities & DisassemblerCapability);
 
     QTC_ASSERT(state() == DebuggerNotReady || state() == DebuggerFinished,
@@ -509,7 +508,6 @@ void DebuggerEngine::breakByFunctionMain()
 void DebuggerEngine::breakByFunction(const QString &functionName)
 {
     breakHandler()->breakByFunction(functionName);
-    breakHandler()->synchronizeBreakpoints();
 }
 
 void DebuggerEngine::resetLocation()
@@ -529,7 +527,7 @@ void DebuggerEngine::gotoLocation(const QString &fileName, int lineNumber, bool
 
 void DebuggerEngine::gotoLocation(const StackFrame &frame, bool setMarker)
 {
-    if (theDebuggerBoolSetting(OperateByInstruction) || !frame.isUsable()) {
+    if (debuggerCore()->boolSetting(OperateByInstruction) || !frame.isUsable()) {
         if (setMarker)
             resetLocation();
         d->m_disassemblerViewAgent.setFrame(frame);
@@ -583,14 +581,14 @@ DebuggerStartParameters &DebuggerEngine::startParameters()
 
 bool DebuggerEngine::qtDumperLibraryEnabled() const
 {
-    return theDebuggerBoolSetting(UseDebuggingHelpers);
+    return debuggerCore()->boolSetting(UseDebuggingHelpers);
 }
 
 QStringList DebuggerEngine::qtDumperLibraryLocations() const
 {
-    if (theDebuggerAction(UseCustomDebuggingHelperLocation)->value().toBool()) {
+    if (debuggerCore()->action(UseCustomDebuggingHelperLocation)->value().toBool()) {
         const QString customLocation =
-            theDebuggerAction(CustomDebuggingHelperLocation)->value().toString();
+            debuggerCore()->action(CustomDebuggingHelperLocation)->value().toString();
         const QString location =
             tr("%1 (explicitly set in the Debugger Options)").arg(customLocation);
         return QStringList(location);
@@ -605,8 +603,8 @@ void DebuggerEngine::showQtDumperLibraryWarning(const QString &details)
 
 QString DebuggerEngine::qtDumperLibraryName() const
 {
-    if (theDebuggerAction(UseCustomDebuggingHelperLocation)->value().toBool())
-        return theDebuggerAction(CustomDebuggingHelperLocation)->value().toString();
+    if (debuggerCore()->action(UseCustomDebuggingHelperLocation)->value().toBool())
+        return debuggerCore()->action(CustomDebuggingHelperLocation)->value().toString();
     return startParameters().dumperLibrary;
 }
 
@@ -994,6 +992,13 @@ void DebuggerEngine::setState(DebuggerState state, bool forced)
     if (!forced && !isAllowedTransition(oldState, state))
         qDebug() << "UNEXPECTED STATE TRANSITION: " << msg;
 
+    if (state == DebuggerFinished) {
+        // Give up ownership on claimed breakpoints.
+        BreakHandler *handler = breakHandler();
+        foreach (BreakpointId id, handler->engineBreakpointIds(this))
+            handler->notifyBreakpointReleased(id);
+    }
+
     const bool running = d->m_state == InferiorRunOk;
     if (running)
         threadsHandler()->notifyRunning();
@@ -1121,12 +1126,6 @@ void DebuggerEngine::progressPing()
     d->m_progress.setProgressValue(progress);
 }
 
-QMessageBox *DebuggerEngine::showMessageBox(int icon, const QString &title,
-    const QString &text, int buttons)
-{
-    return debuggerCore()->showMessageBox(icon, title, text, buttons);
-}
-
 DebuggerRunControl *DebuggerEngine::runControl() const
 {
     return d->m_runControl;
@@ -1213,111 +1212,123 @@ void DebuggerEngine::updateAll()
 {
 }
 
+#if 0
+        // FIXME: Remove explicit use of BreakpointData
+        if (!bp->engine && acceptsBreakpoint(id)) {
+            QTC_ASSERT(state == BreakpointNew, /**/);
+            // Take ownership of the breakpoint.
+            bp->engine = this;
+        }
+#endif
+
 void DebuggerEngine::attemptBreakpointSynchronization()
 {
-    for (int i = 0; i < breakHandler()->size(); i++) {
-        BreakpointData *bp = breakHandler()->at(i);
-        if (!d->m_breakpoints.contains(bp->id)) {
-            d->m_breakpoints.insert(bp->id, bp);
-            bp->state = BreakpointInsertionRequested;
-            addBreakpoint(*bp);
-        }
-        QTC_ASSERT(d->m_breakpoints[bp->id] == bp, qDebug() << "corrupted breakpoint map");
-        if (bp->uiDirty) {
-            bp->uiDirty = false;
-            bp->state = BreakpointChangeRequested;
-            changeBreakpoint(*bp);
-        }
+    if (!stateAcceptsBreakpointChanges()) {
+        showMessage(_("BREAKPOINT SYNCHRONIZATION NOT POSSIBLE IN CURRENT STATE"));
+        return;
     }
 
-    Breakpoints bps = breakHandler()->takeRemovedBreakpoints();
-    foreach (BreakpointData *bp, bps) {
-        if (d->m_breakpoints.contains(bp->id)) {
-            bp->state = BreakpointRemovalRequested;
-            removeBreakpoint(bp->id);
-        } else {
-            delete bp;
+    BreakHandler *handler = breakHandler();
+
+    foreach (BreakpointId id, handler->unclaimedBreakpointIds()) {
+        // Take ownership of the breakpoint. Requests insertion.
+        if (acceptsBreakpoint(id))
+            handler->setEngine(id, this);
+    }
+
+    foreach (BreakpointId id, handler->engineBreakpointIds(this)) {
+        switch (handler->state(id)) {
+        case BreakpointNew:
+            // Should not happen once claimed.
+            QTC_ASSERT(false, /**/);
+            continue;
+        case BreakpointInsertRequested:
+            insertBreakpoint(id);
+            continue;
+        case BreakpointChangeRequested:
+            changeBreakpoint(id);
+            continue;
+        case BreakpointRemoveRequested:
+            removeBreakpoint(id);
+            continue;
+        case BreakpointChangeProceeding:
+        case BreakpointInsertProceeding:
+        case BreakpointRemoveProceeding:
+            //qDebug() << "BREAKPOINT " << id << " STILL IN PROGRESS, STATE"
+            //    << handler->state(id);
+            continue;
+        case BreakpointPending:
+            //qDebug() << "BREAKPOINT " << id << " IS GOOD: PENDING";
+            continue;
+        case BreakpointInserted:
+            //qDebug() << "BREAKPOINT " << id << " IS GOOD: INSERTED";
+            continue;
+        case BreakpointDead:
+            // Should not only be visible inside BreakpointHandler.
+            QTC_ASSERT(false, /**/);
+            continue;
         }
+        QTC_ASSERT(false, qDebug() << "UNKNOWN STATE"  << id << state());
     }
+
 }
 
-bool DebuggerEngine::acceptsBreakpoint(const BreakpointData *)
+bool DebuggerEngine::acceptsBreakpoint(BreakpointId) const
 {
     return true;
 }
 
-void DebuggerEngine::addBreakpoint(const BreakpointData &)
+void DebuggerEngine::insertBreakpoint(BreakpointId)
 {
+    QTC_ASSERT(false, /**/);
 }
 
-void DebuggerEngine::notifyAddBreakpointOk(quint64 id)
+void DebuggerEngine::notifyBreakpointInsertOk(BreakpointId id)
 {
-    BreakpointData *bp = d->m_breakpoints[id];
-    QTC_ASSERT(bp, return);
-    bp->state = BreakpointOk;
+    breakHandler()->notifyBreakpointInsertOk(id);
 }
 
-void DebuggerEngine::notifyAddBreakpointFailed(quint64 id)
+void DebuggerEngine::notifyBreakpointInsertFailed(BreakpointId id)
 {
-    BreakpointData *bp = d->m_breakpoints[id];
-    QTC_ASSERT(bp, return);
-    bp->state = BreakpointDead;
+    breakHandler()->notifyBreakpointInsertFailed(id);
 }
 
-void DebuggerEngine::removeBreakpoint(quint64)
+void DebuggerEngine::removeBreakpoint(BreakpointId)
 {
+    QTC_ASSERT(false, /**/);
 }
 
-void DebuggerEngine::notifyRemoveBreakpointOk(quint64 id)
+void DebuggerEngine::notifyBreakpointRemoveOk(BreakpointId id)
 {
-    BreakpointData *bp = d->m_breakpoints.take(id);
-    QTC_ASSERT(bp, return);
-    bp->state = BreakpointDead;
-    delete bp;
+    breakHandler()->notifyBreakpointRemoveOk(id);
 }
 
-void DebuggerEngine::notifyRemoveBreakpointFailed(quint64 id)
+void DebuggerEngine::notifyBreakpointRemoveFailed(BreakpointId id)
 {
-    BreakpointData *bp = d->m_breakpoints[id];
-    QTC_ASSERT(bp, return);
-    bp->state = BreakpointOk;
+    breakHandler()->notifyBreakpointRemoveFailed(id);
 }
 
-void DebuggerEngine::changeBreakpoint(const BreakpointData &)
+void DebuggerEngine::changeBreakpoint(BreakpointId)
 {
+    QTC_ASSERT(false, /**/);
 }
 
-void DebuggerEngine::notifyChangeBreakpointOk(quint64 id)
+void DebuggerEngine::notifyBreakpointChangeOk(BreakpointId id)
 {
-    BreakpointData *bp = d->m_breakpoints[id];
-    QTC_ASSERT(bp, return);
-    bp->state = BreakpointOk;
+    breakHandler()->notifyBreakpointChangeOk(id);
 }
 
-void DebuggerEngine::notifyChangeBreakpointFailed(quint64 id)
+void DebuggerEngine::notifyBreakpointChangeFailed(BreakpointId id)
 {
-    BreakpointData *bp = d->m_breakpoints[id];
-    QTC_ASSERT(bp, return);
-    bp->state = BreakpointDead;
+    breakHandler()->notifyBreakpointChangeFailed(id);
 }
 
-void DebuggerEngine::notifyBreakpointAdjusted(const BreakpointData & rbp)
+/*
+void DebuggerEngine::notifyBreakpointAdjusted(BreakpointId id)
 {
-    BreakpointData *bp = d->m_breakpoints[rbp.id];
-    QTC_ASSERT(bp, return);
-    bp->bpNumber      = rbp.bpNumber;
-    bp->bpCondition   = rbp.bpCondition;
-    bp->bpIgnoreCount = rbp.bpIgnoreCount;
-    bp->bpFileName    = rbp.bpFileName;
-    bp->bpFullName    = rbp.bpFullName;
-    bp->bpLineNumber  = rbp.bpLineNumber;
-    bp->bpCorrectedLineNumber = rbp.bpCorrectedLineNumber;
-    bp->bpThreadSpec  = rbp.bpThreadSpec;
-    bp->bpFuncName    = rbp.bpFuncName;
-    bp->bpAddress     = rbp.bpAddress;
-    bp->bpMultiple    = rbp.bpMultiple;
-    bp->bpEnabled     = rbp.bpEnabled;
+    breakHandler()->notifyChangeBreakpointAdjusted(id);
 }
+*/
 
 void DebuggerEngine::selectThread(int)
 {
diff --git a/src/plugins/debugger/debuggerengine.h b/src/plugins/debugger/debuggerengine.h
index f3f5f162ad9c0f00f73426fc26df15e2e8e71756..49f78f78bd67a5bd36d4b470971e8b55046b6bce 100644
--- a/src/plugins/debugger/debuggerengine.h
+++ b/src/plugins/debugger/debuggerengine.h
@@ -33,6 +33,7 @@
 #include "debugger_global.h"
 #include "debuggerconstants.h"
 #include "moduleshandler.h" // For 'Symbols'
+#include "breakpoint.h" // For 'BreakpointId'
 
 #include <coreplugin/ssh/sshconnection.h> 
 
@@ -116,11 +117,9 @@ DEBUGGER_EXPORT QDebug operator<<(QDebug str, DebuggerState state);
 
 namespace Internal {
 
-class DebuggerCore;
 class DebuggerPluginPrivate;
 class DisassemblerViewAgent;
 class MemoryViewAgent;
-class Symbol;
 class WatchData;
 class BreakHandler;
 class ModulesHandler;
@@ -183,29 +182,24 @@ public:
     virtual void createSnapshot();
     virtual void updateAll();
 
-    virtual void attemptBreakpointSynchronization();
-    virtual bool acceptsBreakpoint(const Internal::BreakpointData *);
-
-    virtual void addBreakpoint(const Internal::BreakpointData &bp);
-    virtual void notifyAddBreakpointOk(quint64 id);
-    virtual void notifyAddBreakpointFailed(quint64 id);
-    virtual void removeBreakpoint(quint64 id);
-    virtual void notifyRemoveBreakpointOk(quint64 id);
-    virtual void notifyRemoveBreakpointFailed(quint64 id);
-    virtual void changeBreakpoint(const Internal::BreakpointData &bp);
-    virtual void notifyChangeBreakpointOk(quint64 id);
-    virtual void notifyChangeBreakpointFailed(quint64 id);
-    virtual void notifyBreakpointAdjusted(const  Internal::BreakpointData &bp);
 
-    virtual void selectThread(int index);
+    virtual bool stateAcceptsBreakpointChanges() const { return true; }
+    virtual void attemptBreakpointSynchronization();
+    virtual bool acceptsBreakpoint(BreakpointId id) const;  // FIXME: make pure
+    virtual void insertBreakpoint(BreakpointId id);  // FIXME: make pure
+    virtual void notifyBreakpointInsertOk(BreakpointId id);
+    virtual void notifyBreakpointInsertFailed(BreakpointId id);
+    virtual void removeBreakpoint(BreakpointId id);  // FIXME: make pure
+    virtual void notifyBreakpointRemoveOk(BreakpointId id);
+    virtual void notifyBreakpointRemoveFailed(BreakpointId id);
+    virtual void changeBreakpoint(BreakpointId id);  // FIXME: make pure
+    virtual void notifyBreakpointChangeOk(BreakpointId id);
+    virtual void notifyBreakpointChangeFailed(BreakpointId id);
 
     virtual void assignValueInDebugger(const Internal::WatchData *data,
         const QString &expr, const QVariant &value);
     virtual void removeTooltip();
-
-    // Convenience
-    static QMessageBox *showMessageBox
-        (int icon, const QString &title, const QString &text, int buttons = 0);
+    virtual void selectThread(int index);
 
 protected:
     friend class Internal::DebuggerPluginPrivate;
diff --git a/src/plugins/debugger/debuggerplugin.cpp b/src/plugins/debugger/debuggerplugin.cpp
index 2bc8bec20277ec7d4a8388f5b23f68c744623240..7efe4608783394bdae096e8a50f79d6d541a0162 100644
--- a/src/plugins/debugger/debuggerplugin.cpp
+++ b/src/plugins/debugger/debuggerplugin.cpp
@@ -59,6 +59,7 @@
 
 #include "snapshothandler.h"
 #include "threadshandler.h"
+#include "gdb/gdboptionspage.h"
 
 #include "ui_commonoptionspage.h"
 #include "ui_dumperoptionpage.h"
@@ -402,11 +403,6 @@ static SessionManager *sessionManager()
     return ProjectExplorerPlugin::instance()->session();
 }
 
-static QSettings *settings()
-{
-    return ICore::instance()->settings();
-}
-
 static QToolButton *toolButton(QAction *action)
 {
     QToolButton *button = new QToolButton;
@@ -450,7 +446,6 @@ void addTcfOptionPages(QList<IOptionsPage*> *opts);
 void addCdbOptionPages(QList<IOptionsPage*> *opts);
 #endif
 
-
 struct AttachRemoteParameters
 {
     AttachRemoteParameters() : attachPid(0), winCrashEvent(0) {}
@@ -539,7 +534,7 @@ public:
         { return QIcon(QLatin1String(DEBUGGER_COMMON_SETTINGS_CATEGORY_ICON)); }
 
     QWidget *createPage(QWidget *parent);
-    void apply() { m_group.apply(settings()); }
+    void apply() { m_group.apply(ICore::instance()->settings()); }
     void finish() { m_group.finish(); }
     virtual bool matches(const QString &s) const;
 
@@ -555,32 +550,32 @@ QWidget *CommonOptionsPage::createPage(QWidget *parent)
     m_ui.setupUi(w);
     m_group.clear();
 
-    m_group.insert(theDebuggerAction(ListSourceFiles),
+    m_group.insert(debuggerCore()->action(ListSourceFiles),
         m_ui.checkBoxListSourceFiles);
-    m_group.insert(theDebuggerAction(UseAlternatingRowColors),
+    m_group.insert(debuggerCore()->action(UseAlternatingRowColors),
         m_ui.checkBoxUseAlternatingRowColors);
-    m_group.insert(theDebuggerAction(UseToolTipsInMainEditor),
+    m_group.insert(debuggerCore()->action(UseToolTipsInMainEditor),
         m_ui.checkBoxUseToolTipsInMainEditor);
-    m_group.insert(theDebuggerAction(CloseBuffersOnExit),
+    m_group.insert(debuggerCore()->action(CloseBuffersOnExit),
         m_ui.checkBoxCloseBuffersOnExit);
-    m_group.insert(theDebuggerAction(SwitchModeOnExit),
+    m_group.insert(debuggerCore()->action(SwitchModeOnExit),
         m_ui.checkBoxSwitchModeOnExit);
-    m_group.insert(theDebuggerAction(AutoDerefPointers), 0);
-    m_group.insert(theDebuggerAction(UseToolTipsInLocalsView), 0);
-    m_group.insert(theDebuggerAction(UseToolTipsInBreakpointsView), 0);
-    m_group.insert(theDebuggerAction(UseAddressInBreakpointsView), 0);
-    m_group.insert(theDebuggerAction(UseAddressInStackView), 0);
-    m_group.insert(theDebuggerAction(MaximalStackDepth),
+    m_group.insert(debuggerCore()->action(AutoDerefPointers), 0);
+    m_group.insert(debuggerCore()->action(UseToolTipsInLocalsView), 0);
+    m_group.insert(debuggerCore()->action(UseToolTipsInBreakpointsView), 0);
+    m_group.insert(debuggerCore()->action(UseAddressInBreakpointsView), 0);
+    m_group.insert(debuggerCore()->action(UseAddressInStackView), 0);
+    m_group.insert(debuggerCore()->action(MaximalStackDepth),
         m_ui.spinBoxMaximalStackDepth);
-    m_group.insert(theDebuggerAction(ShowStdNamespace), 0);
-    m_group.insert(theDebuggerAction(ShowQtNamespace), 0);
-    m_group.insert(theDebuggerAction(SortStructMembers), 0);
-    m_group.insert(theDebuggerAction(LogTimeStamps), 0);
-    m_group.insert(theDebuggerAction(VerboseLog), 0);
-    m_group.insert(theDebuggerAction(BreakOnThrow), 0);
-    m_group.insert(theDebuggerAction(BreakOnCatch), 0);
+    m_group.insert(debuggerCore()->action(ShowStdNamespace), 0);
+    m_group.insert(debuggerCore()->action(ShowQtNamespace), 0);
+    m_group.insert(debuggerCore()->action(SortStructMembers), 0);
+    m_group.insert(debuggerCore()->action(LogTimeStamps), 0);
+    m_group.insert(debuggerCore()->action(VerboseLog), 0);
+    m_group.insert(debuggerCore()->action(BreakOnThrow), 0);
+    m_group.insert(debuggerCore()->action(BreakOnCatch), 0);
 #ifdef Q_OS_WIN
-    Utils::SavedAction *registerAction = theDebuggerAction(RegisterForPostMortem);
+    Utils::SavedAction *registerAction = debuggerCore()->action(RegisterForPostMortem);
     m_group.insert(registerAction,
         m_ui.checkBoxRegisterForPostMortem);
     connect(registerAction, SIGNAL(toggled(bool)),
@@ -623,8 +618,8 @@ static inline bool oxygenStyle()
 }
 
 class DebuggingHelperOptionPage : public Core::IOptionsPage
-{   // Needs tr - context
-    Q_OBJECT
+{
+    Q_OBJECT // Needs tr-context.
 public:
     DebuggingHelperOptionPage() {}
 
@@ -638,7 +633,7 @@ public:
     { return QIcon(QLatin1String(DEBUGGER_COMMON_SETTINGS_CATEGORY_ICON)); }
 
     QWidget *createPage(QWidget *parent);
-    void apply() { m_group.apply(settings()); }
+    void apply() { m_group.apply(ICore::instance()->settings()); }
     void finish() { m_group.finish(); }
     virtual bool matches(const QString &s) const;
 
@@ -659,22 +654,22 @@ QWidget *DebuggingHelperOptionPage::createPage(QWidget *parent)
         ICore::instance()->resourcePath() + "../../lib");
 
     m_group.clear();
-    m_group.insert(theDebuggerAction(UseDebuggingHelpers),
+    m_group.insert(debuggerCore()->action(UseDebuggingHelpers),
         m_ui.debuggingHelperGroupBox);
-    m_group.insert(theDebuggerAction(UseCustomDebuggingHelperLocation),
+    m_group.insert(debuggerCore()->action(UseCustomDebuggingHelperLocation),
         m_ui.customLocationGroupBox);
     // Suppress Oxygen style's giving flat group boxes bold titles.
     if (oxygenStyle())
         m_ui.customLocationGroupBox->setStyleSheet(_("QGroupBox::title { font: ; }"));
 
-    m_group.insert(theDebuggerAction(CustomDebuggingHelperLocation),
+    m_group.insert(debuggerCore()->action(CustomDebuggingHelperLocation),
         m_ui.dumperLocationChooser);
 
-    m_group.insert(theDebuggerAction(UseCodeModel),
+    m_group.insert(debuggerCore()->action(UseCodeModel),
         m_ui.checkBoxUseCodeModel);
 
 #ifdef QT_DEBUG
-    m_group.insert(theDebuggerAction(DebugDebuggingHelpers),
+    m_group.insert(debuggerCore()->action(DebugDebuggingHelpers),
         m_ui.checkBoxDebugDebuggingHelpers);
 #else
     m_ui.checkBoxDebugDebuggingHelpers->hide();
@@ -818,8 +813,7 @@ static bool isDebuggable(IEditor *editor)
     //   IFile *file = editor->file();
     //   return !(file && file->mimeType() == "application/x-qml");
     // Nowadays, even Qml is debuggable.
-    Q_UNUSED(editor);
-    return true;
+    return editor;
 }
 
 
@@ -881,7 +875,7 @@ public slots:
         currentEngine()->selectThread(index);
     }
 
-    void breakpointSetRemoveMarginActionTriggered()
+    void breakpointSetMarginActionTriggered()
     {
         QString fileName;
         int lineNumber;
@@ -890,12 +884,32 @@ public slots:
             m_breakHandler->toggleBreakpoint(fileName, lineNumber, address);
      }
 
-    void breakpointEnableDisableMarginActionTriggered()
+    void breakpointRemoveMarginActionTriggered()
     {
+        const QAction *act = qobject_cast<QAction *>(sender());
+        QTC_ASSERT(act, return);
+        const BreakpointId id = act->data().toInt();
+        QTC_ASSERT(id > 0, return);
+
         QString fileName;
         int lineNumber;
-        if (positionFromContextActionData(sender(), &fileName, &lineNumber))
-            m_breakHandler->toggleBreakpointEnabled(fileName, lineNumber);
+        quint64 address;
+        if (positionFromContextActionData(sender(), &fileName, &lineNumber, &address))
+            m_breakHandler->toggleBreakpoint(fileName, lineNumber, address);
+     }
+
+    void breakpointEnableMarginActionTriggered()
+    {
+        const QAction *act = qobject_cast<QAction *>(sender());
+        QTC_ASSERT(act, return);
+        breakHandler()->setEnabled(act->data().toInt(), true);
+    }
+
+    void breakpointDisableMarginActionTriggered()
+    {
+        const QAction *act = qobject_cast<QAction *>(sender());
+        QTC_ASSERT(act, return);
+        breakHandler()->setEnabled(act->data().toInt(), false);
     }
 
     void updateWatchersHeader(int section, int, int newSize)
@@ -991,11 +1005,10 @@ public slots:
     void runControlStarted(DebuggerRunControl *runControl);
     void runControlFinished(DebuggerRunControl *runControl);
     DebuggerLanguages activeLanguages() const;
+    QString gdbBinaryForToolChain(int toolChain) const;
     void remoteCommand(const QStringList &options, const QStringList &);
 
     bool isReverseDebugging() const;
-    QMessageBox *showMessageBox(int icon, const QString &title,
-        const QString &text, int buttons);
     void ensureLogVisible();
     void extensionsInitialized();
 
@@ -1042,7 +1055,7 @@ public slots:
     void handleExecStep()
     {
         resetLocation();
-        if (theDebuggerBoolSetting(OperateByInstruction))
+        if (debuggerCore()->boolSetting(OperateByInstruction))
             currentEngine()->executeStepI();
         else
             currentEngine()->executeStep();
@@ -1051,7 +1064,7 @@ public slots:
     void handleExecNext()
     {
         resetLocation();
-        if (theDebuggerBoolSetting(OperateByInstruction))
+        if (debuggerCore()->boolSetting(OperateByInstruction))
             currentEngine()->executeNextI();
         else
             currentEngine()->executeNext();
@@ -1124,10 +1137,9 @@ public slots:
     {
         const QAction *act = qobject_cast<QAction *>(sender());
         QTC_ASSERT(act, return);
-        const QVariant data = act->data();
-        QTC_ASSERT(qVariantCanConvert<BreakpointData *>(data), return);
-        BreakpointData *breakPointData = qvariant_cast<BreakpointData *>(data);
-        BreakWindow::editBreakpoint(breakPointData, mainWindow());
+        const BreakpointId id = act->data().toInt();
+        QTC_ASSERT(id > 0, return);
+        BreakWindow::editBreakpoint(id, mainWindow());
     }
 
     void slotRunToLine()
@@ -1211,6 +1223,10 @@ public slots:
     void clearCppCodeModelSnapshot();
     void showMessage(const QString &msg, int channel, int timeout = -1);
 
+    Utils::SavedAction *action(int code) const;
+    bool boolSetting(int code) const;
+    QString stringSetting(int code) const;
+
 public:
     DebuggerState m_state;
     DebuggerUISwitcher *m_uiSwitcher;
@@ -1285,6 +1301,9 @@ public:
     SnapshotHandler *m_snapshotHandler;
     bool m_shuttingDown;
     DebuggerEngine *m_currentEngine;
+    DebuggerSettings *m_debuggerSettings;
+    QSettings *m_coreSettings;
+    bool m_gdbBinariesChanged;
 };
 
 
@@ -1337,10 +1356,16 @@ DebuggerPluginPrivate::DebuggerPluginPrivate(DebuggerPlugin *plugin)
     m_state = DebuggerNotReady;
     m_snapshotHandler = 0;
     m_currentEngine = 0;
+    m_debuggerSettings = 0;
+
+    m_gdbBinariesChanged = true;
 }
 
 DebuggerPluginPrivate::~DebuggerPluginPrivate()
 {
+    delete m_debuggerSettings;
+    m_debuggerSettings = 0;
+
     m_plugin->removeObject(theDebuggerCore->m_debugMode);
     delete m_debugMode;
     m_debugMode = 0;
@@ -1361,6 +1386,9 @@ DebuggerCore *debuggerCore()
 bool DebuggerPluginPrivate::initialize(const QStringList &arguments,
     QString *errorMessage)
 {
+    m_coreSettings = ICore::instance()->settings();
+    m_debuggerSettings = new DebuggerSettings(m_coreSettings);
+    
     m_continuableContext = Context("Gdb.Continuable");
     m_interruptibleContext = Context("Gdb.Interruptible");
     m_undisturbableContext = Context("Gdb.Undisturbable");
@@ -1399,8 +1427,6 @@ bool DebuggerPluginPrivate::initialize(const QStringList &arguments,
     m_statusLabel->setMinimumSize(QSize(30, 10));
 
     m_breakHandler = new BreakHandler;
-    connect(m_breakHandler, SIGNAL(breakpointSynchronizationRequested()),
-        SLOT(synchronizeBreakpoints()));
     m_breakWindow = new BreakWindow;
     m_breakWindow->setObjectName(QLatin1String("CppDebugBreakpoints"));
     m_breakWindow->setModel(m_breakHandler->model());
@@ -1522,21 +1548,22 @@ bool DebuggerPluginPrivate::initialize(const QStringList &arguments,
     act = m_actions.frameUpAction = new QAction(tr("Move to Calling Frame"), this);
     connect(act, SIGNAL(triggered()), SLOT(handleFrameUp()));
 
-    connect(theDebuggerAction(OperateByInstruction), SIGNAL(triggered()),
+    connect(debuggerCore()->action(OperateByInstruction), SIGNAL(triggered()),
         SLOT(handleOperateByInstructionTriggered()));
 
     connect(&m_statusTimer, SIGNAL(timeout()), SLOT(clearStatusMessage()));
 
-    connect(theDebuggerAction(ExecuteCommand), SIGNAL(triggered()),
+    connect(debuggerCore()->action(ExecuteCommand), SIGNAL(triggered()),
         SLOT(executeDebuggerCommand()));
 
-    readSettings();
-
     // Cpp/Qml ui setup
     m_uiSwitcher = new DebuggerUISwitcher(m_debugMode, this);
     ExtensionSystem::PluginManager::instance()->addObject(m_uiSwitcher);
     m_uiSwitcher->addLanguage(CppLanguage, cppDebuggercontext);
     m_uiSwitcher->addLanguage(QmlLanguage, qmlDebuggerContext);
+    m_uiSwitcher->initialize(m_coreSettings);
+
+    readSettings();
 
     // Dock widgets
     m_breakDock = m_uiSwitcher->createDockWidget(CppLanguage, m_breakWindow);
@@ -1793,7 +1820,7 @@ bool DebuggerPluginPrivate::initialize(const QStringList &arguments,
         Constants::FRAME_UP, cppDebuggercontext);
 
 
-    cmd = am->registerAction(theDebuggerAction(OperateByInstruction),
+    cmd = am->registerAction(debuggerCore()->action(OperateByInstruction),
         Constants::OPERATE_BY_INSTRUCTION, cppDebuggercontext);
     cmd->setAttribute(Command::CA_Hide);
     m_uiSwitcher->addMenuAction(cmd, CppLanguage);
@@ -1886,7 +1913,7 @@ bool DebuggerPluginPrivate::initialize(const QStringList &arguments,
         SLOT(editorOpened(Core::IEditor*)));
 
     // Application interaction
-    connect(theDebuggerAction(SettingsDialog), SIGNAL(triggered()),
+    connect(debuggerCore()->action(SettingsDialog), SIGNAL(triggered()),
         SLOT(showSettingsDialog()));
 
     // Toolbar
@@ -1922,7 +1949,7 @@ bool DebuggerPluginPrivate::initialize(const QStringList &arguments,
         SIGNAL(dockResetRequested(Debugger::DebuggerLanguages)),
         SLOT(setSimpleDockWidgetArrangement(Debugger::DebuggerLanguages)));
 
-    connect(theDebuggerAction(EnableReverseDebugging),
+    connect(debuggerCore()->action(EnableReverseDebugging),
         SIGNAL(valueChanged(QVariant)),
         SLOT(enableReverseDebuggingTriggered(QVariant)));
 
@@ -1943,16 +1970,16 @@ bool DebuggerPluginPrivate::initialize(const QStringList &arguments,
 
 void DebuggerPluginPrivate::setConfigValue(const QString &name, const QVariant &value)
 {
-    settings()->setValue(_("DebugMode/") + name, value);
+    m_coreSettings->setValue(_("DebugMode/") + name, value);
 }
 
 QVariant DebuggerPluginPrivate::configValue(const QString &name) const
 {
-    const QVariant value = settings()->value(_("DebugMode/") + name);
+    const QVariant value = m_coreSettings->value(_("DebugMode/") + name);
     if (value.isValid())
         return value;
     // Legacy (pre-2.1): Check old un-namespaced-settings.
-    return settings()->value(name);
+    return m_coreSettings->value(name);
 }
 
 void DebuggerPluginPrivate::onCurrentProjectChanged(Project *project)
@@ -2259,7 +2286,7 @@ void DebuggerPluginPrivate::requestContextMenu(TextEditor::ITextEditor *editor,
     if (!isDebuggable(editor))
         return;
 
-    BreakpointData *data = 0;
+    BreakpointId id = -1;
     QString fileName;
     quint64 address = 0;
 
@@ -2267,14 +2294,13 @@ void DebuggerPluginPrivate::requestContextMenu(TextEditor::ITextEditor *editor,
         fileName = editor->file()->fileName();
         QString line = editor->contents()
             .section('\n', lineNumber - 1, lineNumber - 1);
-        BreakpointData needle;
-        address = DisassemblerViewAgent::addressFromDisassemblyLine(line);
-        needle.address = address;
+        BreakpointResponse needle;
+        needle.bpAddress = DisassemblerViewAgent::addressFromDisassemblyLine(line);
         needle.bpLineNumber = -1;
-        data = m_breakHandler->findSimilarBreakpoint(&needle);
+        id = breakHandler()->findSimilarBreakpoint(needle);
     } else {
         fileName = editor->file()->fileName();
-        data = m_breakHandler->findBreakpoint(fileName, lineNumber);
+        id = breakHandler()->findBreakpointByFileAndLine(fileName, lineNumber);
     }
 
     QList<QVariant> args;
@@ -2282,51 +2308,43 @@ void DebuggerPluginPrivate::requestContextMenu(TextEditor::ITextEditor *editor,
     args.append(lineNumber);
     args.append(address);
 
-    if (data) {
-        // existing breakpoint
-        const QString number = QString::fromAscii(data->bpNumber);
-        QAction *act;
-        if (number.isEmpty())
-            act = new QAction(tr("Remove Breakpoint"), menu);
-        else
-            act = new QAction(tr("Remove Breakpoint %1").arg(number), menu);
-        act->setData(args);
+    if (id != BreakpointId(-1)) {
+        // Remove existing breakpoint.
+        QAction *act = new QAction(menu);
+        act->setData(int(id));
+        act->setText(tr("Remove Breakpoint %1").arg(id));
         connect(act, SIGNAL(triggered()),
-            SLOT(breakpointSetRemoveMarginActionTriggered()));
+            SLOT(breakpointRemoveMarginActionTriggered()));
         menu->addAction(act);
 
-        QAction *act2;
-        if (data->enabled)
-            if (number.isEmpty())
-                act2 = new QAction(tr("Disable Breakpoint"), menu);
-            else
-                act2 = new QAction(tr("Disable Breakpoint %1").arg(number), menu);
-        else
-            if (number.isEmpty())
-                act2 = new QAction(tr("Enable Breakpoint"), menu);
-            else
-                act2 = new QAction(tr("Enable Breakpoint %1").arg(number), menu);
-        act2->setData(args);
-        connect(act2, SIGNAL(triggered()),
-            this, SLOT(breakpointEnableDisableMarginActionTriggered()));
-        menu->addAction(act2);
-        QAction *editAction;
-        if (number.isEmpty())
-            editAction = new QAction(tr("Edit Breakpoint..."), menu);
-        else
-            editAction = new QAction(tr("Edit Breakpoint %1...").arg(number), menu);
-        connect(editAction, SIGNAL(triggered()), SLOT(slotEditBreakpoint()));
-        editAction->setData(qVariantFromValue(data));
-        menu->addAction(editAction);
+        // Enable/disable existing breakpoint.
+        act = new QAction(menu);
+        if (breakHandler()->isEnabled(id)) {
+            act->setText(tr("Disable Breakpoint %1").arg(id));
+            connect(act, SIGNAL(triggered()),
+                SLOT(breakpointDisableMarginActionTriggered()));
+        } else {
+            act->setText(tr("Enable Breakpoint %1").arg(id));
+            connect(act, SIGNAL(triggered()),
+                SLOT(breakpointEnableMarginActionTriggered()));
+        }
+        menu->addAction(act);
+
+        // Edit existing breakpoint.
+        act = new QAction(menu);
+        act->setText(tr("Edit Breakpoint %1...").arg(id));
+        connect(act, SIGNAL(triggered()), SLOT(slotEditBreakpoint()));
+        act->setData(int(id));
+        menu->addAction(act);
     } else {
-        // non-existing
+        // Handle non-existing breakpoint.
         const QString text = address ?
                     tr("Set Breakpoint at 0x%1").arg(address, 0, 16) :
                     tr("Set Breakpoint at line %1").arg(lineNumber);
         QAction *act = new QAction(text, menu);
         act->setData(args);
         connect(act, SIGNAL(triggered()),
-            SLOT(breakpointSetRemoveMarginActionTriggered()));
+            SLOT(breakpointSetMarginActionTriggered()));
         menu->addAction(act);
     }
     // Run to, jump to line below in stopped state.
@@ -2362,12 +2380,11 @@ void DebuggerPluginPrivate::toggleBreakpoint()
 void DebuggerPluginPrivate::toggleBreakpoint(const QString &fileName, int lineNumber)
 {
     m_breakHandler->toggleBreakpoint(fileName, lineNumber);
-    m_breakHandler->synchronizeBreakpoints();
 }
 
 void DebuggerPluginPrivate::requestMark(ITextEditor *editor, int lineNumber)
 {
-    if (isDebuggable(editor) && editor && editor->file())
+    if (isDebuggable(editor) && editor->file())
         toggleBreakpoint(editor->file()->fileName(), lineNumber);
 }
 
@@ -2376,7 +2393,7 @@ void DebuggerPluginPrivate::showToolTip(ITextEditor *editor,
 {
     if (!isDebuggable(editor))
         return;
-    if (!theDebuggerBoolSetting(UseToolTipsInMainEditor))
+    if (!boolSetting(UseToolTipsInMainEditor))
         return;
     if (state() != InferiorStopOk)
         return;
@@ -2485,27 +2502,26 @@ void DebuggerPluginPrivate::cleanupViews()
     m_actions.reverseDirectionAction->setEnabled(false);
     hideDebuggerToolTip();
 
-    // FIXME ABC: Delete run control / engine?
-    //if (d->m_engine)
-    //    d->m_engine->cleanup();
-
-    if (theDebuggerBoolSetting(CloseBuffersOnExit)) {
-        if (EditorManager *editorManager = EditorManager::instance()) {
-            QList<IEditor *> toClose;
-            foreach (IEditor *editor, editorManager->openedEditors()) {
-                if (editor->property(Debugger::Constants::OPENED_BY_DEBUGGER).toBool()) {
-                    // close disassembly views. close other opened files if they are not modified and not current editor
-                    if (editor->property(Debugger::Constants::OPENED_WITH_DISASSEMBLY).toBool()
-                            || (!editor->file()->isModified() && editor != editorManager->currentEditor())) {
-                        toClose.append(editor);
-                    } else {
-                        editor->setProperty(Debugger::Constants::OPENED_BY_DEBUGGER, false);
-                    }
-                }
+    if (!boolSetting(CloseBuffersOnExit))
+        return;
+
+    EditorManager *editorManager = EditorManager::instance();
+    QTC_ASSERT(editorManager, return);
+    QList<IEditor *> toClose;
+    foreach (IEditor *editor, editorManager->openedEditors()) {
+        if (editor->property(Constants::OPENED_BY_DEBUGGER).toBool()) {
+            // Close disassembly views. Close other opened files
+            // if they are not modified and not current editor.
+            if (editor->property(Constants::OPENED_WITH_DISASSEMBLY).toBool()
+                    || (!editor->file()->isModified()
+                        && editor != editorManager->currentEditor())) {
+                toClose.append(editor);
+            } else {
+                editor->setProperty(Constants::OPENED_BY_DEBUGGER, false);
             }
-            editorManager->closeEditors(toClose);
         }
     }
+    editorManager->closeEditors(toClose);
 }
 
 void DebuggerPluginPrivate::setBusyCursor(bool busy)
@@ -2606,7 +2622,7 @@ void DebuggerPluginPrivate::setInitialState()
     m_actions.watchAction2->setEnabled(true);
     m_actions.breakAction->setEnabled(true);
     //m_actions.snapshotAction->setEnabled(false);
-    theDebuggerAction(OperateByInstruction)->setEnabled(false);
+    debuggerCore()->action(OperateByInstruction)->setEnabled(false);
 
     m_actions.exitAction->setEnabled(false);
     m_actions.resetAction->setEnabled(false);
@@ -2619,9 +2635,9 @@ void DebuggerPluginPrivate::setInitialState()
     m_actions.jumpToLineAction->setEnabled(false);
     m_actions.nextAction->setEnabled(false);
 
-    theDebuggerAction(AutoDerefPointers)->setEnabled(true);
-    theDebuggerAction(ExpandStack)->setEnabled(false);
-    theDebuggerAction(ExecuteCommand)->setEnabled(m_state == InferiorStopOk);
+    debuggerCore()->action(AutoDerefPointers)->setEnabled(true);
+    debuggerCore()->action(ExpandStack)->setEnabled(false);
+    debuggerCore()->action(ExecuteCommand)->setEnabled(m_state == InferiorStopOk);
 
     m_scriptConsoleWindow->setEnabled(false);
 
@@ -2728,7 +2744,7 @@ void DebuggerPluginPrivate::updateState(DebuggerEngine *engine)
 
     const uint caps = engine->debuggerCapabilities();
     const bool canReverse = (caps & ReverseSteppingCapability)
-                && theDebuggerBoolSetting(EnableReverseDebugging);
+                && debuggerCore()->boolSetting(EnableReverseDebugging);
     m_actions.reverseDirectionAction->setEnabled(canReverse);
 
     m_actions.watchAction1->setEnabled(true);
@@ -2736,7 +2752,7 @@ void DebuggerPluginPrivate::updateState(DebuggerEngine *engine)
     m_actions.breakAction->setEnabled(true);
     //m_actions.snapshotAction->setEnabled(stopped && (caps & SnapshotCapability));
 
-    theDebuggerAction(OperateByInstruction)->setEnabled(stopped);
+    debuggerCore()->action(OperateByInstruction)->setEnabled(stopped);
 
     m_actions.resetAction->setEnabled(m_state != DebuggerNotReady
                                       && m_state != DebuggerFinished);
@@ -2754,10 +2770,10 @@ void DebuggerPluginPrivate::updateState(DebuggerEngine *engine)
     m_actions.nextAction->setEnabled(stopped);
 
     const bool canDeref = actionsEnabled && (caps & AutoDerefPointersCapability);
-    theDebuggerAction(AutoDerefPointers)->setEnabled(canDeref);
-    theDebuggerAction(AutoDerefPointers)->setEnabled(true);
-    theDebuggerAction(ExpandStack)->setEnabled(actionsEnabled);
-    theDebuggerAction(ExecuteCommand)->setEnabled(m_state == InferiorStopOk);
+    debuggerCore()->action(AutoDerefPointers)->setEnabled(canDeref);
+    debuggerCore()->action(AutoDerefPointers)->setEnabled(true);
+    debuggerCore()->action(ExpandStack)->setEnabled(actionsEnabled);
+    debuggerCore()->action(ExecuteCommand)->setEnabled(m_state == InferiorStopOk);
 
     const bool notbusy = m_state == InferiorStopOk
         || m_state == DebuggerNotReady
@@ -2921,25 +2937,24 @@ void DebuggerPluginPrivate::coreShutdown()
 
 void DebuggerPluginPrivate::writeSettings() const
 {
-    QSettings *s = settings();
-    DebuggerSettings::instance()->writeSettings(s);
-    if (m_uiSwitcher)
-        m_uiSwitcher->writeSettings(s);
+    m_debuggerSettings->writeSettings();
+    m_uiSwitcher->writeSettings();
+    if (GdbOptionsPage::gdbBinariesChanged)
+        GdbOptionsPage::writeGdbBinarySettings();
 }
 
 void DebuggerPluginPrivate::readSettings()
 {
     //qDebug() << "PLUGIN READ SETTINGS";
-    QSettings *s = settings();
-    DebuggerSettings::instance()->readSettings(s);
-    if (m_uiSwitcher)
-        m_uiSwitcher->writeSettings(s);
+    m_debuggerSettings->readSettings();
+    m_uiSwitcher->readSettings();
+    GdbOptionsPage::readGdbBinarySettings();
 }
 
 const CPlusPlus::Snapshot &DebuggerPluginPrivate::cppCodeModelSnapshot() const
 {
     if (m_codeModelSnapshot.isEmpty()
-            && theDebuggerAction(UseCodeModel)->isChecked())
+            && debuggerCore()->action(UseCodeModel)->isChecked())
         m_codeModelSnapshot = CppTools::CppModelManagerInterface::instance()->snapshot();
     return m_codeModelSnapshot;
 }
@@ -3050,7 +3065,7 @@ void DebuggerPluginPrivate::showQtDumperLibraryWarning(const QString &details)
             _(Qt4ProjectManager::Constants::QT_SETTINGS_CATEGORY),
             _(Qt4ProjectManager::Constants::QTVERSION_SETTINGS_PAGE_ID));
     } else if (dialog.clickedButton() == helperOff) {
-        theDebuggerAction(UseDebuggingHelpers)
+        debuggerCore()->action(UseDebuggingHelpers)
             ->setValue(qVariantFromValue(false), false);
     }
 }
@@ -3080,7 +3095,7 @@ void DebuggerPluginPrivate::runControlStarted(DebuggerRunControl *runControl)
 
     const QString message = runControl->idString();
     showMessage(message, StatusBar);
-    showMessage(DebuggerSettings::instance()->dump(), LogDebug);
+    showMessage(m_debuggerSettings->dump(), LogDebug);
     m_snapshotHandler->appendSnapshot(runControl);
     connectEngine(runControl->engine());
 }
@@ -3089,7 +3104,7 @@ void DebuggerPluginPrivate::runControlFinished(DebuggerRunControl *runControl)
 {
     m_snapshotHandler->removeSnapshot(runControl);
     disconnectEngine();
-    if (theDebuggerBoolSetting(SwitchModeOnExit))
+    if (debuggerCore()->boolSetting(SwitchModeOnExit))
         if (m_snapshotHandler->size() == 0)
             activatePreviousMode();
 }
@@ -3115,6 +3130,11 @@ void DebuggerPluginPrivate::remoteCommand(const QStringList &options,
                arg(options.join(QString(QLatin1Char(' '))))));
 }
 
+QString DebuggerPluginPrivate::gdbBinaryForToolChain(int toolChain) const
+{
+    return GdbOptionsPage::gdbBinaryToolChainMap.key(toolChain);
+}
+
 DebuggerLanguages DebuggerPluginPrivate::activeLanguages() const
 {
     return m_uiSwitcher->activeDebugLanguages();
@@ -3125,11 +3145,12 @@ bool DebuggerPluginPrivate::isReverseDebugging() const
     return m_actions.reverseDirectionAction->isChecked();
 }
 
-QMessageBox *DebuggerPluginPrivate::showMessageBox(int icon, const QString &title,
+QMessageBox *showMessageBox(int icon, const QString &title,
     const QString &text, int buttons)
 {
     QMessageBox *mb = new QMessageBox(QMessageBox::Icon(icon),
-        title, text, QMessageBox::StandardButtons(buttons), mainWindow());
+        title, text, QMessageBox::StandardButtons(buttons),
+        debuggerCore()->mainWindow());
     mb->setAttribute(Qt::WA_DeleteOnClose);
     mb->show();
     return mb;
@@ -3144,7 +3165,7 @@ void DebuggerPluginPrivate::ensureLogVisible()
 
 void DebuggerPluginPrivate::extensionsInitialized()
 {
-    m_uiSwitcher->initialize(settings());
+    QTC_ASSERT(m_coreSettings, /**/);
     m_watchersWindow->setVisible(false);
     m_returnWindow->setVisible(false);
     connect(m_uiSwitcher, SIGNAL(memoryEditorRequested()),
@@ -3160,6 +3181,21 @@ void DebuggerPluginPrivate::extensionsInitialized()
         QTimer::singleShot(0, this, SLOT(attachCmdLine()));
 }
 
+Utils::SavedAction *DebuggerPluginPrivate::action(int code) const
+{
+    return m_debuggerSettings->item(code);
+}
+
+bool DebuggerPluginPrivate::boolSetting(int code) const
+{
+    return m_debuggerSettings->item(code)->value().toBool();
+}
+
+QString DebuggerPluginPrivate::stringSetting(int code) const
+{
+    return m_debuggerSettings->item(code)->value().toString();
+}
+
 } // namespace Internal
 
 using namespace Debugger::Internal;
@@ -3177,7 +3213,6 @@ DebuggerPlugin::DebuggerPlugin()
 
 DebuggerPlugin::~DebuggerPlugin()
 {
-    delete DebuggerSettings::instance();
     delete theDebuggerCore;
     theDebuggerCore = 0;
 }
@@ -3256,6 +3291,7 @@ DebuggerUISwitcher *DebuggerPlugin::uiSwitcher()
     return theDebuggerCore->m_uiSwitcher;
 }
 
+
 //////////////////////////////////////////////////////////////////////
 //
 // Testing
diff --git a/src/plugins/debugger/debuggerrunner.cpp b/src/plugins/debugger/debuggerrunner.cpp
index ee9fde62793a5c6a893c745800fd61992b876ed2..5362ecc261d403eddd3e897e0d9e99728dc5d5bc 100644
--- a/src/plugins/debugger/debuggerrunner.cpp
+++ b/src/plugins/debugger/debuggerrunner.cpp
@@ -38,6 +38,7 @@
 #include "gdb/gdbengine.h"
 #include "gdb/remotegdbserveradapter.h"
 #include "gdb/remoteplaingdbadapter.h"
+#include "gdb/gdboptionspage.h"
 #include "qml/qmlengine.h"
 #include "qml/qmlcppengine.h"
 #include "lldb/lldbenginehost.h"
@@ -76,7 +77,7 @@ DebuggerEngine *createQmlEngine(const DebuggerStartParameters &);
 DebuggerEngine *createQmlCppEngine(const DebuggerStartParameters &);
 DebuggerEngine *createLLDBEngine(const DebuggerStartParameters &);
 
-bool checkGdbConfiguration(int toolChain, QString *errorMsg, QString *settingsPage);
+extern QString msgNoBinaryForToolChain(int tc);
 
 // FIXME: Outdated?
 // The createCdbEngine function takes a list of options pages it can add to.
@@ -552,9 +553,14 @@ bool DebuggerRunControl::checkDebugConfiguration(int toolChain,
     case ProjectExplorer::ToolChain_GCCE:
     case ProjectExplorer::ToolChain_RVCT_ARMV5:
     case ProjectExplorer::ToolChain_RVCT_ARMV6:
-        success = checkGdbConfiguration(toolChain, errorMessage, settingsPage);
-        if (!success)
+        if (debuggerCore()->gdbBinaryForToolChain(toolChain).isEmpty()) {
+            *errorMessage = msgNoBinaryForToolChain(toolChain);
+            *settingsPage = GdbOptionsPage::settingsId();
             *errorMessage += msgEngineNotAvailable("Gdb");
+            success = false;
+        } else {
+            success = true;
+        }
         break;
     case ProjectExplorer::ToolChain_MSVC:
         success = checkCdbConfiguration(toolChain, errorMessage, settingsPage);
diff --git a/src/plugins/debugger/debuggerstreamops.cpp b/src/plugins/debugger/debuggerstreamops.cpp
index aea66f5a6b0a4b9f6ca0c4d27fce2c0b0b16ce3a..024560d5d134edf414fff82613d455782379451c 100644
--- a/src/plugins/debugger/debuggerstreamops.cpp
+++ b/src/plugins/debugger/debuggerstreamops.cpp
@@ -134,56 +134,64 @@ QDataStream &operator>>(QDataStream &stream, StackFrames &frames)
     return stream;
 }
 
-QDataStream &operator<<(QDataStream &stream, const BreakpointData &s)
+QDataStream &operator<<(QDataStream &stream, const BreakpointResponse &s)
 {
-    stream << s.fileName;
-    stream << s.condition;
-    stream << (quint64)s.ignoreCount;
-    stream << (quint64)s.lineNumber;
-    stream << s.address;
-    stream << s.funcName;
-    stream << s.useFullPath;
-
     stream << s.bpNumber;
     stream << s.bpCondition;
     stream << s.bpIgnoreCount;
     stream << s.bpFileName;
     stream << s.bpFullName;
     stream << s.bpLineNumber;
-    stream << s.bpCorrectedLineNumber;
+    //stream << s.bpCorrectedLineNumber;
     stream << s.bpThreadSpec;
     stream << s.bpFuncName;
     stream << s.bpAddress;
-
     return stream;
 }
 
-QDataStream &operator>>(QDataStream &stream, BreakpointData &s)
+QDataStream &operator>>(QDataStream &stream, BreakpointResponse &s)
 {
-    quint64 t;
-    stream >> s.fileName;
-    stream >> s.condition;
-    stream >> t;
-    s.ignoreCount = t;
-    stream >> t;
-    s.lineNumber = t;
-    stream >> s.address;
-    stream >> s.funcName;
-    stream >> s.useFullPath;
-
     stream >> s.bpNumber;
     stream >> s.bpCondition;
     stream >> s.bpIgnoreCount;
     stream >> s.bpFileName;
     stream >> s.bpFullName;
     stream >> s.bpLineNumber;
-    stream >> s.bpCorrectedLineNumber;
+    //stream >> s.bpCorrectedLineNumber;
     stream >> s.bpThreadSpec;
     stream >> s.bpFuncName;
     stream >> s.bpAddress;
     return stream;
 }
 
+QDataStream &operator<<(QDataStream &stream, const BreakpointData &s)
+{
+    stream << s.fileName();
+    stream << s.condition();
+    stream << quint64(s.ignoreCount());
+    stream << quint64(s.lineNumber());
+    stream << quint64(s.address());
+    stream << s.functionName();
+    stream << s.useFullPath();
+    return stream;
+}
+
+QDataStream &operator>>(QDataStream &stream, BreakpointData &s)
+{
+    quint64 t;
+    QString str;
+    QByteArray ba;
+    bool b;
+    stream >> str; s.setFileName(str);
+    stream >> ba; s.setCondition(ba);
+    stream >> t; s.setIgnoreCount(t);
+    stream >> t; s.setLineNumber(t);
+    stream >> t; s.setAddress(t);
+    stream >> str; s.setFunctionName(str);
+    stream >> b; s.setUseFullPath(b);
+    return stream;
+}
+
 QDataStream &operator<<(QDataStream &stream, const WatchData &wd)
 {
     stream << wd.id;
diff --git a/src/plugins/debugger/debuggerstreamops.h b/src/plugins/debugger/debuggerstreamops.h
index 8bb38a45d7d9ab318ff9c33092c52101acc7c316..af93b59e60c62e7be67d49de7bf8675b02884c89 100644
--- a/src/plugins/debugger/debuggerstreamops.h
+++ b/src/plugins/debugger/debuggerstreamops.h
@@ -47,12 +47,12 @@ QDataStream &operator<<(QDataStream& stream, const StackFrame& frame);
 QDataStream &operator>>(QDataStream& stream, StackFrame &frame);
 QDataStream &operator<<(QDataStream& stream, const StackFrames& frames);
 QDataStream &operator>>(QDataStream& stream, StackFrames &frames);
-QDataStream &operator<<(QDataStream& stream, const BreakpointData &bps);
-QDataStream &operator>>(QDataStream& stream, BreakpointData &bps);
-QDataStream &operator<<(QDataStream& stream, const WatchData &bps);
-QDataStream &operator>>(QDataStream& stream, WatchData &bps);
-QDataStream &operator<<(QDataStream& stream, const WatchData &bps);
-QDataStream &operator>>(QDataStream& stream, WatchData &bps);
+QDataStream &operator<<(QDataStream& stream, const BreakpointData &data);
+QDataStream &operator>>(QDataStream& stream, BreakpointData &data);
+QDataStream &operator<<(QDataStream& stream, const BreakpointResponse &data);
+QDataStream &operator>>(QDataStream& stream, BreakpointResponse &data);
+QDataStream &operator<<(QDataStream& stream, const WatchData &data);
+QDataStream &operator>>(QDataStream& stream, WatchData &data);
 
 } // namespace Internal
 } // namespace Debugger
diff --git a/src/plugins/debugger/debuggeruiswitcher.cpp b/src/plugins/debugger/debuggeruiswitcher.cpp
index 80aa00fb91880cb13db3fda6ed86ccf85c0d745e..635bfb60e43ba530be216adb4781bf3782a32999 100644
--- a/src/plugins/debugger/debuggeruiswitcher.cpp
+++ b/src/plugins/debugger/debuggeruiswitcher.cpp
@@ -140,6 +140,7 @@ struct DebuggerUISwitcherPrivate
     QWeakPointer<ProjectExplorer::RunConfiguration> m_previousRunConfiguration;
 
     bool m_initialized;
+    QSettings *m_settings;
 };
 
 DebuggerUISwitcherPrivate::DebuggerUISwitcherPrivate(DebuggerUISwitcher *q)
@@ -155,6 +156,7 @@ DebuggerUISwitcherPrivate::DebuggerUISwitcherPrivate(DebuggerUISwitcher *q)
     , m_viewsMenu(0)
     , m_debugMenu(0)
     , m_initialized(false)
+    , m_settings(0)
 {
 }
 
@@ -583,44 +585,39 @@ QWidget *DebuggerUISwitcher::createContents(BaseMode *mode)
     return splitter;
 }
 
-void DebuggerUISwitcher::writeSettings(QSettings *settings) const
+void DebuggerUISwitcher::writeSettings() const
 {
-    {
-        settings->beginGroup(QLatin1String("DebugMode.CppMode"));
-        QHashIterator<QString, QVariant> it(d->m_dockWidgetActiveStateCpp);
-        while (it.hasNext()) {
-            it.next();
-            settings->setValue(it.key(), it.value());
-        }
-        settings->endGroup();
+    d->m_settings->beginGroup(QLatin1String("DebugMode.CppMode"));
+    QHashIterator<QString, QVariant> it(d->m_dockWidgetActiveStateCpp);
+    while (it.hasNext()) {
+        it.next();
+        d->m_settings->setValue(it.key(), it.value());
     }
-    {
-        settings->beginGroup(QLatin1String("DebugMode.CppQmlMode"));
-        QHashIterator<QString, QVariant> it(d->m_dockWidgetActiveStateQmlCpp);
-        while (it.hasNext()) {
-            it.next();
-            settings->setValue(it.key(), it.value());
-        }
-        settings->endGroup();
+    d->m_settings->endGroup();
+
+    d->m_settings->beginGroup(QLatin1String("DebugMode.CppQmlMode"));
+    it = QHashIterator<QString, QVariant>(d->m_dockWidgetActiveStateQmlCpp);
+    while (it.hasNext()) {
+        it.next();
+        d->m_settings->setValue(it.key(), it.value());
     }
+    d->m_settings->endGroup();
 }
 
-void DebuggerUISwitcher::readSettings(QSettings *settings)
+void DebuggerUISwitcher::readSettings()
 {
     d->m_dockWidgetActiveStateCpp.clear();
     d->m_dockWidgetActiveStateQmlCpp.clear();
 
-    settings->beginGroup(QLatin1String("DebugMode.CppMode"));
-    foreach (const QString &key, settings->childKeys()) {
-        d->m_dockWidgetActiveStateCpp.insert(key, settings->value(key));
-    }
-    settings->endGroup();
+    d->m_settings->beginGroup(QLatin1String("DebugMode.CppMode"));
+    foreach (const QString &key, d->m_settings->childKeys())
+        d->m_dockWidgetActiveStateCpp.insert(key, d->m_settings->value(key));
+    d->m_settings->endGroup();
 
-    settings->beginGroup(QLatin1String("DebugMode.CppQmlMode"));
-    foreach (const QString &key, settings->childKeys()) {
-        d->m_dockWidgetActiveStateQmlCpp.insert(key, settings->value(key));
-    }
-    settings->endGroup();
+    d->m_settings->beginGroup(QLatin1String("DebugMode.CppQmlMode"));
+    foreach (const QString &key, d->m_settings->childKeys())
+        d->m_dockWidgetActiveStateQmlCpp.insert(key, d->m_settings->value(key));
+    d->m_settings->endGroup();
 
     // reset initial settings when there are none yet
     DebuggerLanguages langs = d->m_activeDebugLanguages;
@@ -637,10 +634,11 @@ void DebuggerUISwitcher::readSettings(QSettings *settings)
 
 void DebuggerUISwitcher::initialize(QSettings *settings)
 {
+    d->m_settings = settings;
     createViewsMenuItems();
 
     emit dockResetRequested(AnyLanguage);
-    readSettings(settings);
+    readSettings();
 
     updateUi();
 
diff --git a/src/plugins/debugger/debuggeruiswitcher.h b/src/plugins/debugger/debuggeruiswitcher.h
index 4b243db8432b4d35859ba06488afe9f0c7e99c43..1700e12439fcd3fb1eee8f2bd4625bf9abe9405d 100644
--- a/src/plugins/debugger/debuggeruiswitcher.h
+++ b/src/plugins/debugger/debuggeruiswitcher.h
@@ -130,8 +130,8 @@ private slots:
 public slots:
     void updateActiveLanguages();
     void updateDockWidgetSettings();
-    void readSettings(QSettings *settings);
-    void writeSettings(QSettings *settings) const;
+    void readSettings();
+    void writeSettings() const;
 
 private:
     // Used by MainWindow
diff --git a/src/plugins/debugger/gdb/abstractplaingdbadapter.cpp b/src/plugins/debugger/gdb/abstractplaingdbadapter.cpp
index 241776dc480198490334b2e910e613d219e97146..e4e7ea16a93aafc468eb5929c658fcf5d3d481dd 100644
--- a/src/plugins/debugger/gdb/abstractplaingdbadapter.cpp
+++ b/src/plugins/debugger/gdb/abstractplaingdbadapter.cpp
@@ -31,6 +31,7 @@
 #include "gdbmi.h"
 #include "gdbengine.h"
 #include "debuggeractions.h"
+#include "debuggercore.h"
 #include "debuggerstringutils.h"
 
 #include <utils/qtcassert.h>
@@ -96,7 +97,7 @@ void AbstractPlainGdbAdapter::handleExecRun(const GdbResponse &response)
         showMessage(_("INFERIOR STARTED"));
         showMessage(msgInferiorSetupOk(), StatusBar);
         // FIXME: That's the wrong place for it.
-        if (theDebuggerBoolSetting(EnableReverseDebugging))
+        if (debuggerCore()->boolSetting(EnableReverseDebugging))
             m_engine->postCommand("target record");
     } else {
         QString msg = fromLocalEncoding(response.data.findChild("msg").data());
diff --git a/src/plugins/debugger/gdb/classicgdbengine.cpp b/src/plugins/debugger/gdb/classicgdbengine.cpp
index 8f227d2f53e0582cec479d3ea504e44445e3eb15..732122f3e2fad18486b026ed13f471032365c2df 100644
--- a/src/plugins/debugger/gdb/classicgdbengine.cpp
+++ b/src/plugins/debugger/gdb/classicgdbengine.cpp
@@ -273,7 +273,7 @@ void GdbEngine::updateSubItemClassic(const WatchData &data0)
         qDebug() << "IT'S A POINTER";
 #        endif
 
-        if (theDebuggerBoolSetting(AutoDerefPointers)) {
+        if (debuggerCore()->boolSetting(AutoDerefPointers)) {
             // Try automatic dereferentiation
             data.exp = "(*(" + data.exp + "))";
             data.type = data.type + "."; // FIXME: fragile HACK to avoid recursion
@@ -658,7 +658,7 @@ void GdbEngine::handleStackListLocalsClassic(const GdbResponse &response)
     // handleStop1, which passes on the frame as cookie. The whole stack
     // is not known at this point.
     QStringList uninitializedVariables;
-    if (theDebuggerAction(UseCodeModel)->isChecked()) {
+    if (debuggerCore()->action(UseCodeModel)->isChecked()) {
         const StackFrame frame =
             qVariantCanConvert<Debugger::Internal::StackFrame>(response.cookie)
                 ? qVariantValue<Debugger::Internal::StackFrame>(response.cookie)
diff --git a/src/plugins/debugger/gdb/coregdbadapter.cpp b/src/plugins/debugger/gdb/coregdbadapter.cpp
index 552d84cae2411a4c20cfc2e5a102104ebcdfd34f..77afb67a6546894e3aec9656d13c1880af5055ad 100644
--- a/src/plugins/debugger/gdb/coregdbadapter.cpp
+++ b/src/plugins/debugger/gdb/coregdbadapter.cpp
@@ -28,10 +28,12 @@
 **************************************************************************/
 
 #include "coregdbadapter.h"
-#include "gdbmi.h"
+
+#include "debuggercore.h"
 #include "debuggeractions.h"
-#include "gdbengine.h"
 #include "debuggerstringutils.h"
+#include "gdbmi.h"
+#include "gdbengine.h"
 
 #include <utils/qtcassert.h>
 
@@ -73,7 +75,7 @@ void CoreGdbAdapter::startAdapter()
         return;
 
     //if (m_executable.isEmpty()) {
-    //    DebuggerEngine::showMessageBox(QMessageBox::Warning,
+    //    showMessageBox(QMessageBox::Warning,
     //        tr("Error Loading Symbols"),
     //        tr("No executable to load symbols from specified."));
     //}
@@ -100,7 +102,7 @@ void CoreGdbAdapter::startAdapter()
         msg += _(" ");
         msg += tr("Try to specify the binary using the "
             "<i>Debug->Start Debugging->Attach to Core</i> dialog.");
-        DebuggerEngine::showMessageBox(QMessageBox::Warning,
+        showMessageBox(QMessageBox::Warning,
             tr("Loading core file failed"), msg);
         m_engine->notifyEngineSetupFailed();
     }
diff --git a/src/plugins/debugger/gdb/gdbengine.cpp b/src/plugins/debugger/gdb/gdbengine.cpp
index 089322f01987b40b3eb0c775da65eab0efabe6ae..fdae9ffc626d3bcadb739de2fff275c1a4fc33c5 100644
--- a/src/plugins/debugger/gdb/gdbengine.cpp
+++ b/src/plugins/debugger/gdb/gdbengine.cpp
@@ -191,11 +191,11 @@ GdbEngine::GdbEngine(const DebuggerStartParameters &startParameters)
     initializeVariables();
     m_gdbAdapter = createAdapter();
 
-    connect(theDebuggerAction(AutoDerefPointers), SIGNAL(valueChanged(QVariant)),
+    connect(debuggerCore()->action(AutoDerefPointers), SIGNAL(valueChanged(QVariant)),
             SLOT(reloadLocals()));
-    connect(theDebuggerAction(SortStructMembers), SIGNAL(valueChanged(QVariant)),
+    connect(debuggerCore()->action(SortStructMembers), SIGNAL(valueChanged(QVariant)),
             SLOT(reloadLocals()));
-    connect(theDebuggerAction(CreateFullBacktrace), SIGNAL(triggered()),
+    connect(debuggerCore()->action(CreateFullBacktrace), SIGNAL(triggered()),
             SLOT(createFullBacktrace()));
 }
 
@@ -456,9 +456,8 @@ void GdbEngine::handleResponse(const QByteArray &buff)
                 // line="1584",shlib="/../libFoo_debug.dylib",times="0"}
                 const GdbMi bkpt = result.findChild("bkpt");
                 const int number = bkpt.findChild("number").data().toInt();
-                BreakpointData *data = breakHandler()->findBreakpointByNumber(number);
-                setBreakpointDataFromOutput(data, bkpt);
-                breakHandler()->updateMarkers();
+                BreakpointId id = breakHandler()->findBreakpointByNumber(number);
+                setBreakpointDataFromOutput(id, bkpt);
             } else {
                 qDebug() << "IGNORED ASYNC OUTPUT"
                     << asyncClass << result.toString();
@@ -809,7 +808,7 @@ void GdbEngine::flushCommand(const GdbCommand &cmd0)
 
 int GdbEngine::commandTimeoutTime() const
 {
-    int time = theDebuggerAction(GdbWatchdogTimeout)->value().toInt();
+    int time = debuggerCore()->action(GdbWatchdogTimeout)->value().toInt();
     return 1000 * qMax(20, time);
 }
 
@@ -917,7 +916,7 @@ void GdbEngine::handleResultRecord(GdbResponse *response)
     }
 
     GdbCommand cmd = m_cookieForToken.take(token);
-    if (theDebuggerBoolSetting(LogTimeStamps)) {
+    if (debuggerCore()->boolSetting(LogTimeStamps)) {
         showMessage(_("Response time: %1: %2 s")
             .arg(_(cmd.command))
             .arg(cmd.postTime.msecsTo(QTime::currentTime()) / 1000.),
@@ -1124,7 +1123,7 @@ static bool isExitedReason(const QByteArray &reason)
 void GdbEngine::handleAqcuiredInferior()
 {
     // Reverse debugging. FIXME: Should only be used when available.
-    //if (theDebuggerBoolSetting(EnableReverseDebugging))
+    //if (debuggerCore()->boolSetting(EnableReverseDebugging))
     //    postCommand("target response");
 
     tryLoadDebuggingHelpers();
@@ -1132,16 +1131,16 @@ void GdbEngine::handleAqcuiredInferior()
 #    ifndef Q_OS_MAC
     // intentionally after tryLoadDebuggingHelpers(),
     // otherwise we'd interrupt solib loading.
-    if (theDebuggerBoolSetting(AllPluginBreakpoints)) {
+    if (debuggerCore()->boolSetting(AllPluginBreakpoints)) {
         postCommand("set auto-solib-add on");
         postCommand("set stop-on-solib-events 0");
         postCommand("sharedlibrary .*");
-    } else if (theDebuggerBoolSetting(SelectedPluginBreakpoints)) {
+    } else if (debuggerCore()->boolSetting(SelectedPluginBreakpoints)) {
         postCommand("set auto-solib-add on");
         postCommand("set stop-on-solib-events 1");
         postCommand("sharedlibrary "
           + theDebuggerStringSetting(SelectedPluginBreakpointsPattern));
-    } else if (theDebuggerBoolSetting(NoPluginBreakpoints)) {
+    } else if (debuggerCore()->boolSetting(NoPluginBreakpoints)) {
         // should be like that already
         postCommand("set auto-solib-add off");
         postCommand("set stop-on-solib-events 0");
@@ -1240,7 +1239,7 @@ void GdbEngine::handleStopResponse(const GdbMi &data)
             postCommand("set stop-on-solib-events 0");
 #if 0
             // The related code (handleAqcuiredInferior()) is disabled as well.
-            if (theDebuggerBoolSetting(SelectedPluginBreakpoints)) {
+            if (debuggerCore()->boolSetting(SelectedPluginBreakpoints)) {
                 QString dataStr = _(data.toString());
                 showMessage(_("SHARED LIBRARY EVENT: ") + dataStr);
                 QString pat = theDebuggerStringSetting(SelectedPluginBreakpointsPattern);
@@ -1297,7 +1296,7 @@ void GdbEngine::handleStopResponse(const GdbMi &data)
 
     // Jump over well-known frames.
     static int stepCounter = 0;
-    if (theDebuggerBoolSetting(SkipKnownFrames)) {
+    if (debuggerCore()->boolSetting(SkipKnownFrames)) {
         if (reason == "end-stepping-range" || reason == "function-finished") {
             GdbMi frame = data.findChild("frame");
             //showMessage(frame.toString());
@@ -1417,7 +1416,7 @@ void GdbEngine::handleStop1(const GdbMi &data)
     } else {
         QString reasontr = tr("Stopped: \"%1\"").arg(_(reason));
         if (reason == "signal-received"
-            && theDebuggerBoolSetting(UseMessageBoxForSignals)) {
+            && debuggerCore()->boolSetting(UseMessageBoxForSignals)) {
             QByteArray name = data.findChild("signal-name").data();
             QByteArray meaning = data.findChild("signal-meaning").data();
             // Ignore these as they are showing up regularly when
@@ -1721,16 +1720,11 @@ int GdbEngine::currentFrame() const
     return stackHandler()->currentIndex();
 }
 
-static inline QString msgNoBinaryForToolChain(int tc)
+QString msgNoBinaryForToolChain(int tc)
 {
-    const ProjectExplorer::ToolChainType toolChain = static_cast<ProjectExplorer::ToolChainType>(tc);
-    const QString toolChainName = ProjectExplorer::ToolChain::toolChainName(toolChain);
-    return GdbEngine::tr("There is no gdb binary available for '%1'").arg(toolChainName);
-}
-
-static QString gdbBinaryForToolChain(int toolChain)
-{
-    return DebuggerSettings::instance()->gdbBinaryToolChainMap().key(toolChain);
+    using namespace ProjectExplorer;
+    return GdbEngine::tr("There is no gdb binary available for '%1'")
+        .arg(ToolChain::toolChainName(ToolChainType(tc)));
 }
 
 AbstractGdbAdapter *GdbEngine::createAdapter()
@@ -1770,17 +1764,16 @@ AbstractGdbAdapter *GdbEngine::createAdapter()
 
 void GdbEngine::setupEngine()
 {
-    //qDebug() << "GDB START DEBUGGER";
     QTC_ASSERT(state() == EngineSetupRequested, qDebug() << state());
     QTC_ASSERT(m_debuggingHelperState == DebuggingHelperUninitialized, /**/);
 
-    //qDebug() << "CREATED ADAPTER: " << m_gdbAdapter;
-
     if (m_gdbAdapter->dumperHandling() != AbstractGdbAdapter::DumperNotAvailable) {
-        connect(theDebuggerAction(UseDebuggingHelpers), SIGNAL(valueChanged(QVariant)),
-                this, SLOT(setUseDebuggingHelpers(QVariant)));
-        connect(theDebuggerAction(DebugDebuggingHelpers), SIGNAL(valueChanged(QVariant)),
-                this, SLOT(setDebugDebuggingHelpersClassic(QVariant)));
+        connect(debuggerCore()->action(UseDebuggingHelpers),
+            SIGNAL(valueChanged(QVariant)),
+            SLOT(setUseDebuggingHelpers(QVariant)));
+        connect(debuggerCore()->action(DebugDebuggingHelpers),
+            SIGNAL(valueChanged(QVariant)),
+            SLOT(setDebugDebuggingHelpersClassic(QVariant)));
     }
 
     QTC_ASSERT(state() == EngineSetupRequested, /**/);
@@ -2047,7 +2040,7 @@ void GdbEngine::setTokenBarrier()
     }
     PENDING_DEBUG("\n--- token barrier ---\n");
     showMessage(_("--- token barrier ---"), LogMiscInput);
-    if (theDebuggerBoolSetting(LogTimeStamps))
+    if (debuggerCore()->boolSetting(LogTimeStamps))
         showMessage(LogWindow::logTimeStamp(), LogMiscInput);
     m_oldestAcceptableToken = currentToken();
 }
@@ -2059,31 +2052,31 @@ void GdbEngine::setTokenBarrier()
 //
 //////////////////////////////////////////////////////////////////////
 
-void GdbEngine::setBreakpointDataFromOutput(BreakpointData *data, const GdbMi &bkpt)
+void GdbEngine::setBreakpointDataFromOutput(BreakpointId id, const GdbMi &bkpt)
 {
     if (!bkpt.isValid())
         return;
-    if (!data)
-        return;
-    data->pending = false;
-    data->bpMultiple = false;
-    data->bpEnabled = true;
-    data->bpCondition.clear();
+
+    BreakpointResponse response;
+    //data->pending = false;
+    response.bpMultiple = false;
+    response.bpEnabled = true;
+    response.bpCondition.clear();
     QByteArray file, fullName;
     foreach (const GdbMi &child, bkpt.children()) {
         if (child.hasName("number")) {
-            data->bpNumber = child.data();
+            response.bpNumber = child.data().toInt();
         } else if (child.hasName("func")) {
-            data->bpFuncName = _(child.data());
+            response.bpFuncName = _(child.data());
         } else if (child.hasName("addr")) {
             // <MULTIPLE> happens in constructors. In this case there are
             // _two_ fields named "addr" in the response. On Linux that is...
             if (child.data().startsWith("0x")) {
-                data->bpAddress = child.data().mid(2).toULongLong(0, 16);
+                response.bpAddress = child.data().mid(2).toULongLong(0, 16);
             } else {
-                data->bpState = child.data();
+                response.bpState = child.data();
                 if (child.data() == "<MULTIPLE>")
-                    data->bpMultiple = true;
+                    response.bpMultiple = true;
             }
         } else if (child.hasName("file")) {
             file = child.data();
@@ -2092,18 +2085,20 @@ void GdbEngine::setBreakpointDataFromOutput(BreakpointData *data, const GdbMi &b
         } else if (child.hasName("line")) {
             bool ok;
             const int lineNumber = child.data().toInt(&ok);
-            data->bpLineNumber = lineNumber;
-            if (ok && data->bpCorrectedLineNumber <= 0)
-                data->setMarkerLineNumber(lineNumber);
+            response.bpLineNumber = lineNumber;
+            //if (ok && response.bpCorrectedLineNumber <= 0)
+            //    data->setMarkerLineNumber(lineNumber);
         } else if (child.hasName("cond")) {
-            data->bpCondition = child.data();
+            response.bpCondition = child.data();
             // gdb 6.3 likes to "rewrite" conditions. Just accept that fact.
-            if (data->bpCondition != data->condition && data->conditionsMatch())
-                data->condition = data->bpCondition;
+            //if (response.bpCondition != data->condition()
+            //        && data->conditionsMatch(response.bpCondition))
+            //    data->setCondition(response.bpCondition);
         } else if (child.hasName("enabled")) {
-            data->bpEnabled = (child.data() == "y");
+            response.bpEnabled = (child.data() == "y");
         } else if (child.hasName("pending")) {
-            data->pending = true;
+            //data->setState(BreakpointPending);
+            breakHandler()->setState(id, BreakpointPending);
             // Any content here would be interesting only if we did accept
             // spontaneously appearing breakpoints (user using gdb commands).
         } else if (child.hasName("at")) {
@@ -2111,9 +2106,9 @@ void GdbEngine::setBreakpointDataFromOutput(BreakpointData *data, const GdbMi &b
             QByteArray ba = child.data();
             if (ba.startsWith('<') && ba.endsWith('>'))
                 ba = ba.mid(1, ba.size() - 2);
-            data->bpFuncName = _(ba);
+            response.bpFuncName = _(ba);
         } else if (child.hasName("thread")) {
-            data->bpThreadSpec = child.data();
+            response.bpThreadSpec = child.data();
         } else if (child.hasName("type")) {
             // FIXME: This should not change the type.
             //if (child.data().contains("reakpoint")) // "breakpoint", "hw breakpoint"
@@ -2130,15 +2125,18 @@ void GdbEngine::setBreakpointDataFromOutput(BreakpointData *data, const GdbMi &b
     QString name;
     if (!fullName.isEmpty()) {
         name = cleanupFullName(QFile::decodeName(fullName));
-        if (data->markerFileName().isEmpty())
-            data->setMarkerFileName(name);
+        response.bpFileName = name;
+        //if (data->markerFileName().isEmpty())
+        //    data->setMarkerFileName(name);
     } else {
         name = QFile::decodeName(file);
         // Use fullName() once we have a mapping which is more complete than
         // gdb's own. No point in assigning markerFileName for now.
     }
     if (!name.isEmpty())
-        data->bpFileName = name;
+        response.bpFileName = name;
+
+    breakHandler()->setResponse(id, response);
 }
 
 QString GdbEngine::breakLocation(const QString &file) const
@@ -2150,78 +2148,50 @@ QString GdbEngine::breakLocation(const QString &file) const
     return where;
 }
 
-static inline QByteArray bpAddressSpec(quint64 address)
+static QByteArray addressSpec(quint64 address)
 {
     return "*0x" + QByteArray::number(address, 16);
 }
 
-QByteArray GdbEngine::breakpointLocation(const BreakpointData *data)
+QByteArray GdbEngine::breakpointLocation(BreakpointId id)
 {
-    if (!data->funcName.isEmpty()) {
-        if (data->funcName == QLatin1String(BreakpointData::throwFunction))
-            return QByteArray("__cxa_throw");
-        if (data->funcName == QLatin1String(BreakpointData::catchFunction))
-            return QByteArray("__cxa_begin_catch");
-        return data->funcName.toLatin1();
-    }
-    if (data->address)
-        return bpAddressSpec(data->address);
+    BreakHandler *handler = breakHandler();
+    QByteArray functionName = handler->functionName(id).toUtf8();
+    if (!functionName.isEmpty()) {
+        // FIXME: Use the types.
+        if (functionName == BreakpointData::throwFunction)
+            return "__cxa_throw";
+        if (functionName == BreakpointData::catchFunction)
+            return "__cxa_begin_catch";
+        return functionName;
+    }
+    quint64 address = handler->address(id);
+    if (address)
+        return addressSpec(address);
     // In this case, data->funcName is something like '*0xdeadbeef'
-    if (data->lineNumber == 0)
-        return data->funcName.toLatin1();
-    QString loc = data->useFullPath ? data->fileName : breakLocation(data->fileName);
+    int lineNumber = handler->lineNumber(id);
+    if (lineNumber == 0)
+        return functionName;
+    QString fileName = handler->fileName(id);
+    if (handler->useFullPath(id))
+        fileName = breakLocation(fileName);
     // The argument is simply a C-quoted version of the argument to the
     // non-MI "break" command, including the "original" quoting it wants.
-    return "\"\\\"" + GdbMi::escapeCString(loc).toLocal8Bit() + "\\\":"
-        + QByteArray::number(data->lineNumber) + '"';
-}
-
-void GdbEngine::sendInsertBreakpoint(int index)
-{
-    const BreakpointData *data = breakHandler()->at(index);
-    // Set up fallback in case of pending breakpoints which aren't handled
-    // by the MI interface.
-    if (data->type == Watchpoint) {
-        postCommand("watch " + bpAddressSpec(data->address),
-            NeedsStop | RebuildBreakpointModel,
-            CB(handleWatchInsert), index);
-        return;
-    }
-
-    QByteArray cmd;
-    if (m_isMacGdb) {
-        cmd = "-break-insert -l -1 -f ";
-    } else if (m_gdbAdapter->isTrkAdapter()) {
-        cmd = "-break-insert -h -f ";
-    } 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 {
-        cmd = "-break-insert ";
-    }
-    //if (!data->condition.isEmpty())
-    //    cmd += "-c " + data->condition + ' ';
-    cmd += breakpointLocation(data);
-    postCommand(cmd, NeedsStop | RebuildBreakpointModel,
-        CB(handleBreakInsert1), index);
+    return "\"\\\"" + GdbMi::escapeCString(fileName).toLocal8Bit() + "\\\":"
+        + QByteArray::number(lineNumber) + '"';
 }
 
 void GdbEngine::handleWatchInsert(const GdbResponse &response)
 {
-    int index = response.cookie.toInt();
+    const int id = response.cookie.toInt();
     if (response.resultClass == GdbResultDone) {
         // "Hardware watchpoint 2: *0xbfffed40\n"
         QByteArray ba = response.data.findChild("consolestreamoutput").data();
         if (ba.startsWith("Hardware watchpoint ")) {
             const int pos = ba.indexOf(':', 20);
-            BreakpointData *data = breakHandler()->at(index);
-            data->bpNumber = ba.mid(20, pos - 20);
-            breakHandler()->updateMarkers();
+            BreakpointResponse response = breakHandler()->response(id);
+            response.bpNumber = ba.mid(20, pos - 20).toInt();
+            breakHandler()->setResponse(id, response);
         } else {
             showMessage(_("CANNOT PARSE WATCHPOINT FROM" + ba));
         }
@@ -2230,19 +2200,19 @@ void GdbEngine::handleWatchInsert(const GdbResponse &response)
 
 void GdbEngine::handleBreakInsert1(const GdbResponse &response)
 {
-    int index = response.cookie.toInt();
-    BreakpointData *data = breakHandler()->at(index);
+    const int id = response.cookie.toInt();
     if (response.resultClass == GdbResultDone) {
         // Interesting only on Mac?
         GdbMi bkpt = response.data.findChild("bkpt");
-        setBreakpointDataFromOutput(data, bkpt);
+        setBreakpointDataFromOutput(id, bkpt);
+        notifyBreakpointInsertOk(id);
     } 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(data);
+        QByteArray cmd = "break " + breakpointLocation(id);
         postCommand(cmd, NeedsStop | RebuildBreakpointModel,
-            CB(handleBreakInsert2), index);
+            CB(handleBreakInsert2), id);
     }
 }
 
@@ -2262,9 +2232,11 @@ void GdbEngine::handleBreakInsert2(const GdbResponse &response)
 
 void GdbEngine::reloadBreakListInternal()
 {
+/*
     postCommand("-break-list",
         NeedsStop | RebuildBreakpointModel,
         CB(handleBreakList));
+*/
 }
 
 void GdbEngine::handleBreakList(const GdbResponse &response)
@@ -2305,16 +2277,17 @@ void GdbEngine::handleBreakList(const GdbMi &table)
     }
 
     foreach (const GdbMi &bkpt, bkpts) {
-        BreakpointData temp;
-        setBreakpointDataFromOutput(&temp, bkpt);
-        BreakpointData *data = breakHandler()->findSimilarBreakpoint(&temp);
+        BreakpointResponse needle;
+        needle.bpFileName = _("xx");
+        BreakpointId id = breakHandler()->findSimilarBreakpoint(needle);
         //qDebug() << "\n\nGOT: " << bkpt.toString() << '\n' << temp.toString();
-        if (data) {
+        // FIXME: use setBreakpointDataFromOutput(BreakpointId id, const GdbMi &bkpt)
+        if (id != BreakpointId(-1)) {
             //qDebug() << "  FROM: " << data->toString();
-            setBreakpointDataFromOutput(data, bkpt);
+            setBreakpointDataFromOutput(id, bkpt);
             //qDebug() << "  TO: " << data->toString();
         } else {
-            //qDebug() << "  NOTHING SUITABLE FOUND";
+            qDebug() << "  NOTHING SUITABLE FOUND";
             showMessage(_("CANNOT FIND BP: " + bkpt.toString()));
         }
     }
@@ -2331,7 +2304,6 @@ void GdbEngine::handleBreakDisable(const GdbResponse &response)
 
 void GdbEngine::handleBreakIgnore(const GdbResponse &response)
 {
-    int bpNumber = response.cookie.toInt();
     // gdb 6.8:
     // ignore 2 0:
     // ~"Will stop next time breakpoint 2 is reached.\n"
@@ -2342,8 +2314,7 @@ void GdbEngine::handleBreakIgnore(const GdbResponse &response)
     // 29^done
     //
     // gdb 6.3 does not produce any console output
-    BreakpointData *data = breakHandler()->findBreakpointByNumber(bpNumber);
-    if (response.resultClass == GdbResultDone && data) {
+    if (response.resultClass == GdbResultDone) {
         QString msg = _(response.data.findChild("consolestreamoutput").data());
         //if (msg.contains(__("Will stop next time breakpoint"))) {
         //    data->bpIgnoreCount = _("0");
@@ -2351,36 +2322,31 @@ void GdbEngine::handleBreakIgnore(const GdbResponse &response)
         //    data->bpIgnoreCount = data->ignoreCount;
         //}
         // FIXME: this assumes it is doing the right thing...
-        data->bpIgnoreCount = data->ignoreCount;
-        breakHandler()->updateMarkers();
+        breakHandler()->ackIgnoreCount(BreakpointId(response.cookie.toInt()));
     }
 }
 
 void GdbEngine::handleBreakCondition(const GdbResponse &response)
 {
-    int bpNumber = response.cookie.toInt();
-    BreakpointData *data = breakHandler()->findBreakpointByNumber(bpNumber);
+    const int id = response.cookie.toInt();
     if (response.resultClass == GdbResultDone) {
         // We just assume it was successful. Otherwise we had to parse
         // the output stream data.
         //qDebug() << "HANDLE BREAK CONDITION" << bpNumber << data->condition;
-        data->bpCondition = data->condition;
+        breakHandler()->ackCondition(id);
     } else {
         QByteArray msg = response.data.findChild("msg").data();
         // happens on Mac
         if (1 || msg.startsWith("Error parsing breakpoint condition. "
                 " Will try again when we hit the breakpoint.")) {
             //qDebug() << "ERROR BREAK CONDITION" << bpNumber << data->condition;
-            data->bpCondition = data->condition;
+            breakHandler()->ackCondition(id);
         }
     }
-    breakHandler()->updateMarkers();
 }
 
-void GdbEngine::extractDataFromInfoBreak(const QString &output, BreakpointData *data)
+void GdbEngine::extractDataFromInfoBreak(const QString &output, BreakpointId id)
 {
-    data->bpFileName = _("<MULTIPLE>");
-
     //qDebug() << output;
     if (output.isEmpty())
         return;
@@ -2401,10 +2367,15 @@ void GdbEngine::extractDataFromInfoBreak(const QString &output, BreakpointData *
     QRegExp re(_("MULTIPLE.*(0x[0-9a-f]+) in (.*)\\s+at (.*):([\\d]+)([^\\d]|$)"));
     re.setMinimal(true);
 
+    BreakpointResponse response;
+    response.bpFileName = _("<MULTIPLE>");
+
+    QString requestedFileName = breakHandler()->fileName(id);
+
     if (re.indexIn(output) != -1) {
-        data->bpAddress = re.cap(1).toULongLong(0, 16);
-        data->bpFuncName = re.cap(2).trimmed();
-        data->bpLineNumber = re.cap(4).toInt();
+        response.bpAddress = re.cap(1).toULongLong(0, 16);
+        response.bpFuncName = re.cap(2).trimmed();
+        response.bpLineNumber = re.cap(4).toInt();
         QString full = fullName(re.cap(3));
         if (full.isEmpty()) {
             // FIXME: This happens without UsePreciseBreakpoints regularly.
@@ -2421,18 +2392,19 @@ void GdbEngine::extractDataFromInfoBreak(const QString &output, BreakpointData *
         // for "/full/path/to/foo.cpp". In this case, using the requested
         // instead of the acknowledged name makes sense as it will allow setting
         // the marker in more cases.
-        if (data->fileName.endsWith(full))
-            full = data->fileName;
-        data->setMarkerLineNumber(data->bpLineNumber);
-        if (data->markerFileName().isEmpty()) {
-            qDebug() << "111";
-            data->setMarkerFileName(full);
-        }
-        data->bpFileName = full;
+        if (requestedFileName.endsWith(full))
+            full = requestedFileName;
+        //response.bpCorrectedLineNumber = breakHandler()->lineNumber();
+        //if (data->markerFileName().isEmpty()) {
+        //    qDebug() << "111";
+        //    data->setMarkerFileName(full);
+        //}
+        response.bpFileName = full;
     } else {
         qDebug() << "COULD NOT MATCH " << re.pattern() << " AND " << output;
-        data->bpNumber = "<unavailable>";
+        response.bpNumber = -1; // <unavailable>
     }
+    breakHandler()->setResponse(id, response);
 }
 
 void GdbEngine::handleBreakInfo(const GdbResponse &response)
@@ -2440,13 +2412,10 @@ void GdbEngine::handleBreakInfo(const GdbResponse &response)
     if (response.resultClass == GdbResultDone) {
         // Old-style output for multiple breakpoints, presumably in a
         // constructor.
-        const int bpNumber = response.cookie.toInt();
-        BreakpointData *data = breakHandler()->findBreakpointByNumber(bpNumber);
-        if (data) {
-            QString str = QString::fromLocal8Bit(
-                response.data.findChild("consolestreamoutput").data());
-            extractDataFromInfoBreak(str, data);
-        }
+        const BreakpointId id(response.cookie.toInt());
+        const QString str = QString::fromLocal8Bit(
+            response.data.findChild("consolestreamoutput").data());
+        extractDataFromInfoBreak(str, id);
     }
 }
 
@@ -2456,20 +2425,34 @@ void GdbEngine::handleInfoLine(const GdbResponse &response)
         // Old-style output: "Line 1102 of \"simple/app.cpp\" starts
         // at address 0x80526aa <_Z10...+131> and ends at 0x80526b5
         // <_Z10testQStackv+142>.\n"
-        const int bpNumber = response.cookie.toInt();
-        BreakpointData *data = breakHandler()->findBreakpointByNumber(bpNumber);
-        if (!data)
-            return;
         QByteArray ba = response.data.findChild("consolestreamoutput").data();
         const int pos = ba.indexOf(' ', 5);
         if (ba.startsWith("Line ") && pos != -1) {
             const int line = ba.mid(5, pos - 5).toInt();
-            data->bpCorrectedLineNumber = line;
-            data->setMarkerLineNumber(line);
+            const BreakpointId id = response.cookie.toInt();
+            BreakpointResponse br = breakHandler()->response(id);
+            br.bpLineNumber = line;
+            breakHandler()->setResponse(id, br);
         }
     }
 }
 
+
+bool GdbEngine::stateAcceptsBreakpointChanges() const
+{
+    switch (state()) {
+    case InferiorSetupRequested:
+    case InferiorRunRequested:
+    case InferiorRunOk:
+    case InferiorStopRequested:
+    case InferiorStopOk:
+        return true;
+    default:
+        return false;
+    }
+}
+
+/*
 void GdbEngine::attemptBreakpointSynchronization()
 {
     QTC_ASSERT(!m_sourcesListUpdating,
@@ -2518,19 +2501,6 @@ void GdbEngine::attemptBreakpointSynchronization()
         }
     }
 
-    foreach (BreakpointData *data, handler->takeRemovedBreakpoints()) {
-        QByteArray bpNumber = data->bpNumber;
-        if (!bpNumber.trimmed().isEmpty()) {
-            showMessage(_("DELETING BP " + bpNumber + " IN "
-                + data->markerFileName().toLocal8Bit()));
-            postCommand("-break-delete " + bpNumber,
-                NeedsStop | RebuildBreakpointModel);
-        } else {
-            showMessage(_("QUIETLY REMOVING UNNUMBERED BREAKPOINT"));
-        }
-        delete data;
-    }
-
     for (int index = 0; index != handler->size(); ++index) {
         BreakpointData *data = handler->at(index);
         if (data->bpNumber.isEmpty()) { // Unset breakpoint?
@@ -2540,14 +2510,14 @@ void GdbEngine::attemptBreakpointSynchronization()
             if (data->bpMultiple && data->bpFileName.isEmpty()) {
                 postCommand("info break " + data->bpNumber,
                     NeedsStop | RebuildBreakpointModel,
-                    CB(handleBreakInfo), data->bpNumber.toInt());
+                    CB(handleBreakInfo), id);
                 continue;
             }
             if (data->condition != data->bpCondition && !data->conditionsMatch()) {
                 // Update conditions if needed.
                 postCommand("condition " + data->bpNumber + ' '  + data->condition,
                     NeedsStop | RebuildBreakpointModel,
-                    CB(handleBreakCondition), data->bpNumber.toInt());
+                    CB(handleBreakCondition), id);
             }
             else // Because gdb won't do both changes at a time anyway.
             if (data->ignoreCount != data->bpIgnoreCount) {
@@ -2555,13 +2525,13 @@ void GdbEngine::attemptBreakpointSynchronization()
                 QByteArray ic = QByteArray::number(data->ignoreCount);
                 postCommand("ignore " + data->bpNumber + ' ' + ic,
                     NeedsStop | RebuildBreakpointModel,
-                    CB(handleBreakIgnore), data->bpNumber.toInt());
+                    CB(handleBreakIgnore), id);
                 continue;
             }
             if (!data->enabled && data->bpEnabled) {
                 postCommand("-break-disable " + data->bpNumber,
                     NeedsStop | RebuildBreakpointModel,
-                    CB(handleBreakDisable), data->bpNumber.toInt());
+                    CB(handleBreakDisable), id);
                 data->bpEnabled = false;
                 continue;
             }
@@ -2577,11 +2547,11 @@ void GdbEngine::attemptBreakpointSynchronization()
             if (data->bpAddress && data->bpCorrectedLineNumber == 0) {
                 // Prevent endless loop.
                 data->bpCorrectedLineNumber = -1;
-                if (theDebuggerBoolSetting(AdjustBreakpointLocations)) {
+                if (debuggerCore()->boolSetting(AdjustBreakpointLocations)) {
                     postCommand(
                         "info line *0x" + QByteArray::number(data->bpAddress, 16),
                         NeedsStop | RebuildBreakpointModel,
-                        CB(handleInfoLine), data->bpNumber.toInt());
+                        CB(handleInfoLine), id)
                 }
             }
         }
@@ -2589,10 +2559,71 @@ void GdbEngine::attemptBreakpointSynchronization()
 
     handler->updateMarkers();
 }
+*/
+
 
-bool GdbEngine::acceptsBreakpoint(const Internal::BreakpointData *br)
+bool GdbEngine::acceptsBreakpoint(BreakpointId id) const
 {
-    return !( br->fileName.endsWith(QLatin1String("js")) || br->fileName.endsWith(QLatin1String("qml")) );
+    const QString fileName = breakHandler()->fileName(id);
+    return !fileName.endsWith(QLatin1String("js"))
+        && !fileName.endsWith(QLatin1String("qml"));
+}
+
+void GdbEngine::insertBreakpoint(BreakpointId id)
+{
+    // Set up fallback in case of pending breakpoints which aren't handled
+    // by the MI interface.
+    BreakHandler *handler = breakHandler();
+    QTC_ASSERT(handler->state(id) == BreakpointInsertRequested, /**/);
+    handler->setState(id, BreakpointInsertProceeding);
+    if (handler->type(id) == Watchpoint) {
+        postCommand("watch " + addressSpec(handler->address(id)),
+            NeedsStop | RebuildBreakpointModel,
+            CB(handleWatchInsert), id);
+        return;
+    }
+
+    QByteArray cmd;
+    if (m_isMacGdb) {
+        cmd = "-break-insert -l -1 -f ";
+    } else if (m_gdbAdapter->isTrkAdapter()) {
+        cmd = "-break-insert -h -f ";
+    } else if (m_gdbVersion >= 70000) {
+        QByteArray spec = handler->threadSpec(id);
+        cmd = "-break-insert ";
+        if (!spec.isEmpty())
+            cmd += "-p " + spec;
+        cmd += " -f ";
+    } else if (m_gdbVersion >= 60800) {
+        // Probably some earlier version would work as well.
+        cmd = "-break-insert -f ";
+    } else {
+        cmd = "-break-insert ";
+    }
+    //if (!data->condition.isEmpty())
+    //    cmd += "-c " + data->condition + ' ';
+    cmd += breakpointLocation(id);
+    postCommand(cmd, NeedsStop | RebuildBreakpointModel,
+        CB(handleBreakInsert1), id);
+}
+
+void GdbEngine::changeBreakpoint(BreakpointId)
+{
+    QTC_ASSERT(false, return);
+}
+
+void GdbEngine::removeBreakpoint(BreakpointId id)
+{
+    BreakHandler *handler = breakHandler();
+    QTC_ASSERT(handler->state(id) == BreakpointRemoveRequested, /**/);
+    handler->setState(id, BreakpointRemoveProceeding);
+    BreakpointResponse br = handler->response(id);
+    showMessage(_("DELETING BP %1 IN ").arg(br.bpNumber)
+        + handler->markerFileName(id));
+    postCommand("-break-delete " + QByteArray::number(br.bpNumber),
+        NeedsStop | RebuildBreakpointModel);
+    // Pretend it succeeds without waiting for response. Feels better.
+    handler->notifyBreakpointRemoveOk(id);
 }
 
 
@@ -2806,7 +2837,7 @@ void GdbEngine::reloadStack(bool forceGotoLocation)
 {
     PENDING_DEBUG("RELOAD STACK");
     QByteArray cmd = "-stack-list-frames";
-    int stackDepth = theDebuggerAction(MaximalStackDepth)->value().toInt();
+    int stackDepth = debuggerCore()->action(MaximalStackDepth)->value().toInt();
     if (stackDepth && !m_gdbAdapter->isTrkAdapter())
         cmd += " 0 " + QByteArray::number(stackDepth);
     // FIXME: gdb 6.4 symbianelf likes to be asked twice. The first time it
@@ -2891,8 +2922,8 @@ void GdbEngine::handleStackListFrames(const GdbResponse &response)
     }
 
     bool canExpand = !cookie.isFull
-        && (n >= theDebuggerAction(MaximalStackDepth)->value().toInt());
-    theDebuggerAction(ExpandStack)->setEnabled(canExpand);
+        && (n >= debuggerCore()->action(MaximalStackDepth)->value().toInt());
+    debuggerCore()->action(ExpandStack)->setEnabled(canExpand);
     stackHandler()->setFrames(stackFrames, canExpand);
 
     // We can't jump to any file if we don't have any frames.
@@ -2904,7 +2935,7 @@ void GdbEngine::handleStackListFrames(const GdbResponse &response)
     // a few exceptions:
 
     // Always jump to frame #0 when stepping by instruction.
-    if (theDebuggerBoolSetting(OperateByInstruction))
+    if (debuggerCore()->boolSetting(OperateByInstruction))
         targetFrame = 0;
 
     // If there is no frame with source, jump to frame #0.
@@ -2967,7 +2998,7 @@ void GdbEngine::handleThreadInfo(const GdbResponse &response)
         updateViews(); // Adjust Threads combobox.
         if (m_hasInferiorThreadList) {
             postCommand("threadnames " +
-                theDebuggerAction(MaximalStackDepth)->value().toByteArray(),
+                debuggerCore()->action(MaximalStackDepth)->value().toByteArray(),
                 CB(handleThreadNames), id);
         }
     } else {
@@ -3192,7 +3223,7 @@ bool GdbEngine::showToolTip()
 {
     QByteArray iname = tooltipIName(m_toolTipExpression);
 
-    if (!theDebuggerBoolSetting(UseToolTipsInMainEditor)) {
+    if (!debuggerCore()->boolSetting(UseToolTipsInMainEditor)) {
         watchHandler()->removeData(iname);
         return true;
     }
@@ -3217,7 +3248,7 @@ void GdbEngine::setToolTipExpression(const QPoint &mousePos,
         return;
     }
 
-    if (theDebuggerBoolSetting(DebugDebuggingHelpers)) {
+    if (debuggerCore()->boolSetting(DebugDebuggingHelpers)) {
         // minimize interference
         return;
     }
@@ -3335,7 +3366,7 @@ void GdbEngine::reloadLocals()
 
 bool GdbEngine::hasDebuggingHelperForType(const QByteArray &type) const
 {
-    if (!theDebuggerBoolSetting(UseDebuggingHelpers))
+    if (!debuggerCore()->boolSetting(UseDebuggingHelpers))
         return false;
 
     if (m_gdbAdapter->dumperHandling() == AbstractGdbAdapter::DumperNotAvailable) {
@@ -3344,7 +3375,7 @@ bool GdbEngine::hasDebuggingHelperForType(const QByteArray &type) const
             || type == "QStringList" || type.endsWith("::QStringList");
     }
 
-    if (theDebuggerBoolSetting(DebugDebuggingHelpers)
+    if (debuggerCore()->boolSetting(DebugDebuggingHelpers)
             && stackHandler()->isDebuggingDebuggingHelpers())
         return false;
 
@@ -3442,7 +3473,7 @@ void GdbEngine::rebuildWatchModel()
     if (!isSynchronous())
         m_processedNames.clear();
     PENDING_DEBUG("REBUILDING MODEL" << count);
-    if (theDebuggerBoolSetting(LogTimeStamps))
+    if (debuggerCore()->boolSetting(LogTimeStamps))
         showMessage(LogWindow::logTimeStamp(), LogMiscInput);
     showMessage(_("<Rebuild Watchmodel %1>").arg(count), LogMiscInput);
     showStatusMessage(tr("Finished retrieving data"), 400);
@@ -3629,7 +3660,8 @@ void GdbEngine::insertData(const WatchData &data0)
     watchHandler()->insertData(data);
 }
 
-void GdbEngine::assignValueInDebugger(const Internal::WatchData *, const QString &expression, const QVariant &value)
+void GdbEngine::assignValueInDebugger(const WatchData *,
+    const QString &expression, const QVariant &value)
 {
     postCommand("-var-delete assign");
     postCommand("-var-create assign * " + expression.toLatin1());
@@ -4008,7 +4040,7 @@ bool GdbEngine::startGdb(const QStringList &args, const QString &gdb, const QStr
 
     m_gdb = QString::fromLocal8Bit(qgetenv("QTC_DEBUGGER_PATH"));
     if (m_gdb.isEmpty() && startParameters().startMode != StartRemoteGdb)
-        m_gdb = gdbBinaryForToolChain(startParameters().toolChainType);
+        m_gdb = debuggerCore()->gdbBinaryForToolChain(startParameters().toolChainType);
     if (m_gdb.isEmpty())
         m_gdb = gdb;
     if (m_gdb.isEmpty()) {
@@ -4149,7 +4181,7 @@ bool GdbEngine::startGdb(const QStringList &args, const QString &gdb, const QStr
         loadPythonDumpers();
     }
 
-    QString scriptFileName = theDebuggerStringSetting(GdbScriptFile);
+    QString scriptFileName = debuggerCore()->stringSetting(GdbScriptFile);
     if (!scriptFileName.isEmpty()) {
         if (QFileInfo(scriptFileName).isReadable()) {
             postCommand("source " + scriptFileName.toLocal8Bit());
@@ -4397,16 +4429,6 @@ void GdbEngine::removeTooltip()
 // Factory
 //
 
-bool checkGdbConfiguration(int toolChain, QString *errorMessage, QString *settingsPage)
-{
-    if (gdbBinaryForToolChain(toolChain).isEmpty()) {
-        *errorMessage = msgNoBinaryForToolChain(toolChain);
-        *settingsPage = GdbOptionsPage::settingsId();
-        return false;
-    }
-    return true;
-}
-
 DebuggerEngine *createGdbEngine(const DebuggerStartParameters &startParameters)
 {
     return new GdbEngine(startParameters);
diff --git a/src/plugins/debugger/gdb/gdbengine.h b/src/plugins/debugger/gdb/gdbengine.h
index 396693ee8bcb832a0a167bb81135d89e924efc94..ce932356a2f766daab184ad011cad15a8c8df1d1 100644
--- a/src/plugins/debugger/gdb/gdbengine.h
+++ b/src/plugins/debugger/gdb/gdbengine.h
@@ -305,25 +305,29 @@ private: ////////// Gdb Output, State & Capability Handling //////////
 private: ////////// Inferior Management //////////
 
     // This should be always the last call in a function.
-    Q_SLOT virtual void attemptBreakpointSynchronization();
-    bool acceptsBreakpoint(const Internal::BreakpointData *br);
-
-    virtual void executeStep();
-    virtual void executeStepOut();
-    virtual void executeNext();
-    virtual void executeStepI();
-    virtual void executeNextI();
+    //Q_SLOT virtual void attemptBreakpointSynchronization();
+    bool stateAcceptsBreakpointChanges() const;
+    bool acceptsBreakpoint(BreakpointId id) const;
+    void insertBreakpoint(BreakpointId id);
+    void removeBreakpoint(BreakpointId id);
+    void changeBreakpoint(BreakpointId id);
+
+    void executeStep();
+    void executeStepOut();
+    void executeNext();
+    void executeStepI();
+    void executeNextI();
 
     void continueInferiorInternal();
     void autoContinueInferior();
-    virtual void continueInferior();
-    virtual void interruptInferior();
+    void continueInferior();
+    void interruptInferior();
     void interruptInferiorTemporarily();
 
-    virtual void executeRunToLine(const QString &fileName, int lineNumber);
-    virtual void executeRunToFunction(const QString &functionName);
-    virtual void executeJumpToLine(const QString &fileName, int lineNumber);
-    virtual void executeReturn();
+    void executeRunToLine(const QString &fileName, int lineNumber);
+    void executeRunToFunction(const QString &functionName);
+    void executeJumpToLine(const QString &fileName, int lineNumber);
+    void executeReturn();
 
     void handleExecuteContinue(const GdbResponse &response);
     void handleExecuteStep(const GdbResponse &response);
@@ -340,8 +344,8 @@ private: ////////// Inferior Management //////////
 
 private: ////////// View & Data Stuff //////////
 
-    virtual void selectThread(int index);
-    virtual void activateFrame(int index);
+    void selectThread(int index);
+    void activateFrame(int index);
 
     //
     // Breakpoint specific stuff
@@ -356,21 +360,20 @@ private: ////////// View & Data Stuff //////////
     void handleBreakInfo(const GdbResponse &response);
     void handleWatchInsert(const GdbResponse &response);
     void handleInfoLine(const GdbResponse &response);
-    void extractDataFromInfoBreak(const QString &output, BreakpointData *data);
-    void setBreakpointDataFromOutput(BreakpointData *data, const GdbMi &bkpt);
-    QByteArray breakpointLocation(const BreakpointData *data);
-    void sendInsertBreakpoint(int index);
+    void extractDataFromInfoBreak(const QString &output, BreakpointId);
+    void setBreakpointDataFromOutput(BreakpointId id, const GdbMi &bkpt);
+    QByteArray breakpointLocation(BreakpointId id);
     QString breakLocation(const QString &file) const;
     void reloadBreakListInternal();
 
     //
     // Modules specific stuff
     //
-    virtual void loadSymbols(const QString &moduleName);
-    virtual void loadAllSymbols();
-    virtual void requestModuleSymbols(const QString &moduleName);
-    virtual void reloadModules();
-    virtual void examineModules();
+    void loadSymbols(const QString &moduleName);
+    void loadAllSymbols();
+    void requestModuleSymbols(const QString &moduleName);
+    void reloadModules();
+    void examineModules();
     void reloadModulesInternal();
     void handleModulesList(const GdbResponse &response);
 
@@ -385,15 +388,15 @@ private: ////////// View & Data Stuff //////////
     //
     // Register specific stuff
     //
-    Q_SLOT virtual void reloadRegisters();
-    virtual void setRegisterValue(int nr, const QString &value);
+    Q_SLOT void reloadRegisters();
+    void setRegisterValue(int nr, const QString &value);
     void handleRegisterListNames(const GdbResponse &response);
     void handleRegisterListValues(const GdbResponse &response);
 
     //
     // Disassembler specific stuff
     //
-    virtual void fetchDisassembler(DisassemblerViewAgent *agent);
+    void fetchDisassembler(DisassemblerViewAgent *agent);
     void fetchDisassemblerByAddress(const DisassemblerAgentCookie &ac,
         bool useMixedMode);
     void fetchDisassemblerByCli(const DisassemblerAgentCookie &ac,
@@ -408,7 +411,7 @@ private: ////////// View & Data Stuff //////////
     //
     // Source file specific stuff
     //
-    virtual void reloadSourceFiles();
+    void reloadSourceFiles();
     void reloadSourceFilesInternal();
     void handleQuerySources(const GdbResponse &response);
 
diff --git a/src/plugins/debugger/gdb/gdboptionspage.cpp b/src/plugins/debugger/gdb/gdboptionspage.cpp
index 62b1db19c43af1679d1b32b559ca43c22f9596d6..5e831edb9797cd6951649f9440c6d7a345c75105 100644
--- a/src/plugins/debugger/gdb/gdboptionspage.cpp
+++ b/src/plugins/debugger/gdb/gdboptionspage.cpp
@@ -29,15 +29,115 @@
 
 #include "gdboptionspage.h"
 #include "debuggeractions.h"
-#include "debuggerconstants.h"
+#include "debuggercore.h"
 
 #include <coreplugin/icore.h>
+#include <projectexplorer/projectexplorer.h>
+#include <projectexplorer/toolchain.h>
+#include <projectexplorer/toolchaintype.h>
+
 #include <QtCore/QCoreApplication>
 #include <QtCore/QTextStream>
+#include <QtCore/QFileInfo>
 
 namespace Debugger {
 namespace Internal {
 
+const char gdbBinariesSettingsGroupC[] = "GdbBinaries";
+const char debugModeGdbBinaryKeyC[] = "GdbBinary";
+
+GdbOptionsPage::GdbBinaryToolChainMap GdbOptionsPage::gdbBinaryToolChainMap;
+bool GdbOptionsPage::gdbBinariesChanged = true;
+
+void GdbOptionsPage::readGdbBinarySettings() /* static */
+{
+    using namespace ProjectExplorer;
+    QSettings *settings = Core::ICore::instance()->settings();
+    // Convert gdb binaries from flat settings list (see writeSettings)
+    // into map ("binary1=gdb,1,2", "binary2=symbian_gdb,3,4").
+    gdbBinaryToolChainMap.clear();
+    const QChar separator = QLatin1Char(',');
+    const QString keyRoot = QLatin1String(gdbBinariesSettingsGroupC) + QLatin1Char('/') +
+                            QLatin1String(debugModeGdbBinaryKeyC);
+    for (int i = 1; ; i++) {
+        const QString value = settings->value(keyRoot + QString::number(i)).toString();
+        if (value.isEmpty())
+            break;
+        // Split apart comma-separated binary and its numerical toolchains.
+        QStringList tokens = value.split(separator);
+        if (tokens.size() < 2)
+            break;
+        const QString binary = tokens.front();
+        // Skip non-existent absolute binaries allowing for upgrades by the installer.
+        // Force a rewrite of the settings file.
+        const QFileInfo binaryInfo(binary);
+        if (binaryInfo.isAbsolute() && !binaryInfo.isExecutable()) {
+            gdbBinariesChanged = true;
+            const QString msg = QString::fromLatin1("Warning: The gdb binary '%1' does not exist, skipping.\n").arg(binary);
+            qWarning("%s", qPrintable(msg));
+            continue;
+        }
+        // Create entries for all toolchains.
+        tokens.pop_front();
+        foreach (const QString &t, tokens) {
+            // Paranoia: Check if the there is already a binary configured for the toolchain.
+            const int toolChain = t.toInt();
+            const QString predefinedGdb = gdbBinaryToolChainMap.key(toolChain);
+            if (predefinedGdb.isEmpty()) {
+                gdbBinaryToolChainMap.insert(binary, toolChain);
+            } else {
+                const QString toolChainName =
+                    ProjectExplorer::ToolChain::toolChainName(ToolChainType(toolChain));
+                const QString msg =
+                        QString::fromLatin1("An inconsistency has been encountered in the Ini-file '%1':\n"
+                                            "Skipping gdb binary '%2' for toolchain '%3' as '%4' is already configured for it.").
+                        arg(settings->fileName(), binary, toolChainName, predefinedGdb);
+                qWarning("%s", qPrintable(msg));
+            }
+        }
+    }
+    // Linux defaults
+#ifdef Q_OS_UNIX
+    if (gdbBinaryToolChainMap.isEmpty()) {
+        const QString gdb = QLatin1String("gdb");
+        gdbBinaryToolChainMap.insert(gdb, ToolChain_GCC);
+        gdbBinaryToolChainMap.insert(gdb, ToolChain_LINUX_ICC);
+        gdbBinaryToolChainMap.insert(gdb, ToolChain_OTHER);
+        gdbBinaryToolChainMap.insert(gdb, ToolChain_UNKNOWN);
+    }
+#endif
+}
+
+void GdbOptionsPage::writeGdbBinarySettings() /* static */
+{
+    QSettings *settings = Core::ICore::instance()->settings();
+    // Convert gdb binaries map into a flat settings list of
+    // ("binary1=gdb,1,2", "binary2=symbian_gdb,3,4"). It needs to be ASCII for installers
+    QString lastBinary;
+    QStringList settingsList;
+    const QChar separator = QLatin1Char(',');
+    const GdbBinaryToolChainMap::const_iterator cend = gdbBinaryToolChainMap.constEnd();
+    for (GdbBinaryToolChainMap::const_iterator it = gdbBinaryToolChainMap.constBegin(); it != cend; ++it) {
+        if (it.key() != lastBinary) {
+            lastBinary = it.key(); // Start new entry with first toolchain
+            settingsList.push_back(lastBinary);
+        }
+        settingsList.back().append(separator); // Append toolchain to last binary
+        settingsList.back().append(QString::number(it.value()));
+    }
+    // Terminate settings list by an empty element such that consecutive keys resulting
+    // from ini-file merging are suppressed while reading.
+    settingsList.push_back(QString());
+    // Write out list
+    settings->beginGroup(QLatin1String(gdbBinariesSettingsGroupC));
+    settings->remove(QString()); // remove all keys in group.
+    const int count = settingsList.size();
+    const QString keyRoot = QLatin1String(debugModeGdbBinaryKeyC);
+    for (int i = 0; i < count; i++)
+        settings->setValue(keyRoot + QString::number(i + 1), settingsList.at(i));
+    settings->endGroup();
+}
+
 GdbOptionsPage::GdbOptionsPage()
 {
 }
@@ -71,44 +171,43 @@ QWidget *GdbOptionsPage::createPage(QWidget *parent)
 {
     QWidget *w = new QWidget(parent);
     m_ui.setupUi(w);
-    m_ui.gdbChooserWidget
-        ->setGdbBinaries(DebuggerSettings::instance()->gdbBinaryToolChainMap());
+    m_ui.gdbChooserWidget->setGdbBinaries(gdbBinaryToolChainMap);
     m_ui.scriptFileChooser->setExpectedKind(Utils::PathChooser::File);
     m_ui.scriptFileChooser->setPromptDialogTitle(tr("Choose Location of Startup Script File"));
 
     m_group.clear();
-    m_group.insert(theDebuggerAction(GdbScriptFile),
+    m_group.insert(debuggerCore()->action(GdbScriptFile),
         m_ui.scriptFileChooser);
-    m_group.insert(theDebuggerAction(GdbEnvironment),
+    m_group.insert(debuggerCore()->action(GdbEnvironment),
         m_ui.environmentEdit);
-    m_group.insert(theDebuggerAction(AdjustBreakpointLocations),
+    m_group.insert(debuggerCore()->action(AdjustBreakpointLocations),
         m_ui.checkBoxAdjustBreakpointLocations);
-    m_group.insert(theDebuggerAction(GdbWatchdogTimeout),
+    m_group.insert(debuggerCore()->action(GdbWatchdogTimeout),
         m_ui.spinBoxGdbWatchdogTimeout);
 
-    m_group.insert(theDebuggerAction(UseMessageBoxForSignals),
+    m_group.insert(debuggerCore()->action(UseMessageBoxForSignals),
         m_ui.checkBoxUseMessageBoxForSignals);
-    m_group.insert(theDebuggerAction(SkipKnownFrames),
+    m_group.insert(debuggerCore()->action(SkipKnownFrames),
         m_ui.checkBoxSkipKnownFrames);
-    m_group.insert(theDebuggerAction(EnableReverseDebugging),
+    m_group.insert(debuggerCore()->action(EnableReverseDebugging),
         m_ui.checkBoxEnableReverseDebugging);
-    m_group.insert(theDebuggerAction(GdbWatchdogTimeout), 0);
+    m_group.insert(debuggerCore()->action(GdbWatchdogTimeout), 0);
 
 #if 1
     m_ui.groupBoxPluginDebugging->hide();
 #else // The related code (handleAqcuiredInferior()) is disabled as well.
-    m_group.insert(theDebuggerAction(AllPluginBreakpoints),
+    m_group.insert(debuggerCore()->action(AllPluginBreakpoints),
         m_ui.radioButtonAllPluginBreakpoints);
-    m_group.insert(theDebuggerAction(SelectedPluginBreakpoints),
+    m_group.insert(debuggerCore()->action(SelectedPluginBreakpoints),
         m_ui.radioButtonSelectedPluginBreakpoints);
-    m_group.insert(theDebuggerAction(NoPluginBreakpoints),
+    m_group.insert(debuggerCore()->action(NoPluginBreakpoints),
         m_ui.radioButtonNoPluginBreakpoints);
-    m_group.insert(theDebuggerAction(SelectedPluginBreakpointsPattern),
+    m_group.insert(debuggerCore()->action(SelectedPluginBreakpointsPattern),
         m_ui.lineEditSelectedPluginBreakpointsPattern);
 #endif
 
     m_ui.lineEditSelectedPluginBreakpointsPattern->
-        setEnabled(theDebuggerAction(SelectedPluginBreakpoints)->value().toBool());
+        setEnabled(debuggerCore()->action(SelectedPluginBreakpoints)->value().toBool());
     connect(m_ui.radioButtonSelectedPluginBreakpoints, SIGNAL(toggled(bool)),
         m_ui.lineEditSelectedPluginBreakpointsPattern, SLOT(setEnabled(bool)));
 
@@ -128,13 +227,14 @@ QWidget *GdbOptionsPage::createPage(QWidget *parent)
     }
     return w;
 }
+
 void GdbOptionsPage::apply()
 {
     m_group.apply(Core::ICore::instance()->settings());
 
     if (m_ui.gdbChooserWidget->isDirty()) {
-        DebuggerSettings::instance()
-            ->setGdbBinaryToolChainMap(m_ui.gdbChooserWidget->gdbBinaries());
+        gdbBinariesChanged = true;
+        gdbBinaryToolChainMap = m_ui.gdbChooserWidget->gdbBinaries();
         m_ui.gdbChooserWidget->clearDirty();
     }
 }
diff --git a/src/plugins/debugger/gdb/gdboptionspage.h b/src/plugins/debugger/gdb/gdboptionspage.h
index 7cd7ad8b2ec52efe0977a021d7cd1837d2bf3055..445dac36e58c8da6c7da2fa3a01695d3c1bda379 100644
--- a/src/plugins/debugger/gdb/gdboptionspage.h
+++ b/src/plugins/debugger/gdb/gdboptionspage.h
@@ -57,6 +57,12 @@ public:
 
     static QString settingsId();
 
+    typedef QMultiMap<QString, int> GdbBinaryToolChainMap;
+    static GdbBinaryToolChainMap gdbBinaryToolChainMap;
+    static bool gdbBinariesChanged;
+    static void readGdbBinarySettings();
+    static void writeGdbBinarySettings();
+
 private:
     Ui::GdbOptionsPage m_ui;
     Utils::SavedActionSet m_group;
diff --git a/src/plugins/debugger/gdb/localplaingdbadapter.cpp b/src/plugins/debugger/gdb/localplaingdbadapter.cpp
index f0483c6c6b8baa01fbe5d5458754bf4de3809f9d..89a8d549abf08a87ed89c84917c093cf8fc33521 100644
--- a/src/plugins/debugger/gdb/localplaingdbadapter.cpp
+++ b/src/plugins/debugger/gdb/localplaingdbadapter.cpp
@@ -31,6 +31,7 @@
 
 #include "gdbengine.h"
 #include "procinterrupt.h"
+#include "debuggercore.h"
 #include "debuggerstringutils.h"
 
 #include <utils/qtcassert.h>
@@ -140,7 +141,7 @@ void LocalPlainGdbAdapter::checkForReleaseBuild()
     // "30 .debug_info   00087d36  00000000  00000000  0006bbd5  2**0\n"
     // " CONTENTS, READONLY, DEBUGGING"
     if (ba.contains("Sections:") && !ba.contains(".debug_info")) {
-        m_engine->showMessageBox(QMessageBox::Information, "Warning",
+        showMessageBox(QMessageBox::Information, "Warning",
            tr("This does not seem to be a \"Debug\" build.\n"
               "Setting breakpoints by file name and line number may fail."));
     }
diff --git a/src/plugins/debugger/gdb/pythongdbengine.cpp b/src/plugins/debugger/gdb/pythongdbengine.cpp
index 7a3ece861724307fb0b4ecbe1d8b6c18f753ab75..aa21cd979a17d66a96aae26108727945a02875de 100644
--- a/src/plugins/debugger/gdb/pythongdbengine.cpp
+++ b/src/plugins/debugger/gdb/pythongdbengine.cpp
@@ -31,6 +31,7 @@
 #include "gdbmi.h"
 #include "abstractgdbadapter.h"
 #include "debuggeractions.h"
+#include "debuggercore.h"
 #include "debuggerstringutils.h"
 
 #include "breakhandler.h"
@@ -75,9 +76,9 @@ void GdbEngine::updateLocalsPython(bool tryPartial, const QByteArray &varList)
     }
 
     QByteArray options;
-    if (theDebuggerBoolSetting(UseDebuggingHelpers))
+    if (debuggerCore()->boolSetting(UseDebuggingHelpers))
         options += "fancy,";
-    if (theDebuggerBoolSetting(AutoDerefPointers))
+    if (debuggerCore()->boolSetting(AutoDerefPointers))
         options += "autoderef,";
     if (!qgetenv("QTC_DEBUGGER_PYTHON_VERBOSE").isEmpty())
         options += "pe,";
diff --git a/src/plugins/debugger/gdb/remotegdbserveradapter.cpp b/src/plugins/debugger/gdb/remotegdbserveradapter.cpp
index dfa9e356e50a7b8416f82515587aa5cfaf20a7eb..006dbb2ab72187f2644184d64e5e03da998d198c 100644
--- a/src/plugins/debugger/gdb/remotegdbserveradapter.cpp
+++ b/src/plugins/debugger/gdb/remotegdbserveradapter.cpp
@@ -28,9 +28,11 @@
 **************************************************************************/
 
 #include "remotegdbserveradapter.h"
-#include "gdbmi.h"
+
+#include "debuggercore.h"
 #include "debuggerstringutils.h"
 #include "gdbengine.h"
+#include "gdbmi.h"
 
 #include <utils/qtcassert.h>
 #include <utils/fancymainwindow.h>
@@ -132,7 +134,7 @@ void RemoteGdbServerAdapter::uploadProcError(QProcess::ProcessError error)
     }
 
     showMessage(msg, StatusBar);
-    DebuggerEngine::showMessageBox(QMessageBox::Critical, tr("Error"), msg);
+    showMessageBox(QMessageBox::Critical, tr("Error"), msg);
 }
 
 void RemoteGdbServerAdapter::readUploadStandardOutput()
diff --git a/src/plugins/debugger/gdb/tcftrkgdbadapter.cpp b/src/plugins/debugger/gdb/tcftrkgdbadapter.cpp
index a6e6899fa4e2dabe18330e4db282aa063e608f58..cf2b8c30074c0ed82ca339787617ae8a9f7d6bec 100644
--- a/src/plugins/debugger/gdb/tcftrkgdbadapter.cpp
+++ b/src/plugins/debugger/gdb/tcftrkgdbadapter.cpp
@@ -34,6 +34,7 @@
 
 #include "registerhandler.h"
 #include "threadshandler.h"
+#include "debuggercore.h"
 #include "debuggeractions.h"
 #include "debuggerstringutils.h"
 #include "watchutils.h"
@@ -135,9 +136,9 @@ TcfTrkGdbAdapter::TcfTrkGdbAdapter(GdbEngine *engine) :
 #endif
     m_gdbServerName = _("127.0.0.1:%1").arg(2222 + portOffset);
 
-    setVerbose(theDebuggerBoolSetting(VerboseLog) ? 1 : 0);
+    setVerbose(debuggerCore()->boolSetting(VerboseLog) ? 1 : 0);
 
-    connect(theDebuggerAction(VerboseLog), SIGNAL(valueChanged(QVariant)),
+    connect(debuggerCore()->action(VerboseLog), SIGNAL(valueChanged(QVariant)),
         this, SLOT(setVerbose(QVariant)));
     connect(m_trkDevice, SIGNAL(error(QString)),
         this, SLOT(tcftrkDeviceError(QString)));
diff --git a/src/plugins/debugger/gdb/termgdbadapter.cpp b/src/plugins/debugger/gdb/termgdbadapter.cpp
index f38fae20aa22c0c7d0bcd4c40739e4e9c176b1e9..1f9826d20dcdf7069cbf0ea9cdf364f7e6fe641f 100644
--- a/src/plugins/debugger/gdb/termgdbadapter.cpp
+++ b/src/plugins/debugger/gdb/termgdbadapter.cpp
@@ -32,6 +32,7 @@
 #include "gdbengine.h"
 #include "procinterrupt.h"
 #include "debuggerstringutils.h"
+#include "debuggercore.h"
 
 #include <utils/qtcassert.h>
 #include <coreplugin/icore.h>
@@ -199,7 +200,7 @@ void TermGdbAdapter::interruptInferior()
 
 void TermGdbAdapter::stubMessage(const QString &msg, bool)
 {
-    DebuggerEngine::showMessageBox(QMessageBox::Critical, tr("Debugger Error"), msg);
+    showMessageBox(QMessageBox::Critical, tr("Debugger Error"), msg);
 }
 
 void TermGdbAdapter::stubExited()
diff --git a/src/plugins/debugger/gdb/trkgdbadapter.cpp b/src/plugins/debugger/gdb/trkgdbadapter.cpp
index 32f6f16fb9962370d4b3341b031ea594c454aef8..c5790f26f6de8efb8ff45bb66f660d8e43872bd6 100644
--- a/src/plugins/debugger/gdb/trkgdbadapter.cpp
+++ b/src/plugins/debugger/gdb/trkgdbadapter.cpp
@@ -38,6 +38,7 @@
 #include "registerhandler.h"
 #include "threadshandler.h"
 #include "debuggeractions.h"
+#include "debuggercore.h"
 #include "debuggerstringutils.h"
 #include "watchutils.h"
 #ifndef STANDALONE_RUNNER
@@ -107,9 +108,9 @@ TrkGdbAdapter::TrkGdbAdapter(GdbEngine *engine) :
 #endif
     m_gdbServerName = _("127.0.0.1:%1").arg(2222 + portOffset);
 
-    setVerbose(theDebuggerBoolSetting(VerboseLog));
+    setVerbose(debuggerCore()->boolSetting(VerboseLog));
 
-    connect(theDebuggerAction(VerboseLog), SIGNAL(valueChanged(QVariant)),
+    connect(debuggerCore()->action(VerboseLog), SIGNAL(valueChanged(QVariant)),
         this, SLOT(setVerbose(QVariant)));
 }
 
diff --git a/src/plugins/debugger/lldb/ipcenginehost.cpp b/src/plugins/debugger/lldb/ipcenginehost.cpp
index 277fd26607cd133117a76d8805eb4e73673de885..f1bc78fa2e63be8333a846ed4b34c8c6371948c9 100644
--- a/src/plugins/debugger/lldb/ipcenginehost.cpp
+++ b/src/plugins/debugger/lldb/ipcenginehost.cpp
@@ -475,7 +475,7 @@ void IPCEngineHost::rpcCallback(quint64 f, QByteArray payload)
                 SET_NATIVE_BYTE_ORDER(s);
                 quint64 id;
                 s >> id;
-                notifyAddBreakpointOk(id);
+                notifyBreakpointInsertOk(id);
             }
         case IPCEngineGuest::NotifyAddBreakpointFailed:
             {
@@ -483,7 +483,7 @@ void IPCEngineHost::rpcCallback(quint64 f, QByteArray payload)
                 SET_NATIVE_BYTE_ORDER(s);
                 quint64 id;
                 s >> id;
-                notifyAddBreakpointFailed(id);
+                notifyBreakpointInsertFailed(id);
             }
         case IPCEngineGuest::NotifyRemoveBreakpointOk:
             {
@@ -491,7 +491,7 @@ void IPCEngineHost::rpcCallback(quint64 f, QByteArray payload)
                 SET_NATIVE_BYTE_ORDER(s);
                 quint64 id;
                 s >> id;
-                notifyRemoveBreakpointOk(id);
+                notifyBreakpointRemoveOk(id);
             }
         case IPCEngineGuest::NotifyRemoveBreakpointFailed:
             {
@@ -499,7 +499,7 @@ void IPCEngineHost::rpcCallback(quint64 f, QByteArray payload)
                 SET_NATIVE_BYTE_ORDER(s);
                 quint64 id;
                 s >> id;
-                notifyRemoveBreakpointFailed(id);
+                notifyBreakpointRemoveFailed(id);
             }
         case IPCEngineGuest::NotifyChangeBreakpointOk:
             {
@@ -507,7 +507,7 @@ void IPCEngineHost::rpcCallback(quint64 f, QByteArray payload)
                 SET_NATIVE_BYTE_ORDER(s);
                 quint64 id;
                 s >> id;
-                notifyChangeBreakpointOk(id);
+                notifyBreakpointChangeOk(id);
             }
         case IPCEngineGuest::NotifyChangeBreakpointFailed:
             {
@@ -515,7 +515,7 @@ void IPCEngineHost::rpcCallback(quint64 f, QByteArray payload)
                 SET_NATIVE_BYTE_ORDER(s);
                 quint64 id;
                 s >> id;
-                notifyChangeBreakpointFailed(id);
+                notifyBreakpointChangeFailed(id);
             }
         case IPCEngineGuest::NotifyBreakpointAdjusted:
             {
@@ -523,7 +523,8 @@ void IPCEngineHost::rpcCallback(quint64 f, QByteArray payload)
                 SET_NATIVE_BYTE_ORDER(s);
                 BreakpointData d;
                 s >> d;
-                notifyBreakpointAdjusted(d);
+                qDebug() << "FIXME";
+                //notifyBreakpointAdjusted(d);
             }
     }
 }
diff --git a/src/plugins/debugger/logwindow.cpp b/src/plugins/debugger/logwindow.cpp
index d11fad9eb71c16a58e64c0b260f1781a38f6eb3d..bdd731541a7f23ac0d9825fed04eaab9312f9ac7 100644
--- a/src/plugins/debugger/logwindow.cpp
+++ b/src/plugins/debugger/logwindow.cpp
@@ -30,7 +30,7 @@
 #include "logwindow.h"
 
 #include "debuggeractions.h"
-#include "debuggerconstants.h"
+#include "debuggercore.h"
 
 #include <QtCore/QDebug>
 #include <QtCore/QFile>
@@ -198,12 +198,12 @@ public:
         menu->addAction(m_clearContentsAction);
         menu->addAction(m_saveContentsAction); // X11 clipboard is unreliable for long texts
         addContextActions(menu);
-        theDebuggerAction(ExecuteCommand)->setData(textCursor().block().text());
-        menu->addAction(theDebuggerAction(ExecuteCommand));
-        menu->addAction(theDebuggerAction(LogTimeStamps));
-        menu->addAction(theDebuggerAction(VerboseLog));
+        debuggerCore()->action(ExecuteCommand)->setData(textCursor().block().text());
+        menu->addAction(debuggerCore()->action(ExecuteCommand));
+        menu->addAction(debuggerCore()->action(LogTimeStamps));
+        menu->addAction(debuggerCore()->action(VerboseLog));
         menu->addSeparator();
-        menu->addAction(theDebuggerAction(SettingsDialog));
+        menu->addAction(debuggerCore()->action(SettingsDialog));
         menu->exec(ev->globalPos());
         delete menu;
     }
@@ -248,7 +248,7 @@ private:
     void keyPressEvent(QKeyEvent *ev)
     {
         if (ev->modifiers() == Qt::ControlModifier && ev->key() == Qt::Key_Return)
-            theDebuggerAction(ExecuteCommand)->trigger(textCursor().block().text());
+            debuggerCore()->action(ExecuteCommand)->trigger(textCursor().block().text());
         else if (ev->modifiers() == Qt::ControlModifier && ev->key() == Qt::Key_R)
             emit clearContentsRequested();
         else
@@ -276,7 +276,7 @@ private:
 
     void addContextActions(QMenu *menu)
     {
-       menu->addAction(theDebuggerAction(ExecuteCommand));
+       menu->addAction(debuggerCore()->action(ExecuteCommand));
     }
 
     void focusInEvent(QFocusEvent *ev)
@@ -393,7 +393,7 @@ void LogWindow::showOutput(int channel, const QString &output)
     cursor.movePosition(QTextCursor::End);
     bool atEnd = oldCursor.position() == cursor.position();
 
-    if (theDebuggerBoolSetting(LogTimeStamps))
+    if (debuggerCore()->boolSetting(LogTimeStamps))
         m_combinedText->appendPlainText(charForChannel(LogTime) + logTimeStamp());
     foreach (QString line, output.split('\n')) {
         // FIXME: QTextEdit asserts on really long lines...
@@ -415,7 +415,7 @@ void LogWindow::showOutput(int channel, const QString &output)
 void LogWindow::showInput(int channel, const QString &input)
 {
     Q_UNUSED(channel)
-    if (theDebuggerBoolSetting(LogTimeStamps))
+    if (debuggerCore()->boolSetting(LogTimeStamps))
         m_inputText->appendPlainText(logTimeStamp());
     m_inputText->appendPlainText(input);
     QTextCursor cursor = m_inputText->textCursor();
diff --git a/src/plugins/debugger/moduleswindow.cpp b/src/plugins/debugger/moduleswindow.cpp
index e73cab44a63e0d8c58b3e3e00b645d80a283f9fc..4de85fa91ef6c2245169193227b260a813428a60 100644
--- a/src/plugins/debugger/moduleswindow.cpp
+++ b/src/plugins/debugger/moduleswindow.cpp
@@ -56,7 +56,7 @@ namespace Internal {
 ModulesWindow::ModulesWindow(QWidget *parent)
   : QTreeView(parent), m_alwaysResizeColumnsToContents(false)
 {
-    QAction *act = theDebuggerAction(UseAlternatingRowColors);
+    QAction *act = debuggerCore()->action(UseAlternatingRowColors);
     setWindowTitle(tr("Modules"));
     setAttribute(Qt::WA_MacShowFocusRect, false);
     setSortingEnabled(true);
@@ -146,7 +146,7 @@ void ModulesWindow::contextMenuEvent(QContextMenuEvent *ev)
     actAlwaysAdjustColumnWidth->setCheckable(true);
     actAlwaysAdjustColumnWidth->setChecked(m_alwaysResizeColumnsToContents);
     menu.addSeparator();
-    menu.addAction(theDebuggerAction(SettingsDialog));
+    menu.addAction(debuggerCore()->action(SettingsDialog));
 
     QAction *act = menu.exec(ev->globalPos());
 
diff --git a/src/plugins/debugger/pdb/pdbengine.cpp b/src/plugins/debugger/pdb/pdbengine.cpp
index 2afdbdb429eaa152c641eae2d86ce23240d7a33e..9533c8da7ec27ae9ff53043533c9891fab316bd8 100644
--- a/src/plugins/debugger/pdb/pdbengine.cpp
+++ b/src/plugins/debugger/pdb/pdbengine.cpp
@@ -32,7 +32,7 @@
 #include "pdbengine.h"
 
 #include "debuggeractions.h"
-#include "debuggerconstants.h"
+#include "debuggercore.h"
 #include "debuggerdialogs.h"
 #include "debuggerplugin.h"
 #include "debuggerstringutils.h"
@@ -50,7 +50,6 @@
 
 #include <texteditor/itexteditor.h>
 #include <coreplugin/ifile.h>
-//#include <coreplugin/scriptmanager/scriptmanager.h>
 #include <coreplugin/icore.h>
 
 #include <QtCore/QDateTime>
@@ -327,33 +326,28 @@ void PdbEngine::selectThread(int index)
     Q_UNUSED(index)
 }
 
-static QByteArray breakpointLocation(const BreakpointData *data)
-{
-    if (!data->funcName.isEmpty())
-        return data->funcName.toLatin1();
-    // In this case, data->funcName is something like '*0xdeadbeef'
-    if (data->lineNumber == 0)
-        return data->funcName.toLatin1();
-    //QString loc = data->useFullPath ? data->fileName : breakLocation(data->fileName);
-    // The argument is simply a C-quoted version of the argument to the
-    // non-MI "break" command, including the "original" quoting it wants.
-    //return "\"\\\"" + GdbMi::escapeCString(data->fileName).toLocal8Bit() + "\\\":"
-    //    + data->lineNumber + '"';
-    return data->fileName.toLocal8Bit() + ':' + QByteArray::number(data->lineNumber);
-}
-
 void PdbEngine::attemptBreakpointSynchronization()
 {
     BreakHandler *handler = breakHandler();
     //qDebug() << "ATTEMPT BP SYNC";
     bool updateNeeded = false;
-    for (int index = 0; index != handler->size(); ++index) {
-        BreakpointData *data = handler->at(index);
-        if (data->pending) {
-            data->pending = false; // FIXME
+    foreach (BreakpointId id, handler->engineBreakpointIds(this)) {
+        if (handler->state(id) == BreakpointInsertRequested) {
+            handler->setState(id, BreakpointInserted); // FIXME
             updateNeeded = true;
-            QByteArray loc = breakpointLocation(data);
-            postCommand("break " + loc, CB(handleBreakInsert), QVariant(index));
+
+            QByteArray loc;
+            if (!handler->functionName(id).isEmpty())
+                loc = handler->functionName(id).toLatin1();
+            // The argument is simply a C-quoted version of the argument to the
+            // non-MI "break" command, including the "original" quoting it wants.
+            //return "\"\\\"" + GdbMi::escapeCString(data->fileName).toLocal8Bit()
+            // + "\\\":" + data->lineNumber + '"';
+            else 
+                loc = handler->fileName(id).toLocal8Bit() + ':'
+                 + QByteArray::number(handler->lineNumber(id));
+
+            postCommand("break " + loc, CB(handleBreakInsert), QVariant(id));
         }
 /*
         if (data->bpNumber.isEmpty()) {
@@ -375,10 +369,8 @@ void PdbEngine::handleBreakInsert(const PdbResponse &response)
 {
     //qDebug() << "BP RESPONSE: " << response.data;
     // "Breakpoint 1 at /pdb/math.py:10"
-    int index = response.cookie.toInt();
+    BreakpointId id(response.cookie.toInt());
     BreakHandler *handler = breakHandler();
-    BreakpointData *data = handler->at(index);
-    QTC_ASSERT(data, return);
     QTC_ASSERT(response.data.startsWith("Breakpoint "), return);
     int pos1 = response.data.indexOf(" at ");
     QTC_ASSERT(pos1 != -1, return);
@@ -386,10 +378,11 @@ void PdbEngine::handleBreakInsert(const PdbResponse &response)
     int pos2 = response.data.lastIndexOf(":");
     QByteArray file = response.data.mid(pos1 + 4, pos2 - pos1 - 4);
     QByteArray line = response.data.mid(pos2 + 1);
-    data->bpNumber = bpnr;
-    data->bpFileName = _(file);
-    data->bpLineNumber = line.toInt();
-    handler->updateMarkers();
+    BreakpointResponse br;
+    br.bpNumber = bpnr.toInt();
+    br.bpFileName = _(file);
+    br.bpLineNumber = line.toInt();
+    handler->setResponse(id, br);
 }
 
 void PdbEngine::loadSymbols(const QString &moduleName)
@@ -741,9 +734,9 @@ void PdbEngine::updateLocals()
     }
 
     QByteArray options;
-    if (theDebuggerBoolSetting(UseDebuggingHelpers))
+    if (debuggerCore()->boolSetting(UseDebuggingHelpers))
         options += "fancy,";
-    if (theDebuggerBoolSetting(AutoDerefPointers))
+    if (debuggerCore()->boolSetting(AutoDerefPointers))
         options += "autoderef,";
     if (options.isEmpty())
         options += "defaults,";
diff --git a/src/plugins/debugger/qml/qmlcppengine.cpp b/src/plugins/debugger/qml/qmlcppengine.cpp
index 8cd04b7557451c44c082d2e3d9d6e272c1e95a49..74c788a4c41e848aa2681b721f89c7af24731569 100644
--- a/src/plugins/debugger/qml/qmlcppengine.cpp
+++ b/src/plugins/debugger/qml/qmlcppengine.cpp
@@ -238,10 +238,10 @@ void QmlCppEngine::attemptBreakpointSynchronization()
     static_cast<DebuggerEngine*>(d->m_qmlEngine)->attemptBreakpointSynchronization();
 }
 
-bool QmlCppEngine::acceptsBreakpoint(const Internal::BreakpointData *br)
+bool QmlCppEngine::acceptsBreakpoint(BreakpointId id)
 {
-    return d->m_cppEngine->acceptsBreakpoint(br)
-        || d->m_qmlEngine->acceptsBreakpoint(br);
+    return d->m_cppEngine->acceptsBreakpoint(id)
+        || d->m_qmlEngine->acceptsBreakpoint(id);
 }
 
 void QmlCppEngine::selectThread(int index)
diff --git a/src/plugins/debugger/qml/qmlcppengine.h b/src/plugins/debugger/qml/qmlcppengine.h
index a79593b119e647a6368447a8974788d70404f5df..9bb063adde8157f614cf1f9d5f0f7421b3457157 100644
--- a/src/plugins/debugger/qml/qmlcppengine.h
+++ b/src/plugins/debugger/qml/qmlcppengine.h
@@ -53,7 +53,7 @@ public:
     virtual void updateAll();
 
     virtual void attemptBreakpointSynchronization();
-    virtual bool acceptsBreakpoint(const Internal::BreakpointData *br);
+    virtual bool acceptsBreakpoint(BreakpointId id);
     virtual void selectThread(int index);
 
     virtual void assignValueInDebugger(const Internal::WatchData *w,
diff --git a/src/plugins/debugger/qml/qmlengine.cpp b/src/plugins/debugger/qml/qmlengine.cpp
index b41b0a5f040d1b564e0e4ce906e5a4c3f7a0a280..2082ca77845e3850135f8ee37134281a22d3821e 100644
--- a/src/plugins/debugger/qml/qmlengine.cpp
+++ b/src/plugins/debugger/qml/qmlengine.cpp
@@ -31,12 +31,13 @@
 #include "qmladapter.h"
 
 #include "debuggeractions.h"
-#include "debuggertooltip.h"
 #include "debuggerconstants.h"
+#include "debuggercore.h"
 #include "debuggerdialogs.h"
+#include "debuggerrunner.h"
 #include "debuggerstringutils.h"
+#include "debuggertooltip.h"
 #include "debuggeruiswitcher.h"
-#include "debuggerrunner.h"
 
 #include "breakhandler.h"
 #include "moduleshandler.h"
@@ -142,6 +143,8 @@ static QDataStream &operator>>(QDataStream &s, StackFrame &frame)
 
 } // namespace Internal
 
+using namespace Internal;
+
 struct QmlEnginePrivate
 {
     explicit QmlEnginePrivate(QmlEngine *q);
@@ -199,9 +202,9 @@ void QmlEngine::gotoLocation(const QString &fileName, int lineNumber, bool setMa
     DebuggerEngine::gotoLocation(processedFilename, lineNumber, setMarker);
 }
 
-void QmlEngine::gotoLocation(const Internal::StackFrame &frame, bool setMarker)
+void QmlEngine::gotoLocation(const StackFrame &frame, bool setMarker)
 {
-    Internal::StackFrame adjustedFrame = frame;
+    StackFrame adjustedFrame = frame;
     if (isShadowBuildProject())
         adjustedFrame.file = fromShadowBuildFilename(frame.file);
 
@@ -478,14 +481,11 @@ void QmlEngine::executeJumpToLine(const QString &fileName, int lineNumber)
 
 void QmlEngine::activateFrame(int index)
 {
-    Q_UNUSED(index)
-
     QByteArray reply;
     QDataStream rs(&reply, QIODevice::WriteOnly);
     rs << QByteArray("ACTIVATE_FRAME");
     rs << index;
     sendMessage(reply);
-
     gotoLocation(stackHandler()->frames().value(index), true);
 }
 
@@ -496,18 +496,17 @@ void QmlEngine::selectThread(int index)
 
 void QmlEngine::attemptBreakpointSynchronization()
 {
-    Internal::BreakHandler *handler = breakHandler();
+    BreakHandler *handler = breakHandler();
     //bool updateNeeded = false;
-    Internal::JSAgentBreakpoints breakpoints;
-    for (int index = 0; index != handler->size(); ++index) {
-        Internal::BreakpointData *data = handler->at(index);
-        QString processedFilename = data->fileName;
+    JSAgentBreakpoints breakpoints;
+    foreach (BreakpointId id, handler->engineBreakpointIds(this)) {
+        QString processedFilename = handler->fileName(id);
         if (isShadowBuildProject())
-            processedFilename = toShadowBuildFilename(data->fileName);
-        Internal::JSAgentBreakpointData bp;
+            processedFilename = toShadowBuildFilename(handler->fileName(id));
+        JSAgentBreakpointData bp;
         bp.fileName = processedFilename.toUtf8();
-        bp.lineNumber = data->lineNumber;
-        bp.functionName = data->funcName.toUtf8();
+        bp.lineNumber = handler->lineNumber(id);
+        bp.functionName = handler->functionName(id).toUtf8();
         breakpoints.insert(bp);
     }
 
@@ -519,10 +518,11 @@ void QmlEngine::attemptBreakpointSynchronization()
     sendMessage(reply);
 }
 
-bool QmlEngine::acceptsBreakpoint(const Internal::BreakpointData *br)
+bool QmlEngine::acceptsBreakpoint(BreakpointId id)
 {
-    return br->fileName.endsWith(QLatin1String(".qml"))
-        || br->fileName.endsWith(QLatin1String(".js"));
+    const QString fileName = breakHandler()->fileName(id);
+    return fileName.endsWith(QLatin1String(".qml"))
+        || fileName.endsWith(QLatin1String(".js"));
 }
 
 void QmlEngine::loadSymbols(const QString &moduleName)
@@ -563,7 +563,7 @@ void QmlEngine::setToolTipExpression(const QPoint &mousePos,
 //
 //////////////////////////////////////////////////////////////////////
 
-void QmlEngine::assignValueInDebugger(const Internal::WatchData *,
+void QmlEngine::assignValueInDebugger(const WatchData *,
     const QString &expression, const QVariant &valueV)
 {
     QRegExp inObject("@([0-9a-fA-F]+)->(.+)");
@@ -581,8 +581,8 @@ void QmlEngine::assignValueInDebugger(const Internal::WatchData *,
     }
 }
 
-void QmlEngine::updateWatchData(const Internal::WatchData &data,
-    const Internal::WatchUpdateFlags &)
+void QmlEngine::updateWatchData(const WatchData &data,
+    const WatchUpdateFlags &)
 {
 //    qDebug() << "UPDATE WATCH DATA" << data.toString();
     //watchHandler()->rebuildModel();
@@ -661,15 +661,15 @@ void QmlEngine::messageReceived(const QByteArray &message)
     stream >> command;
 
     showMessage(QLatin1String("RECEIVED RESPONSE: ")
-        + Internal::quoteUnprintableLatin1(message));
+        + quoteUnprintableLatin1(message));
 
     if (command == "STOPPED") {
         if (state() == InferiorRunOk)
             notifyInferiorSpontaneousStop();
 
-        Internal::StackFrames stackFrames;
-        QList<Internal::WatchData> watches;
-        QList<Internal::WatchData> locals;
+        StackFrames stackFrames;
+        QList<WatchData> watches;
+        QList<WatchData> locals;
         stream >> stackFrames >> watches >> locals;
 
         for (int i = 0; i != stackFrames.size(); ++i)
@@ -681,7 +681,7 @@ void QmlEngine::messageReceived(const QByteArray &message)
         watchHandler()->beginCycle();
         bool needPing = false;
 
-        foreach (Internal::WatchData data, watches) {
+        foreach (WatchData data, watches) {
             data.iname = watchHandler()->watcherName(data.exp);
             watchHandler()->insertData(data);
 
@@ -691,7 +691,7 @@ void QmlEngine::messageReceived(const QByteArray &message)
             }
         }
 
-        foreach (Internal::WatchData data, locals) {
+        foreach (WatchData data, locals) {
             data.iname = "local." + data.exp;
             watchHandler()->insertData(data);
 
@@ -734,22 +734,21 @@ void QmlEngine::messageReceived(const QByteArray &message)
                 }
             }
 
-            Internal::BreakHandler *handler = breakHandler();
-            for (int index = 0; index != handler->size(); ++index) {
-                Internal::BreakpointData *data = handler->at(index);
-                QString processedFilename = data->fileName;
-
-                if (processedFilename == file && data->lineNumber == line) {
-                    data->pending = false;
-                    data->bpFileName = file;
-                    data->bpLineNumber = line;
-                    data->bpFuncName = function;
-                    handler->updateMarker(data);
+            BreakHandler *handler = breakHandler();
+            foreach (BreakpointId id, handler->engineBreakpointIds(this)) {
+                QString processedFilename = handler->fileName(id);
+                if (processedFilename == file && handler->lineNumber(id) == line) {
+                    handler->setState(id, BreakpointInserted);
+                    BreakpointResponse br = handler->response(id);
+                    br.bpFileName = file;
+                    br.bpLineNumber = line;
+                    br.bpFuncName = function;
+                    handler->setResponse(id, br);
                 }
             }
         }
     } else if (command == "RESULT") {
-        Internal::WatchData data;
+        WatchData data;
         QByteArray iname;
         stream >> iname >> data;
         data.iname = iname;
@@ -761,11 +760,11 @@ void QmlEngine::messageReceived(const QByteArray &message)
             qWarning() << "QmlEngine: Unexcpected result: " << iname << data.value;
         }
     } else if (command == "EXPANDED") {
-        QList<Internal::WatchData> result;
+        QList<WatchData> result;
         QByteArray iname;
         stream >> iname >> result;
         bool needPing = false;
-        foreach (Internal::WatchData data, result) {
+        foreach (WatchData data, result) {
             data.iname = iname + '.' + data.exp;
             watchHandler()->insertData(data);
 
@@ -777,12 +776,12 @@ void QmlEngine::messageReceived(const QByteArray &message)
         if (needPing)
             sendPing();
     } else if (command == "LOCALS") {
-        QList<Internal::WatchData> locals;
+        QList<WatchData> locals;
         int frameId;
         stream >> frameId >> locals;
         watchHandler()->beginCycle();
         bool needPing = false;
-        foreach (Internal::WatchData data, locals) {
+        foreach (WatchData data, locals) {
             data.iname = "local." + data.exp;
             watchHandler()->insertData(data);
             if (watchHandler()->expandedINames().contains(data.iname)) {
diff --git a/src/plugins/debugger/qml/qmlengine.h b/src/plugins/debugger/qml/qmlengine.h
index 9df910b0b9055a99ca89a99d2a2be9fc5e4194b2..3cc949d7d3225d3eeedd25b856a5e8adec6540b4 100644
--- a/src/plugins/debugger/qml/qmlengine.h
+++ b/src/plugins/debugger/qml/qmlengine.h
@@ -94,9 +94,10 @@ private:
     void selectThread(int index);
 
     void attemptBreakpointSynchronization();
-    bool acceptsBreakpoint(const Internal::BreakpointData *br);
+    bool acceptsBreakpoint(BreakpointId id);
 
-    void assignValueInDebugger(const Internal::WatchData *w, const QString &expr, const QVariant &value);
+    void assignValueInDebugger(const Internal::WatchData *data,
+        const QString &expr, const QVariant &value);
     void loadSymbols(const QString &moduleName);
     void loadAllSymbols();
     void requestModuleSymbols(const QString &moduleName);
diff --git a/src/plugins/debugger/registerwindow.cpp b/src/plugins/debugger/registerwindow.cpp
index 053b23719fe92aa6ec9ceadaf8239b028cff8ad3..6893dcc3433ac2318900a17bfd62f0e02e3d6c42 100644
--- a/src/plugins/debugger/registerwindow.cpp
+++ b/src/plugins/debugger/registerwindow.cpp
@@ -157,7 +157,7 @@ public:
 RegisterWindow::RegisterWindow(QWidget *parent)
   : QTreeView(parent), m_alwaysResizeColumnsToContents(true)
 {
-    QAction *act = theDebuggerAction(UseAlternatingRowColors);
+    QAction *act = debuggerCore()->action(UseAlternatingRowColors);
     setFrameStyle(QFrame::NoFrame);
     setWindowTitle(tr("Registers"));
     setAttribute(Qt::WA_MacShowFocusRect, false);
@@ -226,7 +226,7 @@ void RegisterWindow::contextMenuEvent(QContextMenuEvent *ev)
     actAlwaysAdjust->setChecked(m_alwaysResizeColumnsToContents);
     menu.addSeparator();
 
-    menu.addAction(theDebuggerAction(SettingsDialog));
+    menu.addAction(debuggerCore()->action(SettingsDialog));
 
     QAction *act = menu.exec(ev->globalPos());
 
diff --git a/src/plugins/debugger/script/scriptengine.cpp b/src/plugins/debugger/script/scriptengine.cpp
index b6f3ff35547501e972bc10c5fe499fbdea000310..dd70b92d4dc60df1a6a474f014ca071a5f7f4b02 100644
--- a/src/plugins/debugger/script/scriptengine.cpp
+++ b/src/plugins/debugger/script/scriptengine.cpp
@@ -33,6 +33,7 @@
 
 #include "breakhandler.h"
 #include "debuggerconstants.h"
+#include "debuggercore.h"
 #include "debuggerdialogs.h"
 #include "debuggerstringutils.h"
 #include "moduleshandler.h"
@@ -448,6 +449,8 @@ void ScriptEngine::selectThread(int index)
 
 void ScriptEngine::attemptBreakpointSynchronization()
 {
+    QTC_ASSERT(false, /* FIXME */);
+/*
     BreakHandler *handler = breakHandler();
     bool updateNeeded = false;
     for (int index = 0; index != handler->size(); ++index) {
@@ -468,6 +471,7 @@ void ScriptEngine::attemptBreakpointSynchronization()
     }
     if (updateNeeded)
         handler->updateMarkers();
+*/
 }
 
 void ScriptEngine::loadSymbols(const QString &moduleName)
@@ -589,31 +593,6 @@ void ScriptEngine::assignValueInDebugger(const Internal::WatchData *,
     updateLocals();
 }
 
-static BreakpointData *findBreakPointByFunction(BreakHandler *handler,
-                                                const QString &functionName)
-{
-    const int count = handler->size();
-    for (int b = 0; b < count; b++) {
-        BreakpointData *data = handler->at(b);
-        if (data->funcName == functionName)
-            return data;
-    }
-    return 0;
-}
-
-static BreakpointData *findBreakPointByFileName(BreakHandler *handler,
-                                              int lineNumber,
-                                              const QString &fileName)
-{
-    const int count = handler->size();
-    for (int b = 0; b < count; b++) {
-        BreakpointData *data = handler->at(b);
-        if (lineNumber == data->lineNumber && fileName == data->fileName)
-            return data;
-    }
-    return 0;
-}
-
 bool ScriptEngine::checkForBreakCondition(bool byFunction)
 {
     // FIXME: Should that ever happen after setAgent(0) in shutdownInferior()?
@@ -629,33 +608,30 @@ bool ScriptEngine::checkForBreakCondition(bool byFunction)
     const QString fileName = info.fileName();
     const int lineNumber = byFunction
         ? info.functionStartLineNumber() : info.lineNumber();
-    SDEBUG(Q_FUNC_INFO << byFunction << functionName
-        << lineNumber << fileName);
+    SDEBUG(Q_FUNC_INFO << byFunction << functionName << lineNumber << fileName);
     if (m_stopOnNextLine) {
         // Interrupt inferior
         m_stopOnNextLine = false;
     } else {
         if (byFunction && functionName.isEmpty())
             return false;
-        BreakpointData *data = byFunction ?
-           findBreakPointByFunction(breakHandler(), functionName) :
-           findBreakPointByFileName(breakHandler(), lineNumber, fileName);
-        if (!data)
-            return false;
+        BreakHandler *handler = breakHandler();
+        BreakpointId id = byFunction ?
+           handler->findBreakpointByFunction(functionName) :
+           handler->findBreakpointByFileAndLine(fileName, lineNumber, false);
 
         // Skip disabled breakpoint.
-        if (!data->enabled)
+        if (!handler->isEnabled(id))
             return false;
 
+        BreakpointResponse br;
         // We just run into a breakpoint.
         //SDEBUG("RESOLVING BREAKPOINT AT " << fileName << lineNumber);
-        data->bpLineNumber = lineNumber;
-        data->bpFileName = fileName;
-        data->bpFuncName = functionName;
-        data->setMarkerLineNumber(lineNumber);
-        data->setMarkerFileName(fileName);
-        data->pending = false;
-        breakHandler()->updateMarker(data);
+        br.bpLineNumber = lineNumber;
+        br.bpFileName = fileName;
+        br.bpFuncName = functionName;
+        handler->setState(id, BreakpointInserted);
+        handler->setResponse(id, br);
     }
     notifyInferiorSpontaneousStop();
     SDEBUG("Stopped at " << lineNumber << fileName);
diff --git a/src/plugins/debugger/script/scriptengine.h b/src/plugins/debugger/script/scriptengine.h
index 82b6894fa78e1e0219f50ce6fa138ecf6dba2c73..d73a2e034f0277cce14b8e718d4b02cc892c3eb9 100644
--- a/src/plugins/debugger/script/scriptengine.h
+++ b/src/plugins/debugger/script/scriptengine.h
@@ -89,7 +89,8 @@ private:
 
     void attemptBreakpointSynchronization();
 
-    void assignValueInDebugger(const Internal::WatchData *w, const QString &expr, const QVariant &value);
+    void assignValueInDebugger(const WatchData *w,
+        const QString &expr, const QVariant &value);
     void executeDebuggerCommand(const QString &command);
 
     void loadSymbols(const QString &moduleName);
diff --git a/src/plugins/debugger/snapshotwindow.cpp b/src/plugins/debugger/snapshotwindow.cpp
index 74b534e4e50461f63cbb4c18a853cdf279e2d2e7..97519b68e8a97dd84a5aa27ea6a6af11de8d06bf 100644
--- a/src/plugins/debugger/snapshotwindow.cpp
+++ b/src/plugins/debugger/snapshotwindow.cpp
@@ -31,7 +31,7 @@
 #include "snapshothandler.h"
 
 #include "debuggeractions.h"
-#include "debuggerconstants.h"
+#include "debuggercore.h"
 #include "debuggerrunner.h"
 
 #include <utils/qtcassert.h>
@@ -43,15 +43,6 @@
 #include <QtGui/QMenu>
 #include <QtGui/QKeyEvent>
 
-static QModelIndexList normalizeIndexes(const QModelIndexList &list)
-{
-    QModelIndexList res;
-    foreach (const QModelIndex &idx, list)
-        if (idx.column() == 0)
-            res.append(idx);
-    return res;
-}
-
 
 namespace Debugger {
 namespace Internal {
@@ -67,7 +58,7 @@ SnapshotWindow::SnapshotWindow(SnapshotHandler *handler)
 {
     m_snapshotHandler = handler;
 
-    QAction *act = theDebuggerAction(UseAlternatingRowColors);
+    QAction *act = debuggerCore()->action(UseAlternatingRowColors);
     setWindowTitle(tr("Snapshots"));
     setAttribute(Qt::WA_MacShowFocusRect, false);
     setFrameStyle(QFrame::NoFrame);
@@ -96,8 +87,10 @@ void SnapshotWindow::keyPressEvent(QKeyEvent *ev)
         QModelIndexList si = sm->selectedIndexes();
         if (si.isEmpty())
             si.append(currentIndex().sibling(currentIndex().row(), 0));
-        foreach (const QModelIndex &idx, normalizeIndexes(si))
-            removeSnapshot(idx.row());
+
+        foreach (const QModelIndex &idx, si)
+            if (idx.column() == 0)
+                removeSnapshot(idx.row());
     }
     QTreeView::keyPressEvent(ev);
 }
@@ -127,7 +120,7 @@ void SnapshotWindow::contextMenuEvent(QContextMenuEvent *ev)
 
     menu.addSeparator();
 
-    menu.addAction(theDebuggerAction(SettingsDialog));
+    menu.addAction(debuggerCore()->action(SettingsDialog));
 
     QAction *act = menu.exec(ev->globalPos());
 
diff --git a/src/plugins/debugger/sourcefileswindow.cpp b/src/plugins/debugger/sourcefileswindow.cpp
index f7bcadf213b588af4d93ab635fa205539fbef4ac..55e075c317f96dec45b06251a7be60c0721cee04 100644
--- a/src/plugins/debugger/sourcefileswindow.cpp
+++ b/src/plugins/debugger/sourcefileswindow.cpp
@@ -62,7 +62,7 @@ static DebuggerEngine *currentEngine()
 SourceFilesWindow::SourceFilesWindow(QWidget *parent)
     : QTreeView(parent)
 {
-    QAction *act = theDebuggerAction(UseAlternatingRowColors);
+    QAction *act = debuggerCore()->action(UseAlternatingRowColors);
 
     setAttribute(Qt::WA_MacShowFocusRect, false);
     setFrameStyle(QFrame::NoFrame);
@@ -108,7 +108,7 @@ void SourceFilesWindow::contextMenuEvent(QContextMenuEvent *ev)
     menu.addAction(act1);
     menu.addAction(act2);
     menu.addSeparator();
-    menu.addAction(theDebuggerAction(SettingsDialog));
+    menu.addAction(debuggerCore()->action(SettingsDialog));
 
     QAction *act = menu.exec(ev->globalPos());
 
diff --git a/src/plugins/debugger/stackhandler.cpp b/src/plugins/debugger/stackhandler.cpp
index 731523f333a81e0d74dc2111150f9e9267d136ab..a2c5df6bf182c080777f4c85f1950ebd1cfc2d86 100644
--- a/src/plugins/debugger/stackhandler.cpp
+++ b/src/plugins/debugger/stackhandler.cpp
@@ -31,6 +31,7 @@
 
 #include "debuggeractions.h"
 #include "debuggeragents.h"
+#include "debuggercore.h"
 #include "debuggerengine.h"
 
 #include <utils/qtcassert.h>
@@ -54,7 +55,7 @@ StackHandler::StackHandler()
 {
     m_currentIndex = 0;
     m_canExpand = false;
-    connect(theDebuggerAction(OperateByInstruction), SIGNAL(triggered()),
+    connect(debuggerCore()->action(OperateByInstruction), SIGNAL(triggered()),
         this, SLOT(resetModel()));
 }
 
@@ -142,7 +143,7 @@ Qt::ItemFlags StackHandler::flags(const QModelIndex &index) const
         return QAbstractTableModel::flags(index);
     const StackFrame &frame = m_stackFrames.at(index.row());
     const bool isValid = (frame.isUsable() && !frame.function.isEmpty())
-        || theDebuggerBoolSetting(OperateByInstruction);
+        || debuggerCore()->boolSetting(OperateByInstruction);
     return isValid ? QAbstractTableModel::flags(index) : Qt::ItemFlags(0);
 }
 
diff --git a/src/plugins/debugger/stackwindow.cpp b/src/plugins/debugger/stackwindow.cpp
index 007fe9758b240c0ddd42240f1c4170bab76fd9d9..25f5cae841e6d9ebe58690ce849f8d6f9446f45e 100644
--- a/src/plugins/debugger/stackwindow.cpp
+++ b/src/plugins/debugger/stackwindow.cpp
@@ -61,7 +61,7 @@ StackWindow::StackWindow(QWidget *parent)
     setAttribute(Qt::WA_MacShowFocusRect, false);
     setFrameStyle(QFrame::NoFrame);
 
-    QAction *act = theDebuggerAction(UseAlternatingRowColors);
+    QAction *act = debuggerCore()->action(UseAlternatingRowColors);
     setWindowTitle(tr("Stack"));
 
     setAlternatingRowColors(act->isChecked());
@@ -76,11 +76,11 @@ StackWindow::StackWindow(QWidget *parent)
         SLOT(rowActivated(QModelIndex)));
     connect(act, SIGNAL(toggled(bool)),
         SLOT(setAlternatingRowColorsHelper(bool)));
-    connect(theDebuggerAction(UseAddressInStackView), SIGNAL(toggled(bool)),
+    connect(debuggerCore()->action(UseAddressInStackView), SIGNAL(toggled(bool)),
         SLOT(showAddressColumn(bool)));
-    connect(theDebuggerAction(ExpandStack), SIGNAL(triggered()),
+    connect(debuggerCore()->action(ExpandStack), SIGNAL(triggered()),
         SLOT(reloadFullStack()));
-    connect(theDebuggerAction(MaximalStackDepth), SIGNAL(triggered()),
+    connect(debuggerCore()->action(MaximalStackDepth), SIGNAL(triggered()),
         SLOT(reloadFullStack()));
 }
 
@@ -107,13 +107,13 @@ void StackWindow::contextMenuEvent(QContextMenuEvent *ev)
     const quint64 address = frame.address;
 
     QMenu menu;
-    menu.addAction(theDebuggerAction(ExpandStack));
+    menu.addAction(debuggerCore()->action(ExpandStack));
 
     QAction *actCopyContents = menu.addAction(tr("Copy Contents to Clipboard"));
     actCopyContents->setEnabled(model() != 0);
 
     if (engineCapabilities & CreateFullBacktraceCapability)
-        menu.addAction(theDebuggerAction(CreateFullBacktrace));
+        menu.addAction(debuggerCore()->action(CreateFullBacktrace));
 
     QAction *actShowMemory = menu.addAction(QString());
     if (address == 0) {
@@ -135,9 +135,9 @@ void StackWindow::contextMenuEvent(QContextMenuEvent *ev)
 
     menu.addSeparator();
 #if 0 // @TODO: not implemented
-    menu.addAction(theDebuggerAction(UseToolTipsInStackView));
+    menu.addAction(debuggerCore()->action(UseToolTipsInStackView));
 #endif
-    menu.addAction(theDebuggerAction(UseAddressInStackView));
+    menu.addAction(debuggerCore()->action(UseAddressInStackView));
 
     QAction *actAdjust = menu.addAction(tr("Adjust Column Widths to Contents"));
 
@@ -148,7 +148,7 @@ void StackWindow::contextMenuEvent(QContextMenuEvent *ev)
 
     menu.addSeparator();
 
-    menu.addAction(theDebuggerAction(SettingsDialog));
+    menu.addAction(debuggerCore()->action(SettingsDialog));
 
     QAction *act = menu.exec(ev->globalPos());
 
diff --git a/src/plugins/debugger/threadswindow.cpp b/src/plugins/debugger/threadswindow.cpp
index e63ba6656e2dd38bca00459f931459f7ddd20c61..5349204fbd5e815623e977d97f2a99971724abe1 100644
--- a/src/plugins/debugger/threadswindow.cpp
+++ b/src/plugins/debugger/threadswindow.cpp
@@ -47,7 +47,7 @@ namespace Internal {
 ThreadsWindow::ThreadsWindow(QWidget *parent)
     : QTreeView(parent), m_alwaysResizeColumnsToContents(false)
 {
-    QAction *act = theDebuggerAction(UseAlternatingRowColors);
+    QAction *act = debuggerCore()->action(UseAlternatingRowColors);
 
     setAttribute(Qt::WA_MacShowFocusRect, false);
     setFrameStyle(QFrame::NoFrame);
@@ -80,7 +80,7 @@ void ThreadsWindow::contextMenuEvent(QContextMenuEvent *ev)
     alwaysAdjustColumnAction->setChecked(m_alwaysResizeColumnsToContents);
     menu.addSeparator();
 
-    menu.addAction(theDebuggerAction(SettingsDialog));
+    menu.addAction(debuggerCore()->action(SettingsDialog));
 
     QAction *act = menu.exec(ev->globalPos());
     if (!act)
diff --git a/src/plugins/debugger/watchhandler.cpp b/src/plugins/debugger/watchhandler.cpp
index 65cf5d59c3576b3f2f7c674332027f1289813f6e..488de4223dc5865eb7848311fd5e05db413e8e5b 100644
--- a/src/plugins/debugger/watchhandler.cpp
+++ b/src/plugins/debugger/watchhandler.cpp
@@ -383,9 +383,9 @@ QString WatchModel::displayType(const WatchData &data) const
     if (!data.displayedType.isEmpty())
         return data.displayedType;
     QString type = niceTypeHelper(data.type);
-    if (!theDebuggerBoolSetting(ShowStdNamespace))
+    if (!debuggerCore()->boolSetting(ShowStdNamespace))
         type.remove(QLatin1String("std::"));
-    if (!theDebuggerBoolSetting(ShowQtNamespace)) {
+    if (!debuggerCore()->boolSetting(ShowQtNamespace)) {
         const QString qtNamespace = QString::fromLatin1(engine()->qtNamespace());
         if (!qtNamespace.isEmpty())
             type.remove(qtNamespace);
@@ -742,7 +742,7 @@ QVariant WatchModel::data(const QModelIndex &idx, int role) const
                 default: break;
             }  // switch editrole column
         case Qt::ToolTipRole:
-            return theDebuggerBoolSetting(UseToolTipsInLocalsView)
+            return debuggerCore()->boolSetting(UseToolTipsInLocalsView)
                 ? data.toToolTip() : QVariant();
 
         case Qt::ForegroundRole: {
@@ -800,7 +800,7 @@ QVariant WatchModel::data(const QModelIndex &idx, int role) const
 
         case LocalsIsWatchpointAtAddressRole:
             return engine()->breakHandler()
-                ->watchPointAt(data.coreAddress());
+                ->hasWatchpointAt(data.coreAddress());
 
         case LocalsAddressRole:
             return data.coreAddress();
@@ -808,7 +808,7 @@ QVariant WatchModel::data(const QModelIndex &idx, int role) const
         case LocalsIsWatchpointAtPointerValueRole:
             if (isPointerType(data.type))
                 return engine()->breakHandler()
-                    ->watchPointAt(pointerValue(data.value));
+                    ->hasWatchpointAt(pointerValue(data.value));
             return false;
 
         default:
@@ -966,7 +966,7 @@ bool watchItemSorter(const WatchItem *item1, const WatchItem *item2)
 
 static int findInsertPosition(const QList<WatchItem *> &list, const WatchItem *item)
 {
-    sortWatchDataAlphabetically = theDebuggerBoolSetting(SortStructMembers);
+    sortWatchDataAlphabetically = debuggerCore()->boolSetting(SortStructMembers);
     const QList<WatchItem *>::const_iterator it =
         qLowerBound(list.begin(), list.end(), item, watchItemSorter);
     return it - list.begin();
@@ -1053,7 +1053,7 @@ void WatchModel::insertBulkData(const QList<WatchData> &list)
     }
     QModelIndex index = watchIndex(parent);
 
-    sortWatchDataAlphabetically = theDebuggerBoolSetting(SortStructMembers);
+    sortWatchDataAlphabetically = debuggerCore()->boolSetting(SortStructMembers);
     QMap<WatchDataSortKey, WatchData> newList;
     typedef QMap<WatchDataSortKey, WatchData>::iterator Iterator;
     foreach (const WatchItem &data, list)
@@ -1185,11 +1185,11 @@ WatchHandler::WatchHandler(DebuggerEngine *engine)
     m_watchers = new WatchModel(this, WatchersWatch);
     m_tooltips = new WatchModel(this, TooltipsWatch);
 
-    connect(theDebuggerAction(ShowStdNamespace),
+    connect(debuggerCore()->action(ShowStdNamespace),
         SIGNAL(triggered()), this, SLOT(emitAllChanged()));
-    connect(theDebuggerAction(ShowQtNamespace),
+    connect(debuggerCore()->action(ShowQtNamespace),
         SIGNAL(triggered()), this, SLOT(emitAllChanged()));
-    connect(theDebuggerAction(SortStructMembers),
+    connect(debuggerCore()->action(SortStructMembers),
         SIGNAL(triggered()), this, SLOT(emitAllChanged()));
 }
 
diff --git a/src/plugins/debugger/watchwindow.cpp b/src/plugins/debugger/watchwindow.cpp
index bcab265b8f5006a86b478bf5a775147c93b469c7..fdb016f161b78e2e9f70f702b1fa65322f6daf66 100644
--- a/src/plugins/debugger/watchwindow.cpp
+++ b/src/plugins/debugger/watchwindow.cpp
@@ -140,7 +140,7 @@ WatchWindow::WatchWindow(Type type, QWidget *parent)
 {
     m_grabbing = false;
 
-    QAction *act = theDebuggerAction(UseAlternatingRowColors);
+    QAction *act = debuggerCore()->action(UseAlternatingRowColors);
     setFrameStyle(QFrame::NoFrame);
     setAttribute(Qt::WA_MacShowFocusRect, false);
     setWindowTitle(tr("Locals and Watchers"));
@@ -343,29 +343,29 @@ void WatchWindow::contextMenuEvent(QContextMenuEvent *ev)
                 .arg(pointerValue, 0, 16), &menu);
     menu.addSeparator();
 
-    QAction *actSetWatchPointAtVariableAddress = 0;
-    QAction *actSetWatchPointAtPointerValue = 0;
+    QAction *actSetWatchpointAtVariableAddress = 0;
+    QAction *actSetWatchpointAtPointerValue = 0;
     const bool canSetWatchpoint = engineCapabilities & WatchpointCapability;
     if (canSetWatchpoint && address) {
-        actSetWatchPointAtVariableAddress =
+        actSetWatchpointAtVariableAddress =
             new QAction(tr("Add Watchpoint at Object's Address (0x%1)")
                 .arg(address, 0, 16), &menu);
-        actSetWatchPointAtVariableAddress->
+        actSetWatchpointAtVariableAddress->
             setChecked(mi0.data(LocalsIsWatchpointAtAddressRole).toBool());
         if (createPointerActions) {
-            actSetWatchPointAtPointerValue =
+            actSetWatchpointAtPointerValue =
                 new QAction(tr("Add Watchpoint at Referenced Address (0x%1)")
                     .arg(pointerValue, 0, 16), &menu);
-            actSetWatchPointAtPointerValue->setCheckable(true);
-            actSetWatchPointAtPointerValue->
+            actSetWatchpointAtPointerValue->setCheckable(true);
+            actSetWatchpointAtPointerValue->
                 setChecked(mi0.data(LocalsIsWatchpointAtPointerValueRole).toBool());
         }
     } else {
-        actSetWatchPointAtVariableAddress =
+        actSetWatchpointAtVariableAddress =
             new QAction(tr("At Watchpoint"), &menu);
-        actSetWatchPointAtVariableAddress->setEnabled(false);
+        actSetWatchpointAtVariableAddress->setEnabled(false);
     }
-    actSetWatchPointAtVariableAddress->setToolTip(
+    actSetWatchpointAtVariableAddress->setToolTip(
         tr("Setting a watchpoint on an address will cause the program "
            "to stop when the data at the address it modified."));
 
@@ -395,17 +395,17 @@ void WatchWindow::contextMenuEvent(QContextMenuEvent *ev)
     if (actOpenMemoryEditAtPointerValue)
         menu.addAction(actOpenMemoryEditAtPointerValue);
     menu.addAction(actOpenMemoryEditor);
-    menu.addAction(actSetWatchPointAtVariableAddress);
-    if (actSetWatchPointAtPointerValue)
-        menu.addAction(actSetWatchPointAtPointerValue);
+    menu.addAction(actSetWatchpointAtVariableAddress);
+    if (actSetWatchpointAtPointerValue)
+        menu.addAction(actSetWatchpointAtPointerValue);
     menu.addSeparator();
 
-    menu.addAction(theDebuggerAction(UseDebuggingHelpers));
-    menu.addAction(theDebuggerAction(UseToolTipsInLocalsView));
-    menu.addAction(theDebuggerAction(AutoDerefPointers));
-    menu.addAction(theDebuggerAction(ShowStdNamespace));
-    menu.addAction(theDebuggerAction(ShowQtNamespace));
-    menu.addAction(theDebuggerAction(SortStructMembers));
+    menu.addAction(debuggerCore()->action(UseDebuggingHelpers));
+    menu.addAction(debuggerCore()->action(UseToolTipsInLocalsView));
+    menu.addAction(debuggerCore()->action(AutoDerefPointers));
+    menu.addAction(debuggerCore()->action(ShowStdNamespace));
+    menu.addAction(debuggerCore()->action(ShowQtNamespace));
+    menu.addAction(debuggerCore()->action(SortStructMembers));
 
     QAction *actAdjustColumnWidths =
         menu.addAction(tr("Adjust Column Widths to Contents"));
@@ -418,13 +418,13 @@ void WatchWindow::contextMenuEvent(QContextMenuEvent *ev)
     QAction *actClearCodeModelSnapshot
         = new QAction(tr("Refresh Code Model Snapshot"), &menu);
     actClearCodeModelSnapshot->setEnabled(actionsEnabled
-        && theDebuggerAction(UseCodeModel)->isChecked());
+        && debuggerCore()->action(UseCodeModel)->isChecked());
     menu.addAction(actClearCodeModelSnapshot);
     QAction *actShowInEditor
         = new QAction(tr("Show View Contents in Editor"), &menu);
     actShowInEditor->setEnabled(actionsEnabled);
     menu.addAction(actShowInEditor);
-    menu.addAction(theDebuggerAction(SettingsDialog));
+    menu.addAction(debuggerCore()->action(SettingsDialog));
 
     QAction *act = menu.exec(ev->globalPos());
     if (act == 0)
@@ -444,9 +444,9 @@ void WatchWindow::contextMenuEvent(QContextMenuEvent *ev)
         AddressDialog dialog;
         if (dialog.exec() == QDialog::Accepted)
             (void) new MemoryViewAgent(currentEngine(), dialog.address());
-    } else if (act == actSetWatchPointAtVariableAddress) {
+    } else if (act == actSetWatchpointAtVariableAddress) {
         setWatchpoint(address);
-    } else if (act == actSetWatchPointAtPointerValue) {
+    } else if (act == actSetWatchpointAtPointerValue) {
         setWatchpoint(pointerValue);
     } else if (act == actSelectWidgetToWatch) {
         grabMouse(Qt::CrossCursor);
@@ -574,18 +574,7 @@ QVariant WatchWindow::modelData(int role, const QModelIndex &index)
 
 void WatchWindow::setWatchpoint(quint64 address)
 {
-    DebuggerEngine *engine = currentEngine();
-    BreakHandler *handler = engine->breakHandler();
-    const int index = handler->findWatchPointIndexByAddress(address);
-    if (index == -1) {
-        BreakpointData *data = new BreakpointData;
-        data->type = Watchpoint;
-        data->address = address;
-        handler->appendBreakpoint(data);
-    } else {
-        handler->removeBreakpoint(index);
-    }
-    engine->attemptBreakpointSynchronization();
+    breakHandler()->setWatchpointByAddress(address);
 }
 
 } // namespace Internal