diff --git a/share/qtcreator/gdbmacros/gdbmacros.cpp b/share/qtcreator/gdbmacros/gdbmacros.cpp
index 29b6feed765cbde9a846aeae741dd9bbf4135704..156bfc5e3f2ed03ad217c2ad2814f5987f689ca8 100644
--- a/share/qtcreator/gdbmacros/gdbmacros.cpp
+++ b/share/qtcreator/gdbmacros/gdbmacros.cpp
@@ -844,6 +844,26 @@ static void qDumpUnknown(QDumper &d, const char *why = 0)
     d.disarm();
 }
 
+static inline void dumpStdStringValue(QDumper &d, const std::string &str)
+{
+    d.beginItem("value");
+    d.putBase64Encoded(str.c_str(), str.size());
+    d.endItem();
+    d.putItem("valueencoded", "1");
+    d.putItem("type", "std::string");
+    d.putItem("numchild", "0");
+}
+
+static inline void dumpStdWStringValue(QDumper &d, const std::wstring &str)
+{
+    d.beginItem("value");
+    d.putBase64Encoded((const char *)str.c_str(), str.size() * sizeof(wchar_t));
+    d.endItem();
+    d.putItem("valueencoded", (sizeof(wchar_t) == 2 ? "2" : "3"));
+    d.putItem("type", "std::wstring");
+    d.putItem("numchild", "0");
+}
+
 static void qDumpInnerValueHelper(QDumper &d, const char *type, const void *addr,
     const char *field = "value")
 {
@@ -928,6 +948,16 @@ static void qDumpInnerValueHelper(QDumper &d, const char *type, const void *addr
                 d.putItem(field, *(QString*)addr);
             }
             return;
+        case 't':
+            if (isEqual(type, "std::string")
+                || isEqual(type, "std::basic_string<char,std::char_traits<char>,std::allocator<char> >")) {
+                d.putCommaIfNeeded();
+                dumpStdStringValue(d, *reinterpret_cast<const std::string*>(addr));
+            } else if (isEqual(type, "std::wstring")
+                       || isEqual(type, "std::basic_string<unsigned short,std::char_traits<unsigned short>,std::allocator<unsigned short> >")) {
+                dumpStdWStringValue(d, *reinterpret_cast<const std::wstring*>(addr));
+            }
+            return;
         default:
             return;
     }
@@ -944,7 +974,6 @@ static void qDumpInnerValue(QDumper &d, const char *type, const void *addr)
     qDumpInnerValueHelper(d, type, addr);
 }
 
-
 static void qDumpInnerValueOrPointer(QDumper &d,
     const char *type, const char *strippedtype, const void *addr)
 {
@@ -2753,37 +2782,28 @@ static void qDumpStdString(QDumper &d)
 {
     const std::string &str = *reinterpret_cast<const std::string *>(d.data);
 
-    if (!str.empty()) {
+    const std::string::size_type size = str.size();
+    if (int(size) < 0)
+        return;
+    if (size) {
         qCheckAccess(str.c_str());
-        qCheckAccess(str.c_str() + str.size() - 1);
+        qCheckAccess(str.c_str() + size - 1);
     }
-
-    d.beginItem("value");
-    d.putBase64Encoded(str.c_str(), str.size());
-    d.endItem();
-    d.putItem("valueencoded", "1");
-    d.putItem("type", "std::string");
-    d.putItem("numchild", "0");
-
+    dumpStdStringValue(d, str);
     d.disarm();
 }
 
 static void qDumpStdWString(QDumper &d)
 {
     const std::wstring &str = *reinterpret_cast<const std::wstring *>(d.data);
-
-    if (!str.empty()) {
+    const std::wstring::size_type size = str.size();
+    if (int(size) < 0)
+        return;
+    if (size) {
         qCheckAccess(str.c_str());
-        qCheckAccess(str.c_str() + str.size() - 1);
+        qCheckAccess(str.c_str() + size - 1);
     }
-
-    d.beginItem("value");
-    d.putBase64Encoded((const char *)str.c_str(), str.size() * sizeof(wchar_t));
-    d.endItem();
-    d.putItem("valueencoded", (sizeof(wchar_t) == 2 ? "2" : "3"));
-    d.putItem("type", "std::wstring");
-    d.putItem("numchild", "0");
-
+    dumpStdWStringValue(d, str);
     d.disarm();
 }
 
@@ -3164,6 +3184,8 @@ void *qDumpObjectData440(
          .put("std::string=\"").put(sizeof(std::string)).put("\",")
          .put("std::wstring=\"").put(sizeof(std::wstring)).put("\",")
          .put("std::allocator=\"").put(sizeof(std::allocator<int>)).put("\",")
+         .put("std::char_traits<char>=\"").put(sizeof(std::char_traits<char>)).put("\",")
+         .put("std::char_traits<unsigned short>=\"").put(sizeof(std::char_traits<unsigned short>)).put("\",")
 #if QT_VERSION >= 0x040500
          .put(NS"QSharedPointer=\"").put(sizeof(QSharedPointer<int>)).put("\",")
          .put(NS"QSharedDataPointer=\"").put(sizeof(QSharedDataPointer<QSharedData>)).put("\",")
diff --git a/share/qtcreator/gdbmacros/test/main.cpp b/share/qtcreator/gdbmacros/test/main.cpp
index fe6c2c6723eebd142c3b812f49bcccaac5cbd72e..eca00156df3ecf9f10b1e1e5c170d9a32389cef6 100644
--- a/share/qtcreator/gdbmacros/test/main.cpp
+++ b/share/qtcreator/gdbmacros/test/main.cpp
@@ -256,6 +256,18 @@ static int dumpStdStringVector()
     return 0;
 }
 
+static int dumpStdWStringVector()
+{
+    std::vector<std::wstring> test;
+    test.push_back(L"item1");
+    test.push_back(L"item2");
+    prepareInBuffer("std::vector", "local.wstringvector", "local.wstringvector", "std::wstring");
+    qDumpObjectData440(2, 42, testAddress(&test), 1, sizeof(std::wstring), sizeof(std::list<int>::allocator_type), 0, 0);
+    fputs(qDumpOutBuffer, stdout);
+    fputc('\n', stdout);
+    return 0;
+}
+
 static int dumpStdIntSet()
 {
     std::set<int> test;
@@ -335,6 +347,8 @@ static bool dumpType(const char *arg)
         { dumpStdIntVector(); return true; }
     if (!qstrcmp(arg, "vector<string>"))
         { dumpStdStringVector(); return true; }
+    if (!qstrcmp(arg, "vector<wstring>"))
+        { dumpStdWStringVector(); return true; }
     if (!qstrcmp(arg, "set<int>"))
         { dumpStdIntSet(); return true; }
     if (!qstrcmp(arg, "set<string>"))
diff --git a/src/libs/cplusplus/pp-engine.cpp b/src/libs/cplusplus/pp-engine.cpp
index 372926f59755cb51d82c8bca939498362830d22a..c7688c986bd5c7ec144c39fb41909933de42c171 100644
--- a/src/libs/cplusplus/pp-engine.cpp
+++ b/src/libs/cplusplus/pp-engine.cpp
@@ -1421,6 +1421,8 @@ bool Preprocessor::isQtReservedWord(const QByteArray &macroId) const
     const int size = macroId.size();
     if      (size == 9 && macroId.at(0) == 'Q' && macroId == "Q_SIGNALS")
         return true;
+    else if (size == 9 && macroId.at(0) == 'Q' && macroId == "Q_FOREACH")
+        return true;
     else if (size == 7 && macroId.at(0) == 'Q' && macroId == "Q_SLOTS")
         return true;
     else if (size == 8 && macroId.at(0) == 'Q' && macroId == "Q_SIGNAL")
@@ -1433,6 +1435,8 @@ bool Preprocessor::isQtReservedWord(const QByteArray &macroId) const
         return true;
     else if (size == 7 && macroId.at(0) == 's' && macroId == "signals")
         return true;
+    else if (size == 7 && macroId.at(0) == 'f' && macroId == "foreach")
+        return true;
     else if (size == 5 && macroId.at(0) == 's' && macroId == "slots")
         return true;
     return false;
diff --git a/src/plugins/cmakeprojectmanager/cmakeopenprojectwizard.cpp b/src/plugins/cmakeprojectmanager/cmakeopenprojectwizard.cpp
index ae955202252bce0d360d1afc41cdd627e1bf4086..9d07264c7455a255f41fd3f9d1f09f918c17e527 100644
--- a/src/plugins/cmakeprojectmanager/cmakeopenprojectwizard.cpp
+++ b/src/plugins/cmakeprojectmanager/cmakeopenprojectwizard.cpp
@@ -82,7 +82,6 @@ CMakeOpenProjectWizard::CMakeOpenProjectWizard(CMakeManager *cmakeManager, const
 
     setPage(InSourcePageId, new InSourceBuildPage(this));
     setPage(ShadowBuildPageId, new ShadowBuildPage(this));
-    setPage(XmlFileUpToDatePageId, new XmlFileUpToDatePage(this));
     setPage(CMakeRunPageId, new CMakeRunPage(this));
 
     setStartId(startid);
@@ -137,15 +136,9 @@ int CMakeOpenProjectWizard::nextId() const
         return QWizard::nextId();
     int cid = currentId();
     if (cid == InSourcePageId) {
-        if (existsUpToDateXmlFile())
-            return XmlFileUpToDatePageId;
-        else
-            return CMakeRunPageId;
+        return CMakeRunPageId;
     } else if (cid == ShadowBuildPageId) {
-        if (existsUpToDateXmlFile())
-            return XmlFileUpToDatePageId;
-        else
-            return CMakeRunPageId;
+        return CMakeRunPageId;
     }
     return -1;
 }
@@ -227,18 +220,6 @@ InSourceBuildPage::InSourceBuildPage(CMakeOpenProjectWizard *cmakeWizard)
 }
 
 
-XmlFileUpToDatePage::XmlFileUpToDatePage(CMakeOpenProjectWizard *cmakeWizard)
-    : QWizardPage(cmakeWizard), m_cmakeWizard(cmakeWizard)
-{
-    setLayout(new QVBoxLayout);
-    QLabel *label = new QLabel(this);
-    label->setWordWrap(true);
-    label->setText(tr("Qt Creator has found a recent cbp file, which Qt Creator will parse to gather information about the project. "
-                   "You can change the command line arguments used to create this file in the project mode. "
-                   "Click finish to load the project."));
-    layout()->addWidget(label);
-}
-
 ShadowBuildPage::ShadowBuildPage(CMakeOpenProjectWizard *cmakeWizard, bool change)
     : QWizardPage(cmakeWizard), m_cmakeWizard(cmakeWizard)
 {
@@ -313,10 +294,19 @@ void CMakeRunPage::initWidgets()
 void CMakeRunPage::initializePage()
 {
     if (m_mode == Initial) {
+        m_complete = m_cmakeWizard->existsUpToDateXmlFile();
         m_buildDirectory = m_cmakeWizard->buildDirectory();
-        m_descriptionLabel->setText(
-                tr("The directory %1 does not contain a cbp file. Qt Creator needs to create this file by running cmake. "
-                   "Some projects require command line arguments to the initial cmake call.").arg(m_buildDirectory));
+
+        if (m_cmakeWizard->existsUpToDateXmlFile()) {
+            m_descriptionLabel->setText(
+                    tr("The directoyr %1 already contains a cbp file, which is recent enough. "
+                       "You can pass special arguments or change the used toolchain here and rerun cmake. "
+                       "Or simply finish the wizard directly").arg(m_buildDirectory));
+        } else {
+            m_descriptionLabel->setText(
+                    tr("The directory %1 does not contain a cbp file. Qt Creator needs to create this file by running cmake. "
+                       "Some projects require command line arguments to the initial cmake call.").arg(m_buildDirectory));
+        }
     } else if (m_mode == CMakeRunPage::Update) {
         m_descriptionLabel->setText(tr("The directory %1 contains an outdated .cbp file. Qt "
                                        "Creator needs to update this file by running cmake. "
diff --git a/src/plugins/cmakeprojectmanager/cmakeopenprojectwizard.h b/src/plugins/cmakeprojectmanager/cmakeopenprojectwizard.h
index 908ea70d7be812c8a20310499dd45a00a84ba46c..e60dcc153d0a5796443db55563dbb8a3d9b26132 100644
--- a/src/plugins/cmakeprojectmanager/cmakeopenprojectwizard.h
+++ b/src/plugins/cmakeprojectmanager/cmakeopenprojectwizard.h
@@ -58,7 +58,6 @@ public:
     enum PageId {
         InSourcePageId,
         ShadowBuildPageId,
-        XmlFileUpToDatePageId,
         CMakeRunPageId
     };
 
@@ -85,9 +84,9 @@ public:
     ProjectExplorer::Environment environment() const;
     QString msvcVersion() const;
     void setMsvcVersion(const QString &version);
+    bool existsUpToDateXmlFile() const;
 private:
     void init();
-    bool existsUpToDateXmlFile() const;
     bool hasInSourceBuild() const;
     CMakeManager *m_cmakeManager;
     QString m_buildDirectory;
@@ -107,17 +106,6 @@ private:
     CMakeOpenProjectWizard *m_cmakeWizard;
 };
 
-
-class XmlFileUpToDatePage : public QWizardPage
-{
-    Q_OBJECT
-public:
-    XmlFileUpToDatePage(CMakeOpenProjectWizard *cmakeWizard);
-private:
-    CMakeOpenProjectWizard *m_cmakeWizard;
-};
-
-
 class ShadowBuildPage : public QWizardPage
 {
     Q_OBJECT
diff --git a/src/plugins/debugger/cdb/cdbdumperhelper.cpp b/src/plugins/debugger/cdb/cdbdumperhelper.cpp
index 0209a08e2b479df8a9df9f5ee66befe7f5a787e4..bedf02dd41e0368f1e40c032471c391097883c8c 100644
--- a/src/plugins/debugger/cdb/cdbdumperhelper.cpp
+++ b/src/plugins/debugger/cdb/cdbdumperhelper.cpp
@@ -544,12 +544,23 @@ static inline QString msgDumpFailed(const WatchData &wd, const QString *why)
     return QString::fromLatin1("Unable to dump '%1' (%2): %3").arg(wd.name, wd.type, *why);
 }
 
+static inline QString msgNotHandled(const QString &type)
+{
+    return QString::fromLatin1("The type '%1' is not handled.").arg(type);
+}
+
 CdbDumperHelper::DumpResult CdbDumperHelper::dumpType(const WatchData &wd, bool dumpChildren, int source,
                                                       QList<WatchData> *result, QString *errorMessage)
 {
     // Check failure cache and supported types
-    if (m_state == Disabled || m_failedTypes.contains(wd.type))
+    if (m_state == Disabled) {
+        *errorMessage = QLatin1String("Dumpers are disabled");
         return DumpNotHandled;
+    }
+    if (m_failedTypes.contains(wd.type)) {
+        *errorMessage = msgNotHandled(wd.type);
+        return DumpNotHandled;
+    }
 
     // Ensure types are parsed and known.
     if (!ensureInitialized(errorMessage)) {
@@ -562,8 +573,10 @@ CdbDumperHelper::DumpResult CdbDumperHelper::dumpType(const WatchData &wd, bool
     const QtDumperHelper::TypeData td = m_helper.typeData(wd.type);    
     if (loadDebug)
         qDebug() << "dumpType" << wd.type << td;
-    if (td.type == QtDumperHelper::UnknownType)
+    if (td.type == QtDumperHelper::UnknownType) {
+        *errorMessage = msgNotHandled(wd.type);
         return DumpNotHandled;
+    }
 
     // Now evaluate
     const QString message = QCoreApplication::translate("Debugger::Internal::CdbDumperHelper",
diff --git a/src/plugins/debugger/cdb/cdbstackframecontext.cpp b/src/plugins/debugger/cdb/cdbstackframecontext.cpp
index 9cd7589636e031473725e619439aae54ae12eddb..870ba8f262f2fc4b42ba897e568f7fbc2ecb4cb0 100644
--- a/src/plugins/debugger/cdb/cdbstackframecontext.cpp
+++ b/src/plugins/debugger/cdb/cdbstackframecontext.cpp
@@ -257,7 +257,7 @@ bool CdbStackFrameContext::completeData(const WatchData &incompleteLocal,
             foreach(const WatchData &dwd, dumperResult)
                 wh->insertData(dwd);
         } else {
-            const QString msg = QString::fromLatin1("Unable to further expand dumper watch data: %1 (%2): %3/%4").arg(incompleteLocal.name, incompleteLocal.type).arg(int(dr)).arg(*errorMessage);
+            const QString msg = QString::fromLatin1("Unable to further expand dumper watch data: '%1' (%2): %3/%4").arg(incompleteLocal.name, incompleteLocal.type).arg(int(dr)).arg(*errorMessage);
             qWarning("%s", qPrintable(msg));
             WatchData wd = incompleteLocal;
             wd.setAllUnneeded();
diff --git a/src/plugins/debugger/debuggertooltip.cpp b/src/plugins/debugger/debuggertooltip.cpp
index 18fa2f7d6f1695d6e903052b34e3bd5fa7bb9a4d..622a8948e872f436d318902503bbfcd1bff757ec 100644
--- a/src/plugins/debugger/debuggertooltip.cpp
+++ b/src/plugins/debugger/debuggertooltip.cpp
@@ -144,7 +144,7 @@ void ToolTipWidget::done()
 }
 
 void ToolTipWidget::run(const QPoint &point, QAbstractItemModel *model,
-    const QModelIndex &index, const QString &msg)
+    const QModelIndex &index, const QString & /* msg */)
 {
     move(point);
     setModel(model);
diff --git a/src/plugins/debugger/watchhandler.cpp b/src/plugins/debugger/watchhandler.cpp
index abe3b3cb8c01c878c3e86ab0fa40f0968ce586f1..30eb77478b0ea7cec227020968d26fe9d698d2ed 100644
--- a/src/plugins/debugger/watchhandler.cpp
+++ b/src/plugins/debugger/watchhandler.cpp
@@ -390,9 +390,29 @@ static QString chopConst(QString type)
     return type;
 }
 
-QString niceType(QString type)
+static inline QRegExp stdStringRegExp(const QString &charType)
 {
-    type.replace('*', '@');
+    QString rc = QLatin1String("basic_string<");
+    rc += charType;
+    rc += QLatin1String(",[ ]?std::char_traits<");
+    rc += charType;
+    rc += QLatin1String(">,[ ]?std::allocator<");
+    rc += charType;
+    rc += QLatin1String("> >");
+    const QRegExp re(rc);
+    Q_ASSERT(re.isValid());
+    return re;
+}
+
+QString niceType(const QString typeIn)
+{
+    static QMap<QString, QString> cache;
+    const QMap<QString, QString>::const_iterator it = cache.constFind(typeIn);
+    if (it != cache.constEnd()) {
+        return it.value();
+    }
+    QString type = typeIn;
+    type.replace(QLatin1Char('*'), QLatin1Char('@'));
 
     for (int i = 0; i < 10; ++i) {
         int start = type.indexOf("std::allocator<");
@@ -414,33 +434,37 @@ QString niceType(QString type)
         QString alloc = type.mid(start, pos + 1 - start).trimmed();
         QString inner = alloc.mid(15, alloc.size() - 16).trimmed();
 
-        if (inner == QLatin1String("char"))
-            // std::string
-            type.replace(QLatin1String("basic_string<char, std::char_traits<char>, "
-                "std::allocator<char> >"), QLatin1String("string"));
-        else if (inner == QLatin1String("wchar_t"))
-            // std::wstring
-            type.replace(QLatin1String("basic_string<wchar_t, std::char_traits<wchar_t>, "
-                "std::allocator<wchar_t> >"), QLatin1String("wstring"));
-
+        if (inner == QLatin1String("char")) { // std::string
+            static const QRegExp stringRegexp = stdStringRegExp(inner);
+            type.replace(stringRegexp, QLatin1String("string"));
+        } else if (inner == QLatin1String("wchar_t")) { // std::wstring
+            static const QRegExp wchartStringRegexp = stdStringRegExp(inner);
+            type.replace(wchartStringRegexp, QLatin1String("wstring"));
+        } else if (inner == QLatin1String("unsigned short")) { // std::wstring/MSVC
+            static const QRegExp usStringRegexp = stdStringRegExp(inner);
+            type.replace(usStringRegexp, QLatin1String("wstring"));
+        }
         // std::vector, std::deque, std::list
-        QRegExp re1(QString("(vector|list|deque)<%1, %2\\s*>").arg(inner, alloc));
+        static const QRegExp re1(QString::fromLatin1("(vector|list|deque)<%1,[ ]?%2\\s*>").arg(inner, alloc));
+        Q_ASSERT(re1.isValid());
         if (re1.indexIn(type) != -1)
-            type.replace(re1.cap(0), QString("%1<%2>").arg(re1.cap(1), inner));
-
+            type.replace(re1.cap(0), QString::fromLatin1("%1<%2>").arg(re1.cap(1), inner));
 
         // std::stack
-        QRegExp re6(QString("stack<%1, std::deque<%2> >").arg(inner, inner));
-        re6.setMinimal(true);
+        static QRegExp re6(QString::fromLatin1("stack<%1,[ ]?std::deque<%2> >").arg(inner, inner));
+        if (!re6.isMinimal())
+            re6.setMinimal(true);
+        Q_ASSERT(re6.isValid());
         if (re6.indexIn(type) != -1)
-            type.replace(re6.cap(0), QString("stack<%1>").arg(inner));
+            type.replace(re6.cap(0), QString::fromLatin1("stack<%1>").arg(inner));
 
         // std::set
-        QRegExp re4(QString("set<%1, std::less<%2>, %3\\s*>").arg(inner, inner, alloc));
-        re4.setMinimal(true);
+        static QRegExp re4(QString::fromLatin1("set<%1,[ ]?std::less<%2>,[ ]?%3\\s*>").arg(inner, inner, alloc));
+        if (!re4.isMinimal())
+            re4.setMinimal(true);
+        Q_ASSERT(re4.isValid());
         if (re4.indexIn(type) != -1)
-            type.replace(re4.cap(0), QString("set<%1>").arg(inner));
-
+            type.replace(re4.cap(0), QString::fromLatin1("set<%1>").arg(inner));
 
         // std::map
         if (inner.startsWith("std::pair<")) {
@@ -460,25 +484,46 @@ QString niceType(QString type)
             QString key = chopConst(ckey);
             QString value = inner.mid(pos + 2, inner.size() - 3 - pos);
 
-            QRegExp re5(QString("map<%1, %2, std::less<%3>, %4\\s*>")
+            static QRegExp re5(QString("map<%1,[ ]?%2,[ ]?std::less<%3>,[ ]?%4\\s*>")
                 .arg(key, value, key, alloc));
-            re5.setMinimal(true);
+            if (!re5.isMinimal())
+                re5.setMinimal(true);
+            Q_ASSERT(re5.isValid());
             if (re5.indexIn(type) != -1)
                 type.replace(re5.cap(0), QString("map<%1, %2>").arg(key, value));
             else {
-                QRegExp re7(QString("map<const %1, %2, std::less<const %3>, %4\\s*>")
+                static QRegExp re7(QString("map<const %1,[ ]?%2,[ ]?std::less<const %3>,[ ]?%4\\s*>")
                     .arg(key, value, key, alloc));
-                re7.setMinimal(true);
+                if (!re7.isMinimal())
+                    re7.setMinimal(true);
                 if (re7.indexIn(type) != -1)
                     type.replace(re7.cap(0), QString("map<const %1, %2>").arg(key, value));
             }
         }
     }
-    type.replace('@', '*');
+    type.replace(QLatin1Char('@'), QLatin1Char('*'));
     type.replace(QLatin1String(" >"), QString(QLatin1Char('>')));
+    cache.insert(typeIn, type); // For simplicity, also cache unmodified types
     return type;
 }
 
+static QString formattedValue(const WatchData &data,
+    int individualFormat, int typeFormat)
+{
+    if (isIntType(data.type)) {
+        int format = individualFormat == -1 ? typeFormat : individualFormat;
+        int value = data.value.toInt();
+        if (format == 1)
+            return ("(hex) ") + QString::number(value, 16);
+        if (format == 2)
+            return ("(bin) ") + QString::number(value, 2);
+        if (format == 3)
+            return ("(oct) ") + QString::number(value, 8);
+    }
+
+    return data.value;
+}
+
 bool WatchModel::canFetchMore(const QModelIndex &index) const
 {
     return index.isValid() && !watchItem(index)->fetchTriggered;
@@ -573,6 +618,18 @@ QModelIndex WatchModel::watchIndexHelper(const WatchItem *needle,
     return QModelIndex();
 }
 
+void WatchModel::emitDataChanged(int column, const QModelIndex &parentIndex) 
+{
+    QModelIndex idx1 = index(0, column, parentIndex);
+    QModelIndex idx2 = index(rowCount(parentIndex) - 1, column, parentIndex);
+    if (idx1.isValid() && idx2.isValid())
+        emit dataChanged(idx1, idx2);
+    //qDebug() << "CHANGING:\n" << idx1 << "\n" << idx2 << "\n"
+    //    << data(parentIndex, INameRole).toString();
+    for (int i = rowCount(parentIndex); --i >= 0; )
+        emitDataChanged(column, index(i, 0, parentIndex));
+}
+
 QVariant WatchModel::data(const QModelIndex &idx, int role) const
 {
     const WatchItem &data = *watchItem(idx);
@@ -581,7 +638,9 @@ QVariant WatchModel::data(const QModelIndex &idx, int role) const
         case Qt::DisplayRole: {
             switch (idx.column()) {
                 case 0: return data.name;
-                case 1: return data.value;
+                case 1: return formattedValue(data,
+                    m_handler->m_individualFormats[data.iname],
+                    m_handler->m_typeFormats[data.type]);
                 case 2: return niceType(data.type);
                 default: break;
             }
@@ -616,7 +675,23 @@ QVariant WatchModel::data(const QModelIndex &idx, int role) const
         case ActiveDataRole:
             qDebug() << "ASK FOR" << data.iname;
             return true;
-    
+   
+        case TypeFormatListRole:
+            if (isIntType(data.type))
+                return QStringList() << tr("decimal") << tr("hexadecimal")
+                    << tr("binary") << tr("octal");
+            break;
+
+        case TypeFormatRole:
+            return m_handler->m_typeFormats[data.type];
+
+        case IndividualFormatRole: {
+            int format = m_handler->m_individualFormats[data.iname];
+            if (format == -1)
+                return m_handler->m_typeFormats[data.type];
+            return format;
+        }
+
         default:
             break; 
     }
@@ -625,12 +700,16 @@ QVariant WatchModel::data(const QModelIndex &idx, int role) const
 
 bool WatchModel::setData(const QModelIndex &index, const QVariant &value, int role)
 {
+    WatchItem &data = *watchItem(index);
     if (role == ExpandedRole) {
-        QString iname = data(index, INameRole).toString();
         if (value.toBool())
-            m_handler->m_expandedINames.insert(iname);
+            m_handler->m_expandedINames.insert(data.iname);
         else
-            m_handler->m_expandedINames.remove(iname);
+            m_handler->m_expandedINames.remove(data.iname);
+    } else if (role == TypeFormatRole) {
+        m_handler->setFormat(data.type, value.toInt());
+    } else if (role == IndividualFormatRole) {
+        m_handler->m_individualFormats[data.iname] = value.toInt();
     }
     emit dataChanged(index, index);
     return true;
@@ -773,66 +852,6 @@ void WatchHandler::endCycle()
     m_locals->removeOutdated();
     m_watchers->removeOutdated();
     m_tooltips->removeOutdated();
-
-/*
-    if (m_inChange) {
-        MODEL_DEBUG("RECREATE MODEL IGNORED, CURRENT SET:\n" << toString());
-        return;
-    }
-
-    #ifdef DEBUG_PENDING
-    MODEL_DEBUG("RECREATE MODEL, CURRENT SET:\n" << toString());
-    #endif
-
-    QHash<QString, int> oldTopINames;
-    QHash<QString, QString> oldValues;
-    for (int i = 0, n = m_oldSet.size(); i != n; ++i) {
-        WatchData &data = m_oldSet[i];
-        oldValues[data.iname] = data.value;
-        if (data.level == 2)
-            ++oldTopINames[data.iname];
-    }
-    #ifdef DEBUG_PENDING
-    MODEL_DEBUG("OLD VALUES: " << oldValues);
-    #endif
-
-    for (int i = m_completeSet.size(); --i >= 0; ) {
-        WatchData &data = m_completeSet[i];
-        data.level = data.iname.isEmpty() ? 0 : data.iname.count('.') + 1;
-        data.childIndex.clear();
-    }
-
-    qSort(m_completeSet.begin(), m_completeSet.end(), &iNameSorter);
-
-    // Possibly append dummy items to prevent empty views
-    bool ok = true;
-
-    if (ok) {
-        for (int i = 1; i <= 3; ++i) {
-            WatchData &data = m_displaySet[i];
-            if (data.childIndex.size() == 0) {
-                WatchData dummy;
-                dummy.state = 0;
-                dummy.row = 0;
-                if (i == 1) {
-                    dummy.iname = QLatin1String("local.dummy");
-                    dummy.name  = tr("<No Locals>");
-                } else if (i == 2) {
-                    dummy.iname = QLatin1String("tooltip.dummy");
-                    dummy.name  = tr("<No Tooltip>");
-                } else {
-                    dummy.iname = QLatin1String("watch.dummy");
-                    dummy.name  = tr("<No Watchers>");
-                }
-                dummy.level = 2;
-                dummy.parentIndex = i;
-                dummy.childCount = 0;
-                data.childIndex.append(m_displaySet.size());
-                m_displaySet.append(dummy); 
-            }
-        }
-    }
-*/
 }
 
 void WatchHandler::cleanup()
@@ -1020,17 +1039,19 @@ void WatchHandler::loadWatchers()
     sessionValueRequested("Watchers", &value);
     foreach (const QString &exp, value.toStringList())
         m_watcherNames[exp] = watcherCounter++;
+
     //qDebug() << "LOAD WATCHERS: " << m_watchers;
     //reinitializeWatchersHelper();
 }
 
 void WatchHandler::saveWatchers()
 {
-    //qDebug() << "SAVE WATCHERS: " << m_watchers.keys();
+    //qDebug() << "SAVE WATCHERS: " << m_watchers;
     // Filter out valid watchers.
     QStringList watcherNames;
-    const QHash<QString, int>::const_iterator cend = m_watcherNames.constEnd();
-    for (QHash<QString, int>::const_iterator it = m_watcherNames.constBegin(); it != cend; ++it) {
+    QHashIterator<QString, int> it(m_watcherNames);
+    while (it.hasNext()) {
+        it.next();
         const QString &watcherName = it.key();
         if (!watcherName.isEmpty() && watcherName != watcherEditPlaceHolder())
             watcherNames.push_back(watcherName);
@@ -1038,14 +1059,42 @@ void WatchHandler::saveWatchers()
     setSessionValueRequested("Watchers", QVariant(watcherNames));
 }
 
+void WatchHandler::loadTypeFormats()
+{
+    QVariant value;
+    sessionValueRequested("DefaultFormats", &value);
+    QMap<QString, QVariant> typeFormats = value.toMap();
+    QMapIterator<QString, QVariant> it(typeFormats);
+    while (it.hasNext()) {
+        it.next();
+        if (!it.key().isEmpty())
+            m_typeFormats.insert(it.key(), it.value().toInt());
+    }
+}
+
+void WatchHandler::saveTypeFormats()
+{
+    QMap<QString, QVariant> typeFormats;
+    QHashIterator<QString, int> it(m_typeFormats);
+    while (it.hasNext()) {
+        it.next();
+        QString key = it.key().trimmed();
+        if (!key.isEmpty())
+            typeFormats.insert(key, it.value());
+    }
+    setSessionValueRequested("DefaultFormats", QVariant(typeFormats));
+}
+
 void WatchHandler::saveSessionData()
 {
     saveWatchers();
+    saveTypeFormats();
 }
 
 void WatchHandler::loadSessionData()
 {
     loadWatchers();
+    loadTypeFormats();
     foreach (const QString &exp, m_watcherNames.keys()) {
         WatchData data;
         data.iname = watcherName(exp);
@@ -1092,5 +1141,14 @@ QString WatchHandler::watcherEditPlaceHolder()
     return rc;
 }
 
+void WatchHandler::setFormat(const QString &type, int format)
+{
+    m_typeFormats[type] = format;
+    saveTypeFormats();
+    m_locals->emitDataChanged(1);
+    m_watchers->emitDataChanged(1);
+    m_tooltips->emitDataChanged(1);
+}
+
 } // namespace Internal
 } // namespace Debugger
diff --git a/src/plugins/debugger/watchhandler.h b/src/plugins/debugger/watchhandler.h
index 2ee1cb10746aed776bbc12e1377c2996d911bdb2..b9be24b4ba3fd85f55ca45fcda1000d6555bcbd0 100644
--- a/src/plugins/debugger/watchhandler.h
+++ b/src/plugins/debugger/watchhandler.h
@@ -139,8 +139,11 @@ enum WatchRoles
 {
     INameRole = Qt::UserRole,
     ExpressionRole,
-    ExpandedRole,
+    ExpandedRole,    // used to communicate prefered expanded state to the view
     ActiveDataRole,  // used for tooltip
+    TypeFormatListRole,
+    TypeFormatRole,  // used to communicate alternative formats to the view
+    IndividualFormatRole
 };
 
 class WatchModel : public QAbstractItemModel
@@ -180,6 +183,9 @@ private:
     void removeItem(WatchItem *item);
     void setActiveData(const QString &data) { m_activeData = data; }
 
+    void emitDataChanged(int column,
+        const QModelIndex &parentIndex = QModelIndex());
+
 private:
     WatchHandler *m_handler;
     WatchType m_type;
@@ -234,6 +240,10 @@ private:
     void loadWatchers();
     void saveWatchers();
 
+    void loadTypeFormats();
+    void saveTypeFormats();
+    void setFormat(const QString &type, int format);
+
     bool m_expandPointers;
     bool m_inChange;
 
@@ -242,6 +252,8 @@ private:
 
     QHash<QString, int> m_watcherNames;
     QString watcherName(const QString &exp);
+    QHash<QString, int> m_typeFormats;
+    QHash<QString, int> m_individualFormats;
 
     void setDisplayedIName(const QString &iname, bool on);
     QSet<QString> m_expandedINames;  // those expanded in the treeview
diff --git a/src/plugins/debugger/watchutils.cpp b/src/plugins/debugger/watchutils.cpp
index 6933b68ff8e6df33fbf6d4bec997773542bbe3ab..5ef9523ed4535fba43d55b7af9f1db97270542f6 100644
--- a/src/plugins/debugger/watchutils.cpp
+++ b/src/plugins/debugger/watchutils.cpp
@@ -266,30 +266,43 @@ bool extractTemplate(const QString &type, QString *tmplate, QString *inner)
     // Input "Template<Inner1,Inner2,...>::Foo" will return "Template::Foo" in
     // 'tmplate' and "Inner1@Inner2@..." etc in 'inner'. Result indicates
     // whether parsing was successful
+    // Gdb inserts a blank after each comma which we would like to avoid
+    tmplate->clear();
+    inner->clear();
+    if (!type.contains(QLatin1Char('<')))
+        return  false;
     int level = 0;
     bool skipSpace = false;
+    const int size = type.size();
 
-    for (int i = 0; i != type.size(); ++i) {
+    for (int i = 0; i != size; ++i) {
         const QChar c = type.at(i);
-        if (c == QLatin1Char(' ') && skipSpace) {
-            skipSpace = false;
-        } else if (c == QLatin1Char('<')) {
+        const char asciiChar = c.toAscii();
+        switch (asciiChar) {
+        case '<':
             *(level == 0 ? tmplate : inner) += c;
             ++level;
-        } else if (c == QLatin1Char('>')) {
+            break;
+        case '>':
             --level;
             *(level == 0 ? tmplate : inner) += c;
-        } else if (c == QLatin1Char(',')) {
+            break;
+        case ',':
             *inner += (level == 1) ? QLatin1Char('@') : QLatin1Char(',');
             skipSpace = true;
-        } else {
-            *(level == 0 ? tmplate : inner) += c;
+            break;
+        default:
+            if (!skipSpace || asciiChar != ' ') {
+                *(level == 0 ? tmplate : inner) += c;
+                skipSpace = false;
+            }
+            break;
         }
     }
     *tmplate = tmplate->trimmed();
     *tmplate = tmplate->remove(QLatin1String("<>"));
     *inner = inner->trimmed();
-    //qDebug() << "EXTRACT TEMPLATE: " << *tmplate << *inner << " FROM " << type;
+    // qDebug() << "EXTRACT TEMPLATE: " << *tmplate << *inner << " FROM " << type;
     return !inner->isEmpty();
 }
 
@@ -305,18 +318,25 @@ QString extractTypeFromPTypeOutput(const QString &str)
     return res.simplified();
 }
 
-bool isIntOrFloatType(const QString &type)
+bool isIntType(const QString &type)
 {
     static const QStringList types = QStringList()
         << QLatin1String("char") << QLatin1String("int") << QLatin1String("short")
-        << QLatin1String("float") << QLatin1String("double") << QLatin1String("long")
-        << QLatin1String("bool") << QLatin1String("signed char") << QLatin1String("unsigned")
+        << QLatin1String("long") << QLatin1String("bool")
+        << QLatin1String("signed char") << QLatin1String("unsigned")
         << QLatin1String("unsigned char")
         << QLatin1String("unsigned int") << QLatin1String("unsigned long")
         << QLatin1String("long long")  << QLatin1String("unsigned long long");
     return types.contains(type);
 }
 
+bool isIntOrFloatType(const QString &type)
+{
+    static const QStringList types = QStringList()
+        << QLatin1String("float") << QLatin1String("double");
+    return isIntType(type) || types.contains(type);
+}
+
 QString sizeofTypeExpression(const QString &type)
 {
     if (type.endsWith(QLatin1Char('*')))
@@ -401,7 +421,7 @@ bool isCppEditor(Core::IEditor *editor)
 // Find the function the cursor is in to use a scope.
 
 
-    
+
 
 
 // Return the Cpp expression, and, if desired, the function
@@ -435,7 +455,7 @@ QString cppExpressionAt(TextEditor::ITextEditor *editor, int pos,
         const QTextCursor tc = plaintext->textCursor();
         *column = tc.columnNumber();
         *line = tc.blockNumber();
-    }    
+    }
 
     if (function && !expr.isEmpty())
         if (const Core::IFile *file = editor->file())
@@ -448,6 +468,7 @@ QString cppExpressionAt(TextEditor::ITextEditor *editor, int pos,
 // --------------- QtDumperResult
 
 QtDumperResult::Child::Child() :
+   keyEncoded(0),
    valueEncoded(0),
    childCount(0),
    valuedisabled(false)
@@ -468,6 +489,7 @@ void QtDumperResult::clear()
     value.clear();
     address.clear();
     type.clear();
+    extra.clear();
     displayedType.clear();
     valueEncoded = 0;
     valuedisabled = false;
@@ -502,8 +524,17 @@ QList<WatchData> QtDumperResult::toWatchData(int source) const
                 wchild.source = source;
                 wchild.iname = iname;
                 wchild.iname += dot;
-                wchild.iname += dchild.name;                
-                wchild.name = dchild.name;
+                wchild.iname += dchild.name;
+                // Use key entry as name (which is used for map nodes)
+                if (dchild.key.isEmpty()) {
+                    wchild.name = dchild.name;
+                } else {
+                    wchild.name = decodeData(dchild.key, dchild.keyEncoded);
+                    if (wchild.name.size() > 13) {
+                        wchild.name.truncate(12);
+                        wchild.name += QLatin1String("...");
+                    }
+                }
                 wchild.exp = dchild.exp;
                 wchild.valuedisabled = dchild.valuedisabled;
                 wchild.setType(dchild.type.isEmpty() ? childType : dchild.type);
@@ -526,18 +557,21 @@ QDebug operator<<(QDebug in, const QtDumperResult &d)
             << " address=" << d.address
             << " value="  << d.value
             << " disabled=" << d.valuedisabled
-            << " encoded=" << d.valueEncoded << " internal=" << d.internal;
+            << " encoded=" << d.valueEncoded << " internal=" << d.internal
+            << " extra='" << d.extra << "'\n";
     const int realChildCount = d.children.size();
     if (d.childCount || realChildCount) {
-        nospace << " childCount=" << d.childCount << '/' << realChildCount
+        nospace << "childCount=" << d.childCount << '/' << realChildCount
                 << " childType=" << d.childType << '\n';
         for (int i = 0; i < realChildCount; i++) {
             const QtDumperResult::Child &c = d.children.at(i);
             nospace << "   #" << i << " addr=" << c.address
                     << " disabled=" << c.valuedisabled
                     << " type=" << c.type << " exp=" << c.exp
-                    << " name=" << c.name << " encoded=" << c.valueEncoded
-                    << " value=" << c.value
+                    << " name=" << c.name;
+            if (!c.key.isEmpty())
+                nospace << " keyencoded=" << c.keyEncoded << " key=" << c.key;
+            nospace << " valueencoded=" << c.valueEncoded << " value=" << c.value
                     << "childcount=" << c.childCount << '\n';
         }
     }
@@ -763,6 +797,7 @@ class DumperParser
 public:
     explicit DumperParser(const char *s) : m_s(s) {}
     bool run();
+    virtual ~DumperParser() {}
 
 protected:
     // handle 'key="value"'
@@ -826,9 +861,9 @@ bool DumperParser::parseHash(int level, const char *&pos)
             return false;
         pos = equalsPtr + 1;
         if (!*pos)
-            return false;        
+            return false;
         if (!parseValue(level + 1, pos))
-            return false;    
+            return false;
         if (*pos == ',')
             pos++;
     }
@@ -864,7 +899,7 @@ bool DumperParser::parseValue(int level, const char *&pos)
                 if (*pos == ',')
                     pos++;
             }
-        }        
+        }
         return false;
         // A hash '{a="b",b="c"}'
     case '{': {
@@ -872,7 +907,7 @@ bool DumperParser::parseValue(int level, const char *&pos)
                 return false;
             pos++;
             if (!parseHash(level + 1, pos))
-                return false;            
+                return false;
             return handleHashEnd();
         }
         return false;
@@ -945,7 +980,7 @@ public:
 
 protected:
     virtual bool handleKeyword(const char *k, int size);
-    virtual bool handleListStart();    
+    virtual bool handleListStart();
     virtual bool handleListEnd();
     virtual bool handleHashEnd();
     virtual bool handleValue(const char *k, int size);
@@ -965,7 +1000,7 @@ QueryDumperParser::QueryDumperParser(const char *s) :
 {
 }
 
-bool QueryDumperParser::handleKeyword(const char *k, int size)        
+bool QueryDumperParser::handleKeyword(const char *k, int size)
 {
     switch (m_mode) {
     case ExpectingSizes:
@@ -1057,7 +1092,6 @@ bool QtDumperHelper::parseQuery(const char *data, Debugger debugger)
     foreach (const QueryDumperParser::SizeEntry &se, parser.data().sizes)
         addSize(se.first, se.second);
     m_expressionCache = parser.data().expressionCache;
-    qDebug() << m_expressionCache;
     return true;
 }
 
@@ -1074,13 +1108,15 @@ void QtDumperHelper::addSize(const QString &name, int size)
         return;
     }
     do {
+        // CDB helpers
         if (name == QLatin1String("std::string")) {
-            m_sizeCache.insert(QLatin1String("std::basic_string<char,std::char_traits<char>,std::allocator<char>>"), size);
+            m_sizeCache.insert(QLatin1String("std::basic_string<char,std::char_traits<char>,std::allocator<char> >"), size);
+            m_sizeCache.insert(QLatin1String("basic_string<char,char_traits<char>,allocator<char> >"), size);
             break;
         }
         if (name == QLatin1String("std::wstring")) {
-            // FIXME: check space between > > below?
-            m_sizeCache.insert(QLatin1String("std::basic_string<unsigned short,std::char_traits<unsignedshort>,std::allocator<unsignedshort> >"), size);
+            m_sizeCache.insert(QLatin1String("basic_string<unsigned short,char_traits<unsignedshort>,allocator<unsignedshort> >"), size);
+            m_sizeCache.insert(QLatin1String("std::basic_string<unsigned short,std::char_traits<unsigned short>,std::allocator<unsigned short> >"), size);
             break;
         }
     } while (false);
@@ -1290,10 +1326,16 @@ void QtDumperHelper::evaluationParameters(const WatchData &data,
             // But we need the offset of the second item in the value pair.
             // We read the type of the pair from the allocator argument because
             // that gets the constness "right" (in the sense that gdb can
-            // read it back;
+            // read it back: "std::allocator<std::pair<Key,Value> >"
+            // -> "std::pair<Key,Value>". Different debuggers have varying
+            // amounts of terminating blanks...
             QString pairType = inners.at(3);
-            // remove 'std::allocator<...>':
-            pairType = pairType.mid(15, pairType.size() - 15 - 2);
+            int bracketPos = pairType.indexOf(QLatin1Char('<'));
+            if (bracketPos != -1)
+                pairType.remove(0, bracketPos + 1);
+            bracketPos = pairType.indexOf(QLatin1Char('>'));
+            if (bracketPos != -1)
+                pairType.truncate(bracketPos + 1);
             extraArgs[2] = QLatin1String("(size_t)&(('");
             extraArgs[2] += pairType;
             extraArgs[2] += QLatin1String("'*)0)->second");
@@ -1370,12 +1412,15 @@ private:
                 ExpectingType, ExpectingDisplayedType, ExpectingInternal,
                 ExpectingValueDisabled,  ExpectingValueEncoded,
                 ExpectingCommonChildType, ExpectingChildCount,
+                ExpectingExtra,
                 IgnoreNext,
                 ChildModeStart,
                 ExpectingChildren,ExpectingChildName, ExpectingChildAddress,
                 ExpectingChildExpression, ExpectingChildType,
+                ExpectingChildKey, ExpectingChildKeyEncoded,
                 ExpectingChildValue, ExpectingChildValueEncoded,
-                ExpectingChildValueDisabled, ExpectingChildChildCount
+                ExpectingChildValueDisabled, ExpectingChildChildCount,
+                IgnoreNextChildMode
               };
 
     static inline Mode nextMode(Mode in, const char *keyword, int size);
@@ -1398,6 +1443,8 @@ ValueDumperParser::Mode ValueDumperParser::nextMode(Mode in, const char *keyword
     case 3:
         if (!qstrncmp(keyword, "exp", size))
             return ExpectingChildExpression;
+        if (!qstrncmp(keyword, "key", size))
+            return ExpectingChildKey;
         break;
     case 4:
         if (!qstrncmp(keyword, "addr", size))
@@ -1412,6 +1459,8 @@ ValueDumperParser::Mode ValueDumperParser::nextMode(Mode in, const char *keyword
             return ExpectingIName;
         if (!qstrncmp(keyword, "value", size))
             return in > ChildModeStart ? ExpectingChildValue : ExpectingValue;
+        if (!qstrncmp(keyword, "extra", size))
+            return ExpectingExtra;
         break;
     case 8:
         if (!qstrncmp(keyword, "children", size))
@@ -1424,7 +1473,11 @@ ValueDumperParser::Mode ValueDumperParser::nextMode(Mode in, const char *keyword
     case 9:
         if (!qstrncmp(keyword, "childtype", size))
             return ExpectingCommonChildType;
-        break;    
+        break;
+    case 10:
+        if (!qstrncmp(keyword, "keyencoded", size))
+            return ExpectingChildKeyEncoded;
+        break;
     case 12:
         if (!qstrncmp(keyword, "valueencoded", size))
             return in > ChildModeStart ? ExpectingChildValueEncoded : ExpectingValueEncoded;
@@ -1435,10 +1488,10 @@ ValueDumperParser::Mode ValueDumperParser::nextMode(Mode in, const char *keyword
         if (!qstrncmp(keyword, "displayedtype", size))
             return ExpectingDisplayedType;
         if (!qstrncmp(keyword, "childnumchild", size))
-            return IgnoreNext;
+            return IgnoreNextChildMode;
         break;
     }
-    return IgnoreNext;
+    return in > ChildModeStart ? IgnoreNextChildMode : IgnoreNext;
 }
 
 bool ValueDumperParser::handleKeyword(const char *k, int size)
@@ -1484,6 +1537,9 @@ bool ValueDumperParser::handleValue(const char *k, int size)
     case ExpectingDisplayedType:
         m_result.displayedType = QString::fromLatin1(valueBA);
         break;
+    case ExpectingExtra:
+        m_result.extra = valueBA;
+        break;
     case ExpectingInternal:
         m_result.internal = valueBA == "true";
         break;
@@ -1494,6 +1550,7 @@ bool ValueDumperParser::handleValue(const char *k, int size)
         m_result.childCount = QString::fromLatin1(valueBA).toInt();
         break;
     case ExpectingChildren:
+    case IgnoreNextChildMode:
     case IgnoreNext:
         break;
     case ExpectingChildName:
@@ -1502,6 +1559,12 @@ bool ValueDumperParser::handleValue(const char *k, int size)
     case ExpectingChildAddress:
         m_result.children.back().address = QString::fromLatin1(valueBA);
         break;
+    case ExpectingChildKeyEncoded:
+        m_result.children.back().keyEncoded = QString::fromLatin1(valueBA).toInt();
+        break;
+    case ExpectingChildKey:
+        m_result.children.back().key = valueBA;
+        break;
     case ExpectingChildValue:
         m_result.children.back().value = valueBA;
         break;
@@ -1525,7 +1588,7 @@ bool ValueDumperParser::handleValue(const char *k, int size)
 }
 
 bool QtDumperHelper::parseValue(const char *data, QtDumperResult *r)
-{    
+{
     ValueDumperParser parser(data);
     if (!parser.run())
         return false;
@@ -1534,7 +1597,7 @@ bool QtDumperHelper::parseValue(const char *data, QtDumperResult *r)
     if (r->childCount < r->children.size())
         r->childCount  = r->children.size();
     if (debug)
-        qDebug() << '\n' << data << *r;
+        qDebug() << '\n' << data << '\n' << *r;
     return true;
 }
 
diff --git a/src/plugins/debugger/watchutils.h b/src/plugins/debugger/watchutils.h
index d9a43d136f946f22e408214cde3f944121bbd94c..9d39372aa0e8588fd3c56ccf50024c0e94a99269 100644
--- a/src/plugins/debugger/watchutils.h
+++ b/src/plugins/debugger/watchutils.h
@@ -72,6 +72,7 @@ QString gdbQuoteTypes(const QString &type);
 bool extractTemplate(const QString &type, QString *tmplate, QString *inner);
 QString extractTypeFromPTypeOutput(const QString &str);
 bool isIntOrFloatType(const QString &type);
+bool isIntType(const QString &type);
 QString sizeofTypeExpression(const QString &type);
 QString quoteUnprintableLatin1(const QByteArray &ba);
 
@@ -89,13 +90,15 @@ struct QtDumperResult
     struct Child {
         Child();
 
-        int valueEncoded;
+        int keyEncoded;
+        int valueEncoded;        
         int childCount;
         bool valuedisabled;
         QString name;
         QString address;
         QString exp;
         QString type;
+        QByteArray key;
         QByteArray value;
     };
 
@@ -106,6 +109,7 @@ struct QtDumperResult
     QString iname;
     QString address;
     QString type;
+    QString extra;
     QString displayedType;
     QByteArray value;
     int valueEncoded;
diff --git a/src/plugins/debugger/watchwindow.cpp b/src/plugins/debugger/watchwindow.cpp
index feab5a2989cb9350b886587d8836978f5116cc01..57946b807e58fda2476938b937f614f36f376b41 100644
--- a/src/plugins/debugger/watchwindow.cpp
+++ b/src/plugins/debugger/watchwindow.cpp
@@ -199,30 +199,65 @@ void WatchWindow::dropEvent(QDropEvent *ev)
 
 void WatchWindow::contextMenuEvent(QContextMenuEvent *ev)
 {
+    QModelIndex idx = indexAt(ev->pos());
+    QModelIndex mi0 = idx.sibling(idx.row(), 0);
+    QModelIndex mi1 = idx.sibling(idx.row(), 1);
+    QModelIndex mi2 = idx.sibling(idx.row(), 2);
+    QString exp = model()->data(mi0).toString();
+    QString type = model()->data(mi2).toString();
+
+    QStringList alternativeFormats = 
+        model()->data(mi0, TypeFormatListRole).toStringList();
+    int typeFormat = 
+        model()->data(mi0, TypeFormatRole).toInt();
+    int individualFormat = 
+        model()->data(mi0, IndividualFormatRole).toInt();
+
+    QMenu typeFormatMenu(tr("Change format for type '%1'").arg(type));
+    QMenu individualFormatMenu(tr("Change format for expression '%1'").arg(exp));
+    QList<QAction *> typeFormatActions;
+    QList<QAction *> individualFormatActions;
+    for (int i = 0; i != alternativeFormats.size(); ++i) {
+        const QString format = alternativeFormats.at(i);
+        QAction *act = new QAction(format, &typeFormatMenu);
+        act->setCheckable(true);
+        if (i == typeFormat)
+            act->setChecked(true);
+        typeFormatMenu.addAction(act);
+        typeFormatActions.append(act);
+        act = new QAction(format, &individualFormatMenu);
+        act->setCheckable(true);
+        if (i == individualFormat)
+            act->setChecked(true);
+        individualFormatMenu.addAction(act);
+        individualFormatActions.append(act);
+    }
+    //typeFormatMenu.setActive(!alternativeFormats.isEmpty());
+    //individualFormatMenu.setActive(!alternativeFormats.isEmpty());
+
     QMenu menu;
     QAction *act1 = new QAction(tr("Adjust column widths to contents"), &menu);
     QAction *act2 = new QAction(tr("Always adjust column widths to contents"), &menu);
+
     act2->setCheckable(true);
     act2->setChecked(m_alwaysResizeColumnsToContents);
 
-    menu.addAction(act1);
-    menu.addAction(act2);
-
-    QModelIndex idx = indexAt(ev->pos());
-    QModelIndex mi0 = idx.sibling(idx.row(), 0);
-    QString exp = model()->data(mi0).toString();
-
-    menu.addSeparator();
-    int type = (m_type == LocalsType) ? WatchExpression : RemoveWatchExpression;
-    menu.addAction(theDebuggerAction(type)->updatedAction(exp));
-
     //QAction *act4 = theDebuggerAction(WatchExpressionInWindow);
     //menu.addAction(act4);
 
     QAction *act3 = new QAction(tr("Insert new watch item"), &menu); 
-    menu.addAction(act3);
     QAction *act4 = new QAction(tr("Select widget to watch"), &menu);
+
+    menu.addAction(act1);
+    menu.addAction(act2);
+    menu.addSeparator();
+    int atype = (m_type == LocalsType) ? WatchExpression : RemoveWatchExpression;
+    menu.addAction(theDebuggerAction(atype)->updatedAction(exp));
+
+    menu.addAction(act3);
     menu.addAction(act4);
+    menu.addMenu(&typeFormatMenu);
+    menu.addMenu(&individualFormatMenu);
 
     menu.addSeparator();
     menu.addAction(theDebuggerAction(RecheckDebuggingHelpers));
@@ -232,16 +267,23 @@ void WatchWindow::contextMenuEvent(QContextMenuEvent *ev)
 
     QAction *act = menu.exec(ev->globalPos());
 
-    if (act == act1)
+    if (act == act1) {
         resizeColumnsToContents();
-    else if (act == act2)
+    } else if (act == act2) {
         setAlwaysResizeColumnsToContents(!m_alwaysResizeColumnsToContents);
-    else if (act == act3)
+    } else if (act == act3) {
         theDebuggerAction(WatchExpression)
             ->trigger(WatchHandler::watcherEditPlaceHolder());
-    else if (act == act4) {
+    } else if (act == act4) {
         grabMouse(Qt::CrossCursor);
         m_grabbing = true;
+    } else { 
+        for (int i = 0; i != alternativeFormats.size(); ++i) {
+            if (act == typeFormatActions.at(i))
+                model()->setData(mi1, i, TypeFormatRole);
+            else if (act == individualFormatActions.at(i))
+                model()->setData(mi1, i, IndividualFormatRole);
+        }
     }
 }
 
diff --git a/src/plugins/fakevim/fakevimhandler.cpp b/src/plugins/fakevim/fakevimhandler.cpp
index 761a97fa272650ac99b4a438de01c7816bda615e..edddd9f61c06e4e5e2386807f420e8be8ccd2c9f 100644
--- a/src/plugins/fakevim/fakevimhandler.cpp
+++ b/src/plugins/fakevim/fakevimhandler.cpp
@@ -235,7 +235,7 @@ public:
     bool atEndOfLine() const
         { return m_tc.atBlockEnd() && m_tc.block().length() > 1; }
 
-    int lastPositionInDocument() const;
+    int lastPositionInDocument() const; // last valid pos in doc
     int firstPositionInLine(int line) const; // 1 based line, 0 based pos
     int lastPositionInLine(int line) const; // 1 based line, 0 based pos
     int lineForPosition(int pos) const;  // 1 based line, 0 based pos
@@ -272,6 +272,7 @@ public:
     void moveToEndOfDocument() { m_tc.movePosition(EndOfDocument, MoveAnchor); }
     void moveToStartOfLine();
     void moveToEndOfLine();
+    void moveBehindEndOfLine();
     void moveUp(int n = 1) { moveDown(-n); }
     void moveDown(int n = 1); // { m_tc.movePosition(Down, MoveAnchor, n); }
     void moveRight(int n = 1) { m_tc.movePosition(Right, MoveAnchor, n); }
@@ -633,6 +634,13 @@ void FakeVimHandler::Private::moveToEndOfLine()
 #endif
 }
 
+void FakeVimHandler::Private::moveBehindEndOfLine()
+{
+    const QTextBlock &block = m_tc.block();
+    int pos = qMin(block.position() + block.length(), lastPositionInDocument());
+    setPosition(pos);
+}
+
 void FakeVimHandler::Private::moveToStartOfLine()
 {
 #if 0
@@ -887,9 +895,10 @@ EventResult FakeVimHandler::Private::handleCommandMode(int key, int unmodified,
     } else if (m_submode == YankSubMode && key == 'y') {
         moveToStartOfLine();
         setAnchor();
-        moveDown(count());
+        moveDown(count() - 1);
+        moveBehindEndOfLine();
         m_moveType = MoveLineWise;
-        finishMovement("y");
+        finishMovement();
     } else if (m_submode == ShiftLeftSubMode && key == '<') {
         setAnchor();
         moveDown(count() - 1);
@@ -1086,7 +1095,7 @@ EventResult FakeVimHandler::Private::handleCommandMode(int key, int unmodified,
         m_passing = !m_passing;
         updateMiniBuffer();
     } else if (key == '.') {
-        qDebug() << "REPEATING" << quoteUnprintable(m_dotCommand);
+        //qDebug() << "REPEATING" << quoteUnprintable(m_dotCommand);
         QString savedCommand = m_dotCommand;
         m_dotCommand.clear();
         replay(savedCommand, count());
@@ -2024,7 +2033,7 @@ void FakeVimHandler::Private::search(const QString &needle0, bool forward)
             scrollToLineInDocument(cursorLineInDocument() - linesOnScreen() / 2);
         highlightMatches(needle);
     } else {
-        m_tc.setPosition(forward ? 0 : lastPositionInDocument() - 1);
+        m_tc.setPosition(forward ? 0 : lastPositionInDocument());
         EDITOR(setTextCursor(m_tc));
         if (EDITOR(find(needle, flags))) {
             m_tc = EDITOR(textCursor());
@@ -2199,7 +2208,7 @@ void FakeVimHandler::Private::moveToWordBoundary(bool simple, bool forward)
 {
     int repeat = count();
     QTextDocument *doc = m_tc.document();
-    int n = forward ? lastPositionInDocument() - 1 : 0;
+    int n = forward ? lastPositionInDocument() : 0;
     int lastClass = -1;
     while (true) {
         QChar c = doc->characterAt(m_tc.position() + (forward ? 1 : -1));
@@ -2257,7 +2266,7 @@ void FakeVimHandler::Private::moveToNextWord(bool simple)
 {
     // FIXME: 'w' should stop on empty lines, too
     int repeat = count();
-    int n = lastPositionInDocument() - 1;
+    int n = lastPositionInDocument();
     int lastClass = charClass(characterAtCursor(), simple);
     while (true) {
         QChar c = characterAtCursor();
@@ -2344,7 +2353,7 @@ void FakeVimHandler::Private::scrollUp(int count)
 int FakeVimHandler::Private::lastPositionInDocument() const
 {
     QTextBlock block = m_tc.document()->lastBlock();
-    return block.position() + block.length();
+    return block.position() + block.length() - 1;
 }
 
 QString FakeVimHandler::Private::lastSearchString() const
diff --git a/src/plugins/projectexplorer/toolchain.cpp b/src/plugins/projectexplorer/toolchain.cpp
index 16769ca0ddc5499ea0233f89fc7d645a6f00cfbc..1aa284121c11dea70cd1fc6e0d0346474034e7cc 100644
--- a/src/plugins/projectexplorer/toolchain.cpp
+++ b/src/plugins/projectexplorer/toolchain.cpp
@@ -316,10 +316,10 @@ void MSVCToolChain::addToEnvironment(ProjectExplorer::Environment &env)
         QString desc;
         QString varsbat;
         if (m_amd64)
-                varsbat = path + "VC\\bin\\amd64\\vcvarsamd64.bat";
+            varsbat = path + "VC\\bin\\amd64\\vcvarsamd64.bat";
         else
-                varsbat = path + "Common7\\Tools\\vsvars32.bat";
-//        qDebug() << varsbat;
+            varsbat = path + "Common7\\Tools\\vsvars32.bat";
+        //        qDebug() << varsbat;
         if (QFileInfo(varsbat).exists()) {
             QTemporaryFile tf(QDir::tempPath() + "\\XXXXXX.bat");
             if (!tf.open())
diff --git a/src/shared/cplusplus/AST.cpp b/src/shared/cplusplus/AST.cpp
index c809f6e1d02dd10a7f2231a674a42f742c4b8611..dc6a50567751613fbad3f63d3dc0c2dec1bd757f 100644
--- a/src/shared/cplusplus/AST.cpp
+++ b/src/shared/cplusplus/AST.cpp
@@ -874,6 +874,24 @@ unsigned ExpressionStatementAST::lastToken() const
     return 0;
 }
 
+unsigned ForeachStatementAST::firstToken() const
+{
+    return foreach_token;
+}
+
+unsigned ForeachStatementAST::lastToken() const
+{
+    if (statement)
+        return statement->lastToken();
+    else if (rparen_token)
+        return rparen_token + 1;
+    else if (expression)
+        return expression->lastToken();
+    else if (comma_token)
+        return comma_token + 1;
+
+    return foreach_token + 1;
+}
 
 unsigned ForStatementAST::firstToken() const
 {
diff --git a/src/shared/cplusplus/AST.h b/src/shared/cplusplus/AST.h
index f345fd76b0cadfe485310c0acedb4c6c2ad47454..d22735eeb145b23c01098a7d1e7ac67b450d8d39 100644
--- a/src/shared/cplusplus/AST.h
+++ b/src/shared/cplusplus/AST.h
@@ -131,6 +131,7 @@ public:
     virtual ExpressionListAST *asExpressionList() { return 0; }
     virtual ExpressionOrDeclarationStatementAST *asExpressionOrDeclarationStatement() { return 0; }
     virtual ExpressionStatementAST *asExpressionStatement() { return 0; }
+    virtual ForeachStatementAST *asForeachStatement() { return 0; }
     virtual ForStatementAST *asForStatement() { return 0; }
     virtual FunctionDeclaratorAST *asFunctionDeclarator() { return 0; }
     virtual FunctionDefinitionAST *asFunctionDefinition() { return 0; }
@@ -1135,6 +1136,37 @@ protected:
     virtual void accept0(ASTVisitor *visitor);
 };
 
+class CPLUSPLUS_EXPORT ForeachStatementAST: public StatementAST
+{
+public:
+    unsigned foreach_token;
+    unsigned lparen_token;
+    // declaration
+    SpecifierAST *type_specifiers;
+    DeclaratorAST *declarator;
+    // or an expression
+    ExpressionAST *initializer;
+    unsigned comma_token;
+    ExpressionAST *expression;
+    unsigned rparen_token;
+    StatementAST *statement;
+
+public: // annotations
+    Block *symbol;
+
+public:
+    virtual ForeachStatementAST *asForeachStatement()
+    { return this; }
+
+    virtual unsigned firstToken() const;
+    virtual unsigned lastToken() const;
+
+    virtual ForeachStatementAST *clone(MemoryPool *pool) const;
+
+protected:
+    virtual void accept0(ASTVisitor *visitor);
+};
+
 class CPLUSPLUS_EXPORT ForStatementAST: public StatementAST
 {
 public:
diff --git a/src/shared/cplusplus/ASTClone.cpp b/src/shared/cplusplus/ASTClone.cpp
index c3eb1ab40fa487778aec152b6c39dd1c31cf7f34..2e446c89ef1274f4542c053d17aeb7e89b569e68 100644
--- a/src/shared/cplusplus/ASTClone.cpp
+++ b/src/shared/cplusplus/ASTClone.cpp
@@ -514,6 +514,23 @@ FunctionDefinitionAST *FunctionDefinitionAST::clone(MemoryPool *pool) const
     return ast;
 }
 
+ForeachStatementAST *ForeachStatementAST::clone(MemoryPool *pool) const
+{
+    ForeachStatementAST *ast = new (pool) ForeachStatementAST;
+    // copy StatementAST
+    // copy ForeachStatementAST
+    ast->foreach_token = foreach_token;
+    ast->lparen_token = lparen_token;
+    if (type_specifiers) ast->type_specifiers = type_specifiers->clone(pool);
+    if (declarator) ast->declarator = declarator->clone(pool);
+    if (initializer) ast->initializer = initializer->clone(pool);
+    ast->comma_token = comma_token;
+    if (expression) ast->expression = expression->clone(pool);
+    ast->rparen_token = rparen_token;
+    if (statement) ast->statement = statement->clone(pool);
+    return ast;
+}
+
 ForStatementAST *ForStatementAST::clone(MemoryPool *pool) const
 {
     ForStatementAST *ast = new (pool) ForStatementAST;
diff --git a/src/shared/cplusplus/ASTVisit.cpp b/src/shared/cplusplus/ASTVisit.cpp
index c85ce397078542fc73696161b92d78927de94fb7..1673577474f4a8793b613287f4e2d9e74de6fdc6 100644
--- a/src/shared/cplusplus/ASTVisit.cpp
+++ b/src/shared/cplusplus/ASTVisit.cpp
@@ -474,6 +474,21 @@ void FunctionDefinitionAST::accept0(ASTVisitor *visitor)
     visitor->endVisit(this);
 }
 
+void ForeachStatementAST::accept0(ASTVisitor *visitor)
+{
+    if (visitor->visit(this)) {
+        // visit ForeachStatementAST
+        for (SpecifierAST *it = type_specifiers; it; it = it->next)
+            accept(it, visitor);
+        accept(declarator, visitor);
+        accept(initializer, visitor);
+        accept(expression, visitor);
+        accept(statement, visitor);
+        // visit StatementAST
+    }
+    visitor->endVisit(this);
+}
+
 void ForStatementAST::accept0(ASTVisitor *visitor)
 {
     if (visitor->visit(this)) {
diff --git a/src/shared/cplusplus/ASTVisitor.h b/src/shared/cplusplus/ASTVisitor.h
index 45c8d89efc708e7f19abc0421c6b8b17669d1f7d..caa93e5e1b82572c87f90c818fb8a7a144bf1bdc 100644
--- a/src/shared/cplusplus/ASTVisitor.h
+++ b/src/shared/cplusplus/ASTVisitor.h
@@ -134,6 +134,7 @@ public:
     virtual bool visit(ExpressionListAST *) { return true; }
     virtual bool visit(ExpressionOrDeclarationStatementAST *) { return true; }
     virtual bool visit(ExpressionStatementAST *) { return true; }
+    virtual bool visit(ForeachStatementAST *) { return true; }
     virtual bool visit(ForStatementAST *) { return true; }
     virtual bool visit(FunctionDeclaratorAST *) { return true; }
     virtual bool visit(FunctionDefinitionAST *) { return true; }
@@ -242,6 +243,7 @@ public:
     virtual void endVisit(ExpressionListAST *) { }
     virtual void endVisit(ExpressionOrDeclarationStatementAST *) { }
     virtual void endVisit(ExpressionStatementAST *) { }
+    virtual void endVisit(ForeachStatementAST *) { }
     virtual void endVisit(ForStatementAST *) { }
     virtual void endVisit(FunctionDeclaratorAST *) { }
     virtual void endVisit(FunctionDefinitionAST *) { }
diff --git a/src/shared/cplusplus/ASTfwd.h b/src/shared/cplusplus/ASTfwd.h
index 0f4d9581bfb9404a34cea61cace67d94e776e171..ee5f8e876ffaf2b961439f959b7bb4667350c65c 100644
--- a/src/shared/cplusplus/ASTfwd.h
+++ b/src/shared/cplusplus/ASTfwd.h
@@ -101,6 +101,7 @@ class ExpressionAST;
 class ExpressionListAST;
 class ExpressionOrDeclarationStatementAST;
 class ExpressionStatementAST;
+class ForeachStatementAST;
 class ForStatementAST;
 class FunctionDeclaratorAST;
 class FunctionDefinitionAST;
diff --git a/src/shared/cplusplus/CheckDeclaration.cpp b/src/shared/cplusplus/CheckDeclaration.cpp
index 038d70b9a48a9dff38726cba7a748dc98ea2eb2f..1bd8086cdbc6fdb5d2d3914f7186cb9938d357ba 100644
--- a/src/shared/cplusplus/CheckDeclaration.cpp
+++ b/src/shared/cplusplus/CheckDeclaration.cpp
@@ -251,7 +251,7 @@ bool CheckDeclaration::visit(AccessDeclarationAST *ast)
     semantic()->switchVisibility(visibility);
     if (ast->slots_token)
         semantic()->switchMethodKey(Function::SlotMethod);
-    else if (accessSpecifier == T_SIGNALS)
+    else if (accessSpecifier == T_Q_SIGNALS)
         semantic()->switchMethodKey(Function::SignalMethod);
     else
         semantic()->switchMethodKey(Function::NormalMethod);
diff --git a/src/shared/cplusplus/CheckStatement.cpp b/src/shared/cplusplus/CheckStatement.cpp
index 0d7bced86ecc3acd65bae7dca0c8be84065124b8..c93eca0492de9712e2246617f542c89a1e1bff42 100644
--- a/src/shared/cplusplus/CheckStatement.cpp
+++ b/src/shared/cplusplus/CheckStatement.cpp
@@ -141,6 +141,35 @@ bool CheckStatement::visit(ExpressionStatementAST *ast)
     return false;
 }
 
+bool CheckStatement::visit(ForeachStatementAST *ast)
+{
+    Block *block = control()->newBlock(ast->foreach_token);
+    block->setStartOffset(tokenAt(ast->firstToken()).offset);
+    block->setEndOffset(tokenAt(ast->lastToken()).offset);
+    ast->symbol = block;
+    _scope->enterSymbol(block);
+    Scope *previousScope = switchScope(block->members());
+    if (ast->type_specifiers && ast->declarator) {
+        FullySpecifiedType ty = semantic()->check(ast->type_specifiers, _scope);
+        Name *name = 0;
+        ty = semantic()->check(ast->declarator, ty, _scope, &name);
+        unsigned location = ast->declarator->firstToken();
+        if (CoreDeclaratorAST *core_declarator = ast->declarator->core_declarator)
+            location = core_declarator->firstToken();
+        Declaration *decl = control()->newDeclaration(location, name);
+        decl->setType(ty);
+        _scope->enterSymbol(decl);
+    } else {
+        FullySpecifiedType exprTy = semantic()->check(ast->initializer, _scope);
+        (void) exprTy;
+    }
+
+    FullySpecifiedType exprTy = semantic()->check(ast->expression, _scope);
+    semantic()->check(ast->statement, _scope);
+    (void) switchScope(previousScope);
+    return false;
+}
+
 bool CheckStatement::visit(ForStatementAST *ast)
 {
     Block *block = control()->newBlock(ast->for_token);
diff --git a/src/shared/cplusplus/CheckStatement.h b/src/shared/cplusplus/CheckStatement.h
index 59b74b136351a7f3a17e4583379eb2ad59870697..baa2bdccf393e823ce98d42421326a7f68a702c0 100644
--- a/src/shared/cplusplus/CheckStatement.h
+++ b/src/shared/cplusplus/CheckStatement.h
@@ -75,6 +75,7 @@ protected:
     virtual bool visit(DoStatementAST *ast);
     virtual bool visit(ExpressionOrDeclarationStatementAST *ast);
     virtual bool visit(ExpressionStatementAST *ast);
+    virtual bool visit(ForeachStatementAST *ast);
     virtual bool visit(ForStatementAST *ast);
     virtual bool visit(IfStatementAST *ast);
     virtual bool visit(LabeledStatementAST *ast);
diff --git a/src/shared/cplusplus/Control.h b/src/shared/cplusplus/Control.h
index b06063d4f529418fb20d43cb2fa8c80b1eb8d24a..8b4f09afffb829548474eebab0af54acbec74362 100644
--- a/src/shared/cplusplus/Control.h
+++ b/src/shared/cplusplus/Control.h
@@ -115,7 +115,7 @@ public:
     NamedType *namedType(Name *name);
 
     /// Creates a new Declaration symbol.
-    Declaration *newDeclaration(unsigned sourceLocation, Name *name = 0);
+    Declaration *newDeclaration(unsigned sourceLocation, Name *name);
 
     /// Creates a new Argument symbol.
     Argument *newArgument(unsigned sourceLocation, Name *name = 0);
diff --git a/src/shared/cplusplus/Keywords.cpp b/src/shared/cplusplus/Keywords.cpp
index e1b605668a0f75af8849b158cb87c86fb1892bce..3d8fc434f5ec51560b5d2f34c6873ee20ddaa6b0 100644
--- a/src/shared/cplusplus/Keywords.cpp
+++ b/src/shared/cplusplus/Keywords.cpp
@@ -297,7 +297,7 @@ static inline int classify5(const char *s, bool q) {
         if (s[2] == 'o') {
           if (s[3] == 't') {
             if (s[4] == 's') {
-              return T_SLOTS;
+              return T_Q_SLOTS;
             }
           }
         }
@@ -620,6 +620,21 @@ static inline int classify7(const char *s, bool q) {
       }
     }
   }
+  else if (q && s[0] == 'f') {
+    if (s[1] == 'o') {
+      if (s[2] == 'r') {
+        if (s[3] == 'e') {
+          if (s[4] == 'a') {
+            if (s[5] == 'c') {
+              if (s[6] == 'h') {
+                return T_Q_FOREACH;
+              }
+            }
+          }
+        }
+      }
+    }
+  }
   else if (q && s[0] == 's') {
     if (s[1] == 'i') {
       if (s[2] == 'g') {
@@ -627,7 +642,7 @@ static inline int classify7(const char *s, bool q) {
           if (s[4] == 'a') {
             if (s[5] == 'l') {
               if (s[6] == 's') {
-                return T_SIGNALS;
+                return T_Q_SIGNALS;
               }
             }
           }
@@ -687,7 +702,7 @@ static inline int classify7(const char *s, bool q) {
           if (s[4] == 'O') {
             if (s[5] == 'T') {
               if (s[6] == 'S') {
-                return T_SLOTS;
+                return T_Q_SLOTS;
               }
             }
           }
@@ -950,7 +965,21 @@ static inline int classify9(const char *s, bool q) {
               if (s[6] == 'A') {
                 if (s[7] == 'L') {
                   if (s[8] == 'S') {
-                    return T_SIGNALS;
+                    return T_Q_SIGNALS;
+                  }
+                }
+              }
+            }
+          }
+        }
+      } else if (s[2] == 'F') {
+        if (s[3] == 'O') {
+          if (s[4] == 'R') {
+            if (s[5] == 'E') {
+              if (s[6] == 'A') {
+                if (s[7] == 'C') {
+                  if (s[8] == 'H') {
+                    return T_Q_FOREACH;
                   }
                 }
               }
diff --git a/src/shared/cplusplus/Parser.cpp b/src/shared/cplusplus/Parser.cpp
index 08266e9f79db0daa607ab611f3fd4377b6d7b464..e94a9ca5d9207291438a7bec42977260a00bd162 100644
--- a/src/shared/cplusplus/Parser.cpp
+++ b/src/shared/cplusplus/Parser.cpp
@@ -1464,11 +1464,11 @@ bool Parser::parseAccessSpecifier(SpecifierAST *&node)
 
 bool Parser::parseAccessDeclaration(DeclarationAST *&node)
 {
-    if (LA() == T_PUBLIC || LA() == T_PROTECTED || LA() == T_PRIVATE || LA() == T_SIGNALS) {
-        bool isSignals = LA() == T_SIGNALS;
+    if (LA() == T_PUBLIC || LA() == T_PROTECTED || LA() == T_PRIVATE || LA() == T_Q_SIGNALS) {
+        bool isSignals = LA() == T_Q_SIGNALS;
         AccessDeclarationAST *ast = new (_pool) AccessDeclarationAST;
         ast->access_specifier_token = consumeToken();
-        if (! isSignals && LA() == T_SLOTS)
+        if (! isSignals && LA() == T_Q_SLOTS)
             ast->slots_token = consumeToken();
         match(T_COLON, &ast->colon_token);
         node = ast;
@@ -1489,7 +1489,7 @@ bool Parser::parseMemberSpecification(DeclarationAST *&node)
     case T_TEMPLATE:
         return parseTemplateDeclaration(node);
 
-    case T_SIGNALS:
+    case T_Q_SIGNALS:
     case T_PUBLIC:
     case T_PROTECTED:
     case T_PRIVATE:
@@ -1861,6 +1861,9 @@ bool Parser::parseStatement(StatementAST *&node)
     case T_DO:
         return parseDoStatement(node);
 
+    case T_Q_FOREACH:
+        return parseForeachStatement(node);
+
     case T_FOR:
         return parseForStatement(node);
 
@@ -2108,6 +2111,41 @@ bool Parser::parseDoStatement(StatementAST *&node)
     return false;
 }
 
+bool Parser::parseForeachStatement(StatementAST *&node)
+{
+    if (LA() == T_Q_FOREACH) {
+        ForeachStatementAST *ast = new (_pool) ForeachStatementAST;
+        ast->foreach_token = consumeToken();
+        match(T_LPAREN, &ast->lparen_token);
+
+        unsigned startOfTypeSpecifier = cursor();
+        bool blocked = blockErrors(true);
+
+        if (parseTypeSpecifier(ast->type_specifiers))
+            parseDeclarator(ast->declarator);
+
+        if (! ast->type_specifiers || ! ast->declarator) {
+            ast->type_specifiers = 0;
+            ast->declarator = 0;
+
+            blockErrors(blocked);
+            rewind(startOfTypeSpecifier);
+            parseAssignmentExpression(ast->expression);
+        }
+
+        blockErrors(blocked);
+
+        match(T_COMMA, &ast->comma_token);
+        parseExpression(ast->expression);
+        match(T_RPAREN, &ast->rparen_token);
+        parseStatement(ast->statement);
+
+        node = ast;
+        return true;
+    }
+    return false;
+}
+
 bool Parser::parseForStatement(StatementAST *&node)
 {
     if (LA() == T_FOR) {
diff --git a/src/shared/cplusplus/Parser.h b/src/shared/cplusplus/Parser.h
index 330bb84b3d761e6548bef0fcaf3e9fa652137c31..c5515b05ec0107db849b94b9f154cbcccfe14c72 100644
--- a/src/shared/cplusplus/Parser.h
+++ b/src/shared/cplusplus/Parser.h
@@ -121,6 +121,7 @@ public:
     bool parseExpressionOrDeclarationStatement(StatementAST *&node);
     bool parseExpressionStatement(StatementAST *&node);
     bool parseForInitStatement(StatementAST *&node);
+    bool parseForeachStatement(StatementAST *&node);
     bool parseForStatement(StatementAST *&node);
     bool parseFunctionBody(StatementAST *&node);
     bool parseIfStatement(StatementAST *&node);
diff --git a/src/shared/cplusplus/Semantic.cpp b/src/shared/cplusplus/Semantic.cpp
index 9e7108bbc54f71a218a442446ef5615de6a24a7b..6f44072302e52b0280bd1962a56b982f88df51ae 100644
--- a/src/shared/cplusplus/Semantic.cpp
+++ b/src/shared/cplusplus/Semantic.cpp
@@ -179,7 +179,7 @@ int Semantic::visibilityForAccessSpecifier(int tokenKind) const
         return Symbol::Protected;
     case T_PRIVATE:
         return Symbol::Private;
-    case T_SIGNALS:
+    case T_Q_SIGNALS:
         return Symbol::Protected;
     default:
         return Symbol::Public;
diff --git a/src/shared/cplusplus/Token.cpp b/src/shared/cplusplus/Token.cpp
index 6e5e428c2dbd7511db32adc7c3c57219c83a3e77..37a95d6cd772d4c12bb5986ef1454ad27e25a6bf 100644
--- a/src/shared/cplusplus/Token.cpp
+++ b/src/shared/cplusplus/Token.cpp
@@ -90,7 +90,7 @@ static const char *token_names[] = {
     ("@protected"), ("@protocol"), ("@public"), ("@required"), ("@selector"),
     ("@synchronized"), ("@synthesize"), ("@throw"), ("@try"),
 
-    ("SIGNAL"), ("SLOT"), ("Q_SIGNAL"), ("Q_SLOT"), ("signals"), ("slots")
+    ("SIGNAL"), ("SLOT"), ("Q_SIGNAL"), ("Q_SLOT"), ("signals"), ("slots"), ("Q_FOREACH")
 };
 
 Token::Token() :
diff --git a/src/shared/cplusplus/Token.h b/src/shared/cplusplus/Token.h
index 660e91e4b67e08645b483dfb6e35650df99d6548..6774dba3361d8528a0cfa917c5a7b1d4455ca845 100644
--- a/src/shared/cplusplus/Token.h
+++ b/src/shared/cplusplus/Token.h
@@ -234,10 +234,11 @@ enum Kind {
     T_SLOT,
     T_Q_SIGNAL,
     T_Q_SLOT,
-    T_SIGNALS,
-    T_SLOTS,
+    T_Q_SIGNALS,
+    T_Q_SLOTS,
+    T_Q_FOREACH,
 
-    T_LAST_KEYWORD = T_SLOTS,
+    T_LAST_KEYWORD = T_Q_FOREACH,
 
     // aliases
     T_OR = T_PIPE_PIPE,
diff --git a/tests/auto/debugger/main.cpp b/tests/auto/debugger/main.cpp
index 1286158d721dc928a53d992ca6f243d6b2bd004f..eb79b6180c55e8eed7730b814e8881421065865f 100644
--- a/tests/auto/debugger/main.cpp
+++ b/tests/auto/debugger/main.cpp
@@ -116,6 +116,7 @@ private slots:
     void dumpQHash();
     void dumpQObject();
     void dumpQString();
+    void dumpQVariant();
     void dumpStdVector();
 
 public slots:
@@ -454,6 +455,25 @@ void tst_Debugger::dumpQString()
         &s, NS"QString", false);
 }
 
+void tst_Debugger::dumpQVariant()
+{ 
+    QVariant v;
+    testDumper("value='(invalid)',type='$T',numchild='0'",
+        &v, NS"QVariant", false);
+    v = "abc";
+    testDumper("value='KFFTdHJpbmcpICJhYmMi',valueencoded='5',type='$T',"
+        "numchild='1',children=[{name='value',value='IgBhAGIAYwAiAA==',"
+        "valueencoded='4',type='QString',numchild='0'}]",
+        &v, NS"QVariant", true);
+    v = QStringList() << "Hi";
+return; // FIXME
+    testDumper("value='(QStringList) ',type='$T',"
+        "numchild='1',children=[{name='value',"
+        "exp='(*('myns::QStringList'*)3215364300)',"
+        "type='QStringList',numchild='1'}]",
+        &v, NS"QVariant", true);
+}
+
 void tst_Debugger::dumpStdVector()
 {
     std::vector<std::list<int> *> vector;
diff --git a/tests/auto/fakevim/main.cpp b/tests/auto/fakevim/main.cpp
index 2952d054677d14e6953adb2284f634fbefb1ad68..08773eeb0a4d6627e89c74e6156bfafff0c3d3e3 100644
--- a/tests/auto/fakevim/main.cpp
+++ b/tests/auto/fakevim/main.cpp
@@ -69,6 +69,8 @@ private slots:
     void command_right();
     void command_up();
     void command_w();
+    void command_yyp();
+    void command_Gyyp();
 
     // special tests
     void test_i_cw_i();
@@ -305,6 +307,7 @@ void tst_FakeVim::command_dfx_down()
     check("df ",  l[0] + "\n#inc@<QtCore>\n" + lmid(2));
     check("j",    l[0] + "\n#inc<QtCore>\n#inc@lude <QtGui>\n" + lmid(3));
     check(".",    l[0] + "\n#inc<QtCore>\n#inc@<QtGui>\n" + lmid(3));
+    qWarning("FIXME");
 return;
     check("u",    l[0] + "\n#inc<QtCore>\n#inc@lude <QtGui>\n" + lmid(3));
     check("u",    l[0] + "\n#inc@lude <QtCore>\n" + lmid(2));
@@ -396,6 +399,7 @@ void tst_FakeVim::command_r()
     check("rx",  lmid(0, 4) + "\nint main(int argc, char *argv[]x@\n" + lmid(5)); 
     check("2h",  lmid(0, 4) + "\nint main(int argc, char *argv[@]x\n" + lmid(5));
     check("4ra", lmid(0, 4) + "\nint main(int argc, char *argv[@]x\n" + lmid(5));
+    qWarning("FIXME");
 return; // FIXME
     check("3rb", lmid(0, 4) + "\nint main(int argc, char *argv[bb@b\n" + lmid(5));
     check("2rc", lmid(0, 4) + "\nint main(int argc, char *argv[bb@b\n" + lmid(5));
@@ -440,7 +444,23 @@ void tst_FakeVim::command_w()
     move("w",   "@{");
 }
 
+void tst_FakeVim::command_yyp()
+{
+    setup();
+    move("4j",   "@int main");
+    check("yyp", lmid(0, 4) + "\n" + lmid(4, 1) + "\n@" + lmid(4));
+}
+
+void tst_FakeVim::command_Gyyp()
+{
+    qWarning("FIXME");
+return; // FIXME
+    setup();
+    check("G",   lmid(0) + "@");
+    check("yyp", lmid(0) + "@" + lmid(9, 1));
+}
 /*
+
 #include <QtCore>
 #include <QtGui>
 
@@ -458,6 +478,7 @@ void tst_FakeVim::test_i_cw_i()
     setup();
     move("j",                "@" + l[1]);
     check("ixx" + escape,    l[0] + "\nx@x" + lmid(1));
+    qWarning("FIXME");
 return; // FIXME: not in sync with Gui behaviour?
     check("cwyy" + escape,   l[0] + "\nxy@y" + lmid(1));
     check("iaa" + escape,    l[0] + "\nxya@ay" + lmid(1));
diff --git a/tests/manual/gdbdebugger/simple/app.cpp b/tests/manual/gdbdebugger/simple/app.cpp
index b8b327af50ecd77041b23f7397998b6b7a3fedcb..9330df449a39d4a9a342de2f1e50c0e8f88e9cb9 100644
--- a/tests/manual/gdbdebugger/simple/app.cpp
+++ b/tests/manual/gdbdebugger/simple/app.cpp
@@ -1001,8 +1001,10 @@ void testQVectorOfQList()
 
 void testNoArgumentName(int i, int, int k)
 {
-    i = 1;
-    k = 2;
+    i = 1000;
+    k = 2000;
+    ++k;
+    ++k;
 }
 
 void foo() {}
@@ -1273,4 +1275,4 @@ struct QMetaTypeId< QMap<uint, QStringList> >
         return metatype_id;                                    \
     }                                                           \
 };
-QT_END_NAMESPACE
+QT_END_NAMESPACE
\ No newline at end of file