diff --git a/src/plugins/debugger/breakhandler.cpp b/src/plugins/debugger/breakhandler.cpp
index c41eb00c86a2824d7defa848ad294e5acac0aec5..8db1e38dc1be1e57eeaf41d667e3cad83fb1639c 100644
--- a/src/plugins/debugger/breakhandler.cpp
+++ b/src/plugins/debugger/breakhandler.cpp
@@ -31,6 +31,7 @@
 
 #include "debuggeractions.h"
 #include "debuggermanager.h"
+#include "debuggerstringutils.h"
 #include "stackframe.h"
 
 #include <texteditor/basetextmark.h>
@@ -53,13 +54,11 @@ using namespace Debugger::Internal;
 // Compare file names case insensitively on Windows.
 static inline bool fileNameMatch(const QString &f1, const QString &f2)
 {
-    return f1.compare(f2,
 #ifdef Q_OS_WIN
-                      Qt::CaseInsensitive
+    return f1.compare(f2, Qt::CaseInsensitive) == 0;
 #else
-                      Qt::CaseSensitive
+    return f1 == f2;
 #endif
-                      ) == 0;
 }
 
 namespace Debugger {
@@ -87,7 +86,7 @@ public:
 
     QIcon icon() const
     {
-        const BreakHandler *handler = DebuggerManager::instance()->breakHandler();
+        const BreakHandler *handler = m_data->handler();
         if (!m_enabled)
             return handler->disabledBreakpointIcon();
         return m_pending ? handler->pendingBreakPointIcon() : handler->breakpointIcon();
@@ -162,28 +161,21 @@ private:
 //
 //////////////////////////////////////////////////////////////////
 
-BreakpointData::BreakpointData(BreakHandler *handler)
+BreakpointData::BreakpointData()
 {
-    //qDebug() << "CREATE BREAKPOINTDATA" << this;
-    m_handler = handler;
+    m_handler = 0;
     enabled = true;
     pending = true;
+    type = BreakpointType;
     marker = 0;
     m_markerLineNumber = 0;
     bpMultiple = false;
-//#if defined(Q_OS_MAC)
-//    // full names do not work on Mac/MI
     useFullPath = false;
-//#else
-//    //where = m_manager->shortName(data->fileName);
-//    useFullPath = true;
-//#endif
 }
 
 BreakpointData::~BreakpointData()
 {
     removeMarker();
-    //qDebug() << "DESTROY BREAKPOINTDATA" << this;
 }
 
 void BreakpointData::removeMarker()
@@ -227,8 +219,6 @@ QString BreakpointData::toToolTip() const
         << "</td><td>" << m_markerLineNumber << "</td></tr>"
         << "<tr><td>" << BreakHandler::tr("Breakpoint Number:")
         << "</td><td>" << bpNumber << "</td></tr>"
-        << "<tr><td>" << BreakHandler::tr("Breakpoint Address:")
-        << "</td><td>" << bpAddress << "</td></tr>"
         << "</table><br><hr><table>"
         << "<tr><th>" << BreakHandler::tr("Property")
         << "</th><th>" << BreakHandler::tr("Requested")
@@ -241,6 +231,8 @@ QString BreakpointData::toToolTip() const
         << "</td><td>" << funcName << "</td><td>" << bpFuncName << "</td></tr>"
         << "<tr><td>" << BreakHandler::tr("Line Number:")
         << "</td><td>" << lineNumber << "</td><td>" << bpLineNumber << "</td></tr>"
+        << "<tr><td>" << BreakHandler::tr("Breakpoint Address:")
+        << "</td><td>" << address << "</td><td>" << bpAddress << "</td></tr>"
         << "<tr><td>" << BreakHandler::tr("Corrected Line Number:")
         << "</td><td>-</td><td>" << bpCorrectedLineNumber << "</td></tr>"
         << "<tr><td>" << BreakHandler::tr("Condition:")
@@ -260,13 +252,14 @@ QString BreakpointData::toString() const
     str << BreakHandler::tr("Marker File:") << m_markerFileName << ' '
         << BreakHandler::tr("Marker Line:") << m_markerLineNumber << ' '
         << BreakHandler::tr("Breakpoint Number:") << bpNumber << ' '
-        << BreakHandler::tr("Breakpoint Address:") << bpAddress << '\n'
         << BreakHandler::tr("File Name:")
         << fileName << " -- " << bpFileName << '\n'
         << BreakHandler::tr("Function Name:")
         << funcName << " -- " << bpFuncName << '\n'
         << BreakHandler::tr("Line Number:")
         << lineNumber << " -- " << bpLineNumber << '\n'
+        << BreakHandler::tr("Breakpoint Address:")
+        << address << " -- " << bpAddress << '\n'
         << BreakHandler::tr("Condition:")
         << condition << " -- " << bpCondition << '\n'
         << BreakHandler::tr("Ignore Count:")
@@ -310,9 +303,10 @@ bool BreakpointData::conditionsMatch() const
 
 BreakHandler::BreakHandler(DebuggerManager *manager, QObject *parent) :
     QAbstractTableModel(parent),
-    m_breakpointIcon(QLatin1String(":/debugger/images/breakpoint_16.png")),
-    m_disabledBreakpointIcon(QLatin1String(":/debugger/images/breakpoint_disabled_16.png")),
-    m_pendingBreakPointIcon(QLatin1String(":/debugger/images/breakpoint_pending_16.png")),
+    m_breakpointIcon(_(":/debugger/images/breakpoint_16.png")),
+    m_disabledBreakpointIcon(_(":/debugger/images/breakpoint_disabled_16.png")),
+    m_pendingBreakPointIcon(_(":/debugger/images/breakpoint_pending_16.png")),
+    m_watchpointIcon(_(":/debugger/images/watchpoint.png")),
     m_manager(manager)
 {
 }
@@ -412,22 +406,29 @@ void BreakHandler::saveBreakpoints()
     for (int index = 0; index != size(); ++index) {
         const BreakpointData *data = at(index);
         QMap<QString, QVariant> map;
+        // Do not persist Watchpoints.
+        //if (data->type == BreakpointData::WatchpointType)
+        //    continue;
+        if (data->type != BreakpointData::BreakpointType)
+            map.insert(_("type"), data->type);
         if (!data->fileName.isEmpty())
-            map.insert(QLatin1String("filename"), data->fileName);
+            map.insert(_("filename"), data->fileName);
         if (!data->lineNumber.isEmpty())
-            map.insert(QLatin1String("linenumber"), data->lineNumber);
+            map.insert(_("linenumber"), data->lineNumber);
         if (!data->funcName.isEmpty())
-            map.insert(QLatin1String("funcname"), data->funcName);
+            map.insert(_("funcname"), data->funcName);
+        if (!data->address.isEmpty())
+            map.insert(_("address"), data->address);
         if (!data->condition.isEmpty())
-            map.insert(QLatin1String("condition"), data->condition);
+            map.insert(_("condition"), data->condition);
         if (!data->ignoreCount.isEmpty())
-            map.insert(QLatin1String("ignorecount"), data->ignoreCount);
+            map.insert(_("ignorecount"), data->ignoreCount);
         if (!data->threadSpec.isEmpty())
-            map.insert(QLatin1String("threadspec"), data->threadSpec);
+            map.insert(_("threadspec"), data->threadSpec);
         if (!data->enabled)
-            map.insert(QLatin1String("disabled"), QLatin1String("1"));
+            map.insert(_("disabled"), _("1"));
         if (data->useFullPath)
-            map.insert(QLatin1String("usefullpath"), QLatin1String("1"));
+            map.insert(_("usefullpath"), _("1"));
         list.append(map);
     }
     m_manager->setSessionValue("Breakpoints", list);
@@ -440,31 +441,37 @@ void BreakHandler::loadBreakpoints()
     clear();
     foreach (const QVariant &var, list) {
         const QMap<QString, QVariant> map = var.toMap();
-        BreakpointData *data = new BreakpointData(this);
-        QVariant v = map.value(QLatin1String("filename"));
+        BreakpointData *data = new BreakpointData;
+        QVariant v = map.value(_("filename"));
         if (v.isValid())
             data->fileName = v.toString();
-        v = map.value(QLatin1String("linenumber"));
+        v = map.value(_("linenumber"));
         if (v.isValid())
             data->lineNumber = v.toString().toLatin1();
-        v = map.value(QLatin1String("condition"));
+        v = map.value(_("condition"));
         if (v.isValid())
             data->condition = v.toString().toLatin1();
-        v = map.value(QLatin1String("ignorecount"));
+        v = map.value(_("address"));
+        if (v.isValid())
+            data->address = v.toString().toLatin1();
+        v = map.value(_("ignorecount"));
         if (v.isValid())
             data->ignoreCount = v.toString().toLatin1();
-        v = map.value(QLatin1String("threadspec"));
+        v = map.value(_("threadspec"));
         if (v.isValid())
             data->threadSpec = v.toString().toLatin1();
-        v = map.value(QLatin1String("funcname"));
+        v = map.value(_("funcname"));
         if (v.isValid())
             data->funcName = v.toString();
-        v = map.value(QLatin1String("disabled"));
+        v = map.value(_("disabled"));
         if (v.isValid())
             data->enabled = !v.toInt();
-        v = map.value(QLatin1String("usefullpath"));
+        v = map.value(_("usefullpath"));
         if (v.isValid())
             data->useFullPath = bool(v.toInt());
+        v = map.value(_("type"));
+        if (v.isValid())
+            data->type = BreakpointData::Type(v.toInt());
         data->setMarkerFileName(data->fileName);
         data->setMarkerLineNumber(data->lineNumber.toInt());
         append(data);
@@ -538,6 +545,8 @@ QVariant BreakHandler::data(const QModelIndex &mi, int role) const
             if (role == Qt::UserRole)
                 return data->enabled;
             if (role == Qt::DecorationRole) {
+                if (data->type == BreakpointData::WatchpointType)
+                    return m_watchpointIcon;
                 if (!data->enabled)
                     return m_disabledBreakpointIcon;
                 return data->pending ? m_pendingBreakPointIcon : m_breakpointIcon;
@@ -606,8 +615,11 @@ QVariant BreakHandler::data(const QModelIndex &mi, int role) const
             if (role == Qt::UserRole + 1)
                 return data->threadSpec;
         case 7:
-            if (role == Qt::DisplayRole)
+            if (role == Qt::DisplayRole) {
+                if (data->type == BreakpointData::WatchpointType)
+                    return data->address;
                 return data->bpAddress;
+            } 
             break;
     }
     if (role == Qt::ToolTipRole)
@@ -706,6 +718,7 @@ bool BreakHandler::setData(const QModelIndex &mi, const QVariant &value, int rol
 
 void BreakHandler::append(BreakpointData *data)
 {
+    data->m_handler = this;
     m_bp.append(data);
     m_inserted.append(data);
 }
@@ -823,7 +836,7 @@ void BreakHandler::breakByFunction(const QString &functionName)
                 && data->ignoreCount.isEmpty())
             return;
     }
-    BreakpointData *data = new BreakpointData(this);
+    BreakpointData *data = new BreakpointData;
     data->funcName = functionName;
     append(data);
     saveBreakpoints();
diff --git a/src/plugins/debugger/breakhandler.h b/src/plugins/debugger/breakhandler.h
index ad2c640a30f7b7441d12a111f56d2fcc11baf77c..c773fdd2001f4fc42e248a3370d56c6236b5255f 100644
--- a/src/plugins/debugger/breakhandler.h
+++ b/src/plugins/debugger/breakhandler.h
@@ -30,90 +30,15 @@
 #ifndef DEBUGGER_BREAKHANDLER_H
 #define DEBUGGER_BREAKHANDLER_H
 
+#include "breakpoint.h"
+
 #include <QtCore/QObject>
 #include <QtCore/QAbstractTableModel>
 #include <QtGui/QIcon>
 
 namespace Debugger {
-class DebuggerManager;
 namespace Internal {
 
-class BreakpointMarker;
-class BreakHandler;
-
-//////////////////////////////////////////////////////////////////
-//
-// BreakpointData
-//
-//////////////////////////////////////////////////////////////////
-
-class BreakpointData
-{
-public:
-    explicit BreakpointData(BreakHandler *handler);
-    ~BreakpointData();
-
-    void removeMarker();
-    void updateMarker();
-    QString toToolTip() const;
-    QString toString() const;
-    BreakHandler *handler() { return m_handler; }
-
-    bool isLocatedAt(const QString &fileName, int lineNumber) const;
-    bool conditionsMatch() const;
-
-private:
-    // Intentionally unimplemented.
-    // Making it copyable is tricky because of the markers.
-    void operator=(const BreakpointData &);
-    BreakpointData(const BreakpointData &);
-
-    // Our owner
-    BreakHandler *m_handler; // Not owned.
-
-public:
-    bool enabled;            // Should we talk to the debugger engine?
-    bool pending;            // Does the debugger engine know about us already?
-
-    // This "user requested information" will get stored in the session.
-    QString fileName;        // Short name of source file.
-    QByteArray condition;    // Condition associated with breakpoint.
-    QByteArray ignoreCount;  // Ignore count associated with breakpoint.
-    QByteArray lineNumber;   // Line in source file.
-    QByteArray threadSpec;   // Thread specification.
-    QString funcName;        // Name of containing function.
-    bool useFullPath;        // Should we use the full path when setting the bp?
-
-    // This is what gdb produced in response.
-    QByteArray bpNumber;     // Breakpoint number assigned by the debugger engine.
-    QByteArray bpCondition;  // Condition acknowledged by the debugger engine.
-    QByteArray 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.
-    QByteArray bpLineNumber; // Line number acknowledged by the debugger engine.
-    QByteArray bpCorrectedLineNumber; // Acknowledged by the debugger engine.
-    QByteArray bpThreadSpec; // Thread spec acknowledged by the debugger engine.
-    QString bpFuncName;      // Function name acknowledged by the debugger engine.
-    QByteArray bpAddress;    // Address acknowledged by the debugger engine.
-    bool bpMultiple;         // Happens in constructors/gdb.
-    bool bpEnabled;          // Enable/disable command sent.
-
-    void setMarkerFileName(const QString &fileName);
-    QString markerFileName() const { return m_markerFileName; }
-
-    void setMarkerLineNumber(int lineNumber);
-    int markerLineNumber() const { return m_markerLineNumber; }
-
-private:
-    // Taken from either user input or gdb responses.
-    QString m_markerFileName; // Used to locate the marker.
-    int m_markerLineNumber;
-
-    // Our red blob in the editor.
-    BreakpointMarker *marker;
-};
-
-
 //////////////////////////////////////////////////////////////////
 //
 // BreakHandler
@@ -184,6 +109,7 @@ private:
     const QIcon m_breakpointIcon;
     const QIcon m_disabledBreakpointIcon;
     const QIcon m_pendingBreakPointIcon;
+    const QIcon m_watchpointIcon;
 
     DebuggerManager *m_manager; // Not owned.
     QList<BreakpointData *> m_bp;
diff --git a/src/plugins/debugger/breakpoint.h b/src/plugins/debugger/breakpoint.h
new file mode 100644
index 0000000000000000000000000000000000000000..5a9eef7a92322d8062e90e09252e848fe82e38c5
--- /dev/null
+++ b/src/plugins/debugger/breakpoint.h
@@ -0,0 +1,123 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** GNU Lesser General Public License Usage
+**
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://qt.nokia.com/contact.
+**
+**************************************************************************/
+
+#ifndef DEBUGGER_BREAKPOINT_H
+#define DEBUGGER_BREAKPOINT_H
+
+#include <QtCore/QString>
+
+namespace Debugger {
+class DebuggerManager;
+namespace Internal {
+
+class BreakpointMarker;
+class BreakHandler;
+
+//////////////////////////////////////////////////////////////////
+//
+// BreakpointData
+//
+//////////////////////////////////////////////////////////////////
+
+class BreakpointData
+{
+public:
+    BreakpointData();
+    ~BreakpointData();
+
+    void removeMarker();
+    void updateMarker();
+    QString toToolTip() const;
+    QString toString() const;
+    BreakHandler *handler() { return m_handler; }
+
+    bool isLocatedAt(const QString &fileName, int lineNumber) const;
+    bool conditionsMatch() const;
+
+private:
+    // Intentionally unimplemented.
+    // Making it copyable is tricky because of the markers.
+    void operator=(const BreakpointData &);
+    BreakpointData(const BreakpointData &);
+
+    // Our owner
+    BreakHandler *m_handler; // Not owned.
+    friend class BreakHandler;
+
+public:
+    enum Type { BreakpointType, WatchpointType };
+
+    bool enabled;            // Should we talk to the debugger engine?
+    bool pending;            // Does the debugger engine know about us already?
+    Type type;               // Type of breakpoint.
+
+    // This "user requested information" will get stored in the session.
+    QString fileName;        // Short name of source file.
+    QByteArray condition;    // Condition associated with breakpoint.
+    QByteArray ignoreCount;  // Ignore count associated with breakpoint.
+    QByteArray lineNumber;   // Line in source file.
+    QByteArray address;      // Address for watchpoints.
+    QByteArray threadSpec;   // Thread specification.
+    QString funcName;        // Name of containing function.
+    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.
+    QByteArray 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.
+    QByteArray bpLineNumber; // Line number acknowledged by the debugger engine.
+    QByteArray bpCorrectedLineNumber; // Acknowledged by the debugger engine.
+    QByteArray bpThreadSpec; // Thread spec acknowledged by the debugger engine.
+    QString bpFuncName;      // Function name acknowledged by the debugger engine.
+    QByteArray bpAddress;    // Address acknowledged by the debugger engine.
+    bool bpMultiple;         // Happens in constructors/gdb.
+    bool bpEnabled;          // Enable/disable command sent.
+
+    void setMarkerFileName(const QString &fileName);
+    QString markerFileName() const { return m_markerFileName; }
+
+    void setMarkerLineNumber(int lineNumber);
+    int markerLineNumber() const { return m_markerLineNumber; }
+
+private:
+    // Taken from either user input or gdb responses.
+    QString m_markerFileName; // Used to locate the marker.
+    int m_markerLineNumber;
+
+    // Our red blob in the editor.
+    BreakpointMarker *marker;
+};
+
+
+} // namespace Internal
+} // namespace Debugger
+
+#endif // DEBUGGER_BREAKPOINT_H
diff --git a/src/plugins/debugger/breakwindow.cpp b/src/plugins/debugger/breakwindow.cpp
index f26b23ac8be18dd710bffee8e751e91672436931..c92f33ac00a49929e91a127592d86523b3ec6d85 100644
--- a/src/plugins/debugger/breakwindow.cpp
+++ b/src/plugins/debugger/breakwindow.cpp
@@ -355,29 +355,30 @@ void BreakWindow::editBreakpoint(const QModelIndexList &list)
     ui.labelFileName->hide();
     ui.lineEditLineNumber->hide();
     ui.labelLineNumber->hide();
+    QAbstractItemModel *m = model();
     //ui.lineEditFunction->setText(
-    //    model()->data(idx.sibling(row, 1), role).toString());
+    //    m->data(idx.sibling(row, 1), role).toString());
     //ui.lineEditFileName->setText(
-    //    model()->data(idx.sibling(row, 2), role).toString());
+    //    m->data(idx.sibling(row, 2), role).toString());
     //ui.lineEditLineNumber->setText(
-    //    model()->data(idx.sibling(row, 3), role).toString());
+    //    m->data(idx.sibling(row, 3), role).toString());
     ui.lineEditCondition->setText(
-        model()->data(idx.sibling(row, 4), role).toString());
+        m->data(idx.sibling(row, 4), role).toString());
     ui.lineEditIgnoreCount->setText(
-        model()->data(idx.sibling(row, 5), role).toString());
+        m->data(idx.sibling(row, 5), role).toString());
     ui.lineEditThreadSpec->setText(
-        model()->data(idx.sibling(row, 6), role).toString());
+        m->data(idx.sibling(row, 6), role).toString());
 
     if (dlg.exec() == QDialog::Rejected)
         return;
 
     foreach (const QModelIndex &idx, list) {
-        //model()->setData(idx.sibling(idx.row(), 1), ui.lineEditFunction->text());
-        //model()->setData(idx.sibling(idx.row(), 2), ui.lineEditFileName->text());
-        //model()->setData(idx.sibling(idx.row(), 3), ui.lineEditLineNumber->text());
-        model()->setData(idx.sibling(idx.row(), 4), ui.lineEditCondition->text());
-        model()->setData(idx.sibling(idx.row(), 5), ui.lineEditIgnoreCount->text());
-        model()->setData(idx.sibling(idx.row(), 6), ui.lineEditThreadSpec->text());
+        //m->setData(idx.sibling(idx.row(), 1), ui.lineEditFunction->text());
+        //m->setData(idx.sibling(idx.row(), 2), ui.lineEditFileName->text());
+        //m->setData(idx.sibling(idx.row(), 3), ui.lineEditLineNumber->text());
+        m->setData(idx.sibling(idx.row(), 4), ui.lineEditCondition->text());
+        m->setData(idx.sibling(idx.row(), 5), ui.lineEditIgnoreCount->text());
+        m->setData(idx.sibling(idx.row(), 6), ui.lineEditThreadSpec->text());
     }
     emit breakpointSynchronizationRequested();
 }
diff --git a/src/plugins/debugger/debugger.pro b/src/plugins/debugger/debugger.pro
index 666019ae24e58f49dfbafab19ff599dbfe878a8c..93eec280b68c716bb809c613ff1e6c2a85254b77 100644
--- a/src/plugins/debugger/debugger.pro
+++ b/src/plugins/debugger/debugger.pro
@@ -16,6 +16,7 @@ QT += gui \
     script
 HEADERS += breakhandler.h \
     breakwindow.h \
+    breakpoint.h \
     debuggeragents.h \
     debuggeractions.h \
     debuggerconstants.h \
diff --git a/src/plugins/debugger/debugger.qrc b/src/plugins/debugger/debugger.qrc
index a542bdfce22d23c9e9783de8e7f4c576dbee18c1..7688ef39a42c1a81211367136b55d49d941e6c3e 100644
--- a/src/plugins/debugger/debugger.qrc
+++ b/src/plugins/debugger/debugger.qrc
@@ -18,6 +18,7 @@
         <file>images/debugger_stepoverproc_small.png</file>
         <file>images/debugger_stop.png</file>
         <file>images/debugger_stop_small.png</file>
+        <file>images/watchpoint.png</file>
         <file>images/breakpoint_16.png</file>
         <file>images/breakpoint_24.png</file>
         <file>images/breakpoint_disabled_16.png</file>
diff --git a/src/plugins/debugger/debuggerconstants.h b/src/plugins/debugger/debuggerconstants.h
index 1aada273ac6f81cd575e78df6d5f92a1aa22f9a0..020f94f9d09ea1a4a6e28551179c6832fc2ed497 100644
--- a/src/plugins/debugger/debuggerconstants.h
+++ b/src/plugins/debugger/debuggerconstants.h
@@ -132,7 +132,8 @@ enum DebuggerCapabilities
     BreakOnThrowAndCatchCapability = 0x200,
     ReturnFromFunctionCapability = 0x400,
     CreateFullBacktraceCapability = 0x800,
-    AddWatcherCapability = 0x1000
+    AddWatcherCapability = 0x1000,
+    WatchpointCapability = 0x2000
 };
 
 enum LogChannel
diff --git a/src/plugins/debugger/debuggermanager.cpp b/src/plugins/debugger/debuggermanager.cpp
index 100423734c8c1fe0b12bf20bc9bed72d2c88059a..a2c6b4e7f14773fa0b3c4ebe1e618cc40e144e13 100644
--- a/src/plugins/debugger/debuggermanager.cpp
+++ b/src/plugins/debugger/debuggermanager.cpp
@@ -897,9 +897,9 @@ BreakpointData *DebuggerManager::findBreakpoint(const QString &fileName, int lin
 // FIXME: move further up the plugin where there's more specific context
 // information available.
 static BreakpointData *createBreakpointByFileAndLine
-    (const QString &fileName, int lineNumber, BreakHandler *handler)
+    (const QString &fileName, int lineNumber)
 {
-    BreakpointData *data = new BreakpointData(handler);
+    BreakpointData *data = new BreakpointData;
     if (lineNumber > 0) {
         data->fileName = fileName;
         data->lineNumber = QByteArray::number(lineNumber);
@@ -934,7 +934,7 @@ void DebuggerManager::toggleBreakpoint(const QString &fileName, int lineNumber)
     int index = d->m_breakHandler->findBreakpoint(fileName, lineNumber);
     if (index == -1)
         d->m_breakHandler->appendBreakpoint(
-            createBreakpointByFileAndLine(fileName, lineNumber, d->m_breakHandler));
+            createBreakpointByFileAndLine(fileName, lineNumber));
     else
         d->m_breakHandler->removeBreakpoint(index);
 
@@ -1410,6 +1410,13 @@ void DebuggerManager::breakByFunction(const QString &functionName)
     attemptBreakpointSynchronization();
 }
 
+void DebuggerManager::appendBreakpoint(BreakpointData *data)
+{
+    QTC_ASSERT(d->m_breakHandler, return);
+    d->m_breakHandler->appendBreakpoint(data);
+    attemptBreakpointSynchronization();
+}
+
 void DebuggerManager::setBusyCursor(bool busy)
 {
     //STATE_DEBUG("BUSY FROM: " << d->m_busy << " TO: " << d->m_busy);
diff --git a/src/plugins/debugger/debuggermanager.h b/src/plugins/debugger/debuggermanager.h
index 19991c84ed99c123774d6bb7f95c0c1bdb33d29d..8b15b6487f4454c958c2341e09c897efece4ade9 100644
--- a/src/plugins/debugger/debuggermanager.h
+++ b/src/plugins/debugger/debuggermanager.h
@@ -289,6 +289,7 @@ public slots: // FIXME
     void reloadRegisters();
     void registerDockToggled(bool on);
     void clearStatusMessage();
+    void appendBreakpoint(Internal::BreakpointData *data);
     void attemptBreakpointSynchronization();
     void reloadFullStack();
     void operateByInstructionTriggered();
diff --git a/src/plugins/debugger/gdb/gdbengine.cpp b/src/plugins/debugger/gdb/gdbengine.cpp
index d42f5e93a4ac1e67af8e69356d5266d2424a95de..1f08b61605287cf8a609cc24d15cd6a156a49873 100644
--- a/src/plugins/debugger/gdb/gdbengine.cpp
+++ b/src/plugins/debugger/gdb/gdbengine.cpp
@@ -1394,7 +1394,19 @@ void GdbEngine::handleStop1(const GdbMi &data)
             reloadBreakListInternal();
     }
 
-    if (reason == "breakpoint-hit") {
+    if (reason == "watchpoint-trigger") {
+        // *stopped,reason="watchpoint-trigger",wpt={number="2",exp="*0xbfffed40"},
+        // value={old="1",new="0"},frame={addr="0x00451e1b",
+        // func="QScopedPointer",args=[{name="this",value="0xbfffed40"},
+        // {name="p",value="0x0"}],file="x.h",fullname="/home/.../x.h",line="95"},
+        // thread-id="1",stopped-threads="all",core="2" 
+        GdbMi wpt = data.findChild("wpt");
+        QByteArray bpNumber = wpt.findChild("number").data();
+        QByteArray bpAddress = wpt.findChild("exp").data();
+        //QByteArray threadId = data.findChild("thread-id").data();
+        showStatusMessage(tr("Watchpoint %1 at %2 triggered:")
+            .arg(_(bpNumber), _(bpAddress)));
+    } else if (reason == "breakpoint-hit") {
         QByteArray bpNumber = data.findChild("bkptno").data();
         QByteArray threadId = data.findChild("thread-id").data();
         showStatusMessage(tr("Stopped at breakpoint %1 in thread %2")
@@ -1825,6 +1837,7 @@ unsigned GdbEngine::debuggerCapabilities() const
         | ReloadModuleSymbolsCapability | BreakOnThrowAndCatchCapability
         | ReturnFromFunctionCapability 
         | CreateFullBacktraceCapability
+        | WatchpointCapability
         | AddWatcherCapability;
 }
 
@@ -2174,6 +2187,13 @@ void GdbEngine::sendInsertBreakpoint(int index)
     const BreakpointData *data = manager()->breakHandler()->at(index);
     // Set up fallback in case of pending breakpoints which aren't handled
     // by the MI interface.
+    if (data->type == BreakpointData::WatchpointType) {
+        postCommand("watch *" + data->address,
+            NeedsStop | RebuildBreakpointModel,
+            CB(handleWatchInsert), index);
+        return;
+    }
+
     QByteArray cmd;
     if (m_isMacGdb) {
         cmd = "-break-insert -l -1 -f ";
@@ -2197,6 +2217,23 @@ void GdbEngine::sendInsertBreakpoint(int index)
         CB(handleBreakInsert1), index);
 }
 
+void GdbEngine::handleWatchInsert(const GdbResponse &response)
+{
+    int index = 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 = manager()->breakHandler()->at(index);
+            data->bpNumber = ba.mid(20, pos - 20);
+            manager()->breakHandler()->updateMarkers();
+        } else {
+            debugMessage(_("CANNOT PARSE WATCHPOINT FROM" + ba));
+        }
+    }
+}
+
 void GdbEngine::handleBreakInsert1(const GdbResponse &response)
 {
     int index = response.cookie.toInt();
@@ -2275,7 +2312,7 @@ void GdbEngine::handleBreakList(const GdbMi &table)
 
     BreakHandler *handler = manager()->breakHandler();
     for (int index = 0; index != bkpts.size(); ++index) {
-        BreakpointData temp(handler);
+        BreakpointData temp;
         breakpointDataFromOutput(&temp, bkpts.at(index));
         int found = handler->findBreakpoint(temp);
         if (found != -1)
@@ -2444,7 +2481,7 @@ void GdbEngine::attemptBreakpointSynchronization()
 {
     QTC_ASSERT(!m_sourcesListUpdating,
         qDebug() << "SOURCES LIST CURRENTLY UPDATING"; return);
-    debugMessage(tr("ATTEMPT BREAKPOINT SYNC"));
+    debugMessage(_("ATTEMPT BREAKPOINT SYNC"));
 
     switch (state()) {
     case InferiorStarting:
@@ -2455,6 +2492,7 @@ void GdbEngine::attemptBreakpointSynchronization()
         break;
     default:
         //qDebug() << "attempted breakpoint sync in state" << state();
+        debugMessage(_("... NOT POSSIBLE IN CURRENT STATE"));
         return;
     }
 
diff --git a/src/plugins/debugger/gdb/gdbengine.h b/src/plugins/debugger/gdb/gdbengine.h
index 45b48fce6ad05e759cd8383fd619f86c8b31e7f4..553d2833c5f30962ded8594d9d16c45c4db61bfe 100644
--- a/src/plugins/debugger/gdb/gdbengine.h
+++ b/src/plugins/debugger/gdb/gdbengine.h
@@ -344,6 +344,7 @@ private: ////////// View & Data Stuff //////////
     void handleBreakInsert2(const GdbResponse &response);
     void handleBreakCondition(const GdbResponse &response);
     void handleBreakInfo(const GdbResponse &response);
+    void handleWatchInsert(const GdbResponse &response);
     void handleInfoLine(const GdbResponse &response);
     void extractDataFromInfoBreak(const QString &output, BreakpointData *data);
     void breakpointDataFromOutput(BreakpointData *data, const GdbMi &bkpt);
diff --git a/src/plugins/debugger/images/watchpoint.png b/src/plugins/debugger/images/watchpoint.png
new file mode 100644
index 0000000000000000000000000000000000000000..133378a8e7dd3a82296c0fd4b2093efce0e26972
Binary files /dev/null and b/src/plugins/debugger/images/watchpoint.png differ
diff --git a/src/plugins/debugger/watchwindow.cpp b/src/plugins/debugger/watchwindow.cpp
index af071542d1961508bcf7cc7605f1b91dc9cfbdd1..e2e4e21e3a0cfc3d6ee549b65527e1ebe50630ec 100644
--- a/src/plugins/debugger/watchwindow.cpp
+++ b/src/plugins/debugger/watchwindow.cpp
@@ -30,6 +30,7 @@
 #include "watchwindow.h"
 #include "watchhandler.h"
 
+#include "breakpoint.h"
 #include "debuggeractions.h"
 #include "debuggeragents.h"
 #include "debuggerdialogs.h"
@@ -284,7 +285,8 @@ void WatchWindow::contextMenuEvent(QContextMenuEvent *ev)
 
     const QString address = model()->data(mi0, AddressRole).toString();
     QAction *actWatchKnownMemory = 0;
-    QAction *actWatchUnknownMemory = new QAction(tr("Open Memory Editor..."), &menu);
+    QAction *actWatchUnknownMemory =
+        new QAction(tr("Open Memory Editor..."), &menu);
     const bool canShowMemory = engineCapabilities & ShowMemoryCapability;
     actWatchUnknownMemory->setEnabled(actionsEnabled && canShowMemory);
 
@@ -293,6 +295,17 @@ void WatchWindow::contextMenuEvent(QContextMenuEvent *ev)
             new QAction(tr("Open Memory Editor at %1").arg(address), &menu);
     menu.addSeparator();
 
+    QAction *actSetWatchpoint = 0;
+    const bool canSetWatchpoint = engineCapabilities & WatchpointCapability;
+    if (canSetWatchpoint && !address.isEmpty()) {
+        actSetWatchpoint =
+            new QAction(tr("Break on changing %1").arg(address), &menu);
+    } else {
+        actSetWatchpoint =
+            new QAction(tr("Break on changing contents"), &menu);
+        actSetWatchpoint->setEnabled(false);
+    }
+
     QAction *actWatchOrRemove;
     if (m_type == LocalsType) {
         actWatchOrRemove = theDebuggerAction(WatchExpression)->updatedAction(exp);
@@ -311,6 +324,7 @@ void WatchWindow::contextMenuEvent(QContextMenuEvent *ev)
     if (actWatchKnownMemory)
         menu.addAction(actWatchKnownMemory);
     menu.addAction(actWatchUnknownMemory);
+    menu.addAction(actSetWatchpoint);
     menu.addSeparator();
 
     menu.addAction(theDebuggerAction(RecheckDebuggingHelpers));
@@ -353,6 +367,11 @@ void WatchWindow::contextMenuEvent(QContextMenuEvent *ev)
         if (dialog.exec() == QDialog::Accepted) {
             (void) new MemoryViewAgent(m_manager, dialog.address());
         }
+    } else if (act == actSetWatchpoint) {
+        BreakpointData *data = new BreakpointData;
+        data->type = BreakpointData::WatchpointType;
+        data->address = address.toLatin1();
+        m_manager->appendBreakpoint(data);
     } else if (act == actSelectWidgetToWatch) {
         grabMouse(Qt::CrossCursor);
         m_grabbing = true;